1 // Copyright (C) 2014-2015 EDF-R&D
2 // This library is free software; you can redistribute it and/or
3 // modify it under the terms of the GNU Lesser General Public
4 // License as published by the Free Software Foundation; either
5 // version 2.1 of the License, or (at your option) any later version.
7 // This library is distributed in the hope that it will be useful,
8 // but WITHOUT ANY WARRANTY; without even the implied warranty of
9 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
10 // Lesser General Public License for more details.
12 // You should have received a copy of the GNU Lesser General Public
13 // License along with this library; if not, write to the Free Software
14 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
16 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
19 #include <HYDROData_Projection.h>
20 #include <BRepAdaptor_Curve.hxx>
21 #include <BRep_Builder.hxx>
22 #include <BRepBuilderAPI_Sewing.hxx>
23 #include <BRepLib.hxx>
24 #include <BRepLib_MakeEdge.hxx>
25 #include <BRepLib_MakeFace.hxx>
26 #include <BRepExtrema_DistShapeShape.hxx>
27 #include <Bnd_Box.hxx>
28 #include <BRepBndLib.hxx>
31 #include <HLRAlgo_Projector.hxx>
32 #include <HLRBRep_Algo.hxx>
33 #include <HLRBRep_HLRToShape.hxx>
34 #include <IntCurvesFace_ShapeIntersector.hxx>
35 #include <Precision.hxx>
36 #include <TopoDS_Edge.hxx>
37 #include <TopoDS_Shape.hxx>
38 #include <TopoDS_Vertex.hxx>
39 #include <TopoDS_Wire.hxx>
41 #include <TopoDS_Iterator.hxx>
43 #include <TopTools_ListIteratorOfListOfShape.hxx>
44 #include <TopTools_MapOfShape.hxx>
45 #include <TopTools_DataMapOfShapeReal.hxx>
47 HYDROData_Make3dMesh::HYDROData_Make3dMesh( const TopoDS_Shape& aShape,
48 const Standard_Real Tolerance )
50 myIntersector.Load(aShape, Tolerance);
53 Standard_Boolean HYDROData_Make3dMesh::GetHighestOriginal(const Standard_Real aX,
54 const Standard_Real aY,
57 gp_Pnt ProjPnt(aX, aY, 0.);
58 gp_Lin Ray(ProjPnt, -gp::DZ());
59 myIntersector.PerformNearest(Ray, -Precision::Infinite(), 0.);
60 if (!myIntersector.IsDone() || myIntersector.NbPnt() == 0)
61 return Standard_False;
63 HighestPoint = myIntersector.Pnt(1);
67 //=======================================================================
68 //function : FindClosestDirection
69 //purpose : auxiliary function
70 //=======================================================================
71 TopoDS_Edge HYDROData_Projection::FindClosestDirection( const TopoDS_Vertex& StartVertex,
72 const TopTools_ListOfShape& Candidates,
73 const gp_Vec& StartDir )
75 Standard_Real MinAngle = M_PI;
78 TopTools_ListIteratorOfListOfShape itl(Candidates);
79 for (; itl.More(); itl.Next())
81 TopoDS_Edge anEdge = TopoDS::Edge(itl.Value());
82 BRepAdaptor_Curve BAcurve(anEdge);
86 Standard_Real Par, Par2 = 0.; //to avoid warning
87 Standard_Boolean ToReverse = Standard_False;
90 TopExp::Vertices(anEdge, V1, V2);
91 if (StartVertex.IsSame(V1))
92 Par = 0.99*BAcurve.FirstParameter() + 0.01*BAcurve.LastParameter();
95 Par = 0.01*BAcurve.FirstParameter() + 0.99*BAcurve.LastParameter();
96 ToReverse = Standard_True;
100 Par2 = 0.01*BAcurve.FirstParameter() + 0.99*BAcurve.LastParameter();
103 BAcurve.D1(Par, aPnt, aDir);
109 BAcurve.D1(Par2, aPnt2, aDir2);
113 Standard_Real anAngle = StartDir.Angle(aDir);
114 if (anAngle < MinAngle)
122 anAngle = StartDir.Angle(aDir2);
123 if (anAngle < MinAngle)
134 //=======================================================================
135 //function : BuildOutWire
136 //purpose : auxiliary function
137 //=======================================================================
138 TopoDS_Wire HYDROData_Projection::BuildOutWire( const TopTools_IndexedDataMapOfShapeListOfShape& VEmap,
139 const TopoDS_Vertex& StartVertex,
140 TopoDS_Edge& StartEdge)
142 Standard_Real AngularTol = 0.1; //0.01; //1.e-4; //Precision::Angular();
143 TopTools_MapOfShape BoundEdges;
147 BB.MakeWire(theWire);
149 TopoDS_Vertex V1, V2;
150 TopExp::Vertices(StartEdge, V1, V2);
151 if (StartVertex.IsSame(V1))
152 StartEdge.Orientation(TopAbs_FORWARD);
154 StartEdge.Orientation(TopAbs_REVERSED);
155 BB.Add(theWire, StartEdge);
156 BoundEdges.Add(StartEdge);
158 TopoDS_Vertex CurVertex = (StartVertex.IsSame(V1))? V2 : V1;
159 TopoDS_Edge CurEdge = StartEdge;
160 gp_Vec Normal(0., 0., 1.);
163 if (CurVertex.IsSame(StartVertex))
165 theWire.Closed(Standard_True);
169 const TopTools_ListOfShape& Candidates = VEmap.FindFromKey(CurVertex);
170 Standard_Real MinAngle = M_PI;
172 BRepAdaptor_Curve CurCurve(CurEdge);
173 TopExp::Vertices(CurEdge, V1, V2);
174 Standard_Real CurPar;
175 if (CurVertex.IsSame(V2))
176 CurPar = CurCurve.LastParameter();
178 CurPar = CurCurve.FirstParameter();
181 CurCurve.D1(CurPar, aPnt, CurDir);
182 if (CurDir.SquareMagnitude() < Precision::PConfusion())
184 CurPar = (CurVertex.IsSame(V2))?
185 0.01*CurCurve.FirstParameter() + 0.99*CurCurve.LastParameter() :
186 0.99*CurCurve.FirstParameter() + 0.01*CurCurve.LastParameter();
187 CurCurve.D1(CurPar, aPnt, CurDir);
189 if (CurVertex.IsSame(V1))
193 TopTools_ListIteratorOfListOfShape itl(Candidates);
194 for (; itl.More(); itl.Next())
196 TopoDS_Edge anEdge = TopoDS::Edge(itl.Value());
197 if (BoundEdges.Contains(anEdge)) //if (anEdge.IsSame(CurEdge))
200 TopExp::Vertices(anEdge, V1, V2);
204 BRepAdaptor_Curve BAcurve(anEdge);
206 Standard_Real aPar = (CurVertex.IsSame(V1))?
207 0.99*BAcurve.FirstParameter() + 0.01*BAcurve.LastParameter() :
208 0.01*BAcurve.FirstParameter() + 0.99*BAcurve.LastParameter();
209 //BAcurve.FirstParameter() : BAcurve.LastParameter();
211 BAcurve.D1(aPar, aPnt, aDir);
212 if (CurVertex.IsSame(V2))
215 Standard_Real anAngle = CurDir.AngleWithRef(aDir, Normal);
216 if (Abs(anAngle + M_PI) < AngularTol) //anAngle = -PI
218 if (anAngle < MinAngle)
224 if (theEdge.IsNull())
227 TopExp::Vertices(theEdge, V1, V2);
228 if (CurVertex.IsSame(V1))
229 theEdge.Orientation(TopAbs_FORWARD);
231 theEdge.Orientation(TopAbs_REVERSED);
232 BB.Add(theWire, theEdge);
233 BoundEdges.Add(theEdge);
235 CurVertex = (CurVertex.IsSame(V1))? V2 : V1;
242 //=======================================================================
243 //Function : MakeProjection
244 //purpose : this function makes the "shadow" of a shape on the plane XOY
245 //=======================================================================
246 TopoDS_Face HYDROData_Projection::MakeProjection( const TopoDS_Shape& aShape )
248 if ( aShape.IsNull() )
249 return TopoDS_Face();
251 HLRAlgo_Projector theProjector(gp::XOY());
253 Handle(HLRBRep_Algo) aHLRAlgo = new HLRBRep_Algo();
254 aHLRAlgo->Add(aShape);
255 aHLRAlgo->Projector(theProjector);
258 HLRBRep_HLRToShape aHLRToShape(aHLRAlgo);
260 TopoDS_Shape SharpEdges, OutLines;
261 TopoDS_Compound Total;
263 BB.MakeCompound(Total);
265 SharpEdges = aHLRToShape.VCompound();
266 OutLines = aHLRToShape.OutLineVCompound();
269 if (!SharpEdges.IsNull())
271 for (itc.Initialize(SharpEdges); itc.More(); itc.Next())
272 BB.Add(Total, itc.Value());
274 if (!OutLines.IsNull())
276 for (itc.Initialize(OutLines); itc.More(); itc.Next())
277 BB.Add(Total, itc.Value());
280 BRepBuilderAPI_Sewing aSewing;
281 Standard_Real tol = 1.0e-06;
282 Standard_Boolean NonManifoldMode = Standard_False;
283 aSewing.Init(tol, Standard_True,Standard_True,Standard_True,NonManifoldMode);
284 aSewing.SetFloatingEdgesMode(Standard_True);
286 aSewing.Add( Total );
289 TopoDS_Shape SewedEdges = aSewing.SewedShape();
291 BRepLib::BuildCurves3d( SewedEdges );
294 BRepBndLib::Add(SewedEdges, theBox);
295 Standard_Real Xmin, Ymin, Zmin, Xmax, Ymax, Zmax;
296 theBox.Get(Xmin, Ymin, Zmin, Xmax, Ymax, Zmax);
298 gp_Pnt P1(Xmin, Ymin, 0.), P2(Xmax, Ymin, 0.);
299 TopoDS_Edge LowerBound = BRepLib_MakeEdge(P1, P2);
301 Standard_Real Deviation = 1.e-7; //1.e-5;
302 BRepExtrema_DistShapeShape DSS(SewedEdges, LowerBound, Deviation);
304 TopTools_IndexedDataMapOfShapeListOfShape StartShapes;
305 TopTools_DataMapOfShapeReal EdgesWithPars;
307 for (i = 1; i <= DSS.NbSolution(); i++)
309 if (!StartShapes.Contains( DSS.SupportOnShape1(i) ))
311 TopTools_ListOfShape aList;
312 aList.Append( DSS.SupportOnShape2(i) );
313 StartShapes.Add( DSS.SupportOnShape1(i), aList );
317 TopTools_ListOfShape& aList = StartShapes.ChangeFromKey( DSS.SupportOnShape1(i) );
318 aList.Append( DSS.SupportOnShape2(i) );
320 if (DSS.SupportTypeShape1(i) == BRepExtrema_IsOnEdge)
323 DSS.ParOnEdgeS1(i, aPar);
324 EdgesWithPars.Bind( DSS.SupportOnShape1(i), aPar );
328 TopoDS_Shape aStartShape;
329 for (i = 1; i <= StartShapes.Extent(); i++)
331 const TopoDS_Shape& aShape = StartShapes.FindKey(i);
332 if (aShape.ShapeType() == TopAbs_EDGE)
334 aStartShape = aShape;
338 if (aStartShape.IsNull())
339 aStartShape = StartShapes.FindKey(1); //it is a vertex
341 TopoDS_Vertex StartVertex;
342 TopoDS_Edge StartEdge;
343 gp_Vec StartDir(1.,0.,0.);
344 TopTools_IndexedDataMapOfShapeListOfShape VEmap;
345 TopExp::MapShapesAndAncestors(SewedEdges, TopAbs_VERTEX, TopAbs_EDGE, VEmap);
346 if (aStartShape.ShapeType() == TopAbs_EDGE)
348 StartEdge = TopoDS::Edge(aStartShape);
349 Standard_Real StartPar = EdgesWithPars(StartEdge);
350 BRepAdaptor_Curve BAcurve(StartEdge);
353 BAcurve.D1(StartPar, aPnt, aDir);
354 StartVertex = (StartDir * aDir > 0.)?
355 TopExp::FirstVertex(StartEdge) : TopExp::LastVertex(StartEdge);
357 else // it is a vertex
359 StartVertex = TopoDS::Vertex(aStartShape);
360 const TopTools_ListOfShape& Candidates = VEmap.FindFromKey(StartVertex);
361 StartEdge = FindClosestDirection(StartVertex, Candidates, StartDir);
364 TopoDS_Wire OutWire = BuildOutWire(VEmap, StartVertex, StartEdge);
365 TopoDS_Face ProjFace = BRepLib_MakeFace(OutWire, Standard_True); //only plane