Salome HOME
IMP 0021511: EDF 2153 GEOM: Choose to take units into account or not when importing...
[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     
220     // for Face1
221     E2 = BRepBuilderAPI_MakeEdge(aCircle, V2, TopoDS::Vertex(V3.Reversed())); 
222     E3 = BRepBuilderAPI_MakeEdge(V3,TopoDS::Vertex(V4.Reversed()));
223     E4 = BRepBuilderAPI_MakeEdge(V4,TopoDS::Vertex(V1.Reversed()));
224       
225     // for Face2
226     if (i==6)
227     {
228       E5 = BRepBuilderAPI_MakeEdge(aCircle, V3, TopoDS::Vertex(V2_init.Reversed()));
229       E7 = BRepBuilderAPI_MakeEdge(V1_init,TopoDS::Vertex(V4.Reversed()));
230     }
231     else
232     {
233       E5 = BRepBuilderAPI_MakeEdge(aCircle, V3, TopoDS::Vertex(V2_60.Reversed()));
234       E7 = BRepBuilderAPI_MakeEdge(V1_60,TopoDS::Vertex(V4.Reversed()));
235     }    
236     E6 = BRepBuilderAPI_MakeEdge(V2_60,TopoDS::Vertex(V1_60.Reversed()));
237     
238     // for Face3
239     E9 = BRepBuilderAPI_MakeEdge(V1_60,TopoDS::Vertex(O.Reversed()));
240     
241     
242     // Wires
243     
244     //Wire1
245     aBuilder.MakeWire(W1);
246     if (i==1)
247       aBuilder.Add(W1,E1);
248     else
249       aBuilder.Add(W1,TopoDS::Edge(E1.Reversed()));
250     aBuilder.Add(W1,E2);
251     aBuilder.Add(W1,E3);
252     aBuilder.Add(W1,E4);
253     
254     // Wire 2
255     aBuilder.MakeWire(W2);
256     aBuilder.Add(W2,TopoDS::Edge(E3.Reversed()));
257     aBuilder.Add(W2,E5);
258     if (i==6)
259       aBuilder.Add(W2,TopoDS::Edge(E1_init.Reversed()));
260     else
261       aBuilder.Add(W2,E6);
262     aBuilder.Add(W2,E7);
263     
264     // Wire3
265     aBuilder.MakeWire(W3);
266     if (i==1)
267       aBuilder.Add(W3,E8);
268     else 
269       aBuilder.Add(W3,TopoDS::Edge(E8.Reversed()));    
270     aBuilder.Add(W3,TopoDS::Edge(E4.Reversed()));
271     aBuilder.Add(W3,TopoDS::Edge(E7.Reversed()));
272     if (i==6)
273       aBuilder.Add(W3,TopoDS::Edge(E8_init.Reversed()));
274     else
275       aBuilder.Add(W3,E9);
276       
277     // Faces creation
278     F1 = BRepBuilderAPI_MakeFace(aPlane,W1);
279     F2 = BRepBuilderAPI_MakeFace(aPlane,W2);
280     F3 = BRepBuilderAPI_MakeFace(aPlane,W3);
281     
282     //Shell
283     aBuilder.Add(S, F1);
284     aBuilder.Add(S, F2);
285     aBuilder.Add(S, F3);
286           
287     // rotation
288     V1=V1_60;
289     V2=V2_60;
290     
291     xform.Perform(V1_60,Standard_True);
292     V1_60 = TopoDS::Vertex(xform.Shape());
293     xform.Perform(V2_60,Standard_True);
294     V2_60 = TopoDS::Vertex(xform.Shape());
295     xform.Perform(V3,Standard_True);
296     V3    = TopoDS::Vertex(xform.Shape());
297     xform.Perform(V4,Standard_True);
298     V4    = TopoDS::Vertex(xform.Shape());
299     
300     // "Increment" of edges
301     E1=E6;
302     E8=E9;         
303   }
304   
305   return S;
306 }
307
308 //=======================================================================
309 //function : MakeDiskSquare
310 //purpose  :
311 //=======================================================================
312 TopoDS_Shape GEOMImpl_DividedDiskDriver::MakeDiskSquare(double R, double Ratio) const
313 {
314   // Geometry
315   gp_Dir ZDir(0,0,1);
316   gp_Dir XDir(1,0,0);
317   gp_Pnt Orig(0,0,0);
318   
319   // Circle
320   gp_Ax1 Ax1(Orig,ZDir);
321   gp_Ax2 Ax(Orig,ZDir,XDir);
322   gp_Circ aCircle(Ax, R);
323   
324   // Points
325   gp_Pnt P1(0.01*Ratio*R,0,0);
326   gp_Pnt P2(R,0,0);
327   
328   //surfaces
329   gp_Ax2 anAx (gp::XOY());
330   Handle(Geom_Plane) aPlane = new Geom_Plane (anAx);
331   
332   // Topology
333   
334   // Vertices
335   TopoDS_Vertex V1_init = BRepBuilderAPI_MakeVertex(P1);
336   TopoDS_Vertex V2_init = BRepBuilderAPI_MakeVertex(P2);
337   
338   TopoDS_Vertex V1 = V1_init;
339   TopoDS_Vertex V2 = V2_init;
340   
341   //Rotation
342   gp_Trsf myTrsf;
343   myTrsf.SetRotation(Ax1, M_PI/2);
344   
345   BRepBuilderAPI_Transform xform(myTrsf);
346   xform.Perform(V1,Standard_True);
347   TopoDS_Vertex V1_rotated = TopoDS::Vertex(xform.Shape()); 
348   xform.Perform(V2,Standard_True);
349   TopoDS_Vertex V2_rotated = TopoDS::Vertex(xform.Shape());
350   
351   // Declaration of shapes (used in the loop) 
352   TopoDS_Edge E1, E2, E3, E4;
353   TopoDS_Wire W1, W2;
354   TopoDS_Face F1, F2;   
355   TopoDS_Shell S;
356   
357   BRep_Builder aBuilder;
358   aBuilder.MakeWire(W2);  // Central Wire
359   aBuilder.MakeShell(S);  // Shell
360   
361   // Initialisation of edges
362   TopoDS_Edge E1_init = BRepBuilderAPI_MakeEdge(V1,TopoDS::Vertex(V2.Reversed()));
363   E1 = E1_init;
364   
365   for (int i=1;i<=4;i++)
366   { 
367     // Edges
368     // for Face1
369    
370     E3 = BRepBuilderAPI_MakeEdge(V2_rotated,TopoDS::Vertex(V1_rotated.Reversed()));
371     if (i == 4)
372     {
373       E2 = BRepBuilderAPI_MakeEdge(aCircle, V2, TopoDS::Vertex(V2_init.Reversed())); 
374       E4 = BRepBuilderAPI_MakeEdge(V1_init,TopoDS::Vertex(V1.Reversed()));
375     }
376     else
377     {
378       E2 = BRepBuilderAPI_MakeEdge(aCircle, V2, TopoDS::Vertex(V2_rotated.Reversed())); 
379       E4 = BRepBuilderAPI_MakeEdge(V1_rotated,TopoDS::Vertex(V1.Reversed()));
380     }
381     
382     // Wires
383     //Wire1
384     aBuilder.MakeWire(W1);
385     if (i==1)
386       aBuilder.Add(W1,E1);
387     else
388       aBuilder.Add(W1,TopoDS::Edge(E1.Reversed()));
389     aBuilder.Add(W1,E2);
390     if (i==4)
391       aBuilder.Add(W1,TopoDS::Edge(E1_init.Reversed()));
392     else
393       aBuilder.Add(W1,E3);
394     aBuilder.Add(W1,E4);
395     
396     // Wire central
397     aBuilder.Add(W2,TopoDS::Edge(E4.Reversed()));
398     
399     // Faces creation
400     F1 = BRepBuilderAPI_MakeFace(aPlane,W1);
401     
402     //Shell
403     aBuilder.Add(S, F1);
404     
405     // rotation
406     V1=V1_rotated;
407     V2=V2_rotated;
408     
409     xform.Perform(V1_rotated,Standard_True);
410     V1_rotated = TopoDS::Vertex(xform.Shape());
411     xform.Perform(V2_rotated,Standard_True);
412     V2_rotated = TopoDS::Vertex(xform.Shape());
413     
414     // "Increment" of edges
415     E1=E3;        
416   }
417   // Central square Face 
418   F2 = BRepBuilderAPI_MakeFace(aPlane,W2);
419   aBuilder.Add(S, F2);
420   
421   return S;
422 }
423
424
425 //=======================================================================
426 //function :  TrasformShape(TopoDS_Shape aShape,int theOrientation)
427 //purpose  :  Perform shape transformation accordingly with specified
428 //            orientation
429 //=======================================================================
430 TopoDS_Shape GEOMImpl_DividedDiskDriver::TransformShape(TopoDS_Shape theShape, int theOrientation) const
431 {
432   gp_Dir N, Vx;
433   gp_Pnt theOrigin = gp::Origin();
434   
435   switch(theOrientation)
436   {
437     case 1:
438     {
439       N = gp::DZ();
440       Vx = gp::DX();
441       break;
442     }
443     case 2:
444     {
445       N = gp::DX();
446       Vx = gp::DY();
447       break;
448     }
449     case 3:
450     {
451       N = gp::DY();
452       Vx = gp::DZ();
453       break;
454     }
455   }
456     
457   gp_Ax3 aWPlane = gp_Ax3(theOrigin, N, Vx);
458   
459   return WPlaneTransform(theShape, aWPlane);
460 }
461
462 //=======================================================================
463 //function :  TrasformShape(TopoDS_Shape aShape, gp_Dir V, gp_Pnt P)
464 //purpose  :  Perform shape transformation accordingly with specified
465 //            pnt and direction
466 //=======================================================================
467 TopoDS_Shape GEOMImpl_DividedDiskDriver::TransformShape(TopoDS_Shape theShape, gp_Pnt P, gp_Dir V) const
468 {
469   gp_Ax3 aWPlane( P, V );
470   return WPlaneTransform(theShape, aWPlane);
471 }
472
473 //=======================================================================
474 //function :  WPlaneTransform
475 //purpose  :  Perform shape transformation accordingly with the given 
476 //            Working Plane  
477 //=======================================================================
478 TopoDS_Shape GEOMImpl_DividedDiskDriver::WPlaneTransform(TopoDS_Shape theShape, gp_Ax3 theWPlane) const
479 {
480   gp_Trsf aTrans;
481   aTrans.SetTransformation(theWPlane);
482   aTrans.Invert();
483   BRepBuilderAPI_Transform aTransformation (theShape, aTrans, Standard_False);
484   return aTransformation.Shape();
485 }
486
487 //=======================================================================
488 //function :  GEOMImpl_DividedDiskDriver_Type_
489 //purpose  :
490 //=======================================================================
491 Standard_EXPORT Handle_Standard_Type& GEOMImpl_DividedDiskDriver_Type_()
492 {
493   static Handle_Standard_Type aType1 = STANDARD_TYPE(TFunction_Driver);
494   if ( aType1.IsNull()) aType1 = STANDARD_TYPE(TFunction_Driver);
495   static Handle_Standard_Type aType2 = STANDARD_TYPE(MMgt_TShared);
496   if ( aType2.IsNull()) aType2 = STANDARD_TYPE(MMgt_TShared);
497   static Handle_Standard_Type aType3 = STANDARD_TYPE(Standard_Transient);
498   if ( aType3.IsNull()) aType3 = STANDARD_TYPE(Standard_Transient);
499
500   static Handle_Standard_Transient _Ancestors[]= {aType1,aType2,aType3,NULL};
501   static Handle_Standard_Type _aType = new Standard_Type("GEOMImpl_DividedDiskDriver",
502                                                          sizeof(GEOMImpl_DividedDiskDriver),
503                                                          1,
504                                                          (Standard_Address)_Ancestors,
505                                                          (Standard_Address)NULL);
506   return _aType;
507 }
508
509 //=======================================================================
510 //function : DownCast
511 //purpose  :
512 //=======================================================================
513 const Handle(GEOMImpl_DividedDiskDriver) Handle(GEOMImpl_DividedDiskDriver)::DownCast(const Handle(Standard_Transient)& AnObject)
514 {
515   Handle(GEOMImpl_DividedDiskDriver) _anOtherObject;
516
517   if (!AnObject.IsNull()) {
518      if (AnObject->IsKind(STANDARD_TYPE(GEOMImpl_DividedDiskDriver))) {
519        _anOtherObject = Handle(GEOMImpl_DividedDiskDriver)((Handle(GEOMImpl_DividedDiskDriver)&)AnObject);
520      }
521   }
522
523   return _anOtherObject;
524 }