Radium Engine  1.5.0
TopologicalMesh.hpp
1 #pragma once
2 
3 #include <Core/RaCore.hpp>
4 
5 #include <Core/Containers/VectorArray.hpp>
6 #include <Core/Geometry/OpenMesh.hpp>
7 #include <Core/Geometry/StandardAttribNames.hpp>
8 #include <Core/Geometry/TriangleMesh.hpp>
9 #include <Core/Types.hpp>
10 #include <Core/Utils/Index.hpp>
11 #include <Core/Utils/StdOptional.hpp>
12 
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>
18 
19 #include <Eigen/Core>
20 #include <Eigen/Geometry>
21 
22 #include <set>
23 #include <typeinfo>
24 #include <unordered_map>
25 
26 namespace Ra {
27 namespace Core {
28 namespace Geometry {
29 namespace deprecated {
30 using namespace Utils; // log, AttribXXX
31 
35 struct TopologicalMeshTraits : OpenMesh::DefaultTraits {
36  using Point = Ra::Core::Vector3;
37  using Normal = Ra::Core::Vector3;
38 
39  VertexAttributes( OpenMesh::Attributes::Status | OpenMesh::Attributes::Normal );
40  FaceAttributes( OpenMesh::Attributes::Status | OpenMesh::Attributes::Normal );
41  EdgeAttributes( OpenMesh::Attributes::Status );
42  // Add OpenMesh::Attributes::PrevHalfedge for efficiency ?
43  HalfedgeAttributes( OpenMesh::Attributes::Status | OpenMesh::Attributes::Normal );
44 };
45 
56 class RA_CORE_API TopologicalMesh : public OpenMesh::PolyMesh_ArrayKernelT<TopologicalMeshTraits>
57 {
58  private:
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;
63 
64  public:
65  EIGEN_MAKE_ALIGNED_OPERATOR_NEW
66 
79  template <typename NonManifoldFaceCommand>
80  explicit TopologicalMesh( const Ra::Core::Geometry::TriangleMesh& triMesh,
81  NonManifoldFaceCommand command );
82 
87  explicit TopologicalMesh( const Ra::Core::Geometry::TriangleMesh& triMesh );
88 
92  explicit TopologicalMesh();
93 
98  TriangleMesh toTriangleMesh();
99 
105  void updateTriangleMesh( Ra::Core::Geometry::TriangleMesh& mesh );
106 
107  // import other version of halfedge_handle method
108  using base::halfedge_handle;
109 
114  inline HalfedgeHandle halfedge_handle( VertexHandle vh, FaceHandle fh ) const;
115 
120  [[deprecated]] inline const Normal& normal( VertexHandle vh, FaceHandle fh ) const;
121 
126  [[deprecated]] void set_normal( VertexHandle vh, FaceHandle fh, const Normal& n );
127 
130  using base::normal;
131  using base::set_normal;
133 
140  [[deprecated]] void propagate_normal_to_halfedges( VertexHandle vh );
141 
146  inline const OpenMesh::HPropHandleT<Index>& getInputTriangleMeshIndexPropHandle() const;
147 
153  inline const OpenMesh::HPropHandleT<Index>& getOutputTriangleMeshIndexPropHandle() const;
154 
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;
169 
175 
181  inline void createNormalPropOnFaces( OpenMesh::FPropHandleT<Normal>& fProp );
182 
187  inline void clearProp( OpenMesh::FPropHandleT<Normal>& fProp );
188 
192  inline void copyNormal( HalfedgeHandle input_heh, HalfedgeHandle copy_heh );
193 
197  inline void
198  copyNormalFromFace( FaceHandle fh, HalfedgeHandle heh, OpenMesh::FPropHandleT<Normal> fProp );
199 
203  inline void
204  interpolateNormal( HalfedgeHandle in_a, HalfedgeHandle in_b, HalfedgeHandle out, Scalar f );
205 
209  inline void interpolateNormalOnFaces( FaceHandle fh, OpenMesh::FPropHandleT<Normal> fProp );
211 
217 
223  template <typename T>
224  void createPropsOnFaces( const std::vector<OpenMesh::HPropHandleT<T>>& input,
225  std::vector<OpenMesh::FPropHandleT<T>>& output );
226 
231  template <typename T>
232  void clearProps( std::vector<OpenMesh::FPropHandleT<T>>& props );
233 
237  template <typename T>
238  void copyProps( HalfedgeHandle input_heh,
239  HalfedgeHandle copy_heh,
240  const std::vector<OpenMesh::HPropHandleT<T>>& props );
241 
246  template <typename T>
247  void copyPropsFromFace( FaceHandle fh,
248  HalfedgeHandle heh,
249  const std::vector<OpenMesh::FPropHandleT<T>>& fProps,
250  const std::vector<OpenMesh::HPropHandleT<T>>& hProps );
251 
255  template <typename T>
256  void interpolateProps( HalfedgeHandle in_a,
257  HalfedgeHandle in_b,
258  HalfedgeHandle out,
259  Scalar f,
260  const std::vector<OpenMesh::HPropHandleT<T>>& props );
261 
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 );
271 
276 
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 );
288 
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 );
298 
302  inline void copyAllProps( HalfedgeHandle input_heh, HalfedgeHandle copy_heh );
303 
310  inline void copyAllPropsFromFace( FaceHandle fh,
311  HalfedgeHandle heh,
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 );
317 
321  inline void
322  interpolateAllProps( HalfedgeHandle in_a, HalfedgeHandle in_b, HalfedgeHandle out, Scalar f );
323 
330  inline void
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 );
338 
343 
355  bool splitEdge( TopologicalMesh::EdgeHandle eh, Scalar f );
356  bool splitEdgeWedge( TopologicalMesh::EdgeHandle eh, Scalar f );
357 
359 
360  private:
361  template <typename T>
362  using HandleAndValueVector =
363  std::vector<std::pair<AttribHandle<T>, T>,
364  Eigen::aligned_allocator<std::pair<AttribHandle<T>, T>>>;
365 
366  template <typename T>
367  using PropPair = std::pair<AttribHandle<T>, OpenMesh::HPropHandleT<T>>;
368 
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 );
374 
375  template <typename T>
376  inline void addAttribPairToTopo( const TriangleMesh& triMesh,
378  std::vector<PropPair<T>>& vprop,
379  std::vector<OpenMesh::HPropHandleT<T>>& pph );
380 
381  void split_copy( EdgeHandle _eh, VertexHandle _vh );
382  void split( EdgeHandle _eh, VertexHandle _vh );
383 
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;
391 
392  friend class TMOperations;
393 };
394 
395 template <typename NonManifoldFaceCommand>
396 inline TopologicalMesh::TopologicalMesh( const TriangleMesh& triMesh,
397  NonManifoldFaceCommand command ) :
398  TopologicalMesh() {
399 
400  LOG( logINFO ) << "TopologicalMesh: load triMesh with " << triMesh.getIndices().size()
401  << " faces and " << triMesh.vertices().size() << " vertices.";
402 
403  struct hash_vec {
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;
409  }
410  };
411  // use a hashmap for fast search of existing vertex position
412  using VertexMap = std::unordered_map<Vector3, TopologicalMesh::VertexHandle, hash_vec>;
413  VertexMap vertexHandles;
414 
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;
419 
420  // loop over all attribs and build correspondance pair
421  triMesh.vertexAttribs().for_each_attrib(
422  [&triMesh, this, &vprop_float, &vprop_vec2, &vprop_vec3, &vprop_vec4]( const auto& attr ) {
423  // skip builtin attribs
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 );
434  else
435  LOG( logWARNING )
436  << "Warning, mesh attribute " << attr->getName()
437  << " type is not supported (only float, vec2, vec3 nor vec4 are supported)";
438  }
439  } );
440 
441  size_t num_triangles = triMesh.getIndices().size();
442 
443  command.initialize( triMesh );
444 
445  const bool hasNormals = !triMesh.normals().empty();
446  if ( !hasNormals ) {
447  release_face_normals();
448  release_vertex_normals();
449  release_halfedge_normals();
450  }
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];
459 
460  typename VertexMap::iterator vtr = vertexHandles.find( p );
461 
462  TopologicalMesh::VertexHandle vh;
463  if ( vtr == vertexHandles.end() ) {
464  vh = add_vertex( p );
465  vertexHandles.insert( vtr, typename VertexMap::value_type( p, vh ) );
466  }
467  else { vh = vtr->second; }
468 
469  face_vhandles[j] = vh;
470  face_vertexIndex[j] = inMeshVertexIndex;
471  if ( hasNormals ) face_normals[j] = triMesh.normals()[inMeshVertexIndex];
472  }
473 
474  TopologicalMesh::FaceHandle fh;
475 
476  // skip 2 vertex face
477  if ( face_vhandles.size() > 2 ) fh = add_face( face_vhandles );
478  // x-----------------------------------------------------------------------------------x
479 
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] );
489  }
490  }
491  else { command.process( face_vhandles ); }
492  face_vhandles.clear();
493  face_normals.clear();
494  face_vertexIndex.clear();
495  }
496  command.postProcess( *this );
497 
498  // grabage collect since some wedge might already be deleted
499  garbage_collection();
500 }
501 
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 ) );
512  pph.push_back( oh );
513  }
514  else {
515  LOG( logWARNING ) << "[TopologicalMesh] Skip badly sized attribute " << attr->getName()
516  << ".";
517  }
518 }
519 
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];
527  }
528 }
529 
530 inline const TopologicalMesh::Normal& TopologicalMesh::normal( VertexHandle vh,
531  FaceHandle fh ) const {
532  // find halfedge that point to vh and member of fh
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 };
536  return dummy;
537  }
538  return normal( halfedge_handle( vh, fh ) );
539 }
540 
541 inline void TopologicalMesh::set_normal( VertexHandle vh, FaceHandle fh, const Normal& n ) {
542  if ( !has_halfedge_normals() ) {
543  LOG( logERROR ) << "TopologicalMesh has no normals, nothing set";
544  return;
545  }
546 
547  set_normal( halfedge_handle( vh, fh ), n );
548 }
549 
550 inline void TopologicalMesh::propagate_normal_to_halfedges( VertexHandle vh ) {
551  if ( !has_halfedge_normals() ) {
552  LOG( logERROR ) << "TopologicalMesh has no normals, nothing set";
553  return;
554  }
555  for ( VertexIHalfedgeIter vih_it = vih_iter( vh ); vih_it.is_valid(); ++vih_it ) {
556  set_normal( *vih_it, normal( vh ) );
557  }
558 }
559 
560 inline TopologicalMesh::HalfedgeHandle TopologicalMesh::halfedge_handle( VertexHandle vh,
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; }
564  }
565  CORE_ASSERT( false, "vh is not a vertex of face fh" );
566  return HalfedgeHandle();
567 }
568 
569 inline const OpenMesh::HPropHandleT<TopologicalMesh::Index>&
571  return m_inputTriangleMeshIndexPph;
572 }
573 
574 inline const OpenMesh::HPropHandleT<TopologicalMesh::Index>&
576  return m_outputTriangleMeshIndexPph;
577 }
578 
579 inline const std::vector<OpenMesh::HPropHandleT<Scalar>>&
580 TopologicalMesh::getFloatPropsHandles() const {
581  return m_floatPph;
582 }
583 
584 inline const std::vector<OpenMesh::HPropHandleT<Vector2>>&
585 TopologicalMesh::getVector2PropsHandles() const {
586  return m_vec2Pph;
587 }
588 
589 inline const std::vector<OpenMesh::HPropHandleT<Vector3>>&
590 TopologicalMesh::getVector3PropsHandles() const {
591  return m_vec3Pph;
592 }
593 
594 inline const std::vector<OpenMesh::HPropHandleT<Vector4>>&
595 TopologicalMesh::getVector4PropsHandles() const {
596  return m_vec4Pph;
597 }
598 
599 inline void TopologicalMesh::createNormalPropOnFaces( OpenMesh::FPropHandleT<Normal>& fProp ) {
600  if ( !has_halfedge_normals() ) {
601  LOG( logERROR ) << "TopologicalMesh has no normals, nothing set";
602  return;
603  }
604  auto nph = halfedge_normals_pph();
605  add_property( fProp, property( nph ).name() + "_subdiv_copy_F" );
606 }
607 
608 inline void TopologicalMesh::clearProp( OpenMesh::FPropHandleT<Normal>& fProp ) {
609  remove_property( fProp );
610 }
611 
612 inline void TopologicalMesh::copyNormal( HalfedgeHandle input_heh, HalfedgeHandle copy_heh ) {
613  if ( !has_halfedge_normals() ) {
614  LOG( logERROR ) << "TopologicalMesh has no normals, nothing set";
615  return;
616  }
617  auto nph = halfedge_normals_pph();
618  property( nph, copy_heh ) = property( nph, input_heh );
619 }
620 
621 inline void TopologicalMesh::copyNormalFromFace( FaceHandle fh,
622  HalfedgeHandle heh,
623  OpenMesh::FPropHandleT<Normal> fProp ) {
624  if ( !has_halfedge_normals() ) {
625  LOG( logERROR ) << "TopologicalMesh has no normals, nothing set";
626  return;
627  }
628  auto nph = halfedge_normals_pph();
629  property( nph, heh ) = property( fProp, fh );
630 }
631 
632 inline void TopologicalMesh::interpolateNormal( HalfedgeHandle in_a,
633  HalfedgeHandle in_b,
634  HalfedgeHandle out,
635  Scalar f ) {
636  auto nph = halfedge_normals_pph();
637  property( nph, out ) =
638  ( ( 1 - f ) * property( nph, in_a ) + f * property( nph, in_b ) ).normalized();
639 }
640 
641 inline void TopologicalMesh::interpolateNormalOnFaces( FaceHandle fh,
642  OpenMesh::FPropHandleT<Normal> fProp ) {
643  if ( !has_halfedge_normals() ) {
644  LOG( logERROR ) << "TopologicalMesh has no normals, nothing set";
645  return;
646  }
647  auto nph = halfedge_normals_pph();
648 
649  // init sum to first
650  auto heh = halfedge_handle( fh );
651  property( fProp, fh ) = property( nph, heh );
652  heh = next_halfedge_handle( heh );
653 
654  // sum others
655  for ( size_t i = 1; i < valence( fh ); ++i ) {
656  property( fProp, fh ) += property( nph, heh );
657  heh = next_halfedge_handle( heh );
658  }
659 
660  // normalize
661  property( fProp, fh ) = property( fProp, fh ).normalized();
662 }
663 
664 template <typename T>
665 void TopologicalMesh::createPropsOnFaces( const std::vector<OpenMesh::HPropHandleT<T>>& input,
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_ );
672  }
673 }
674 
675 template <typename T>
676 void TopologicalMesh::clearProps( std::vector<OpenMesh::FPropHandleT<T>>& props ) {
677  for ( auto& oh : props ) {
678  remove_property( oh );
679  }
680  props.clear();
681 }
682 
683 template <typename T>
684 void TopologicalMesh::copyProps( HalfedgeHandle input_heh,
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 );
689  }
690 }
691 
692 template <typename T>
694  HalfedgeHandle heh,
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 ) {
698  auto hp = hProps[i];
699  auto fp = fProps[i];
700  property( hp, heh ) = property( fp, fh );
701  }
702 }
703 
704 template <typename T>
705 void TopologicalMesh::interpolateProps( HalfedgeHandle in_a,
706  HalfedgeHandle in_b,
707  HalfedgeHandle out,
708  Scalar f,
709  const std::vector<OpenMesh::HPropHandleT<T>>& props ) {
710  // interpolate properties
711  for ( const auto& oh : props ) {
712  property( oh, out ) = ( 1 - f ) * property( oh, in_a ) + f * property( oh, in_b );
713  }
714 }
715 
716 template <typename T>
718  FaceHandle fh,
719  const std::vector<OpenMesh::HPropHandleT<T>>& hProps,
720  const std::vector<OpenMesh::FPropHandleT<T>>& fProps ) {
721  auto heh = halfedge_handle( fh );
722  const size_t v = valence( fh );
723 
724  // init sum to first
725  for ( size_t j = 0; j < fProps.size(); ++j ) {
726  auto hp = hProps[j];
727  auto fp = fProps[j];
728  property( fp, fh ) = property( hp, heh );
729  }
730  heh = next_halfedge_handle( heh );
731  // sum others
732  for ( size_t i = 1; i < v; ++i ) {
733  for ( size_t j = 0; j < fProps.size(); ++j ) {
734  auto hp = hProps[j];
735  auto fp = fProps[j];
736  property( fp, fh ) += property( hp, heh );
737  }
738  heh = next_halfedge_handle( heh );
739  }
740  // normalize
741  for ( size_t j = 0; j < fProps.size(); ++j ) {
742  auto fp = fProps[j];
743  property( fp, fh ) = property( fp, fh ) / v;
744  }
745 }
746 
747 inline void
748 TopologicalMesh::createAllPropsOnFaces( OpenMesh::FPropHandleT<Normal>& normalProp,
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 ) {
753  createNormalPropOnFaces( normalProp );
754  createPropsOnFaces( getFloatPropsHandles(), floatProps );
755  createPropsOnFaces( getVector2PropsHandles(), vec2Props );
756  createPropsOnFaces( getVector3PropsHandles(), vec3Props );
757  createPropsOnFaces( getVector4PropsHandles(), vec4Props );
758 }
759 
760 inline void
761 TopologicalMesh::clearAllProps( OpenMesh::FPropHandleT<Normal>& normalProp,
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 ) {
766  clearProp( normalProp );
767  clearProps( floatProps );
768  clearProps( vec2Props );
769  clearProps( vec3Props );
770  clearProps( vec4Props );
771 }
772 
773 inline void TopologicalMesh::copyAllProps( HalfedgeHandle input_heh, HalfedgeHandle copy_heh ) {
774  copyNormal( input_heh, copy_heh );
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() );
779 }
780 
781 inline void
783  HalfedgeHandle heh,
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 ) {
789  copyNormalFromFace( fh, heh, normalProp );
790  copyPropsFromFace( fh, heh, floatProps, getFloatPropsHandles() );
791  copyPropsFromFace( fh, heh, vec2Props, getVector2PropsHandles() );
792  copyPropsFromFace( fh, heh, vec3Props, getVector3PropsHandles() );
793  copyPropsFromFace( fh, heh, vec4Props, getVector4PropsHandles() );
794 }
795 
796 inline void TopologicalMesh::interpolateAllProps( HalfedgeHandle in_a,
797  HalfedgeHandle in_b,
798  HalfedgeHandle out,
799  Scalar f ) {
800  interpolateNormal( in_a, in_b, out, f );
801  interpolateProps( in_a, in_b, out, f, getFloatPropsHandles() );
802  interpolateProps( in_a, in_b, out, f, getVector2PropsHandles() );
803  interpolateProps( in_a, in_b, out, f, getVector3PropsHandles() );
804  interpolateProps( in_a, in_b, out, f, getVector4PropsHandles() );
805 }
806 
808  FaceHandle fh,
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 ) {
814  interpolateNormalOnFaces( fh, normalProp );
815  interpolatePropsOnFaces( fh, getFloatPropsHandles(), floatProps );
816  interpolatePropsOnFaces( fh, getVector2PropsHandles(), vec2Props );
817  interpolatePropsOnFaces( fh, getVector3PropsHandles(), vec3Props );
818  interpolatePropsOnFaces( fh, getVector4PropsHandles(), vec4Props );
819 }
820 
821 } // namespace deprecated
822 } // namespace Geometry
823 } // namespace Core
824 } // namespace Ra
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 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)
Definition: Cage.cpp:3