3 #include <Core/RaCore.hpp>
5 #include <Core/Containers/VectorArray.hpp>
6 #include <Core/Geometry/OpenMesh.hpp>
7 #include <Core/Geometry/StandardAttribNames.hpp>
8 #include <Core/Geometry/TriangleMesh.hpp>
10 #include <Core/Utils/Index.hpp>
11 #include <Core/Utils/StdOptional.hpp>
13 #include <OpenMesh/Core/Mesh/PolyMesh_ArrayKernelT.hh>
14 #include <OpenMesh/Core/Mesh/Traits.hh>
15 #include <OpenMesh/Core/Mesh/TriMesh_ArrayKernelT.hh>
16 #include <OpenMesh/Core/Utils/Property.hh>
17 #include <OpenMesh/Core/Utils/PropertyManager.hh>
20 #include <Eigen/Geometry>
24 #include <unordered_map>
29 namespace deprecated {
30 using namespace Utils;
36 using Point = Ra::Core::Vector3;
37 using Normal = Ra::Core::Vector3;
39 VertexAttributes( OpenMesh::Attributes::Status | OpenMesh::Attributes::Normal );
40 FaceAttributes( OpenMesh::Attributes::Status | OpenMesh::Attributes::Normal );
41 EdgeAttributes( OpenMesh::Attributes::Status );
43 HalfedgeAttributes( OpenMesh::Attributes::Status | OpenMesh::Attributes::Normal );
56 class 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;
65 EIGEN_MAKE_ALIGNED_OPERATOR_NEW
79 template <
typename NonManifoldFaceCommand>
81 NonManifoldFaceCommand command );
87 explicit TopologicalMesh(
const Ra::Core::Geometry::TriangleMesh& triMesh );
98 TriangleMesh toTriangleMesh();
108 using base::halfedge_handle;
114 inline HalfedgeHandle halfedge_handle( VertexHandle vh, FaceHandle fh )
const;
120 [[deprecated]]
inline const Normal& normal( VertexHandle vh, FaceHandle fh )
const;
126 [[deprecated]]
void set_normal( VertexHandle vh, FaceHandle fh,
const Normal& n );
131 using base::set_normal;
140 [[deprecated]]
void propagate_normal_to_halfedges( VertexHandle vh );
146 inline const OpenMesh::HPropHandleT<Index>& getInputTriangleMeshIndexPropHandle()
const;
153 inline const OpenMesh::HPropHandleT<Index>& getOutputTriangleMeshIndexPropHandle()
const;
160 [[deprecated]]
inline const std::vector<OpenMesh::HPropHandleT<Scalar>>&
161 getFloatPropsHandles()
const;
162 [[deprecated]]
inline const std::vector<OpenMesh::HPropHandleT<Vector2>>&
163 getVector2PropsHandles()
const;
164 [[deprecated]]
inline const std::vector<OpenMesh::HPropHandleT<Vector3>>&
165 getVector3PropsHandles()
const;
166 [[deprecated]]
inline const std::vector<OpenMesh::HPropHandleT<Vector4>>&
167 getVector4PropsHandles()
const;
181 inline void createNormalPropOnFaces( OpenMesh::FPropHandleT<Normal>& fProp );
187 inline void clearProp( OpenMesh::FPropHandleT<Normal>& fProp );
192 inline void copyNormal( HalfedgeHandle input_heh, HalfedgeHandle copy_heh );
198 copyNormalFromFace( FaceHandle fh, HalfedgeHandle heh, OpenMesh::FPropHandleT<Normal> fProp );
204 interpolateNormal( HalfedgeHandle in_a, HalfedgeHandle in_b, HalfedgeHandle out, Scalar f );
209 inline void interpolateNormalOnFaces( FaceHandle fh, OpenMesh::FPropHandleT<Normal> fProp );
223 template <
typename T>
224 void createPropsOnFaces(
const std::vector<OpenMesh::HPropHandleT<T>>& input,
225 std::vector<OpenMesh::FPropHandleT<T>>& output );
231 template <
typename T>
232 void clearProps( std::vector<OpenMesh::FPropHandleT<T>>& props );
237 template <
typename T>
238 void copyProps( HalfedgeHandle input_heh,
239 HalfedgeHandle copy_heh,
240 const std::vector<OpenMesh::HPropHandleT<T>>& props );
246 template <
typename T>
247 void copyPropsFromFace( FaceHandle fh,
249 const std::vector<OpenMesh::FPropHandleT<T>>& fProps,
250 const std::vector<OpenMesh::HPropHandleT<T>>& hProps );
255 template <
typename T>
256 void interpolateProps( HalfedgeHandle in_a,
260 const std::vector<OpenMesh::HPropHandleT<T>>& props );
266 template <
typename T>
267 void interpolatePropsOnFaces( FaceHandle fh,
268 const std::vector<OpenMesh::HPropHandleT<T>>& hProps,
269 const std::vector<OpenMesh::FPropHandleT<T>>& fProps );
283 inline void createAllPropsOnFaces( OpenMesh::FPropHandleT<Normal>& normalProp,
284 std::vector<OpenMesh::FPropHandleT<Scalar>>& floatProps,
285 std::vector<OpenMesh::FPropHandleT<Vector2>>& vec2Props,
286 std::vector<OpenMesh::FPropHandleT<Vector3>>& vec3Props,
287 std::vector<OpenMesh::FPropHandleT<Vector4>>& vec4Props );
293 inline void clearAllProps( OpenMesh::FPropHandleT<Normal>& normalProp,
294 std::vector<OpenMesh::FPropHandleT<Scalar>>& floatProps,
295 std::vector<OpenMesh::FPropHandleT<Vector2>>& vec2Props,
296 std::vector<OpenMesh::FPropHandleT<Vector3>>& vec3Props,
297 std::vector<OpenMesh::FPropHandleT<Vector4>>& vec4Props );
302 inline void copyAllProps( HalfedgeHandle input_heh, HalfedgeHandle copy_heh );
310 inline void copyAllPropsFromFace( FaceHandle fh,
312 OpenMesh::FPropHandleT<Normal> normalProp,
313 std::vector<OpenMesh::FPropHandleT<Scalar>>& floatProps,
314 std::vector<OpenMesh::FPropHandleT<Vector2>>& vec2Props,
315 std::vector<OpenMesh::FPropHandleT<Vector3>>& vec3Props,
316 std::vector<OpenMesh::FPropHandleT<Vector4>>& vec4Props );
322 interpolateAllProps( HalfedgeHandle in_a, HalfedgeHandle in_b, HalfedgeHandle out, Scalar f );
331 interpolateAllPropsOnFaces( FaceHandle fh,
332 OpenMesh::FPropHandleT<Normal> normalProp,
333 std::vector<OpenMesh::FPropHandleT<Scalar>>& floatProps,
334 std::vector<OpenMesh::FPropHandleT<Vector2>>& vec2Props,
335 std::vector<OpenMesh::FPropHandleT<Vector3>>& vec3Props,
336 std::vector<OpenMesh::FPropHandleT<Vector4>>& vec4Props );
355 bool splitEdge( TopologicalMesh::EdgeHandle eh, Scalar f );
356 bool splitEdgeWedge( TopologicalMesh::EdgeHandle eh, Scalar f );
361 template <
typename T>
362 using HandleAndValueVector =
363 std::vector<std::pair<AttribHandle<T>, T>,
364 Eigen::aligned_allocator<std::pair<AttribHandle<T>, T>>>;
366 template <
typename T>
367 using PropPair = std::pair<AttribHandle<T>, OpenMesh::HPropHandleT<T>>;
369 template <
typename T>
370 inline void copyAttribToTopo(
const TriangleMesh& triMesh,
371 const std::vector<PropPair<T>>& vprop,
372 TopologicalMesh::HalfedgeHandle heh,
373 unsigned int vindex );
375 template <
typename T>
376 inline void addAttribPairToTopo(
const TriangleMesh& triMesh,
378 std::vector<PropPair<T>>& vprop,
379 std::vector<OpenMesh::HPropHandleT<T>>& pph );
381 void split_copy( EdgeHandle _eh, VertexHandle _vh );
382 void split( EdgeHandle _eh, VertexHandle _vh );
385 OpenMesh::HPropHandleT<Index> m_inputTriangleMeshIndexPph;
386 OpenMesh::HPropHandleT<Index> m_outputTriangleMeshIndexPph;
387 [[deprecated]] std::vector<OpenMesh::HPropHandleT<Scalar>> m_floatPph;
388 [[deprecated]] std::vector<OpenMesh::HPropHandleT<Vector2>> m_vec2Pph;
389 [[deprecated]] std::vector<OpenMesh::HPropHandleT<Vector3>> m_vec3Pph;
390 [[deprecated]] std::vector<OpenMesh::HPropHandleT<Vector4>> m_vec4Pph;
392 friend class TMOperations;
395 template <
typename NonManifoldFaceCommand>
397 NonManifoldFaceCommand command ) :
400 LOG( logINFO ) <<
"TopologicalMesh: load triMesh with " << triMesh.getIndices().size()
401 <<
" faces and " << triMesh.vertices().size() <<
" vertices.";
404 size_t operator()(
const Vector3& lvalue )
const {
405 size_t hx = std::hash<Scalar>()( lvalue[0] );
406 size_t hy = std::hash<Scalar>()( lvalue[1] );
407 size_t hz = std::hash<Scalar>()( lvalue[2] );
408 return ( hx ^ ( hy << 1 ) ) ^ hz;
412 using VertexMap = std::unordered_map<Vector3, TopologicalMesh::VertexHandle, hash_vec>;
413 VertexMap vertexHandles;
415 std::vector<PropPair<Scalar>> vprop_float;
416 std::vector<std::pair<AttribHandle<Vector2>, OpenMesh::HPropHandleT<Vector2>>> vprop_vec2;
417 std::vector<std::pair<AttribHandle<Vector3>, OpenMesh::HPropHandleT<Vector3>>> vprop_vec3;
418 std::vector<std::pair<AttribHandle<Vector4>, OpenMesh::HPropHandleT<Vector4>>> vprop_vec4;
421 triMesh.vertexAttribs().for_each_attrib(
422 [&triMesh,
this, &vprop_float, &vprop_vec2, &vprop_vec3, &vprop_vec4](
const auto& attr ) {
424 if ( attr->getName() != std::string( getAttribName( MeshAttrib::VERTEX_POSITION ) ) &&
425 attr->getName() != std::string( getAttribName( MeshAttrib::VERTEX_NORMAL ) ) ) {
426 if ( attr->isFloat() )
427 addAttribPairToTopo( triMesh, attr, vprop_float, m_floatPph );
428 else if ( attr->isVector2() )
429 addAttribPairToTopo( triMesh, attr, vprop_vec2, m_vec2Pph );
430 else if ( attr->isVector3() )
431 addAttribPairToTopo( triMesh, attr, vprop_vec3, m_vec3Pph );
432 else if ( attr->isVector4() )
433 addAttribPairToTopo( triMesh, attr, vprop_vec4, m_vec4Pph );
436 <<
"Warning, mesh attribute " << attr->getName()
437 <<
" type is not supported (only float, vec2, vec3 nor vec4 are supported)";
441 size_t num_triangles = triMesh.getIndices().size();
443 command.initialize( triMesh );
445 const bool hasNormals = !triMesh.normals().empty();
447 release_face_normals();
448 release_vertex_normals();
449 release_halfedge_normals();
451 for (
unsigned int i = 0; i < num_triangles; i++ ) {
452 std::vector<TopologicalMesh::VertexHandle> face_vhandles( 3 );
453 std::vector<TopologicalMesh::Normal> face_normals( 3 );
454 std::vector<unsigned int> face_vertexIndex( 3 );
455 const auto& triangle = triMesh.getIndices()[i];
456 for (
size_t j = 0; j < 3; ++j ) {
457 unsigned int inMeshVertexIndex = triangle[j];
458 const Vector3& p = triMesh.vertices()[inMeshVertexIndex];
460 typename VertexMap::iterator vtr = vertexHandles.find( p );
462 TopologicalMesh::VertexHandle vh;
463 if ( vtr == vertexHandles.end() ) {
464 vh = add_vertex( p );
465 vertexHandles.insert( vtr,
typename VertexMap::value_type( p, vh ) );
467 else { vh = vtr->second; }
469 face_vhandles[j] = vh;
470 face_vertexIndex[j] = inMeshVertexIndex;
471 if ( hasNormals ) face_normals[j] = triMesh.normals()[inMeshVertexIndex];
474 TopologicalMesh::FaceHandle fh;
477 if ( face_vhandles.size() > 2 ) fh = add_face( face_vhandles );
480 if ( fh.is_valid() ) {
481 for (
size_t vindex = 0; vindex < face_vhandles.size(); vindex++ ) {
482 TopologicalMesh::HalfedgeHandle heh =
halfedge_handle( face_vhandles[vindex], fh );
483 if ( hasNormals )
set_normal( heh, face_normals[vindex] );
484 property( m_inputTriangleMeshIndexPph, heh ) = face_vertexIndex[vindex];
485 copyAttribToTopo( triMesh, vprop_float, heh, face_vertexIndex[vindex] );
486 copyAttribToTopo( triMesh, vprop_vec2, heh, face_vertexIndex[vindex] );
487 copyAttribToTopo( triMesh, vprop_vec3, heh, face_vertexIndex[vindex] );
488 copyAttribToTopo( triMesh, vprop_vec4, heh, face_vertexIndex[vindex] );
491 else { command.process( face_vhandles ); }
492 face_vhandles.clear();
493 face_normals.clear();
494 face_vertexIndex.clear();
496 command.postProcess( *
this );
499 garbage_collection();
502 template <
typename T>
503 void TopologicalMesh::addAttribPairToTopo(
const TriangleMesh& triMesh,
504 AttribManager::pointer_type attr,
505 std::vector<TopologicalMesh::PropPair<T>>& vprop,
506 std::vector<OpenMesh::HPropHandleT<T>>& pph ) {
507 AttribHandle<T> h = triMesh.getAttribHandle<T>( attr->getName() );
508 if ( attr->getSize() == triMesh.vertices().size() ) {
509 OpenMesh::HPropHandleT<T> oh;
510 this->add_property( oh, attr->getName() );
511 vprop.push_back( std::make_pair( h, oh ) );
515 LOG( logWARNING ) <<
"[TopologicalMesh] Skip badly sized attribute " << attr->getName()
520 template <
typename T>
521 void TopologicalMesh::copyAttribToTopo(
const TriangleMesh& triMesh,
522 const std::vector<PropPair<T>>& vprop,
523 TopologicalMesh::HalfedgeHandle heh,
524 unsigned int vindex ) {
525 for (
auto pp : vprop ) {
526 this->property( pp.second, heh ) = triMesh.getAttrib( pp.first ).data()[vindex];
531 FaceHandle fh )
const {
533 if ( !has_halfedge_normals() ) {
534 LOG( logERROR ) <<
"TopologicalMesh has no normals, return dummy ref to (0,0,0)";
535 static TopologicalMesh::Normal dummy { 0_ra, 0_ra, 0_ra };
542 if ( !has_halfedge_normals() ) {
543 LOG( logERROR ) <<
"TopologicalMesh has no normals, nothing set";
551 if ( !has_halfedge_normals() ) {
552 LOG( logERROR ) <<
"TopologicalMesh has no normals, nothing set";
555 for ( VertexIHalfedgeIter vih_it = vih_iter( vh ); vih_it.is_valid(); ++vih_it ) {
561 FaceHandle fh )
const {
562 for ( ConstVertexIHalfedgeIter vih_it = cvih_iter( vh ); vih_it.is_valid(); ++vih_it ) {
563 if ( face_handle( *vih_it ) == fh ) {
return *vih_it; }
565 CORE_ASSERT(
false,
"vh is not a vertex of face fh" );
566 return HalfedgeHandle();
569 inline const OpenMesh::HPropHandleT<TopologicalMesh::Index>&
571 return m_inputTriangleMeshIndexPph;
574 inline const OpenMesh::HPropHandleT<TopologicalMesh::Index>&
576 return m_outputTriangleMeshIndexPph;
579 inline const std::vector<OpenMesh::HPropHandleT<Scalar>>&
580 TopologicalMesh::getFloatPropsHandles()
const {
584 inline const std::vector<OpenMesh::HPropHandleT<Vector2>>&
585 TopologicalMesh::getVector2PropsHandles()
const {
589 inline const std::vector<OpenMesh::HPropHandleT<Vector3>>&
590 TopologicalMesh::getVector3PropsHandles()
const {
594 inline const std::vector<OpenMesh::HPropHandleT<Vector4>>&
595 TopologicalMesh::getVector4PropsHandles()
const {
600 if ( !has_halfedge_normals() ) {
601 LOG( logERROR ) <<
"TopologicalMesh has no normals, nothing set";
604 auto nph = halfedge_normals_pph();
605 add_property( fProp, property( nph ).name() +
"_subdiv_copy_F" );
609 remove_property( fProp );
613 if ( !has_halfedge_normals() ) {
614 LOG( logERROR ) <<
"TopologicalMesh has no normals, nothing set";
617 auto nph = halfedge_normals_pph();
618 property( nph, copy_heh ) = property( nph, input_heh );
623 OpenMesh::FPropHandleT<Normal> fProp ) {
624 if ( !has_halfedge_normals() ) {
625 LOG( logERROR ) <<
"TopologicalMesh has no normals, nothing set";
628 auto nph = halfedge_normals_pph();
629 property( nph, heh ) = property( fProp, fh );
636 auto nph = halfedge_normals_pph();
637 property( nph, out ) =
638 ( ( 1 - f ) * property( nph, in_a ) + f * property( nph, in_b ) ).normalized();
642 OpenMesh::FPropHandleT<Normal> fProp ) {
643 if ( !has_halfedge_normals() ) {
644 LOG( logERROR ) <<
"TopologicalMesh has no normals, nothing set";
647 auto nph = halfedge_normals_pph();
651 property( fProp, fh ) = property( nph, heh );
652 heh = next_halfedge_handle( heh );
655 for (
size_t i = 1; i < valence( fh ); ++i ) {
656 property( fProp, fh ) += property( nph, heh );
657 heh = next_halfedge_handle( heh );
661 property( fProp, fh ) = property( fProp, fh ).normalized();
664 template <
typename T>
666 std::vector<OpenMesh::FPropHandleT<T>>& output ) {
667 output.reserve( input.size() );
668 for (
const auto& oh : input ) {
669 OpenMesh::FPropHandleT<T> oh_;
670 add_property( oh_, property( oh ).name() +
"_subdiv_copy_F" );
671 output.push_back( oh_ );
675 template <
typename T>
677 for (
auto& oh : props ) {
678 remove_property( oh );
683 template <
typename T>
685 HalfedgeHandle copy_heh,
686 const std::vector<OpenMesh::HPropHandleT<T>>& props ) {
687 for (
const auto& oh : props ) {
688 property( oh, copy_heh ) = property( oh, input_heh );
692 template <
typename T>
695 const std::vector<OpenMesh::FPropHandleT<T>>& fProps,
696 const std::vector<OpenMesh::HPropHandleT<T>>& hProps ) {
697 for ( uint i = 0; i < fProps.size(); ++i ) {
700 property( hp, heh ) = property( fp, fh );
704 template <
typename T>
709 const std::vector<OpenMesh::HPropHandleT<T>>& props ) {
711 for (
const auto& oh : props ) {
712 property( oh, out ) = ( 1 - f ) * property( oh, in_a ) + f * property( oh, in_b );
716 template <
typename T>
719 const std::vector<OpenMesh::HPropHandleT<T>>& hProps,
720 const std::vector<OpenMesh::FPropHandleT<T>>& fProps ) {
722 const size_t v = valence( fh );
725 for (
size_t j = 0; j < fProps.size(); ++j ) {
728 property( fp, fh ) = property( hp, heh );
730 heh = next_halfedge_handle( heh );
732 for (
size_t i = 1; i < v; ++i ) {
733 for (
size_t j = 0; j < fProps.size(); ++j ) {
736 property( fp, fh ) += property( hp, heh );
738 heh = next_halfedge_handle( heh );
741 for (
size_t j = 0; j < fProps.size(); ++j ) {
743 property( fp, fh ) = property( fp, fh ) / v;
749 std::vector<OpenMesh::FPropHandleT<Scalar>>& floatProps,
750 std::vector<OpenMesh::FPropHandleT<Vector2>>& vec2Props,
751 std::vector<OpenMesh::FPropHandleT<Vector3>>& vec3Props,
752 std::vector<OpenMesh::FPropHandleT<Vector4>>& vec4Props ) {
762 std::vector<OpenMesh::FPropHandleT<Scalar>>& floatProps,
763 std::vector<OpenMesh::FPropHandleT<Vector2>>& vec2Props,
764 std::vector<OpenMesh::FPropHandleT<Vector3>>& vec3Props,
765 std::vector<OpenMesh::FPropHandleT<Vector4>>& vec4Props ) {
775 copyProps( input_heh, copy_heh, getFloatPropsHandles() );
776 copyProps( input_heh, copy_heh, getVector2PropsHandles() );
777 copyProps( input_heh, copy_heh, getVector3PropsHandles() );
778 copyProps( input_heh, copy_heh, getVector4PropsHandles() );
784 OpenMesh::FPropHandleT<Normal> normalProp,
785 std::vector<OpenMesh::FPropHandleT<Scalar>>& floatProps,
786 std::vector<OpenMesh::FPropHandleT<Vector2>>& vec2Props,
787 std::vector<OpenMesh::FPropHandleT<Vector3>>& vec3Props,
788 std::vector<OpenMesh::FPropHandleT<Vector4>>& vec4Props ) {
809 OpenMesh::FPropHandleT<Normal> normalProp,
810 std::vector<OpenMesh::FPropHandleT<Scalar>>& floatProps,
811 std::vector<OpenMesh::FPropHandleT<Vector2>>& vec2Props,
812 std::vector<OpenMesh::FPropHandleT<Vector3>>& vec3Props,
813 std::vector<OpenMesh::FPropHandleT<Vector4>>& vec4Props ) {
void copyNormal(HalfedgeHandle input_heh, HalfedgeHandle copy_heh)
void copyNormalFromFace(FaceHandle fh, HalfedgeHandle heh, OpenMesh::FPropHandleT< Normal > fProp)
void clearProps(std::vector< OpenMesh::FPropHandleT< T >> &props)
void createNormalPropOnFaces(OpenMesh::FPropHandleT< Normal > &fProp)
void set_normal(VertexHandle vh, FaceHandle fh, const Normal &n)
void interpolateProps(HalfedgeHandle in_a, HalfedgeHandle in_b, HalfedgeHandle out, Scalar f, const std::vector< OpenMesh::HPropHandleT< T >> &props)
const OpenMesh::HPropHandleT< Index > & getInputTriangleMeshIndexPropHandle() const
const Normal & normal(VertexHandle vh, FaceHandle fh) const
const OpenMesh::HPropHandleT< Index > & getOutputTriangleMeshIndexPropHandle() const
void copyAllProps(HalfedgeHandle input_heh, HalfedgeHandle copy_heh)
void copyAllPropsFromFace(FaceHandle fh, HalfedgeHandle heh, OpenMesh::FPropHandleT< Normal > normalProp, std::vector< OpenMesh::FPropHandleT< Scalar >> &floatProps, std::vector< OpenMesh::FPropHandleT< Vector2 >> &vec2Props, std::vector< OpenMesh::FPropHandleT< Vector3 >> &vec3Props, std::vector< OpenMesh::FPropHandleT< Vector4 >> &vec4Props)
void interpolateAllProps(HalfedgeHandle in_a, HalfedgeHandle in_b, HalfedgeHandle out, Scalar f)
void createAllPropsOnFaces(OpenMesh::FPropHandleT< Normal > &normalProp, std::vector< OpenMesh::FPropHandleT< Scalar >> &floatProps, std::vector< OpenMesh::FPropHandleT< Vector2 >> &vec2Props, std::vector< OpenMesh::FPropHandleT< Vector3 >> &vec3Props, std::vector< OpenMesh::FPropHandleT< Vector4 >> &vec4Props)
void updateTriangleMesh(Ra::Core::Geometry::TriangleMesh &mesh)
EIGEN_MAKE_ALIGNED_OPERATOR_NEW TopologicalMesh(const Ra::Core::Geometry::TriangleMesh &triMesh, NonManifoldFaceCommand command)
void copyPropsFromFace(FaceHandle fh, HalfedgeHandle heh, const std::vector< OpenMesh::FPropHandleT< T >> &fProps, const std::vector< OpenMesh::HPropHandleT< T >> &hProps)
HalfedgeHandle halfedge_handle(VertexHandle vh, FaceHandle fh) const
void interpolateAllPropsOnFaces(FaceHandle fh, OpenMesh::FPropHandleT< Normal > normalProp, std::vector< OpenMesh::FPropHandleT< Scalar >> &floatProps, std::vector< OpenMesh::FPropHandleT< Vector2 >> &vec2Props, std::vector< OpenMesh::FPropHandleT< Vector3 >> &vec3Props, std::vector< OpenMesh::FPropHandleT< Vector4 >> &vec4Props)
void interpolateNormal(HalfedgeHandle in_a, HalfedgeHandle in_b, HalfedgeHandle out, Scalar f)
void createPropsOnFaces(const std::vector< OpenMesh::HPropHandleT< T >> &input, std::vector< OpenMesh::FPropHandleT< T >> &output)
void copyProps(HalfedgeHandle input_heh, HalfedgeHandle copy_heh, const std::vector< OpenMesh::HPropHandleT< T >> &props)
void interpolatePropsOnFaces(FaceHandle fh, const std::vector< OpenMesh::HPropHandleT< T >> &hProps, const std::vector< OpenMesh::FPropHandleT< T >> &fProps)
void interpolateNormalOnFaces(FaceHandle fh, OpenMesh::FPropHandleT< Normal > fProp)
void propagate_normal_to_halfedges(VertexHandle vh)
void clearProp(OpenMesh::FPropHandleT< Normal > &fProp)
void clearAllProps(OpenMesh::FPropHandleT< Normal > &normalProp, std::vector< OpenMesh::FPropHandleT< Scalar >> &floatProps, std::vector< OpenMesh::FPropHandleT< Vector2 >> &vec2Props, std::vector< OpenMesh::FPropHandleT< Vector3 >> &vec3Props, std::vector< OpenMesh::FPropHandleT< Vector4 >> &vec4Props)