diff --git a/src/Mod/Draft/Draft.py b/src/Mod/Draft/Draft.py index 0065f6659..2e47c83fe 100644 --- a/src/Mod/Draft/Draft.py +++ b/src/Mod/Draft/Draft.py @@ -3782,12 +3782,23 @@ class _ShapeString(_DraftObject): p = w.Vertexes[0].Point u,v = face.Surface.parameter(p) if face.isPartOfDomain(u,v): - if face.Orientation == w.Orientation: - w.reverse() + f = Part.Face(w) + if face.Orientation == f.Orientation: + if f.Surface.Axis * face.Surface.Axis < 0: + w.reverse() + else: + if f.Surface.Axis * face.Surface.Axis > 0: + w.reverse() wire2Face.append(w) else: - compFaces.append(Part.Face(w)) + f = Part.Face(w) + if f.Surface.Axis.z < 0.0: + f.reverse() + compFaces.append(f) face = Part.Face(wire2Face) + face.validate() + if face.Surface.Axis.z < 0.0: + face.reverse() compFaces.append(face) ret = Part.Compound(compFaces) return ret diff --git a/src/Mod/Part/App/TopoShapeFacePy.xml b/src/Mod/Part/App/TopoShapeFacePy.xml index 8d18c4a04..8c8bb25a4 100644 --- a/src/Mod/Part/App/TopoShapeFacePy.xml +++ b/src/Mod/Part/App/TopoShapeFacePy.xml @@ -59,6 +59,11 @@ Make a half-space solid by this face and a reference point. + + + Validate the face. + + Set the tolerance for the face. diff --git a/src/Mod/Part/App/TopoShapeFacePyImp.cpp b/src/Mod/Part/App/TopoShapeFacePyImp.cpp index b0460a580..00e86fddd 100644 --- a/src/Mod/Part/App/TopoShapeFacePyImp.cpp +++ b/src/Mod/Part/App/TopoShapeFacePyImp.cpp @@ -25,6 +25,7 @@ #ifndef _PreComp_ # include # include +# include # include # include # include @@ -49,6 +50,10 @@ # include # include # include +# include +# include +# include +# include #endif #include @@ -445,6 +450,59 @@ PyObject* TopoShapeFacePy::makeHalfSpace(PyObject *args) } } +PyObject* TopoShapeFacePy::validate(PyObject *args) +{ + if (!PyArg_ParseTuple(args, "")) + return 0; + + try { + const TopoDS_Face& face = TopoDS::Face(getTopoShapePtr()->_Shape); + BRepCheck_Analyzer aChecker(face); + if (!aChecker.IsValid()) { + TopoDS_Wire outerwire = ShapeAnalysis::OuterWire(face); + TopTools_IndexedMapOfShape myMap; + myMap.Add(outerwire); + + TopExp_Explorer xp(face,TopAbs_WIRE); + ShapeFix_Wire fix; + fix.SetFace(face); + fix.Load(outerwire); + fix.Perform(); + BRepBuilderAPI_MakeFace mkFace(fix.WireAPIMake()); + while (xp.More()) { + if (!myMap.Contains(xp.Current())) { + fix.Load(TopoDS::Wire(xp.Current())); + fix.Perform(); + mkFace.Add(fix.WireAPIMake()); + } + xp.Next(); + } + + aChecker.Init(mkFace.Face()); + if (!aChecker.IsValid()) { + ShapeFix_Shape fix(mkFace.Face()); + fix.SetPrecision(Precision::Confusion()); + fix.SetMaxTolerance(Precision::Confusion()); + fix.SetMaxTolerance(Precision::Confusion()); + fix.Perform(); + fix.FixWireTool()->Perform(); + fix.FixFaceTool()->Perform(); + getTopoShapePtr()->_Shape = fix.Shape(); + } + else { + getTopoShapePtr()->_Shape = mkFace.Face(); + } + } + + Py_Return; + } + catch (Standard_Failure) { + Handle_Standard_Failure e = Standard_Failure::Caught(); + PyErr_SetString(PyExc_Exception, e->GetMessageString()); + return 0; + } +} + Py::Object TopoShapeFacePy::getSurface() const { const TopoDS_Face& f = TopoDS::Face(getTopoShapePtr()->_Shape);