X-Git-Url: http://git.salome-platform.org/gitweb/?a=blobdiff_plain;f=src%2FGeomAlgoAPI%2FGeomAlgoAPI_SketchBuilder.cpp;h=5dd1a6a901eb69975047a41d8ba7a1ee46ac1cd7;hb=4c86b629d1bf8daa737f90b64e934c7bd22f6525;hp=bbeccf7b2a310dc48e8fcddbe45ed3cd5ecdf546;hpb=d400668ba119991a05de96e8d57cd7a4e91ba03c;p=modules%2Fshaper.git diff --git a/src/GeomAlgoAPI/GeomAlgoAPI_SketchBuilder.cpp b/src/GeomAlgoAPI/GeomAlgoAPI_SketchBuilder.cpp index bbeccf7b2..5dd1a6a90 100644 --- a/src/GeomAlgoAPI/GeomAlgoAPI_SketchBuilder.cpp +++ b/src/GeomAlgoAPI/GeomAlgoAPI_SketchBuilder.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014-2017 CEA/DEN, EDF R&D +// Copyright (C) 2014-2024 CEA, EDF // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public @@ -12,15 +12,16 @@ // // You should have received a copy of the GNU Lesser General Public // License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // -// See http://www.salome-platform.org/ or -// email : webmaster.salome@opencascade.com +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // #include #include +#include + #include #include #include @@ -164,7 +165,7 @@ bool isFirst(const TopoDS_Shape& theFirst, const TopoDS_Shape& theSecond, } // sorts faces (in theAreas list) to make persistent order: by initial shapes edges -static void sortFaces(TopTools_ListOfShape& theAreas, +static void sortAreas(TopTools_ListOfShape& theAreas, const std::list >& theInitialShapes) { // collect indices of all edges to operate them quickly @@ -199,46 +200,54 @@ static void sortFaces(TopTools_ListOfShape& theAreas, } } -void GeomAlgoAPI_SketchBuilder::createFaces( +void GeomAlgoAPI_SketchBuilder::build( const std::shared_ptr& theOrigin, const std::shared_ptr& theDirX, const std::shared_ptr& theNorm, - const std::list >& theFeatures, - std::list >& theResultFaces) + const std::list >& theEdges) { - if (theFeatures.empty()) + myResultFaces.clear(); + setDone(false); + if (theEdges.empty()) return; BRep_Builder aBuilder; // Planar face, where the sketch was built - Handle(Geom_Surface) aPlane(new Geom_Plane(theOrigin->impl(), theNorm->impl())); + gp_Ax3 aPlnAxes(theOrigin->impl(), theNorm->impl(), theDirX->impl()); + Handle(Geom_Surface) aPlane(new Geom_Plane(aPlnAxes)); TopoDS_Face aPlnFace; aBuilder.MakeFace(aPlnFace, aPlane, Precision::Confusion()); // Use General Fuse algorithm to prepare all subfaces, bounded by given list of edges - BOPAlgo_Builder aBB; - aBB.AddArgument(aPlnFace); + BOPAlgo_Builder* aBB = new BOPAlgo_Builder; + aBB->AddArgument(aPlnFace); + // Set fuzzy value for BOP, because PlaneGCS can solve the set of constraints with + // the precision up to 5.e-5 if the sketch contains arcs. + static const double THE_FUZZY_TOL = 5.e-5; + aBB->SetFuzzyValue(THE_FUZZY_TOL); + + setImpl(aBB); + setBuilderType(OCCT_BOPAlgo_Builder); NCollection_List anEdges; NCollection_List::Iterator aShapeIt; - std::list >::const_iterator aFeatIt = theFeatures.begin(); - for (; aFeatIt != theFeatures.end(); aFeatIt++) { + std::list >::const_iterator aFeatIt = theEdges.begin(); + for (; aFeatIt != theEdges.end(); aFeatIt++) { std::shared_ptr aShape(*aFeatIt); const TopoDS_Edge& anEdge = aShape->impl(); if (anEdge.ShapeType() == TopAbs_EDGE) - aBB.AddArgument(anEdge); + aBB->AddArgument(anEdge); } - aBB.Perform(); -#ifdef USE_OCCT_720 - if (aBB.HasErrors()) + aBB->Perform(); + if (aBB->HasErrors()) return; -#else - if (aBB.ErrorStatus()) - return; -#endif + + TopoDS_Compound aResult; + aBuilder.MakeCompound(aResult); + // Collect faces - TopTools_ListOfShape anAreas = aBB.Modified(aPlnFace); - sortFaces(anAreas, theFeatures); // sort faces by the edges in them + TopTools_ListOfShape anAreas = aBB->Modified(aPlnFace); + sortAreas(anAreas, theEdges); // sort faces by the edges in them TopTools_ListIteratorOfListOfShape anIt(anAreas); for (; anIt.More(); anIt.Next()) { TopoDS_Face aFace = TopoDS::Face(anIt.Value()); @@ -251,14 +260,25 @@ void GeomAlgoAPI_SketchBuilder::createFaces( TopoDS_Face aNewFace; aBuilder.MakeFace(aNewFace, aPlane, Precision::Confusion()); - // iterate on wires + // sort inner wires according to the original edges as well as faces + TopTools_ListOfShape aWires; TopExp_Explorer aWireExp(aFace, TopAbs_WIRE); - for (; aWireExp.More(); aWireExp.Next()) { - TopoDS_Wire aWire = TopoDS::Wire(aWireExp.Current()); + for (; aWireExp.More(); aWireExp.Next()) + aWires.Append(aWireExp.Current()); + if (aWires.Size() > 2) { + TopoDS_Shape anOuterWire = aWires.First(); + aWires.RemoveFirst(); + sortAreas(aWires, theEdges); + aWires.Prepend(anOuterWire); + } + + // iterate on wires + for (TopTools_ListIteratorOfListOfShape aWIt(aWires); aWIt.More(); aWIt.Next()) { + TopoDS_Wire aWire = TopoDS::Wire(aWIt.Value()); // to make faces equal on different platforms, we will find // a vertex lying on an edge with the lowest index in the list of initial edges - TopoDS_Vertex aStartVertex = findStartVertex(aWire, aFace, theFeatures); + TopoDS_Vertex aStartVertex = findStartVertex(aWire, aFace, theEdges); TopoDS_Wire aNewWire; aBuilder.MakeWire(aNewWire); @@ -294,30 +314,43 @@ void GeomAlgoAPI_SketchBuilder::createFaces( } // store face - aFace = aNewFace; + aBuilder.Add(aResult, aNewFace); std::shared_ptr aResFace(new GeomAPI_Shape); - aResFace->setImpl(new TopoDS_Face(aFace)); - theResultFaces.push_back(aResFace); + aResFace->setImpl(new TopoDS_Face(aNewFace)); + myResultFaces.push_back(aResFace); } + + // update results + GeomShapePtr aResShape(new GeomAPI_Shape); + aResShape->setImpl(new TopoDS_Shape(aResult)); + setShape(aResShape); + setDone(true); +} + +GeomAlgoAPI_SketchBuilder::GeomAlgoAPI_SketchBuilder( + const std::shared_ptr& thePlane, + const std::list >& theEdges) +{ + build(thePlane->location(), thePlane->xDirection(), thePlane->direction(), theEdges); } -void GeomAlgoAPI_SketchBuilder::createFaces(const std::shared_ptr& theOrigin, - const std::shared_ptr& theDirX, - const std::shared_ptr& theNorm, - const std::shared_ptr& theWire, - std::list >& theResultFaces) +GeomAlgoAPI_SketchBuilder::GeomAlgoAPI_SketchBuilder( + const std::shared_ptr& theOrigin, + const std::shared_ptr& theDirX, + const std::shared_ptr& theNorm, + const std::shared_ptr& theWire) { std::shared_ptr aWire = std::dynamic_pointer_cast(theWire); if(aWire) { // Filter wires, return only faces. - createFaces(theOrigin, theDirX, theNorm, aWire->getEdges(), theResultFaces); + build(theOrigin, theDirX, theNorm, aWire->getEdges()); } else { // it may be only one circle std::shared_ptr anEdge = std::dynamic_pointer_cast(theWire); if (anEdge) { std::list > aList; aList.push_back(anEdge); - createFaces(theOrigin, theDirX, theNorm, aList, theResultFaces); + build(theOrigin, theDirX, theNorm, aList); } } }