diff --git a/GeoModelCore/GeoModelHelpers/GeoModelHelpers/getChildNodesWithTrf.h b/GeoModelCore/GeoModelHelpers/GeoModelHelpers/getChildNodesWithTrf.h index 4e2b2e8e69fbf6a58fb37ce859c420ba564f9289..f8c3599b2f837fa103a3d6a7b5f6c82e46ef7c4b 100644 --- a/GeoModelCore/GeoModelHelpers/GeoModelHelpers/getChildNodesWithTrf.h +++ b/GeoModelCore/GeoModelHelpers/GeoModelHelpers/getChildNodesWithTrf.h @@ -39,8 +39,12 @@ std::vector <GeoChildNodeWithTrf> getChildrenWithRef (PVConstLink physVol, bool summarizeEqualVol = true); /**** @brief Traverses through the GeoVPhysVol tree and returns all sub volumes of this tree.*/ std::vector<GeoChildNodeWithTrf> getAllSubVolumes(PVConstLink physVol); - - +/*** @brief Traverses thorugh the GeoVPhysVOl tree and returns all subvolumes satisfying an external + * selection. + */ +std::vector<GeoChildNodeWithTrf> getAllSubVolumes(PVConstLink physVol, + std::function<bool(const GeoChildNodeWithTrf&)> selector, + bool summarizeEqualVol = false); /** * Returns whether a volume has fullPhysical volume nodes in diff --git a/GeoModelCore/GeoModelHelpers/src/getChildNodesWithTrf.cxx b/GeoModelCore/GeoModelHelpers/src/getChildNodesWithTrf.cxx index 3aa9dd8eb97d1db64c0bb4824ca4269b10b923ba..81947388084a5eeff4320cd4f7055dfe48458a63 100644 --- a/GeoModelCore/GeoModelHelpers/src/getChildNodesWithTrf.cxx +++ b/GeoModelCore/GeoModelHelpers/src/getChildNodesWithTrf.cxx @@ -64,14 +64,16 @@ std::vector <GeoChildNodeWithTrf> getChildrenWithRef(PVConstLink physVol, } return children; } - -std::vector<GeoChildNodeWithTrf> getAllSubVolumes(PVConstLink physVol) { - std::vector<GeoChildNodeWithTrf> children{getChildrenWithRef(physVol, false)}, subVolumes{}; +std::vector<GeoChildNodeWithTrf> getAllSubVolumes(PVConstLink physVol, + std::function<bool(const GeoChildNodeWithTrf&)> selector, + bool summarizeEqualVol) { + std::vector<GeoChildNodeWithTrf> children{getChildrenWithRef(physVol, summarizeEqualVol)}, subVolumes{}; subVolumes.reserve(children.size()); for (const GeoChildNodeWithTrf& child : children) { - subVolumes.push_back(child); - std::vector<GeoChildNodeWithTrf> grandChildren = getAllSubVolumes(child.volume); - subVolumes.reserve(grandChildren.size() + subVolumes.size()); + std::vector<GeoChildNodeWithTrf> grandChildren = getAllSubVolumes(child.volume, selector, summarizeEqualVol); + if (selector(child)) subVolumes.push_back(child); + + subVolumes.reserve(grandChildren.size() + subVolumes.capacity()); std::transform(std::make_move_iterator(grandChildren.begin()), std::make_move_iterator(grandChildren.end()), std::back_inserter(subVolumes), [&child](GeoChildNodeWithTrf&& grandChild){ @@ -80,6 +82,13 @@ std::vector<GeoChildNodeWithTrf> getAllSubVolumes(PVConstLink physVol) { }); } return subVolumes; + } + + +std::vector<GeoChildNodeWithTrf> getAllSubVolumes(PVConstLink physVol) { + return getAllSubVolumes(physVol, + [](const GeoChildNodeWithTrf& child){ + return true;}, false); } bool hasFullPhysVolInTree(PVConstLink physVol) { diff --git a/GeoModelCore/GeoModelKernel/GeoModelKernel/GeoDefinitions.h b/GeoModelCore/GeoModelKernel/GeoModelKernel/GeoDefinitions.h index cbc81fd9d4fb9ac7424c10951aee21e9a28e30f0..d1861a649cf047642cd5fff069252c009589503d 100644 --- a/GeoModelCore/GeoModelKernel/GeoModelKernel/GeoDefinitions.h +++ b/GeoModelCore/GeoModelKernel/GeoModelKernel/GeoDefinitions.h @@ -197,6 +197,8 @@ namespace GeoTrf { /// @brief Simple comparison returning -1, 0, 1 int compare(const EulerAngles& other) const; operator bool() const; + /// @brief Returns the set of Euler angles to invert the rotation + EulerAngles inverse() const; }; @@ -218,6 +220,8 @@ namespace GeoTrf { bool operator<(const CoordEulerAngles& other) const; /// @brief Simple comparison returning -1, 0, 1 int compare(const CoordEulerAngles& other) const; + /// @brief Returns the set of CoordEulerAngles to invert the Rotation + CoordEulerAngles inverse() const; operator bool() const; }; @@ -250,9 +254,10 @@ namespace GeoTrf { class GeoTransformRT : public Transform3D { public: - GeoTransformRT(const GeoRotation& rot, const Vector3D& trans) - : Transform3D(Translation3D(trans)*Transform3D(AngleAxis3D(rot))) - {} + GeoTransformRT(const GeoRotation& rot, const Vector3D& trans); + GeoTransformRT(const EulerAngles& angles, const Vector3D& trans); + GeoTransformRT(const CoordEulerAngles&angles, const Vector3D& trans); + virtual ~GeoTransformRT() = default; }; } diff --git a/GeoModelCore/GeoModelKernel/src/GeoDefinitions.cxx b/GeoModelCore/GeoModelKernel/src/GeoDefinitions.cxx index 79dd1b7a0d867ad17ac3cd1b9bb78d90bfdb7e0d..01e49145c2881318c2e67e23a86d456c12d39e48 100755 --- a/GeoModelCore/GeoModelKernel/src/GeoDefinitions.cxx +++ b/GeoModelCore/GeoModelKernel/src/GeoDefinitions.cxx @@ -7,7 +7,7 @@ #include <cmath> namespace { - constexpr double rotTolerance = 0.01 * GeoModelKernelUnits::deg; + constexpr double rotTolerance = 0.001 * GeoModelKernelUnits::deg; inline double cutOff(const double val, const double cutOff) { return std::abs(val) > cutOff ? val : 0.; @@ -91,6 +91,10 @@ namespace GeoTrf { EulerAngles::operator bool() const { return std::abs(phi) > rotTolerance || std::abs(theta) > rotTolerance || std::abs(psi) > rotTolerance; } + EulerAngles EulerAngles::inverse() const { + return getGeoRotationAngles(GeoRotation(*this).inverse()); + } + int CoordEulerAngles::compare(const CoordEulerAngles& other) const { if (std::abs(alpha - other.alpha) > rotTolerance) return alpha < other.alpha ? -1 : 1; @@ -104,6 +108,21 @@ namespace GeoTrf { CoordEulerAngles::operator bool() const { return std::abs(alpha) > rotTolerance || std::abs(beta) > rotTolerance || std::abs(gamma) > rotTolerance; } + CoordEulerAngles CoordEulerAngles::inverse() const { + return getCoordRotationAngles(GeoRotation(*this).inverse()); + } + + GeoTransformRT::GeoTransformRT(const EulerAngles& angles, const Vector3D& trans): + GeoTransformRT{GeoRotation{angles}, trans}{} + + + GeoTransformRT::GeoTransformRT(const CoordEulerAngles&angles, const Vector3D& trans): + GeoTransformRT{GeoRotation{angles}, trans} { + + } + + GeoTransformRT::GeoTransformRT(const GeoRotation& rot, const Vector3D& trans): + Transform3D(Translation3D(trans)*Transform3D(AngleAxis3D(rot))){} } diff --git a/GeoModelCore/GeoModelKernel/tests/testEulerAngles.cxx b/GeoModelCore/GeoModelKernel/tests/testEulerAngles.cxx index bc3ed0758417c8063efe4ab890050bbc690c79da..541eebc2c12ae060baac743c944e32fe70188d76 100644 --- a/GeoModelCore/GeoModelKernel/tests/testEulerAngles.cxx +++ b/GeoModelCore/GeoModelKernel/tests/testEulerAngles.cxx @@ -80,6 +80,12 @@ int main() { GeoTrf::get3DRotMatX(coordAngles.alpha *GeoModelKernelUnits::deg)<<std::endl; } + if (!isIdentity(coordRot * GeoTrf::GeoRotation{coordAngles.inverse()})){ + std::cout<<"testEulerAngles() "<<__LINE__<<"The inverse of "<<coordAngles<<" " + <<coordAngles.inverse()<<" does not lead to Identity rotation "<<std::endl; + return EXIT_FAILURE; + } + const GeoTrf::CoordEulerAngles calcCoordAngles = GeoTrf::getCoordRotationAngles(coordRot); const GeoTrf::GeoRotation extCoordRot{calcCoordAngles}; if (!isIdentity(extCoordRot.inverse()* coordRot)) { @@ -90,6 +96,11 @@ int main() { <<calcCoordAngles.beta*toDeg<<"/"<<calcCoordAngles.gamma*toDeg<<std::endl<<extCoordRot<<std::endl; return EXIT_FAILURE; } + if (!isIdentity(extCoordRot * GeoTrf::GeoRotation{calcCoordAngles.inverse()})){ + std::cout<<"testEulerAngles() "<<__LINE__<<"The inverse of "<<calcCoordAngles<<" " + <<calcCoordAngles.inverse()<<" does not lead to Identity rotation "<<std::endl; + return EXIT_FAILURE; + } } } }