9 #include <boost/test/data/test_case.hpp>
10 #include <boost/test/tools/output_test_stream.hpp>
11 #include <boost/test/unit_test.hpp>
55 using namespace UnitLiterals;
64 std::vector<std::tuple<std::string, bool, unsigned int>>
testModes = {
65 {
"",
false, 72}, {
"Triangulate",
true, 72}, {
"Extremas",
false, 1}};
67 auto transform = std::make_shared<Transform3>(Transform3::Identity());
69 BOOST_AUTO_TEST_SUITE(Surfaces)
73 double hzpmin = 10_mm;
75 double hzneg = -20_mm;
77 double phiSector = 0.358;
80 unsigned int segments = std::get<unsigned int>(
mode);
82 bool modetrg = std::get<bool>(
mode);
85 auto cone = std::make_shared<ConeBounds>(
alpha, 0_mm, hzpos);
86 auto oneCone = Surface::makeShared<ConeSurface>(
transform, cone);
87 auto oneConePh = oneCone->polyhedronRepresentation(
tgContext, segments);
88 size_t expectedFaces = segments < 4 ? 4 : segments;
89 BOOST_CHECK_EQUAL(oneConePh.faces.size(), expectedFaces);
90 BOOST_CHECK_EQUAL(oneConePh.vertices.size(), expectedFaces + 1);
92 double r = hzpos * std::tan(alpha);
93 auto extent = oneConePh.extent();
104 auto conePiece = std::make_shared<ConeBounds>(
alpha, hzpmin, hzpos);
105 auto oneConePiece = Surface::makeShared<ConeSurface>(
transform, conePiece);
106 auto oneConePiecePh =
107 oneConePiece->polyhedronRepresentation(
tgContext, segments);
108 expectedFaces = segments < 4 ? 4 : segments;
110 double rmin = hzpmin * std::tan(alpha);
111 extent = oneConePiecePh.extent();
122 auto coneBoth = std::make_shared<ConeBounds>(
alpha, hzneg, hzpos);
123 auto twoCones = Surface::makeShared<ConeSurface>(
transform, coneBoth);
124 auto twoConesPh = twoCones->polyhedronRepresentation(
tgContext, segments);
125 expectedFaces = segments < 4 ? 8 : 2 * segments;
126 BOOST_CHECK_EQUAL(twoConesPh.faces.size(), expectedFaces);
127 BOOST_CHECK_EQUAL(twoConesPh.vertices.size(), expectedFaces + 1);
128 extent = twoConesPh.extent();
140 std::make_shared<ConeBounds>(
alpha, hzneg, hzpos, phiSector, 0.);
142 Surface::makeShared<ConeSurface>(
transform, sectoralBoth);
143 auto sectoralConesPh =
144 sectoralCones->polyhedronRepresentation(
tgContext, segments);
145 extent = sectoralConesPh.extent();
159 double phiSector = 0.458;
160 double averagePhi = -1.345;
163 unsigned int segments = std::get<unsigned int>(
mode);
165 bool modetrg = std::get<bool>(
mode);
167 size_t expectedFaces = segments < 4 ? 4 : segments;
168 size_t expectedVertices = segments < 4 ? 8 : 2 * segments;
171 auto cylinder = std::make_shared<CylinderBounds>(
r, hZ);
173 Surface::makeShared<CylinderSurface>(
transform, cylinder);
174 auto fullCylinderPh =
175 fullCylinder->polyhedronRepresentation(
tgContext, segments);
177 BOOST_CHECK_EQUAL(fullCylinderPh.faces.size(), expectedFaces);
178 BOOST_CHECK_EQUAL(fullCylinderPh.vertices.size(), expectedVertices);
180 auto extent = fullCylinderPh.extent();
191 auto sectorCentered = std::make_shared<CylinderBounds>(
r, phiSector, hZ);
192 auto centerSectoredCylinder =
193 Surface::makeShared<CylinderSurface>(
transform, sectorCentered);
194 auto centerSectoredCylinderPh =
195 centerSectoredCylinder->polyhedronRepresentation(
tgContext, segments);
198 extent = centerSectoredCylinderPh.extent();
210 std::make_shared<CylinderBounds>(
r, averagePhi, phiSector, hZ);
211 auto shiftedSectoredCylinder =
212 Surface::makeShared<CylinderSurface>(
transform, sectorShifted);
213 auto shiftedSectoredCylinderPh =
214 shiftedSectoredCylinder->polyhedronRepresentation(
tgContext, segments);
217 extent = shiftedSectoredCylinderPh.extent();
227 double innerR = 10_mm;
228 double outerR = 25_mm;
230 double phiSector = 0.345;
231 double averagePhi = -1.0;
233 double cphi = std::cos(phiSector);
234 double sphi = std::sin(phiSector);
236 std::pair<Vector3, Vector3> lineA = {
238 std::pair<Vector3, Vector3> lineB = {
241 double minPhi = averagePhi - phiSector;
242 double maxPhi = averagePhi + phiSector;
244 Vector3(outerR * std::cos(minPhi), outerR * std::sin(minPhi), 0.)};
246 Vector3(outerR * std::cos(maxPhi), outerR * std::sin(maxPhi), 0.)};
249 unsigned int segments = std::get<unsigned int>(
mode);
251 bool modetrg = std::get<bool>(
mode);
254 auto disc = std::make_shared<RadialBounds>(0_mm, outerR);
255 auto fullDisc = Surface::makeShared<DiscSurface>(
transform, disc);
256 auto fullDiscPh = fullDisc->polyhedronRepresentation(
tgContext, segments);
258 unsigned int expectedVertices = segments > 4 ? segments : 4;
259 unsigned int expectedFaces = 1;
261 BOOST_CHECK_EQUAL(fullDiscPh.faces.size(), expectedFaces);
262 BOOST_CHECK_EQUAL(fullDiscPh.vertices.size(), expectedVertices);
264 auto extent = fullDiscPh.extent();
275 auto radial = std::make_shared<RadialBounds>(innerR, outerR);
276 auto radialDisc = Surface::makeShared<DiscSurface>(
transform, radial);
277 auto radialPh = radialDisc->polyhedronRepresentation(
tgContext, segments);
278 extent = radialPh.extent();
289 auto sector = std::make_shared<RadialBounds>(0., outerR, phiSector);
290 auto sectorDisc = Surface::makeShared<DiscSurface>(
transform, sector);
291 auto sectorPh = sectorDisc->polyhedronRepresentation(
tgContext, segments);
292 extent = sectorPh.extent();
305 auto sectorRing = std::make_shared<RadialBounds>(innerR, outerR, phiSector);
306 auto sectorRingDisc =
307 Surface::makeShared<DiscSurface>(
transform, sectorRing);
308 auto sectorRingDiscPh =
309 sectorRingDisc->polyhedronRepresentation(
tgContext, segments);
310 extent = sectorRingDiscPh.extent();
324 auto sectorRingShifted =
325 std::make_shared<RadialBounds>(innerR, outerR, averagePhi, phiSector);
326 auto sectorRingDiscShifted =
327 Surface::makeShared<DiscSurface>(
transform, sectorRingShifted);
328 auto sectorRingDiscShiftedPh =
329 sectorRingDiscShifted->polyhedronRepresentation(
tgContext, segments);
330 extent = sectorRingDiscShiftedPh.extent();
337 double halfXmin = 10_mm;
338 double halfXmax = 20_mm;
339 auto trapezoidDisc = std::make_shared<DiscTrapezoidBounds>(
340 halfXmin, halfXmax, innerR, outerR, 0.);
341 auto trapezoidDiscSf =
342 Surface::makeShared<DiscSurface>(
transform, trapezoidDisc);
343 auto trapezoidDiscSfPh =
344 trapezoidDiscSf->polyhedronRepresentation(
tgContext, segments);
345 extent = trapezoidDiscSfPh.extent();
351 auto trapezoidDiscShifted = std::make_shared<DiscTrapezoidBounds>(
352 halfXmin, halfXmax, innerR, outerR, averagePhi);
353 auto trapezoidDiscShiftedSf =
354 Surface::makeShared<DiscSurface>(
transform, trapezoidDiscShifted);
355 auto trapezoidDiscShiftedSfPh =
356 trapezoidDiscShiftedSf->polyhedronRepresentation(
tgContext, segments);
357 extent = trapezoidDiscShiftedSfPh.extent();
365 double minPhiA = 0.75;
366 double maxPhiA = 1.4;
371 minPhiA, maxPhiA,
offset);
372 auto annulusDisc = Surface::makeShared<DiscSurface>(
transform, annulus);
374 annulusDisc->polyhedronRepresentation(
tgContext, segments);
382 double shiftY = 50_mm;
383 auto rectangular = std::make_shared<RectangleBounds>(rhX, rhY);
387 auto shiftedTransform = std::make_shared<Transform3>(Transform3::Identity());
388 shiftedTransform->pretranslate(shift);
390 Surface::makeShared<PlaneSurface>(shiftedTransform, rectangular);
391 auto shiftedPh = shiftedPlane->polyhedronRepresentation(
tgContext, 1);
392 auto shiftedExtent = shiftedPh.extent();
400 unsigned int segments = std::get<unsigned int>(
mode);
402 bool modetrg = std::get<bool>(
mode);
405 auto rectangularPlane =
406 Surface::makeShared<PlaneSurface>(
transform, rectangular);
408 rectangularPlane->polyhedronRepresentation(
tgContext, segments);
409 auto extent = rectangularPh.extent();
416 std::hypot(rhX, rhY), 1
e-6);
419 BOOST_CHECK(rectangularPh.vertices.size() == 4);
420 BOOST_CHECK(rectangularPh.faces.size() == 1);
421 std::vector<size_t> expectedRect = {0, 1, 2, 3};
422 BOOST_CHECK(rectangularPh.faces[0] == expectedRect);
429 auto trapezoid = std::make_shared<TrapezoidBounds>(thX1, thX2, thY);
430 auto trapezoidalPlane =
431 Surface::makeShared<PlaneSurface>(
transform, trapezoid);
433 trapezoidalPlane->polyhedronRepresentation(
tgContext, segments);
434 extent = trapezoidalPh.extent();
436 double thX = std::max(thX1, thX2);
443 std::hypot(thX, thY), 1
e-6);
446 BOOST_CHECK(trapezoidalPh.vertices.size() == 4);
447 BOOST_CHECK(trapezoidalPh.faces.size() == 1);
448 std::vector<size_t> expectedTra = {0, 1, 2, 3};
449 BOOST_CHECK(trapezoidalPh.faces[0] == expectedTra);
452 double rMaxX = 30_mm;
453 double rMaxY = 40_mm;
454 auto ellipse = std::make_shared<EllipseBounds>(0., 0., rMaxX, rMaxY);
455 auto ellipsoidPlane = Surface::makeShared<PlaneSurface>(
transform, ellipse);
457 ellipsoidPlane->polyhedronRepresentation(
tgContext, segments);
458 extent = ellispoidPh.extent();
468 double rMinX = 10_mm;
469 double rMinY = 20_mm;
471 std::make_shared<EllipseBounds>(rMinX, rMaxX, rMinY, rMaxY);
472 auto ellipsoidRingPlane =
473 Surface::makeShared<PlaneSurface>(
transform, ellipseRing);
474 auto ellispoidRingPh =
475 ellipsoidRingPlane->polyhedronRepresentation(
tgContext, segments);
477 extent = ellispoidPh.extent();
488 std::vector<Vector2> vtxs = {
493 auto sextagon = std::make_shared<ConvexPolygonBounds<6>>(vtxs);
494 auto sextagonPlane = Surface::makeShared<PlaneSurface>(
transform, sextagon);
495 auto sextagonPlanePh =
496 sextagonPlane->polyhedronRepresentation(
tgContext, segments);
499 double hMinX = 10_mm;
500 double hMedX = 20_mm;
501 double hMaxX = 15_mm;
502 double hMinY = 40_mm;
503 double hMaxY = 50_mm;
505 std::make_shared<DiamondBounds>(hMinX, hMedX, hMaxX, hMinY, hMaxY);
506 auto diamondPlane = Surface::makeShared<PlaneSurface>(
transform, diamond);
508 diamondPlane->polyhedronRepresentation(
tgContext, segments);
509 BOOST_CHECK(diamondPh.vertices.size() == 6);
510 BOOST_CHECK(diamondPh.faces.size() == 1);
511 extent = diamondPh.extent();
518 std::hypot(hMaxX, hMaxY), 1
e-6);
524 BOOST_AUTO_TEST_SUITE_END()