]> SALOME platform Git repositories - modules/geom.git/blob - src/GEOMImpl/GEOMImpl_DividedDiskDriver.cxx
Salome HOME
EDF 2281 : Added possibility to choose the division pattern.
[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 enum
59 {
60   SQUARE,
61   HEXAGON
62 };
63 //=======================================================================
64 //function : GetID
65 //purpose  :
66 //=======================================================================
67 const Standard_GUID& GEOMImpl_DividedDiskDriver::GetID()
68 {
69   static Standard_GUID aGUID("0b01da9a-c5da-11e1-8d80-78e7d1879630");
70   return aGUID;
71 }
72
73 //=======================================================================
74 //function : GEOMImpl_DividedDiskDriver
75 //purpose  :
76 //=======================================================================
77 GEOMImpl_DividedDiskDriver::GEOMImpl_DividedDiskDriver()
78 {
79 }
80
81 //=======================================================================
82 //function : Execute
83 //purpose  :
84 //=======================================================================
85 Standard_Integer GEOMImpl_DividedDiskDriver::Execute(TFunction_Logbook& log) const
86 {
87   if (Label().IsNull()) return 0;
88   Handle(GEOM_Function) aFunction = GEOM_Function::GetFunction(Label());
89
90   GEOMImpl_IDividedDisk aData (aFunction);
91   Standard_Integer aType = aFunction->GetType();
92
93   TopoDS_Shape aShape;
94
95   // Getting data
96   double R       = aData.GetR();
97   double Ratio   = aData.GetRatio();
98   int    Pattern = aData.GetType();
99   
100   // Build reference disk (in the global coordinate system)
101   TopoDS_Shape aDisk;
102   
103   if (Pattern == SQUARE)
104     aDisk = MakeDiskSquare( R, Ratio );
105   else if (Pattern == HEXAGON)
106     aDisk = MakeDiskHexagon( R, Ratio );
107   
108   if (aType == DIVIDEDDISK_R_RATIO) 
109   { 
110     int theOrientation = aData.GetOrientation();        
111     aShape = TransformShape(aDisk, theOrientation);   
112   }
113   else if (aType == DIVIDEDDISK_R_VECTOR_PNT)
114   {
115     Handle(GEOM_Function) aRefPoint  = aData.GetCenter();
116     Handle(GEOM_Function) aRefVector = aData.GetVector();
117     TopoDS_Shape aShapePnt = aRefPoint->GetValue();
118     TopoDS_Shape aShapeVec = aRefVector->GetValue();
119     
120     if (aShapePnt.ShapeType() == TopAbs_VERTEX &&
121         aShapeVec.ShapeType() == TopAbs_EDGE) 
122     {
123       gp_Pnt aPnt = BRep_Tool::Pnt(TopoDS::Vertex(aShapePnt));
124       TopoDS_Edge anE = TopoDS::Edge(aShapeVec);
125       TopoDS_Vertex V1, V2;
126       TopExp::Vertices(anE, V1, V2, Standard_True);
127       if (!V1.IsNull() && !V2.IsNull()) 
128       {
129         gp_Vec aVec (BRep_Tool::Pnt(V1), BRep_Tool::Pnt(V2));
130         gp_Dir aDir(aVec);
131         aShape = TransformShape(aDisk, aPnt, aDir); 
132       }
133     }   
134   }
135
136   if (aShape.IsNull()) return 0;
137
138   aFunction->SetValue(aShape);
139
140   log.SetTouched(Label());
141
142   return 1;
143 }
144
145
146 //=======================================================================
147 //function : MakeDiskHexagon
148 //purpose  :
149 //=======================================================================
150 TopoDS_Shell GEOMImpl_DividedDiskDriver::MakeDiskHexagon(double R, double Ratio) const
151 {
152   // Geometry
153   gp_Dir ZDir(0,0,1);
154   gp_Dir XDir(1,0,0);
155   gp_Pnt Orig(0,0,0);
156   
157   // Circle
158   gp_Ax1 Ax1(Orig,ZDir);
159   gp_Ax2 Ax(Orig,ZDir,XDir);
160   gp_Circ aCircle(Ax, R);
161   
162   // Points
163 //   gp_Pnt P4(0.01*Ratio*R,0,0); 
164 //   gp_Pnt P3(R,0,0);
165 //   gp_Pnt P2 = P3.Rotated(Ax1,-M_PI/6.0);
166 //   gp_Pnt P1(P4.X(), 
167 //             P4.X()/sqrt(3.0),0);
168   gp_Pnt P1(0.01*Ratio*R*sqrt(3.0)/2,0,0);
169   gp_Pnt P2(R,0,0);
170   gp_Pnt P3 = P2.Rotated(Ax1,M_PI/6.0);
171   gp_Pnt P4(P1.X(), 
172             P1.X()/sqrt(3.0),0);
173
174   
175   //surfaces
176   gp_Ax2 anAx (gp::XOY());
177   Handle(Geom_Plane) aPlane = new Geom_Plane (anAx);
178   
179   // Topology
180   
181   // Vertices
182   TopoDS_Vertex O  = BRepBuilderAPI_MakeVertex(Orig);
183   TopoDS_Vertex V1_init = BRepBuilderAPI_MakeVertex(P1);
184   TopoDS_Vertex V2_init = BRepBuilderAPI_MakeVertex(P2);
185   TopoDS_Vertex V3 = BRepBuilderAPI_MakeVertex(P3);
186   TopoDS_Vertex V4 = BRepBuilderAPI_MakeVertex(P4);
187   
188   TopoDS_Vertex V1 = V1_init;
189   TopoDS_Vertex V2 = V2_init;
190   
191   //Rotation
192   gp_Trsf myTrsf;
193   myTrsf.SetRotation(Ax1, M_PI/3.0);
194   
195   BRepBuilderAPI_Transform xform(myTrsf);
196   xform.Perform(V1,Standard_True);
197   TopoDS_Vertex V1_60 = TopoDS::Vertex(xform.Shape()); 
198   xform.Perform(V2,Standard_True);
199   TopoDS_Vertex V2_60 = TopoDS::Vertex(xform.Shape());
200   
201   // Declaration of shapes (used in the loop) 
202   TopoDS_Edge E1, E2, E3, E4, E5, E6, E7, E8, E9;
203   TopoDS_Wire W1, W2, W3;
204   TopoDS_Face F1, F2, F3;   
205   TopoDS_Shell S;
206   
207   BRep_Builder aBuilder;
208   aBuilder.MakeShell(S);
209   
210   // Initialisation of edges
211   TopoDS_Edge E1_init = BRepBuilderAPI_MakeEdge(V1,TopoDS::Vertex(V2.Reversed()));
212   E1 = E1_init;
213   TopoDS_Edge E8_init = BRepBuilderAPI_MakeEdge(O,TopoDS::Vertex(V1.Reversed()));
214   E8 = E8_init;
215   
216   for (int i=1;i<=6;i++)
217   { 
218     // Edges
219     // for Face1
220     E2 = BRepBuilderAPI_MakeEdge(aCircle, V2, TopoDS::Vertex(V3.Reversed())); 
221     E3 = BRepBuilderAPI_MakeEdge(V3,TopoDS::Vertex(V4.Reversed()));
222     E4 = BRepBuilderAPI_MakeEdge(V4,TopoDS::Vertex(V1.Reversed()));
223       
224     // for Face2
225     if (i==6)
226     {
227       E5 = BRepBuilderAPI_MakeEdge(aCircle, V3, TopoDS::Vertex(V2_init.Reversed()));
228       E7 = BRepBuilderAPI_MakeEdge(V1_init,TopoDS::Vertex(V4.Reversed()));
229     }
230     else
231     {
232       E5 = BRepBuilderAPI_MakeEdge(aCircle, V3, TopoDS::Vertex(V2_60.Reversed()));
233       E7 = BRepBuilderAPI_MakeEdge(V1_60,TopoDS::Vertex(V4.Reversed()));
234     }    
235     E6 = BRepBuilderAPI_MakeEdge(V2_60,TopoDS::Vertex(V1_60.Reversed()));
236     
237     // for Face3
238     E9 = BRepBuilderAPI_MakeEdge(V1_60,TopoDS::Vertex(O.Reversed()));
239     
240     
241     // Wires
242     //Wire1
243     aBuilder.MakeWire(W1);
244     if (i==1)
245       aBuilder.Add(W1,E1);
246     else
247       aBuilder.Add(W1,TopoDS::Edge(E1.Reversed()));
248     aBuilder.Add(W1,E2);
249     aBuilder.Add(W1,E3);
250     aBuilder.Add(W1,E4);
251     
252     // Wire 2
253     aBuilder.MakeWire(W2);
254     aBuilder.Add(W2,TopoDS::Edge(E3.Reversed()));
255     aBuilder.Add(W2,E5);
256     if (i==6)
257       aBuilder.Add(W2,TopoDS::Edge(E1_init.Reversed()));
258     else
259       aBuilder.Add(W2,E6);
260     aBuilder.Add(W2,E7);
261     
262     // Wire3
263     aBuilder.MakeWire(W3);
264     if (i==1)
265       aBuilder.Add(W3,E8);
266     else 
267       aBuilder.Add(W3,TopoDS::Edge(E8.Reversed()));    
268     aBuilder.Add(W3,TopoDS::Edge(E4.Reversed()));
269     aBuilder.Add(W3,TopoDS::Edge(E7.Reversed()));
270     if (i==6)
271       aBuilder.Add(W3,TopoDS::Edge(E8_init.Reversed()));
272     else
273       aBuilder.Add(W3,E9);
274       
275     // Faces creation
276     F1 = BRepBuilderAPI_MakeFace(aPlane,W1);
277     F2 = BRepBuilderAPI_MakeFace(aPlane,W2);
278     F3 = BRepBuilderAPI_MakeFace(aPlane,W3);
279     
280     //Shell
281     aBuilder.Add(S, F1);
282     aBuilder.Add(S, F2);
283     aBuilder.Add(S, F3);
284           
285     // rotation
286     V1=V1_60;
287     V2=V2_60;
288     
289     xform.Perform(V1_60,Standard_True);
290     V1_60 = TopoDS::Vertex(xform.Shape());
291     xform.Perform(V2_60,Standard_True);
292     V2_60 = TopoDS::Vertex(xform.Shape());
293     xform.Perform(V3,Standard_True);
294     V3    = TopoDS::Vertex(xform.Shape());
295     xform.Perform(V4,Standard_True);
296     V4    = TopoDS::Vertex(xform.Shape());
297     
298     // "Increment" of edges
299     E1=E6;
300     E8=E9;         
301   }
302   
303   return S;
304 }
305
306 //=======================================================================
307 //function : MakeDiskSquare
308 //purpose  :
309 //=======================================================================
310 TopoDS_Shape GEOMImpl_DividedDiskDriver::MakeDiskSquare(double R, double Ratio) const
311 {
312   // Geometry
313   gp_Dir ZDir(0,0,1);
314   gp_Dir XDir(1,0,0);
315   gp_Pnt Orig(0,0,0);
316   
317   // Circle
318   gp_Ax1 Ax1(Orig,ZDir);
319   gp_Ax2 Ax(Orig,ZDir,XDir);
320   gp_Circ aCircle(Ax, R);
321   
322   // Points
323   gp_Pnt P1(0.01*Ratio*R,0,0);
324   gp_Pnt P2(R,0,0);
325   
326   //surfaces
327   gp_Ax2 anAx (gp::XOY());
328   Handle(Geom_Plane) aPlane = new Geom_Plane (anAx);
329   
330   // Topology
331   
332   // Vertices
333   TopoDS_Vertex V1_init = BRepBuilderAPI_MakeVertex(P1);
334   TopoDS_Vertex V2_init = BRepBuilderAPI_MakeVertex(P2);
335   
336   TopoDS_Vertex V1 = V1_init;
337   TopoDS_Vertex V2 = V2_init;
338   
339   //Rotation
340   gp_Trsf myTrsf;
341   myTrsf.SetRotation(Ax1, M_PI/2);
342   
343   BRepBuilderAPI_Transform xform(myTrsf);
344   xform.Perform(V1,Standard_True);
345   TopoDS_Vertex V1_rotated = TopoDS::Vertex(xform.Shape()); 
346   xform.Perform(V2,Standard_True);
347   TopoDS_Vertex V2_rotated = TopoDS::Vertex(xform.Shape());
348   
349   // Declaration of shapes (used in the loop) 
350   TopoDS_Edge E1, E2, E3, E4;
351   TopoDS_Wire W1, W2;
352   TopoDS_Face F1, F2;   
353   TopoDS_Shell S;
354   
355   BRep_Builder aBuilder;
356   aBuilder.MakeWire(W2);  // Central Wire
357   aBuilder.MakeShell(S);  // Shell
358   
359   // Initialisation of edges
360   TopoDS_Edge E1_init = BRepBuilderAPI_MakeEdge(V1,TopoDS::Vertex(V2.Reversed()));
361   E1 = E1_init;
362   
363   for (int i=1;i<=4;i++)
364   { 
365     // Edges
366     // for Face1
367    
368     E3 = BRepBuilderAPI_MakeEdge(V2_rotated,TopoDS::Vertex(V1_rotated.Reversed()));
369     if (i == 4)
370     {
371       E2 = BRepBuilderAPI_MakeEdge(aCircle, V2, TopoDS::Vertex(V2_init.Reversed())); 
372       E4 = BRepBuilderAPI_MakeEdge(V1_init,TopoDS::Vertex(V1.Reversed()));
373     }
374     else
375     {
376       E2 = BRepBuilderAPI_MakeEdge(aCircle, V2, TopoDS::Vertex(V2_rotated.Reversed())); 
377       E4 = BRepBuilderAPI_MakeEdge(V1_rotated,TopoDS::Vertex(V1.Reversed()));
378     }
379     
380     // Wires
381     //Wire1
382     aBuilder.MakeWire(W1);
383     if (i==1)
384       aBuilder.Add(W1,E1);
385     else
386       aBuilder.Add(W1,TopoDS::Edge(E1.Reversed()));
387     aBuilder.Add(W1,E2);
388     if (i==4)
389       aBuilder.Add(W1,TopoDS::Edge(E1_init.Reversed()));
390     else
391       aBuilder.Add(W1,E3);
392     aBuilder.Add(W1,E4);
393     
394     // Wire central
395     aBuilder.Add(W2,TopoDS::Edge(E4.Reversed()));
396     
397     // Faces creation
398     F1 = BRepBuilderAPI_MakeFace(aPlane,W1);
399     
400     //Shell
401     aBuilder.Add(S, F1);
402     
403     // rotation
404     V1=V1_rotated;
405     V2=V2_rotated;
406     
407     xform.Perform(V1_rotated,Standard_True);
408     V1_rotated = TopoDS::Vertex(xform.Shape());
409     xform.Perform(V2_rotated,Standard_True);
410     V2_rotated = TopoDS::Vertex(xform.Shape());
411     
412     // "Increment" of edges
413     E1=E3;        
414   }
415   // Central square Face 
416   F2 = BRepBuilderAPI_MakeFace(aPlane,W2);
417   aBuilder.Add(S, F2);
418   
419   return S;
420 }
421
422
423 //=======================================================================
424 //function :  TrasformShape(TopoDS_Shape aShape,int theOrientation)
425 //purpose  :  Perform shape transformation accordingly with specified
426 //            orientation
427 //=======================================================================
428 TopoDS_Shape GEOMImpl_DividedDiskDriver::TransformShape(TopoDS_Shape theShape, int theOrientation) const
429 {
430   gp_Dir N, Vx;
431   gp_Pnt theOrigin = gp::Origin();
432   
433   switch(theOrientation)
434   {
435     case 1:
436     {
437       N = gp::DZ();
438       Vx = gp::DX();
439       break;
440     }
441     case 2:
442     {
443       N = gp::DX();
444       Vx = gp::DY();
445       break;
446     }
447     case 3:
448     {
449       N = gp::DY();
450       Vx = gp::DZ();
451       break;
452     }
453   }
454     
455   gp_Ax3 aWPlane = gp_Ax3(theOrigin, N, Vx);
456   
457   return WPlaneTransform(theShape, aWPlane);
458 }
459
460 //=======================================================================
461 //function :  TrasformShape(TopoDS_Shape aShape, gp_Dir V, gp_Pnt P)
462 //purpose  :  Perform shape transformation accordingly with specified
463 //            pnt and direction
464 //=======================================================================
465 TopoDS_Shape GEOMImpl_DividedDiskDriver::TransformShape(TopoDS_Shape theShape, gp_Pnt P, gp_Dir V) const
466 {
467   gp_Ax3 aWPlane( P, V );
468   return WPlaneTransform(theShape, aWPlane);
469 }
470
471 //=======================================================================
472 //function :  WPlaneTransform
473 //purpose  :  Perform shape transformation accordingly with the given 
474 //            Working Plane  
475 //=======================================================================
476 TopoDS_Shape GEOMImpl_DividedDiskDriver::WPlaneTransform(TopoDS_Shape theShape, gp_Ax3 theWPlane) const
477 {
478   gp_Trsf aTrans;
479   aTrans.SetTransformation(theWPlane);
480   aTrans.Invert();
481   BRepBuilderAPI_Transform aTransformation (theShape, aTrans, Standard_False);
482   return aTransformation.Shape();
483 }
484
485 //=======================================================================
486 //function :  GEOMImpl_DividedDiskDriver_Type_
487 //purpose  :
488 //=======================================================================
489 Standard_EXPORT Handle_Standard_Type& GEOMImpl_DividedDiskDriver_Type_()
490 {
491   static Handle_Standard_Type aType1 = STANDARD_TYPE(TFunction_Driver);
492   if ( aType1.IsNull()) aType1 = STANDARD_TYPE(TFunction_Driver);
493   static Handle_Standard_Type aType2 = STANDARD_TYPE(MMgt_TShared);
494   if ( aType2.IsNull()) aType2 = STANDARD_TYPE(MMgt_TShared);
495   static Handle_Standard_Type aType3 = STANDARD_TYPE(Standard_Transient);
496   if ( aType3.IsNull()) aType3 = STANDARD_TYPE(Standard_Transient);
497
498   static Handle_Standard_Transient _Ancestors[]= {aType1,aType2,aType3,NULL};
499   static Handle_Standard_Type _aType = new Standard_Type("GEOMImpl_DividedDiskDriver",
500                                                          sizeof(GEOMImpl_DividedDiskDriver),
501                                                          1,
502                                                          (Standard_Address)_Ancestors,
503                                                          (Standard_Address)NULL);
504   return _aType;
505 }
506
507 //=======================================================================
508 //function : DownCast
509 //purpose  :
510 //=======================================================================
511 const Handle(GEOMImpl_DividedDiskDriver) Handle(GEOMImpl_DividedDiskDriver)::DownCast(const Handle(Standard_Transient)& AnObject)
512 {
513   Handle(GEOMImpl_DividedDiskDriver) _anOtherObject;
514
515   if (!AnObject.IsNull()) {
516      if (AnObject->IsKind(STANDARD_TYPE(GEOMImpl_DividedDiskDriver))) {
517        _anOtherObject = Handle(GEOMImpl_DividedDiskDriver)((Handle(GEOMImpl_DividedDiskDriver)&)AnObject);
518      }
519   }
520
521   return _anOtherObject;
522 }