diff --git a/cadquery/occ_impl/shapes.py b/cadquery/occ_impl/shapes.py index 9be33d8c5..04610a19f 100644 --- a/cadquery/occ_impl/shapes.py +++ b/cadquery/occ_impl/shapes.py @@ -156,7 +156,7 @@ from OCP.TopExp import TopExp -from OCP.ShapeFix import ShapeFix_Shape, ShapeFix_Solid +from OCP.ShapeFix import ShapeFix_Shape, ShapeFix_Solid, ShapeFix_Face from OCP.STEPControl import STEPControl_Writer, STEPControl_AsIs @@ -2100,7 +2100,12 @@ def makeFromWires( if not BRepLib_FindSurface(ws.wrapped, OnlyPlane=True).Found(): raise ValueError("Cannot build face(s): wires not planar") - face_builder = BRepBuilderAPI_MakeFace(outerWire.wrapped, True) + # fix outer wire + sf_s = ShapeFix_Shape(outerWire.wrapped) + sf_s.Perform() + wo = TopoDS.Wire_s(sf_s.Shape()) + + face_builder = BRepBuilderAPI_MakeFace(wo, True) for w in innerWires: face_builder.Add(w.wrapped) @@ -2110,9 +2115,13 @@ def makeFromWires( if not face_builder.IsDone(): raise ValueError(f"Cannot build face(s): {face_builder.Error()}") - face = face_builder.Shape() + face = face_builder.Face() + + sf_f = ShapeFix_Face(face) + sf_f.FixOrientation() + sf_f.Perform() - return cls(face).fix() + return cls(sf_f.Result()) @classmethod def makeSplineApprox( @@ -2127,7 +2136,7 @@ def makeSplineApprox( Approximate a spline surface through the provided points. :param points: a 2D list of Vectors that represent the points - :param tol: tolerance of the algorithm (consult OCC documentation). + :param tol: tolerance of the algorithm (consult OCC documentation). :param smoothing: optional tuple of 3 weights use for variational smoothing (default: None) :param minDeg: minimum spline degree. Enforced only when smothing is None (default: 1) :param maxDeg: maximum spline degree (default: 6) diff --git a/cadquery/selectors.py b/cadquery/selectors.py index 673bdec93..d4ddd6feb 100644 --- a/cadquery/selectors.py +++ b/cadquery/selectors.py @@ -488,7 +488,7 @@ class AreaNthSelector(_NthSelector): - closed planar Wires - a temporary face is created to compute area Will ignore non-planar or non-closed wires. - + Among other things can be used to select one of the nested coplanar wires or faces. @@ -534,7 +534,7 @@ def key(self, obj: Shape) -> float: return obj.Area() elif isinstance(obj, Wire): try: - return Face.makeFromWires(obj).Area() + return abs(Face.makeFromWires(obj).Area()) except Exception as ex: raise ValueError( f"Can not compute area of the Wire: {ex}. AreaNthSelector supports only closed planar Wires."