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