File indexing completed on 2026-10-19 08:35:38
0001
0002
0003
0004
0005
0006
0007
0008
0009 #include <boost/test/data/monomorphic/fwd.hpp>
0010 #include <boost/test/data/test_case.hpp>
0011 #include <boost/test/tools/context.hpp>
0012 #include <boost/test/tools/old/interface.hpp>
0013 #include <boost/test/unit_test.hpp>
0014 #include <boost/test/unit_test_suite.hpp>
0015
0016 #include "Acts/Definitions/Algebra.hpp"
0017 #include "Acts/Definitions/Units.hpp"
0018 #include "Acts/Geometry/CuboidPortalShell.hpp"
0019 #include "Acts/Geometry/CuboidVolumeBounds.hpp"
0020 #include "Acts/Geometry/CylinderVolumeBounds.hpp"
0021 #include "Acts/Geometry/GridPortalLink.hpp"
0022 #include "Acts/Geometry/Portal.hpp"
0023 #include "Acts/Geometry/TrackingVolume.hpp"
0024 #include "Acts/Geometry/TrivialPortalLink.hpp"
0025 #include "Acts/Utilities/AxisDefinitions.hpp"
0026 #include "Acts/Utilities/ThrowAssert.hpp"
0027
0028 #include <cstddef>
0029 #include <initializer_list>
0030 #include <memory>
0031 #include <stdexcept>
0032 #include <utility>
0033
0034 using namespace Acts;
0035 using namespace Acts::UnitLiterals;
0036
0037 namespace ActsTests {
0038 auto gctx = GeometryContext::dangerouslyDefaultConstruct();
0039
0040 std::size_t getVolumeIndex() {
0041 static std::size_t i = 1;
0042 return i++;
0043 }
0044
0045 auto makeVolume(auto&&... pars) {
0046 TrackingVolume vol(Transform3::Identity(),
0047 std::make_shared<CuboidVolumeBounds>(
0048 std::forward<decltype(pars)>(pars)...));
0049 vol.setVolumeName("cube" + std::to_string(getVolumeIndex()));
0050 return vol;
0051 };
0052
0053 auto logger = getDefaultLogger("UnitTests", Logging::VERBOSE);
0054
0055 BOOST_AUTO_TEST_SUITE(GeometrySuite)
0056
0057 BOOST_AUTO_TEST_CASE(ConstructionFromVolume) {
0058 auto cube = makeVolume(30_mm, 40_mm, 50_mm);
0059
0060 TrackingVolume cylVolume(
0061 Transform3::Identity(),
0062 std::make_shared<CylinderVolumeBounds>(10_mm, 20_mm, 10_mm));
0063
0064 BOOST_CHECK_THROW(SingleCuboidPortalShell(gctx, cylVolume),
0065 std::invalid_argument);
0066
0067 SingleCuboidPortalShell shell1{gctx, cube};
0068 BOOST_CHECK_EQUAL(shell1.size(), 6);
0069
0070 using enum CuboidVolumeBounds::Face;
0071
0072
0073 const auto pXY = shell1.portal(PositiveZFace);
0074 BOOST_REQUIRE_NE(pXY, nullptr);
0075 BOOST_CHECK_EQUAL(
0076 pXY->resolveVolume(gctx, Vector3{25_mm, 20_mm, 50_mm}, -Vector3::UnitZ())
0077 .value(),
0078 &cube);
0079 BOOST_CHECK_EQUAL(
0080 pXY->resolveVolume(gctx, Vector3{25_mm, 20_mm, 50_mm}, Vector3::UnitZ())
0081 .value(),
0082 nullptr);
0083
0084 const auto nXY = shell1.portal(NegativeZFace);
0085 BOOST_REQUIRE_NE(nXY, nullptr);
0086 BOOST_CHECK_EQUAL(
0087 nXY->resolveVolume(gctx, Vector3{25_mm, 20_mm, -50_mm}, -Vector3::UnitZ())
0088 .value(),
0089 nullptr);
0090 BOOST_CHECK_EQUAL(
0091 nXY->resolveVolume(gctx, Vector3{25_mm, 20_mm, -50_mm}, Vector3::UnitZ())
0092 .value(),
0093 &cube);
0094
0095
0096 const auto pYZ = shell1.portal(PositiveXFace);
0097 BOOST_REQUIRE_NE(pYZ, nullptr);
0098 BOOST_CHECK_EQUAL(
0099 pYZ->resolveVolume(gctx, Vector3{30_mm, 10_mm, 30_mm}, -Vector3::UnitX())
0100 .value(),
0101 &cube);
0102 BOOST_CHECK_EQUAL(
0103 pYZ->resolveVolume(gctx, Vector3{30_mm, 10_mm, 30_mm}, Vector3::UnitX())
0104 .value(),
0105 nullptr);
0106
0107 const auto nYZ = shell1.portal(NegativeXFace);
0108 BOOST_REQUIRE_NE(nYZ, nullptr);
0109 BOOST_CHECK_EQUAL(
0110 nYZ->resolveVolume(gctx, Vector3{-30_mm, 10_mm, 30_mm}, -Vector3::UnitX())
0111 .value(),
0112 nullptr);
0113 BOOST_CHECK_EQUAL(
0114 nYZ->resolveVolume(gctx, Vector3{-30_mm, 10_mm, 30_mm}, Vector3::UnitX())
0115 .value(),
0116 &cube);
0117
0118
0119 const auto pZX = shell1.portal(PositiveYFace);
0120 BOOST_REQUIRE_NE(pZX, nullptr);
0121 BOOST_CHECK_EQUAL(
0122 pZX->resolveVolume(gctx, Vector3{15_mm, 40_mm, -10_mm}, -Vector3::UnitY())
0123 .value(),
0124 &cube);
0125 BOOST_CHECK_EQUAL(
0126 pZX->resolveVolume(gctx, Vector3{15_mm, 40_mm, -10_mm}, Vector3::UnitY())
0127 .value(),
0128 nullptr);
0129
0130 const auto nZX = shell1.portal(NegativeYFace);
0131 BOOST_REQUIRE_NE(nZX, nullptr);
0132 BOOST_CHECK_EQUAL(nZX->resolveVolume(gctx, Vector3{15_mm, -40_mm, -10_mm},
0133 -Vector3::UnitY())
0134 .value(),
0135 nullptr);
0136 BOOST_CHECK_EQUAL(
0137 nZX->resolveVolume(gctx, Vector3{15_mm, -40_mm, -10_mm}, Vector3::UnitY())
0138 .value(),
0139 &cube);
0140 }
0141
0142 BOOST_AUTO_TEST_CASE(PortalAssignment) {
0143 using enum CuboidVolumeBounds::Face;
0144 TrackingVolume vol(Transform3::Identity(),
0145 std::make_shared<CuboidVolumeBounds>(30_mm, 40_mm, 50_mm));
0146
0147 SingleCuboidPortalShell shell{gctx, vol};
0148
0149 const auto pXY = shell.portal(PositiveZFace);
0150 const auto nXY = shell.portal(NegativeZFace);
0151 const auto nYZ = shell.portal(NegativeXFace);
0152 const auto pZX = shell.portal(PositiveYFace);
0153 auto pYZ = shell.portal(PositiveXFace);
0154 auto nZX = shell.portal(NegativeYFace);
0155
0156
0157 BOOST_REQUIRE_NE(pYZ, nullptr);
0158 auto* pYZLink = dynamic_cast<const TrivialPortalLink*>(
0159 pYZ->getLink(Direction::OppositeNormal()));
0160 BOOST_REQUIRE_NE(pYZLink, nullptr);
0161
0162 auto grid = pYZLink->makeGrid(AxisDirection::AxisX);
0163
0164 auto portal2 =
0165 std::make_shared<Portal>(Direction::OppositeNormal(), std::move(grid));
0166 shell.setPortal(portal2, PositiveXFace);
0167 BOOST_CHECK_EQUAL(shell.portal(PositiveXFace), portal2);
0168
0169
0170 BOOST_CHECK_EQUAL(shell.portal(PositiveZFace), pXY);
0171 BOOST_CHECK_EQUAL(shell.portal(NegativeZFace), nXY);
0172 BOOST_CHECK_EQUAL(shell.portal(NegativeXFace), nYZ);
0173 BOOST_CHECK_EQUAL(shell.portal(PositiveYFace), pZX);
0174 BOOST_CHECK_EQUAL(shell.portal(NegativeYFace), nZX);
0175
0176
0177 BOOST_REQUIRE_NE(nZX, nullptr);
0178 auto* nZXLink = dynamic_cast<const TrivialPortalLink*>(
0179 nZX->getLink(Direction::AlongNormal()));
0180 BOOST_REQUIRE_NE(nZXLink, nullptr);
0181
0182 grid = nZXLink->makeGrid(AxisDirection::AxisY);
0183
0184 auto portal3 =
0185 std::make_shared<Portal>(Direction::AlongNormal(), std::move(grid));
0186 shell.setPortal(portal3, NegativeYFace);
0187 BOOST_CHECK_EQUAL(shell.portal(NegativeYFace), portal3);
0188
0189
0190 BOOST_CHECK_EQUAL(shell.portal(PositiveZFace), pXY);
0191 BOOST_CHECK_EQUAL(shell.portal(NegativeZFace), nXY);
0192 BOOST_CHECK_EQUAL(shell.portal(NegativeXFace), nYZ);
0193 BOOST_CHECK_EQUAL(shell.portal(PositiveYFace), pZX);
0194 BOOST_CHECK_EQUAL(shell.portal(PositiveXFace), portal2);
0195 }
0196
0197 BOOST_AUTO_TEST_SUITE(CuboidStack)
0198 BOOST_DATA_TEST_CASE(XYZDirection,
0199 boost::unit_test::data::make(AxisDirection::AxisX,
0200 AxisDirection::AxisY,
0201 AxisDirection::AxisZ) *
0202 boost::unit_test::data::make(0_degree, 180_degree),
0203 dir, angle) {
0204 AxisDirection dirOrth1{};
0205 AxisDirection dirOrth2{};
0206 std::size_t dirIdx = 0;
0207 switch (dir) {
0208 case AxisDirection::AxisX:
0209 dirOrth1 = AxisDirection::AxisY;
0210 dirOrth2 = AxisDirection::AxisZ;
0211 dirIdx = 0;
0212 break;
0213 case AxisDirection::AxisY:
0214 dirOrth1 = AxisDirection::AxisX;
0215 dirOrth2 = AxisDirection::AxisZ;
0216 dirIdx = 1;
0217 break;
0218 case AxisDirection::AxisZ:
0219 dirOrth1 = AxisDirection::AxisX;
0220 dirOrth2 = AxisDirection::AxisY;
0221 dirIdx = 2;
0222 break;
0223 default:
0224 throw std::invalid_argument("Invalid direction");
0225 }
0226
0227 auto boundDir = CuboidVolumeBounds::boundsFromAxisDirection(dir);
0228 auto boundDirOrth1 = CuboidVolumeBounds::boundsFromAxisDirection(dirOrth1);
0229 auto boundDirOrth2 = CuboidVolumeBounds::boundsFromAxisDirection(dirOrth2);
0230
0231 auto [frontFace, backFace, sideFaces] =
0232 CuboidVolumeBounds::facesFromAxisDirection(dir);
0233
0234 using enum CuboidVolumeBounds::Face;
0235 auto bounds1 = std::make_shared<CuboidVolumeBounds>(
0236 std::initializer_list<std::pair<CuboidVolumeBounds::BoundValues, double>>{
0237 {boundDir, 100_mm}, {boundDirOrth1, 30_mm}, {boundDirOrth2, 100_mm}});
0238
0239 auto bounds2 = std::make_shared<CuboidVolumeBounds>(
0240 std::initializer_list<std::pair<CuboidVolumeBounds::BoundValues, double>>{
0241 {boundDir, 100_mm}, {boundDirOrth1, 30_mm}, {boundDirOrth2, 100_mm}});
0242
0243
0244
0245 const Transform3 placement =
0246 Translation3{Vector3{10_mm, 20_mm, 30_mm}} *
0247 AngleAxis3{angle, Vector3::Unit((dirIdx + 1) % 3)};
0248 TrackingVolume vol1(placement * Translation3{Vector3::Unit(dirIdx) * -100_mm},
0249 bounds1);
0250 TrackingVolume vol2(placement * Translation3{Vector3::Unit(dirIdx) * 100_mm},
0251 bounds2);
0252
0253 SingleCuboidPortalShell shell1{gctx, vol1};
0254 SingleCuboidPortalShell shell2{gctx, vol2};
0255
0256 std::map<CuboidVolumeBounds::Face, Vector3> centers1;
0257 std::map<CuboidVolumeBounds::Face, Vector3> centers2;
0258 for (const auto face : sideFaces) {
0259 Vector3 normal{};
0260 switch (face) {
0261 case NegativeZFace:
0262 normal = Vector3::UnitZ();
0263 break;
0264 case PositiveZFace:
0265 normal = -Vector3::UnitZ();
0266 break;
0267 case NegativeYFace:
0268 normal = Vector3::UnitY();
0269 break;
0270 case PositiveYFace:
0271 normal = -Vector3::UnitY();
0272 break;
0273 case NegativeXFace:
0274 normal = Vector3::UnitX();
0275 break;
0276 case PositiveXFace:
0277 normal = -Vector3::UnitX();
0278 break;
0279 }
0280
0281 normal = placement.linear() * normal;
0282
0283 const auto center1 = shell1.portal(face)->surface().center(gctx);
0284 const auto center2 = shell2.portal(face)->surface().center(gctx);
0285
0286 centers1[face] = center1;
0287 centers2[face] = center2;
0288
0289 BOOST_CHECK_EQUAL(
0290 shell1.portal(face)->resolveVolume(gctx, center1, normal).value(),
0291 &vol1);
0292 BOOST_CHECK_EQUAL(
0293 shell1.portal(face)->resolveVolume(gctx, center1, -normal).value(),
0294 nullptr);
0295
0296 BOOST_CHECK_EQUAL(
0297 shell2.portal(face)->resolveVolume(gctx, center2, normal).value(),
0298 &vol2);
0299 BOOST_CHECK_EQUAL(
0300 shell2.portal(face)->resolveVolume(gctx, center2, -normal).value(),
0301 nullptr);
0302 }
0303
0304 BOOST_CHECK_NE(shell1.portal(backFace), shell2.portal(frontFace));
0305
0306 CuboidStackPortalShell stack(gctx, {&shell1, &shell2}, dir, *logger);
0307 BOOST_CHECK_EQUAL(stack.size(), 6);
0308
0309 BOOST_CHECK_EQUAL(shell1.portal(frontFace), stack.portal(frontFace));
0310 BOOST_CHECK_EQUAL(shell1.portal(backFace), shell2.portal(frontFace));
0311 BOOST_CHECK_EQUAL(shell2.portal(backFace), stack.portal(backFace));
0312
0313 for (const auto& face : sideFaces) {
0314 Vector3 normal{};
0315 switch (face) {
0316 case NegativeZFace:
0317 normal = Vector3::UnitZ();
0318 break;
0319 case PositiveZFace:
0320 normal = -Vector3::UnitZ();
0321 break;
0322 case NegativeYFace:
0323 normal = Vector3::UnitY();
0324 break;
0325 case PositiveYFace:
0326 normal = -Vector3::UnitY();
0327 break;
0328 case NegativeXFace:
0329 normal = Vector3::UnitX();
0330 break;
0331 case PositiveXFace:
0332 normal = -Vector3::UnitX();
0333 break;
0334 }
0335
0336 normal = placement.linear() * normal;
0337
0338 BOOST_CHECK_EQUAL(shell1.portal(face), stack.portal(face));
0339 BOOST_CHECK_EQUAL(shell2.portal(face), stack.portal(face));
0340
0341 const auto& center1 = centers1.at(face);
0342 const auto& center2 = centers2.at(face);
0343
0344 BOOST_CHECK_EQUAL(
0345 shell1.portal(face)->resolveVolume(gctx, center1, normal).value(),
0346 &vol1);
0347 BOOST_CHECK_EQUAL(
0348 shell1.portal(face)->resolveVolume(gctx, center1, -normal).value(),
0349 nullptr);
0350
0351 BOOST_CHECK_EQUAL(
0352 shell2.portal(face)->resolveVolume(gctx, center2, normal).value(),
0353 &vol2);
0354 BOOST_CHECK_EQUAL(
0355 shell2.portal(face)->resolveVolume(gctx, center2, -normal).value(),
0356 nullptr);
0357 }
0358
0359 shell1 = SingleCuboidPortalShell{gctx, vol1};
0360 shell2 = SingleCuboidPortalShell{gctx, vol2};
0361
0362 BOOST_CHECK_THROW(CuboidStackPortalShell(gctx, {&shell2, &shell1}, dir),
0363 AssertionFailureException);
0364
0365 BOOST_CHECK_NE(shell1.portal(backFace), shell2.portal(frontFace));
0366 for (const auto face : sideFaces) {
0367 BOOST_CHECK_NE(shell1.portal(face), shell2.portal(face));
0368 }
0369
0370 BOOST_CHECK_THROW(
0371 CuboidStackPortalShell(gctx, {&shell1, &shell2}, AxisDirection::AxisR),
0372 std::invalid_argument);
0373 }
0374
0375 BOOST_AUTO_TEST_CASE(EmptyStack) {
0376 BOOST_CHECK_THROW(CuboidStackPortalShell(gctx, {}, AxisDirection::AxisZ),
0377 AssertionFailureException);
0378 }
0379
0380 BOOST_AUTO_TEST_CASE(NestedStacks) {
0381
0382
0383
0384
0385
0386
0387
0388
0389
0390
0391
0392
0393
0394
0395
0396
0397
0398
0399
0400
0401
0402
0403
0404
0405 Transform3 base = Transform3::Identity();
0406
0407 TrackingVolume vol1(
0408 base, std::make_shared<CuboidVolumeBounds>(30_mm, 100_mm, 200_mm),
0409 "vol1");
0410
0411 TrackingVolume vol2(
0412 base * Translation3(Vector3::UnitZ() * 300_mm),
0413 std::make_shared<CuboidVolumeBounds>(30_mm, 100_mm, 100_mm), "vol2");
0414
0415 TrackingVolume vol3(
0416 base * Translation3(Vector3::UnitZ() * 600_mm),
0417 std::make_shared<CuboidVolumeBounds>(30_mm, 100_mm, 200_mm), "vol3");
0418
0419 TrackingVolume vol4(
0420 base * Translation3{Vector3::UnitX() * 60_mm + Vector3::UnitZ() * 300_mm},
0421 std::make_shared<CuboidVolumeBounds>(30_mm, 100_mm, 500_mm), "vol4");
0422
0423 SingleCuboidPortalShell shell1{gctx, vol1};
0424 BOOST_CHECK(shell1.isValid());
0425 SingleCuboidPortalShell shell2{gctx, vol2};
0426 BOOST_CHECK(shell2.isValid());
0427 SingleCuboidPortalShell shell3{gctx, vol3};
0428 BOOST_CHECK(shell3.isValid());
0429
0430 CuboidStackPortalShell stack{
0431 gctx, {&shell1, &shell2, &shell3}, AxisDirection::AxisZ};
0432
0433 BOOST_CHECK(stack.isValid());
0434
0435 SingleCuboidPortalShell shell4{gctx, vol4};
0436 BOOST_CHECK(shell4.isValid());
0437
0438 CuboidStackPortalShell stack2{
0439 gctx, {&stack, &shell4}, AxisDirection::AxisX, *logger};
0440 BOOST_CHECK(stack2.isValid());
0441
0442 using enum CuboidVolumeBounds::Face;
0443
0444 auto lookup = [](auto& shell, CuboidPortalShell::Face face, Vector3 position,
0445 Vector3 direction) -> const TrackingVolume* {
0446 const auto portal = shell.portal(face);
0447 BOOST_REQUIRE_NE(portal, nullptr);
0448 return portal->resolveVolume(gctx, position, direction).value();
0449 };
0450
0451
0452 BOOST_CHECK_EQUAL(lookup(shell1, NegativeZFace,
0453 Vector3(10_mm, 20_mm, -200_mm), -Vector3::UnitZ()),
0454 nullptr);
0455 BOOST_CHECK_EQUAL(lookup(shell1, NegativeZFace,
0456 Vector3(10_mm, 20_mm, -200_mm), Vector3::UnitZ()),
0457 &vol1);
0458
0459 BOOST_CHECK_EQUAL(lookup(shell1, PositiveZFace, Vector3(10_mm, 20_mm, 200_mm),
0460 -Vector3::UnitZ()),
0461 &vol1);
0462 BOOST_CHECK_EQUAL(lookup(shell1, PositiveZFace, Vector3(10_mm, 20_mm, 200_mm),
0463 Vector3::UnitZ()),
0464 &vol2);
0465
0466 BOOST_CHECK_EQUAL(lookup(shell1, NegativeXFace, Vector3(-30_mm, 10_mm, 20_mm),
0467 -Vector3::UnitX()),
0468 nullptr);
0469 BOOST_CHECK_EQUAL(lookup(shell1, NegativeXFace, Vector3(-30_mm, 10_mm, 20_mm),
0470 Vector3::UnitX()),
0471 &vol1);
0472
0473 BOOST_CHECK_EQUAL(lookup(shell1, PositiveXFace, Vector3(30_mm, 10_mm, 20_mm),
0474 -Vector3::UnitX()),
0475 &vol1);
0476 BOOST_CHECK_EQUAL(lookup(shell1, PositiveXFace, Vector3(30_mm, 10_mm, 20_mm),
0477 Vector3::UnitX()),
0478 &vol4);
0479
0480 BOOST_CHECK_EQUAL(lookup(shell1, NegativeYFace,
0481 Vector3(10_mm, -100_mm, 20_mm), -Vector3::UnitY()),
0482 nullptr);
0483 BOOST_CHECK_EQUAL(lookup(shell1, NegativeYFace,
0484 Vector3(10_mm, -100_mm, 20_mm), Vector3::UnitY()),
0485 &vol1);
0486
0487 BOOST_CHECK_EQUAL(lookup(shell1, PositiveYFace, Vector3(10_mm, 100_mm, 20_mm),
0488 -Vector3::UnitY()),
0489 &vol1);
0490 BOOST_CHECK_EQUAL(lookup(shell1, PositiveYFace, Vector3(10_mm, 100_mm, 20_mm),
0491 Vector3::UnitY()),
0492 nullptr);
0493
0494
0495 BOOST_CHECK_EQUAL(lookup(shell2, NegativeZFace, Vector3(10_mm, 20_mm, 200_mm),
0496 -Vector3::UnitZ()),
0497 &vol1);
0498 BOOST_CHECK_EQUAL(lookup(shell2, NegativeZFace, Vector3(10_mm, 20_mm, 200_mm),
0499 Vector3::UnitZ()),
0500 &vol2);
0501
0502 BOOST_CHECK_EQUAL(lookup(shell2, PositiveZFace, Vector3(10_mm, 20_mm, 400_mm),
0503 -Vector3::UnitZ()),
0504 &vol2);
0505 BOOST_CHECK_EQUAL(lookup(shell2, PositiveZFace, Vector3(10_mm, 20_mm, 400_mm),
0506 Vector3::UnitZ()),
0507 &vol3);
0508
0509 BOOST_CHECK_EQUAL(lookup(shell2, NegativeXFace,
0510 Vector3(-30_mm, 10_mm, 220_mm), -Vector3::UnitX()),
0511 nullptr);
0512 BOOST_CHECK_EQUAL(lookup(shell2, NegativeXFace,
0513 Vector3(-30_mm, 10_mm, 220_mm), Vector3::UnitX()),
0514 &vol2);
0515
0516 BOOST_CHECK_EQUAL(lookup(shell2, PositiveXFace, Vector3(30_mm, 10_mm, 220_mm),
0517 -Vector3::UnitX()),
0518 &vol2);
0519 BOOST_CHECK_EQUAL(lookup(shell2, PositiveXFace, Vector3(30_mm, 10_mm, 220_mm),
0520 Vector3::UnitX()),
0521 &vol4);
0522
0523 BOOST_CHECK_EQUAL(lookup(shell2, NegativeYFace,
0524 Vector3(10_mm, -100_mm, 220_mm), -Vector3::UnitY()),
0525 nullptr);
0526 BOOST_CHECK_EQUAL(lookup(shell2, NegativeYFace,
0527 Vector3(10_mm, -100_mm, 220_mm), Vector3::UnitY()),
0528 &vol2);
0529
0530 BOOST_CHECK_EQUAL(lookup(shell2, PositiveYFace,
0531 Vector3(10_mm, 100_mm, 220_mm), -Vector3::UnitY()),
0532 &vol2);
0533 BOOST_CHECK_EQUAL(lookup(shell2, PositiveYFace,
0534 Vector3(10_mm, 100_mm, 220_mm), Vector3::UnitY()),
0535 nullptr);
0536
0537
0538 BOOST_CHECK_EQUAL(lookup(shell3, NegativeZFace, Vector3(10_mm, 20_mm, 400_mm),
0539 -Vector3::UnitZ()),
0540 &vol2);
0541 BOOST_CHECK_EQUAL(lookup(shell3, NegativeZFace, Vector3(10_mm, 20_mm, 400_mm),
0542 Vector3::UnitZ()),
0543 &vol3);
0544
0545 BOOST_CHECK_EQUAL(lookup(shell3, PositiveZFace, Vector3(10_mm, 20_mm, 800_mm),
0546 -Vector3::UnitZ()),
0547 &vol3);
0548 BOOST_CHECK_EQUAL(lookup(shell3, PositiveZFace, Vector3(10_mm, 20_mm, 800_mm),
0549 Vector3::UnitZ()),
0550 nullptr);
0551
0552 BOOST_CHECK_EQUAL(lookup(shell3, NegativeXFace,
0553 Vector3(-30_mm, 10_mm, 420_mm), -Vector3::UnitX()),
0554 nullptr);
0555 BOOST_CHECK_EQUAL(lookup(shell3, NegativeXFace,
0556 Vector3(-30_mm, 10_mm, 420_mm), Vector3::UnitX()),
0557 &vol3);
0558
0559 BOOST_CHECK_EQUAL(lookup(shell3, PositiveXFace, Vector3(30_mm, 10_mm, 420_mm),
0560 -Vector3::UnitX()),
0561 &vol3);
0562 BOOST_CHECK_EQUAL(lookup(shell3, PositiveXFace, Vector3(30_mm, 10_mm, 420_mm),
0563 Vector3::UnitX()),
0564 &vol4);
0565
0566 BOOST_CHECK_EQUAL(lookup(shell3, NegativeYFace,
0567 Vector3(10_mm, -100_mm, 420_mm), -Vector3::UnitY()),
0568 nullptr);
0569 BOOST_CHECK_EQUAL(lookup(shell3, NegativeYFace,
0570 Vector3(10_mm, -100_mm, 420_mm), Vector3::UnitY()),
0571 &vol3);
0572
0573 BOOST_CHECK_EQUAL(lookup(shell3, PositiveYFace,
0574 Vector3(10_mm, 100_mm, 420_mm), -Vector3::UnitY()),
0575 &vol3);
0576 BOOST_CHECK_EQUAL(lookup(shell3, PositiveYFace,
0577 Vector3(10_mm, 100_mm, 420_mm), Vector3::UnitY()),
0578 nullptr);
0579
0580
0581 BOOST_CHECK_EQUAL(lookup(shell4, NegativeZFace,
0582 Vector3(50_mm, 20_mm, -200_mm), -Vector3::UnitZ()),
0583 nullptr);
0584 BOOST_CHECK_EQUAL(lookup(shell4, NegativeZFace,
0585 Vector3(50_mm, 20_mm, -200_mm), Vector3::UnitZ()),
0586 &vol4);
0587
0588 BOOST_CHECK_EQUAL(lookup(shell4, PositiveZFace, Vector3(50_mm, 20_mm, 800_mm),
0589 -Vector3::UnitZ()),
0590 &vol4);
0591 BOOST_CHECK_EQUAL(lookup(shell4, PositiveZFace, Vector3(50_mm, 20_mm, 800_mm),
0592 Vector3::UnitZ()),
0593 nullptr);
0594
0595 BOOST_CHECK_EQUAL(lookup(shell4, NegativeXFace, Vector3(30_mm, 10_mm, 0_mm),
0596 -Vector3::UnitX()),
0597 &vol1);
0598 BOOST_CHECK_EQUAL(lookup(shell4, NegativeXFace, Vector3(30_mm, 10_mm, 220_mm),
0599 -Vector3::UnitX()),
0600 &vol2);
0601 BOOST_CHECK_EQUAL(lookup(shell4, NegativeXFace, Vector3(30_mm, 10_mm, 420_mm),
0602 -Vector3::UnitX()),
0603 &vol3);
0604 BOOST_CHECK_EQUAL(lookup(shell4, NegativeXFace, Vector3(30_mm, 10_mm, 300_mm),
0605 Vector3::UnitX()),
0606 &vol4);
0607
0608 BOOST_CHECK_EQUAL(lookup(shell4, PositiveXFace, Vector3(90_mm, 10_mm, 300_mm),
0609 -Vector3::UnitX()),
0610 &vol4);
0611 BOOST_CHECK_EQUAL(lookup(shell4, PositiveXFace, Vector3(90_mm, 10_mm, 300_mm),
0612 Vector3::UnitX()),
0613 nullptr);
0614
0615 BOOST_CHECK_EQUAL(lookup(shell4, NegativeYFace,
0616 Vector3(50_mm, -100_mm, 300_mm), -Vector3::UnitY()),
0617 nullptr);
0618 BOOST_CHECK_EQUAL(lookup(shell4, NegativeYFace,
0619 Vector3(50_mm, -100_mm, 300_mm), Vector3::UnitY()),
0620 &vol4);
0621
0622 BOOST_CHECK_EQUAL(lookup(shell4, PositiveYFace,
0623 Vector3(50_mm, 100_mm, 300_mm), -Vector3::UnitY()),
0624 &vol4);
0625 BOOST_CHECK_EQUAL(lookup(shell4, PositiveYFace,
0626 Vector3(50_mm, 100_mm, 300_mm), Vector3::UnitY()),
0627 nullptr);
0628
0629
0630 BOOST_CHECK_EQUAL(lookup(stack, NegativeZFace, Vector3(10_mm, 20_mm, -200_mm),
0631 -Vector3::UnitZ()),
0632 nullptr);
0633 BOOST_CHECK_EQUAL(lookup(stack, NegativeZFace, Vector3(10_mm, 20_mm, -200_mm),
0634 Vector3::UnitZ()),
0635 &vol1);
0636
0637 BOOST_CHECK_EQUAL(lookup(stack, PositiveZFace, Vector3(10_mm, 20_mm, 800_mm),
0638 -Vector3::UnitZ()),
0639 &vol3);
0640 BOOST_CHECK_EQUAL(lookup(stack, PositiveZFace, Vector3(10_mm, 20_mm, 800_mm),
0641 Vector3::UnitZ()),
0642 nullptr);
0643
0644 BOOST_CHECK_EQUAL(lookup(stack, NegativeXFace, Vector3(-30_mm, 10_mm, 300_mm),
0645 -Vector3::UnitX()),
0646 nullptr);
0647 BOOST_CHECK_EQUAL(lookup(stack, NegativeXFace, Vector3(-30_mm, 10_mm, 0_mm),
0648 Vector3::UnitX()),
0649 &vol1);
0650 BOOST_CHECK_EQUAL(lookup(stack, NegativeXFace, Vector3(-30_mm, 10_mm, 220_mm),
0651 Vector3::UnitX()),
0652 &vol2);
0653 BOOST_CHECK_EQUAL(lookup(stack, NegativeXFace, Vector3(-30_mm, 10_mm, 420_mm),
0654 Vector3::UnitX()),
0655 &vol3);
0656
0657 BOOST_CHECK_EQUAL(lookup(stack, PositiveXFace, Vector3(30_mm, 10_mm, 0_mm),
0658 -Vector3::UnitX()),
0659 &vol1);
0660 BOOST_CHECK_EQUAL(lookup(stack, PositiveXFace, Vector3(30_mm, 10_mm, 220_mm),
0661 -Vector3::UnitX()),
0662 &vol2);
0663 BOOST_CHECK_EQUAL(lookup(stack, PositiveXFace, Vector3(30_mm, 10_mm, 420_mm),
0664 -Vector3::UnitX()),
0665 &vol3);
0666 BOOST_CHECK_EQUAL(lookup(stack, PositiveXFace, Vector3(30_mm, 10_mm, 300_mm),
0667 Vector3::UnitX()),
0668 &vol4);
0669
0670 BOOST_CHECK_EQUAL(lookup(stack, NegativeYFace,
0671 Vector3(10_mm, -100_mm, 300_mm), -Vector3::UnitY()),
0672 nullptr);
0673 BOOST_CHECK_EQUAL(lookup(stack, NegativeYFace, Vector3(10_mm, -100_mm, 0_mm),
0674 Vector3::UnitY()),
0675 &vol1);
0676 BOOST_CHECK_EQUAL(lookup(stack, NegativeYFace,
0677 Vector3(10_mm, -100_mm, 220_mm), Vector3::UnitY()),
0678 &vol2);
0679 BOOST_CHECK_EQUAL(lookup(stack, NegativeYFace,
0680 Vector3(10_mm, -100_mm, 420_mm), Vector3::UnitY()),
0681 &vol3);
0682
0683 BOOST_CHECK_EQUAL(lookup(stack, PositiveYFace, Vector3(10_mm, 100_mm, 0_mm),
0684 -Vector3::UnitY()),
0685 &vol1);
0686 BOOST_CHECK_EQUAL(lookup(stack, PositiveYFace, Vector3(10_mm, 100_mm, 220_mm),
0687 -Vector3::UnitY()),
0688 &vol2);
0689 BOOST_CHECK_EQUAL(lookup(stack, PositiveYFace, Vector3(10_mm, 100_mm, 420_mm),
0690 -Vector3::UnitY()),
0691 &vol3);
0692 BOOST_CHECK_EQUAL(lookup(stack, PositiveYFace, Vector3(10_mm, 100_mm, 300_mm),
0693 Vector3::UnitY()),
0694 nullptr);
0695
0696
0697 BOOST_CHECK_EQUAL(lookup(stack2, NegativeZFace,
0698 Vector3(10_mm, 20_mm, -200_mm), -Vector3::UnitZ()),
0699 nullptr);
0700 BOOST_CHECK_EQUAL(lookup(stack2, NegativeZFace,
0701 Vector3(10_mm, 20_mm, -200_mm), Vector3::UnitZ()),
0702 &vol1);
0703 BOOST_CHECK_EQUAL(lookup(stack2, NegativeZFace,
0704 Vector3(50_mm, 20_mm, -200_mm), Vector3::UnitZ()),
0705 &vol4);
0706
0707 BOOST_CHECK_EQUAL(lookup(stack2, PositiveZFace, Vector3(10_mm, 20_mm, 800_mm),
0708 -Vector3::UnitZ()),
0709 &vol3);
0710 BOOST_CHECK_EQUAL(lookup(stack2, PositiveZFace, Vector3(50_mm, 20_mm, 800_mm),
0711 -Vector3::UnitZ()),
0712 &vol4);
0713 BOOST_CHECK_EQUAL(lookup(stack2, PositiveZFace, Vector3(10_mm, 20_mm, 800_mm),
0714 Vector3::UnitZ()),
0715 nullptr);
0716
0717 BOOST_CHECK_EQUAL(lookup(stack2, NegativeXFace,
0718 Vector3(-30_mm, 10_mm, 300_mm), -Vector3::UnitX()),
0719 nullptr);
0720 BOOST_CHECK_EQUAL(lookup(stack2, NegativeXFace, Vector3(-30_mm, 10_mm, 0_mm),
0721 Vector3::UnitX()),
0722 &vol1);
0723 BOOST_CHECK_EQUAL(lookup(stack2, NegativeXFace,
0724 Vector3(-30_mm, 10_mm, 220_mm), Vector3::UnitX()),
0725 &vol2);
0726 BOOST_CHECK_EQUAL(lookup(stack2, NegativeXFace,
0727 Vector3(-30_mm, 10_mm, 420_mm), Vector3::UnitX()),
0728 &vol3);
0729
0730 BOOST_CHECK_EQUAL(lookup(shell4, PositiveXFace, Vector3(90_mm, 10_mm, 300_mm),
0731 -Vector3::UnitX()),
0732 &vol4);
0733 BOOST_CHECK_EQUAL(lookup(shell4, PositiveXFace, Vector3(90_mm, 10_mm, 300_mm),
0734 Vector3::UnitX()),
0735 nullptr);
0736
0737 BOOST_CHECK_EQUAL(lookup(stack2, NegativeYFace,
0738 Vector3(10_mm, -100_mm, 300_mm), -Vector3::UnitY()),
0739 nullptr);
0740 BOOST_CHECK_EQUAL(lookup(stack2, NegativeYFace, Vector3(10_mm, -100_mm, 0_mm),
0741 Vector3::UnitY()),
0742 &vol1);
0743 BOOST_CHECK_EQUAL(lookup(stack2, NegativeYFace,
0744 Vector3(10_mm, -100_mm, 220_mm), Vector3::UnitY()),
0745 &vol2);
0746 BOOST_CHECK_EQUAL(lookup(stack2, NegativeYFace,
0747 Vector3(10_mm, -100_mm, 420_mm), Vector3::UnitY()),
0748 &vol3);
0749 BOOST_CHECK_EQUAL(lookup(stack2, NegativeYFace,
0750 Vector3(50_mm, -100_mm, 420_mm), Vector3::UnitY()),
0751 &vol4);
0752
0753 BOOST_CHECK_EQUAL(lookup(stack2, PositiveYFace, Vector3(10_mm, 100_mm, 0_mm),
0754 -Vector3::UnitY()),
0755 &vol1);
0756 BOOST_CHECK_EQUAL(lookup(stack2, PositiveYFace,
0757 Vector3(10_mm, 100_mm, 220_mm), -Vector3::UnitY()),
0758 &vol2);
0759 BOOST_CHECK_EQUAL(lookup(stack2, PositiveYFace,
0760 Vector3(10_mm, 100_mm, 420_mm), -Vector3::UnitY()),
0761 &vol3);
0762 BOOST_CHECK_EQUAL(lookup(stack2, PositiveYFace,
0763 Vector3(50_mm, 100_mm, 420_mm), -Vector3::UnitY()),
0764 &vol4);
0765 BOOST_CHECK_EQUAL(lookup(stack2, PositiveYFace,
0766 Vector3(10_mm, 100_mm, 300_mm), Vector3::UnitY()),
0767 nullptr);
0768 }
0769
0770 BOOST_AUTO_TEST_CASE(Fill) {
0771 Transform3 base = Transform3::Identity();
0772
0773 TrackingVolume vol1(
0774 base, std::make_shared<CuboidVolumeBounds>(30_mm, 100_mm, 200_mm),
0775 "vol1");
0776
0777 TrackingVolume vol2(
0778 base * Translation3(Vector3::UnitZ() * 300_mm),
0779 std::make_shared<CuboidVolumeBounds>(30_mm, 100_mm, 100_mm), "vol2");
0780
0781 SingleCuboidPortalShell shell{gctx, vol1};
0782
0783 using enum CuboidVolumeBounds::Face;
0784
0785 BOOST_CHECK_EQUAL(
0786 shell.portal(PositiveZFace)->getLink(Direction::AlongNormal()), nullptr);
0787
0788 shell.fill(vol2);
0789
0790 BOOST_CHECK_NE(shell.portal(PositiveZFace)->getLink(Direction::AlongNormal()),
0791 nullptr);
0792 }
0793
0794 BOOST_AUTO_TEST_CASE(RegisterInto) {
0795 using enum CuboidVolumeBounds::Face;
0796 TrackingVolume vol1(
0797 Transform3::Identity(),
0798 std::make_shared<CuboidVolumeBounds>(100_mm, 100_mm, 100_mm));
0799
0800 SingleCuboidPortalShell shell{gctx, vol1};
0801
0802 BOOST_CHECK_EQUAL(vol1.portals().size(), 0);
0803
0804 shell.applyToVolume();
0805 BOOST_CHECK_EQUAL(vol1.portals().size(), 6);
0806 }
0807
0808 BOOST_AUTO_TEST_SUITE_END()
0809 BOOST_AUTO_TEST_SUITE_END()
0810
0811 }