From 4c0c7fc84bd97b34ea49cecdf9327385315ec4f7 Mon Sep 17 00:00:00 2001 From: Eric Price Date: Thu, 26 Sep 2024 21:43:42 +0200 Subject: [PATCH] Do not allow loft where the segment shapes are too close ( fix #5855 ) A loft or pocket only makes sense if the segments used for it have some minimum separation. Having the shapes identical causes segfaults in OCCT Checking for CoG is a hack. Identical shapes have identical CoG - but an identical CoG does not necessarily mean identical shapes - however it can be argued that a shape that is not offset at least somewhat in the direction of the loft doesnt make a valid shape for a loft (it will typically freeze OCCT instead of crashing it) and a sufficiently suitable shape will have a different CoG throwing the exception will make it easy to identify if there ever is a case where this is a bad thing - and exceptions are better than segfaults. --- src/Mod/Part/App/TopoShapeExpansion.cpp | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/Mod/Part/App/TopoShapeExpansion.cpp b/src/Mod/Part/App/TopoShapeExpansion.cpp index 8527fecee7..3fdc9425ea 100644 --- a/src/Mod/Part/App/TopoShapeExpansion.cpp +++ b/src/Mod/Part/App/TopoShapeExpansion.cpp @@ -4157,7 +4157,15 @@ TopoShape& TopoShape::makeElementLoft(const std::vector& shapes, "Need at least two vertices, edges or wires to create loft face"); } + int i=0; + Base::Vector3d center1,center2; for (auto& sh : profiles) { + if (i>0) { + if (sh.getCenterOfGravity(center1) && profiles[i-1].getCenterOfGravity(center2) && center1.IsEqual(center2,Precision::Confusion())) { + FC_THROWM(Base::CADKernelError, + "Segments of a Loft/Pad do not have sufficient separation"); + } + } const auto& shape = sh.getShape(); if (shape.ShapeType() == TopAbs_VERTEX) { aGenerator.AddVertex(TopoDS::Vertex(shape)); @@ -4165,6 +4173,7 @@ TopoShape& TopoShape::makeElementLoft(const std::vector& shapes, else { aGenerator.AddWire(TopoDS::Wire(shape)); } + i++; } // close loft by duplicating initial profile as last profile. not perfect. if (isClosed == IsClosed::closed) {