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