Salome HOME
Refs #289 - Spline profile is represented in OCC view as polyline profile
[modules/hydro.git] / src / HYDROData / HYDROData_Pipes.cxx
1 // File:      HYDROData_Pipes.cxx
2 // Created:   25.12.13 16:39:40
3 // Author:    jgv@ROLEX
4 // Copyright: Open CASCADE 2013
5
6 #include <HYDROData_Pipes.h>
7 #include <TopExp.hxx>
8 #include <TopoDS.hxx>
9 #include <TopoDS_Edge.hxx>
10 #include <TopoDS_Face.hxx>
11 #include <TopoDS_Iterator.hxx>
12 #include <gp_Pln.hxx>
13 #include <BRepOffsetAPI_NormalProjection.hxx>
14 #include <BRepLib_MakeVertex.hxx>
15 #include <BRepLib_MakeEdge.hxx>
16 #include <BRepLib_MakeFace.hxx>
17 #include <BRepLib_MakeWire.hxx>
18 #include <BRepExtrema_ExtCC.hxx>
19 #include <BRepBuilderAPI_Transform.hxx>
20 #include <BRepOffsetAPI_MakePipeShell.hxx>
21 #include <BRep_Tool.hxx>
22 #include <Geom_Curve.hxx>
23
24 HYDROData_Canal3dAnd2d::HYDROData_Canal3dAnd2d(const TopoDS_Wire& Profile,
25                            const TopoDS_Wire& Guideline)
26   : myProfile(Profile), myGuideline(Guideline)
27 {
28   TopExp::Vertices(myProfile, myLeftVertex, myRightVertex);
29
30   ProjectWireOntoXOY(myGuideline, myProjectedGuideline);
31   Make2dProfile();
32   SetMiddlePoint2d();
33   SetMiddlePoint3d();
34 }
35
36 Standard_Boolean HYDROData_Canal3dAnd2d::ProjectWireOntoXOY(const TopoDS_Wire& aWire,
37                                                   TopoDS_Wire& ProjectedWire)
38 {
39   gp_Pln XOY; //default plane
40   TopoDS_Face theXOYface = BRepLib_MakeFace(XOY);
41
42   BRepOffsetAPI_NormalProjection OrtProj(theXOYface);
43   OrtProj.Add(aWire);
44   //OrtProj.SetParams(...); ???
45   OrtProj.Build();
46   TopTools_ListOfShape Wires;
47   OrtProj.BuildWire(Wires);
48
49   if (Wires.Extent() != 1)
50     return Standard_False;
51   
52   ProjectedWire = TopoDS::Wire(Wires.First());
53   return Standard_True;
54 }
55
56 TopoDS_Vertex HYDROData_Canal3dAnd2d::ProjectVertexOntoXOY(const TopoDS_Vertex& aVertex)
57 {
58   gp_Pnt aPoint = BRep_Tool::Pnt(aVertex);
59   gp_Pnt aProjPoint(aPoint.X(), aPoint.Y(), 0.);
60   TopoDS_Vertex aProjVertex = BRepLib_MakeVertex(aProjPoint);
61   return aProjVertex;
62 }
63
64 void HYDROData_Canal3dAnd2d::Make2dProfile()
65 {
66   TopoDS_Vertex ProjectedLeftVertex = ProjectVertexOntoXOY(myLeftVertex);
67   TopoDS_Vertex ProjectedRightVertex = ProjectVertexOntoXOY(myRightVertex);
68   TopoDS_Edge anEdge = BRepLib_MakeEdge(ProjectedLeftVertex, ProjectedRightVertex);
69   myProjectedProfile = BRepLib_MakeWire(anEdge);
70 }
71
72 void HYDROData_Canal3dAnd2d::SetMiddlePoint2d()
73 {
74   TopoDS_Vertex V1, V2;
75   TopExp::Vertices(myProjectedProfile, V1, V2);
76   gp_Pnt Pnt1 = BRep_Tool::Pnt(V1);
77   gp_Pnt Pnt2 = BRep_Tool::Pnt(V2);
78   myMiddlePoint2d.SetXYZ(0.5*(Pnt1.XYZ() + Pnt2.XYZ()));
79 }
80
81 void HYDROData_Canal3dAnd2d::SetMiddlePoint3d()
82 {
83   gp_Lin MidLin(myMiddlePoint2d, gp::DZ());
84   TopoDS_Edge MidEdge = BRepLib_MakeEdge(MidLin);
85   TopoDS_Iterator itw(myProfile);
86   for (; itw.More(); itw.Next())
87   {
88     const TopoDS_Edge& anEdge = TopoDS::Edge(itw.Value());
89     BRepExtrema_ExtCC ExtremaEE(MidEdge, anEdge);
90     if (ExtremaEE.IsDone() && ExtremaEE.NbExt() != 0)
91     {
92       for (Standard_Integer i = 1; i <= ExtremaEE.NbExt(); i++)
93       {
94         if (ExtremaEE.SquareDistance(i) <= Precision::Confusion())
95         {
96           myMiddlePoint3d = ExtremaEE.PointOnE1(i);
97           break;
98         }
99       }
100     }
101   }
102 }
103
104 TopoDS_Wire HYDROData_Canal3dAnd2d::SetTransformedProfile(const TopoDS_Wire& aProfile,
105                                                 const TopoDS_Wire& aGuideline,
106                                                 const gp_Pnt& aMiddlePoint)
107 {
108   TopoDS_Wire aTransformedProfile;
109   
110   TopoDS_Iterator itw(myProjectedGuideline);
111   TopoDS_Edge FirstEdge = TopoDS::Edge(itw.Value());
112   Standard_Real fpar, lpar;
113   Handle(Geom_Curve) FirstCurve = BRep_Tool::Curve(FirstEdge, fpar, lpar);
114   gp_Pnt StartPnt;
115   gp_Vec StartVec;
116   FirstCurve->D1(fpar, StartPnt, StartVec);
117
118   TopoDS_Vertex FirstOnGuide, LastOnGuide;
119   TopExp::Vertices(aGuideline, FirstOnGuide, LastOnGuide);
120   gp_Pnt StartPointOnGuide = BRep_Tool::Pnt(FirstOnGuide);
121
122   gp_Trsf Translation, Rotation;
123   Translation.SetTranslation(aMiddlePoint, StartPointOnGuide);
124   aTransformedProfile =
125     TopoDS::Wire(BRepBuilderAPI_Transform(aProfile, Translation, Standard_True)); //copy
126
127   gp_Vec Vertical(0.,0.,1.);
128   TopoDS_Vertex LeftVertex, RightVertex;
129   TopExp::Vertices(aTransformedProfile, LeftVertex, RightVertex);
130   gp_Pnt LeftPoint  = BRep_Tool::Pnt(LeftVertex);
131   gp_Pnt RightPoint = BRep_Tool::Pnt(RightVertex);
132   gp_Vec LeftToRight(LeftPoint, RightPoint);
133   gp_Vec NormalToProfile = Vertical ^ LeftToRight;
134
135   gp_Vec AxisOfRotation = NormalToProfile ^ StartVec;
136   if (AxisOfRotation.Magnitude() <= gp::Resolution())
137   {
138     if (Vertical * LeftToRight < 0.)
139     {
140       gp_Ax1 theVertical(StartPointOnGuide, gp::DZ());
141       Rotation.SetRotation(theVertical, M_PI);
142     }
143   }
144   else
145   {
146     gp_Ax1 theAxis(StartPointOnGuide, AxisOfRotation);
147     Standard_Real theAngle = NormalToProfile.AngleWithRef(StartVec, AxisOfRotation);
148     Rotation.SetRotation(theAxis, theAngle);
149   }
150
151   aTransformedProfile =
152     TopoDS::Wire(BRepBuilderAPI_Transform(aTransformedProfile, Rotation, Standard_True)); //copy
153   
154   return aTransformedProfile;
155 }
156
157 Standard_Boolean HYDROData_Canal3dAnd2d::Create3dPresentation()
158 {
159   myTransformedProfile3d = SetTransformedProfile(myProfile, myGuideline, myMiddlePoint3d);
160
161   mySweep3d = new BRepOffsetAPI_MakePipeShell(myGuideline);
162   mySweep3d->SetMode(gp::DZ()); //optional
163   mySweep3d->Add(myTransformedProfile3d);
164   //mySweep3d->SetTransitionMode(BRepBuilderAPI_RightCorner); //optional
165   mySweep3d->Build();
166   if (!mySweep3d->IsDone())
167     return Standard_False;
168
169   myPipe3d = mySweep3d->Shape();
170   return Standard_True;
171 }
172
173 Standard_Boolean HYDROData_Canal3dAnd2d::Create2dPresentation()
174 {
175   myTransformedProfile2d = SetTransformedProfile(myProjectedProfile, myProjectedGuideline, myMiddlePoint2d);
176
177   mySweep2d = new BRepOffsetAPI_MakePipeShell(myProjectedGuideline);
178   mySweep2d->SetMode(gp::DZ()); //optional
179   mySweep2d->Add(myTransformedProfile2d);
180   //mySweep2d->SetTransitionMode(BRepBuilderAPI_RightCorner); //optional
181   mySweep2d->Build();
182   if (!mySweep2d->IsDone())
183     return Standard_False;
184
185   myPipe2d = mySweep2d->Shape();
186   myInlet  = TopoDS::Wire(mySweep2d->FirstShape());
187   myOutlet = TopoDS::Wire(mySweep2d->LastShape());
188   TopoDS_Vertex V1, V2, V3, V4;
189   TopExp::Vertices(myTransformedProfile2d, V1, V2);
190   TopExp::Vertices(myInlet, V3, V4);
191   gp_Pnt P1 = BRep_Tool::Pnt(V1);
192   gp_Pnt P3 = BRep_Tool::Pnt(V3);
193   if (P1.IsEqual(P3, Precision::Confusion()))
194   { myLeftVertex2d = V3; myRightVertex2d = V4; }
195   else
196   { myLeftVertex2d = V4; myRightVertex2d = V3; }
197   
198   return Standard_True;
199 }
200
201 TopoDS_Wire HYDROData_Canal3dAnd2d::GetBank(const TopoDS_Vertex& aFreeVertex)
202 {
203   TopoDS_Wire aBank;
204
205   TopTools_ListOfShape GeneratedShapes;
206   GeneratedShapes = mySweep2d->Generated(aFreeVertex);
207   BRepLib_MakeWire MW;
208   MW.Add(GeneratedShapes);
209   aBank = MW.Wire();
210
211   return aBank;
212 }
213
214 TopoDS_Shape HYDROData_Canal3dAnd2d::Get3dPresentation()
215 {
216   return myPipe3d;
217 }
218
219 TopoDS_Shape HYDROData_Canal3dAnd2d::Get2dPresentation()
220 {
221   return myPipe2d;
222 }
223
224 TopoDS_Wire HYDROData_Canal3dAnd2d::GetInlet()
225 {
226   return myInlet;
227 }
228
229 TopoDS_Wire HYDROData_Canal3dAnd2d::GetOutlet()
230 {
231   return myOutlet;
232 }
233
234 TopoDS_Wire HYDROData_Canal3dAnd2d::GetLeftBank()
235 {
236   return GetBank(myLeftVertex2d);
237 }
238
239 TopoDS_Wire HYDROData_Canal3dAnd2d::GetRightBank()
240 {
241   return GetBank(myRightVertex2d);
242 }