1 // Copyright (C) 2014-2024 CEA, EDF
3 // This library is free software; you can redistribute it and/or
4 // modify it under the terms of the GNU Lesser General Public
5 // License as published by the Free Software Foundation; either
6 // version 2.1 of the License, or (at your option) any later version.
8 // This library is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 // Lesser General Public License for more details.
13 // You should have received a copy of the GNU Lesser General Public
14 // License along with this library; if not, write to the Free Software
15 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
20 #include <GeomAlgoAPI_NonPlanarFace.h>
22 #include <BRep_Builder.hxx>
23 #include <BRep_Tool.hxx>
24 #include <BRepTools_WireExplorer.hxx>
25 #include <BRepBuilderAPI_Copy.hxx>
26 #include <BRepOffsetAPI_MakeFilling.hxx>
27 #include <BRepBuilderAPI_MakeFace.hxx>
28 #include <BOPTools_AlgoTools.hxx>
30 #include <GeomAPI_Shape.h>
31 #include <Geom_Surface.hxx>
33 #include <ShapeFix_Face.hxx>
34 #include <ShapeAnalysis_FreeBounds.hxx>
35 #include <ShapeFix_ShapeTolerance.hxx>
36 #include <TopTools_HSequenceOfShape.hxx>
37 #include <TColStd_IndexedDataMapOfTransientTransient.hxx>
38 #include <TopoDS_Edge.hxx>
39 #include <TopoDS_Wire.hxx>
40 #include <TopoDS_Face.hxx>
41 #include <TopExp_Explorer.hxx>
44 //==================================================================================================
45 GeomAlgoAPI_NonPlanarFace::GeomAlgoAPI_NonPlanarFace(
46 const ListOfShape& theEdges)
51 //==================================================================================================
52 void GeomAlgoAPI_NonPlanarFace::build
53 (const ListOfShape& theEdges)
55 myResultFaces.clear();
63 Handle(TopTools_HSequenceOfShape) aSeqEdgesIn = new TopTools_HSequenceOfShape;
64 TColStd_IndexedDataMapOfTransientTransient aMapTShapes;
65 TopTools_MapOfShape aMapEdges;
66 for (auto anEdge: theEdges)
68 const TopoDS_Edge& aTEdge = anEdge->impl<TopoDS_Edge>();
69 if (aMapEdges.Add(aTEdge))
71 BRepBuilderAPI_Copy aCopy(aTEdge, Standard_False, Standard_False);
72 const TopoDS_Shape& aCopyEdge = aCopy.Shape();
73 aSeqEdgesIn->Append(aCopyEdge);
78 if (aSeqEdgesIn->IsEmpty())
83 // Connect edges to wires of maximum length
84 Handle(TopTools_HSequenceOfShape) aSeqWiresOut;
85 ShapeAnalysis_FreeBounds::ConnectEdgesToWires(aSeqEdgesIn, Precision::Confusion(), Standard_False, aSeqWiresOut);
87 // prepare compound result
88 BRep_Builder aBuilder;
89 TopoDS_Compound aResult;
90 aBuilder.MakeCompound(aResult);
92 // try to construct face for each non-planar wire
93 for(int ind = 1; ind <= aSeqWiresOut->Length(); ind++)
95 if(!aSeqWiresOut->Value(ind).Closed())
99 TopoDS_Wire aWire = TopoDS::Wire(aSeqWiresOut->Value(ind));
101 // try to construct filling surface
102 BRepOffsetAPI_MakeFilling aMF;
103 BRepTools_WireExplorer aWExp(aWire);
104 for (; aWExp.More(); aWExp.Next())
106 aMF.Add(TopoDS::Edge(aWExp.Current()), GeomAbs_C0);
114 TopoDS_Shape aFillRes = aMF.Shape();
115 Handle(Geom_Surface) aGS = BRep_Tool::Surface(TopoDS::Face(aFillRes));
116 BRepBuilderAPI_MakeFace aMakeFace(aGS, aWire);
117 if (aMakeFace.IsDone())
119 TopoDS_Face aNewFace = aMakeFace.Face();
120 Handle(ShapeFix_Face) aFix = new ShapeFix_Face(aNewFace);
122 aFix->FixOrientation();
123 aNewFace = aFix->Face();
125 //check and fix pcurves, if necessary
126 TopExp_Explorer aExpE;
127 Standard_Real aT, aTolE, aDMax;
128 ShapeFix_ShapeTolerance sat;
129 aExpE.Init(aNewFace, TopAbs_EDGE);
130 for (; aExpE.More(); aExpE.Next())
132 const TopoDS_Edge& aE = *(TopoDS_Edge*)&aExpE.Current();
133 if (!BOPTools_AlgoTools::ComputeTolerance(aNewFace, aE, aDMax, aT)) continue;
134 aTolE = BRep_Tool::Tolerance(aE);
135 if (aDMax < aTolE) continue;
137 sat.LimitTolerance(aE, aDMax);
141 aBuilder.Add(aResult, aNewFace);
142 std::shared_ptr<GeomAPI_Shape> aResFace(new GeomAPI_Shape);
143 aResFace->setImpl(new TopoDS_Face(aNewFace));
144 myResultFaces.push_back(aResFace);
149 GeomShapePtr aResShape(new GeomAPI_Shape);
150 aResShape->setImpl(new TopoDS_Shape(aResult));