triangle_mesh.h
Go to the documentation of this file.
00001 /*
00002  * Software License Agreement (BSD License)
00003  *
00004  * Point Cloud Library (PCL) - www.pointclouds.org
00005  * Copyright (c) 2009-2012, Willow Garage, Inc.
00006  * Copyright (c) 2012-, Open Perception, Inc.
00007  *
00008  * All rights reserved.
00009  *
00010  * Redistribution and use in source and binary forms, with or without
00011  * modification, are permitted provided that the following conditions
00012  * are met:
00013  *
00014  *  * Redistributions of source code must retain the above copyright
00015  *    notice, this list of conditions and the following disclaimer.
00016  *  * Redistributions in binary form must reproduce the above
00017  *    copyright notice, this list of conditions and the following
00018  *    disclaimer in the documentation and/or other materials provided
00019  *    with the distribution.
00020  *  * Neither the name of the copyright holder(s) nor the names of its
00021  *    contributors may be used to endorse or promote products derived
00022  *    from this software without specific prior written permission.
00023  *
00024  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
00025  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
00026  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
00027  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
00028  * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
00029  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
00030  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
00031  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
00032  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
00033  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
00034  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
00035  * POSSIBILITY OF SUCH DAMAGE.
00036  *
00037  * $Id$
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         // Indices
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         // Circulators
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           // Try to add two faces
00192           // 3 - 2
00193           // | / |
00194           // 0 - 1
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); // might be possible to add now
00205             return (std::make_pair (idx_face_1, idx_face_0));
00206           }
00207 
00208           // Try to add two faces
00209           // 3 - 2
00210           // | \ |
00211           // 0 - 1
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); // might be possible to add now
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           // Check manifoldness
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           // Connect the triangle pair
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         // NOTE: Can't use the typedef of Base as a friend.
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         // d - c
00274         // | / |
00275         // a - b
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           // Add new half-edges
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           // Get the existing half-edges
00297           const HalfEdgeIndex idx_he_ab_prev = Base::getPrevHalfEdgeIndex (idx_he_ab); // No reference!
00298           const HalfEdgeIndex idx_he_ab_next = Base::getNextHalfEdgeIndex (idx_he_ab); // No reference!
00299 
00300           const HalfEdgeIndex idx_he_cd_prev = Base::getPrevHalfEdgeIndex (idx_he_cd); // No reference!
00301           const HalfEdgeIndex idx_he_cd_next = Base::getNextHalfEdgeIndex (idx_he_cd); // No reference!
00302 
00303           // Connect the outer half-edges
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           // Connect the inner half-edges
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           // Connect the vertices to the boundary half-edges
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           // Add and connect the faces
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         // Members
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   } // End namespace geom
00359 } // End namespace pcl
00360 
00361 #endif // PCL_GEOMETRY_TRIANGLE_MESH_H


pcl
Author(s): Open Perception
autogenerated on Wed Aug 26 2015 15:37:06