9 #include <boost/test/data/test_case.hpp>
10 #include <boost/test/tools/output_test_stream.hpp>
11 #include <boost/test/unit_test.hpp>
57 using namespace UnitLiterals;
66 std::vector<std::tuple<std::string, bool, unsigned int>>
testModes = {
67 {
"",
false, 72}, {
"Triangulate",
true, 72}, {
"Extremas",
false, 1}};
69 auto transform = std::make_shared<Transform3D>(Transform3D::Identity());
71 BOOST_AUTO_TEST_SUITE(Surfaces)
75 std::vector<IdentifiedPolyderon> testTypes;
77 double hzpmin = 10
_mm;
79 double hzneg = -20
_mm;
81 double phiSector = 0.358;
82 ObjTestWriter::writeSectorPlanesObj(
"ConeSectorPlanes", phiSector, 0., hzpos,
86 unsigned int segments = std::get<unsigned int>(mode);
87 std::string modename = std::get<std::string>(mode);
88 bool modetrg = std::get<bool>(mode);
91 auto cone = std::make_shared<ConeBounds>(
alpha, 0
_mm, hzpos);
92 auto oneCone = Surface::makeShared<ConeSurface>(
transform, cone);
93 auto oneConePh = oneCone->polyhedronRepresentation(
tgContext, segments);
94 size_t expectedFaces = segments < 4 ? 4 : segments;
95 BOOST_CHECK_EQUAL(oneConePh.faces.size(), expectedFaces);
96 BOOST_CHECK_EQUAL(oneConePh.vertices.size(), expectedFaces + 1);
98 double r = hzpos * std::tan(alpha);
99 auto extent = oneConePh.extent();
108 testTypes.push_back({
"ConeOneFull" + modename, modetrg, oneConePh});
111 auto conePiece = std::make_shared<ConeBounds>(
alpha, hzpmin, hzpos);
112 auto oneConePiece = Surface::makeShared<ConeSurface>(
transform, conePiece);
113 auto oneConePiecePh =
114 oneConePiece->polyhedronRepresentation(
tgContext, segments);
115 expectedFaces = segments < 4 ? 4 : segments;
117 double rmin = hzpmin * std::tan(alpha);
118 extent = oneConePiecePh.extent();
128 {
"ConeOnePieceFull" + modename, modetrg, oneConePiecePh});
131 auto coneBoth = std::make_shared<ConeBounds>(
alpha, hzneg, hzpos);
132 auto twoCones = Surface::makeShared<ConeSurface>(
transform, coneBoth);
133 auto twoConesPh = twoCones->polyhedronRepresentation(
tgContext, segments);
134 expectedFaces = segments < 4 ? 8 : 2 * segments;
135 BOOST_CHECK_EQUAL(twoConesPh.faces.size(), expectedFaces);
136 BOOST_CHECK_EQUAL(twoConesPh.vertices.size(), expectedFaces + 1);
137 extent = twoConesPh.extent();
146 testTypes.push_back({
"ConesTwoFull" + modename, modetrg, twoConesPh});
150 std::make_shared<ConeBounds>(
alpha, hzneg, hzpos, phiSector, 0.);
152 Surface::makeShared<ConeSurface>(
transform, sectoralBoth);
153 auto sectoralConesPh =
154 sectoralCones->polyhedronRepresentation(
tgContext, segments);
155 extent = sectoralConesPh.extent();
161 testTypes.push_back({
"ConesSectoral" + modename, modetrg, sectoralConesPh});
163 ObjTestWriter::writeObj(testTypes);
171 double phiSector = 0.458;
172 double averagePhi = -1.345;
173 ObjTestWriter::writeSectorPlanesObj(
"CylinderCentralSectorPlanes", phiSector,
174 0., 1.5 * r, 1.5 * hZ);
175 ObjTestWriter::writeSectorPlanesObj(
"CylinderShiftedSectorPlanes", phiSector,
176 averagePhi, 1.5 * r, 1.5 * hZ);
178 std::vector<IdentifiedPolyderon> testTypes;
181 unsigned int segments = std::get<unsigned int>(mode);
182 std::string modename = std::get<std::string>(mode);
183 bool modetrg = std::get<bool>(mode);
185 size_t expectedFaces = segments < 4 ? 4 : segments;
186 size_t expectedVertices = segments < 4 ? 8 : 2 * segments;
189 auto cylinder = std::make_shared<CylinderBounds>(
r, hZ);
191 Surface::makeShared<CylinderSurface>(
transform, cylinder);
192 auto fullCylinderPh =
193 fullCylinder->polyhedronRepresentation(
tgContext, segments);
195 BOOST_CHECK_EQUAL(fullCylinderPh.faces.size(), expectedFaces);
196 BOOST_CHECK_EQUAL(fullCylinderPh.vertices.size(), expectedVertices);
198 auto extent = fullCylinderPh.extent();
207 testTypes.push_back({
"CylinderFull" + modename, modetrg, fullCylinderPh});
210 auto sectorCentered = std::make_shared<CylinderBounds>(
r, phiSector, hZ);
211 auto centerSectoredCylinder =
212 Surface::makeShared<CylinderSurface>(
transform, sectorCentered);
213 auto centerSectoredCylinderPh =
214 centerSectoredCylinder->polyhedronRepresentation(
tgContext, segments);
217 extent = centerSectoredCylinderPh.extent();
226 testTypes.push_back({
"CylinderSectorCentered" + modename, modetrg,
227 centerSectoredCylinderPh});
231 std::make_shared<CylinderBounds>(
r, averagePhi, phiSector, hZ);
232 auto shiftedSectoredCylinder =
233 Surface::makeShared<CylinderSurface>(
transform, sectorShifted);
234 auto shiftedSectoredCylinderPh =
235 shiftedSectoredCylinder->polyhedronRepresentation(
tgContext, segments);
238 extent = shiftedSectoredCylinderPh.extent();
243 testTypes.push_back({
"CylinderSectorShifted" + modename, modetrg,
244 shiftedSectoredCylinderPh});
247 ObjTestWriter::writeObj(testTypes);
252 std::vector<IdentifiedPolyderon> testTypes;
254 double innerR = 10
_mm;
255 double outerR = 25
_mm;
257 double phiSector = 0.345;
258 double averagePhi = -1.0;
260 double cphi = std::cos(phiSector);
261 double sphi = std::sin(phiSector);
263 std::pair<Vector3D, Vector3D> lineA = {
265 std::pair<Vector3D, Vector3D> lineB = {
267 ObjTestWriter::writeSectorLinesObj(
"DiscSectorLines", lineA, lineB);
269 double minPhi = averagePhi - phiSector;
270 double maxPhi = averagePhi + phiSector;
272 Vector3D(outerR * std::cos(minPhi), outerR * std::sin(minPhi), 0.)};
274 Vector3D(outerR * std::cos(maxPhi), outerR * std::sin(maxPhi), 0.)};
275 ObjTestWriter::writeSectorLinesObj(
"DiscSectorLinesShifted", lineA, lineB);
278 unsigned int segments = std::get<unsigned int>(mode);
279 std::string modename = std::get<std::string>(mode);
280 bool modetrg = std::get<bool>(mode);
283 auto disc = std::make_shared<RadialBounds>(0
_mm, outerR);
284 auto fullDisc = Surface::makeShared<DiscSurface>(
transform, disc);
285 auto fullDiscPh = fullDisc->polyhedronRepresentation(
tgContext, segments);
287 unsigned int expectedVertices = segments > 4 ? segments : 4;
288 unsigned int expectedFaces = 1;
290 BOOST_CHECK_EQUAL(fullDiscPh.faces.size(), expectedFaces);
291 BOOST_CHECK_EQUAL(fullDiscPh.vertices.size(), expectedVertices);
293 auto extent = fullDiscPh.extent();
303 testTypes.push_back({
"DiscFull" + modename, modetrg, fullDiscPh});
306 auto radial = std::make_shared<RadialBounds>(innerR, outerR);
307 auto radialDisc = Surface::makeShared<DiscSurface>(
transform, radial);
308 auto radialPh = radialDisc->polyhedronRepresentation(
tgContext, segments);
309 extent = radialPh.extent();
318 testTypes.push_back({
"DiscRing" + modename, modetrg, radialPh});
321 auto sector = std::make_shared<RadialBounds>(0., outerR, phiSector);
322 auto sectorDisc = Surface::makeShared<DiscSurface>(
transform, sector);
323 auto sectorPh = sectorDisc->polyhedronRepresentation(
tgContext, segments);
324 extent = sectorPh.extent();
335 testTypes.push_back({
"DiscSectorCentered" + modename, modetrg, sectorPh});
338 auto sectorRing = std::make_shared<RadialBounds>(innerR, outerR, phiSector);
339 auto sectorRingDisc =
340 Surface::makeShared<DiscSurface>(
transform, sectorRing);
341 auto sectorRingDiscPh =
342 sectorRingDisc->polyhedronRepresentation(
tgContext, segments);
343 extent = sectorRingDiscPh.extent();
356 {
"DiscRingSectorCentered" + modename, modetrg, sectorRingDiscPh});
359 auto sectorRingShifted =
360 std::make_shared<RadialBounds>(innerR, outerR, averagePhi, phiSector);
361 auto sectorRingDiscShifted =
362 Surface::makeShared<DiscSurface>(
transform, sectorRingShifted);
363 auto sectorRingDiscShiftedPh =
364 sectorRingDiscShifted->polyhedronRepresentation(
tgContext, segments);
365 extent = sectorRingDiscShiftedPh.extent();
371 {
"DiscRingSectorShifted" + modename, modetrg, sectorRingDiscShiftedPh});
374 double halfXmin = 10
_mm;
375 double halfXmax = 20
_mm;
376 auto trapezoidDisc = std::make_shared<DiscTrapezoidBounds>(
377 halfXmin, halfXmax, innerR, outerR, 0.);
378 auto trapezoidDiscSf =
379 Surface::makeShared<DiscSurface>(
transform, trapezoidDisc);
380 auto trapezoidDiscSfPh =
381 trapezoidDiscSf->polyhedronRepresentation(
tgContext, segments);
382 extent = trapezoidDiscSfPh.extent();
388 {
"DiscTrapezoidCentered" + modename, modetrg, trapezoidDiscSfPh});
390 auto trapezoidDiscShifted = std::make_shared<DiscTrapezoidBounds>(
391 halfXmin, halfXmax, innerR, outerR, averagePhi);
392 auto trapezoidDiscShiftedSf =
393 Surface::makeShared<DiscSurface>(
transform, trapezoidDiscShifted);
394 auto trapezoidDiscShiftedSfPh =
395 trapezoidDiscShiftedSf->polyhedronRepresentation(
tgContext, segments);
396 extent = trapezoidDiscShiftedSfPh.extent();
402 {
"DiscTrapezoidShifted" + modename, modetrg, trapezoidDiscShiftedSfPh});
406 double minPhiA = 0.75;
407 double maxPhiA = 1.4;
412 minPhiA, maxPhiA,
offset);
413 auto annulusDisc = Surface::makeShared<DiscSurface>(
transform, annulus);
415 annulusDisc->polyhedronRepresentation(
tgContext, segments);
418 {
"DiscAnnulus" + modename, modetrg, trapezoidDiscShiftedSfPh});
421 ObjTestWriter::writeObj(testTypes);
426 std::vector<IdentifiedPolyderon> testTypes;
430 double shiftY = 50
_mm;
431 auto rectangular = std::make_shared<RectangleBounds>(rhX, rhY);
435 auto shiftedTransform =
436 std::make_shared<Transform3D>(Transform3D::Identity());
437 shiftedTransform->pretranslate(shift);
439 Surface::makeShared<PlaneSurface>(shiftedTransform, rectangular);
440 auto shiftedPh = shiftedPlane->polyhedronRepresentation(
tgContext, 1);
441 auto shiftedExtent = shiftedPh.extent();
449 unsigned int segments = std::get<unsigned int>(mode);
450 std::string modename = std::get<std::string>(mode);
451 bool modetrg = std::get<bool>(mode);
454 auto rectangularPlane =
455 Surface::makeShared<PlaneSurface>(
transform, rectangular);
457 rectangularPlane->polyhedronRepresentation(
tgContext, segments);
458 auto extent = rectangularPh.extent();
465 std::sqrt(rhX * rhX + rhY * rhY), 1
e-6);
468 BOOST_CHECK(rectangularPh.vertices.size() == 4);
469 BOOST_CHECK(rectangularPh.faces.size() == 1);
470 std::vector<size_t> expectedRect = {0, 1, 2, 3};
471 BOOST_CHECK(rectangularPh.faces[0] == expectedRect);
472 testTypes.push_back({
"PlaneRectangle" + modename, modetrg, rectangularPh});
479 auto trapezoid = std::make_shared<TrapezoidBounds>(thX1, thX2, thY);
480 auto trapezoidalPlane =
481 Surface::makeShared<PlaneSurface>(
transform, trapezoid);
483 trapezoidalPlane->polyhedronRepresentation(
tgContext, segments);
484 extent = trapezoidalPh.extent();
493 std::sqrt(thX * thX + thY * thY), 1
e-6);
496 BOOST_CHECK(trapezoidalPh.vertices.size() == 4);
497 BOOST_CHECK(trapezoidalPh.faces.size() == 1);
498 std::vector<size_t> expectedTra = {0, 1, 2, 3};
499 BOOST_CHECK(trapezoidalPh.faces[0] == expectedTra);
500 testTypes.push_back({
"PlaneTrapezoid" + modename, modetrg, trapezoidalPh});
503 double rMaxX = 30
_mm;
504 double rMaxY = 40
_mm;
505 auto ellipse = std::make_shared<EllipseBounds>(0., 0., rMaxX, rMaxY);
506 auto ellipsoidPlane = Surface::makeShared<PlaneSurface>(
transform, ellipse);
508 ellipsoidPlane->polyhedronRepresentation(
tgContext, segments);
509 extent = ellispoidPh.extent();
519 testTypes.push_back({
"PlaneFullEllipse" + modename, modetrg, ellispoidPh});
521 double rMinX = 10
_mm;
522 double rMinY = 20
_mm;
524 std::make_shared<EllipseBounds>(rMinX, rMaxX, rMinY, rMaxY);
525 auto ellipsoidRingPlane =
526 Surface::makeShared<PlaneSurface>(
transform, ellipseRing);
527 auto ellispoidRingPh =
528 ellipsoidRingPlane->polyhedronRepresentation(
tgContext, segments);
530 extent = ellispoidPh.extent();
541 {
"PlaneRingEllipse" + modename, modetrg, ellispoidRingPh});
544 std::vector<Vector2D> vtxs = {
549 auto sextagon = std::make_shared<ConvexPolygonBounds<6>>(vtxs);
550 auto sextagonPlane = Surface::makeShared<PlaneSurface>(
transform, sextagon);
551 auto sextagonPlanePh =
552 sextagonPlane->polyhedronRepresentation(
tgContext, segments);
553 testTypes.push_back({
"PlaneSextagon" + modename, modetrg, sextagonPlanePh});
556 double hMinX = 10
_mm;
557 double hMedX = 20
_mm;
558 double hMaxX = 15
_mm;
559 double hMinY = 40
_mm;
560 double hMaxY = 50
_mm;
562 std::make_shared<DiamondBounds>(hMinX, hMedX, hMaxX, hMinY, hMaxY);
563 auto diamondPlane = Surface::makeShared<PlaneSurface>(
transform, diamond);
565 diamondPlane->polyhedronRepresentation(
tgContext, segments);
566 BOOST_CHECK(diamondPh.vertices.size() == 6);
567 BOOST_CHECK(diamondPh.faces.size() == 1);
568 extent = diamondPh.extent();
575 std::sqrt(hMaxX * hMaxX + hMaxY * hMaxY), 1
e-6);
578 testTypes.push_back({
"PlaneDiamond" + modename, modetrg, diamondPh});
580 ObjTestWriter::writeObj(testTypes);
583 BOOST_AUTO_TEST_SUITE_END()