increase tolerance on helical shapes to avoid crash / broken geometry (#17356)

* increase tolerance on helical shapes to avoid crash

fix #17113
fix #9377
fix #11083

* added test cases for additive and subtractive helix

* fixed whitespace issue, reduced turncount for speed

* relaxed large scale testcases for OCCT 7.3 and below, work around windows CI error #17394

* Further reduce max size in test for buggy Ubuntu OCCT
This commit is contained in:
Eric Price
2024-11-11 17:44:27 +01:00
committed by GitHub
parent 0e25675aeb
commit 7680872e41
4 changed files with 162 additions and 1 deletions

View File

@@ -34,6 +34,7 @@
# include <BRepOffsetAPI_MakePipe.hxx>
# include <BRepOffsetAPI_MakePipeShell.hxx>
# include <BRepPrimAPI_MakeRevol.hxx>
# include <ShapeFix_ShapeTolerance.hxx>
# include <Precision.hxx>
# include <TopoDS.hxx>
# include <TopoDS_Face.hxx>
@@ -61,6 +62,7 @@ PROPERTY_SOURCE(PartDesign::Helix, PartDesign::ProfileBased)
// we purposely use not FLT_MAX because this would not be computable
const App::PropertyFloatConstraint::Constraints Helix::floatTurns = { Precision::Confusion(), INT_MAX, 1.0 };
const App::PropertyFloatConstraint::Constraints Helix::floatTolerance = { 0.1, INT_MAX, 1.0 };
const App::PropertyAngle::Constraints Helix::floatAngle = { -89.0, 89.0, 1.0 };
Helix::Helix()
@@ -104,6 +106,9 @@ Helix::Helix()
ADD_PROPERTY_TYPE(HasBeenEdited, (false), group, App::Prop_Hidden,
QT_TRANSLATE_NOOP("App::Property", "If false, the tool will propose an initial value for the pitch based on the profile bounding box,\n"
"so that self intersection is avoided."));
ADD_PROPERTY_TYPE(Tolerance, (0.1), group, App::Prop_None,
QT_TRANSLATE_NOOP("App::Property", "Fusion Tolerance for the Helix, increase if helical shape does not merge nicely with part."));
Tolerance.setConstraints(&floatTolerance);
setReadWriteStatusForMode(initialMode);
}
@@ -229,6 +234,17 @@ App::DocumentObjectExecReturn* Helix::execute()
TopoDS_Shape face = sketchshape;
face.Move(invObjLoc);
Bnd_Box bounds;
BRepBndLib::Add(path, bounds);
double size=sqrt(bounds.SquareExtent());
ShapeFix_ShapeTolerance fix;
fix.LimitTolerance(path, Precision::Confusion() * 1e-6 * size ); // needed to produce valid Pipe for very big parts
// We introduce final part tolerance with the second call to LimitTolerance below, however
// OCCT has a bug where the side-walls of the Pipe disappear with very large (km range) pieces
// increasing a tiny bit of extra tolerance to the path fixes this. This will in any case
// be less than the tolerance lower limit below, but sufficient to avoid the bug
BRepOffsetAPI_MakePipe mkPS(TopoDS::Wire(path), face, GeomFill_Trihedron::GeomFill_IsFrenet, Standard_False);
result = mkPS.Shape();
@@ -237,6 +253,8 @@ App::DocumentObjectExecReturn* Helix::execute()
if (SC.State() == TopAbs_IN) {
result.Reverse();
}
fix.LimitTolerance(result, Precision::Confusion() * size * Tolerance.getValue() ); // significant precision reduction due to helical approximation - needed to allow fusion to succeed
AddSubShape.setValue(result);