56class RA_CORE_API
TopologicalMesh :
public OpenMesh::PolyMesh_ArrayKernelT<TopologicalMeshTraits>
59 using base = OpenMesh::PolyMesh_ArrayKernelT<TopologicalMeshTraits>;
60 using base::PolyMesh_ArrayKernelT;
61 using Index = Ra::Core::Utils::Index;
62 using Vector3 = Ra::Core::Vector3;
77 template <
typename NonManifoldFaceCommand>
78 explicit TopologicalMesh(
const Ra::Core::Geometry::TriangleMesh& triMesh,
79 NonManifoldFaceCommand command );
85 explicit TopologicalMesh(
const Ra::Core::Geometry::TriangleMesh& triMesh );
96 TriangleMesh toTriangleMesh();
106 using base::halfedge_handle;
112 inline HalfedgeHandle halfedge_handle( VertexHandle vh, FaceHandle fh )
const;
118 [[deprecated]]
inline const Normal& normal( VertexHandle vh, FaceHandle fh )
const;
124 [[deprecated]]
void set_normal( VertexHandle vh, FaceHandle fh,
const Normal& n );
129 using base::set_normal;
138 [[deprecated]]
void propagate_normal_to_halfedges( VertexHandle vh );
144 inline const OpenMesh::HPropHandleT<Index>& getInputTriangleMeshIndexPropHandle()
const;
151 inline const OpenMesh::HPropHandleT<Index>& getOutputTriangleMeshIndexPropHandle()
const;
159 getFloatPropsHandles()
const;
161 getVector2PropsHandles()
const;
163 getVector3PropsHandles()
const;
165 getVector4PropsHandles()
const;
179 inline void createNormalPropOnFaces( OpenMesh::FPropHandleT<Normal>& fProp );
185 inline void clearProp( OpenMesh::FPropHandleT<Normal>& fProp );
190 inline void copyNormal( HalfedgeHandle input_heh, HalfedgeHandle copy_heh );
196 copyNormalFromFace( FaceHandle fh, HalfedgeHandle heh, OpenMesh::FPropHandleT<Normal> fProp );
202 interpolateNormal( HalfedgeHandle in_a, HalfedgeHandle in_b, HalfedgeHandle out, Scalar f );
207 inline void interpolateNormalOnFaces( FaceHandle fh, OpenMesh::FPropHandleT<Normal> fProp );
221 template <
typename T>
222 void createPropsOnFaces(
const std::vector<OpenMesh::HPropHandleT<T>>& input,
229 template <
typename T>
230 void clearProps(
std::vector<OpenMesh::FPropHandleT<T>>& props );
235 template <
typename T>
236 void copyProps( HalfedgeHandle input_heh,
237 HalfedgeHandle copy_heh,
238 const std::vector<OpenMesh::HPropHandleT<T>>& props );
244 template <
typename T>
245 void copyPropsFromFace( FaceHandle fh,
247 const std::vector<OpenMesh::FPropHandleT<T>>& fProps,
248 const std::vector<OpenMesh::HPropHandleT<T>>& hProps );
253 template <
typename T>
254 void interpolateProps( HalfedgeHandle in_a,
258 const std::vector<OpenMesh::HPropHandleT<T>>& props );
264 template <
typename T>
265 void interpolatePropsOnFaces( FaceHandle fh,
266 const std::vector<OpenMesh::HPropHandleT<T>>& hProps,
267 const std::vector<OpenMesh::FPropHandleT<T>>& fProps );
281 inline void createAllPropsOnFaces( OpenMesh::FPropHandleT<Normal>& normalProp,
282 std::vector<OpenMesh::FPropHandleT<Scalar>>& floatProps,
283 std::vector<OpenMesh::FPropHandleT<Vector2>>& vec2Props,
284 std::vector<OpenMesh::FPropHandleT<Vector3>>& vec3Props,
285 std::vector<OpenMesh::FPropHandleT<Vector4>>& vec4Props );
291 inline void clearAllProps( OpenMesh::FPropHandleT<Normal>& normalProp,
292 std::vector<OpenMesh::FPropHandleT<Scalar>>& floatProps,
293 std::vector<OpenMesh::FPropHandleT<Vector2>>& vec2Props,
294 std::vector<OpenMesh::FPropHandleT<Vector3>>& vec3Props,
295 std::vector<OpenMesh::FPropHandleT<Vector4>>& vec4Props );
300 inline void copyAllProps( HalfedgeHandle input_heh, HalfedgeHandle copy_heh );
308 inline void copyAllPropsFromFace( FaceHandle fh,
310 OpenMesh::FPropHandleT<Normal> normalProp,
311 std::vector<OpenMesh::FPropHandleT<Scalar>>& floatProps,
312 std::vector<OpenMesh::FPropHandleT<Vector2>>& vec2Props,
313 std::vector<OpenMesh::FPropHandleT<Vector3>>& vec3Props,
314 std::vector<OpenMesh::FPropHandleT<Vector4>>& vec4Props );
320 interpolateAllProps( HalfedgeHandle in_a, HalfedgeHandle in_b, HalfedgeHandle out, Scalar f );
329 interpolateAllPropsOnFaces( FaceHandle fh,
330 OpenMesh::FPropHandleT<Normal> normalProp,
331 std::vector<OpenMesh::FPropHandleT<Scalar>>& floatProps,
332 std::vector<OpenMesh::FPropHandleT<Vector2>>& vec2Props,
333 std::vector<OpenMesh::FPropHandleT<Vector3>>& vec3Props,
334 std::vector<OpenMesh::FPropHandleT<Vector4>>& vec4Props );
353 bool splitEdge( TopologicalMesh::EdgeHandle eh, Scalar f );
354 bool splitEdgeWedge( TopologicalMesh::EdgeHandle eh, Scalar f );
359 template <
typename T>
362 Eigen::aligned_allocator<std::pair<AttribHandle<T>, T>>>;
364 template <
typename T>
367 template <
typename T>
368 inline void copyAttribToTopo(
const TriangleMesh& triMesh,
370 TopologicalMesh::HalfedgeHandle heh,
371 unsigned int vindex );
373 template <
typename T>
374 inline void addAttribPairToTopo(
const TriangleMesh& triMesh,
379 void split_copy( EdgeHandle _eh, VertexHandle _vh );
380 void split( EdgeHandle _eh, VertexHandle _vh );
383 OpenMesh::HPropHandleT<Index> m_inputTriangleMeshIndexPph;
384 OpenMesh::HPropHandleT<Index> m_outputTriangleMeshIndexPph;
390 friend class TMOperations;
395 NonManifoldFaceCommand command ) :
398 LOG( logINFO ) <<
"TopologicalMesh: load triMesh with " << triMesh.getIndices().
size()
399 <<
" faces and " << triMesh.
vertices().size() <<
" vertices.";
402 size_t operator()(
const Vector3& lvalue )
const {
406 return ( hx ^ ( hy << 1 ) ) ^ hz;
411 VertexMap vertexHandles;
420 [&triMesh,
this, &vprop_float, &vprop_vec2, &vprop_vec3, &vprop_vec4](
const auto& attr ) {
422 if ( attr->getName() !=
std::string( getAttribName( MeshAttrib::VERTEX_POSITION ) ) &&
423 attr->getName() !=
std::string( getAttribName( MeshAttrib::VERTEX_NORMAL ) ) ) {
424 if ( attr->isFloat() )
425 addAttribPairToTopo( triMesh, attr, vprop_float, m_floatPph );
426 else if ( attr->isVector2() )
427 addAttribPairToTopo( triMesh, attr, vprop_vec2, m_vec2Pph );
428 else if ( attr->isVector3() )
429 addAttribPairToTopo( triMesh, attr, vprop_vec3, m_vec3Pph );
430 else if ( attr->isVector4() )
431 addAttribPairToTopo( triMesh, attr, vprop_vec4, m_vec4Pph );
434 <<
"Warning, mesh attribute " << attr->getName()
435 <<
" type is not supported (only float, vec2, vec3 nor vec4 are supported)";
439 size_t num_triangles = triMesh.getIndices().
size();
441 command.initialize( triMesh );
443 const bool hasNormals = !triMesh.
normals().empty();
445 release_face_normals();
446 release_vertex_normals();
447 release_halfedge_normals();
449 for (
unsigned int i = 0; i < num_triangles; i++ ) {
453 const auto& triangle = triMesh.getIndices()[i];
454 for (
size_t j = 0; j < 3; ++j ) {
455 unsigned int inMeshVertexIndex = triangle[j];
456 const Vector3& p = triMesh.
vertices()[inMeshVertexIndex];
458 typename VertexMap::iterator vtr = vertexHandles.find( p );
460 TopologicalMesh::VertexHandle vh;
461 if ( vtr == vertexHandles.end() ) {
462 vh = add_vertex( p );
463 vertexHandles.insert( vtr,
typename VertexMap::value_type( p, vh ) );
465 else { vh = vtr->second; }
467 face_vhandles[j] = vh;
468 face_vertexIndex[j] = inMeshVertexIndex;
469 if ( hasNormals ) face_normals[j] = triMesh.
normals()[inMeshVertexIndex];
472 TopologicalMesh::FaceHandle fh;
475 if ( face_vhandles.
size() > 2 ) fh = add_face( face_vhandles );
478 if ( fh.is_valid() ) {
479 for (
size_t vindex = 0; vindex < face_vhandles.
size(); vindex++ ) {
480 TopologicalMesh::HalfedgeHandle heh =
halfedge_handle( face_vhandles[vindex], fh );
481 if ( hasNormals )
set_normal( heh, face_normals[vindex] );
482 property( m_inputTriangleMeshIndexPph, heh ) = face_vertexIndex[vindex];
483 copyAttribToTopo( triMesh, vprop_float, heh, face_vertexIndex[vindex] );
484 copyAttribToTopo( triMesh, vprop_vec2, heh, face_vertexIndex[vindex] );
485 copyAttribToTopo( triMesh, vprop_vec3, heh, face_vertexIndex[vindex] );
486 copyAttribToTopo( triMesh, vprop_vec4, heh, face_vertexIndex[vindex] );
489 else { command.process( face_vhandles ); }
490 face_vhandles.
clear();
491 face_normals.
clear();
492 face_vertexIndex.
clear();
494 command.postProcess( *
this );
497 garbage_collection();