[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.
This commit is contained in:
Uwe
2022-01-30 18:43:11 +01:00
parent 55f71f4015
commit 7c55db58d1

View File

@@ -578,6 +578,12 @@ void Extrusion::makeDraft(const ExtrusionParameters& params, const TopoDS_Shape&
void Extrusion::checkInnerWires(std::vector<bool>& isInnerWire, const ExtrusionParameters& params,
std::vector<bool>& checklist, bool forInner, std::vector<TopoDS_Shape> 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<bool>& 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<bool>& 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);