DGtal 1.4.0
Loading...
Searching...
No Matches
testMeshVoxelization.cpp
Go to the documentation of this file.
1
28#include <iostream>
29#include "ConfigTest.h"
30#include "DGtalCatch.h"
31#include "DGtal/shapes/MeshVoxelizer.h"
32#include "DGtal/kernel/sets/CDigitalSet.h"
33#include "DGtal/kernel/domains/HyperRectDomain.h"
34#include "DGtal/io/readers/MeshReader.h"
35#include "DGtal/io/Display3D.h"
36#include "DGtal/io/readers/MeshReader.h"
37#include "DGtal/io/boards/Board3D.h"
39
40using namespace DGtal;
41using namespace Z3i;
42
43TEST_CASE("Basic voxelization test", "[voxelization]")
44{
45 using PointR3 = PointVector<3, double>;
46 using VectorR3 = PointVector<3, double>;
47 using PointR2 = PointVector<2, double>;
48 using PointZ3 = PointVector<3, int>;
49
50 using MeshVoxelizer26 = MeshVoxelizer< DigitalSet, 26>;
51 using MeshVoxelizer6 = MeshVoxelizer< DigitalSet, 6>;
52
53 using TriOr = MeshVoxelizer6::TriangleOrientation;
54
55 // ---------------------------------------------------------
56 SECTION("Test distance point/plan 3D")
57 {
58 // Triangle ABC in R3
59 const PointR3 A(38.6908 , 14.5441 , -0.71205);
60 const PointR3 B(34.6171 , 13.5999 , 2.44455);
61 const PointR3 C(37.4205 , 2.44239 , 6.31301);
62
63 // Point v
64 const PointZ3 v(35, 2, 5);
65
66 const VectorR3 e1 = A - B;
67 const VectorR3 e2 = A - C;
68
69 double distance = MeshVoxelizer6::distance(A, e1.crossProduct(e2), v);
70
71 REQUIRE( 2.40 < distance );
72 REQUIRE( distance < 2.41 );
73 }
74
75 // ---------------------------------------------------------
76 SECTION("Test if 2D point is inside triangle 2D")
77 {
78 // Triangle ABC in R2
79 PointR2 A(1.0, 1.0);
80 PointR2 B(2.0, 3.0);
81 PointR2 C(3.0, 1.0);
82
83 typedef InHalfPlaneBySimple3x3Matrix<PointR2, double> OrientationFunctor;
84 OrientationFunctor orientationFunctor;
85
86 //geometric predicate
87 PredicateFromOrientationFunctor2<OrientationFunctor> pointPredicate( orientationFunctor );
88
89 if(! pointPredicate(A, B, C))
90 {
91 std::swap(A, C);
92 }
93
94 // Test if point v is inside triangle ABC
95 // 0 : outside
96 // 1 : inside
97 // 2 : on edge
98 // 3 : on vertex
99 PointR2 v;
100
101 v[0] = 3.0;
102 v[1] = 3.0;
103 REQUIRE(MeshVoxelizer6::pointIsInside2DTriangle(A, B, C, v) == TriOr::TRIANGLE_OUTSIDE);
104
105 v[0] = 2.0;
106 v[1] = 2.0;
107 REQUIRE(MeshVoxelizer6::pointIsInside2DTriangle(A, B, C, v) == TriOr::TRIANGLE_INSIDE);
108
109 v[0] = 2;
110 v[1] = 1;
111 REQUIRE(MeshVoxelizer6::pointIsInside2DTriangle(A, B, C, v) == TriOr::TRIANGLE_ONEDGE);
112
113 v[0] = 3;
114 v[1] = 1;
115 REQUIRE(MeshVoxelizer6::pointIsInside2DTriangle(A, B, C, v) == TriOr::TRIANGLE_ONVERTEX);
116
117 // another case
118 A = { 16.3299, 0. };
119 B = { 0., 16.3299 };
120 C = { -16.3299, 0. };
121 v = { -17., 0.};
122 REQUIRE(MeshVoxelizer6::pointIsInside2DTriangle(A, B, C, v) == TriOr::TRIANGLE_OUTSIDE);
123
124 // another case
125 A = { -0.891282, 9.91201 };
126 B = { -1.40823, 9.91261 };
127 C = { -1.36963, 9.37414 };
128 v = { -1.16961, 9.83039 };
129 REQUIRE(MeshVoxelizer6::pointIsInside2DTriangle(A, B, C, v) == TriOr::TRIANGLE_INSIDE);
130 }
131
132 // ---------------------------------------------------------
133 SECTION("Test if 3D point is inside voxel")
134 {
135 // Triangle ABC in R2
136 PointR3 P(-0.89, 9.91, 0.86);
137 PointZ3 v(-1, 10, 1);
138
139 REQUIRE(MeshVoxelizer6::pointIsInsideVoxel(P, v) == true); // inside
140
141 P[0] = -1.41;
142 P[1] = 9.91;
143 REQUIRE(MeshVoxelizer6::pointIsInsideVoxel(P, v) == true); // inside
144
145 P[0] = -1.37;
146 P[1] = 9.37;
147 REQUIRE(MeshVoxelizer6::pointIsInsideVoxel(P, v) == false); // outside
148
149 P[0] = -1.17;
150 P[1] = 9.83;
151 P[2] = 0;
152 REQUIRE(MeshVoxelizer6::pointIsInsideVoxel(P, v) == false); // outside
153 }
154
155 // ---------------------------------------------------------
156 SECTION("26-sep voxelization of a single triangle")
157 {
158 Domain domain(Point(0,0,0), Point(10,10,10));
159 DigitalSet outputSet(domain);
160 MeshVoxelizer26 voxelizer;
161
162 voxelizer.voxelize(outputSet, Point(5,0,0), Point(0,5,0), Point(0,0,5));
164 for(auto p: outputSet)
165 board << p ;
166 board.saveOBJ("triangle26-dig.obj");
167
168 REQUIRE( outputSet.size() == 46 );
169 }
170
171 // ---------------------------------------------------------
172 SECTION("6-sep voxelization of a single triangle")
173 {
174 Domain domain(Point(0,0,0), Point(10,10,10));
175 DigitalSet outputSet(domain);
176 MeshVoxelizer6 voxelizer;
177
178 voxelizer.voxelize(outputSet, Point(5,0,0), Point(0,5,0), Point(0,0,5));
180 for(auto p: outputSet)
181 board << p ;
182 board.saveOBJ("triangle6-dig.obj");
183
184 REQUIRE( outputSet.size() == 21 );
185 }
186
187 // ---------------------------------------------------------
188 SECTION("6-sep voxelization of a OFF cube mesh")
189 {
190 //Importing OFF mesh
191 Mesh<Z3i::RealPoint> inputMesh;
192 MeshReader<Z3i::RealPoint>::importOFFFile(testPath +"/samples/box.off" , inputMesh);
193 Z3i::Domain domain( Point().diagonal(-30), Point().diagonal(30));
194 DigitalSet outputSet(domain);
195 MeshVoxelizer6 voxelizer;
196
197 CAPTURE(inputMesh.nbFaces());
198
199 voxelizer.voxelize(outputSet, inputMesh, 10.0 );
201 for(auto p: outputSet)
202 board << p ;
203 board.saveOBJ("box6-dig.obj");
204
205 CAPTURE(outputSet.size());
206 //hard coded test.
207 REQUIRE( outputSet.size() == 2562 );
208 }
209 // ---------------------------------------------------------
210 SECTION("26-sep voxelization of a OFF cube mesh")
211 {
212 //Importing OFF mesh
213 Mesh<Z3i::RealPoint> inputMesh;
214 MeshReader<Z3i::RealPoint>::importOFFFile(testPath +"/samples/box.off" , inputMesh);
215 Z3i::Domain domain( Point().diagonal(-30), Point().diagonal(30));
216 DigitalSet outputSet(domain);
217 MeshVoxelizer26 voxelizer;
218
219 CAPTURE(inputMesh.nbFaces());
220
221 voxelizer.voxelize(outputSet, inputMesh, 10.0 );
223 for(auto p: outputSet)
224 board << p ;
225 board.saveOBJ("box26-dig.obj");
226
227 CAPTURE(outputSet.size());
228 //hard coded test.
229 REQUIRE( outputSet.size() == 4162 );
230 }
231}
The class Board3D is a type of Display3D which export the figures in the format OBJ/MTL when calling ...
Definition Board3D.h:82
void saveOBJ(const std::string &filename, const bool isNormalized=false)
Aim: A wrapper class around a STL associative container for storing sets of digital points within som...
Aim: Class that implements an orientation functor, ie. it provides a way to compute the orientation o...
Aim: A class for computing the digitization of a triangle or a Mesh.
Aim: This class is defined to represent a surface mesh through a set of vertices and faces....
Definition Mesh.h:92
Size nbFaces() const
Aim: Implements basic operations that will be used in Point and Vector classes.
Aim: Small adapter to models of COrientationFunctor2. It is a model of concepts::CPointPredicate....
Space::Point Point
Definition StdDefs.h:168
DGtal is the top-level namespace which contains all DGtal functions and types.
static bool importOFFFile(const std::string &filename, DGtal::Mesh< TPoint > &aMesh, bool invertVertexOrder=false, bool onlyFaceVertex=false)
CAPTURE(thicknessHV)
TEST_CASE("Basic voxelization test", "[voxelization]")
Domain domain
SECTION("Testing constant forward iterators")
REQUIRE(domain.isInside(aPoint))