@@ -15,9 +15,6 @@ namespace Geometry {
1515
1616using namespace Utils ; // log, AttribXXX
1717
18- template <typename T>
19- using PropPair = std::pair<AttribHandle<T>, OpenMesh::HPropHandleT<T>>;
20-
2118// /////////////// HELPERS ///////////////
2219
2320std::string wedgeInfo ( const Ra::Core::Geometry::TopologicalMesh& topo,
@@ -127,56 +124,23 @@ void printWedgesInfo( const Ra::Core::Geometry::TopologicalMesh& topo ) {
127124 }
128125}
129126
130- template <typename T>
131- void addAttribPairToTopo ( const TriangleMesh& triMesh,
132- TopologicalMesh* topoMesh,
133- AttribManager::pointer_type attr,
134- std::vector<PropPair<T>>& vprop,
135- std::vector<OpenMesh::HPropHandleT<T>>& pph ) {
136- AttribHandle<T> h = triMesh.getAttribHandle <T>( attr->getName () );
137- if ( attr->getSize () == triMesh.vertices ().size () )
138- {
139- OpenMesh::HPropHandleT<T> oh;
140- topoMesh->add_property ( oh, attr->getName () );
141- vprop.push_back ( std::make_pair ( h, oh ) );
142- pph.push_back ( oh );
143- }
144- else
145- {
146- LOG ( logWARNING ) << " [TopologicalMesh] Skip badly sized attribute " << attr->getName ()
147- << " ." ;
148- }
149- }
150-
151- template <typename T>
127+ template <typename P, typename T>
152128void addAttribPairToCore ( TriangleMesh& triMesh,
153129 const TopologicalMesh* topoMesh,
154130 OpenMesh::HPropHandleT<T> oh,
155- std::vector<PropPair<T> >& vprop ) {
131+ std::vector<P >& vprop ) {
156132 AttribHandle<T> h = triMesh.addAttrib <T>( topoMesh->property ( oh ).name () );
157133 vprop.push_back ( std::make_pair ( h, oh ) );
158134}
159135
160- template <typename T>
161- void copyAttribToTopo ( const TriangleMesh& triMesh,
162- TopologicalMesh* topoMesh,
163- const std::vector<PropPair<T>>& vprop,
164- TopologicalMesh::HalfedgeHandle heh,
165- unsigned int vindex ) {
166- for ( auto pp : vprop )
167- {
168- topoMesh->property ( pp.second , heh ) = triMesh.getAttrib ( pp.first ).data ()[vindex];
169- }
170- }
171-
172136template <typename T>
173137using HandleAndValueVector = std::vector<std::pair<AttribHandle<T>, T>,
174138 Eigen::aligned_allocator<std::pair<AttribHandle<T>, T>>>;
175139
176- template <typename T>
140+ template <typename P, typename T>
177141void copyAttribToCoreVertex ( HandleAndValueVector<T>& data,
178142 const TopologicalMesh* topoMesh,
179- const std::vector<PropPair<T> >& vprop,
143+ const std::vector<P >& vprop,
180144 TopologicalMesh::HalfedgeHandle heh ) {
181145 for ( auto pp : vprop )
182146 {
@@ -196,197 +160,25 @@ void copyAttribToCore( TriangleMesh& triMesh, const HandleAndValueVector<T>& dat
196160 }
197161}
198162
199- template <typename T>
200- void copyAttribToWedgeData ( const TriangleMesh& mesh,
201- unsigned int vindex,
202- const std::vector<AttribHandle<T>>& attrHandleVec,
203- VectorArray<T>* to ) {
204- for ( auto handle : attrHandleVec )
205- {
206- auto & attr = mesh.getAttrib <T>( handle );
207- to->push_back ( attr.data ()[vindex] );
163+ // ! [Default command implementation]
164+ struct DefaultNonManifoldFaceCommand {
165+ // / \brief Initalize with input Ra::Core::Geometry::TriangleMesh
166+ inline void initialize ( const TriangleMesh& /* triMesh*/ ) {}
167+ // / \brief Process non-manifold face
168+ inline void process ( const std::vector<TopologicalMesh::VertexHandle>& /* face_vhandles*/ ) {
169+ LOG ( logWARNING ) << " Invalid face handle returned : face not added (1)" ;
170+ // / TODO memorize invalid faces for post processing ...
171+ // / see
172+ // / https://www.graphics.rwth-aachen.de/media/openflipper_static/Daily-Builds/Doc/Free/Developer/OBJImporter_8cc_source.html
173+ // / for an exemple of loading
208174 }
209- }
210-
211- void copyMeshToWedgeData ( const TriangleMesh& mesh,
212- unsigned int vindex,
213- const std::vector<AttribHandle<float >>& wprop_float,
214- const std::vector<AttribHandle<Vector2>>& wprop_vec2,
215- const std::vector<AttribHandle<Vector3>>& wprop_vec3,
216- const std::vector<AttribHandle<Vector4>>& wprop_vec4,
217- TopologicalMesh::WedgeData* wd ) {
218-
219- copyAttribToWedgeData ( mesh, vindex, wprop_float, &wd->m_floatAttrib );
220- copyAttribToWedgeData ( mesh, vindex, wprop_vec2, &wd->m_vector2Attrib );
221- copyAttribToWedgeData ( mesh, vindex, wprop_vec3, &wd->m_vector3Attrib );
222- copyAttribToWedgeData ( mesh, vindex, wprop_vec4, &wd->m_vector4Attrib );
223- }
224-
225- TopologicalMesh::TopologicalMesh ( const TriangleMesh& triMesh ) {
226- // initWithWedge( triMesh );
227- // return;
175+ // / \brief If needed, apply post-processing on the Ra::Core::Geometry::TopologicalMesh
176+ inline void postProcess ( TopologicalMesh& /* tm*/ ) {}
177+ // ! [Default command implementation]
178+ };
228179
229- LOG ( logINFO ) << " TopologicalMesh: load triMesh with " << triMesh.getIndices ().size ()
230- << " faces and " << triMesh.vertices ().size () << " vertices." ;
231-
232- struct hash_vec {
233- size_t operator ()( const Vector3& lvalue ) const {
234- size_t hx = std::hash<Scalar>()( lvalue[0 ] );
235- size_t hy = std::hash<Scalar>()( lvalue[1 ] );
236- size_t hz = std::hash<Scalar>()( lvalue[2 ] );
237- return ( hx ^ ( hy << 1 ) ) ^ hz;
238- }
239- };
240- // use a hashmap for fast search of existing vertex position
241- using VertexMap = std::unordered_map<Vector3, TopologicalMesh::VertexHandle, hash_vec>;
242- VertexMap vertexHandles;
243-
244- add_property ( m_inputTriangleMeshIndexPph );
245-
246- add_property ( m_wedgeIndexPph );
247-
248- std::vector<PropPair<float >> vprop_float;
249- std::vector<PropPair<Vector2>> vprop_vec2;
250- std::vector<PropPair<Vector3>> vprop_vec3;
251- std::vector<PropPair<Vector4>> vprop_vec4;
252-
253- // loop over all attribs and build correspondance pair
254- triMesh.vertexAttribs ().for_each_attrib (
255- [&triMesh, this , &vprop_float, &vprop_vec2, &vprop_vec3, &vprop_vec4]( const auto & attr ) {
256- // skip builtin attribs
257- if ( attr->getName () != std::string ( " in_position" ) &&
258- attr->getName () != std::string ( " in_normal" ) )
259- {
260- if ( attr->isFloat () )
261- addAttribPairToTopo ( triMesh, this , attr, vprop_float, m_floatPph );
262- else if ( attr->isVector2 () )
263- addAttribPairToTopo ( triMesh, this , attr, vprop_vec2, m_vec2Pph );
264- else if ( attr->isVector3 () )
265- addAttribPairToTopo ( triMesh, this , attr, vprop_vec3, m_vec3Pph );
266- else if ( attr->isVector4 () )
267- addAttribPairToTopo ( triMesh, this , attr, vprop_vec4, m_vec4Pph );
268- else
269- LOG ( logWARNING )
270- << " Warning, mesh attribute " << attr->getName ()
271- << " type is not supported (only float, vec2, vec3 nor vec4 are supported)" ;
272- }
273- } );
274- // loop over all attribs and build correspondance pair
275- triMesh.vertexAttribs ().for_each_attrib (
276- [&triMesh, this ]( const auto & attr ) {
277- if ( attr->getSize () != triMesh.vertices ().size () )
278- {
279- LOG ( logWARNING ) << " [TopologicalMesh] Skip badly sized attribute "
280- << attr->getName ();
281- }
282- else if ( attr->getName () != std::string ( " in_position" ) )
283- {
284- if ( attr->isFloat () )
285- {
286- m_wedges.m_wedgeFloatAttribHandles .push_back (
287- triMesh.getAttribHandle <float >( attr->getName () ) );
288- m_wedges.addProp <float >( attr->getName () );
289- }
290- else if ( attr->isVector2 () )
291- {
292- m_wedges.m_wedgeVector2AttribHandles .push_back (
293- triMesh.getAttribHandle <Vector2>( attr->getName () ) );
294- m_wedges.addProp <Vector2>( attr->getName () );
295- }
296- else if ( attr->isVector3 () )
297- {
298- m_wedges.m_wedgeVector3AttribHandles .push_back (
299- triMesh.getAttribHandle <Vector3>( attr->getName () ) );
300- m_wedges.addProp <Vector3>( attr->getName () );
301- }
302- else if ( attr->isVector4 () )
303- {
304- m_wedges.m_wedgeVector4AttribHandles .push_back (
305- triMesh.getAttribHandle <Vector4>( attr->getName () ) );
306- m_wedges.addProp <Vector4>( attr->getName () );
307- }
308- else
309- LOG ( logWARNING )
310- << " Warning, mesh attribute " << attr->getName ()
311- << " type is not supported (only float, vec2, vec3 nor vec4 are supported)" ;
312- }
313- } );
314-
315- size_t num_triangles = triMesh.getIndices ().size ();
316-
317- for ( unsigned int i = 0 ; i < num_triangles; i++ )
318- {
319- std::vector<TopologicalMesh::VertexHandle> face_vhandles ( 3 );
320- std::vector<TopologicalMesh::Normal> face_normals ( 3 );
321- std::vector<unsigned int > face_vertexIndex ( 3 );
322- std::vector<WedgeIndex> face_wedges ( 3 );
323- const auto & triangle = triMesh.getIndices ()[i];
324- for ( size_t j = 0 ; j < 3 ; ++j )
325- {
326- unsigned int inMeshVertexIndex = triangle[j];
327- const Vector3& p = triMesh.vertices ()[inMeshVertexIndex];
328- const Vector3& n = triMesh.normals ()[inMeshVertexIndex];
329-
330- VertexMap::iterator vtr = vertexHandles.find ( p );
331-
332- TopologicalMesh::VertexHandle vh;
333- if ( vtr == vertexHandles.end () )
334- {
335- vh = add_vertex ( p );
336- vertexHandles.insert ( vtr, VertexMap::value_type ( p, vh ) );
337- }
338- else
339- { vh = vtr->second ; }
340-
341- face_vhandles[j] = vh;
342- face_normals[j] = n;
343- face_vertexIndex[j] = inMeshVertexIndex;
344- WedgeData wd;
345- wd.m_position = p;
346-
347- copyMeshToWedgeData ( triMesh,
348- inMeshVertexIndex,
349- m_wedges.m_wedgeFloatAttribHandles ,
350- m_wedges.m_wedgeVector2AttribHandles ,
351- m_wedges.m_wedgeVector3AttribHandles ,
352- m_wedges.m_wedgeVector4AttribHandles ,
353- &wd );
354-
355- face_wedges[j] = m_wedges.add ( wd );
356- }
357-
358- // Add the face, then add attribs to vh
359- auto fh = add_face ( face_vhandles );
360- // In case of topological inconsistancy, face will be invalid ...
361- if ( fh.is_valid () )
362- {
363- for ( size_t vindex = 0 ; vindex < face_vhandles.size (); vindex++ )
364- {
365- TopologicalMesh::HalfedgeHandle heh = halfedge_handle ( face_vhandles[vindex], fh );
366- set_normal ( heh, face_normals[vindex] );
367- property ( m_inputTriangleMeshIndexPph, heh ) = face_vertexIndex[vindex];
368- copyAttribToTopo ( triMesh, this , vprop_float, heh, face_vertexIndex[vindex] );
369- copyAttribToTopo ( triMesh, this , vprop_vec2, heh, face_vertexIndex[vindex] );
370- copyAttribToTopo ( triMesh, this , vprop_vec3, heh, face_vertexIndex[vindex] );
371- copyAttribToTopo ( triMesh, this , vprop_vec4, heh, face_vertexIndex[vindex] );
372- property ( m_wedgeIndexPph, heh ) = face_wedges[vindex];
373- }
374- }
375- else
376- {
377- LOG ( logWARNING ) << " Invalid face handle returned : face not added (1)" ;
378- // TODO memorize invalid faces for post processing ...
379- // see
380- // https://www.graphics.rwth-aachen.de/media/openflipper_static/Daily-Builds/Doc/Free/Developer/OBJImporter_8cc_source.html
381- // for an exemple of loading
382- }
383- face_vhandles.clear ();
384- face_normals.clear ();
385- face_vertexIndex.clear ();
386- }
387- // LOG( logINFO ) << "TopologicalMesh: load end with " << m_wedges.size() << " wedges ";
388- // printWedgesInfo( *this );
389- }
180+ TopologicalMesh::TopologicalMesh ( const TriangleMesh& triMesh ) :
181+ TopologicalMesh ( triMesh, DefaultNonManifoldFaceCommand() ) {}
390182
391183void TopologicalMesh::initWithWedge ( const TriangleMesh& triMesh ) {
392184
0 commit comments