diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index a57487fc02b1d61b453cb8b25fa1c6bd174d9538..b40baa047d5062b2e1b7eb08e45ec5e4a7577e8c 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -12,6 +12,7 @@ native_Debian_clang: script: &native_scr - pwd - export PYTHONPATH=$CI_PROJECT_DIR/build/lib + - export MPLBACKEND=Agg - mkdir build - cd build - cmake .. -DCMAKE_CXX_COMPILER_LAUNCHER=ccache -DBA_PY_PACKAGE=ON -DCMAKE_PREFIX_PATH="/home/build/Qt/6.2.3/gcc_64/lib/cmake" #-DWERROR=ON diff --git a/Resample/Processed/Slicer.cpp b/Resample/Processed/Slicer.cpp index 4ffa4b8a1f2c6f658acb4b4ce1f10a5f392d2123..f028998ef5961827789520fcbb088cbc11d83372 100644 --- a/Resample/Processed/Slicer.cpp +++ b/Resample/Processed/Slicer.cpp @@ -61,6 +61,92 @@ SlicingEffects computeSlicingEffects(ZLimits limits, const R3& position, double return {new_position, dz_bottom, dz_top}; } +IFormFactor* doSlice(const IFormFactor* ff, double dz_bottom, double dz_top) +{ + if (const auto* f = dynamic_cast<const Pyramid2*>(ff)) { + double dbase_edge = 2 * dz_bottom * Math::cot(f->alpha()); + return new Pyramid2(f->length() - dbase_edge, f->width() - dbase_edge, + f->height() - dz_bottom - dz_top, f->alpha()); + } + if (const auto* f = dynamic_cast<const Box*>(ff)) { + return new Box(f->length(), f->width(), f->height() - dz_bottom - dz_top); + } + if (const auto* f = dynamic_cast<const Cone*>(ff)) { + double dradius = dz_bottom * Math::cot(f->alpha()); + return new Cone(f->radius() - dradius, f->height() - dz_bottom - dz_top, f->alpha()); + } + if (const auto* f = dynamic_cast<const Pyramid6*>(ff)) { + double dbase_edge = dz_bottom * Math::cot(f->alpha()); + return new Pyramid6(f->baseEdge() - dbase_edge, f->height() - dz_bottom - dz_top, + f->alpha()); + } + if (const auto* f = dynamic_cast<const Bipyramid4*>(ff)) { + if (dz_bottom > f->base_height()) { + double dbase_edge = 2 * (dz_bottom - f->base_height()) * Math::cot(f->alpha()); + return new Pyramid4(f->length() - dbase_edge, f->height() - dz_bottom - dz_top, + f->alpha()); + } + if (dz_top > f->heightRatio() * f->base_height()) { + double dbase_edge = 2 * (f->base_height() - dz_bottom) * Math::cot(f->alpha()); + return new Pyramid4(f->length() - dbase_edge, f->height() - dz_bottom - dz_top, + M_PI - f->alpha()); + } + { + return new Bipyramid4(f->length(), f->base_height() - dz_bottom, + f->heightRatio() * f->base_height() - dz_top, f->alpha()); + } + } + if (const auto* f = dynamic_cast<const Cylinder*>(ff)) { + return new Cylinder(f->radius(), f->height() - dz_bottom - dz_top); + } + if (const auto* f = dynamic_cast<const EllipsoidalCylinder*>(ff)) { + return new EllipsoidalCylinder(f->radiusX(), f->radiusY(), + f->height() - dz_bottom - dz_top); + } + if (const auto* f = dynamic_cast<const HorizontalCylinder*>(ff)) { + return new HorizontalCylinder(f->radius(), f->length(), -f->radius() + dz_bottom, + f->radius() - dz_top); + } + if (const auto* f = dynamic_cast<const Sphere*>(ff)) { + return new TruncatedSphere(f->radius(), f->height() - dz_bottom, dz_top); + } + if (const auto* f = dynamic_cast<const Spheroid*>(ff)) { + double flattening = f->height() / (2.0 * f->radius()); + return new TruncatedSpheroid(f->radius(), f->height() - dz_bottom, flattening, dz_top); + } + if (const auto* f = dynamic_cast<const LongBoxGauss*>(ff)) { + return new LongBoxGauss(f->length(), f->width(), f->height() - dz_bottom - dz_top); + } + if (const auto* f = dynamic_cast<const LongBoxLorentz*>(ff)) { + return new LongBoxLorentz(f->length(), f->width(), f->height() - dz_bottom - dz_top); + } + if (const auto* f = dynamic_cast<const Prism3*>(ff)) { + return new Prism3(f->baseEdge(), f->height() - dz_bottom - dz_top); + } + if (const auto* f = dynamic_cast<const Prism6*>(ff)) { + return new Prism6(f->baseEdge(), f->height() - dz_bottom - dz_top); + } + if (const auto* f = dynamic_cast<const Pyramid4*>(ff)) { + double dbaseEdge = 2 * dz_bottom * Math::cot(f->alpha()); + return new Pyramid4(f->baseEdge() - dbaseEdge, f->height() - dz_bottom - dz_top, + f->alpha()); + } + if (const auto* f = dynamic_cast<const Pyramid3*>(ff)) { + double dbaseEdge = 2 * sqrt(3) * dz_bottom * Math::cot(f->alpha()); + return new Pyramid3(f->baseEdge() - dbaseEdge, f->height() - dz_bottom - dz_top, + f->alpha()); + } + if (const auto* f = dynamic_cast<const TruncatedSphere*>(ff)) { + return new TruncatedSphere(f->radius(), f->untruncated_height() - dz_bottom, + dz_top + f->removedTop()); + } + if (const auto* f = dynamic_cast<const TruncatedSpheroid*>(ff)) { + return new TruncatedSpheroid(f->radius(), f->untruncated_height() - dz_bottom, + f->heightFlattening(), dz_top + f->removedTop()); + } else + throw std::runtime_error("Slicing of " + ff->className() + " not supported"); +} + ReParticle* createTransformedFormFactor(const IFormFactor* formfactor, const R3& translation, const IRotation* rot) { @@ -84,140 +170,10 @@ ReParticle* createParticleSlice(const IFormFactor* ff, ZLimits limits, const R3& throw std::runtime_error("Slicing of " + ff->className() + " not supported for the given rotation"); - if (const auto* f = dynamic_cast<const Pyramid2*>(ff)) { - const SlicingEffects effects = computeSlicingEffects(limits, translation, f->height()); - double dbase_edge = 2 * effects.dz_bottom * Math::cot(f->alpha()); - auto* slicedff = new Pyramid2(f->length() - dbase_edge, f->width() - dbase_edge, - f->height() - effects.dz_bottom - effects.dz_top, f->alpha()); - return createTransformedFormFactor(slicedff, effects.position, rot); - - } else if (const auto* f = dynamic_cast<const Box*>(ff)) { - const SlicingEffects effects = computeSlicingEffects(limits, translation, f->height()); - auto* slicedff = - new Box(f->length(), f->width(), f->height() - effects.dz_bottom - effects.dz_top); - return createTransformedFormFactor(slicedff, effects.position, rot); - - } else if (const auto* f = dynamic_cast<const Cone*>(ff)) { - const SlicingEffects effects = computeSlicingEffects(limits, translation, f->height()); - double dradius = effects.dz_bottom * Math::cot(f->alpha()); - auto* slicedff = new Cone(f->radius() - dradius, - f->height() - effects.dz_bottom - effects.dz_top, f->alpha()); - return createTransformedFormFactor(slicedff, effects.position, rot); - - } else if (const auto* f = dynamic_cast<const Pyramid6*>(ff)) { - const SlicingEffects effects = computeSlicingEffects(limits, translation, f->height()); - double dbase_edge = effects.dz_bottom * Math::cot(f->alpha()); - auto* slicedff = new Pyramid6(f->baseEdge() - dbase_edge, - f->height() - effects.dz_bottom - effects.dz_top, f->alpha()); - return createTransformedFormFactor(slicedff, effects.position, rot); - - } else if (const auto* f = dynamic_cast<const Bipyramid4*>(ff)) { - const SlicingEffects effects = computeSlicingEffects(limits, translation, f->height()); - if (effects.dz_bottom > f->base_height()) { - double dbase_edge = 2 * (effects.dz_bottom - f->base_height()) * Math::cot(f->alpha()); - auto* slicedff = - new Pyramid4(f->length() - dbase_edge, - f->height() - effects.dz_bottom - effects.dz_top, f->alpha()); - return createTransformedFormFactor(slicedff, effects.position, rot); - } - if (effects.dz_top > f->heightRatio() * f->base_height()) { - double dbase_edge = 2 * (f->base_height() - effects.dz_bottom) * Math::cot(f->alpha()); - auto* slicedff = - new Pyramid4(f->length() - dbase_edge, - f->height() - effects.dz_bottom - effects.dz_top, M_PI - f->alpha()); - return createTransformedFormFactor(slicedff, effects.position, rot); - } - auto* slicedff = - new Bipyramid4(f->length(), f->base_height() - effects.dz_bottom, - f->heightRatio() * f->base_height() - effects.dz_top, f->alpha()); - return createTransformedFormFactor(slicedff, effects.position, rot); - - } else if (const auto* f = dynamic_cast<const Cylinder*>(ff)) { - auto effects = computeSlicingEffects(limits, translation, f->height()); - auto* slicedff = - new Cylinder(f->radius(), f->height() - effects.dz_bottom - effects.dz_top); - return createTransformedFormFactor(slicedff, effects.position, rot); - - } else if (const auto* f = dynamic_cast<const EllipsoidalCylinder*>(ff)) { - auto effects = computeSlicingEffects(limits, translation, f->height()); - auto* slicedff = new EllipsoidalCylinder(f->radiusX(), f->radiusY(), - f->height() - effects.dz_bottom - effects.dz_top); - return createTransformedFormFactor(slicedff, effects.position, rot); - - } else if (const auto* f = dynamic_cast<const HorizontalCylinder*>(ff)) { - auto effects = computeSlicingEffects(limits, translation, f->height()); - auto* slicedff = - new HorizontalCylinder(f->radius(), f->length(), -f->radius() + effects.dz_bottom, - f->radius() - effects.dz_top); - return createTransformedFormFactor(slicedff, effects.position, rot); - - } else if (const auto* f = dynamic_cast<const Sphere*>(ff)) { - auto effects = computeSlicingEffects(limits, translation, f->height()); - auto* slicedff = - new TruncatedSphere(f->radius(), f->height() - effects.dz_bottom, effects.dz_top); - return createTransformedFormFactor(slicedff, effects.position, rot); - - } else if (const auto* f = dynamic_cast<const Spheroid*>(ff)) { - double flattening = f->height() / (2.0 * f->radius()); - auto effects = computeSlicingEffects(limits, translation, f->height()); - auto* slicedff = new TruncatedSpheroid(f->radius(), f->height() - effects.dz_bottom, - flattening, effects.dz_top); - return createTransformedFormFactor(slicedff, effects.position, rot); - - } else if (const auto* f = dynamic_cast<const LongBoxGauss*>(ff)) { - auto effects = computeSlicingEffects(limits, translation, f->height()); - auto* slicedff = new LongBoxGauss(f->length(), f->width(), - f->height() - effects.dz_bottom - effects.dz_top); - return createTransformedFormFactor(slicedff, effects.position, rot); - - } else if (const auto* f = dynamic_cast<const LongBoxLorentz*>(ff)) { - auto effects = computeSlicingEffects(limits, translation, f->height()); - auto* slicedff = new LongBoxLorentz(f->length(), f->width(), - f->height() - effects.dz_bottom - effects.dz_top); - return createTransformedFormFactor(slicedff, effects.position, rot); - - } else if (const auto* f = dynamic_cast<const Prism3*>(ff)) { - auto effects = computeSlicingEffects(limits, translation, f->height()); - auto* slicedff = - new Prism3(f->baseEdge(), f->height() - effects.dz_bottom - effects.dz_top); - return createTransformedFormFactor(slicedff, effects.position, rot); - - } else if (const auto* f = dynamic_cast<const Prism6*>(ff)) { - auto effects = computeSlicingEffects(limits, translation, f->height()); - auto* slicedff = - new Prism6(f->baseEdge(), f->height() - effects.dz_bottom - effects.dz_top); - return createTransformedFormFactor(slicedff, effects.position, rot); - - } else if (const auto* f = dynamic_cast<const Pyramid4*>(ff)) { - auto effects = computeSlicingEffects(limits, translation, f->height()); - double dbaseEdge = 2 * effects.dz_bottom * Math::cot(f->alpha()); - auto* slicedff = new Pyramid4(f->baseEdge() - dbaseEdge, - f->height() - effects.dz_bottom - effects.dz_top, f->alpha()); - return createTransformedFormFactor(slicedff, effects.position, rot); - - } else if (const auto* f = dynamic_cast<const Pyramid3*>(ff)) { - auto effects = computeSlicingEffects(limits, translation, f->height()); - double dbaseEdge = 2 * sqrt(3) * effects.dz_bottom * Math::cot(f->alpha()); - auto* slicedff = new Pyramid3(f->baseEdge() - dbaseEdge, - f->height() - effects.dz_bottom - effects.dz_top, f->alpha()); - return createTransformedFormFactor(slicedff, effects.position, rot); - - } else if (const auto* f = dynamic_cast<const TruncatedSphere*>(ff)) { - auto effects = computeSlicingEffects(limits, translation, f->height()); - auto* slicedff = - new TruncatedSphere(f->radius(), f->untruncated_height() - effects.dz_bottom, - effects.dz_top + f->removedTop()); - return createTransformedFormFactor(slicedff, effects.position, rot); - - } else if (const auto* f = dynamic_cast<const TruncatedSpheroid*>(ff)) { - auto effects = computeSlicingEffects(limits, translation, f->height()); - auto* slicedff = - new TruncatedSpheroid(f->radius(), f->untruncated_height() - effects.dz_bottom, - f->heightFlattening(), effects.dz_top + f->removedTop()); - return createTransformedFormFactor(slicedff, effects.position, rot); - - } else - throw std::runtime_error("Slicing of " + ff->className() + " not supported"); + const double height = span.hig() - span.low(); + const SlicingEffects effects = computeSlicingEffects(limits, translation, height); + IFormFactor* slicedff = doSlice(ff, effects.dz_bottom, effects.dz_top); + return createTransformedFormFactor(slicedff, effects.position, rot); } //! Recursively processes the basis of a mesocrystal.