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 #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
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
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
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
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
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