Go to the documentation of this file.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 #include <pcl/apps/in_hand_scanner/mesh_processing.h>
00042 
00043 #include <cmath>
00044 
00045 #include <pcl/apps/in_hand_scanner/utils.h>
00046 
00048 
00049 pcl::ihs::MeshProcessing::MeshProcessing ()
00050 {
00051 }
00052 
00054 
00055 void
00056 pcl::ihs::MeshProcessing::processBoundary (Mesh& mesh, const std::vector <HalfEdgeIndices>& boundary_collection, const bool cleanup) const
00057 {
00058   typedef std::vector <Mesh::HalfEdgeIndices> BoundaryCollection;
00059 
00060   Mesh::VertexIndex vi_a, vi_b, vi_c, vi_d;
00061   Eigen::Vector3f ab, bc, ac, n_adb, n_plane; 
00062   Mesh::FaceIndex opposite_face;
00063 
00064   for (BoundaryCollection::const_iterator it_bc=boundary_collection.begin (); it_bc!=boundary_collection.end (); ++it_bc)
00065   {
00066     const Mesh::HalfEdgeIndices& boundary = *it_bc;
00067     if (boundary.size () == 3)
00068     {
00069       opposite_face = mesh.getOppositeFaceIndex (boundary [0]);
00070 
00071       if (mesh.getOppositeFaceIndex (boundary [1]) == opposite_face  &&
00072           mesh.getOppositeFaceIndex (boundary [2]) == opposite_face)
00073       {
00074         
00075         mesh.deleteFace (opposite_face);
00076       }
00077       else
00078       {
00079         
00080         mesh.addFace (mesh.getTerminatingVertexIndex (boundary [0]),
00081                       mesh.getTerminatingVertexIndex (boundary [1]),
00082                       mesh.getTerminatingVertexIndex (boundary [2]));
00083       }
00084     }
00085     else 
00086     {
00087       
00088 
00089       
00090       
00091       
00092       
00093       
00094       
00095 
00096       for (int i=0; i<boundary.size (); ++i)
00097       {
00098         
00099         vi_a = mesh.getOriginatingVertexIndex (boundary [i]);
00100         vi_b = mesh.getTerminatingVertexIndex (boundary [i]);
00101         vi_c = mesh.getTerminatingVertexIndex (boundary [(i+1) % boundary.size ()]);
00102 
00103         const Eigen::Vector4f& v_a = mesh.getVertexDataCloud () [vi_a.get ()].getVector4fMap ();
00104         const Eigen::Vector4f& v_b = mesh.getVertexDataCloud () [vi_b.get ()].getVector4fMap ();
00105         const Eigen::Vector4f& v_c = mesh.getVertexDataCloud () [vi_c.get ()].getVector4fMap ();
00106 
00107         ab = (v_b - v_a).head <3> ();
00108         bc = (v_c - v_b).head <3> ();
00109         ac = (v_c - v_a).head <3> ();
00110 
00111         const float angle = std::acos (pcl::ihs::clamp (-ab.dot (bc) / ab.norm () / bc.norm (), -1.f, 1.f));
00112 
00113         if (angle < 1.047197551196598f) 
00114         {
00115           
00116           vi_d = mesh.getTerminatingVertexIndex (
00117                    mesh.getNextHalfEdgeIndex (
00118                      mesh.getOppositeHalfEdgeIndex (boundary [i])));
00119           const Eigen::Vector4f& v_d = mesh.getVertexDataCloud () [vi_d.get ()].getVector4fMap ();
00120 
00121           
00122           
00123           n_adb   = (v_d - v_a).head <3> ().cross (ab);
00124           n_plane = n_adb.cross (ab);
00125 
00126           if (n_plane.dot (ac) > 0.f)
00127           {
00128             mesh.addFace (vi_a, vi_b, vi_c);
00129           }
00130         }
00131       }
00132     }
00133   }
00134 
00135   if (cleanup)
00136     mesh.cleanUp ();
00137 }
00138