184{
186 typedef Helper::Point
Point;
192 GIVEN(
"Given an octahedron star { (0,0,0), (-2,0,0), (2,0,0), (0,-2,0), (0,2,0), (0,0,-2), (0,0,2) } " ) {
193 std::vector<Point> V
194 = {
Point(0,0,0),
Point(-2,0,0),
Point(2,0,0),
Point(0,-2,0),
Point(0,2,0),
196 WHEN( "Computing its lattice polytope" ){
197 const auto P = Helper::computeLatticePolytope( V, false, true );
199 THEN( "The polytope is valid and has 8 non trivial facets plus 12 edge constraints" ) {
200 REQUIRE( P.nbHalfSpaces() - 6 == 20 );
201 }
202 THEN( "The polytope is Minkowski summable" ) {
204 }
205 THEN( "The polytope contains the input points" ) {
206 REQUIRE( P.isInside( V[ 0 ] ) );
207 REQUIRE( P.isInside( V[ 1 ] ) );
208 REQUIRE( P.isInside( V[ 2 ] ) );
209 REQUIRE( P.isInside( V[ 3 ] ) );
210 REQUIRE( P.isInside( V[ 4 ] ) );
211 REQUIRE( P.isInside( V[ 5 ] ) );
212 REQUIRE( P.isInside( V[ 6 ] ) );
213 }
214 THEN( "The polytope contains 25 points" ) {
216 }
217 THEN( "The interior of the polytope contains 7 points" ) {
218 REQUIRE( P.countInterior() == 7 );
219 }
220 THEN( "The boundary of the polytope contains 18 points" ) {
221 REQUIRE( P.countBoundary() == 18 );
222 }
223 }
224 WHEN( "Computing the boundary of its convex hull as a SurfaceMesh" ){
226 bool ok = Helper::computeConvexHullBoundary( smesh, V, false );
228 THEN( "The surface mesh is valid and has 6 vertices, 12 edges and 8 faces" ) {
233 }
234 THEN( "The surface mesh has the topology of a sphere" ) {
238 }
239 }
240 WHEN( "Computing the boundary of its convex hull as a lattice PolygonalSurface" ){
241 LatticePolySurf lpsurf;
242 bool ok = Helper::computeConvexHullBoundary( lpsurf, V, false );
244 THEN( "The polygonal surface is valid and has 6 vertices, 12 edges and 8 faces" ) {
246 REQUIRE( lpsurf.nbVertices() == 6 );
247 REQUIRE( lpsurf.nbEdges() == 12 );
248 REQUIRE( lpsurf.nbFaces() == 8 );
249 REQUIRE( lpsurf.nbArcs() == 24 );
250 }
251 THEN( "The polygonal surface has the topology of a sphere and no boundary" ) {
252 REQUIRE( lpsurf.Euler() == 2 );
253 REQUIRE( lpsurf.allBoundaryArcs().size() == 0 );
254 REQUIRE( lpsurf.allBoundaryVertices().size() == 0 );
255 }
256 }
257 WHEN( "Computing its convex hull as a ConvexCellComplex" ){
258 CvxCellComplex complex;
259 bool ok = Helper::computeConvexHullCellComplex( complex, V, false );
261 THEN( "The convex cell complex is valid and has 6 vertices, 8 faces and 1 finite cell" ) {
263 REQUIRE( complex.nbVertices() == 6 );
264 REQUIRE( complex.nbFaces() == 8 );
265 REQUIRE( complex.nbCells() == 1 );
266 }
267 }
268 WHEN( "Computing the vertices of its convex hull" ){
269 const auto X = Helper::computeConvexHullVertices( V, false );
271 THEN( "The polytope has 6 vertices" ) {
273 }
274 }
275 }
276 GIVEN(
"Given a cube with an additional outside vertex " ) {
277 std::vector<Point> V
278 = {
Point(-10,-10,-10),
Point(10,-10,-10),
Point(-10,10,-10),
Point(10,10,-10),
279 Point(-10,-10,10),
Point(10,-10,10),
Point(-10,10,10),
Point(10,10,10),
281 WHEN( "Computing its Delaunay cell complex" ){
282 CvxCellComplex complex;
283 bool ok = Helper::computeDelaunayCellComplex( complex, V, false );
285 THEN( "The complex has 2 cells, 10 faces, 9 vertices" ) {
287 REQUIRE( complex.nbCells() == 2 );
288 REQUIRE( complex.nbFaces() == 10 );
289 REQUIRE( complex.nbVertices() == 9 );
290 }
291 THEN( "The faces of cells are finite" ) {
292 bool ok_finite = true;
293 for ( CvxCellComplex::Size c = 0; c < complex.nbCells(); ++c ) {
294 const auto faces = complex.cellFaces( c );
295 for ( auto f : faces )
296 ok_finite = ok_finite && ! complex.isInfinite( complex.faceCell( f ) );
297 }
299 }
300 THEN( "The opposite of faces of cells are infinite except two" ) {
301 int nb_finite = 0;
302 for ( CvxCellComplex::Size c = 0; c < complex.nbCells(); ++c ) {
303 const auto faces = complex.cellFaces( c );
304 for ( auto f : faces ) {
305 const auto opp_f = complex.opposite( f );
306 nb_finite += complex.isInfinite( complex.faceCell( opp_f ) ) ? 0 : 1;
307 }
308 }
310 }
311 }
312 WHEN( "Computing the vertices of its convex hull" ){
313 const auto X = Helper::computeConvexHullVertices( V, false );
315 THEN( "The polytope has 9 vertices" ) {
317 }
318 }
319 }
320 GIVEN(
"Given a degenerated 1d polytope { (0,0,1), (3,-1,2), (9,-3,4), (-6,2,-1) } " ) {
321 std::vector<Point> V
322 = {
Point(0,0,1),
Point(3,-1,2),
Point(9,-3,4),
Point(-6,2,-1) };
323 WHEN( "Computing its lattice polytope" ){
324 const auto P = Helper::computeLatticePolytope( V, false, true );
326 THEN( "The polytope is valid and has 6 non trivial facets" ) {
327 REQUIRE( P.nbHalfSpaces() - 6 == 6 );
328 }
329 THEN( "The polytope contains 6 points" ) {
331 }
332 THEN( "The polytope contains no interior points" ) {
333 REQUIRE( P.countInterior() == 0 );
334 }
335 }
336 WHEN( "Computing the vertices of its convex hull" ){
337 auto X = Helper::computeConvexHullVertices( V, false );
338 std::sort( X.begin(), X.end() );
340 THEN( "The polytope is a segment defined by two points" ) {
344 }
345 }
346 }
347 GIVEN(
"Given a degenerated 1d simplex { (1,0,-1), Point(4,-1,-2), Point(10,-3,-4) } " ) {
348 std::vector<Point> V
350 WHEN( "Computing its lattice polytope" ){
351 const auto P = Helper::computeLatticePolytope( V, false, true );
353 THEN( "The polytope is valid and has 6 non trivial facets" ) {
354 REQUIRE( P.nbHalfSpaces() - 6 == 6 );
355 }
356 THEN( "The polytope contains 4 points" ) {
358 }
359 THEN( "The polytope contains no interior points" ) {
360 REQUIRE( P.countInterior() == 0 );
361 }
362 }
363 WHEN( "Computing the vertices of its convex hull" ){
364 auto X = Helper::computeConvexHullVertices( V, false );
365 std::sort( X.begin(), X.end() );
367 THEN( "The polytope is a segment defined by two points" ) {
371 }
372 }
373 }
374 GIVEN(
"Given a degenerated 2d polytope { (2,1,0), (1,0,1), (1,2,1), (0,1,2), (0,3,2) } " ) {
375 std::vector<Point> V
376 = {
Point(2,1,0),
Point(1,0,1),
Point(1,2,1),
Point(0,1,2),
Point(0,3,2) };
377 WHEN( "Computing its lattice polytope" ){
378 const auto P = Helper::computeLatticePolytope( V, false, true );
380 THEN( "The polytope is valid and has more than 6 non trivial facets" ) {
381 REQUIRE( P.nbHalfSpaces() - 6 == 6 );
382 }
383 THEN( "The polytope contains 7 points" ) {
385 }
386 THEN( "The polytope contains no interior points" ) {
387 REQUIRE( P.countInterior() == 0 );
388 }
389 }
390 WHEN( "Computing the vertices of its convex hull" ){
391 auto X = Helper::computeConvexHullVertices( V, false );
392 std::sort( X.begin(), X.end() );
394 THEN( "The polytope is a quad" ) {
400 }
401 }
402 }
403 GIVEN(
"Given a degenerated 2d simplex { (2,1,0), (1,0,1), (1,5,1), (0,3,2) } " ) {
404 std::vector<Point> V
405 = {
Point(2,1,0),
Point(1,0,1),
Point(1,5,1),
Point(0,3,2) };
406 WHEN( "Computing its lattice polytope" ){
407 const auto P = Helper::computeLatticePolytope( V, false, true );
409 THEN( "The polytope is valid and has more than 6 non trivial facets" ) {
410 REQUIRE( P.nbHalfSpaces() - 6 == 6 );
411 }
412 THEN( "The polytope contains 8 points" ) {
414 }
415 THEN( "The polytope contains no interior points" ) {
416 REQUIRE( P.countInterior() == 0 );
417 }
418 }
419 WHEN( "Computing the vertices of its convex hull" ){
420 auto X = Helper::computeConvexHullVertices( V, false );
421 std::sort( X.begin(), X.end() );
423 THEN( "The polytope is a quad" ) {
429 }
430 }
431 }
432}
Aim: Implements basic operations that will be used in Point and Vector classes.
Aim: Represents a polygon mesh, i.e. a 2-dimensional combinatorial surface whose faces are (topologic...
SurfaceMesh< RealPoint, RealVector > SMesh
Aim: Represents an embedded mesh as faces and a list of vertices. Vertices may be shared among faces ...
Edges computeManifoldBoundaryEdges() const
Edges computeNonManifoldEdges() const
PointVector< 3, double > RealPoint