From 7c55db58d15a9e8aab158ddd3bff4b6908925fa3 Mon Sep 17 00:00:00 2001 From: Uwe Date: Sun, 30 Jan 2022 18:43:11 +0100 Subject: [PATCH] [Part] Extrusion: handle also complex nested structures - there can be strange cases with structures all intersecting each other. Their extrusion has no practical use case but we must avoid that such structures results either in an infinite loop or in an invalid geometric result. --- src/Mod/Part/App/FeatureExtrusion.cpp | 26 +++++++++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/src/Mod/Part/App/FeatureExtrusion.cpp b/src/Mod/Part/App/FeatureExtrusion.cpp index 2d902a53d9..6903f26065 100644 --- a/src/Mod/Part/App/FeatureExtrusion.cpp +++ b/src/Mod/Part/App/FeatureExtrusion.cpp @@ -578,6 +578,12 @@ void Extrusion::makeDraft(const ExtrusionParameters& params, const TopoDS_Shape& void Extrusion::checkInnerWires(std::vector& isInnerWire, const ExtrusionParameters& params, std::vector& checklist, bool forInner, std::vector prisms) { + // store the number of wires to be checked + size_t numCheckWiresInitial = 0; + for (auto checks : checklist) { + if (checks) + ++numCheckWiresInitial; + } GProp_GProps tempProperties; Standard_Real momentOfInertiaInitial; Standard_Real momentOfInertiaFinal; @@ -638,7 +644,7 @@ void Extrusion::checkInnerWires(std::vector& isInnerWire, const ExtrusionP ++i; } - // if all wires are inner ones, we take the first one and issue a warning + // if all wires are inner ones, we take the first one as outer and issue a warning if (numCheckWires == isInnerWire.size()) { isInnerWire[0] = false; checklist[0] = false; @@ -647,6 +653,24 @@ void Extrusion::checkInnerWires(std::vector& isInnerWire, const ExtrusionP The first input one will now be taken as outer one.\n"); } + // There can be cases with several wires all intersecting each other. + // Then it is impossible to find out what wire is an inner one + // and we can only treat all wires in the checklist as outer ones. + if (numCheckWiresInitial == numCheckWires) { + i = 0; + for (auto checks : checklist) { + if (checks) { + isInnerWire[i] = false; + checklist[i] = false; + --numCheckWires; + } + ++i; + } + Base::Console().Warning("Extrusion: too many self-intersection structures!\n\ + Impossible to determine what structure is an inner one.\n\ + All undeterminable structures will therefore be taken as outer ones.\n"); + } + // recursively call the function until all wires are checked if (numCheckWires > 1) checkInnerWires(isInnerWire, params, checklist, !forInner, prisms);