Salome HOME
Copyright update 2022
[modules/geom.git] / src / AdvancedEngine / AdvancedEngine_DividedDiskDriver.cxx
1 // Copyright (C) 2007-2022  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(Handle(TFunction_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   log->SetTouched(Label());
142
143   return 1;
144 }
145
146
147 //=======================================================================
148 //function : MakeDiskHexagon
149 //purpose  :
150 //=======================================================================
151 TopoDS_Shell AdvancedEngine_DividedDiskDriver::MakeDiskHexagon(double R, double Ratio) const
152 {
153   // Geometry
154   gp_Dir ZDir(0,0,1);
155   gp_Dir XDir(1,0,0);
156   gp_Pnt Orig(0,0,0);
157   
158   // Circle
159   gp_Ax1 Ax1(Orig,ZDir);
160   gp_Ax2 Ax(Orig,ZDir,XDir);
161   gp_Circ aCircle(Ax, R);
162   
163   // Points
164 //   gp_Pnt P4(0.01*Ratio*R,0,0); 
165 //   gp_Pnt P3(R,0,0);
166 //   gp_Pnt P2 = P3.Rotated(Ax1,-M_PI/6.0);
167 //   gp_Pnt P1(P4.X(), 
168 //             P4.X()/sqrt(3.0),0);
169   gp_Pnt P1(0.01*Ratio*R*sqrt(3.0)/2,0,0);
170   gp_Pnt P2(R,0,0);
171   gp_Pnt P3 = P2.Rotated(Ax1,M_PI/6.0);
172   gp_Pnt P4(P1.X(), 
173             P1.X()/sqrt(3.0),0);
174
175   
176   //surfaces
177   gp_Ax2 anAx (gp::XOY());
178   Handle(Geom_Plane) aPlane = new Geom_Plane (anAx);
179   
180   // Topology
181   
182   // Vertices
183   TopoDS_Vertex O  = BRepBuilderAPI_MakeVertex(Orig);
184   TopoDS_Vertex V1_init = BRepBuilderAPI_MakeVertex(P1);
185   TopoDS_Vertex V2_init = BRepBuilderAPI_MakeVertex(P2);
186   TopoDS_Vertex V3 = BRepBuilderAPI_MakeVertex(P3);
187   TopoDS_Vertex V4 = BRepBuilderAPI_MakeVertex(P4);
188   
189   TopoDS_Vertex V1 = V1_init;
190   TopoDS_Vertex V2 = V2_init;
191   
192   //Rotation
193   gp_Trsf myTrsf;
194   myTrsf.SetRotation(Ax1, M_PI/3.0);
195   
196   BRepBuilderAPI_Transform xform(myTrsf);
197   xform.Perform(V1,Standard_True);
198   TopoDS_Vertex V1_60 = TopoDS::Vertex(xform.Shape()); 
199   xform.Perform(V2,Standard_True);
200   TopoDS_Vertex V2_60 = TopoDS::Vertex(xform.Shape());
201   
202   // Declaration of shapes (used in the loop) 
203   TopoDS_Edge E1, E2, E3, E4, E5, E6, E7, E8, E9;
204   TopoDS_Wire W1, W2, W3;
205   TopoDS_Face F1, F2, F3;   
206   TopoDS_Shell S;
207   
208   BRep_Builder aBuilder;
209   aBuilder.MakeShell(S);
210   
211   // Initialisation of edges
212   TopoDS_Edge E1_init = BRepBuilderAPI_MakeEdge(V1,TopoDS::Vertex(V2.Reversed()));
213   E1 = E1_init;
214   TopoDS_Edge E8_init = BRepBuilderAPI_MakeEdge(O,TopoDS::Vertex(V1.Reversed()));
215   E8 = E8_init;
216   
217   for (int i=1;i<=6;i++)
218   { 
219     // Edges
220     
221     // for Face1
222     E2 = BRepBuilderAPI_MakeEdge(aCircle, V2, TopoDS::Vertex(V3.Reversed())); 
223     E3 = BRepBuilderAPI_MakeEdge(V3,TopoDS::Vertex(V4.Reversed()));
224     E4 = BRepBuilderAPI_MakeEdge(V4,TopoDS::Vertex(V1.Reversed()));
225       
226     // for Face2
227     if (i==6)
228     {
229       E5 = BRepBuilderAPI_MakeEdge(aCircle, V3, TopoDS::Vertex(V2_init.Reversed()));
230       E7 = BRepBuilderAPI_MakeEdge(V1_init,TopoDS::Vertex(V4.Reversed()));
231     }
232     else
233     {
234       E5 = BRepBuilderAPI_MakeEdge(aCircle, V3, TopoDS::Vertex(V2_60.Reversed()));
235       E7 = BRepBuilderAPI_MakeEdge(V1_60,TopoDS::Vertex(V4.Reversed()));
236     }    
237     E6 = BRepBuilderAPI_MakeEdge(V2_60,TopoDS::Vertex(V1_60.Reversed()));
238     
239     // for Face3
240     E9 = BRepBuilderAPI_MakeEdge(V1_60,TopoDS::Vertex(O.Reversed()));
241     
242     
243     // Wires
244     
245     //Wire1
246     aBuilder.MakeWire(W1);
247     if (i==1)
248       aBuilder.Add(W1,E1);
249     else
250       aBuilder.Add(W1,TopoDS::Edge(E1.Reversed()));
251     aBuilder.Add(W1,E2);
252     aBuilder.Add(W1,E3);
253     aBuilder.Add(W1,E4);
254     
255     // Wire 2
256     aBuilder.MakeWire(W2);
257     aBuilder.Add(W2,TopoDS::Edge(E3.Reversed()));
258     aBuilder.Add(W2,E5);
259     if (i==6)
260       aBuilder.Add(W2,TopoDS::Edge(E1_init.Reversed()));
261     else
262       aBuilder.Add(W2,E6);
263     aBuilder.Add(W2,E7);
264     
265     // Wire3
266     aBuilder.MakeWire(W3);
267     if (i==1)
268       aBuilder.Add(W3,E8);
269     else 
270       aBuilder.Add(W3,TopoDS::Edge(E8.Reversed()));    
271     aBuilder.Add(W3,TopoDS::Edge(E4.Reversed()));
272     aBuilder.Add(W3,TopoDS::Edge(E7.Reversed()));
273     if (i==6)
274       aBuilder.Add(W3,TopoDS::Edge(E8_init.Reversed()));
275     else
276       aBuilder.Add(W3,E9);
277       
278     // Faces creation
279     F1 = BRepBuilderAPI_MakeFace(aPlane,W1);
280     F2 = BRepBuilderAPI_MakeFace(aPlane,W2);
281     F3 = BRepBuilderAPI_MakeFace(aPlane,W3);
282     
283     //Shell
284     aBuilder.Add(S, F1);
285     aBuilder.Add(S, F2);
286     aBuilder.Add(S, F3);
287           
288     // rotation
289     V1=V1_60;
290     V2=V2_60;
291     
292     xform.Perform(V1_60,Standard_True);
293     V1_60 = TopoDS::Vertex(xform.Shape());
294     xform.Perform(V2_60,Standard_True);
295     V2_60 = TopoDS::Vertex(xform.Shape());
296     xform.Perform(V3,Standard_True);
297     V3    = TopoDS::Vertex(xform.Shape());
298     xform.Perform(V4,Standard_True);
299     V4    = TopoDS::Vertex(xform.Shape());
300     
301     // "Increment" of edges
302     E1=E6;
303     E8=E9;         
304   }
305   
306   return S;
307 }
308
309 //=======================================================================
310 //function : MakeDiskSquare
311 //purpose  :
312 //=======================================================================
313 TopoDS_Shape AdvancedEngine_DividedDiskDriver::MakeDiskSquare(double R, double Ratio) const
314 {
315   // Geometry
316   gp_Dir ZDir(0,0,1);
317   gp_Dir XDir(1,0,0);
318   gp_Pnt Orig(0,0,0);
319   
320   // Circle
321   gp_Ax1 Ax1(Orig,ZDir);
322   gp_Ax2 Ax(Orig,ZDir,XDir);
323   gp_Circ aCircle(Ax, R);
324   
325   // Points
326   gp_Pnt P1(0.01*Ratio*R,0,0);
327   gp_Pnt P2(R,0,0);
328   
329   //surfaces
330   gp_Ax2 anAx (gp::XOY());
331   Handle(Geom_Plane) aPlane = new Geom_Plane (anAx);
332   
333   // Topology
334   
335   // Vertices
336   TopoDS_Vertex V1_init = BRepBuilderAPI_MakeVertex(P1);
337   TopoDS_Vertex V2_init = BRepBuilderAPI_MakeVertex(P2);
338   
339   TopoDS_Vertex V1 = V1_init;
340   TopoDS_Vertex V2 = V2_init;
341   
342   //Rotation
343   gp_Trsf myTrsf;
344   myTrsf.SetRotation(Ax1, M_PI/2);
345   
346   BRepBuilderAPI_Transform xform(myTrsf);
347   xform.Perform(V1,Standard_True);
348   TopoDS_Vertex V1_rotated = TopoDS::Vertex(xform.Shape()); 
349   xform.Perform(V2,Standard_True);
350   TopoDS_Vertex V2_rotated = TopoDS::Vertex(xform.Shape());
351   
352   // Declaration of shapes (used in the loop) 
353   TopoDS_Edge E1, E2, E3, E4;
354   TopoDS_Wire W1, W2;
355   TopoDS_Face F1, F2;   
356   TopoDS_Shell S;
357   
358   BRep_Builder aBuilder;
359   aBuilder.MakeWire(W2);  // Central Wire
360   aBuilder.MakeShell(S);  // Shell
361   
362   // Initialisation of edges
363   TopoDS_Edge E1_init = BRepBuilderAPI_MakeEdge(V1,TopoDS::Vertex(V2.Reversed()));
364   E1 = E1_init;
365   
366   for (int i=1;i<=4;i++)
367   { 
368     // Edges
369     // for Face1
370    
371     E3 = BRepBuilderAPI_MakeEdge(V2_rotated,TopoDS::Vertex(V1_rotated.Reversed()));
372     if (i == 4)
373     {
374       E2 = BRepBuilderAPI_MakeEdge(aCircle, V2, TopoDS::Vertex(V2_init.Reversed())); 
375       E4 = BRepBuilderAPI_MakeEdge(V1_init,TopoDS::Vertex(V1.Reversed()));
376     }
377     else
378     {
379       E2 = BRepBuilderAPI_MakeEdge(aCircle, V2, TopoDS::Vertex(V2_rotated.Reversed())); 
380       E4 = BRepBuilderAPI_MakeEdge(V1_rotated,TopoDS::Vertex(V1.Reversed()));
381     }
382     
383     // Wires
384     //Wire1
385     aBuilder.MakeWire(W1);
386     if (i==1)
387       aBuilder.Add(W1,E1);
388     else
389       aBuilder.Add(W1,TopoDS::Edge(E1.Reversed()));
390     aBuilder.Add(W1,E2);
391     if (i==4)
392       aBuilder.Add(W1,TopoDS::Edge(E1_init.Reversed()));
393     else
394       aBuilder.Add(W1,E3);
395     aBuilder.Add(W1,E4);
396     
397     // Wire central
398     aBuilder.Add(W2,TopoDS::Edge(E4.Reversed()));
399     
400     // Faces creation
401     F1 = BRepBuilderAPI_MakeFace(aPlane,W1);
402     
403     //Shell
404     aBuilder.Add(S, F1);
405     
406     // rotation
407     V1=V1_rotated;
408     V2=V2_rotated;
409     
410     xform.Perform(V1_rotated,Standard_True);
411     V1_rotated = TopoDS::Vertex(xform.Shape());
412     xform.Perform(V2_rotated,Standard_True);
413     V2_rotated = TopoDS::Vertex(xform.Shape());
414     
415     // "Increment" of edges
416     E1=E3;        
417   }
418   // Central square Face 
419   F2 = BRepBuilderAPI_MakeFace(aPlane,W2);
420   aBuilder.Add(S, F2);
421   
422   return S;
423 }
424
425
426 //=======================================================================
427 //function :  TrasformShape(TopoDS_Shape aShape,int theOrientation)
428 //purpose  :  Perform shape transformation accordingly with specified
429 //            orientation
430 //=======================================================================
431 TopoDS_Shape AdvancedEngine_DividedDiskDriver::TransformShape(TopoDS_Shape theShape, int theOrientation) const
432 {
433   gp_Dir N, Vx;
434   gp_Pnt theOrigin = gp::Origin();
435   
436   switch(theOrientation)
437   {
438     case 1:
439     {
440       N = gp::DZ();
441       Vx = gp::DX();
442       break;
443     }
444     case 2:
445     {
446       N = gp::DX();
447       Vx = gp::DY();
448       break;
449     }
450     case 3:
451     {
452       N = gp::DY();
453       Vx = gp::DZ();
454       break;
455     }
456   }
457     
458   gp_Ax3 aWPlane = gp_Ax3(theOrigin, N, Vx);
459   
460   return WPlaneTransform(theShape, aWPlane);
461 }
462
463 //=======================================================================
464 //function :  TrasformShape(TopoDS_Shape aShape, gp_Dir V, gp_Pnt P)
465 //purpose  :  Perform shape transformation accordingly with specified
466 //            pnt and direction
467 //=======================================================================
468 TopoDS_Shape AdvancedEngine_DividedDiskDriver::TransformShape(TopoDS_Shape theShape, gp_Pnt P, gp_Dir V) const
469 {
470   gp_Ax3 aWPlane( P, V );
471   return WPlaneTransform(theShape, aWPlane);
472 }
473
474 //=======================================================================
475 //function :  WPlaneTransform
476 //purpose  :  Perform shape transformation accordingly with the given 
477 //            Working Plane  
478 //=======================================================================
479 TopoDS_Shape AdvancedEngine_DividedDiskDriver::WPlaneTransform(TopoDS_Shape theShape, gp_Ax3 theWPlane) const
480 {
481   gp_Trsf aTrans;
482   aTrans.SetTransformation(theWPlane);
483   aTrans.Invert();
484   BRepBuilderAPI_Transform aTransformation (theShape, aTrans, Standard_False);
485   return aTransformation.Shape();
486 }
487
488 //================================================================================
489 /*!
490  * \brief Returns a name of creation operation and names and values of creation parameters
491  */
492 //================================================================================
493
494 bool AdvancedEngine_DividedDiskDriver::
495 GetCreationInformation(std::string&             theOperationName,
496                        std::vector<GEOM_Param>& theParams)
497 {
498   if (Label().IsNull()) return 0;
499   Handle(GEOM_Function) function = GEOM_Function::GetFunction(Label());
500
501   AdvancedEngine_IDividedDisk aCI( function );
502   Standard_Integer aType = function->GetType();
503
504   theOperationName = "DIVIDEDDISK";
505
506   switch ( aType ) {
507   case DIVIDEDDISK_R_RATIO:
508     AddParam( theParams, "Radius", aCI.GetR() );
509     AddParam( theParams, "Ratio", aCI.GetRatio() );
510     AddParam( theParams, "Orientation", aCI.GetOrientation() );
511     AddParam( theParams, "Division pattern", aCI.GetType() );
512     break;
513   case DIVIDEDDISK_R_VECTOR_PNT:
514     AddParam( theParams, "Center Point", aCI.GetCenter() );
515     AddParam( theParams, "Vector", aCI.GetVector() );
516     AddParam( theParams, "Radius", aCI.GetR() );
517     AddParam( theParams, "Division pattern", aCI.GetType() );
518     break;
519   default:
520     return false;
521   }
522   
523   return true;
524 }
525
526 IMPLEMENT_STANDARD_RTTIEXT (AdvancedEngine_DividedDiskDriver,GEOM_BaseDriver)