Salome HOME
4a9cec16bca62d2bba7136892ace23cc920bad6c
[modules/shaper.git] / src / GeomAlgoAPI / GeomAlgoAPI_ShapeAPI.cpp
1 // Copyright (C) 2014-2017  CEA/DEN, EDF R&D
2 //
3 // This library is free software; you can redistribute it and/or
4 // modify it under the terms of the GNU Lesser General Public
5 // License as published by the Free Software Foundation; either
6 // version 2.1 of the License, or (at your option) any later version.
7 //
8 // This library is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
11 // Lesser General Public License for more details.
12 //
13 // You should have received a copy of the GNU Lesser General Public
14 // License along with this library; if not, write to the Free Software
15 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
16 //
17 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com<mailto:webmaster.salome@opencascade.com>
18 //
19
20 #include "GeomAlgoAPI_ShapeAPI.h"
21
22 #include <GeomAlgoAPI_Box.h>
23 #include <GeomAlgoAPI_Cylinder.h>
24 #include <GeomAlgoAPI_CompoundBuilder.h>
25 #include <GeomAlgoAPI_ConeSegment.h>
26 #include <GeomAlgoAPI_EdgeBuilder.h>
27 #include <GeomAlgoAPI_Rotation.h>
28 #include <GeomAlgoAPI_Scale.h>
29 #include <GeomAlgoAPI_Symmetry.h>
30 #include <GeomAlgoAPI_Translation.h>
31
32 #include <GeomAPI_Lin.h>
33
34 #include <math.h>
35
36 namespace GeomAlgoAPI_ShapeAPI
37 {
38   //===============================================================================================
39   std::shared_ptr<GeomAPI_Shape> GeomAlgoAPI_ShapeAPI::makeBox(
40     const double theDx, const double theDy,
41     const double theDz) throw (GeomAlgoAPI_Exception)
42   {
43     GeomAlgoAPI_Box aBoxAlgo(theDx,theDy,theDz);
44
45     if (!aBoxAlgo.check()) {
46       throw GeomAlgoAPI_Exception(aBoxAlgo.getError());
47     }
48
49     aBoxAlgo.build();
50
51     if(!aBoxAlgo.isDone()) {
52       throw GeomAlgoAPI_Exception(aBoxAlgo.getError());
53     }
54     if (!aBoxAlgo.checkValid("Box builder with dimensions")) {
55       throw GeomAlgoAPI_Exception(aBoxAlgo.getError());
56     }
57     return aBoxAlgo.shape();
58   }
59
60   //===============================================================================================
61   std::shared_ptr<GeomAPI_Shape> GeomAlgoAPI_ShapeAPI::makeBox(
62     std::shared_ptr<GeomAPI_Pnt> theFirstPoint,
63     std::shared_ptr<GeomAPI_Pnt> theSecondPoint) throw (GeomAlgoAPI_Exception)
64   {
65     GeomAlgoAPI_Box aBoxAlgo(theFirstPoint, theSecondPoint);
66
67     if (!aBoxAlgo.check()) {
68       throw GeomAlgoAPI_Exception(aBoxAlgo.getError());
69     }
70
71     aBoxAlgo.build();
72
73     if(!aBoxAlgo.isDone()) {
74       throw GeomAlgoAPI_Exception(aBoxAlgo.getError());
75     }
76     if (!aBoxAlgo.checkValid("Box builder with two points")) {
77       throw GeomAlgoAPI_Exception(aBoxAlgo.getError());
78     }
79     return aBoxAlgo.shape();
80   }
81
82   //===============================================================================================
83   std::shared_ptr<GeomAPI_Shape> GeomAlgoAPI_ShapeAPI::makeCylinder(
84     std::shared_ptr<GeomAPI_Pnt> theBasePoint, std::shared_ptr<GeomAPI_Edge> theEdge,
85     double theRadius, double theHeight) throw (GeomAlgoAPI_Exception)
86   {
87     // Check if the base point is OK
88     if (!theBasePoint) {
89       throw GeomAlgoAPI_Exception("Cylinder builder :: the base point is not valid.");
90     }
91     // Check if the edge is OK
92     if (!theEdge) {
93       throw GeomAlgoAPI_Exception("Cylinder builder :: the axis is not valid.");
94     }
95
96     std::shared_ptr<GeomAPI_Ax2> anAxis;
97     anAxis = std::shared_ptr<GeomAPI_Ax2>(new GeomAPI_Ax2(theBasePoint,
98                                                           theEdge->line()->direction()));
99
100     GeomAlgoAPI_Cylinder aCylinderAlgo(anAxis, theRadius, theHeight);
101
102     if (!aCylinderAlgo.check()) {
103       throw GeomAlgoAPI_Exception(aCylinderAlgo.getError());
104     }
105
106     aCylinderAlgo.build();
107
108     if(!aCylinderAlgo.isDone()) {
109       throw GeomAlgoAPI_Exception(aCylinderAlgo.getError());
110     }
111     if (!aCylinderAlgo.checkValid("Cylinder builder")) {
112       throw GeomAlgoAPI_Exception(aCylinderAlgo.getError());
113     }
114     return aCylinderAlgo.shape();
115   }
116
117   //===============================================================================================
118   std::shared_ptr<GeomAPI_Shape> GeomAlgoAPI_ShapeAPI::makeCylinder(
119     std::shared_ptr<GeomAPI_Pnt> theBasePoint, std::shared_ptr<GeomAPI_Edge> theEdge,
120     double theRadius, double theHeight, double theAngle) throw (GeomAlgoAPI_Exception)
121   {
122     // Check if the base point is OK
123     if (!theBasePoint) {
124       throw GeomAlgoAPI_Exception("Cylinder builder :: the base point is not valid.");
125     }
126     // Check if the edge is OK
127     if (!theEdge) {
128       throw GeomAlgoAPI_Exception("Cylinder builder :: the axis is not valid.");
129     }
130
131     std::shared_ptr<GeomAPI_Ax2> anAxis;
132     anAxis = std::shared_ptr<GeomAPI_Ax2>(new GeomAPI_Ax2(theBasePoint,
133                                                           theEdge->line()->direction()));
134
135     GeomAlgoAPI_Cylinder aCylinderAlgo(anAxis, theRadius, theHeight, theAngle);
136
137     if (!aCylinderAlgo.check()) {
138       throw GeomAlgoAPI_Exception(aCylinderAlgo.getError());
139     }
140
141     aCylinderAlgo.build();
142
143     if(!aCylinderAlgo.isDone()) {
144       throw GeomAlgoAPI_Exception(aCylinderAlgo.getError());
145     }
146     if (!aCylinderAlgo.checkValid("Cylinder portion builder")) {
147       throw GeomAlgoAPI_Exception(aCylinderAlgo.getError());
148     }
149     return aCylinderAlgo.shape();
150   }
151
152   //===============================================================================================
153   std::shared_ptr<GeomAPI_Shape> GeomAlgoAPI_ShapeAPI::makeCylinder(
154     double theRadius, double theHeight) throw (GeomAlgoAPI_Exception)
155   {
156     std::shared_ptr<GeomAPI_Pnt> aBasePoint =
157       std::shared_ptr<GeomAPI_Pnt>(new GeomAPI_Pnt(0.,0.,0.));
158     std::shared_ptr<GeomAPI_Edge> aEdge = GeomAlgoAPI_EdgeBuilder::line(0., 0., 1.);
159     std::shared_ptr<GeomAPI_Ax2> anAxis;
160     anAxis = std::shared_ptr<GeomAPI_Ax2>(new GeomAPI_Ax2(aBasePoint,
161                                                           aEdge->line()->direction()));
162
163     GeomAlgoAPI_Cylinder aCylinderAlgo(anAxis, theRadius, theHeight);
164
165     if (!aCylinderAlgo.check()) {
166       throw GeomAlgoAPI_Exception(aCylinderAlgo.getError());
167     }
168
169     aCylinderAlgo.build();
170
171     if(!aCylinderAlgo.isDone()) {
172       throw GeomAlgoAPI_Exception(aCylinderAlgo.getError());
173     }
174     if (!aCylinderAlgo.checkValid("Cylinder builder")) {
175       throw GeomAlgoAPI_Exception(aCylinderAlgo.getError());
176     }
177     return aCylinderAlgo.shape();
178   }
179
180   //===============================================================================================
181   std::shared_ptr<GeomAPI_Shape> GeomAlgoAPI_ShapeAPI::makeCylinder(
182     double theRadius, double theHeight, double theAngle) throw (GeomAlgoAPI_Exception)
183   {
184     std::shared_ptr<GeomAPI_Pnt> aBasePoint =
185       std::shared_ptr<GeomAPI_Pnt>(new GeomAPI_Pnt(0.,0.,0.));
186     std::shared_ptr<GeomAPI_Edge> aEdge = GeomAlgoAPI_EdgeBuilder::line(0., 0., 1.);
187     std::shared_ptr<GeomAPI_Ax2> anAxis;
188     anAxis = std::shared_ptr<GeomAPI_Ax2>(new GeomAPI_Ax2(aBasePoint,
189                                                           aEdge->line()->direction()));
190
191     GeomAlgoAPI_Cylinder aCylinderAlgo(anAxis, theRadius, theHeight, theAngle);
192
193     if (!aCylinderAlgo.check()) {
194       throw GeomAlgoAPI_Exception(aCylinderAlgo.getError());
195     }
196
197     aCylinderAlgo.build();
198
199     if(!aCylinderAlgo.isDone()) {
200       throw GeomAlgoAPI_Exception(aCylinderAlgo.getError());
201     }
202     if (!aCylinderAlgo.checkValid("Cylinder portion builder")) {
203       throw GeomAlgoAPI_Exception(aCylinderAlgo.getError());
204     }
205     return aCylinderAlgo.shape();
206   }
207
208   //===============================================================================================
209   std::shared_ptr<GeomAPI_Shape> GeomAlgoAPI_ShapeAPI::makeTranslation(
210     std::shared_ptr<GeomAPI_Shape> theSourceShape,
211     std::shared_ptr<GeomAPI_Ax1>   theAxis,
212     const double theDistance) throw (GeomAlgoAPI_Exception)
213   {
214     GeomAlgoAPI_Translation aTranslationAlgo(theSourceShape, theAxis, theDistance);
215
216     if (!aTranslationAlgo.check()) {
217       throw GeomAlgoAPI_Exception(aTranslationAlgo.getError());
218     }
219
220     aTranslationAlgo.build();
221
222     if(!aTranslationAlgo.isDone()) {
223       throw GeomAlgoAPI_Exception(aTranslationAlgo.getError());
224     }
225
226     return aTranslationAlgo.shape();
227   }
228
229   //===============================================================================================
230   std::shared_ptr<GeomAPI_Shape> GeomAlgoAPI_ShapeAPI::makeTranslation(
231     std::shared_ptr<GeomAPI_Shape> theSourceShape,
232     const double theDx,
233     const double theDy,
234     const double theDz) throw (GeomAlgoAPI_Exception)
235   {
236     GeomAlgoAPI_Translation aTranslationAlgo(theSourceShape, theDx, theDy, theDz);
237
238     if (!aTranslationAlgo.check()) {
239       throw GeomAlgoAPI_Exception(aTranslationAlgo.getError());
240     }
241
242     aTranslationAlgo.build();
243
244     if(!aTranslationAlgo.isDone()) {
245       throw GeomAlgoAPI_Exception(aTranslationAlgo.getError());
246     }
247
248     return aTranslationAlgo.shape();
249   }
250
251   //===============================================================================================
252   std::shared_ptr<GeomAPI_Shape> GeomAlgoAPI_ShapeAPI::makeTranslation(
253     std::shared_ptr<GeomAPI_Shape> theSourceShape,
254     std::shared_ptr<GeomAPI_Pnt>   theStartPoint,
255     std::shared_ptr<GeomAPI_Pnt>   theEndPoint) throw (GeomAlgoAPI_Exception)
256   {
257     GeomAlgoAPI_Translation aTranslationAlgo(theSourceShape, theStartPoint, theEndPoint);
258
259     if (!aTranslationAlgo.check()) {
260       throw GeomAlgoAPI_Exception(aTranslationAlgo.getError());
261     }
262
263     aTranslationAlgo.build();
264
265     if(!aTranslationAlgo.isDone()) {
266       throw GeomAlgoAPI_Exception(aTranslationAlgo.getError());
267     }
268
269     return aTranslationAlgo.shape();
270   }
271
272   //===============================================================================================
273   std::shared_ptr<GeomAPI_Shape> GeomAlgoAPI_ShapeAPI::makeRotation(
274     std::shared_ptr<GeomAPI_Shape> theSourceShape,
275     std::shared_ptr<GeomAPI_Ax1> theAxis,
276     const double theAngle) throw (GeomAlgoAPI_Exception)
277   {
278     GeomAlgoAPI_Rotation aRotationAlgo(theSourceShape, theAxis, theAngle);
279
280     if (!aRotationAlgo.check()) {
281       throw GeomAlgoAPI_Exception(aRotationAlgo.getError());
282     }
283
284     aRotationAlgo.build();
285
286     if(!aRotationAlgo.isDone()) {
287       throw GeomAlgoAPI_Exception(aRotationAlgo.getError());
288     }
289
290     return aRotationAlgo.shape();
291   }
292
293   //===============================================================================================
294   std::shared_ptr<GeomAPI_Shape> GeomAlgoAPI_ShapeAPI::makeRotation(
295     std::shared_ptr<GeomAPI_Shape> theSourceShape,
296     std::shared_ptr<GeomAPI_Pnt> theCenterPoint,
297     std::shared_ptr<GeomAPI_Pnt> theStartPoint,
298     std::shared_ptr<GeomAPI_Pnt> theEndPoint) throw (GeomAlgoAPI_Exception)
299   {
300     GeomAlgoAPI_Rotation aRotationAlgo(theSourceShape, theCenterPoint, theStartPoint, theEndPoint);
301
302     if (!aRotationAlgo.check()) {
303       throw GeomAlgoAPI_Exception(aRotationAlgo.getError());
304     }
305
306     aRotationAlgo.build();
307
308     if(!aRotationAlgo.isDone()) {
309       throw GeomAlgoAPI_Exception(aRotationAlgo.getError());
310     }
311
312     return aRotationAlgo.shape();
313   }
314
315   //===============================================================================================
316   std::shared_ptr<GeomAPI_Shape> GeomAlgoAPI_ShapeAPI::makeSymmetry(
317     std::shared_ptr<GeomAPI_Shape> theSourceShape,
318     std::shared_ptr<GeomAPI_Pnt>   thePoint) throw (GeomAlgoAPI_Exception)
319   {
320     GeomAlgoAPI_Symmetry aSymmetryAlgo(theSourceShape, thePoint);
321
322     if (!aSymmetryAlgo.check()) {
323       throw GeomAlgoAPI_Exception(aSymmetryAlgo.getError());
324     }
325
326     aSymmetryAlgo.build();
327
328     if(!aSymmetryAlgo.isDone()) {
329       throw GeomAlgoAPI_Exception(aSymmetryAlgo.getError());
330     }
331
332     return aSymmetryAlgo.shape();
333   }
334
335   //===============================================================================================
336   std::shared_ptr<GeomAPI_Shape> GeomAlgoAPI_ShapeAPI::makeSymmetry(
337     std::shared_ptr<GeomAPI_Shape> theSourceShape,
338     std::shared_ptr<GeomAPI_Ax1>   theAxis) throw (GeomAlgoAPI_Exception)
339   {
340     GeomAlgoAPI_Symmetry aSymmetryAlgo(theSourceShape, theAxis);
341
342     if (!aSymmetryAlgo.check()) {
343       throw GeomAlgoAPI_Exception(aSymmetryAlgo.getError());
344     }
345
346     aSymmetryAlgo.build();
347
348     if(!aSymmetryAlgo.isDone()) {
349       throw GeomAlgoAPI_Exception(aSymmetryAlgo.getError());
350     }
351
352     return aSymmetryAlgo.shape();
353   }
354
355   //===============================================================================================
356   std::shared_ptr<GeomAPI_Shape> GeomAlgoAPI_ShapeAPI::makeSymmetry(
357     std::shared_ptr<GeomAPI_Shape> theSourceShape,
358     std::shared_ptr<GeomAPI_Ax2>   thePlane) throw (GeomAlgoAPI_Exception)
359   {
360     GeomAlgoAPI_Symmetry aSymmetryAlgo(theSourceShape, thePlane);
361
362     if (!aSymmetryAlgo.check()) {
363       throw GeomAlgoAPI_Exception(aSymmetryAlgo.getError());
364     }
365
366     aSymmetryAlgo.build();
367
368     if(!aSymmetryAlgo.isDone()) {
369       throw GeomAlgoAPI_Exception(aSymmetryAlgo.getError());
370     }
371
372     return aSymmetryAlgo.shape();
373   }
374
375   //===============================================================================================
376   std::shared_ptr<GeomAPI_Shape> GeomAlgoAPI_ShapeAPI::makeScale(
377     std::shared_ptr<GeomAPI_Shape> theSourceShape,
378     std::shared_ptr<GeomAPI_Pnt>   theCenterPoint,
379     const double                   theScaleFactor) throw (GeomAlgoAPI_Exception)
380   {
381     GeomAlgoAPI_Scale aScaleAlgo(theSourceShape, theCenterPoint, theScaleFactor);
382
383     if (!aScaleAlgo.check()) {
384       throw GeomAlgoAPI_Exception(aScaleAlgo.getError());
385     }
386
387     aScaleAlgo.build();
388
389     if(!aScaleAlgo.isDone()) {
390       throw GeomAlgoAPI_Exception(aScaleAlgo.getError());
391     }
392
393     return aScaleAlgo.shape();
394   }
395
396   //===============================================================================================
397   std::shared_ptr<GeomAPI_Shape> GeomAlgoAPI_ShapeAPI::makeScale(
398     std::shared_ptr<GeomAPI_Shape> theSourceShape,
399     std::shared_ptr<GeomAPI_Pnt>   theCenterPoint,
400     const double                   theScaleFactorX,
401     const double                   theScaleFactorY,
402     const double                   theScaleFactorZ) throw (GeomAlgoAPI_Exception)
403   {
404     GeomAlgoAPI_Scale aScaleAlgo(theSourceShape, theCenterPoint,
405                                  theScaleFactorX, theScaleFactorY, theScaleFactorZ);
406
407     if (!aScaleAlgo.check()) {
408       throw GeomAlgoAPI_Exception(aScaleAlgo.getError());
409     }
410
411     aScaleAlgo.build();
412
413     if(!aScaleAlgo.isDone()) {
414       throw GeomAlgoAPI_Exception(aScaleAlgo.getError());
415     }
416
417     return aScaleAlgo.shape();
418   }
419
420   //===============================================================================================
421   std::shared_ptr<GeomAPI_Shape> GeomAlgoAPI_ShapeAPI::makeMultiTranslation(
422     std::shared_ptr<GeomAPI_Shape> theSourceShape,
423     std::shared_ptr<GeomAPI_Ax1> theAxis,
424     const double theStep,
425     const int theNumber) throw (GeomAlgoAPI_Exception)
426   {
427     if (!theAxis) {
428       std::string aError = "Multitranslation builder ";
429       aError+=":: the first axis is not valid";
430       throw GeomAlgoAPI_Exception(aError);
431     }
432
433     if (theNumber <=0) {
434       std::string aError = "Multitranslation builder ";
435       aError+=":: the number of copies for the first direction is null or negative.";
436       throw GeomAlgoAPI_Exception(aError);
437     }
438
439     ListOfShape aListOfShape;
440     for (int i=0; i<theNumber; i++) {
441       aListOfShape.
442         push_back(GeomAlgoAPI_ShapeAPI::makeTranslation(theSourceShape, theAxis, i*theStep));
443     }
444     return GeomAlgoAPI_CompoundBuilder::compound(aListOfShape);
445   }
446
447   //===============================================================================================
448   std::shared_ptr<GeomAPI_Shape> GeomAlgoAPI_ShapeAPI::makeMultiTranslation(
449     std::shared_ptr<GeomAPI_Shape> theSourceShape,
450     std::shared_ptr<GeomAPI_Ax1> theFirstAxis,
451     const double theFirstStep,
452     const int theFirstNumber,
453     std::shared_ptr<GeomAPI_Ax1> theSecondAxis,
454     const double theSecondStep,
455     const int theSecondNumber) throw (GeomAlgoAPI_Exception)
456   {
457     if (!theFirstAxis) {
458       std::string aError = "Multitranslation builder ";
459       aError+=":: the first axis is not valid";
460       throw GeomAlgoAPI_Exception(aError);
461     }
462
463     if (!theSecondAxis) {
464       std::string aError = "Multitranslation builder ";
465       aError+=":: the second axis is not valid";
466       throw GeomAlgoAPI_Exception(aError);
467     }
468
469     if (theFirstNumber <=0) {
470       std::string aError = "Multitranslation builder ";
471       aError+=":: the number of copies for the first direction is null or negative.";
472       throw GeomAlgoAPI_Exception(aError);
473     }
474
475     if (theSecondNumber <=0) {
476       std::string aError = "Multitranslation builder ";
477       aError+=":: the number of copies for the second direction is null or negative.";
478       throw GeomAlgoAPI_Exception(aError);
479     }
480
481     // Coord theFirstAxis
482     double x1 = theFirstAxis->dir()->x();
483     double y1 = theFirstAxis->dir()->y();
484     double z1 = theFirstAxis->dir()->z();
485     double norm1 = sqrt(x1*x1 + y1*y1 + z1*z1);
486
487     // Coord theSecondAxis
488     double x2 = theSecondAxis->dir()->x();
489     double y2 = theSecondAxis->dir()->y();
490     double z2 = theSecondAxis->dir()->z();
491     double norm2 = sqrt(x2*x2 + y2*y2 + z2*z2);
492
493     ListOfShape aListOfShape;
494     for (int j=0; j<theSecondStep; j++) {
495       for (int i=0; i<theFirstNumber; i++) {
496         double dx = i*theFirstStep*x1/norm1+j*theSecondStep*x2/norm2;
497         double dy = i*theFirstStep*y1/norm1+j*theSecondStep*y2/norm2;
498         double dz = i*theFirstStep*z1/norm1+j*theSecondStep*z2/norm2;
499         aListOfShape.push_back(GeomAlgoAPI_ShapeAPI::makeTranslation(theSourceShape, dx, dy, dz));
500       }
501     }
502     return GeomAlgoAPI_CompoundBuilder::compound(aListOfShape);
503   }
504
505   //===============================================================================================
506   std::shared_ptr<GeomAPI_Shape> GeomAlgoAPI_ShapeAPI::makeConeSegment(
507     const double theRMin1, const double theRMax1,
508     const double theRMin2, const double theRMax2,
509     const double theZ,
510     const double theStartPhi, const double theDeltaPhi) throw (GeomAlgoAPI_Exception)
511   {
512     GeomAlgoAPI_ConeSegment aConeSegmentAlgo(theRMin1, theRMax1, theRMin2, theRMax2,
513                                              theZ, theStartPhi, theDeltaPhi);
514
515     if (!aConeSegmentAlgo.check()) {
516       throw GeomAlgoAPI_Exception(aConeSegmentAlgo.getError());
517     }
518
519     aConeSegmentAlgo.build();
520
521     if(!aConeSegmentAlgo.isDone()) {
522       throw GeomAlgoAPI_Exception(aConeSegmentAlgo.getError());
523     }
524     if (!aConeSegmentAlgo.checkValid("Cone Segment builder")) {
525       throw GeomAlgoAPI_Exception(aConeSegmentAlgo.getError());
526     }
527     return aConeSegmentAlgo.shape();
528   }
529 }