From 320763d78ab8ab11cd1e77545a0eef187d9d136c Mon Sep 17 00:00:00 2001 From: DeepSOIC Date: Sun, 25 Sep 2016 18:32:33 +0300 Subject: [PATCH] PartDesign: port to use FaceMaker Minimalistic port. Only re-use code that was duplicate before. --- src/Mod/PartDesign/App/FeatureLoft.cpp | 3 +- src/Mod/PartDesign/App/FeaturePipe.cpp | 5 +- src/Mod/PartDesign/App/FeatureSketchBased.cpp | 192 +----------------- src/Mod/PartDesign/App/FeatureSketchBased.h | 7 +- src/Mod/PartDesign/App/PreCompiled.h | 7 + 5 files changed, 15 insertions(+), 199 deletions(-) diff --git a/src/Mod/PartDesign/App/FeatureLoft.cpp b/src/Mod/PartDesign/App/FeatureLoft.cpp index 09b1499ca..e591a9b40 100644 --- a/src/Mod/PartDesign/App/FeatureLoft.cpp +++ b/src/Mod/PartDesign/App/FeatureLoft.cpp @@ -42,6 +42,7 @@ #include #include #include +#include //#include "Body.h" #include "FeatureLoft.h" @@ -151,7 +152,7 @@ App::DocumentObjectExecReturn *Loft::execute(void) for(std::vector& wires : wiresections) backwires.push_back(wires.back()); - TopoDS_Shape back = makeFace(backwires); + TopoDS_Shape back = Part::FaceMakerCheese::makeFace(backwires); BRepBuilderAPI_Sewing sewer; sewer.SetTolerance(Precision::Confusion()); diff --git a/src/Mod/PartDesign/App/FeaturePipe.cpp b/src/Mod/PartDesign/App/FeaturePipe.cpp index c183b516d..ad3e8bdf2 100644 --- a/src/Mod/PartDesign/App/FeaturePipe.cpp +++ b/src/Mod/PartDesign/App/FeaturePipe.cpp @@ -63,6 +63,7 @@ #include #include #include +#include //#include "Body.h" #include "FeaturePipe.h" @@ -256,8 +257,8 @@ App::DocumentObjectExecReturn *Pipe::execute(void) } //build the top and bottom face, sew the shell and build the final solid - TopoDS_Shape front = makeFace(frontwires); - TopoDS_Shape back = makeFace(backwires); + TopoDS_Shape front = Part::FaceMakerCheese::makeFace(frontwires); + TopoDS_Shape back = Part::FaceMakerCheese::makeFace(backwires); BRepBuilderAPI_Sewing sewer; sewer.SetTolerance(Precision::Confusion()); diff --git a/src/Mod/PartDesign/App/FeatureSketchBased.cpp b/src/Mod/PartDesign/App/FeatureSketchBased.cpp index 256b37a8e..35c8ed255 100644 --- a/src/Mod/PartDesign/App/FeatureSketchBased.cpp +++ b/src/Mod/PartDesign/App/FeatureSketchBased.cpp @@ -77,6 +77,7 @@ #include #include #include +#include #include "FeatureSketchBased.h" #include "DatumPlane.h" #include "DatumLine.h" @@ -203,7 +204,7 @@ TopoDS_Shape ProfileBased::getVerifiedFace(bool silent) const { if (result->getTypeId().isDerivedFrom(Part::Part2DObject::getClassTypeId())) { auto wires = getProfileWires(); - return makeFace(wires); + return Part::FaceMakerCheese::makeFace(wires); } else if(result->getTypeId().isDerivedFrom(Part::Feature::getClassTypeId())) { if(Profile.getSubValues().empty()) @@ -373,195 +374,6 @@ void ProfileBased::onChanged(const App::Property* prop) FeatureAddSub::onChanged(prop); } -bool ProfileBased::isInside(const TopoDS_Wire& wire1, const TopoDS_Wire& wire2) const -{ - Bnd_Box box1; - BRepBndLib::Add(wire1, box1); - box1.SetGap(0.0); - - Bnd_Box box2; - BRepBndLib::Add(wire2, box2); - box2.SetGap(0.0); - - if (box1.IsOut(box2)) - return false; - - double prec = Precision::Confusion(); - - BRepBuilderAPI_MakeFace mkFace(wire1); - if (!mkFace.IsDone()) - Standard_Failure::Raise("Failed to create a face from wire in sketch"); - TopoDS_Face face = validateFace(mkFace.Face()); - BRepAdaptor_Surface adapt(face); - IntTools_FClass2d class2d(face, prec); - Handle_Geom_Surface surf = new Geom_Plane(adapt.Plane()); - ShapeAnalysis_Surface as(surf); - - TopExp_Explorer xp(wire2,TopAbs_VERTEX); - while (xp.More()) { - TopoDS_Vertex v = TopoDS::Vertex(xp.Current()); - gp_Pnt p = BRep_Tool::Pnt(v); - gp_Pnt2d uv = as.ValueOfUV(p, prec); - if (class2d.Perform(uv) == TopAbs_IN) - return true; - // TODO: We can make a check to see if all points are inside or all outside - // because otherwise we have some intersections which is not allowed - else - return false; - xp.Next(); - } - - return false; -} - -TopoDS_Face ProfileBased::validateFace(const TopoDS_Face& face) const -{ - 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(); - TopoDS_Face fixedFace = TopoDS::Face(fix.Shape()); - aChecker.Init(fixedFace); - if (!aChecker.IsValid()) - Standard_Failure::Raise("Failed to validate broken face"); - return fixedFace; - } - return mkFace.Face(); - } - - return face; -} - -TopoDS_Shape ProfileBased::makeFace(std::list& wires) const -{ - BRepBuilderAPI_MakeFace mkFace(wires.front()); - const TopoDS_Face& face = mkFace.Face(); - if (face.IsNull()) - return face; - gp_Dir axis(0,0,1); - BRepAdaptor_Surface adapt(face); - if (adapt.GetType() == GeomAbs_Plane) { - axis = adapt.Plane().Axis().Direction(); - } - - wires.pop_front(); - for (std::list::iterator it = wires.begin(); it != wires.end(); ++it) { - BRepBuilderAPI_MakeFace mkInnerFace(*it); - const TopoDS_Face& inner_face = mkInnerFace.Face(); - if (inner_face.IsNull()) - return inner_face; // failure - gp_Dir inner_axis(0,0,1); - BRepAdaptor_Surface adapt(inner_face); - if (adapt.GetType() == GeomAbs_Plane) { - inner_axis = adapt.Plane().Axis().Direction(); - } - // It seems that orientation is always 'Forward' and we only have to reverse - // if the underlying plane have opposite normals. - if (axis.Dot(inner_axis) < 0) - it->Reverse(); - mkFace.Add(*it); - } - return validateFace(mkFace.Face()); -} - -TopoDS_Shape ProfileBased::makeFace(const std::vector& w) const -{ - if (w.empty()) - return TopoDS_Shape(); - - //FIXME: Need a safe method to sort wire that the outermost one comes last - // Currently it's done with the diagonal lengths of the bounding boxes -#if 1 - std::vector wires = w; - std::sort(wires.begin(), wires.end(), Wire_Compare()); - std::list wire_list; - wire_list.insert(wire_list.begin(), wires.rbegin(), wires.rend()); -#else - //bug #0001133: try alternative sort algorithm - std::list unsorted_wire_list; - unsorted_wire_list.insert(unsorted_wire_list.begin(), w.begin(), w.end()); - std::list wire_list; - Wire_Compare wc; - while (!unsorted_wire_list.empty()) { - std::list::iterator w_ref = unsorted_wire_list.begin(); - std::list::iterator w_it = unsorted_wire_list.begin(); - for (++w_it; w_it != unsorted_wire_list.end(); ++w_it) { - if (wc(*w_ref, *w_it)) - w_ref = w_it; - } - wire_list.push_back(*w_ref); - unsorted_wire_list.erase(w_ref); - } -#endif - - // separate the wires into several independent faces - std::list< std::list > sep_wire_list; - while (!wire_list.empty()) { - std::list sep_list; - TopoDS_Wire wire = wire_list.front(); - wire_list.pop_front(); - sep_list.push_back(wire); - - std::list::iterator it = wire_list.begin(); - while (it != wire_list.end()) { - if (isInside(wire, *it)) { - sep_list.push_back(*it); - it = wire_list.erase(it); - } - else { - ++it; - } - } - - sep_wire_list.push_back(sep_list); - } - - if (sep_wire_list.size() == 1) { - std::list& wires = sep_wire_list.front(); - return makeFace(wires); - } - else if (sep_wire_list.size() > 1) { - TopoDS_Compound comp; - BRep_Builder builder; - builder.MakeCompound(comp); - for (std::list< std::list >::iterator it = sep_wire_list.begin(); it != sep_wire_list.end(); ++it) { - TopoDS_Shape aFace = makeFace(*it); - if (!aFace.IsNull()) - builder.Add(comp, aFace); - } - - return comp; - } - else { - return TopoDS_Shape(); // error - } -} void ProfileBased::getUpToFaceFromLinkSub(TopoDS_Face& upToFace, const App::PropertyLinkSub& refFace) diff --git a/src/Mod/PartDesign/App/FeatureSketchBased.h b/src/Mod/PartDesign/App/FeatureSketchBased.h index 9a2c838ed..b447b3ae9 100644 --- a/src/Mod/PartDesign/App/FeatureSketchBased.h +++ b/src/Mod/PartDesign/App/FeatureSketchBased.h @@ -151,14 +151,9 @@ protected: /// get Axis from ReferenceAxis void getAxis(const App::DocumentObject* pcReferenceAxis, const std::vector& subReferenceAxis, Base::Vector3d& base, Base::Vector3d& dir); - - TopoDS_Shape makeFace(const std::vector&) const; - + private: void onChanged(const App::Property* prop); - TopoDS_Face validateFace(const TopoDS_Face&) const; - TopoDS_Shape makeFace(std::list&) const; // for internal use only - bool isInside(const TopoDS_Wire&, const TopoDS_Wire&) const; bool isParallelPlane(const TopoDS_Shape&, const TopoDS_Shape&) const; bool isEqualGeometry(const TopoDS_Shape&, const TopoDS_Shape&) const; bool isQuasiEqual(const TopoDS_Shape&, const TopoDS_Shape&) const; diff --git a/src/Mod/PartDesign/App/PreCompiled.h b/src/Mod/PartDesign/App/PreCompiled.h index 85912d2ed..2d5ebfe8c 100644 --- a/src/Mod/PartDesign/App/PreCompiled.h +++ b/src/Mod/PartDesign/App/PreCompiled.h @@ -37,6 +37,13 @@ # define MeshExport #endif +#ifdef _MSC_VER +// disable warning triggered by use of Part::FaceMaker +// see forum thread "Warning C4275 non-dll class used as base for dll class" +// http://forum.freecadweb.org/viewtopic.php?f=10&t=17542 +# pragma warning( disable : 4275) +#endif + #ifdef _PreComp_ // standard