00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041 #ifndef PCL_GEOMETRY_TRIANGLE_MESH_H
00042 #define PCL_GEOMETRY_TRIANGLE_MESH_H
00043
00044 #include <utility>
00045
00046 #include <pcl/geometry/mesh_base.h>
00047
00048 namespace pcl
00049 {
00050 namespace geometry
00051 {
00053 struct TriangleMeshTag {};
00054
00060 template <class MeshTraitsT>
00061 class TriangleMesh : public pcl::geometry::MeshBase <TriangleMesh <MeshTraitsT>, MeshTraitsT, TriangleMeshTag>
00062 {
00063 public:
00064
00065 typedef pcl::geometry::MeshBase <TriangleMesh <MeshTraitsT>, MeshTraitsT, TriangleMeshTag> Base;
00066
00067 typedef TriangleMesh <MeshTraitsT> Self;
00068 typedef boost::shared_ptr <Self> Ptr;
00069 typedef boost::shared_ptr <const Self> ConstPtr;
00070
00071 typedef typename Base::VertexData VertexData;
00072 typedef typename Base::HalfEdgeData HalfEdgeData;
00073 typedef typename Base::EdgeData EdgeData;
00074 typedef typename Base::FaceData FaceData;
00075 typedef typename Base::IsManifold IsManifold;
00076 typedef typename Base::MeshTag MeshTag;
00077
00078 typedef typename Base::HasVertexData HasVertexData;
00079 typedef typename Base::HasHalfEdgeData HasHalfEdgeData;
00080 typedef typename Base::HasEdgeData HasEdgeData;
00081 typedef typename Base::HasFaceData HasFaceData;
00082
00083 typedef typename Base::VertexDataCloud VertexDataCloud;
00084 typedef typename Base::HalfEdgeDataCloud HalfEdgeDataCloud;
00085 typedef typename Base::EdgeDataCloud EdgeDataCloud;
00086 typedef typename Base::FaceDataCloud FaceDataCloud;
00087
00088
00089 typedef typename Base::VertexIndex VertexIndex;
00090 typedef typename Base::HalfEdgeIndex HalfEdgeIndex;
00091 typedef typename Base::EdgeIndex EdgeIndex;
00092 typedef typename Base::FaceIndex FaceIndex;
00093 typedef std::pair <FaceIndex, FaceIndex> FaceIndexPair;
00094
00095 typedef typename Base::VertexIndices VertexIndices;
00096 typedef typename Base::HalfEdgeIndices HalfEdgeIndices;
00097 typedef typename Base::EdgeIndices EdgeIndices;
00098 typedef typename Base::FaceIndices FaceIndices;
00099
00100
00101 typedef typename Base::VertexAroundVertexCirculator VertexAroundVertexCirculator;
00102 typedef typename Base::OutgoingHalfEdgeAroundVertexCirculator OutgoingHalfEdgeAroundVertexCirculator;
00103 typedef typename Base::IncomingHalfEdgeAroundVertexCirculator IncomingHalfEdgeAroundVertexCirculator;
00104 typedef typename Base::FaceAroundVertexCirculator FaceAroundVertexCirculator;
00105 typedef typename Base::VertexAroundFaceCirculator VertexAroundFaceCirculator;
00106 typedef typename Base::InnerHalfEdgeAroundFaceCirculator InnerHalfEdgeAroundFaceCirculator;
00107 typedef typename Base::OuterHalfEdgeAroundFaceCirculator OuterHalfEdgeAroundFaceCirculator;
00108 typedef typename Base::FaceAroundFaceCirculator FaceAroundFaceCirculator;
00109
00111 TriangleMesh ()
00112 : Base (),
00113 add_triangle_ (3),
00114 inner_he_atp_ (4),
00115 is_new_atp_ (4)
00116 {
00117 }
00118
00120 using Base::addFace;
00121
00132 inline FaceIndex
00133 addFace (const VertexIndex& idx_v_0,
00134 const VertexIndex& idx_v_1,
00135 const VertexIndex& idx_v_2,
00136 const FaceData& face_data = FaceData (),
00137 const EdgeData& edge_data = EdgeData (),
00138 const HalfEdgeData& half_edge_data = HalfEdgeData ())
00139 {
00140 add_triangle_ [0] = idx_v_0;
00141 add_triangle_ [1] = idx_v_1;
00142 add_triangle_ [2] = idx_v_2;
00143
00144 return (this->addFaceImplBase (add_triangle_, face_data, edge_data, half_edge_data));
00145 }
00146
00155 FaceIndexPair
00156 addTrianglePair (const VertexIndices& vertices,
00157 const FaceData& face_data = FaceData (),
00158 const EdgeData& edge_data = EdgeData (),
00159 const HalfEdgeData& half_edge_data = HalfEdgeData ())
00160 {
00161 if (vertices.size () != 4)
00162 {
00163 return (std::make_pair (FaceIndex (), FaceIndex ()));
00164 }
00165 else
00166 {
00167 return (this->addTrianglePair (vertices [0], vertices [1], vertices [2], vertices [3], face_data, edge_data, half_edge_data));
00168 }
00169 }
00170
00182 inline FaceIndexPair
00183 addTrianglePair (const VertexIndex& idx_v_0,
00184 const VertexIndex& idx_v_1,
00185 const VertexIndex& idx_v_2,
00186 const VertexIndex& idx_v_3,
00187 const FaceData& face_data = FaceData (),
00188 const EdgeData& edge_data = EdgeData (),
00189 const HalfEdgeData& half_edge_data = HalfEdgeData ())
00190 {
00191
00192
00193
00194
00195 FaceIndex idx_face_0 = this->addFace (idx_v_0, idx_v_1, idx_v_2, face_data);
00196 FaceIndex idx_face_1 = this->addFace (idx_v_0, idx_v_2, idx_v_3, face_data);
00197
00198 if (idx_face_0.isValid ())
00199 {
00200 return (std::make_pair (idx_face_0, idx_face_1));
00201 }
00202 else if (idx_face_1.isValid ())
00203 {
00204 idx_face_0 = this->addFace (idx_v_0, idx_v_1, idx_v_2, face_data);
00205 return (std::make_pair (idx_face_1, idx_face_0));
00206 }
00207
00208
00209
00210
00211
00212 idx_face_0 = this->addFace (idx_v_1, idx_v_2, idx_v_3, face_data);
00213 idx_face_1 = this->addFace (idx_v_0, idx_v_1, idx_v_3, face_data);
00214
00215 if (idx_face_0.isValid ())
00216 {
00217 return (std::make_pair (idx_face_0, idx_face_1));
00218 }
00219 else if (idx_face_1.isValid ())
00220 {
00221 idx_face_0 = this->addFace (idx_v_1, idx_v_2, idx_v_3, face_data);
00222 return (std::make_pair (idx_face_1, idx_face_0));
00223 }
00224
00225 if (!IsManifold::value)
00226 {
00227 return (std::make_pair (FaceIndex (), FaceIndex ()));
00228 }
00229
00230
00231 if (!Base::checkTopology1 (idx_v_0,idx_v_1, inner_he_atp_ [0], is_new_atp_ [0], IsManifold ()) ||
00232 !Base::checkTopology1 (idx_v_1,idx_v_2, inner_he_atp_ [1], is_new_atp_ [1], IsManifold ()) ||
00233 !Base::checkTopology1 (idx_v_2,idx_v_3, inner_he_atp_ [2], is_new_atp_ [2], IsManifold ()) ||
00234 !Base::checkTopology1 (idx_v_3,idx_v_0, inner_he_atp_ [3], is_new_atp_ [3], IsManifold ()))
00235 {
00236 return (std::make_pair (FaceIndex (), FaceIndex ()));
00237 }
00238
00239
00240 if (!is_new_atp_ [0] && is_new_atp_ [1] && !is_new_atp_ [2] && is_new_atp_ [3])
00241 {
00242 return (this->connectTrianglePair (inner_he_atp_ [0], inner_he_atp_ [2], idx_v_0, idx_v_1, idx_v_2, idx_v_3, face_data, edge_data, half_edge_data));
00243 }
00244 else if (is_new_atp_ [0] && !is_new_atp_ [1] && is_new_atp_ [2] && !is_new_atp_ [3])
00245 {
00246 return (this->connectTrianglePair (inner_he_atp_ [1], inner_he_atp_ [3], idx_v_1, idx_v_2, idx_v_3, idx_v_0, face_data, edge_data, half_edge_data));
00247 }
00248 else
00249 {
00250 return (std::make_pair (FaceIndex (), FaceIndex ()));
00251 }
00252 }
00253
00254 private:
00255
00256
00257 friend class pcl::geometry::MeshBase <TriangleMesh <MeshTraitsT>, MeshTraitsT, pcl::geometry::TriangleMeshTag>;
00258
00260 inline FaceIndex
00261 addFaceImpl (const VertexIndices& vertices,
00262 const FaceData& face_data,
00263 const EdgeData& edge_data,
00264 const HalfEdgeData& half_edge_data)
00265 {
00266 if (vertices.size () == 3)
00267 return (this->addFaceImplBase (vertices, face_data, edge_data, half_edge_data));
00268 else
00269 return (FaceIndex ());
00270 }
00271
00273
00274
00275
00276 FaceIndexPair
00277 connectTrianglePair (const HalfEdgeIndex& idx_he_ab,
00278 const HalfEdgeIndex& idx_he_cd,
00279 const VertexIndex& idx_v_a,
00280 const VertexIndex& idx_v_b,
00281 const VertexIndex& idx_v_c,
00282 const VertexIndex& idx_v_d,
00283 const FaceData& face_data,
00284 const EdgeData& edge_data,
00285 const HalfEdgeData& he_data)
00286 {
00287
00288 const HalfEdgeIndex idx_he_bc = Base::addEdge (idx_v_b, idx_v_c, he_data, edge_data);
00289 const HalfEdgeIndex idx_he_da = Base::addEdge (idx_v_d, idx_v_a, he_data, edge_data);
00290 const HalfEdgeIndex idx_he_ca = Base::addEdge (idx_v_c, idx_v_a, he_data, edge_data);
00291
00292 const HalfEdgeIndex idx_he_cb = Base::getOppositeHalfEdgeIndex (idx_he_bc);
00293 const HalfEdgeIndex idx_he_ad = Base::getOppositeHalfEdgeIndex (idx_he_da);
00294 const HalfEdgeIndex idx_he_ac = Base::getOppositeHalfEdgeIndex (idx_he_ca);
00295
00296
00297 const HalfEdgeIndex idx_he_ab_prev = Base::getPrevHalfEdgeIndex (idx_he_ab);
00298 const HalfEdgeIndex idx_he_ab_next = Base::getNextHalfEdgeIndex (idx_he_ab);
00299
00300 const HalfEdgeIndex idx_he_cd_prev = Base::getPrevHalfEdgeIndex (idx_he_cd);
00301 const HalfEdgeIndex idx_he_cd_next = Base::getNextHalfEdgeIndex (idx_he_cd);
00302
00303
00304 Base::connectPrevNext (idx_he_ab_prev, idx_he_ad );
00305 Base::connectPrevNext (idx_he_ad , idx_he_cd_next);
00306 Base::connectPrevNext (idx_he_cd_prev, idx_he_cb );
00307 Base::connectPrevNext (idx_he_cb , idx_he_ab_next);
00308
00309
00310 Base::connectPrevNext (idx_he_ab, idx_he_bc);
00311 Base::connectPrevNext (idx_he_bc, idx_he_ca);
00312 Base::connectPrevNext (idx_he_ca, idx_he_ab);
00313
00314 Base::connectPrevNext (idx_he_ac, idx_he_cd);
00315 Base::connectPrevNext (idx_he_cd, idx_he_da);
00316 Base::connectPrevNext (idx_he_da, idx_he_ac);
00317
00318
00319 Base::setOutgoingHalfEdgeIndex (idx_v_a, idx_he_ad );
00320 Base::setOutgoingHalfEdgeIndex (idx_v_b, idx_he_ab_next);
00321 Base::setOutgoingHalfEdgeIndex (idx_v_c, idx_he_cb );
00322 Base::setOutgoingHalfEdgeIndex (idx_v_d, idx_he_cd_next);
00323
00324
00325 HalfEdgeIndices inner_he_abc; inner_he_abc.reserve (3);
00326 inner_he_abc.push_back (idx_he_ab);
00327 inner_he_abc.push_back (idx_he_bc);
00328 inner_he_abc.push_back (idx_he_ca);
00329
00330 HalfEdgeIndices inner_he_acd; inner_he_acd.reserve (3);
00331 inner_he_acd.push_back (idx_he_ac);
00332 inner_he_acd.push_back (idx_he_cd);
00333 inner_he_acd.push_back (idx_he_da);
00334
00335 const FaceIndex idx_f_abc = Base::connectFace (inner_he_abc, face_data);
00336 const FaceIndex idx_f_acd = Base::connectFace (inner_he_acd, face_data);
00337
00338 return (std::make_pair (idx_f_abc, idx_f_acd));
00339 }
00340
00342
00344
00346 VertexIndices add_triangle_;
00347
00349 HalfEdgeIndices inner_he_atp_;
00350
00352 std::vector <bool> is_new_atp_;
00353
00354 public:
00355
00356 EIGEN_MAKE_ALIGNED_OPERATOR_NEW
00357 };
00358 }
00359 }
00360
00361 #endif // PCL_GEOMETRY_TRIANGLE_MESH_H