41 #ifndef PCL_GEOMETRY_MESH_BASE_H
42 #define PCL_GEOMETRY_MESH_BASE_H
46 #include <pcl/geometry/boost.h>
47 #include <pcl/geometry/eigen.h>
48 #include <pcl/geometry/mesh_circulators.h>
49 #include <pcl/geometry/mesh_indices.h>
50 #include <pcl/geometry/mesh_elements.h>
51 #include <pcl/geometry/mesh_traits.h>
52 #include <pcl/point_cloud.h>
58 #ifdef PCL_GEOMETRY_MESH_BASE_TEST_DELETE_FACE_MANIFOLD_2
63 bool g_pcl_geometry_mesh_base_test_delete_face_manifold_2_success;
76 template <
class MeshT>
97 template <
class DerivedT,
class MeshTraitsT,
class MeshTagT>
103 typedef boost::shared_ptr <Self>
Ptr;
121 typedef boost::integral_constant <bool, !boost::is_same <VertexData , pcl::geometry::NoData>::value>
HasVertexData;
122 typedef boost::integral_constant <bool, !boost::is_same <HalfEdgeData, pcl::geometry::NoData>::value>
HasHalfEdgeData;
123 typedef boost::integral_constant <bool, !boost::is_same <EdgeData , pcl::geometry::NoData>::value>
HasEdgeData;
124 typedef boost::integral_constant <bool, !boost::is_same <FaceData , pcl::geometry::NoData>::value>
HasFaceData;
154 : vertex_data_cloud_ (),
155 half_edge_data_cloud_ (),
166 delete_faces_vertex_ (),
167 delete_faces_face_ ()
182 vertices_.push_back (
Vertex ());
183 this->
addData (vertex_data_cloud_, vertex_data, HasVertexData ());
184 return (VertexIndex (static_cast <int> (this->
sizeVertices () - 1)));
197 const FaceData& face_data = FaceData (),
198 const EdgeData& edge_data = EdgeData (),
199 const HalfEdgeData& half_edge_data = HalfEdgeData ())
202 return (static_cast <Derived*> (
this)->addFaceImpl (vertices, face_data, edge_data, half_edge_data));
211 assert (this->
isValid (idx_vertex));
212 if (this->
isDeleted (idx_vertex))
return;
214 delete_faces_vertex_.clear ();
216 const FaceAroundVertexCirculator circ_end = circ;
223 }
while (++circ!=circ_end);
225 for (FaceIndices::const_iterator it = delete_faces_vertex_.begin (); it!=delete_faces_vertex_.end (); ++it)
237 assert (this->
isValid (idx_he));
254 assert (this->
isValid (idx_edge));
265 assert (this->
isValid (idx_face));
278 const VertexIndices new_vertex_indices =
279 this->remove <Vertices, VertexDataCloud, VertexIndices, HasVertexData>
280 (vertices_, vertex_data_cloud_);
281 const HalfEdgeIndices new_half_edge_indices =
282 this->remove <HalfEdges, HalfEdgeDataCloud, HalfEdgeIndices, HasHalfEdgeData>
283 (half_edges_, half_edge_data_cloud_);
284 const FaceIndices new_face_indices =
285 this->remove <Faces, FaceDataCloud, FaceIndices, HasFaceData>
286 (faces_, face_data_cloud_);
289 if (HasEdgeData::value)
294 HalfEdgeIndices::const_iterator it_ind = new_half_edge_indices.begin ();
295 HalfEdgeIndices::const_iterator it_ind_end = new_half_edge_indices.end ();
297 for (; it_ind!=it_ind_end; it_ind+=2, ++it_ed_old)
299 if (it_ind->isValid ())
301 *it_ed_new++ = *it_ed_old;
308 for (
VertexIterator it = vertices_.begin (); it!=vertices_.end (); ++it)
310 if (it->idx_outgoing_half_edge_.isValid ())
312 it->idx_outgoing_half_edge_ = new_half_edge_indices [it->idx_outgoing_half_edge_.get ()];
316 for (
HalfEdgeIterator it = half_edges_.begin (); it!=half_edges_.end (); ++it)
318 it->idx_terminating_vertex_ = new_vertex_indices [it->idx_terminating_vertex_.get ()];
319 it->idx_next_half_edge_ = new_half_edge_indices [it->idx_next_half_edge_.get ()];
320 it->idx_prev_half_edge_ = new_half_edge_indices [it->idx_prev_half_edge_.get ()];
321 if (it->idx_face_.isValid ())
323 it->idx_face_ = new_face_indices [it->idx_face_.get ()];
327 for (
FaceIterator it = faces_.begin (); it!=faces_.end (); ++it)
329 it->idx_inner_half_edge_ = new_half_edge_indices [it->idx_inner_half_edge_.get ()];
341 assert (this->
isValid (idx_vertex));
342 return (this->
getVertex (idx_vertex).idx_outgoing_half_edge_);
349 assert (this->
isValid (idx_vertex));
361 assert (this->
isValid (idx_half_edge));
362 return (this->
getHalfEdge (idx_half_edge).idx_terminating_vertex_);
369 assert (this->
isValid (idx_half_edge));
377 assert (this->
isValid (idx_half_edge));
379 return (HalfEdgeIndex (idx_half_edge.
get () & 1 ? idx_half_edge.
get () - 1 : idx_half_edge.
get () + 1));
386 assert (this->
isValid (idx_half_edge));
387 return (this->
getHalfEdge (idx_half_edge).idx_next_half_edge_);
394 assert (this->
isValid (idx_half_edge));
395 return (this->
getHalfEdge (idx_half_edge).idx_prev_half_edge_);
402 assert (this->
isValid (idx_half_edge));
403 return (this->
getHalfEdge (idx_half_edge).idx_face_);
410 assert (this->
isValid (idx_half_edge));
422 assert (this->
isValid (idx_face));
423 return (this->
getFace (idx_face).idx_inner_half_edge_);
430 assert (this->
isValid (idx_face));
439 inline VertexAroundVertexCirculator
442 assert (this->
isValid (idx_vertex));
443 return (VertexAroundVertexCirculator (idx_vertex,
this));
447 inline VertexAroundVertexCirculator
450 assert (this->
isValid (idx_outgoing_half_edge));
451 return (VertexAroundVertexCirculator (idx_outgoing_half_edge,
this));
455 inline OutgoingHalfEdgeAroundVertexCirculator
458 assert (this->
isValid (idx_vertex));
459 return (OutgoingHalfEdgeAroundVertexCirculator (idx_vertex,
this));
463 inline OutgoingHalfEdgeAroundVertexCirculator
466 assert (this->
isValid (idx_outgoing_half_edge));
467 return (OutgoingHalfEdgeAroundVertexCirculator (idx_outgoing_half_edge,
this));
471 inline IncomingHalfEdgeAroundVertexCirculator
474 assert (this->
isValid (idx_vertex));
475 return (IncomingHalfEdgeAroundVertexCirculator (idx_vertex,
this));
479 inline IncomingHalfEdgeAroundVertexCirculator
482 assert (this->
isValid (idx_incoming_half_edge));
483 return (IncomingHalfEdgeAroundVertexCirculator (idx_incoming_half_edge,
this));
487 inline FaceAroundVertexCirculator
490 assert (this->
isValid (idx_vertex));
491 return (FaceAroundVertexCirculator (idx_vertex,
this));
495 inline FaceAroundVertexCirculator
498 assert (this->
isValid (idx_outgoing_half_edge));
499 return (FaceAroundVertexCirculator (idx_outgoing_half_edge,
this));
503 inline VertexAroundFaceCirculator
506 assert (this->
isValid (idx_face));
507 return (VertexAroundFaceCirculator (idx_face,
this));
511 inline VertexAroundFaceCirculator
514 assert (this->
isValid (idx_inner_half_edge));
515 return (VertexAroundFaceCirculator (idx_inner_half_edge,
this));
519 inline InnerHalfEdgeAroundFaceCirculator
522 assert (this->
isValid (idx_face));
523 return (InnerHalfEdgeAroundFaceCirculator (idx_face,
this));
527 inline InnerHalfEdgeAroundFaceCirculator
530 assert (this->
isValid (idx_inner_half_edge));
531 return (InnerHalfEdgeAroundFaceCirculator (idx_inner_half_edge,
this));
535 inline OuterHalfEdgeAroundFaceCirculator
538 assert (this->
isValid (idx_face));
539 return (OuterHalfEdgeAroundFaceCirculator (idx_face,
this));
543 inline OuterHalfEdgeAroundFaceCirculator
546 assert (this->
isValid (idx_inner_half_edge));
547 return (OuterHalfEdgeAroundFaceCirculator (idx_inner_half_edge,
this));
551 inline FaceAroundFaceCirculator
554 assert (this->
isValid (idx_face));
555 return (FaceAroundFaceCirculator (idx_face,
this));
559 inline FaceAroundFaceCirculator
562 assert (this->
isValid (idx_inner_half_edge));
563 return (FaceAroundFaceCirculator (idx_inner_half_edge,
this));
599 for (
unsigned int i=0; i<this->
sizeFaces (); ++i)
616 return (idx_vertex >= VertexIndex (0) && idx_vertex < VertexIndex (
int (vertices_.size ())));
623 return (idx_he >= HalfEdgeIndex (0) && idx_he < HalfEdgeIndex (half_edges_.size ()));
630 return (idx_edge >= EdgeIndex (0) && idx_edge < EdgeIndex (half_edges_.size () / 2));
637 return (idx_face >= FaceIndex (0) && idx_face < FaceIndex (faces_.size ()));
648 assert (this->
isValid (idx_vertex));
656 assert (this->
isValid (idx_he));
664 assert (this->
isValid (idx_edge));
673 assert (this->
isValid (idx_face));
685 assert (this->
isValid (idx_vertex));
697 assert (this->
isValid (idx_vertex));
698 if (this->
isIsolated (idx_vertex))
return (
true);
706 assert (this->
isValid (idx_he));
714 assert (this->
isValid (idx_edge));
722 template <
bool CheckVerticesT>
inline bool
725 assert (this->
isValid (idx_face));
726 return (this->
isBoundary (idx_face, boost::integral_constant <bool, CheckVerticesT> ()));
733 assert (this->
isValid (idx_face));
734 return (this->
isBoundary (idx_face, boost::true_type ()));
745 assert (this->
isValid (idx_vertex));
746 if (this->
isIsolated (idx_vertex))
return (
true);
747 return (this->
isManifold (idx_vertex, IsManifold ()));
765 return (vertices_.size ());
772 assert (half_edges_.size () % 2 == 0);
773 return (half_edges_.size ());
780 assert (half_edges_.size () % 2 == 0);
781 return (half_edges_.size () / 2);
788 return (faces_.size ());
806 return (vertices_.empty ());
813 return (half_edges_.empty ());
820 return (faces_.empty ());
831 vertices_.reserve (n);
832 this->
reserveData (vertex_data_cloud_, n, HasVertexData ());
839 half_edges_.reserve (2*n);
840 this->
reserveData (half_edge_data_cloud_, 2*n, HasHalfEdgeData ());
841 this->
reserveData (edge_data_cloud_ , n, HasEdgeData ());
849 this->
reserveData (face_data_cloud_, n, HasFaceData ());
860 vertices_.resize (n);
861 this->
resizeData (vertex_data_cloud_, n, data, HasVertexData ());
867 const EdgeData& edge_data = EdgeData (),
868 const HalfEdgeData he_data = HalfEdgeData ())
870 half_edges_.resize (2*n);
871 this->
resizeData (half_edge_data_cloud_, 2*n, he_data , HasHalfEdgeData ());
872 this->
resizeData (edge_data_cloud_ , n, edge_data, HasEdgeData ());
880 this->
resizeData (face_data_cloud_, n, data, HasFaceData ());
892 half_edges_.clear ();
895 this->
clearData (vertex_data_cloud_ , HasVertexData ());
896 this->
clearData (half_edge_data_cloud_, HasHalfEdgeData ());
897 this->
clearData (edge_data_cloud_ , HasEdgeData ());
898 this->
clearData (face_data_cloud_ , HasFaceData ());
908 inline VertexDataCloud&
911 return (vertex_data_cloud_);
915 inline VertexDataCloud
918 return (vertex_data_cloud_);
928 if (vertex_data_cloud.
size () == vertex_data_cloud_.
size ())
930 vertex_data_cloud_ = vertex_data_cloud;
946 inline HalfEdgeDataCloud&
949 return (half_edge_data_cloud_);
953 inline HalfEdgeDataCloud
956 return (half_edge_data_cloud_);
966 if (half_edge_data_cloud.
size () == half_edge_data_cloud_.
size ())
968 half_edge_data_cloud_ = half_edge_data_cloud;
984 inline EdgeDataCloud&
987 return (edge_data_cloud_);
994 return (edge_data_cloud_);
1004 if (edge_data_cloud.
size () == edge_data_cloud_.
size ())
1006 edge_data_cloud_ = edge_data_cloud;
1022 inline FaceDataCloud&
1025 return (face_data_cloud_);
1029 inline FaceDataCloud
1032 return (face_data_cloud_);
1042 if (face_data_cloud.
size () == face_data_cloud_.
size ())
1044 face_data_cloud_ = face_data_cloud;
1063 if (HasVertexData::value)
1065 assert (&vertex_data >= &vertex_data_cloud_.
front () && &vertex_data <= &vertex_data_cloud_.
back ());
1066 return (VertexIndex (std::distance (&vertex_data_cloud_.
front (), &vertex_data)));
1070 return (VertexIndex ());
1075 inline HalfEdgeIndex
1078 if (HasHalfEdgeData::value)
1080 assert (&half_edge_data >= &half_edge_data_cloud_.
front () && &half_edge_data <= &half_edge_data_cloud_.
back ());
1081 return (HalfEdgeIndex (std::distance (&half_edge_data_cloud_.
front (), &half_edge_data)));
1085 return (HalfEdgeIndex ());
1093 if (HasEdgeData::value)
1095 assert (&edge_data >= &edge_data_cloud_.
front () && &edge_data <= &edge_data_cloud_.
back ());
1096 return (EdgeIndex (std::distance (&edge_data_cloud_.
front (), &edge_data)));
1100 return (EdgeIndex ());
1108 if (HasFaceData::value)
1110 assert (&face_data >= &face_data_cloud_.
front () && &face_data <= &face_data_cloud_.
back ());
1111 return (FaceIndex (std::distance (&face_data_cloud_.
front (), &face_data)));
1115 return (FaceIndex ());
1145 const FaceData& face_data,
1146 const EdgeData& edge_data,
1147 const HalfEdgeData& half_edge_data)
1149 const int n =
static_cast<int> (vertices.size ());
1150 if (n < 3)
return (FaceIndex ());
1153 inner_he_.resize (n);
1154 free_he_.resize (n);
1156 make_adjacent_.resize (n);
1160 if (!this->
checkTopology1 (vertices [i], vertices [(i+1)%n], inner_he_ [i], is_new_ [i], IsManifold ()))
1162 return (FaceIndex ());
1168 if (!this->
checkTopology2 (inner_he_ [i], inner_he_ [j], is_new_ [i], is_new_ [j], this->
isIsolated (vertices [j]), make_adjacent_ [i], free_he_ [i], IsManifold ()))
1170 return (FaceIndex ());
1175 if (!IsManifold::value)
1179 if (make_adjacent_ [i])
1181 this->
makeAdjacent (inner_he_ [i], inner_he_ [(i+1)%n], free_he_ [i]);
1191 inner_he_ [i] = this->
addEdge (vertices [i], vertices [(i+1)%n], half_edge_data, edge_data);
1199 if ( is_new_ [i] && is_new_ [j]) this->
connectNewNew (inner_he_ [i], inner_he_ [j], vertices [j], IsManifold ());
1200 else if ( is_new_ [i] && !is_new_ [j]) this->
connectNewOld (inner_he_ [i], inner_he_ [j], vertices [j]);
1201 else if (!is_new_ [i] && is_new_ [j]) this->
connectOldNew (inner_he_ [i], inner_he_ [j], vertices [j]);
1202 else this->
connectOldOld (inner_he_ [i], inner_he_ [j], vertices [j], IsManifold ());
1204 return (this->
connectFace (inner_he_, face_data));
1220 const VertexIndex& idx_v_b,
1221 const HalfEdgeData& he_data,
1222 const EdgeData& edge_data)
1224 half_edges_.push_back (HalfEdge (idx_v_b));
1225 half_edges_.push_back (HalfEdge (idx_v_a));
1227 this->
addData (half_edge_data_cloud_, he_data , HasHalfEdgeData ());
1228 this->
addData (half_edge_data_cloud_, he_data , HasHalfEdgeData ());
1229 this->
addData (edge_data_cloud_ , edge_data, HasEdgeData ());
1231 return (HalfEdgeIndex (static_cast <int> (half_edges_.size () - 2)));
1247 const VertexIndex& idx_v_b,
1248 HalfEdgeIndex& idx_he_ab,
1249 std::vector <bool>::reference is_new_ab,
1250 boost::true_type )
const
1253 if (this->
isIsolated (idx_v_a))
return (
true);
1257 if (!this->
isBoundary (idx_he_ab))
return (
false);
1265 const VertexIndex& idx_v_b,
1266 HalfEdgeIndex& idx_he_ab,
1267 std::vector <bool>::reference is_new_ab,
1268 boost::false_type )
const
1271 if (this->
isIsolated (idx_v_a))
return (
true);
1275 const VertexAroundVertexCirculator circ_end = circ;
1282 if (!this->
isBoundary (idx_he_ab))
return (
false);
1287 }
while (++circ!=circ_end);
1295 const HalfEdgeIndex& ,
1296 const bool is_new_ab,
1297 const bool is_new_bc,
1298 const bool is_isolated_b,
1299 std::vector <bool>::reference ,
1301 boost::true_type )
const
1303 if (is_new_ab && is_new_bc && !is_isolated_b)
return (
false);
1318 const HalfEdgeIndex& idx_he_bc,
1319 const bool is_new_ab,
1320 const bool is_new_bc,
1322 std::vector <bool>::reference make_adjacent_ab_bc,
1323 HalfEdgeIndex& idx_free_half_edge,
1324 boost::false_type )
const
1326 if (is_new_ab || is_new_bc)
1328 make_adjacent_ab_bc =
false;
1334 make_adjacent_ab_bc =
false;
1338 make_adjacent_ab_bc =
true;
1358 const HalfEdgeIndex& idx_he_bc,
1359 HalfEdgeIndex& idx_free_half_edge)
1382 const FaceData& face_data)
1384 faces_.push_back (Face (inner_he.back ()));
1385 this->
addData (face_data_cloud_, face_data, HasFaceData ());
1387 const FaceIndex idx_face (static_cast <int> (this->
sizeFaces () - 1));
1389 for (HalfEdgeIndices::const_iterator it=inner_he.begin (); it!=inner_he.end (); ++it)
1400 const HalfEdgeIndex& idx_he_bc)
1409 const HalfEdgeIndex& idx_he_bc,
1410 const VertexIndex& idx_v_b,
1425 const HalfEdgeIndex& idx_he_bc,
1426 const VertexIndex& idx_v_b,
1431 this->
connectNewNew (idx_he_ab, idx_he_bc, idx_v_b, boost::true_type ());
1451 const HalfEdgeIndex& idx_he_bc,
1452 const VertexIndex& idx_v_b)
1466 const HalfEdgeIndex& idx_he_bc,
1467 const VertexIndex& idx_v_b)
1481 const HalfEdgeIndex& ,
1482 const VertexIndex& ,
1490 const HalfEdgeIndex& idx_he_bc,
1491 const VertexIndex& idx_v_b,
1497 if (idx_he_b_out == idx_he_bc)
1500 const OutgoingHalfEdgeAroundVertexCirculator circ_end = circ;
1502 while (++circ!=circ_end)
1518 template <
class DataT>
1526 template <
class DataT>
1541 assert (this->
isValid (idx_face));
1542 delete_faces_face_.clear ();
1543 delete_faces_face_.push_back (idx_face);
1545 while (!delete_faces_face_.empty ())
1547 const FaceIndex idx_face_cur = delete_faces_face_.back ();
1548 delete_faces_face_.pop_back ();
1551 this->
deleteFace (idx_face_cur, boost::false_type ());
1560 assert (this->
isValid (idx_face));
1565 is_boundary_.clear ();
1567 const InnerHalfEdgeAroundFaceCirculator circ_end = circ;
1572 }
while (++circ != circ_end);
1573 assert (inner_he_.size () >= 3);
1575 const int n = static_cast <
int> (inner_he_.size ());
1578 if (IsManifold::value)
1580 for (
int i=0; i<n; ++i)
1583 this->
reconnect (inner_he_ [i], inner_he_ [j], is_boundary_ [i], is_boundary_ [j]);
1585 for (
int i=0; i<n; ++i)
1592 for (
int i=0; i<n; ++i)
1595 this->
reconnect (inner_he_ [i], inner_he_ [j], is_boundary_ [i], is_boundary_ [j]);
1610 const HalfEdgeIndex& idx_he_bc,
1611 const bool is_boundary_ba,
1612 const bool is_boundary_cb)
1618 if (is_boundary_ba && is_boundary_cb)
1622 if (idx_he_cb_next == idx_he_ba)
1635 else if (is_boundary_ba && !is_boundary_cb)
1643 else if (!is_boundary_ba && is_boundary_cb)
1651 this->
reconnectNBNB (idx_he_bc, idx_he_cb, idx_v_b, IsManifold ());
1658 const HalfEdgeIndex& idx_he_cb,
1659 const VertexIndex& idx_v_b,
1670 delete_faces_face_.push_back (this->
getFaceIndex ((circ++).getTargetIndex ()));
1672 #ifdef PCL_GEOMETRY_MESH_BASE_TEST_DELETE_FACE_MANIFOLD_2
1679 pcl::geometry::g_pcl_geometry_mesh_base_test_delete_face_manifold_2_success =
false;
1694 const HalfEdgeIndex& ,
1695 const VertexIndex& idx_v_b,
1712 assert (this->
isValid (idx_vertex));
1720 assert (this->
isValid (idx_he));
1728 assert (this->
isValid (idx_edge));
1737 assert (this->
isValid (idx_face));
1754 template <
class ElementContainerT,
class DataContainerT,
class IndexContainerT,
class HasDataT> IndexContainerT
1755 remove (ElementContainerT& elements, DataContainerT& data_cloud)
1757 typedef typename IndexContainerT::value_type Index;
1758 typedef typename ElementContainerT::value_type Element;
1760 if (HasDataT::value) assert (elements.size () == data_cloud.size ());
1761 else assert (data_cloud.empty ());
1763 IndexContainerT new_indices (elements.size (),
typename IndexContainerT::value_type ());
1764 Index ind_old (0), ind_new (0);
1766 typename ElementContainerT::const_iterator it_e_old = elements.begin ();
1767 typename ElementContainerT::iterator it_e_new = elements.begin ();
1769 typename DataContainerT::const_iterator it_d_old = data_cloud.begin ();
1770 typename DataContainerT::iterator it_d_new = data_cloud.begin ();
1772 typename IndexContainerT::iterator it_ind_new = new_indices.begin ();
1773 typename IndexContainerT::const_iterator it_ind_new_end = new_indices.end ();
1775 while (it_ind_new!=it_ind_new_end)
1779 *it_ind_new = ind_new++;
1782 *it_e_new++ = *it_e_old;
1783 this->
assignIf (it_d_old, it_d_new, HasDataT ());
1792 elements.resize (ind_new.get (), Element ());
1793 if (HasDataT::value)
1795 data_cloud.resize (ind_new.get ());
1797 else if (it_d_old != data_cloud.begin () || it_d_new != data_cloud.begin ())
1799 std::cerr <<
"TODO: Bug in MeshBase::remove!\n";
1801 exit (EXIT_FAILURE);
1804 return (new_indices);
1808 template <
class IteratorT>
inline void
1815 template <
class IteratorT>
inline void
1821 template <
class ConstIteratorT,
class IteratorT>
inline void
1822 assignIf (
const ConstIteratorT source, IteratorT target, boost::true_type )
const
1828 template <
class ConstIteratorT,
class IteratorT>
inline void
1829 assignIf (
const ConstIteratorT , IteratorT , boost::false_type )
const
1841 assert (this->
isValid (idx_vertex));
1842 this->
getVertex (idx_vertex).idx_outgoing_half_edge_ = idx_outgoing_half_edge;
1849 assert (this->
isValid (idx_half_edge));
1850 this->
getHalfEdge (idx_half_edge).idx_terminating_vertex_ = idx_terminating_vertex;
1857 assert (this->
isValid (idx_half_edge));
1858 this->
getHalfEdge (idx_half_edge).idx_next_half_edge_ = idx_next_half_edge;
1864 const HalfEdgeIndex& idx_prev_half_edge)
1866 assert (this->
isValid (idx_half_edge));
1867 this->
getHalfEdge (idx_half_edge).idx_prev_half_edge_ = idx_prev_half_edge;
1872 setFaceIndex (
const HalfEdgeIndex& idx_half_edge,
const FaceIndex& idx_face)
1874 assert (this->
isValid (idx_half_edge));
1875 this->
getHalfEdge (idx_half_edge).idx_face_ = idx_face;
1882 assert (this->
isValid (idx_face));
1883 this->
getFace (idx_face).idx_inner_half_edge_ = idx_inner_half_edge;
1895 const VertexAroundFaceCirculator circ_end = circ;
1903 }
while (++circ!=circ_end);
1913 const OuterHalfEdgeAroundFaceCirculator circ_end = circ;
1921 }
while (++circ!=circ_end);
1935 isManifold (
const VertexIndex& idx_vertex, boost::false_type )
const
1938 const OutgoingHalfEdgeAroundVertexCirculator circ_end = circ;
1940 if (!this->
isBoundary ((circ++).getTargetIndex ()))
return (
true);
1944 }
while (++circ != circ_end);
1962 if (!this->
isManifold (VertexIndex (i)))
return (
false);
1972 template <
class DataCloudT>
inline void
1973 reserveData (DataCloudT& cloud,
const size_t n, boost::true_type )
const
1979 template <
class DataCloudT>
inline void
1985 template <
class DataCloudT>
inline void
1986 resizeData (DataCloudT& ,
const size_t n,
const typename DataCloudT::value_type& data, boost::true_type )
const
1988 data.resize (n, data);
1992 template <
class DataCloudT>
inline void
1993 resizeData (DataCloudT& ,
const size_t ,
const typename DataCloudT::value_type& , boost::false_type )
const
1998 template <
class DataCloudT>
inline void
2005 template <
class DataCloudT>
inline void
2018 assert (this->
isValid (idx_vertex));
2019 return (vertices_ [idx_vertex.
get ()]);
2026 assert (this->
isValid (idx_vertex));
2027 return (vertices_ [idx_vertex.
get ()]);
2032 setVertex (
const VertexIndex& idx_vertex,
const Vertex& vertex)
2034 assert (this->
isValid (idx_vertex));
2035 vertices_ [idx_vertex.
get ()] = vertex;
2046 assert (this->
isValid (idx_he));
2047 return (half_edges_ [idx_he.
get ()]);
2054 assert (this->
isValid (idx_he));
2055 return (half_edges_ [idx_he.
get ()]);
2062 assert (this->
isValid (idx_he));
2063 half_edges_ [idx_he.
get ()] = half_edge;
2074 assert (this->
isValid (idx_face));
2075 return (faces_ [idx_face.
get ()]);
2082 assert (this->
isValid (idx_face));
2083 return (faces_ [idx_face.
get ()]);
2088 setFace (
const FaceIndex& idx_face,
const Face& face)
2090 assert (this->
isValid (idx_face));
2091 faces_ [idx_face.
get ()] = face;
2101 VertexDataCloud vertex_data_cloud_;
2104 HalfEdgeDataCloud half_edge_data_cloud_;
2107 EdgeDataCloud edge_data_cloud_;
2110 FaceDataCloud face_data_cloud_;
2116 HalfEdges half_edges_;
2124 HalfEdgeIndices inner_he_;
2127 HalfEdgeIndices free_he_;
2130 std::vector <bool> is_new_;
2133 std::vector <bool> make_adjacent_;
2136 std::vector <bool> is_boundary_;
2139 FaceIndices delete_faces_vertex_;
2142 FaceIndices delete_faces_face_;
2146 template <
class MeshT>
2149 EIGEN_MAKE_ALIGNED_OPERATOR_NEW
2154 #endif // PCL_GEOMETRY_MESH_BASE_H
bool isBoundary(const FaceIndex &idx_face, boost::true_type) const
Check if any vertex of the face lies on the boundary.
void markDeleted(const VertexIndex &idx_vertex)
Mark the given vertex as deleted.
MeshBase< DerivedT, MeshTraitsT, MeshTagT > Self
std::vector< Vertex > Vertices
void deleteFace(const FaceIndex &idx_face, boost::false_type)
Non-manifold version of deleteFace.
void setPrevHalfEdgeIndex(const HalfEdgeIndex &idx_half_edge, const HalfEdgeIndex &idx_prev_half_edge)
Set the previous half-edge index to a given half-edge.
A vertex is a node in the mesh.
pcl::geometry::HalfEdgeIndex HalfEdgeIndex
pcl::geometry::FaceAroundVertexCirculator< const Self > FaceAroundVertexCirculator
std::vector< FaceIndex > FaceIndices
const PointT & front() const
void clearData(DataCloudT &cloud, boost::true_type) const
Clear the mesh data.
size_t sizeFaces() const
Get the number of the faces.
int get() const
Get the index.
An edge is a connection between two vertices.
Faces::iterator FaceIterator
void invalidate()
Invalidate the index.
void resizeFaces(const size_t n, const FaceData &data=FaceData())
Resize the faces to n elements.
void connectOldNew(const HalfEdgeIndex &idx_he_ab, const HalfEdgeIndex &idx_he_bc, const VertexIndex &idx_v_b)
The second half-edge is new.
VertexAroundFaceCirculator getVertexAroundFaceCirculator(const FaceIndex &idx_face) const
bool emptyVertices() const
Check if the vertices are empty.
Vertices::iterator VertexIterator
FaceDataCloud & getFaceDataCloud()
Get access to the stored face data.
size_t sizeEdges() const
Get the number of the edges.
MeshTraitsT::HalfEdgeData HalfEdgeData
boost::shared_ptr< Self > Ptr
VertexIndex getTerminatingVertexIndex(const HalfEdgeIndex &idx_half_edge) const
Get the terminating vertex index to a given half-edge.
pcl::geometry::VertexAroundVertexCirculator< const Self > VertexAroundVertexCirculator
void deleteEdge(const EdgeIndex &idx_edge)
Mark the given edge (both half-edges) and the associated faces as deleted.
VertexAroundFaceCirculator getVertexAroundFaceCirculator(const HalfEdgeIndex &idx_inner_half_edge) const
bool setHalfEdgeDataCloud(const HalfEdgeDataCloud &half_edge_data_cloud)
Change the stored half-edge data.
boost::integral_constant< bool,!boost::is_same< VertexData, pcl::geometry::NoData >::value > HasVertexData
std::vector< HalfEdge > HalfEdges
VertexIndex getVertexIndex(const VertexData &vertex_data) const
Get the index associated to the given vertex data.
void connectPrevNext(const HalfEdgeIndex &idx_he_ab, const HalfEdgeIndex &idx_he_bc)
Connect the next and prev indices of the two half-edges with each other.
bool isBoundary(const FaceIndex &idx_face, boost::false_type) const
Check if any edge of the face lies on the boundary.
bool isValid(const EdgeIndex &idx_edge) const
Check if the given edge index is a valid index into the mesh.
HalfEdgeIndex getNextHalfEdgeIndex(const HalfEdgeIndex &idx_half_edge) const
Get the next half-edge index to a given half-edge.
pcl::geometry::VertexIndex VertexIndex
pcl::geometry::EdgeIndex EdgeIndex
HalfEdgeIndex getOutgoingHalfEdgeIndex(const VertexIndex &idx_vertex) const
Get the outgoing half-edge index to a given vertex.
Circulates clockwise around a face and returns an index to the face of the outer half-edge (the targe...
void resizeEdges(const size_t n, const EdgeData &edge_data=EdgeData(), const HalfEdgeData he_data=HalfEdgeData())
Resize the edges to n elements (half-edges will hold 2*n elements).
bool isIsolated(const VertexIndex &idx_vertex) const
Check if the given vertex is isolated (not connected to other elements).
void setNextHalfEdgeIndex(const HalfEdgeIndex &idx_half_edge, const HalfEdgeIndex &idx_next_half_edge)
Set the next half_edge index to a given half-edge.
Circulates counter-clockwise around a vertex and returns an index to the incoming half-edge (the targ...
size_t sizeHalfEdges() const
Get the number of the half-edges.
bool isValid() const
Returns true if the index is valid.
InnerHalfEdgeAroundFaceCirculator getInnerHalfEdgeAroundFaceCirculator(const FaceIndex &idx_face) const
InnerHalfEdgeAroundFaceCirculator getInnerHalfEdgeAroundFaceCirculator(const HalfEdgeIndex &idx_inner_half_edge) const
void setInnerHalfEdgeIndex(const FaceIndex &idx_face, const HalfEdgeIndex &idx_inner_half_edge)
Set the inner half-edge index to a given face.
void resizeData(DataCloudT &, const size_t n, const typename DataCloudT::value_type &data, boost::true_type) const
Resize the mesh data.
boost::integral_constant< bool,!boost::is_same< HalfEdgeData, pcl::geometry::NoData >::value > HasHalfEdgeData
OuterHalfEdgeAroundFaceCirculator getOuterHalfEdgeAroundFaceCirculator(const HalfEdgeIndex &idx_inner_half_edge) const
void resizeVertices(const size_t n, const VertexData &data=VertexData())
Resize the the vertices to n elements.
VertexIndex getTargetIndex() const
Get the index to the target vertex.
void reserveData(DataCloudT &, const size_t, boost::false_type) const
Does nothing.
void setHalfEdge(const HalfEdgeIndex &idx_he, const HalfEdge &half_edge)
Set the half-edge at the given index.
bool isManifold(const VertexIndex &idx_vertex, boost::false_type) const
Check if the given vertex is manifold.
HalfEdgeIndex getCurrentHalfEdgeIndex() const
Get the half-edge that is currently stored in the circulator.
void deleteEdge(const HalfEdgeIndex &idx_he)
Mark the given half-edge, the opposite half-edge and the associated faces as deleted.
bool isValid(const FaceIndex &idx_face) const
Check if the given face index is a valid index into the mesh.
bool isDeleted(const FaceIndex &idx_face) const
Check if the given face is marked as deleted.
pcl::geometry::VertexAroundFaceCirculator< const Self > VertexAroundFaceCirculator
bool isManifold(const VertexIndex &, boost::true_type) const
Always manifold.
void connectNewNew(const HalfEdgeIndex &idx_he_ab, const HalfEdgeIndex &idx_he_bc, const VertexIndex &idx_v_b, boost::false_type)
Both half-edges are new (non-manifold version).
FaceIndex getTargetIndex() const
Get the index to the target face.
int get() const
Get the index.
void reserveFaces(const size_t n)
Reserve storage space for n faces.
bool isValid(const HalfEdgeIndex &idx_he) const
Check if the given half-edge index is a valid index into the mesh.
HalfEdges::const_iterator HalfEdgeConstIterator
size_t sizeVertices() const
Get the number of the vertices.
void resizeData(DataCloudT &, const size_t, const typename DataCloudT::value_type &, boost::false_type) const
Does nothing.
void addData(pcl::PointCloud< DataT > &, const DataT &, boost::false_type)
Does nothing.
bool isManifold(const VertexIndex &idx_vertex) const
Check if the given vertex is manifold.
void reconnectNBNB(const HalfEdgeIndex &idx_he_bc, const HalfEdgeIndex &idx_he_cb, const VertexIndex &idx_v_b, boost::true_type)
Both edges are not on the boundary.
HalfEdgeIndex getIncomingHalfEdgeIndex(const VertexIndex &idx_vertex) const
Get the incoming half-edge index to a given vertex.
void connectOldOld(const HalfEdgeIndex &, const HalfEdgeIndex &idx_he_bc, const VertexIndex &idx_v_b, boost::false_type)
Both half-edges are old (non-manifold version).
pcl::PointCloud< HalfEdgeData > HalfEdgeDataCloud
pcl::PointCloud< VertexData > VertexDataCloud
HalfEdgeIndex getOppositeHalfEdgeIndex(const HalfEdgeIndex &idx_half_edge) const
Get the opposite half-edge index to a given half-edge.
EdgeDataCloud getEdgeDataCloud() const
Get the stored edge data.
Index used to access elements in the half-edge mesh.
std::vector< Face > Faces
void incrementIf(IteratorT &, boost::false_type) const
Does nothing.
std::vector< HalfEdgeIndex > HalfEdgeIndices
Faces::const_iterator FaceConstIterator
OutgoingHalfEdgeAroundVertexCirculator getOutgoingHalfEdgeAroundVertexCirculator(const VertexIndex &idx_vertex) const
MeshTraitsT::IsManifold IsManifold
VertexIndex addVertex(const VertexData &vertex_data=VertexData())
Add a vertex to the mesh.
void markDeleted(const EdgeIndex &idx_edge)
Mark the given edge (both half-edges) as deleted.
pcl::geometry::HalfEdgeIndex toHalfEdgeIndex(const EdgeIndex &index, const bool get_first=true)
Convert the given edge index to a half-edge index.
void invalidate()
Invalidate the index.
MeshTraitsT::EdgeData EdgeData
bool empty() const
Check if the mesh is empty.
FaceAroundFaceCirculator getFaceAroundFaceCirculator(const HalfEdgeIndex &idx_inner_half_edge) const
HalfEdge & getHalfEdge(const HalfEdgeIndex &idx_he)
Get the half-edge for the given index.
HalfEdgeIndex getPrevHalfEdgeIndex(const HalfEdgeIndex &idx_half_edge) const
Get the previous half-edge index to a given half-edge.
bool isBoundary(const VertexIndex &idx_vertex) const
Check if the given vertex lies on the boundary.
void makeAdjacent(const HalfEdgeIndex &idx_he_ab, const HalfEdgeIndex &idx_he_bc, HalfEdgeIndex &idx_free_half_edge)
Make the half-edges bc the next half-edge of ab.
HalfEdgeIndex addEdge(const VertexIndex &idx_v_a, const VertexIndex &idx_v_b, const HalfEdgeData &he_data, const EdgeData &edge_data)
Add an edge between the two given vertices and connect them with the vertices.
VertexAroundVertexCirculator getVertexAroundVertexCirculator(const HalfEdgeIndex &idx_outgoing_half_edge) const
void assignIf(const ConstIteratorT, IteratorT, boost::false_type) const
Does nothing.
VectorType::const_iterator const_iterator
EdgeIndex getEdgeIndex(const EdgeData &edge_data) const
Get the index associated to the given edge data.
Face & getFace(const FaceIndex &idx_face)
Get the face for the given index.
Circulates counter-clockwise around a vertex and returns an index to the terminating vertex of the ou...
FaceIndex getFaceIndex(const HalfEdgeIndex &idx_half_edge) const
Get the face index to a given half-edge.
void connectOldOld(const HalfEdgeIndex &, const HalfEdgeIndex &, const VertexIndex &, boost::true_type)
Both half-edges are old (manifold version).
void setFace(const FaceIndex &idx_face, const Face &face)
Set the face at the given index.
void setOutgoingHalfEdgeIndex(const VertexIndex &idx_vertex, const HalfEdgeIndex &idx_outgoing_half_edge)
Set the outgoing half-edge index to a given vertex.
VertexIndex getTargetIndex() const
Get the index to the target vertex.
Index used to access elements in the half-edge mesh.
OuterHalfEdgeAroundFaceCirculator getOuterHalfEdgeAroundFaceCirculator(const FaceIndex &idx_face) const
void clear()
Clear all mesh elements and data.
FaceIndex getFaceIndex(const FaceData &face_data) const
Get the index associated to the given face data.
Index used to access elements in the half-edge mesh.
Circulates clockwise around a face and returns an index to the terminating vertex of the inner half-e...
void connectNewNew(const HalfEdgeIndex &idx_he_ab, const HalfEdgeIndex &idx_he_bc, const VertexIndex &idx_v_b, boost::true_type)
Both half-edges are new (manifold version).
Vertex & getVertex(const VertexIndex &idx_vertex)
Get the vertex for the given index.
void assignIf(const ConstIteratorT source, IteratorT target, boost::true_type) const
Assign the source iterator to the target iterator.
bool isBoundary(const FaceIndex &idx_face) const
Check if the given face lies on the boundary.
void push_back(const PointT &pt)
Insert a new point in the cloud, at the end of the container.
void setTerminatingVertexIndex(const HalfEdgeIndex &idx_half_edge, const VertexIndex &idx_terminating_vertex)
Set the terminating vertex index to a given half-edge.
bool isValid(const VertexIndex &idx_vertex) const
Check if the given vertex index is a valid index into the mesh.
Index used to access elements in the half-edge mesh.
void reconnect(const HalfEdgeIndex &idx_he_ab, const HalfEdgeIndex &idx_he_bc, const bool is_boundary_ba, const bool is_boundary_cb)
Deconnect the input half-edges from the mesh and adjust the indices of the connected half-edges...
FaceIndex addFaceImplBase(const VertexIndices &vertices, const FaceData &face_data, const EdgeData &edge_data, const HalfEdgeData &half_edge_data)
General implementation of addFace.
FaceIndex connectFace(const HalfEdgeIndices &inner_he, const FaceData &face_data)
Add a face to the mesh and connect it to the half-edges.
HalfEdgeDataCloud getHalfEdgeDataCloud() const
Get the stored half-edge data.
IncomingHalfEdgeAroundVertexCirculator getIncomingHalfEdgeAroundVertexCirculator(const VertexIndex &idx_vertex) const
bool isDeleted(const VertexIndex &idx_vertex) const
Check if the given vertex is marked as deleted.
IncomingHalfEdgeAroundVertexCirculator getIncomingHalfEdgeAroundVertexCirculator(const HalfEdgeIndex &idx_incoming_half_edge) const
HalfEdges::iterator HalfEdgeIterator
Circulates counter-clockwise around a vertex and returns an index to the outgoing half-edge (the targ...
void reserveVertices(const size_t n)
Reserve storage space n vertices.
boost::shared_ptr< const Self > ConstPtr
MeshTraitsT::FaceData FaceData
void deleteFace(const FaceIndex &idx_face, boost::true_type)
Manifold version of deleteFace.
FaceIndex getOppositeFaceIndex(const HalfEdgeIndex &idx_half_edge) const
Get the face index to a given half-edge.
boost::integral_constant< bool,!boost::is_same< FaceData, pcl::geometry::NoData >::value > HasFaceData
FaceAroundFaceCirculator getFaceAroundFaceCirculator(const FaceIndex &idx_face) const
Vertex getVertex(const VertexIndex &idx_vertex) const
Get the vertex for the given index.
void invalidate()
Invalidate the index.
std::vector< EdgeIndex > EdgeIndices
HalfEdgeIndex getTargetIndex() const
Get the index to the inner half-edge.
const PointT & back() const
pcl::PointCloud< EdgeData > EdgeDataCloud
bool setEdgeDataCloud(const EdgeDataCloud &edge_data_cloud)
Change the stored edge data.
HalfEdgeDataCloud & getHalfEdgeDataCloud()
Get access to the stored half-edge data.
HalfEdgeIndex getTargetIndex() const
Get the index to the outer half-edge.
EdgeDataCloud & getEdgeDataCloud()
Get access to the stored edge data.
bool isDeleted(const HalfEdgeIndex &idx_he) const
Check if the given half-edge is marked as deleted.
pcl::geometry::FaceAroundFaceCirculator< const Self > FaceAroundFaceCirculator
pcl::geometry::OutgoingHalfEdgeAroundVertexCirculator< const Self > OutgoingHalfEdgeAroundVertexCirculator
void reconnectNBNB(const HalfEdgeIndex &idx_he_bc, const HalfEdgeIndex &, const VertexIndex &idx_v_b, boost::false_type)
Both edges are not on the boundary.
bool isBoundary(const HalfEdgeIndex &idx_he) const
Check if the given half-edge lies on the bounddary.
int get() const
Get the index.
bool emptyEdges() const
Check if the edges are empty.
MeshTraitsT::VertexData VertexData
bool checkTopology1(const VertexIndex &idx_v_a, const VertexIndex &idx_v_b, HalfEdgeIndex &idx_he_ab, std::vector< bool >::reference is_new_ab, boost::true_type) const
Check if the edge between the two vertices can be added.
boost::integral_constant< bool,!boost::is_same< EdgeData, pcl::geometry::NoData >::value > HasEdgeData
bool isManifold(boost::true_type) const
Always manifold.
void cleanUp()
Removes all mesh elements and data that are marked as deleted.
bool isBoundary(const EdgeIndex &idx_edge) const
Check if the given edge lies on the boundary (any of the two half-edges lies on the boundary...
FaceIndex addFace(const VertexIndices &vertices, const FaceData &face_data=FaceData(), const EdgeData &edge_data=EdgeData(), const HalfEdgeData &half_edge_data=HalfEdgeData())
Add a face to the mesh.
bool isManifold(boost::false_type) const
Check if all vertices in the mesh are manifold.
VertexDataCloud getVertexDataCloud() const
Get the stored vertex data.
bool isDeleted(const EdgeIndex &idx_edge) const
Check if the given edge (any of the two half-edges) is marked as deleted.
pcl::geometry::Vertex Vertex
void addData(pcl::PointCloud< DataT > &cloud, const DataT &data, boost::true_type)
Add mesh data.
FaceAroundVertexCirculator getFaceAroundVertexCirculator(const HalfEdgeIndex &idx_outgoing_half_edge) const
VertexDataCloud & getVertexDataCloud()
Get access to the stored vertex data.
void setFaceIndex(const HalfEdgeIndex &idx_half_edge, const FaceIndex &idx_face)
Set the face index to a given half-edge.
A face is a closed loop of edges.
Circulates clockwise around a face and returns an index to the inner half-edge (the target)...
void deleteFace(const FaceIndex &idx_face)
Mark the given face as deleted.
bool checkTopology1(const VertexIndex &idx_v_a, const VertexIndex &idx_v_b, HalfEdgeIndex &idx_he_ab, std::vector< bool >::reference is_new_ab, boost::false_type) const
Non manifold version of checkTopology1.
void reserveData(DataCloudT &cloud, const size_t n, boost::true_type) const
Reserve storage space for the mesh data.
pcl::geometry::IncomingHalfEdgeAroundVertexCirculator< const Self > IncomingHalfEdgeAroundVertexCirculator
void markDeleted(const FaceIndex &idx_face)
Mark the given face as deleted.
bool isEqualTopology(const Self &other) const
Check if the other mesh has the same topology as this mesh.
void connectNewOld(const HalfEdgeIndex &idx_he_ab, const HalfEdgeIndex &idx_he_bc, const VertexIndex &idx_v_b)
The first half-edge is new.
Read / write the half-edge mesh from / to a file.
Circulates clockwise around a face and returns an index to the outer half-edge (the target)...
Circulates counter-clockwise around a vertex and returns an index to the face of the outgoing half-ed...
pcl::geometry::InnerHalfEdgeAroundFaceCirculator< const Self > InnerHalfEdgeAroundFaceCirculator
FaceAroundVertexCirculator getFaceAroundVertexCirculator(const VertexIndex &idx_vertex) const
Base class for the half-edge mesh.
pcl::geometry::HalfEdge HalfEdge
void incrementIf(IteratorT &it, boost::true_type) const
Increment the iterator.
bool checkTopology2(const HalfEdgeIndex &idx_he_ab, const HalfEdgeIndex &idx_he_bc, const bool is_new_ab, const bool is_new_bc, const bool, std::vector< bool >::reference make_adjacent_ab_bc, HalfEdgeIndex &idx_free_half_edge, boost::false_type) const
Check if the half-edge bc is the next half-edge of ab.
VectorType::iterator iterator
bool isBoundary(const FaceIndex &idx_face) const
Check if the given face lies on the boundary.
VertexAroundVertexCirculator getVertexAroundVertexCirculator(const VertexIndex &idx_vertex) const
Vertices::const_iterator VertexConstIterator
BOOST_CONCEPT_ASSERT((boost::Convertible< IsManifold, bool >))
Face getFace(const FaceIndex &idx_face) const
Get the face for the given index.
void deleteVertex(const VertexIndex &idx_vertex)
Mark the given vertex and all connected half-edges and faces as deleted.
void resize(size_t n)
Resize the cloud.
pcl::PointCloud< FaceData > FaceDataCloud
void reserveEdges(const size_t n)
Reserve storage space for n edges (2*n storage space is reserved for the half-edges).
bool emptyFaces() const
Check if the faces are empty.
void markDeleted(const HalfEdgeIndex &idx_he)
Mark the given half-edge as deleted.
VertexIndex getOriginatingVertexIndex(const HalfEdgeIndex &idx_half_edge) const
Get the originating vertex index to a given half-edge.
HalfEdgeIndex getHalfEdgeIndex(const HalfEdgeData &half_edge_data) const
Get the index associated to the given half-edge data.
HalfEdgeIndex getInnerHalfEdgeIndex(const FaceIndex &idx_face) const
Get the inner half-edge index to a given face.
pcl::geometry::OuterHalfEdgeAroundFaceCirculator< const Self > OuterHalfEdgeAroundFaceCirculator
void clearData(DataCloudT &, boost::false_type) const
Does nothing.
bool setFaceDataCloud(const FaceDataCloud &face_data_cloud)
Change the stored face data.
HalfEdge getHalfEdge(const HalfEdgeIndex &idx_he) const
Get the half-edge for the given index.
pcl::geometry::FaceIndex FaceIndex
HalfEdgeIndex getOuterHalfEdgeIndex(const FaceIndex &idx_face) const
Get the outer half-edge inex to a given face.
OutgoingHalfEdgeAroundVertexCirculator getOutgoingHalfEdgeAroundVertexCirculator(const HalfEdgeIndex &idx_outgoing_half_edge) const
HalfEdgeIndex getTargetIndex() const
Get the index to the incoming half-edge.
std::vector< VertexIndex > VertexIndices
bool checkTopology2(const HalfEdgeIndex &, const HalfEdgeIndex &, const bool is_new_ab, const bool is_new_bc, const bool is_isolated_b, std::vector< bool >::reference, HalfEdgeIndex &, boost::true_type) const
Check if the face may be added (mesh does not become non-manifold).
void setVertex(const VertexIndex &idx_vertex, const Vertex &vertex)
Set the vertex at the given index.
HalfEdgeIndex getTargetIndex() const
Get the index to the outgoing half-edge.
FaceDataCloud getFaceDataCloud() const
Get the stored face data.
bool isManifold() const
Check if the mesh is manifold.
bool setVertexDataCloud(const VertexDataCloud &vertex_data_cloud)
Change the stored vertex data.