1 // File: Hydro_Projections.cxx
2 // Created: 11.12.13 17:47:42
4 // Copyright: Open CASCADE 2013
6 #include <HYDROData_Projection.h>
7 #include <BRepAdaptor_Curve.hxx>
8 #include <BRep_Builder.hxx>
9 #include <BRepBuilderAPI_Sewing.hxx>
10 #include <BRepLib.hxx>
11 #include <BRepLib_MakeEdge.hxx>
12 #include <BRepLib_MakeFace.hxx>
13 #include <BRepExtrema_DistShapeShape.hxx>
14 #include <Bnd_Box.hxx>
15 #include <BRepBndLib.hxx>
18 #include <HLRAlgo_Projector.hxx>
19 #include <HLRBRep_Algo.hxx>
20 #include <HLRBRep_HLRToShape.hxx>
21 #include <IntCurvesFace_ShapeIntersector.hxx>
22 #include <Precision.hxx>
23 #include <TopoDS_Edge.hxx>
24 #include <TopoDS_Shape.hxx>
25 #include <TopoDS_Vertex.hxx>
26 #include <TopoDS_Wire.hxx>
28 #include <TopoDS_Iterator.hxx>
30 #include <TopTools_ListIteratorOfListOfShape.hxx>
31 #include <TopTools_MapOfShape.hxx>
32 #include <TopTools_IndexedDataMapOfShapeListOfShape.hxx>
33 #include <TopTools_DataMapOfShapeReal.hxx>
35 HYDROData_Make3dMesh::HYDROData_Make3dMesh( const TopoDS_Shape& aShape,
36 const Standard_Real Tolerance )
38 myIntersector.Load(aShape, Tolerance);
41 Standard_Boolean HYDROData_Make3dMesh::GetHighestOriginal(const Standard_Real aX,
42 const Standard_Real aY,
45 gp_Pnt ProjPnt(aX, aY, 0.);
46 gp_Lin Ray(ProjPnt, -gp::DZ());
47 myIntersector.PerformNearest(Ray, -Precision::Infinite(), 0.);
48 if (!myIntersector.IsDone() || myIntersector.NbPnt() == 0)
49 return Standard_False;
51 HighestPoint = myIntersector.Pnt(1);
55 //=======================================================================
56 //function : FindClosestDirection
57 //purpose : auxiliary function
58 //=======================================================================
59 TopoDS_Edge HYDROData_Projection::FindClosestDirection( const TopoDS_Vertex& StartVertex,
60 const TopTools_ListOfShape& Candidates,
61 const gp_Vec& StartDir )
63 Standard_Real MinAngle = M_PI;
66 TopTools_ListIteratorOfListOfShape itl(Candidates);
67 for (; itl.More(); itl.Next())
69 TopoDS_Edge anEdge = TopoDS::Edge(itl.Value());
70 BRepAdaptor_Curve BAcurve(anEdge);
74 Standard_Real Par, Par2 = 0.; //to avoid warning
75 Standard_Boolean ToReverse = Standard_False;
78 TopExp::Vertices(anEdge, V1, V2);
79 if (StartVertex.IsSame(V1))
80 Par = 0.99*BAcurve.FirstParameter() + 0.01*BAcurve.LastParameter();
83 Par = 0.01*BAcurve.FirstParameter() + 0.99*BAcurve.LastParameter();
84 ToReverse = Standard_True;
88 Par2 = 0.01*BAcurve.FirstParameter() + 0.99*BAcurve.LastParameter();
91 BAcurve.D1(Par, aPnt, aDir);
97 BAcurve.D1(Par2, aPnt2, aDir2);
101 Standard_Real anAngle = StartDir.Angle(aDir);
102 if (anAngle < MinAngle)
110 anAngle = StartDir.Angle(aDir2);
111 if (anAngle < MinAngle)
122 //=======================================================================
123 //function : BuildOutWire
124 //purpose : auxiliary function
125 //=======================================================================
126 TopoDS_Wire HYDROData_Projection::BuildOutWire( const TopTools_IndexedDataMapOfShapeListOfShape& VEmap,
127 const TopoDS_Vertex& StartVertex,
128 TopoDS_Edge& StartEdge)
130 Standard_Real AngularTol = 0.1; //0.01; //1.e-4; //Precision::Angular();
131 TopTools_MapOfShape BoundEdges;
135 BB.MakeWire(theWire);
137 TopoDS_Vertex V1, V2;
138 TopExp::Vertices(StartEdge, V1, V2);
139 if (StartVertex.IsSame(V1))
140 StartEdge.Orientation(TopAbs_FORWARD);
142 StartEdge.Orientation(TopAbs_REVERSED);
143 BB.Add(theWire, StartEdge);
144 BoundEdges.Add(StartEdge);
146 TopoDS_Vertex CurVertex = (StartVertex.IsSame(V1))? V2 : V1;
147 TopoDS_Edge CurEdge = StartEdge;
148 gp_Vec Normal(0., 0., 1.);
151 if (CurVertex.IsSame(StartVertex))
153 theWire.Closed(Standard_True);
157 const TopTools_ListOfShape& Candidates = VEmap.FindFromKey(CurVertex);
158 Standard_Real MinAngle = M_PI;
160 BRepAdaptor_Curve CurCurve(CurEdge);
161 TopExp::Vertices(CurEdge, V1, V2);
162 Standard_Real CurPar;
163 if (CurVertex.IsSame(V2))
164 CurPar = CurCurve.LastParameter();
166 CurPar = CurCurve.FirstParameter();
169 CurCurve.D1(CurPar, aPnt, CurDir);
170 if (CurDir.SquareMagnitude() < Precision::PConfusion())
172 CurPar = (CurVertex.IsSame(V2))?
173 0.01*CurCurve.FirstParameter() + 0.99*CurCurve.LastParameter() :
174 0.99*CurCurve.FirstParameter() + 0.01*CurCurve.LastParameter();
175 CurCurve.D1(CurPar, aPnt, CurDir);
177 if (CurVertex.IsSame(V1))
181 TopTools_ListIteratorOfListOfShape itl(Candidates);
182 for (; itl.More(); itl.Next())
184 TopoDS_Edge anEdge = TopoDS::Edge(itl.Value());
185 if (BoundEdges.Contains(anEdge)) //if (anEdge.IsSame(CurEdge))
188 TopExp::Vertices(anEdge, V1, V2);
192 BRepAdaptor_Curve BAcurve(anEdge);
194 Standard_Real aPar = (CurVertex.IsSame(V1))?
195 0.99*BAcurve.FirstParameter() + 0.01*BAcurve.LastParameter() :
196 0.01*BAcurve.FirstParameter() + 0.99*BAcurve.LastParameter();
197 //BAcurve.FirstParameter() : BAcurve.LastParameter();
199 BAcurve.D1(aPar, aPnt, aDir);
200 if (CurVertex.IsSame(V2))
203 Standard_Real anAngle = CurDir.AngleWithRef(aDir, Normal);
204 if (Abs(anAngle + M_PI) < AngularTol) //anAngle = -PI
206 if (anAngle < MinAngle)
212 if (theEdge.IsNull())
215 TopExp::Vertices(theEdge, V1, V2);
216 if (CurVertex.IsSame(V1))
217 theEdge.Orientation(TopAbs_FORWARD);
219 theEdge.Orientation(TopAbs_REVERSED);
220 BB.Add(theWire, theEdge);
221 BoundEdges.Add(theEdge);
223 CurVertex = (CurVertex.IsSame(V1))? V2 : V1;
230 //=======================================================================
231 //Function : MakeProjection
232 //purpose : this function makes the "shadow" of a shape on the plane XOY
233 //=======================================================================
234 TopoDS_Face HYDROData_Projection::MakeProjection( const TopoDS_Shape& aShape )
236 HLRAlgo_Projector theProjector(gp::XOY());
238 Handle(HLRBRep_Algo) aHLRAlgo = new HLRBRep_Algo();
239 aHLRAlgo->Add(aShape);
240 aHLRAlgo->Projector(theProjector);
243 HLRBRep_HLRToShape aHLRToShape(aHLRAlgo);
245 TopoDS_Shape SharpEdges, OutLines;
246 TopoDS_Compound Total;
248 BB.MakeCompound(Total);
250 SharpEdges = aHLRToShape.VCompound();
251 OutLines = aHLRToShape.OutLineVCompound();
254 if (!SharpEdges.IsNull())
256 for (itc.Initialize(SharpEdges); itc.More(); itc.Next())
257 BB.Add(Total, itc.Value());
259 if (!OutLines.IsNull())
261 for (itc.Initialize(OutLines); itc.More(); itc.Next())
262 BB.Add(Total, itc.Value());
265 BRepBuilderAPI_Sewing aSewing;
266 Standard_Real tol = 1.0e-06;
267 Standard_Boolean NonManifoldMode = Standard_False;
268 aSewing.Init(tol, Standard_True,Standard_True,Standard_True,NonManifoldMode);
269 aSewing.SetFloatingEdgesMode(Standard_True);
271 aSewing.Add( Total );
274 TopoDS_Shape SewedEdges = aSewing.SewedShape();
276 BRepLib::BuildCurves3d( SewedEdges );
279 BRepBndLib::Add(SewedEdges, theBox);
280 Standard_Real Xmin, Ymin, Zmin, Xmax, Ymax, Zmax;
281 theBox.Get(Xmin, Ymin, Zmin, Xmax, Ymax, Zmax);
283 gp_Pnt P1(Xmin, Ymin, 0.), P2(Xmax, Ymin, 0.);
284 TopoDS_Edge LowerBound = BRepLib_MakeEdge(P1, P2);
286 Standard_Real Deviation = 1.e-7; //1.e-5;
287 BRepExtrema_DistShapeShape DSS(SewedEdges, LowerBound, Deviation);
289 TopTools_IndexedDataMapOfShapeListOfShape StartShapes;
290 TopTools_DataMapOfShapeReal EdgesWithPars;
292 for (i = 1; i <= DSS.NbSolution(); i++)
294 if (!StartShapes.Contains( DSS.SupportOnShape1(i) ))
296 TopTools_ListOfShape aList;
297 aList.Append( DSS.SupportOnShape2(i) );
298 StartShapes.Add( DSS.SupportOnShape1(i), aList );
302 TopTools_ListOfShape& aList = StartShapes.ChangeFromKey( DSS.SupportOnShape1(i) );
303 aList.Append( DSS.SupportOnShape2(i) );
305 if (DSS.SupportTypeShape1(i) == BRepExtrema_IsOnEdge)
308 DSS.ParOnEdgeS1(i, aPar);
309 EdgesWithPars.Bind( DSS.SupportOnShape1(i), aPar );
313 TopoDS_Shape aStartShape;
314 for (i = 1; i <= StartShapes.Extent(); i++)
316 const TopoDS_Shape& aShape = StartShapes.FindKey(i);
317 if (aShape.ShapeType() == TopAbs_EDGE)
319 aStartShape = aShape;
323 if (aStartShape.IsNull())
324 aStartShape = StartShapes.FindKey(1); //it is a vertex
326 TopoDS_Vertex StartVertex;
327 TopoDS_Edge StartEdge;
328 gp_Vec StartDir(1.,0.,0.);
329 TopTools_IndexedDataMapOfShapeListOfShape VEmap;
330 TopExp::MapShapesAndAncestors(SewedEdges, TopAbs_VERTEX, TopAbs_EDGE, VEmap);
331 if (aStartShape.ShapeType() == TopAbs_EDGE)
333 StartEdge = TopoDS::Edge(aStartShape);
334 Standard_Real StartPar = EdgesWithPars(StartEdge);
335 BRepAdaptor_Curve BAcurve(StartEdge);
338 BAcurve.D1(StartPar, aPnt, aDir);
339 StartVertex = (StartDir * aDir > 0.)?
340 TopExp::FirstVertex(StartEdge) : TopExp::LastVertex(StartEdge);
342 else // it is a vertex
344 StartVertex = TopoDS::Vertex(aStartShape);
345 const TopTools_ListOfShape& Candidates = VEmap.FindFromKey(StartVertex);
346 StartEdge = FindClosestDirection(StartVertex, Candidates, StartDir);
349 TopoDS_Wire OutWire = BuildOutWire(VEmap, StartVertex, StartEdge);
350 TopoDS_Face ProjFace = BRepLib_MakeFace(OutWire, Standard_True); //only plane