test_mesh_common_functions.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_TEST_GEOMETRY_TEST_MESH_COMMON_FUNCTIONS_H
00042 #define PCL_TEST_GEOMETRY_TEST_MESH_COMMON_FUNCTIONS_H
00043 
00044 #include <iostream>
00045 #include <vector>
00046 
00048 
00049 // Abort circulating if the number of evaluations is too damn high.
00050 const unsigned int max_number_polygon_vertices  = 100;
00051 const unsigned int max_number_boundary_vertices = 100;
00052 
00054 
00056 template <class MeshT> bool
00057 hasFaces (const MeshT& mesh, const std::vector <typename MeshT::VertexIndices> faces, const bool verbose = false)
00058 {
00059   typedef typename MeshT::VertexAroundFaceCirculator VAFC;
00060   typedef typename MeshT::VertexIndices              VertexIndices;
00061   typedef typename MeshT::FaceIndex                  FaceIndex;
00062 
00063   if (mesh.sizeFaces () != faces.size ())
00064   {
00065     if (verbose)
00066     {
00067       std::cerr << "Incorrect number of faces: " << mesh.sizeFaces () << " != " << faces.size () << "\n";
00068     }
00069     return (false);
00070   }
00071 
00072   VertexIndices vi;
00073   for (unsigned int i=0; i<mesh.sizeFaces (); ++i)
00074   {
00075     if (verbose) std::cerr << "Face " << std::setw (2) << i << ": ";
00076     VAFC       circ     = mesh.getVertexAroundFaceCirculator (FaceIndex (i));
00077     const VAFC circ_end = circ;
00078     vi.clear ();
00079     unsigned int counter = 0;
00080     do
00081     {
00082       if (verbose) std::cerr << std::setw (2) << circ.getTargetIndex () << " ";
00083 
00084       // Avoid an infinite loop if connectivity is wrong
00085       if (++counter > max_number_polygon_vertices)
00086       {
00087         if (verbose) std::cerr << "... Infinite loop aborted.\n";
00088         return (false);
00089       }
00090       vi.push_back (circ.getTargetIndex ());
00091     } while (++circ != circ_end);
00092 
00093     if (vi.size () != faces [i].size ())
00094     {
00095       std::cerr << "Wrong size!\n";
00096       return (false);
00097     }
00098     if (verbose) std::cerr << "\texpected: ";
00099     for (unsigned int j=0; j<vi.size (); ++j)
00100     {
00101       if (verbose) std::cerr << std::setw (2) << faces [i][j] << " ";
00102       if (vi [j] != faces [i][j])
00103       {
00104         return (false);
00105       }
00106     }
00107     if (verbose) std::cerr << "\n";
00108   }
00109   return (true);
00110 }
00111 
00113 
00117 template <class MeshT> bool
00118 hasFaces (const MeshT& mesh, const std::vector <std::vector <int> > faces, const bool verbose = false)
00119 {
00120   typedef typename MeshT::VertexAroundFaceCirculator VAFC;
00121   typedef typename MeshT::FaceIndex                  FaceIndex;
00122   typedef typename MeshT::VertexDataCloud            VertexDataCloud;
00123 
00124   if (mesh.sizeFaces () != faces.size ())
00125   {
00126     if (verbose)
00127     {
00128       std::cerr << "Incorrect number of faces: " << mesh.sizeFaces () << " != " << faces.size () << "\n";
00129     }
00130     return (false);
00131   }
00132 
00133   const VertexDataCloud& vdc = mesh.getVertexDataCloud ();
00134   std::vector <int> vv;
00135   for (unsigned int i=0; i<mesh.sizeFaces (); ++i)
00136   {
00137     if (verbose) std::cerr << "Face " << std::setw (2) << i << ": ";
00138     VAFC       circ     = mesh.getVertexAroundFaceCirculator (FaceIndex (i));
00139     const VAFC circ_end = circ;
00140     vv.clear ();
00141     unsigned int counter = 0;
00142     do
00143     {
00144       if (verbose) std::cerr << std::setw (2) << vdc [circ.getTargetIndex ().get ()] << " ";
00145 
00146       // Avoid an infinite loop if connectivity is wrong
00147       if (++counter > max_number_polygon_vertices)
00148       {
00149         if (verbose) std::cerr << "... Infinite loop aborted.\n";
00150         return (false);
00151       }
00152       vv.push_back (vdc [circ.getTargetIndex ().get ()]);
00153     } while (++circ != circ_end);
00154 
00155     if (vv.size () != faces [i].size ())
00156     {
00157       std::cerr << "Wrong size!\n";
00158       return (false);
00159     }
00160     if (verbose) std::cerr << "\texpected: ";
00161     for (unsigned int j=0; j<vv.size (); ++j)
00162     {
00163       if (verbose) std::cerr << std::setw (2) << faces [i][j] << " ";
00164       if (vv [j] != faces [i][j])
00165       {
00166         if (verbose) std::cerr << "\n";
00167         return (false);
00168       }
00169     }
00170     if (verbose) std::cerr << "\n";
00171   }
00172   return (true);
00173 }
00174 
00176 
00178 template <class MeshT> typename MeshT::VertexIndices
00179 getBoundaryVertices (const MeshT& mesh, const typename MeshT::VertexIndex& first, const bool verbose = false)
00180 {
00181   typedef typename MeshT::VertexAroundFaceCirculator VAFC;
00182   typedef typename MeshT::HalfEdgeIndex              HalfEdgeIndex;
00183   typedef typename MeshT::VertexIndices              VertexIndices;
00184 
00185   const HalfEdgeIndex boundary_he = mesh.getOutgoingHalfEdgeIndex (first);
00186   if (!mesh.isBoundary (boundary_he))
00187   {
00188     if (verbose) std::cerr << "Vertex " << first << "with outgoing half_edge "
00189                            << mesh.getOriginatingVertexIndex (boundary_he) << "-"
00190                            << mesh.getTerminatingVertexIndex (boundary_he) << " is not on the boundary!\n";
00191     return (VertexIndices ());
00192   }
00193 
00194   VAFC       circ     = mesh.getVertexAroundFaceCirculator (boundary_he);
00195   const VAFC circ_end = circ;
00196 
00197   VertexIndices boundary_vertices;
00198 
00199   unsigned int counter = 0;
00200   do
00201   {
00202     if (verbose) std::cerr << circ.getTargetIndex () << " ";
00203     // Avoid an infinite loop if connectivity is wrong
00204     if (++counter > max_number_boundary_vertices)
00205     {
00206       if (verbose) std::cerr << "... Infinite loop aborted.\n";
00207       return (VertexIndices ());
00208     }
00209     boundary_vertices.push_back (circ.getTargetIndex ());
00210   } while (++circ != circ_end);
00211   if (verbose) std::cerr << "\n";
00212   return (boundary_vertices);
00213 }
00214 
00216 
00218 template <class MeshT> std::vector <int>
00219 getBoundaryVertices (const MeshT& mesh, const int first, const bool verbose = false)
00220 {
00221   typedef typename MeshT::VertexAroundFaceCirculator VAFC;
00222   typedef typename MeshT::VertexIndex                VertexIndex;
00223   typedef typename MeshT::HalfEdgeIndex              HalfEdgeIndex;
00224 
00225   const HalfEdgeIndex boundary_he = mesh.getOutgoingHalfEdgeIndex (VertexIndex (first));
00226   if (!mesh.isBoundary (boundary_he))
00227   {
00228     if (verbose) std::cerr << "Vertex " << first << "with outgoing half_edge "
00229                            << mesh.getOriginatingVertexIndex (boundary_he) << "-"
00230                            << mesh.getTerminatingVertexIndex (boundary_he) << " is not on the boundary!\n";
00231     return (std::vector <int> ());
00232   }
00233 
00234   VAFC       circ     = mesh.getVertexAroundFaceCirculator (boundary_he);
00235   const VAFC circ_end = circ;
00236 
00237   std::vector <int> boundary_vertices;
00238 
00239   unsigned int counter = 0;
00240   do
00241   {
00242     if (verbose) std::cerr << mesh.getVertexDataCloud () [circ.getTargetIndex ().get ()] << " ";
00243     // Avoid an infinite loop if connectivity is wrong
00244     if (++counter > max_number_boundary_vertices)
00245     {
00246       if (verbose) std::cerr << "... Infinite loop aborted.\n";
00247       return (std::vector <int> ());
00248     }
00249     boundary_vertices.push_back (mesh.getVertexDataCloud () [circ.getTargetIndex ().get ()]);
00250   } while (++circ != circ_end);
00251   if (verbose) std::cerr << "\n";
00252   return (boundary_vertices);
00253 }
00254 
00256 
00260 template <class ContainerT> bool
00261 isCircularPermutation (const ContainerT& expected, const ContainerT& actual, const bool verbose = false)
00262 {
00263   const unsigned int n = static_cast <unsigned int> (expected.size ());
00264   EXPECT_EQ (n, actual.size ());
00265   if (n != actual.size ())
00266   {
00267     if (verbose) std::cerr << "expected.size () != actual.size (): " << n << " != " << actual.size () << "\n";
00268     return (false);
00269   }
00270 
00271   for (unsigned int i=0; i<n; ++i)
00272   {
00273     bool all_equal = true;
00274     for (unsigned int j=0; j<n; ++j)
00275     {
00276       if (verbose) std::cerr << actual [(i+j)%n] << " " << expected [j];
00277       if (actual [(i+j)%n] != expected [j])
00278       {
00279         all_equal = false;
00280       }
00281       if (verbose) std::cerr << " | ";
00282     }
00283     if (all_equal)
00284     {
00285       if (verbose) std::cerr << " SUCCESS\n";
00286       return (true);
00287     }
00288     if (verbose) std::cerr << "\n";
00289   }
00290   return (false);
00291 }
00292 
00294 
00296 template <class ContainerT> bool
00297 isCircularPermutationVec (const std::vector <ContainerT> expected, const std::vector <ContainerT> actual, const bool verbose = false)
00298 {
00299   const unsigned int n = static_cast<unsigned int> (expected.size ());
00300   EXPECT_EQ (n, actual.size ());
00301   if (n != actual.size ())
00302   {
00303     if (verbose) std::cerr << "expected.size () != actual.size (): " << n << " != " << actual.size () << "\n";
00304     return (false);
00305   }
00306 
00307   for (unsigned int i=0; i<n; ++i)
00308   {
00309     bool all_equal = true;
00310     for (unsigned int j=0; j<n; ++j)
00311     {
00312       if (verbose) std::cerr << "\n";
00313       if (!isCircularPermutation (expected [j], actual [(i+j)%n], verbose))
00314       {
00315         all_equal = false;
00316       }
00317     }
00318     if (verbose) std::cerr << "\n";
00319     if (all_equal)
00320     {
00321       return (true);
00322     }
00323   }
00324   return (false);
00325 }
00326 
00328 
00332 template <class MeshT> typename MeshT::HalfEdgeIndex
00333 findHalfEdge (const MeshT&                       mesh,
00334               const typename MeshT::VertexIndex& idx_v_0,
00335               const typename MeshT::VertexIndex& idx_v_1)
00336 {
00337   typedef typename MeshT::HalfEdgeIndex                HalfEdgeIndex;
00338   typedef typename MeshT::VertexAroundVertexCirculator VAVC;
00339 
00340   if (mesh.isIsolated (idx_v_0) || mesh.isIsolated (idx_v_1))
00341   {
00342     return (HalfEdgeIndex ());
00343   }
00344 
00345   VAVC       circ     = mesh.getVertexAroundVertexCirculator (idx_v_0);
00346   const VAVC circ_end = circ;
00347 
00348   do
00349   {
00350     if (circ.getTargetIndex () == idx_v_1)
00351     {
00352       return (circ.getCurrentHalfEdgeIndex ());
00353     }
00354   } while (++circ != circ_end);
00355 
00356   return (HalfEdgeIndex ());
00357 }
00358 
00360 
00362 template <class MeshT> bool
00363 checkHalfEdge (const MeshT&                        mesh,
00364                const typename MeshT::HalfEdgeIndex ind_he_ab,
00365                const typename MeshT::VertexIndex   ind_v_a,
00366                const typename MeshT::VertexIndex   ind_v_b)
00367 {
00368   if (mesh.getOriginatingVertexIndex (ind_he_ab) != ind_v_a) return (false);
00369   if (mesh.getTerminatingVertexIndex (ind_he_ab) != ind_v_b) return (false);
00370   return (true);
00371 }
00372 
00374 
00375 #endif // PCL_TEST_GEOMETRY_TEST_MESH_COMMON_FUNCTIONS_H


pcl
Author(s): Open Perception
autogenerated on Wed Aug 26 2015 15:35:08