diff --git a/GeoModelCore/GeoModelHelpers/src/GeoShapeUtils.cxx b/GeoModelCore/GeoModelHelpers/src/GeoShapeUtils.cxx index 73ef9a7622a01cd6c69851a102ed6973ef4da387..413e020748911e4baa3ea5beaa79465f6be81531 100644 --- a/GeoModelCore/GeoModelHelpers/src/GeoShapeUtils.cxx +++ b/GeoModelCore/GeoModelHelpers/src/GeoShapeUtils.cxx @@ -24,6 +24,7 @@ #include "GeoModelKernel/GeoGenericTrap.h" #include "GeoModelKernel/Units.h" +#include "GeoModelHelpers/TransformSorter.h" #include <vector> @@ -51,12 +52,28 @@ unsigned int countComposedShapes(const GeoShape* shape) { } GeoIntrusivePtr<const GeoShape> compressShift(const GeoShape* shift) { - if (shift->typeID() != GeoShapeShift::getClassTypeID()) return GeoIntrusivePtr<const GeoShape>{shift}; - const GeoShapeShift* shapeShift = dynamic_cast<const GeoShapeShift*>(shift); - if (shapeShift->getOp()->typeID() != GeoShapeShift::getClassTypeID()) return GeoIntrusivePtr<const GeoShape>{shift}; + GeoIntrusivePtr<const GeoShape> retPtr{shift}; + if (shift->typeID() != GeoShapeShift::getClassTypeID()) { + return retPtr; + } + + GeoIntrusivePtr<const GeoShapeShift> shapeShift = dynamic_pointer_cast<const GeoShapeShift>(retPtr); + /// If the shape shift is an Identity no need to go go further. + if (!GeoTrf::TransformSorter{}.compare(shapeShift->getX(), GeoTrf::Transform3D::Identity())) { + retPtr = shapeShift->getOp(); + } + if (shapeShift->getOp()->typeID() != GeoShapeShift::getClassTypeID()) { + return retPtr; + } GeoIntrusivePtr<const GeoShape> subShape{compressShift(shapeShift->getOp())}; - const GeoShapeShift* subShift = dynamic_cast<const GeoShapeShift*>(subShape.get()); - return GeoIntrusivePtr<const GeoShape>{new GeoShapeShift(subShift->getOp(), subShift->getX() * shapeShift->getX())}; + + GeoIntrusivePtr<const GeoShapeShift> subShift = dynamic_pointer_cast<const GeoShapeShift>(subShape); + /// Check that the GeoShape shift is actually neccesary. If not bail out + GeoTrf::Transform3D shiftTrf{subShift->getX() * shapeShift->getX()}; + if (!GeoTrf::TransformSorter{}.compare(shiftTrf, GeoTrf::Transform3D::Identity())) { + return GeoIntrusivePtr<const GeoShape>{subShift->getOp()}; + } + return make_intrusive<GeoShapeShift>(subShift->getOp(), std::move(shiftTrf)); } std::vector<const GeoShape*> getBooleanComponents(const GeoShape* booleanShape) { std::pair<const GeoShape*, const GeoShape*> operands = getOps(booleanShape); diff --git a/GeoModelCore/GeoModelHelpers/tests/testPhysVolSorter.cxx b/GeoModelCore/GeoModelHelpers/tests/testPhysVolSorter.cxx index 9d22808b5ecc480988a5e3680098df945f7686c3..095ff482e334df00735d250457626ca0c8c849c3 100644 --- a/GeoModelCore/GeoModelHelpers/tests/testPhysVolSorter.cxx +++ b/GeoModelCore/GeoModelHelpers/tests/testPhysVolSorter.cxx @@ -20,14 +20,14 @@ int main() { GeoIntrusivePtr<GeoPhysVol> world{createGeoWorld()}; const GeoMaterial* air = world->getLogVol()->getMaterial(); - GeoIntrusivePtr<GeoBox> externalBox{new GeoBox(500.,500., 500.)}; - GeoIntrusivePtr<GeoBox> internalBox{new GeoBox(100.,100., 100.)}; + GeoIntrusivePtr<GeoBox> externalBox{make_intrusive<GeoBox>(500.,500., 500.)}; + GeoIntrusivePtr<GeoBox> internalBox{make_intrusive<GeoBox>(100.,100., 100.)}; auto makeBox = [&](bool bigOne) { - return PVLink(new GeoPhysVol(new GeoLogVol("TestVolume", bigOne ? externalBox : internalBox, air))); + return make_intrusive<GeoPhysVol>(make_intrusive<GeoLogVol>("TestVolume", bigOne ? externalBox : internalBox, air)); }; auto makeFullBox = [&](bool bigOne) { - return PVLink(new GeoFullPhysVol(new GeoLogVol("TestFullPhysVol", bigOne ? externalBox : internalBox, air))); + return make_intrusive<GeoFullPhysVol>(make_intrusive<GeoLogVol>("TestFullPhysVol", bigOne ? externalBox : internalBox, air)); }; /// PVLink extVolume = makeBox(true); @@ -54,7 +54,7 @@ int main() { return EXIT_FAILURE; } extVolume = makeBox(true); - extVolume->add(new GeoTransform(GeoTrf::TranslateX3D(50.))); + extVolume->add(make_intrusive<GeoTransform>(GeoTrf::TranslateX3D(50.))); extVolume->add(makeBox(false)); if (!physVolSet.insert(extVolume).second) { std::cerr<<"testPhysVolSorter() "<<__LINE__<<" A box with a displaced box inside is not the same as box ception "<<std::endl;