]> SALOME platform Git repositories - modules/geom.git/blob - src/GEOMImpl/GEOMImpl_DividedDiskDriver.cxx
Salome HOME
EDF 2281 : Second constructor and final documentation for the divided disk
[modules/geom.git] / src / GEOMImpl / GEOMImpl_DividedDiskDriver.cxx
1 //  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
2 //
3 //  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 //  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
5 //
6 //  This library is free software; you can redistribute it and/or
7 //  modify it under the terms of the GNU Lesser General Public
8 //  License as published by the Free Software Foundation; either
9 //  version 2.1 of the License.
10 //
11 //  This library is distributed in the hope that it will be useful,
12 //  but WITHOUT ANY WARRANTY; without even the implied warranty of
13 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 //  Lesser General Public License for more details.
15 //
16 //  You should have received a copy of the GNU Lesser General Public
17 //  License along with this library; if not, write to the Free Software
18 //  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
19 //
20 //  See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
21
22 #include <Standard_Stream.hxx>
23
24 #include <GEOMImpl_DividedDiskDriver.hxx>
25 #include <GEOMImpl_IDividedDisk.hxx>
26 #include <GEOMImpl_Types.hxx>
27 #include <GEOM_Function.hxx>
28
29 // OCCT includes
30 #include <gp_Pnt.hxx>
31 #include <gp_Dir.hxx>
32 #include <gp_Lin.hxx>
33 #include <gp_Circ.hxx>
34 #include <gp_Ax1.hxx>
35 #include <gp_Ax2.hxx>
36
37 #include <BRep_Builder.hxx>
38 #include <BRepBuilderAPI_MakeFace.hxx>
39 #include <BRepBuilderAPI_MakeEdge.hxx>
40 #include <BRepBuilderAPI_MakeVertex.hxx>
41 #include <BRepBuilderAPI_MakeWire.hxx>
42 #include <BRepBuilderAPI_Transform.hxx>
43
44 #include <Geom_Plane.hxx>
45
46 #include <TopoDS.hxx>
47 #include <TopoDS_Shape.hxx>
48 #include <TopoDS_Edge.hxx>
49
50 #include <TFunction_Logbook.hxx>
51 #include <StdFail_NotDone.hxx>
52
53 #include <TopExp.hxx>
54
55 #include <utilities.h>
56 //@@ include required header files here @@//
57
58 //=======================================================================
59 //function : GetID
60 //purpose  :
61 //=======================================================================
62 const Standard_GUID& GEOMImpl_DividedDiskDriver::GetID()
63 {
64   static Standard_GUID aGUID("0b01da9a-c5da-11e1-8d80-78e7d1879630");
65   return aGUID;
66 }
67
68 //=======================================================================
69 //function : GEOMImpl_DividedDiskDriver
70 //purpose  :
71 //=======================================================================
72 GEOMImpl_DividedDiskDriver::GEOMImpl_DividedDiskDriver()
73 {
74 }
75
76 //=======================================================================
77 //function : Execute
78 //purpose  :
79 //=======================================================================
80 Standard_Integer GEOMImpl_DividedDiskDriver::Execute(TFunction_Logbook& log) const
81 {
82   if (Label().IsNull()) return 0;
83   Handle(GEOM_Function) aFunction = GEOM_Function::GetFunction(Label());
84
85   GEOMImpl_IDividedDisk aData (aFunction);
86   Standard_Integer aType = aFunction->GetType();
87
88   TopoDS_Shape aShape;
89
90   // Getting data
91   double R           = aData.GetR();
92   double Ratio       = aData.GetRatio();
93   
94   // Build reference disk (in the global coordinate system)
95   TopoDS_Shell aDisk = MakeDisk( R, Ratio );
96   
97   if (aType == DIVIDEDDISK_R_RATIO) 
98   { 
99     int theOrientation = aData.GetOrientation();        
100     aShape = TransformShape(aDisk, theOrientation);   
101   }
102   else if (aType == DIVIDEDDISK_R_VECTOR_PNT)
103   {
104     Handle(GEOM_Function) aRefPoint  = aData.GetCenter();
105     Handle(GEOM_Function) aRefVector = aData.GetVector();
106     TopoDS_Shape aShapePnt = aRefPoint->GetValue();
107     TopoDS_Shape aShapeVec = aRefVector->GetValue();
108     
109     if (aShapePnt.ShapeType() == TopAbs_VERTEX &&
110         aShapeVec.ShapeType() == TopAbs_EDGE) 
111     {
112       gp_Pnt aPnt = BRep_Tool::Pnt(TopoDS::Vertex(aShapePnt));
113       TopoDS_Edge anE = TopoDS::Edge(aShapeVec);
114       TopoDS_Vertex V1, V2;
115       TopExp::Vertices(anE, V1, V2, Standard_True);
116       if (!V1.IsNull() && !V2.IsNull()) 
117       {
118         gp_Vec aVec (BRep_Tool::Pnt(V1), BRep_Tool::Pnt(V2));
119         gp_Dir aDir(aVec);
120         aShape = TransformShape(aDisk, aPnt, aDir); 
121       }
122     }   
123   }
124
125   if (aShape.IsNull()) return 0;
126
127   aFunction->SetValue(aShape);
128
129   log.SetTouched(Label());
130
131   return 1;
132 }
133
134
135 //=======================================================================
136 //function : MakeDisk
137 //purpose  :
138 //=======================================================================
139 TopoDS_Shell GEOMImpl_DividedDiskDriver::MakeDisk(double R, double Ratio) const
140 {
141   // Geometry
142   gp_Dir ZDir(0,0,1);
143   gp_Dir XDir(1,0,0);
144   gp_Pnt Orig(0,0,0);
145   
146   // Circle
147   gp_Ax1 Ax1(Orig,ZDir);
148   gp_Ax2 Ax(Orig,ZDir,XDir);
149   gp_Circ aCircle(Ax, R);
150   
151   // Points
152   gp_Pnt P1(0.01*Ratio*R,0,0);
153   gp_Pnt P2(R,0,0);
154   gp_Pnt P3 = P2.Rotated(Ax1,M_PI/6.0);
155   gp_Pnt P4(P1.X(), 
156             P1.X()/sqrt(3.0),0);
157   
158   //surfaces
159   gp_Ax2 anAx (gp::XOY());
160   Handle(Geom_Plane) aPlane = new Geom_Plane (anAx);
161   
162   // Topology
163   
164   // Vertices
165   TopoDS_Vertex O  = BRepBuilderAPI_MakeVertex(Orig);
166   TopoDS_Vertex V1_init = BRepBuilderAPI_MakeVertex(P1);
167   TopoDS_Vertex V2_init = BRepBuilderAPI_MakeVertex(P2);
168   TopoDS_Vertex V3 = BRepBuilderAPI_MakeVertex(P3);
169   TopoDS_Vertex V4 = BRepBuilderAPI_MakeVertex(P4);
170   
171   TopoDS_Vertex V1 = V1_init;
172   TopoDS_Vertex V2 = V2_init;
173   
174   //Rotation
175   gp_Trsf myTrsf;
176   myTrsf.SetRotation(Ax1, M_PI/3.0);
177   
178   BRepBuilderAPI_Transform xform(myTrsf);
179   xform.Perform(V1,Standard_True);
180   TopoDS_Vertex V1_60 = TopoDS::Vertex(xform.Shape()); 
181   xform.Perform(V2,Standard_True);
182   TopoDS_Vertex V2_60 = TopoDS::Vertex(xform.Shape());
183   
184   // Declaration of shapes (used in the loop) 
185   TopoDS_Edge E1, E2, E3, E4, E5, E6, E7, E8, E9;
186   TopoDS_Wire W1, W2, W3;
187   TopoDS_Face F1, F2, F3;   
188   TopoDS_Shell S;
189   
190   BRep_Builder aBuilder;
191   aBuilder.MakeShell(S);
192   
193   // Initialisation of edges
194   TopoDS_Edge E1_init = BRepBuilderAPI_MakeEdge(V1,TopoDS::Vertex(V2.Reversed()));
195   E1 = E1_init;
196   TopoDS_Edge E8_init = BRepBuilderAPI_MakeEdge(O,TopoDS::Vertex(V1.Reversed()));
197   E8 = E8_init;
198   
199   for (int i=1;i<=6;i++)
200   { 
201     // Edges
202     // for Face1
203     E2 = BRepBuilderAPI_MakeEdge(aCircle, V2, TopoDS::Vertex(V3.Reversed())); 
204     E3 = BRepBuilderAPI_MakeEdge(V3,TopoDS::Vertex(V4.Reversed()));
205     E4 = BRepBuilderAPI_MakeEdge(V4,TopoDS::Vertex(V1.Reversed()));
206       
207     // for Face2
208     if (i==6)
209     {
210       E5 = BRepBuilderAPI_MakeEdge(aCircle, V3, TopoDS::Vertex(V2_init.Reversed()));
211       E7 = BRepBuilderAPI_MakeEdge(V1_init,TopoDS::Vertex(V4.Reversed()));
212     }
213     else
214     {
215       E5 = BRepBuilderAPI_MakeEdge(aCircle, V3, TopoDS::Vertex(V2_60.Reversed()));
216       E7 = BRepBuilderAPI_MakeEdge(V1_60,TopoDS::Vertex(V4.Reversed()));
217     }    
218     E6 = BRepBuilderAPI_MakeEdge(V2_60,TopoDS::Vertex(V1_60.Reversed()));
219     
220     // for Face3
221     E9 = BRepBuilderAPI_MakeEdge(V1_60,TopoDS::Vertex(O.Reversed()));
222     
223     
224     // Wires
225     //Wire1
226     aBuilder.MakeWire(W1);
227     if (i==1)
228       aBuilder.Add(W1,E1);
229     else
230       aBuilder.Add(W1,TopoDS::Edge(E1.Reversed()));
231     aBuilder.Add(W1,E2);
232     aBuilder.Add(W1,E3);
233     aBuilder.Add(W1,E4);
234     
235     // Wire 2
236     aBuilder.MakeWire(W2);
237     aBuilder.Add(W2,TopoDS::Edge(E3.Reversed()));
238     aBuilder.Add(W2,E5);
239     if (i==6)
240       aBuilder.Add(W2,TopoDS::Edge(E1_init.Reversed()));
241     else
242       aBuilder.Add(W2,E6);
243     aBuilder.Add(W2,E7);
244     
245     // Wire3
246     aBuilder.MakeWire(W3);
247     if (i==1)
248       aBuilder.Add(W3,E8);
249     else 
250       aBuilder.Add(W3,TopoDS::Edge(E8.Reversed()));    
251     aBuilder.Add(W3,TopoDS::Edge(E4.Reversed()));
252     aBuilder.Add(W3,TopoDS::Edge(E7.Reversed()));
253     if (i==6)
254       aBuilder.Add(W3,TopoDS::Edge(E8_init.Reversed()));
255     else
256       aBuilder.Add(W3,E9);
257       
258     // Faces creation
259     F1 = BRepBuilderAPI_MakeFace(aPlane,W1);
260     F2 = BRepBuilderAPI_MakeFace(aPlane,W2);
261     F3 = BRepBuilderAPI_MakeFace(aPlane,W3);
262     
263     //Shell
264     aBuilder.Add(S, F1);
265     aBuilder.Add(S, F2);
266     aBuilder.Add(S, F3);
267           
268     // rotation
269     V1=V1_60;
270     V2=V2_60;
271     
272     xform.Perform(V1_60,Standard_True);
273     V1_60 = TopoDS::Vertex(xform.Shape());
274     xform.Perform(V2_60,Standard_True);
275     V2_60 = TopoDS::Vertex(xform.Shape());
276     xform.Perform(V3,Standard_True);
277     V3    = TopoDS::Vertex(xform.Shape());
278     xform.Perform(V4,Standard_True);
279     V4    = TopoDS::Vertex(xform.Shape());
280     
281     // "Increment" of edges
282     E1=E6;
283     E8=E9;         
284   }
285   
286   return S;
287 }
288
289 //=======================================================================
290 //function :  TrasformShape(TopoDS_Shape aShape,int theOrientation)
291 //purpose  :  Perform shape transformation accordingly with specified
292 //            orientation
293 //=======================================================================
294 TopoDS_Shape GEOMImpl_DividedDiskDriver::TransformShape(TopoDS_Shape theShape, int theOrientation) const
295 {
296   gp_Dir N, Vx;
297   gp_Pnt theOrigin = gp::Origin();
298   
299   switch(theOrientation)
300   {
301     case 1:
302     {
303       N = gp::DZ();
304       Vx = gp::DX();
305       break;
306     }
307     case 2:
308     {
309       N = gp::DX();
310       Vx = gp::DY();
311       break;
312     }
313     case 3:
314     {
315       N = gp::DY();
316       Vx = gp::DZ();
317       break;
318     }
319   }
320     
321   gp_Ax3 aWPlane = gp_Ax3(theOrigin, N, Vx);
322   
323   return WPlaneTransform(theShape, aWPlane);
324 }
325
326 //=======================================================================
327 //function :  TrasformShape(TopoDS_Shape aShape, gp_Dir V, gp_Pnt P)
328 //purpose  :  Perform shape transformation accordingly with specified
329 //            pnt and direction
330 //=======================================================================
331 TopoDS_Shape GEOMImpl_DividedDiskDriver::TransformShape(TopoDS_Shape theShape, gp_Pnt P, gp_Dir V) const
332 {
333   gp_Ax3 aWPlane( P, V );
334   return WPlaneTransform(theShape, aWPlane);
335 }
336
337 //=======================================================================
338 //function :  WPlaneTransform
339 //purpose  :  Perform shape transformation accordingly with the given 
340 //            Working Plane  
341 //=======================================================================
342 TopoDS_Shape GEOMImpl_DividedDiskDriver::WPlaneTransform(TopoDS_Shape theShape, gp_Ax3 theWPlane) const
343 {
344   gp_Trsf aTrans;
345   aTrans.SetTransformation(theWPlane);
346   aTrans.Invert();
347   BRepBuilderAPI_Transform aTransformation (theShape, aTrans, Standard_False);
348   return aTransformation.Shape();
349 }
350
351 //=======================================================================
352 //function :  GEOMImpl_DividedDiskDriver_Type_
353 //purpose  :
354 //=======================================================================
355 Standard_EXPORT Handle_Standard_Type& GEOMImpl_DividedDiskDriver_Type_()
356 {
357   static Handle_Standard_Type aType1 = STANDARD_TYPE(TFunction_Driver);
358   if ( aType1.IsNull()) aType1 = STANDARD_TYPE(TFunction_Driver);
359   static Handle_Standard_Type aType2 = STANDARD_TYPE(MMgt_TShared);
360   if ( aType2.IsNull()) aType2 = STANDARD_TYPE(MMgt_TShared);
361   static Handle_Standard_Type aType3 = STANDARD_TYPE(Standard_Transient);
362   if ( aType3.IsNull()) aType3 = STANDARD_TYPE(Standard_Transient);
363
364   static Handle_Standard_Transient _Ancestors[]= {aType1,aType2,aType3,NULL};
365   static Handle_Standard_Type _aType = new Standard_Type("GEOMImpl_DividedDiskDriver",
366                                                          sizeof(GEOMImpl_DividedDiskDriver),
367                                                          1,
368                                                          (Standard_Address)_Ancestors,
369                                                          (Standard_Address)NULL);
370   return _aType;
371 }
372
373 //=======================================================================
374 //function : DownCast
375 //purpose  :
376 //=======================================================================
377 const Handle(GEOMImpl_DividedDiskDriver) Handle(GEOMImpl_DividedDiskDriver)::DownCast(const Handle(Standard_Transient)& AnObject)
378 {
379   Handle(GEOMImpl_DividedDiskDriver) _anOtherObject;
380
381   if (!AnObject.IsNull()) {
382      if (AnObject->IsKind(STANDARD_TYPE(GEOMImpl_DividedDiskDriver))) {
383        _anOtherObject = Handle(GEOMImpl_DividedDiskDriver)((Handle(GEOMImpl_DividedDiskDriver)&)AnObject);
384      }
385   }
386
387   return _anOtherObject;
388 }