Salome HOME
Merge branch 'V9_8_BR'
[modules/geom.git] / src / GEOMImpl / GEOMImpl_ITransformOperations.cxx
1 // Copyright (C) 2007-2021  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 <GEOMImpl_ITransformOperations.hxx>
26
27 #include <GEOMImpl_TranslateDriver.hxx>
28 #include <GEOMImpl_MirrorDriver.hxx>
29 #include <GEOMImpl_ProjectionDriver.hxx>
30 #include <GEOMImpl_OffsetDriver.hxx>
31 #include <GEOMImpl_ScaleDriver.hxx>
32 #include <GEOMImpl_RotateDriver.hxx>
33 #include <GEOMImpl_PositionDriver.hxx>
34
35 #include <GEOMImpl_ITranslate.hxx>
36 #include <GEOMImpl_IMirror.hxx>
37 #include <GEOMImpl_IProjection.hxx>
38 #include <GEOMImpl_IProjOnCyl.hxx>
39 #include <GEOMImpl_IOffset.hxx>
40 #include <GEOMImpl_IScale.hxx>
41 #include <GEOMImpl_IRotate.hxx>
42 #include <GEOMImpl_IPosition.hxx>
43
44 #include <GEOMImpl_Types.hxx>
45
46 #include <GEOM_Function.hxx>
47 #include <GEOM_PythonDump.hxx>
48
49 #include "utilities.h"
50 #include <OpUtil.hxx>
51 #include <Utils_ExceptHandlers.hxx>
52
53 #include <TFunction_DriverTable.hxx>
54 #include <TFunction_Driver.hxx>
55 #include <TDF_Tool.hxx>
56
57 #include <BRep_Tool.hxx>
58 #include <BRep_Builder.hxx>
59 #include <TopExp.hxx>
60 #include <TopoDS.hxx>
61 #include <TopoDS_Edge.hxx>
62 #include <TopoDS_Vertex.hxx>
63 #include <TopoDS_Compound.hxx>
64 #include <gp_Pnt.hxx>
65 #include <gp_Vec.hxx>
66 #include <gp_Trsf.hxx>
67
68 #include <StdFail_NotDone.hxx>
69 #include <Standard_Failure.hxx>
70 #include <Standard_ErrorHandler.hxx> // CAREFUL ! position of this file is critic : see Lucien PIGNOLONI / OCC
71
72 //=============================================================================
73 /*!
74  *   constructor:
75  */
76 //=============================================================================
77
78 GEOMImpl_ITransformOperations::GEOMImpl_ITransformOperations (GEOM_Engine* theEngine)
79 : GEOM_IOperations(theEngine)
80 {
81   MESSAGE("GEOMImpl_ITransformOperations::GEOMImpl_ITransformOperations");
82 }
83
84 //=============================================================================
85 /*!
86  *  destructor
87  */
88 //=============================================================================
89
90 GEOMImpl_ITransformOperations::~GEOMImpl_ITransformOperations()
91 {
92   MESSAGE("GEOMImpl_ITransformOperations::~GEOMImpl_ITransformOperations");
93 }
94
95
96 //=============================================================================
97 /*!
98  *  TranslateTwoPoints
99  */
100 //=============================================================================
101 Handle(GEOM_Object) GEOMImpl_ITransformOperations::TranslateTwoPoints
102        (Handle(GEOM_Object) theObject, Handle(GEOM_Object) thePoint1, Handle(GEOM_Object) thePoint2)
103 {
104   SetErrorCode(KO);
105
106   if (theObject.IsNull() || thePoint1.IsNull() || thePoint2.IsNull()) return NULL;
107
108   Handle(GEOM_Function) aFunction, aLastFunction = theObject->GetLastFunction();
109   if (aLastFunction.IsNull()) return NULL; //There is no function which creates an object to be moved
110
111   // Get last functions of the arguments
112   Handle(GEOM_Function) aP1F = thePoint1->GetLastFunction();
113   Handle(GEOM_Function) aP2F = thePoint2->GetLastFunction();
114
115   //Add a translate function
116   aFunction = theObject->AddFunction(GEOMImpl_TranslateDriver::GetID(), TRANSLATE_TWO_POINTS);
117
118   if (aFunction.IsNull()) return NULL;
119
120   //Check if the function is set correctly
121   if (aFunction->GetDriverGUID() != GEOMImpl_TranslateDriver::GetID()) return NULL;
122
123   GEOMImpl_ITranslate aTI (aFunction);
124   aTI.SetPoint1(aP1F);
125   aTI.SetPoint2(aP2F);
126   aTI.SetOriginal(aLastFunction);
127
128   //Compute the translation
129   try {
130     OCC_CATCH_SIGNALS;
131     if (!GetSolver()->ComputeFunction(aFunction)) {
132       SetErrorCode("Translation driver failed");
133       return NULL;
134     }
135   }
136   catch (Standard_Failure& aFail) {
137     SetErrorCode(aFail.GetMessageString());
138     return NULL;
139   }
140
141   //Make a Python command
142   GEOM::TPythonDump(aFunction) << "geompy.TranslateTwoPoints("
143     << theObject << ", " << thePoint1 << ", " << thePoint2 << ")";
144
145   SetErrorCode(OK);
146   return theObject;
147 }
148
149 //=============================================================================
150 /*!
151  *  TranslateDXDYDZ
152  */
153 //=============================================================================
154 Handle(GEOM_Object) GEOMImpl_ITransformOperations::TranslateDXDYDZ
155        (Handle(GEOM_Object) theObject, double theX, double theY,  double theZ)
156 {
157   SetErrorCode(KO);
158
159   if (theObject.IsNull()) return NULL;
160
161   Handle(GEOM_Function) aFunction, aLastFunction = theObject->GetLastFunction();
162   if (aLastFunction.IsNull()) return NULL; //There is no function which creates an object to be moved
163
164   //Add a translate function
165   aFunction = theObject->AddFunction(GEOMImpl_TranslateDriver::GetID(), TRANSLATE_XYZ);
166
167   if (aFunction.IsNull()) return NULL;
168
169   //Check if the function is set correctly
170   if (aFunction->GetDriverGUID() != GEOMImpl_TranslateDriver::GetID()) return NULL;
171
172   GEOMImpl_ITranslate aTI(aFunction);
173   aTI.SetDX(theX);
174   aTI.SetDY(theY);
175   aTI.SetDZ(theZ);
176   aTI.SetOriginal(aLastFunction);
177
178   //Compute the translation
179   try {
180     OCC_CATCH_SIGNALS;
181     if (!GetSolver()->ComputeFunction(aFunction)) {
182       SetErrorCode("Translation driver failed");
183       return NULL;
184     }
185   }
186   catch (Standard_Failure& aFail) {
187     SetErrorCode(aFail.GetMessageString());
188     return NULL;
189   }
190
191   //Make a Python command
192   GEOM::TPythonDump(aFunction) << "geompy.TranslateDXDYDZ("
193     << theObject << ", " << theX << ", " << theY << ", " << theZ << ")";
194
195   SetErrorCode(OK);
196   return theObject;
197 }
198
199
200 //=============================================================================
201 /*!
202  *  TranslateTwoPointsCopy
203  */
204 //=============================================================================
205 Handle(GEOM_Object) GEOMImpl_ITransformOperations::TranslateTwoPointsCopy
206        (Handle(GEOM_Object) theObject, Handle(GEOM_Object) thePoint1, Handle(GEOM_Object) thePoint2)
207 {
208   SetErrorCode(KO);
209
210   if (theObject.IsNull() || thePoint1.IsNull() || thePoint2.IsNull()) return NULL;
211
212   Handle(GEOM_Function) aLastFunction = theObject->GetLastFunction();
213   if (aLastFunction.IsNull()) return NULL; //There is no function which creates an object to be moved
214
215   //Add a new Copy object
216   Handle(GEOM_Object) aCopy = GetEngine()->AddObject(GEOM_COPY);
217
218   //Add a translate function
219   Handle(GEOM_Function) aFunction =
220     aCopy->AddFunction(GEOMImpl_TranslateDriver::GetID(), TRANSLATE_TWO_POINTS_COPY);
221
222   //Check if the function is set correctly
223   if (aFunction->GetDriverGUID() != GEOMImpl_TranslateDriver::GetID()) return NULL;
224
225   GEOMImpl_ITranslate aTI(aFunction);
226   aTI.SetPoint1(thePoint1->GetLastFunction());
227   aTI.SetPoint2(thePoint2->GetLastFunction());
228   //aTI.SetShape(theObject->GetValue());
229   aTI.SetOriginal(aLastFunction);
230
231   //Compute the translation
232   try {
233     OCC_CATCH_SIGNALS;
234     if (!GetSolver()->ComputeFunction(aFunction)) {
235       SetErrorCode("Translation driver failed");
236       return NULL;
237     }
238   }
239   catch (Standard_Failure& aFail) {
240     SetErrorCode(aFail.GetMessageString());
241     return NULL;
242   }
243
244   //Make a Python command
245   GEOM::TPythonDump(aFunction) << aCopy << " = geompy.MakeTranslationTwoPoints("
246     << theObject << ", " << thePoint1 << ", " << thePoint2 << ")";
247
248   SetErrorCode(OK);
249   return aCopy;
250 }
251
252 //=============================================================================
253 /*!
254  *  TranslateDXDYDZCopy
255  */
256 //=============================================================================
257 Handle(GEOM_Object) GEOMImpl_ITransformOperations::TranslateDXDYDZCopy
258        (Handle(GEOM_Object) theObject, double theX, double theY,  double theZ)
259 {
260   SetErrorCode(KO);
261
262   if (theObject.IsNull()) return NULL;
263
264   Handle(GEOM_Function) aLastFunction = theObject->GetLastFunction();
265   if (aLastFunction.IsNull()) return NULL; //There is no function which creates an object to be moved
266
267   //Add a new Copy object
268   Handle(GEOM_Object) aCopy = GetEngine()->AddObject(GEOM_COPY);
269
270   //Add a translate function
271   Handle(GEOM_Function) aFunction =
272     aCopy->AddFunction(GEOMImpl_TranslateDriver::GetID(), TRANSLATE_XYZ_COPY);
273
274   //Check if the function is set correctly
275   if (aFunction->GetDriverGUID() != GEOMImpl_TranslateDriver::GetID()) return NULL;
276
277   GEOMImpl_ITranslate aTI(aFunction);
278   aTI.SetDX(theX);
279   aTI.SetDY(theY);
280   aTI.SetDZ(theZ);
281   aTI.SetOriginal(aLastFunction);
282
283   //Compute the translation
284   try {
285     OCC_CATCH_SIGNALS;
286     if (!GetSolver()->ComputeFunction(aFunction)) {
287       SetErrorCode("Translation driver failed");
288       return NULL;
289     }
290   }
291   catch (Standard_Failure& aFail) {
292     SetErrorCode(aFail.GetMessageString());
293     return NULL;
294   }
295
296   //Make a Python command
297   GEOM::TPythonDump(aFunction) << aCopy << " = geompy.MakeTranslation("
298     << theObject << ", " << theX << ", " << theY << ", " << theZ << ")";
299
300   SetErrorCode(OK);
301   return aCopy;
302 }
303
304
305 //=============================================================================
306 /*!
307  *  TranslateVector
308  */
309 //=============================================================================
310 Handle(GEOM_Object) GEOMImpl_ITransformOperations::TranslateVector
311        (Handle(GEOM_Object) theObject, Handle(GEOM_Object) theVector)
312 {
313   SetErrorCode(KO);
314
315   if (theObject.IsNull() || theVector.IsNull()) return NULL;
316
317   Handle(GEOM_Function) aFunction, aLastFunction = theObject->GetLastFunction();
318   if (aLastFunction.IsNull()) return NULL; //There is no function which creates an object to be moved
319
320   // Get last functions of the arguments
321   Handle(GEOM_Function) aVF = theVector->GetLastFunction();
322
323   //Add a translate function
324   aFunction = theObject->AddFunction(GEOMImpl_TranslateDriver::GetID(), TRANSLATE_VECTOR);
325
326   if (aFunction.IsNull()) return NULL;
327
328   //Check if the function is set correctly
329   if (aFunction->GetDriverGUID() != GEOMImpl_TranslateDriver::GetID()) return NULL;
330
331   GEOMImpl_ITranslate aTI (aFunction);
332   aTI.SetVector(aVF);
333   aTI.SetOriginal(aLastFunction);
334
335   //Compute the translation
336   try {
337     OCC_CATCH_SIGNALS;
338     if (!GetSolver()->ComputeFunction(aFunction)) {
339       SetErrorCode("Translation driver failed");
340       return NULL;
341     }
342   }
343   catch (Standard_Failure& aFail) {
344     SetErrorCode(aFail.GetMessageString());
345     return NULL;
346   }
347
348   //Make a Python command
349   GEOM::TPythonDump(aFunction) << "geompy.TranslateVector("
350                                << theObject << ", " << theVector << ")";
351
352   SetErrorCode(OK);
353   return theObject;
354 }
355 //=============================================================================
356 /*!
357  *  TranslateVectorCopy
358  */
359 //=============================================================================
360 Handle(GEOM_Object) GEOMImpl_ITransformOperations::TranslateVectorCopy
361        (Handle(GEOM_Object) theObject, Handle(GEOM_Object) theVector)
362 {
363   SetErrorCode(KO);
364
365   if (theObject.IsNull() || theVector.IsNull()) return NULL;
366
367   Handle(GEOM_Function) aLastFunction = theObject->GetLastFunction();
368   if (aLastFunction.IsNull()) return NULL; //There is no function which creates an object to be moved
369
370   //Add a new Copy object
371   Handle(GEOM_Object) aCopy = GetEngine()->AddObject(GEOM_COPY);
372
373   //Add a translate function
374   Handle(GEOM_Function) aFunction =
375     aCopy->AddFunction(GEOMImpl_TranslateDriver::GetID(), TRANSLATE_VECTOR_COPY);
376
377   //Check if the function is set correctly
378   if (aFunction->GetDriverGUID() != GEOMImpl_TranslateDriver::GetID()) return NULL;
379
380   GEOMImpl_ITranslate aTI(aFunction);
381   aTI.SetVector(theVector->GetLastFunction());
382 //  aTI.SetShape(theObject->GetValue());
383   aTI.SetOriginal(aLastFunction);
384
385   //Compute the translation
386   try {
387     OCC_CATCH_SIGNALS;
388     if (!GetSolver()->ComputeFunction(aFunction)) {
389       SetErrorCode("Translation driver failed");
390       return NULL;
391     }
392   }
393   catch (Standard_Failure& aFail) {
394     SetErrorCode(aFail.GetMessageString());
395     return NULL;
396   }
397
398   //Make a Python command
399   GEOM::TPythonDump(aFunction) << aCopy << " = geompy.MakeTranslationVector("
400                                << theObject << ", " << theVector << ")";
401
402   SetErrorCode(OK);
403   return aCopy;
404 }
405
406 //=============================================================================
407 /*!
408  *  TranslateVectorDistance
409  */
410 //=============================================================================
411 Handle(GEOM_Object) GEOMImpl_ITransformOperations::TranslateVectorDistance
412        (Handle(GEOM_Object) theObject, Handle(GEOM_Object) theVector, double theDistance, bool theCopy)
413 {
414   SetErrorCode(KO);
415
416   if (theObject.IsNull() || theVector.IsNull()) return NULL;
417
418   Handle(GEOM_Function) aLastFunction = theObject->GetLastFunction();
419   if (aLastFunction.IsNull()) return NULL; //There is no function which creates an object to be moved
420
421   Handle(GEOM_Object) aCopy;   //Add a new Copy object
422   Handle(GEOM_Function) aFunction;
423
424   //Add a translate function
425   if (theCopy) {
426     aCopy = GetEngine()->AddObject(theObject->GetType());
427     aFunction = aCopy->AddFunction(GEOMImpl_TranslateDriver::GetID(), TRANSLATE_VECTOR_DISTANCE);
428   }
429   else {
430     aFunction = theObject->AddFunction(GEOMImpl_TranslateDriver::GetID(), TRANSLATE_VECTOR_DISTANCE);
431   }
432   if (aFunction.IsNull()) return NULL;
433
434   //Check if the function is set correctly
435   if (aFunction->GetDriverGUID() != GEOMImpl_TranslateDriver::GetID()) return NULL;
436
437   GEOMImpl_ITranslate aTI(aFunction);
438   aTI.SetVector(theVector->GetLastFunction());
439   aTI.SetDistance(theDistance);
440 //  aTI.SetShape(theObject->GetValue());
441   aTI.SetOriginal(aLastFunction);
442
443   //Compute the translation
444   try {
445     OCC_CATCH_SIGNALS;
446     if (!GetSolver()->ComputeFunction(aFunction)) {
447       SetErrorCode("Translation driver failed");
448       return NULL;
449     }
450   }
451   catch (Standard_Failure& aFail) {
452     SetErrorCode(aFail.GetMessageString());
453     return NULL;
454   }
455
456   //Make a Python command
457   if (theCopy) {
458     GEOM::TPythonDump(aFunction) << aCopy << " = geompy.MakeTranslationVectorDistance("
459                                  << theObject << ", " << theVector << ", " << theDistance << ")";
460     SetErrorCode(OK);
461     return aCopy;
462   }
463
464   GEOM::TPythonDump(aFunction) << "geompy.TranslateVectorDistance("
465                                << theObject << ", " << theVector << ", " << theDistance << ", " << theCopy << ")";
466   SetErrorCode(OK);
467   return theObject;
468 }
469
470 //=============================================================================
471 /*!
472  *  Translate1D
473  */
474 //=============================================================================
475 Handle(GEOM_Object) GEOMImpl_ITransformOperations::Translate1D
476        (Handle(GEOM_Object) theObject, Handle(GEOM_Object) theVector,
477         double theStep, Standard_Integer theNbTimes)
478 {
479   SetErrorCode(KO);
480
481   if (theObject.IsNull()) return NULL;
482
483   Handle(GEOM_Function) aLastFunction = theObject->GetLastFunction();
484   if (aLastFunction.IsNull()) return NULL; //There is no function which creates an object to be moved
485
486   //Add a new Copy object
487   Handle(GEOM_Object) aCopy = GetEngine()->AddObject(theObject->GetType());
488
489   //Add a translate function
490   Handle(GEOM_Function) aFunction =
491     aCopy->AddFunction(GEOMImpl_TranslateDriver::GetID(), TRANSLATE_1D);
492
493   //Check if the function is set correctly
494   if (aFunction->GetDriverGUID() != GEOMImpl_TranslateDriver::GetID()) return NULL;
495
496   GEOMImpl_ITranslate aTI (aFunction);
497   aTI.SetOriginal(aLastFunction);
498   if (!theVector.IsNull())
499     aTI.SetVector(theVector->GetLastFunction());
500   aTI.SetStep1(theStep);
501   aTI.SetNbIter1(theNbTimes);
502
503   //Compute the translation
504   try {
505     OCC_CATCH_SIGNALS;
506     if (!GetSolver()->ComputeFunction(aFunction)) {
507       SetErrorCode("Translation driver failed");
508       return NULL;
509     }
510   }
511   catch (Standard_Failure& aFail) {
512     SetErrorCode(aFail.GetMessageString());
513     return NULL;
514   }
515
516   //Make a Python command
517   GEOM::TPythonDump(aFunction) << aCopy << " = geompy.MakeMultiTranslation1D("
518     << theObject << ", " << theVector << ", " << theStep << ", " << theNbTimes << ")";
519
520   SetErrorCode(OK);
521   return aCopy;
522 }
523
524 //=============================================================================
525 /*!
526  *  Translate2D
527  */
528 //=============================================================================
529 Handle(GEOM_Object) GEOMImpl_ITransformOperations::Translate2D (Handle(GEOM_Object) theObject,
530                                                                 Handle(GEOM_Object) theVector,
531                                                                 double theStep1,
532                                                                 Standard_Integer theNbTimes1,
533                                                                 Handle(GEOM_Object) theVector2,
534                                                                 double theStep2,
535                                                                 Standard_Integer theNbTimes2)
536 {
537   SetErrorCode(KO);
538
539   if (theObject.IsNull()) return NULL;
540
541   Handle(GEOM_Function) aLastFunction = theObject->GetLastFunction();
542   if (aLastFunction.IsNull()) return NULL; //There is no function which creates an object to be moved
543
544   //Add a new Copy object
545   Handle(GEOM_Object) aCopy = GetEngine()->AddObject(theObject->GetType());
546
547   //Add a translate function
548   Handle(GEOM_Function) aFunction =
549     aCopy->AddFunction(GEOMImpl_TranslateDriver::GetID(), TRANSLATE_2D);
550
551   //Check if the function is set correctly
552   if (aFunction->GetDriverGUID() != GEOMImpl_TranslateDriver::GetID()) return NULL;
553
554   GEOMImpl_ITranslate aTI (aFunction);
555   aTI.SetOriginal(aLastFunction);
556   if (!theVector.IsNull())
557     aTI.SetVector(theVector->GetLastFunction());
558   aTI.SetStep1(theStep1);
559   aTI.SetNbIter1(theNbTimes1);
560   if (!theVector2.IsNull())
561     aTI.SetVector2(theVector2->GetLastFunction());
562   aTI.SetStep2(theStep2);
563   aTI.SetNbIter2(theNbTimes2);
564
565   //Compute the translation
566   try {
567     OCC_CATCH_SIGNALS;
568     if (!GetSolver()->ComputeFunction(aFunction)) {
569       SetErrorCode("Translation driver failed");
570       return NULL;
571     }
572   }
573   catch (Standard_Failure& aFail) {
574     SetErrorCode(aFail.GetMessageString());
575     return NULL;
576   }
577
578   //Make a Python command
579   GEOM::TPythonDump(aFunction) << aCopy << " = geompy.MakeMultiTranslation2D("
580     << theObject << ", " << theVector  << ", " << theStep1 << ", " << theNbTimes1
581       << ", " << theVector2 << ", " << theStep2 << ", " << theNbTimes2 << ")";
582
583   SetErrorCode(OK);
584   return aCopy;
585 }
586
587 //=============================================================================
588 /*!
589  *  TranslateShape1D
590  */
591 //=============================================================================
592 /*
593 TopoDS_Shape GEOMImpl_ITransformOperations::TranslateShape1D (const TopoDS_Shape&  theShape,
594                                                               GEOMImpl_ITranslate* theTI)
595 {
596   TopoDS_Shape aRes;
597
598   // Vector
599   Handle(GEOM_Function) aVector = theTI->GetVector();
600   if (aVector.IsNull()) {
601     StdFail_NotDone::Raise("Invalid object is given for vector argument");
602   }
603   TopoDS_Shape aV = aVector->GetValue();
604   if (aV.IsNull() || aV.ShapeType() != TopAbs_EDGE) {
605     StdFail_NotDone::Raise("Invalid object is given for vector argument");
606   }
607   TopoDS_Edge anEdge = TopoDS::Edge(aV);
608
609   gp_Pnt aP1 = BRep_Tool::Pnt(TopExp::FirstVertex(anEdge));
610   gp_Pnt aP2 = BRep_Tool::Pnt(TopExp::LastVertex(anEdge));
611   if (aP1.Distance(aP2) < gp::Resolution()) {
612     StdFail_NotDone::Raise("Invalid object is given for vector argument");
613   }
614
615   // Step and Nb.times
616   Standard_Real step = theTI->GetStep1();
617   Standard_Integer nbtimes = theTI->GetNbIter1();
618
619   // Make multi-translation
620   gp_Trsf aTrsf;
621   gp_Vec aVec;
622   TopoDS_Compound aCompound;
623   BRep_Builder B;
624   B.MakeCompound(aCompound);
625
626   gp_Vec Vec (aP1, aP2);
627   Vec.Normalize();
628
629   TopLoc_Location aLocOrig = theShape.Location();
630   gp_Trsf aTrsfOrig = aLocOrig.Transformation();
631
632   for (int i = 0; i < nbtimes; i++) {
633     aVec = Vec * (i * step);
634     aTrsf.SetTranslation(aVec);
635     //NPAL18620: performance problem: multiple locations are accumulated
636     //           in shape and need a great time to process
637     //BRepBuilderAPI_Transform aTransformation(theShape, aTrsf, Standard_False);
638     //B.Add(aCompound, aTransformation.Shape());
639     TopLoc_Location aLocRes (aTrsf * aTrsfOrig);
640     B.Add(aCompound, theShape.Located(aLocRes));
641   }
642   aRes = aCompound;
643
644   return aRes;
645 }
646 */
647
648 //=============================================================================
649 /*!
650  *  TranslateShape2D
651  */
652 //=============================================================================
653 /*
654 TopoDS_Shape GEOMImpl_ITransformOperations::TranslateShape2D (const TopoDS_Shape&  theShape,
655                                                               GEOMImpl_ITranslate* theTI)
656 {
657   TopoDS_Shape aRes;
658
659   // Vectors
660   Handle(GEOM_Function) aVector1 = theTI->GetVector();
661   Handle(GEOM_Function) aVector2 = theTI->GetVector2();
662
663   if (aVector1.IsNull() || aVector2.IsNull()) {
664     StdFail_NotDone::Raise("Invalid object is given for vector argument");
665   }
666
667   TopoDS_Shape aV1 = aVector1->GetValue();
668   TopoDS_Shape aV2 = aVector2->GetValue();
669
670   if (aV1.IsNull() || aV1.ShapeType() != TopAbs_EDGE ||
671       aV2.IsNull() || aV2.ShapeType() != TopAbs_EDGE) {
672     StdFail_NotDone::Raise("Invalid object is given for vector argument");
673   }
674
675   TopoDS_Edge anEdge1 = TopoDS::Edge(aV1);
676   TopoDS_Edge anEdge2 = TopoDS::Edge(aV2);
677
678   gp_Pnt aP11 = BRep_Tool::Pnt(TopExp::FirstVertex(anEdge1));
679   gp_Pnt aP12 = BRep_Tool::Pnt(TopExp::LastVertex(anEdge1));
680   gp_Pnt aP21 = BRep_Tool::Pnt(TopExp::FirstVertex(anEdge2));
681   gp_Pnt aP22 = BRep_Tool::Pnt(TopExp::LastVertex(anEdge2));
682
683   if (aP11.Distance(aP12) < gp::Resolution() ||
684       aP21.Distance(aP22) < gp::Resolution()) {
685     StdFail_NotDone::Raise("Invalid object is given for vector argument");
686   }
687
688   gp_Vec Vec1 (aP11, aP12);
689   gp_Vec Vec2 (aP21, aP22);
690
691   Vec1.Normalize();
692   Vec2.Normalize();
693
694   // Step and Nb.times
695   Standard_Real step1 = theTI->GetStep1(), step2 = theTI->GetStep2();
696   Standard_Integer nbtimes1 = theTI->GetNbIter1(), nbtimes2 = theTI->GetNbIter2();
697
698   // Make multi-translation
699   gp_Trsf aTrsf;
700   gp_Vec aVec;
701   Standard_Real DX, DY, DZ;
702   TopoDS_Compound aCompound;
703   BRep_Builder B;
704   B.MakeCompound(aCompound);
705
706   TopLoc_Location aLocOrig = theShape.Location();
707   gp_Trsf aTrsfOrig = aLocOrig.Transformation();
708
709   for (int i = 0; i < nbtimes1; i++) {
710     for (int j = 0; j < nbtimes2; j++) {
711       DX = i * step1 * Vec1.X() + j * step2 * Vec2.X();
712       DY = i * step1 * Vec1.Y() + j * step2 * Vec2.Y();
713       DZ = i * step1 * Vec1.Z() + j * step2 * Vec2.Z();
714       aVec.SetCoord(DX, DY, DZ);
715       aTrsf.SetTranslation(aVec);
716       //NPAL18620: performance problem: multiple locations are accumulated
717       //           in shape and need a great time to process
718       //BRepBuilderAPI_Transform aBRepTransformation(theShape, aTrsf, Standard_False);
719       //B.Add(aCompound, aBRepTransformation.Shape());
720       TopLoc_Location aLocRes (aTrsf * aTrsfOrig);
721       B.Add(aCompound, theShape.Located(aLocRes));
722     }
723   }
724   aRes = aCompound;
725
726   return aRes;
727 }
728 */
729
730 //=============================================================================
731 /*!
732  *  MirrorPlane
733  */
734 //=============================================================================
735 Handle(GEOM_Object) GEOMImpl_ITransformOperations::MirrorPlane
736        (Handle(GEOM_Object) theObject, Handle(GEOM_Object) thePlane)
737 {
738   SetErrorCode(KO);
739
740   if (theObject.IsNull() || thePlane.IsNull()) return NULL;
741
742   Handle(GEOM_Function) aLastFunction = theObject->GetLastFunction();
743   if (aLastFunction.IsNull()) return NULL;  //There is no function which creates an object to be mirrored
744
745   // Get last functions of the arguments
746   Handle(GEOM_Function) aPF = thePlane->GetLastFunction();
747
748   //Add a mirror function
749   Handle(GEOM_Function) aFunction =
750     theObject->AddFunction(GEOMImpl_MirrorDriver::GetID(), MIRROR_PLANE);
751   if (aFunction.IsNull()) return NULL;
752
753   //Check if the function is set correctly
754   if (aFunction->GetDriverGUID() != GEOMImpl_MirrorDriver::GetID()) return NULL;
755
756   GEOMImpl_IMirror aTI (aFunction);
757   aTI.SetPlane(aPF);
758   aTI.SetOriginal(aLastFunction);
759
760   //Compute the mirror
761   try {
762     OCC_CATCH_SIGNALS;
763     if (!GetSolver()->ComputeFunction(aFunction)) {
764       SetErrorCode("Mirror driver failed");
765       return NULL;
766     }
767   }
768   catch (Standard_Failure& aFail) {
769     SetErrorCode(aFail.GetMessageString());
770     return NULL;
771   }
772
773   //Make a Python command
774   GEOM::TPythonDump(aFunction) << "geompy.MirrorByPlane("
775                                << theObject << ", " << thePlane << ")";
776
777   SetErrorCode(OK);
778   return theObject;
779 }
780
781 //=============================================================================
782 /*!
783  *  MirrorPlaneCopy
784  */
785 //=============================================================================
786 Handle(GEOM_Object) GEOMImpl_ITransformOperations::MirrorPlaneCopy
787        (Handle(GEOM_Object) theObject, Handle(GEOM_Object) thePlane)
788 {
789   SetErrorCode(KO);
790
791   if (theObject.IsNull() || thePlane.IsNull()) return NULL;
792
793   Handle(GEOM_Function) aLastFunction = theObject->GetLastFunction();
794   if (aLastFunction.IsNull()) return NULL; //There is no function which creates an object to be mirrored
795
796   //Add a new Copy object
797   Handle(GEOM_Object) aCopy = GetEngine()->AddObject(GEOM_COPY);
798
799   //Add a mirror function
800   Handle(GEOM_Function) aFunction =
801     aCopy->AddFunction(GEOMImpl_MirrorDriver::GetID(), MIRROR_PLANE_COPY);
802
803   //Check if the function is set correctly
804   if (aFunction->GetDriverGUID() != GEOMImpl_MirrorDriver::GetID()) return NULL;
805
806   GEOMImpl_IMirror aTI (aFunction);
807   aTI.SetPlane(thePlane->GetLastFunction());
808   aTI.SetOriginal(aLastFunction);
809
810   //Compute the mirror
811   try {
812     OCC_CATCH_SIGNALS;
813     if (!GetSolver()->ComputeFunction(aFunction)) {
814       SetErrorCode("Mirror driver failed");
815       return NULL;
816     }
817   }
818   catch (Standard_Failure& aFail) {
819     SetErrorCode(aFail.GetMessageString());
820     return NULL;
821   }
822
823   //Make a Python command
824   GEOM::TPythonDump(aFunction) << aCopy << " = geompy.MakeMirrorByPlane("
825                                << theObject << ", " << thePlane << ")";
826
827   SetErrorCode(OK);
828   return aCopy;
829 }
830
831 //=============================================================================
832 /*!
833  *  MirrorPoint
834  */
835 //=============================================================================
836 Handle(GEOM_Object) GEOMImpl_ITransformOperations::MirrorPoint
837        (Handle(GEOM_Object) theObject, Handle(GEOM_Object) thePoint)
838 {
839   SetErrorCode(KO);
840
841   if (theObject.IsNull() || thePoint.IsNull()) return NULL;
842
843   Handle(GEOM_Function) aLastFunction = theObject->GetLastFunction();
844   if (aLastFunction.IsNull()) return NULL;  //There is no function which creates an object to be mirrored
845
846   // Get last functions of the arguments
847   Handle(GEOM_Function) aPF = thePoint->GetLastFunction();
848
849   //Add a mirror function
850   Handle(GEOM_Function) aFunction =
851     theObject->AddFunction(GEOMImpl_MirrorDriver::GetID(), MIRROR_POINT);
852   if (aFunction.IsNull()) return NULL;
853
854   //Check if the function is set correctly
855   if (aFunction->GetDriverGUID() != GEOMImpl_MirrorDriver::GetID()) return NULL;
856
857   GEOMImpl_IMirror aTI (aFunction);
858   aTI.SetPoint(aPF);
859   aTI.SetOriginal(aLastFunction);
860
861   //Compute the mirror
862   try {
863     OCC_CATCH_SIGNALS;
864     if (!GetSolver()->ComputeFunction(aFunction)) {
865       SetErrorCode("Mirror driver failed");
866       return NULL;
867     }
868   }
869   catch (Standard_Failure& aFail) {
870     SetErrorCode(aFail.GetMessageString());
871     return NULL;
872   }
873
874   //Make a Python command
875   GEOM::TPythonDump(aFunction) << "geompy.MirrorByPoint("
876                                << theObject << ", " << thePoint << ")";
877
878   SetErrorCode(OK);
879   return NULL;
880 }
881
882 //=============================================================================
883 /*!
884  *  MirrorPointCopy
885  */
886 //=============================================================================
887 Handle(GEOM_Object) GEOMImpl_ITransformOperations::MirrorPointCopy
888        (Handle(GEOM_Object) theObject, Handle(GEOM_Object) thePoint)
889 {
890   SetErrorCode(KO);
891
892   if (theObject.IsNull() || thePoint.IsNull()) return NULL;
893
894   Handle(GEOM_Function) aLastFunction = theObject->GetLastFunction();
895   if (aLastFunction.IsNull()) return NULL; //There is no function which creates an object to be mirrored
896
897   //Add a new Copy object
898   Handle(GEOM_Object) aCopy = GetEngine()->AddObject(GEOM_COPY);
899
900   //Add a mirror function
901   Handle(GEOM_Function) aFunction =
902     aCopy->AddFunction(GEOMImpl_MirrorDriver::GetID(), MIRROR_POINT_COPY);
903
904   //Check if the function is set correctly
905   if (aFunction->GetDriverGUID() != GEOMImpl_MirrorDriver::GetID()) return NULL;
906
907   GEOMImpl_IMirror aTI (aFunction);
908   aTI.SetPoint(thePoint->GetLastFunction());
909   aTI.SetOriginal(aLastFunction);
910
911   //Compute the mirror
912   try {
913     OCC_CATCH_SIGNALS;
914     if (!GetSolver()->ComputeFunction(aFunction)) {
915       SetErrorCode("Mirror driver failed");
916       return NULL;
917     }
918   }
919   catch (Standard_Failure& aFail) {
920     SetErrorCode(aFail.GetMessageString());
921     return NULL;
922   }
923
924   //Make a Python command
925   GEOM::TPythonDump(aFunction) << aCopy << " = geompy.MakeMirrorByPoint("
926                                << theObject << ", " << thePoint << ")";
927
928   SetErrorCode(OK);
929   return aCopy;
930 }
931
932 //=============================================================================
933 /*!
934  *  MirrorAxis
935  */
936 //=============================================================================
937 Handle(GEOM_Object) GEOMImpl_ITransformOperations::MirrorAxis
938        (Handle(GEOM_Object) theObject, Handle(GEOM_Object) theAxis)
939 {
940   SetErrorCode(KO);
941
942   if (theObject.IsNull() || theAxis.IsNull()) return NULL;
943
944   Handle(GEOM_Function) aLastFunction = theObject->GetLastFunction();
945   if (aLastFunction.IsNull()) return NULL;  //There is no function which creates an object to be mirrored
946
947   // Get last functions of the arguments
948   Handle(GEOM_Function) anAF = theAxis->GetLastFunction();
949
950   //Add a mirror function
951   Handle(GEOM_Function) aFunction =
952     theObject->AddFunction(GEOMImpl_MirrorDriver::GetID(), MIRROR_AXIS);
953   if (aFunction.IsNull()) return NULL;
954
955   //Check if the function is set correctly
956   if (aFunction->GetDriverGUID() != GEOMImpl_MirrorDriver::GetID()) return NULL;
957
958   GEOMImpl_IMirror aTI (aFunction);
959   aTI.SetAxis(anAF);
960   aTI.SetOriginal(aLastFunction);
961
962   //Compute the mirror
963   try {
964     OCC_CATCH_SIGNALS;
965     if (!GetSolver()->ComputeFunction(aFunction)) {
966       SetErrorCode("Mirror driver failed");
967       return NULL;
968     }
969   }
970   catch (Standard_Failure& aFail) {
971     SetErrorCode(aFail.GetMessageString());
972     return NULL;
973   }
974
975   //Make a Python command
976   GEOM::TPythonDump(aFunction) << "geompy.MirrorByAxis("
977                                << theObject << ", " << theAxis << ")";
978
979   SetErrorCode(OK);
980   return NULL;
981 }
982
983 //=============================================================================
984 /*!
985  *  MirrorAxisCopy
986  */
987 //=============================================================================
988 Handle(GEOM_Object) GEOMImpl_ITransformOperations::MirrorAxisCopy
989        (Handle(GEOM_Object) theObject, Handle(GEOM_Object) theAxis)
990 {
991   SetErrorCode(KO);
992
993   if (theObject.IsNull() || theAxis.IsNull()) return NULL;
994
995   Handle(GEOM_Function) aLastFunction = theObject->GetLastFunction();
996   if (aLastFunction.IsNull()) return NULL; //There is no function which creates an object to be mirrored
997
998   //Add a new Copy object
999   Handle(GEOM_Object) aCopy = GetEngine()->AddObject(GEOM_COPY);
1000
1001   //Add a mirror function
1002   Handle(GEOM_Function) aFunction =
1003     aCopy->AddFunction(GEOMImpl_MirrorDriver::GetID(), MIRROR_AXIS_COPY);
1004
1005   //Check if the function is set correctly
1006   if (aFunction->GetDriverGUID() != GEOMImpl_MirrorDriver::GetID()) return NULL;
1007
1008   GEOMImpl_IMirror aTI (aFunction);
1009   aTI.SetAxis(theAxis->GetLastFunction());
1010   aTI.SetOriginal(aLastFunction);
1011
1012   //Compute the mirror
1013   try {
1014     OCC_CATCH_SIGNALS;
1015     if (!GetSolver()->ComputeFunction(aFunction)) {
1016       SetErrorCode("Mirror driver failed");
1017       return NULL;
1018     }
1019   }
1020   catch (Standard_Failure& aFail) {
1021     SetErrorCode(aFail.GetMessageString());
1022     return NULL;
1023   }
1024
1025   //Make a Python command
1026   GEOM::TPythonDump(aFunction) << aCopy << " = geompy.MakeMirrorByAxis("
1027                                << theObject << ", " << theAxis << ")";
1028
1029   SetErrorCode(OK);
1030   return aCopy;
1031 }
1032
1033
1034 //=============================================================================
1035 /*!
1036  *  OffsetShape
1037  */
1038 //=============================================================================
1039 Handle(GEOM_Object)
1040 GEOMImpl_ITransformOperations::OffsetShape (Handle(GEOM_Object) theObject,
1041                                             double              theOffset,
1042                                             bool                theJoinByPipes)
1043 {
1044   SetErrorCode(KO);
1045
1046   if (theObject.IsNull()) return NULL;
1047
1048   Handle(GEOM_Function) anOriginal = theObject->GetLastFunction();
1049   if (anOriginal.IsNull()) return NULL; //There is no function which creates an object to be offset
1050
1051   //Add a new Offset function
1052   Handle(GEOM_Function) aFunction =
1053     theObject->AddFunction(GEOMImpl_OffsetDriver::GetID(), OFFSET_SHAPE);
1054   if (aFunction.IsNull()) return NULL;
1055
1056   //Check if the function is set correctly
1057   if (aFunction->GetDriverGUID() != GEOMImpl_OffsetDriver::GetID()) return NULL;
1058
1059   GEOMImpl_IOffset aTI (aFunction);
1060   aTI.SetShape( anOriginal );
1061   aTI.SetValue( theOffset );
1062   aTI.SetJoinByPipes( theJoinByPipes );
1063
1064   //Compute the offset
1065   try {
1066     OCC_CATCH_SIGNALS;
1067     if (!GetSolver()->ComputeFunction(aFunction)) {
1068       SetErrorCode("Offset driver failed");
1069       return NULL;
1070     }
1071   }
1072   catch (Standard_Failure& aFail) {
1073     SetErrorCode(aFail.GetMessageString());
1074     return NULL;
1075   }
1076
1077   //Make a Python command
1078   if (theJoinByPipes)
1079     GEOM::TPythonDump(aFunction) << "geompy.Offset("
1080                                  << theObject << ", " << theOffset << ")";
1081   else
1082     GEOM::TPythonDump(aFunction) << theObject << " = geompy.MakeOffsetIntersectionJoin("
1083                                  << theObject << ", " << theOffset << ")";
1084
1085   SetErrorCode(OK);
1086   return theObject;
1087 }
1088
1089 //=============================================================================
1090 /*!
1091  *  OffsetShapeCopy
1092  */
1093 //=============================================================================
1094 Handle(GEOM_Object)
1095 GEOMImpl_ITransformOperations::OffsetShapeCopy( Handle(GEOM_Object) theObject,
1096                                                 double              theOffset,
1097                                                 bool                theJoinByPipes)
1098 {
1099   SetErrorCode(KO);
1100
1101   if (theObject.IsNull()) return NULL;
1102
1103   Handle(GEOM_Function) anOriginal = theObject->GetLastFunction();
1104   if (anOriginal.IsNull()) return NULL; //There is no function which creates an object to be offset
1105
1106   //Add a new Copy object
1107   Handle(GEOM_Object) aCopy = GetEngine()->AddObject(GEOM_COPY);
1108
1109   //Add a new Offset function
1110   Handle(GEOM_Function) aFunction =
1111     aCopy->AddFunction(GEOMImpl_OffsetDriver::GetID(), OFFSET_SHAPE_COPY);
1112   if (aFunction.IsNull()) return NULL;
1113
1114   //Check if the function is set correctly
1115   if (aFunction->GetDriverGUID() != GEOMImpl_OffsetDriver::GetID()) return NULL;
1116
1117   GEOMImpl_IOffset aTI (aFunction);
1118   aTI.SetShape( anOriginal );
1119   aTI.SetValue( theOffset );
1120   aTI.SetJoinByPipes( theJoinByPipes );
1121
1122   //Compute the offset
1123   try {
1124     OCC_CATCH_SIGNALS;
1125     if (!GetSolver()->ComputeFunction(aFunction)) {
1126       SetErrorCode("Offset driver failed");
1127       return NULL;
1128     }
1129   }
1130   catch (Standard_Failure& aFail) {
1131     SetErrorCode(aFail.GetMessageString());
1132     return NULL;
1133   }
1134
1135   //Make a Python command
1136   if (theJoinByPipes)
1137     GEOM::TPythonDump(aFunction) << aCopy << " = geompy.MakeOffset("
1138                                  << theObject << ", " << theOffset << ")";
1139   else
1140     GEOM::TPythonDump(aFunction) << aCopy << " = geompy.MakeOffsetIntersectionJoin("
1141                                  << theObject << ", " << theOffset << ")";
1142
1143   SetErrorCode(OK);
1144   return aCopy;
1145 }
1146
1147
1148 //=============================================================================
1149 /*!
1150  *  ProjectShapeCopy
1151  */
1152 //=============================================================================
1153 Handle(GEOM_Object)
1154 GEOMImpl_ITransformOperations::ProjectShapeCopy (Handle(GEOM_Object) theSource,
1155                                                  Handle(GEOM_Object) theTarget)
1156 {
1157   SetErrorCode(KO);
1158
1159   if (theSource.IsNull() || theTarget.IsNull()) return NULL;
1160
1161   Handle(GEOM_Function) aLastFunction = theSource->GetLastFunction();
1162   if (aLastFunction.IsNull()) return NULL; //There is no function which creates an object to be projected
1163
1164   Handle(GEOM_Object) aCopy;
1165
1166   TopoDS_Shape aTarget = theTarget->GetValue();
1167   if ( aTarget.IsNull() ) return NULL;
1168   if ( aTarget.ShapeType() == TopAbs_EDGE ||
1169        aTarget.ShapeType() == TopAbs_WIRE )
1170   {
1171     // a TPythonDump prevents dumping ProjectPointOnWire(),
1172     // dump of MakeProjection() is done at the end of this function
1173     GEOM::TPythonDump preventDump(aLastFunction, /*append=*/true);
1174     Standard_Integer dummy;
1175     ProjectPointOnWire( theSource, theTarget, aCopy, dummy );
1176     if ( aCopy.IsNull() || !IsDone() )
1177       return NULL;
1178   }
1179   else
1180   {
1181     //Add a new Projection object
1182     aCopy = GetEngine()->AddObject(GEOM_PROJECTION);
1183
1184     //Add a Projection function
1185     Handle(GEOM_Function) aFunction =
1186       aCopy->AddFunction(GEOMImpl_ProjectionDriver::GetID(), PROJECTION_COPY);
1187
1188     //Check if the function is set correctly
1189     if (aFunction->GetDriverGUID() != GEOMImpl_ProjectionDriver::GetID()) return NULL;
1190
1191     GEOMImpl_IMirror aTI (aFunction);
1192     aTI.SetPlane(theTarget->GetLastFunction());
1193     aTI.SetOriginal(aLastFunction);
1194
1195     //Compute the Projection
1196     try {
1197       OCC_CATCH_SIGNALS;
1198       if (!GetSolver()->ComputeFunction(aFunction)) {
1199         SetErrorCode("Projection driver failed");
1200         return NULL;
1201       }
1202     }
1203     catch (Standard_Failure& aFail) {
1204       SetErrorCode(aFail.GetMessageString());
1205       return NULL;
1206     }
1207   }
1208
1209   //Make a Python command
1210   Handle(GEOM_Function) aFunction = aCopy->GetLastFunction();
1211   GEOM::TPythonDump(aFunction) << aCopy << " = geompy.MakeProjection("
1212                                << theSource << ", " << theTarget << ")";
1213
1214   SetErrorCode(OK);
1215   return aCopy;
1216 }
1217
1218 //=============================================================================
1219 /*!
1220  *  ProjectPointOnWire
1221  */
1222 //=============================================================================
1223 Standard_Real GEOMImpl_ITransformOperations::ProjectPointOnWire
1224                                     (Handle(GEOM_Object) thePoint,
1225                                      Handle(GEOM_Object) theWire,
1226                                      Handle(GEOM_Object) &thePointOnEdge,
1227                                      Standard_Integer    &theEdgeInWireIndex)
1228 {
1229   Standard_Real aResult = -1.;
1230
1231   SetErrorCode(KO);
1232
1233   if (thePoint.IsNull() || theWire.IsNull()) {
1234     return aResult;
1235   }
1236
1237   Handle(GEOM_Function) aLastFunction = thePoint->GetLastFunction();
1238
1239   if (aLastFunction.IsNull()) {
1240     //There is no function which creates an object to be projected
1241     return aResult;
1242   }
1243
1244   //Add a new Projection object
1245   thePointOnEdge = GetEngine()->AddObject(GEOM_PROJECTION);
1246
1247   //Add a Projection function
1248   Handle(GEOM_Function) aFunction = thePointOnEdge->AddFunction
1249     (GEOMImpl_ProjectionDriver::GetID(), PROJECTION_ON_WIRE);
1250
1251   //Check if the function is set correctly
1252   if (aFunction->GetDriverGUID() != GEOMImpl_ProjectionDriver::GetID()) {
1253     return aResult;
1254   }
1255
1256   GEOMImpl_IProjection aProj (aFunction);
1257   aProj.SetPoint(aLastFunction);
1258   aProj.SetShape(theWire->GetLastFunction());
1259
1260   //Compute the Projection
1261   try {
1262     OCC_CATCH_SIGNALS;
1263     if (!GetSolver()->ComputeFunction(aFunction)) {
1264       SetErrorCode("Projection driver failed");
1265       return aResult;
1266     }
1267   }
1268   catch (Standard_Failure& aFail) {
1269     SetErrorCode(aFail.GetMessageString());
1270     return aResult;
1271   }
1272
1273   aResult            = aProj.GetU();
1274   theEdgeInWireIndex = aProj.GetIndex();
1275
1276
1277   //Make a Python command
1278   GEOM::TPythonDump(aFunction) << "(u, " << thePointOnEdge
1279     << ", EdgeInWireIndex) = geompy.MakeProjectionOnWire(" << thePoint
1280     << ", " << theWire << ")";
1281
1282   SetErrorCode(OK);
1283
1284   return aResult;
1285 }
1286
1287 //=============================================================================
1288 /*!
1289  *  ScaleShape
1290  */
1291 //=============================================================================
1292 Handle(GEOM_Object) GEOMImpl_ITransformOperations::ScaleShape
1293        (Handle(GEOM_Object) theObject, Handle(GEOM_Object) thePoint, double theFactor)
1294 {
1295   SetErrorCode(KO);
1296
1297   if (theObject.IsNull()) return NULL;
1298
1299   Handle(GEOM_Function) anOriginal = theObject->GetLastFunction();
1300   if (anOriginal.IsNull()) return NULL; //There is no function which creates an object to be scaled
1301
1302   //Add a scale function
1303   Handle(GEOM_Function) aFunction =
1304     theObject->AddFunction(GEOMImpl_ScaleDriver::GetID(), SCALE_SHAPE);
1305   if (aFunction.IsNull()) return NULL;
1306
1307   //Check if the function is set correctly
1308   if (aFunction->GetDriverGUID() != GEOMImpl_ScaleDriver::GetID()) return NULL;
1309
1310   // Set arguments
1311   GEOMImpl_IScale aTI (aFunction);
1312   aTI.SetShape(anOriginal);
1313   aTI.SetFactor(theFactor);
1314
1315   // Set point argument
1316   if (!thePoint.IsNull()) {
1317     Handle(GEOM_Function) aPF = thePoint->GetLastFunction();
1318     aTI.SetPoint(aPF);
1319   }
1320
1321   //Compute the scale
1322   try {
1323     OCC_CATCH_SIGNALS;
1324     if (!GetSolver()->ComputeFunction(aFunction)) {
1325       SetErrorCode("Scale driver failed");
1326       return NULL;
1327     }
1328   }
1329   catch (Standard_Failure& aFail) {
1330     SetErrorCode(aFail.GetMessageString());
1331     return NULL;
1332   }
1333
1334   //Make a Python command
1335   GEOM::TPythonDump(aFunction) << "geompy.Scale("
1336     << theObject << ", " << thePoint << ", " << theFactor << ")";
1337
1338   SetErrorCode(OK);
1339   return theObject;
1340 }
1341
1342 //=============================================================================
1343 /*!
1344  *  ScaleShapeCopy
1345  */
1346 //=============================================================================
1347 Handle(GEOM_Object) GEOMImpl_ITransformOperations::ScaleShapeCopy
1348        (Handle(GEOM_Object) theObject, Handle(GEOM_Object) thePoint, double theFactor)
1349 {
1350   SetErrorCode(KO);
1351
1352   if (theObject.IsNull()) return NULL;
1353
1354   Handle(GEOM_Function) anOriginal = theObject->GetLastFunction();
1355   if (anOriginal.IsNull()) return NULL; //There is no function which creates an object to be scaled
1356
1357   //Add a new Copy object
1358   Handle(GEOM_Object) aCopy = GetEngine()->AddObject(GEOM_COPY);
1359
1360   //Add a scale function
1361   Handle(GEOM_Function) aFunction =
1362     aCopy->AddFunction(GEOMImpl_ScaleDriver::GetID(), SCALE_SHAPE_COPY);
1363   if (aFunction.IsNull()) return NULL;
1364
1365   //Check if the function is set correctly
1366   if (aFunction->GetDriverGUID() != GEOMImpl_ScaleDriver::GetID()) return NULL;
1367
1368   // Set arguments
1369   GEOMImpl_IScale aTI (aFunction);
1370   aTI.SetShape(anOriginal);
1371   aTI.SetFactor(theFactor);
1372
1373   // Set point argument
1374   if (!thePoint.IsNull()) {
1375     Handle(GEOM_Function) aPF = thePoint->GetLastFunction();
1376     aTI.SetPoint(aPF);
1377   }
1378
1379   //Compute the scale
1380   try {
1381     OCC_CATCH_SIGNALS;
1382     if (!GetSolver()->ComputeFunction(aFunction)) {
1383       SetErrorCode("Scale driver failed");
1384       return NULL;
1385     }
1386   }
1387   catch (Standard_Failure& aFail) {
1388     SetErrorCode(aFail.GetMessageString());
1389     return NULL;
1390   }
1391
1392   //Make a Python command
1393   GEOM::TPythonDump(aFunction) << aCopy << " = geompy.MakeScaleTransform("
1394     << theObject << ", " << thePoint << ", " << theFactor << ")";
1395
1396   SetErrorCode(OK);
1397   return aCopy;
1398 }
1399
1400 //=============================================================================
1401 /*!
1402  *  ScaleShapeAlongAxes
1403  */
1404 //=============================================================================
1405 Handle(GEOM_Object) GEOMImpl_ITransformOperations::ScaleShapeAlongAxes (Handle(GEOM_Object) theObject,
1406                                                                         Handle(GEOM_Object) thePoint,
1407                                                                         double theFactorX,
1408                                                                         double theFactorY,
1409                                                                         double theFactorZ,
1410                                                                         bool   doCopy)
1411 {
1412   SetErrorCode(KO);
1413
1414   if (theObject.IsNull()) return NULL;
1415
1416   Handle(GEOM_Function) anOriginal = theObject->GetLastFunction();
1417   if (anOriginal.IsNull()) return NULL; //There is no function which creates an object to be scaled
1418
1419   //Add a scale function
1420   Handle(GEOM_Object) aCopy;   //Add a new Copy object
1421   Handle(GEOM_Function) aFunction;
1422   if (doCopy) {
1423     aCopy = GetEngine()->AddObject(theObject->GetType());
1424     aFunction = aCopy->AddFunction(GEOMImpl_ScaleDriver::GetID(), SCALE_SHAPE_AXES_COPY);
1425   }
1426   else {
1427     aFunction = theObject->AddFunction(GEOMImpl_ScaleDriver::GetID(), SCALE_SHAPE_AXES);
1428   }
1429   if (aFunction.IsNull()) return NULL;
1430
1431   //Check if the function is set correctly
1432   if (aFunction->GetDriverGUID() != GEOMImpl_ScaleDriver::GetID()) return NULL;
1433
1434   // Set arguments
1435   GEOMImpl_IScale aTI (aFunction);
1436   aTI.SetShape(anOriginal);
1437   aTI.SetFactorX(theFactorX);
1438   aTI.SetFactorY(theFactorY);
1439   aTI.SetFactorZ(theFactorZ);
1440
1441   // Set point (optional argument)
1442   if (!thePoint.IsNull()) {
1443     Handle(GEOM_Function) aPF = thePoint->GetLastFunction();
1444     aTI.SetPoint(aPF);
1445   }
1446
1447   //Compute the scale
1448   try {
1449     OCC_CATCH_SIGNALS;
1450     if (!GetSolver()->ComputeFunction(aFunction)) {
1451       SetErrorCode("Scale driver failed");
1452       return NULL;
1453     }
1454   }
1455   catch (Standard_Failure& aFail) {
1456     SetErrorCode(aFail.GetMessageString());
1457     return NULL;
1458   }
1459
1460   SetErrorCode(OK);
1461
1462   //Make a Python command
1463   if (doCopy) {
1464     GEOM::TPythonDump(aFunction) << aCopy << " = geompy.MakeScaleAlongAxes("
1465                                  << theObject << ", " << thePoint << ", "
1466                                  << theFactorX << ", " << theFactorY << ", " << theFactorZ << ")";
1467     return aCopy;
1468   }
1469
1470   GEOM::TPythonDump(aFunction) << "geompy.ScaleAlongAxes("
1471                                << theObject << ", " << thePoint << ", "
1472                                << theFactorX << ", " << theFactorY << ", " << theFactorZ << ")";
1473   return theObject;
1474 }
1475
1476 //=============================================================================
1477 /*!
1478  *  PositionShape
1479  */
1480 //=============================================================================
1481 Handle(GEOM_Object) GEOMImpl_ITransformOperations::PositionShape
1482         (Handle(GEOM_Object) theObject, Handle(GEOM_Object) theStartLCS, Handle(GEOM_Object) theEndLCS)
1483 {
1484   SetErrorCode(KO);
1485
1486   if (theObject.IsNull() || theEndLCS.IsNull()) return NULL;
1487
1488   Handle(GEOM_Function) anOriginal = theObject->GetLastFunction();
1489   if (anOriginal.IsNull()) return NULL; //There is no function which creates an object to be set in position
1490
1491   //Add a Position function
1492   Standard_Integer aType = POSITION_SHAPE;
1493   if (theStartLCS.IsNull()) aType = POSITION_SHAPE_FROM_GLOBAL;
1494
1495   Handle(GEOM_Function) aFunction =
1496     theObject->AddFunction(GEOMImpl_PositionDriver::GetID(), aType);
1497   if (aFunction.IsNull()) return NULL;
1498
1499   //Check if the function is set correctly
1500   if (aFunction->GetDriverGUID() != GEOMImpl_PositionDriver::GetID()) return NULL;
1501
1502   //Set operation arguments
1503   GEOMImpl_IPosition aTI (aFunction);
1504   aTI.SetShape(anOriginal);
1505   aTI.SetEndLCS(theEndLCS->GetLastFunction());
1506   if (!theStartLCS.IsNull())
1507     aTI.SetStartLCS(theObject == theStartLCS ? anOriginal : theStartLCS->GetLastFunction());
1508
1509   //Compute the Position
1510   try {
1511     OCC_CATCH_SIGNALS;
1512     if (!GetSolver()->ComputeFunction(aFunction)) {
1513       SetErrorCode("Position driver failed");
1514       return NULL;
1515     }
1516   }
1517   catch (Standard_Failure& aFail) {
1518     SetErrorCode(aFail.GetMessageString());
1519     return NULL;
1520   }
1521
1522   //Make a Python command
1523   GEOM::TPythonDump(aFunction) << "geompy.Position("
1524     << theObject << ", " << theStartLCS << ", " << theEndLCS << ")";
1525
1526   SetErrorCode(OK);
1527   return theObject;
1528 }
1529
1530 //=============================================================================
1531 /*!
1532  *  PositionShapeCopy
1533  */
1534 //=============================================================================
1535 Handle(GEOM_Object) GEOMImpl_ITransformOperations::PositionShapeCopy
1536        (Handle(GEOM_Object) theObject, Handle(GEOM_Object) theStartLCS, Handle(GEOM_Object) theEndLCS)
1537 {
1538   SetErrorCode(KO);
1539
1540   if (theObject.IsNull() || theEndLCS.IsNull()) return NULL;
1541
1542   Handle(GEOM_Function) anOriginal = theObject->GetLastFunction();
1543   if (anOriginal.IsNull()) return NULL; //There is no function which creates an object to be set in position
1544
1545   //Add a new Copy object
1546   Handle(GEOM_Object) aCopy = GetEngine()->AddObject(GEOM_COPY);
1547
1548   //Add a position function
1549   Standard_Integer aType = POSITION_SHAPE_COPY;
1550   if (theStartLCS.IsNull()) aType = POSITION_SHAPE_FROM_GLOBAL_COPY;
1551
1552   Handle(GEOM_Function) aFunction =
1553     aCopy->AddFunction(GEOMImpl_PositionDriver::GetID(), aType);
1554   if (aFunction.IsNull()) return NULL;
1555
1556   //Check if the function is set correctly
1557   if (aFunction->GetDriverGUID() != GEOMImpl_PositionDriver::GetID()) return NULL;
1558
1559   GEOMImpl_IPosition aTI (aFunction);
1560   aTI.SetShape(anOriginal);
1561   aTI.SetEndLCS(theEndLCS->GetLastFunction());
1562   if (!theStartLCS.IsNull())
1563     aTI.SetStartLCS(theStartLCS->GetLastFunction());
1564
1565   //Compute the position
1566   try {
1567     OCC_CATCH_SIGNALS;
1568     if (!GetSolver()->ComputeFunction(aFunction)) {
1569       SetErrorCode("Position driver failed");
1570       return NULL;
1571     }
1572   }
1573   catch (Standard_Failure& aFail) {
1574     SetErrorCode(aFail.GetMessageString());
1575     return NULL;
1576   }
1577
1578   //Make a Python command
1579   GEOM::TPythonDump(aFunction) << aCopy << " = geompy.MakePosition("
1580     << theObject << ", " << theStartLCS << ", " << theEndLCS << ")";
1581
1582   SetErrorCode(OK);
1583   return aCopy;
1584 }
1585
1586 //=============================================================================
1587 /*!
1588  *  PositionAlongPath
1589  */
1590 //=============================================================================
1591 Handle(GEOM_Object) GEOMImpl_ITransformOperations::PositionAlongPath
1592        (Handle(GEOM_Object) theObject, Handle(GEOM_Object) thePath,
1593         double theDistance, bool theCopy, bool theReverse)
1594 {
1595   SetErrorCode(KO);
1596
1597   if (theObject.IsNull() || thePath.IsNull()) return NULL;
1598
1599   Handle(GEOM_Function) anOriginal = theObject->GetLastFunction();
1600   if (anOriginal.IsNull()) return NULL; //There is no function which creates an object to be set in position
1601
1602   //Add a position function
1603   Handle(GEOM_Function) aFunction;
1604   Handle(GEOM_Object) aCopy;
1605
1606   if (theCopy) {
1607     aCopy = GetEngine()->AddObject(theObject->GetType());
1608     aFunction = aCopy->AddFunction(GEOMImpl_PositionDriver::GetID(), POSITION_ALONG_PATH);
1609   }
1610   else
1611     aFunction = theObject->AddFunction(GEOMImpl_PositionDriver::GetID(), POSITION_ALONG_PATH);
1612
1613   if (aFunction.IsNull()) return NULL;
1614
1615   //Check if the function is set correctly
1616   if (aFunction->GetDriverGUID() != GEOMImpl_PositionDriver::GetID()) return NULL;
1617
1618   GEOMImpl_IPosition aTI (aFunction);
1619   aTI.SetShape(anOriginal);
1620   aTI.SetPath(thePath->GetLastFunction());
1621   aTI.SetDistance(theDistance);
1622   aTI.SetReverse(theReverse);
1623
1624   //Compute the position
1625   try {
1626     OCC_CATCH_SIGNALS;
1627     if (!GetSolver()->ComputeFunction(aFunction)) {
1628       SetErrorCode("Position driver failed");
1629       return NULL;
1630     }
1631   }
1632   catch (Standard_Failure& aFail) {
1633     SetErrorCode(aFail.GetMessageString());
1634     return NULL;
1635   }
1636
1637   //Make a Python command
1638   if (theCopy) {
1639     GEOM::TPythonDump(aFunction) << aCopy << " = geompy.MakePositionAlongPath("
1640                                  << theObject << ", " << thePath << ", " << theDistance << ", " << theCopy << ", " << theReverse << ")";
1641     SetErrorCode(OK);
1642     return aCopy;
1643   }
1644
1645   GEOM::TPythonDump(aFunction) << "geompy.PositionAlongPath("
1646     << theObject << ", " << thePath << ", " << theDistance << ", " << theCopy << ", " << theReverse << ")";
1647
1648   SetErrorCode(OK);
1649   return theObject;
1650 }
1651
1652 //=============================================================================
1653 /*!
1654  *  Rotate
1655  */
1656 //=============================================================================
1657 Handle(GEOM_Object) GEOMImpl_ITransformOperations::Rotate (Handle(GEOM_Object) theObject,
1658                                                            Handle(GEOM_Object) theAxis,
1659                                                            double theAngle)
1660 {
1661   SetErrorCode(KO);
1662
1663   if (theObject.IsNull() || theAxis.IsNull()) return NULL;
1664
1665   Handle(GEOM_Function) aFunction, aLastFunction = theObject->GetLastFunction();
1666   if (aLastFunction.IsNull()) return NULL;  //There is no function which creates an object to be rotated
1667
1668   // Get last functions of the arguments
1669   Handle(GEOM_Function) anAF = theAxis->GetLastFunction();
1670
1671   //Add a rotate function
1672   aFunction = theObject->AddFunction(GEOMImpl_RotateDriver::GetID(), ROTATE);
1673
1674   if (aFunction.IsNull()) return NULL;
1675
1676   //Check if the function is set correctly
1677   if (aFunction->GetDriverGUID() != GEOMImpl_RotateDriver::GetID()) return NULL;
1678
1679   GEOMImpl_IRotate aRI(aFunction);
1680   aRI.SetAxis(anAF);
1681   aRI.SetOriginal(aLastFunction);
1682   aRI.SetAngle(theAngle);
1683
1684   //Compute the translation
1685   try {
1686     OCC_CATCH_SIGNALS;
1687     if (!GetSolver()->ComputeFunction(aFunction)) {
1688       SetErrorCode("Rotate driver failed");
1689       return NULL;
1690     }
1691   }
1692   catch (Standard_Failure& aFail) {
1693     SetErrorCode(aFail.GetMessageString());
1694     return NULL;
1695   }
1696
1697   //Make a Python command
1698   GEOM::TPythonDump(aFunction) << "geompy.Rotate(" << theObject
1699     << ", " << theAxis << ", " << theAngle * 180.0 / M_PI << "*math.pi/180.0)";
1700
1701   SetErrorCode(OK);
1702   return theObject;
1703 }
1704
1705 //=============================================================================
1706 /*!
1707  *  RotateCopy
1708  */
1709 //=============================================================================
1710 Handle(GEOM_Object) GEOMImpl_ITransformOperations::RotateCopy (Handle(GEOM_Object) theObject,
1711                                                                Handle(GEOM_Object) theAxis,
1712                                                                double theAngle)
1713 {
1714   SetErrorCode(KO);
1715
1716   if (theObject.IsNull() || theAxis.IsNull()) return NULL;
1717
1718   Handle(GEOM_Function) aFunction, aLastFunction = theObject->GetLastFunction();
1719   if (aLastFunction.IsNull()) return NULL;  //There is no function which creates an object to be rotated
1720
1721   //Add a new Copy object
1722   Handle(GEOM_Object) aCopy = GetEngine()->AddObject(GEOM_COPY);
1723
1724   //Add a rotate function
1725   aFunction = aCopy->AddFunction(GEOMImpl_RotateDriver::GetID(), ROTATE_COPY);
1726   if (aFunction.IsNull()) return NULL;
1727
1728     //Check if the function is set correctly
1729   if (aFunction->GetDriverGUID() != GEOMImpl_RotateDriver::GetID()) return NULL;
1730
1731   GEOMImpl_IRotate aRI(aFunction);
1732   aRI.SetAxis(theAxis->GetLastFunction());
1733   aRI.SetOriginal(aLastFunction);
1734   aRI.SetAngle(theAngle);
1735
1736   //Compute the translation
1737   try {
1738     OCC_CATCH_SIGNALS;
1739     if (!GetSolver()->ComputeFunction(aFunction)) {
1740       SetErrorCode("Rotate driver failed");
1741       return NULL;
1742     }
1743   }
1744   catch (Standard_Failure& aFail) {
1745     SetErrorCode(aFail.GetMessageString());
1746     return NULL;
1747   }
1748
1749   //Make a Python command
1750   GEOM::TPythonDump(aFunction) << aCopy << " = geompy.MakeRotation(" << theObject
1751     << ", " << theAxis << ", " << theAngle * 180.0 / M_PI << "*math.pi/180.0)";
1752
1753   SetErrorCode(OK);
1754   return aCopy;
1755 }
1756
1757 //=============================================================================
1758 /*!
1759  *  Rotate1D (for MultiRotate1DNbTimes)
1760  */
1761 //=============================================================================
1762 Handle(GEOM_Object) GEOMImpl_ITransformOperations::Rotate1D (Handle(GEOM_Object) theObject,
1763                                                              Handle(GEOM_Object) theAxis,
1764                                                              Standard_Integer theNbTimes)
1765 {
1766   SetErrorCode(KO);
1767
1768   if (theObject.IsNull()) return NULL;
1769
1770   Handle(GEOM_Function) aFunction, aLastFunction = theObject->GetLastFunction();
1771   if (aLastFunction.IsNull()) return NULL;  //There is no function which creates an object to be rotated
1772
1773   //Add a new Copy object
1774   Handle(GEOM_Object) aCopy = GetEngine()->AddObject(theObject->GetType());
1775
1776   //Add a rotate function
1777   aFunction = aCopy->AddFunction(GEOMImpl_RotateDriver::GetID(), ROTATE_1D);
1778   if (aFunction.IsNull()) return NULL;
1779
1780   //Check if the function is set correctly
1781   if (aFunction->GetDriverGUID() != GEOMImpl_RotateDriver::GetID()) return NULL;
1782
1783   GEOMImpl_IRotate aRI(aFunction);
1784   aRI.SetOriginal(aLastFunction);
1785   if (!theAxis.IsNull())
1786     aRI.SetAxis(theAxis->GetLastFunction());
1787   aRI.SetNbIter1(theNbTimes);
1788
1789   //Compute the translation
1790   try {
1791     OCC_CATCH_SIGNALS;
1792     if (!GetSolver()->ComputeFunction(aFunction)) {
1793       SetErrorCode("Rotate driver failed");
1794       return NULL;
1795     }
1796   }
1797   catch (Standard_Failure& aFail) {
1798     SetErrorCode(aFail.GetMessageString());
1799     return NULL;
1800   }
1801
1802   //Make a Python command
1803   GEOM::TPythonDump(aFunction) << aCopy << " = geompy.MultiRotate1DNbTimes("
1804     << theObject << ", " << theAxis << ", " << theNbTimes << ")";
1805
1806   SetErrorCode(OK);
1807   return aCopy;
1808 }
1809
1810 //=============================================================================
1811 /*!
1812  *  Rotate1D (for MultiRotate1DByStep)
1813  */
1814 //=============================================================================
1815 Handle(GEOM_Object) GEOMImpl_ITransformOperations::Rotate1D (Handle(GEOM_Object) theObject,
1816                                                              Handle(GEOM_Object) theAxis,
1817                                                              double theAngleStep,
1818                                                              Standard_Integer theNbSteps)
1819 {
1820   SetErrorCode(KO);
1821
1822   if (theObject.IsNull()) return NULL;
1823
1824   Handle(GEOM_Function) aFunction, aLastFunction = theObject->GetLastFunction();
1825   if (aLastFunction.IsNull()) return NULL;  //There is no function which creates an object to be rotated
1826
1827   //Add a new Copy object
1828   Handle(GEOM_Object) aCopy = GetEngine()->AddObject(theObject->GetType());
1829
1830   //Add a rotate function
1831   aFunction = aCopy->AddFunction(GEOMImpl_RotateDriver::GetID(), ROTATE_1D_STEP);
1832   if (aFunction.IsNull()) return NULL;
1833
1834   //Check if the function is set correctly
1835   if (aFunction->GetDriverGUID() != GEOMImpl_RotateDriver::GetID()) return NULL;
1836
1837   //Convert angle into degrees
1838   double anAngleStep = theAngleStep * 180. / M_PI;
1839
1840   GEOMImpl_IRotate aRI (aFunction);
1841   aRI.SetOriginal(aLastFunction);
1842   if (!theAxis.IsNull())
1843     aRI.SetAxis(theAxis->GetLastFunction());
1844   aRI.SetAngle(anAngleStep);
1845   aRI.SetNbIter1(theNbSteps);
1846
1847   //Compute the translation
1848   try {
1849     OCC_CATCH_SIGNALS;
1850     if (!GetSolver()->ComputeFunction(aFunction)) {
1851       SetErrorCode("Rotate driver failed");
1852       return NULL;
1853     }
1854   }
1855   catch (Standard_Failure& aFail) {
1856     SetErrorCode(aFail.GetMessageString());
1857     return NULL;
1858   }
1859
1860   //Make a Python command
1861   GEOM::TPythonDump(aFunction)
1862     << aCopy << " = geompy.MultiRotate1DByStep(" << theObject << ", "
1863     << theAxis << ", " << anAngleStep << "*math.pi/180.0, " << theNbSteps << ")";
1864
1865   SetErrorCode(OK);
1866   return aCopy;
1867 }
1868
1869 //=============================================================================
1870 /*!
1871  *  Rotate2D (for MultiRotate2DNbTimes)
1872  */
1873 //=============================================================================
1874 Handle(GEOM_Object) GEOMImpl_ITransformOperations::Rotate2D (Handle(GEOM_Object) theObject,
1875                                                              Handle(GEOM_Object) theAxis,
1876                                                              Standard_Integer theNbObjects,
1877                                                              double theRadialStep,
1878                                                              Standard_Integer theNbSteps)
1879 {
1880   SetErrorCode(KO);
1881
1882   if (theObject.IsNull()) return NULL;
1883
1884   Handle(GEOM_Function) aFunction, aLastFunction = theObject->GetLastFunction();
1885   if (aLastFunction.IsNull()) return NULL;  //There is no function which creates an object to be rotated
1886
1887   //Add a new Copy object
1888   Handle(GEOM_Object) aCopy = GetEngine()->AddObject(theObject->GetType());
1889
1890   //Add a rotate function
1891   aFunction = aCopy->AddFunction(GEOMImpl_RotateDriver::GetID(), ROTATE_2D);
1892   if (aFunction.IsNull()) return NULL;
1893
1894   //Check if the function is set correctly
1895   if (aFunction->GetDriverGUID() != GEOMImpl_RotateDriver::GetID()) return NULL;
1896
1897   double anAngle = 360. / (double)theNbObjects;
1898
1899   GEOMImpl_IRotate aRI (aFunction);
1900   aRI.SetOriginal(aLastFunction);
1901   if (!theAxis.IsNull())
1902     aRI.SetAxis(theAxis->GetLastFunction());
1903   aRI.SetAngle(anAngle);
1904   aRI.SetNbIter1(theNbObjects);
1905   aRI.SetStep(theRadialStep);
1906   aRI.SetNbIter2(theNbSteps);
1907
1908   //Compute the translation
1909   try {
1910     OCC_CATCH_SIGNALS;
1911     if (!GetSolver()->ComputeFunction(aFunction)) {
1912       SetErrorCode("Rotate driver failed");
1913       return NULL;
1914     }
1915   }
1916   catch (Standard_Failure& aFail) {
1917     SetErrorCode(aFail.GetMessageString());
1918     return NULL;
1919   }
1920
1921   //Make a Python command
1922   GEOM::TPythonDump(aFunction) << aCopy << " = geompy.MultiRotate2DNbTimes("
1923                                << theObject << ", " << theAxis << ", " << theNbObjects
1924                                << ", " << theRadialStep << ", " << theNbSteps << ")";
1925
1926   SetErrorCode(OK);
1927   return aCopy;
1928 }
1929
1930 //=============================================================================
1931 /*!
1932  *  Rotate2D (for MultiRotate2DByStep)
1933  */
1934 //=============================================================================
1935 Handle(GEOM_Object) GEOMImpl_ITransformOperations::Rotate2D (Handle(GEOM_Object) theObject,
1936                                                              Handle(GEOM_Object) theAxis,
1937                                                              double theAngleStep,
1938                                                              Standard_Integer theNbTimes1,
1939                                                              double theStep,
1940                                                              Standard_Integer theNbTimes2)
1941 {
1942   SetErrorCode(KO);
1943
1944   if (theObject.IsNull()) return NULL;
1945
1946   Handle(GEOM_Function) aFunction, aLastFunction = theObject->GetLastFunction();
1947   if (aLastFunction.IsNull()) return NULL; //There is no function which creates an object to be rotated
1948
1949   //Add a new Copy object
1950   Handle(GEOM_Object) aCopy = GetEngine()->AddObject(theObject->GetType());
1951
1952   //Add a rotate function
1953   aFunction = aCopy->AddFunction(GEOMImpl_RotateDriver::GetID(), ROTATE_2D);
1954   if (aFunction.IsNull()) return NULL;
1955
1956   //Check if the function is set correctly
1957   if (aFunction->GetDriverGUID() != GEOMImpl_RotateDriver::GetID()) return NULL;
1958
1959   //Convert angle into degrees
1960   double anAngleStep = theAngleStep * 180. / M_PI;
1961
1962   GEOMImpl_IRotate aRI (aFunction);
1963   aRI.SetOriginal(aLastFunction);
1964   if (!theAxis.IsNull())
1965     aRI.SetAxis(theAxis->GetLastFunction());
1966   aRI.SetAngle(anAngleStep);
1967   aRI.SetNbIter1(theNbTimes1);
1968   aRI.SetStep(theStep);
1969   aRI.SetNbIter2(theNbTimes2);
1970
1971   //Compute the translation
1972   try {
1973     OCC_CATCH_SIGNALS;
1974     if (!GetSolver()->ComputeFunction(aFunction)) {
1975       SetErrorCode("Rotate driver failed");
1976       return NULL;
1977     }
1978   }
1979   catch (Standard_Failure& aFail) {
1980     SetErrorCode(aFail.GetMessageString());
1981     return NULL;
1982   }
1983
1984   //Make a Python command
1985   GEOM::TPythonDump(aFunction)
1986     << aCopy << " = geompy.MultiRotate2DByStep(" << theObject << ", "
1987     << theAxis << ", " << anAngleStep << "*math.pi/180.0, "
1988     << theNbTimes1 << ", " << theStep << ", " << theNbTimes2 << ")";
1989
1990   SetErrorCode(OK);
1991   return aCopy;
1992 }
1993
1994 //=============================================================================
1995 /*!
1996  *  RotateThreePoints
1997  */
1998 //=============================================================================
1999 Handle(GEOM_Object) GEOMImpl_ITransformOperations::RotateThreePoints (Handle(GEOM_Object) theObject,
2000                                                                       Handle(GEOM_Object) theCentPoint,
2001                                                                       Handle(GEOM_Object) thePoint1,
2002                                                                       Handle(GEOM_Object) thePoint2)
2003 {
2004   SetErrorCode(KO);
2005
2006   if (theObject.IsNull() || theCentPoint.IsNull() || thePoint1.IsNull() || thePoint2.IsNull()) return NULL;
2007
2008   Handle(GEOM_Function) aFunction, aLastFunction = theObject->GetLastFunction();
2009   if (aLastFunction.IsNull()) return NULL; //There is no function which creates an object to be rotated
2010
2011   // Get last functions of the arguments
2012   Handle(GEOM_Function) aCPF = theCentPoint->GetLastFunction();
2013   Handle(GEOM_Function) aP1F = thePoint1->GetLastFunction();
2014   Handle(GEOM_Function) aP2F = thePoint2->GetLastFunction();
2015
2016
2017   //Add a rotate function
2018   aFunction = theObject->AddFunction(GEOMImpl_RotateDriver::GetID(), ROTATE_THREE_POINTS);
2019
2020   if (aFunction.IsNull()) return NULL;
2021
2022   //Check if the function is set correctly
2023   if (aFunction->GetDriverGUID() != GEOMImpl_RotateDriver::GetID()) return NULL;
2024
2025   GEOMImpl_IRotate aRI(aFunction);
2026   aRI.SetCentPoint(aCPF);
2027   aRI.SetPoint1(aP1F);
2028   aRI.SetPoint2(aP2F);
2029   aRI.SetOriginal(aLastFunction);
2030
2031   //Compute the translation
2032   try {
2033     OCC_CATCH_SIGNALS;
2034     if (!GetSolver()->ComputeFunction(aFunction)) {
2035       SetErrorCode("Rotate driver failed");
2036       return NULL;
2037     }
2038   }
2039   catch (Standard_Failure& aFail) {
2040     SetErrorCode(aFail.GetMessageString());
2041     return NULL;
2042   }
2043
2044   //Make a Python command
2045   GEOM::TPythonDump(aFunction) << "geompy.RotateThreePoints(" << theObject
2046                                << ", " << theCentPoint << ", "<<thePoint1 << ", " << thePoint2 << ")";
2047
2048   SetErrorCode(OK);
2049   return theObject;
2050 }
2051
2052 //=============================================================================
2053 /*!
2054  *  RotateThreePointsCopy
2055  */
2056 //=============================================================================
2057 Handle(GEOM_Object) GEOMImpl_ITransformOperations::RotateThreePointsCopy (Handle(GEOM_Object) theObject,
2058                                                          Handle(GEOM_Object) theCentPoint,
2059                                                          Handle(GEOM_Object) thePoint1,
2060                                                          Handle(GEOM_Object) thePoint2)
2061 {
2062   SetErrorCode(KO);
2063
2064   if (theObject.IsNull() || theCentPoint.IsNull() || thePoint1.IsNull() || thePoint2.IsNull()) return NULL;
2065
2066   Handle(GEOM_Function) aFunction, aLastFunction = theObject->GetLastFunction();
2067   if (aLastFunction.IsNull()) return NULL;  //There is no function which creates an object to be rotated
2068
2069   //Add a new Copy object
2070   Handle(GEOM_Object) aCopy = GetEngine()->AddObject(GEOM_COPY);
2071
2072   //Add a rotate function
2073   aFunction = aCopy->AddFunction(GEOMImpl_RotateDriver::GetID(), ROTATE_THREE_POINTS_COPY);
2074   if (aFunction.IsNull()) return NULL;
2075
2076     //Check if the function is set correctly
2077   if (aFunction->GetDriverGUID() != GEOMImpl_RotateDriver::GetID()) return NULL;
2078
2079   GEOMImpl_IRotate aRI(aFunction);
2080   aRI.SetCentPoint(theCentPoint->GetLastFunction());
2081   aRI.SetPoint1(thePoint1->GetLastFunction());
2082   aRI.SetPoint2(thePoint2->GetLastFunction());
2083   aRI.SetOriginal(aLastFunction);
2084
2085   //Compute the translation
2086   try {
2087     OCC_CATCH_SIGNALS;
2088     if (!GetSolver()->ComputeFunction(aFunction)) {
2089       SetErrorCode("Rotate driver failed");
2090       return NULL;
2091     }
2092   }
2093   catch (Standard_Failure& aFail) {
2094     SetErrorCode(aFail.GetMessageString());
2095     return NULL;
2096   }
2097
2098   //Make a Python command
2099   GEOM::TPythonDump(aFunction) << aCopy << " = geompy.MakeRotationThreePoints(" << theObject
2100                                << ", " << theCentPoint << ", "<<thePoint1 << ", " << thePoint2 << ")";
2101
2102   SetErrorCode(OK);
2103   return aCopy;
2104 }
2105
2106 //=============================================================================
2107 /*!
2108  *  TransformLikeOtherCopy
2109  */
2110 //=============================================================================
2111 Handle(GEOM_Object) GEOMImpl_ITransformOperations::TransformLikeOtherCopy
2112                                                 (Handle(GEOM_Object) theObject,
2113                                                  Handle(GEOM_Object) theSample)
2114 {
2115   SetErrorCode(KO);
2116
2117   if (theObject.IsNull() || theSample.IsNull()) return NULL;
2118
2119   Handle(GEOM_Function) aLastFunction = theObject->GetLastFunction();
2120   if (aLastFunction.IsNull()) return NULL; // There is no function which creates an object to be transformed
2121
2122   Handle(GEOM_Function) aSampleFunc = theSample->GetLastFunction();
2123   if (aSampleFunc.IsNull()) return NULL; // There is no function which creates a sample object
2124
2125   // Add a new Copy object
2126   Handle(GEOM_Object) aCopy = GetEngine()->AddObject(GEOM_COPY);
2127
2128   // Add a transform function (depends on theSample function)
2129   Handle(GEOM_Function) aFunction =
2130     aCopy->AddFunction(aSampleFunc->GetDriverGUID(), aSampleFunc->GetType());
2131   if (aFunction.IsNull()) return NULL;
2132
2133   // Check if the function is set correctly
2134   if (aFunction->GetDriverGUID() != aSampleFunc->GetDriverGUID()) return NULL;
2135
2136   if (aSampleFunc->GetDriverGUID() == GEOMImpl_TranslateDriver::GetID()) {
2137     switch (aSampleFunc->GetType()) {
2138     case TRANSLATE_1D:
2139       {
2140         GEOMImpl_ITranslate aRI_sample (aSampleFunc);
2141         GEOMImpl_ITranslate aRI_target (aFunction);
2142
2143         aRI_target.SetVector(aRI_sample.GetVector());
2144         aRI_target.SetStep1(aRI_sample.GetStep1());
2145         aRI_target.SetNbIter1(aRI_sample.GetNbIter1());
2146
2147         aRI_target.SetOriginal(aLastFunction);
2148       }
2149       break;
2150     case TRANSLATE_2D:
2151       {
2152         GEOMImpl_ITranslate aRI_sample (aSampleFunc);
2153         GEOMImpl_ITranslate aRI_target (aFunction);
2154
2155         aRI_target.SetVector(aRI_sample.GetVector());
2156         aRI_target.SetStep1(aRI_sample.GetStep1());
2157         aRI_target.SetNbIter1(aRI_sample.GetNbIter1());
2158
2159         aRI_target.SetVector2(aRI_sample.GetVector2());
2160         aRI_target.SetStep2(aRI_sample.GetStep2());
2161         aRI_target.SetNbIter2(aRI_sample.GetNbIter2());
2162
2163         aRI_target.SetOriginal(aLastFunction);
2164       }
2165       break;
2166     default:
2167       {
2168         SetErrorCode("Not implemented case of TransformLikeOtherCopy");
2169         return NULL;
2170       }
2171     }
2172   }
2173   else if (aSampleFunc->GetDriverGUID() == GEOMImpl_RotateDriver::GetID()) {
2174     switch (aSampleFunc->GetType()) {
2175     case ROTATE_1D:
2176       {
2177         GEOMImpl_IRotate aRI_sample (aSampleFunc);
2178         GEOMImpl_IRotate aRI_target (aFunction);
2179
2180         aRI_target.SetAxis(aRI_sample.GetAxis());
2181         aRI_target.SetNbIter1(aRI_sample.GetNbIter1());
2182
2183         aRI_target.SetOriginal(aLastFunction);
2184       }
2185       break;
2186     case ROTATE_2D:
2187       {
2188         GEOMImpl_IRotate aRI_sample (aSampleFunc);
2189         GEOMImpl_IRotate aRI_target (aFunction);
2190
2191         aRI_target.SetAxis(aRI_sample.GetAxis());
2192
2193         aRI_target.SetNbIter1(aRI_sample.GetNbIter1());
2194         aRI_target.SetNbIter2(aRI_sample.GetNbIter2());
2195
2196         aRI_target.SetAngle(aRI_sample.GetAngle());
2197         aRI_target.SetStep(aRI_sample.GetStep());
2198
2199         aRI_target.SetDir2(aRI_sample.GetDir2());
2200
2201         aRI_target.SetOriginal(aLastFunction);
2202       }
2203       break;
2204     case ROTATE_THREE_POINTS_COPY:
2205       {
2206         GEOMImpl_IRotate aRI_sample (aSampleFunc);
2207         GEOMImpl_IRotate aRI_target (aFunction);
2208
2209         aRI_target.SetCentPoint(aRI_sample.GetCentPoint());
2210         aRI_target.SetPoint1(aRI_sample.GetPoint1());
2211         aRI_target.SetPoint2(aRI_sample.GetPoint2());
2212
2213         aRI_target.SetOriginal(aLastFunction);
2214       }
2215       break;
2216     default:
2217       {
2218         SetErrorCode("Not implemented case of TransformLikeOtherCopy");
2219         return NULL;
2220       }
2221     }
2222   }
2223   else {
2224     SetErrorCode("Not implemented case of TransformLikeOtherCopy");
2225     return NULL;
2226   }
2227
2228   // Compute the transformation
2229   try {
2230     OCC_CATCH_SIGNALS;
2231     if (!GetSolver()->ComputeFunction(aFunction)) {
2232       SetErrorCode("Driver failed");
2233       return NULL;
2234     }
2235   }
2236   catch (Standard_Failure& aFail) {
2237     SetErrorCode(aFail.GetMessageString());
2238     return NULL;
2239   }
2240
2241   //Make a Python command
2242   //GEOM::TPythonDump(aFunction) << aCopy << " = geompy.TransformLikeOtherCopy("
2243   //                             << theObject << ", " << theSample << ")";
2244
2245   SetErrorCode(OK);
2246   return aCopy;
2247 }
2248
2249 //=============================================================================
2250 /*!
2251  *  MakeProjectionOnCylinder
2252  */
2253 //=============================================================================
2254 Handle(GEOM_Object) GEOMImpl_ITransformOperations::MakeProjectionOnCylinder
2255                              (const Handle(GEOM_Object) &theObject,
2256                               const Standard_Real        theRadius,
2257                               const Standard_Real        theStartAngle,
2258                               const Standard_Real        theAngleLength,
2259                               const Standard_Real        theAngleRotation)
2260 {
2261   SetErrorCode(KO);
2262
2263   if (theObject.IsNull()) {
2264     return NULL;
2265   }
2266
2267   Handle(GEOM_Function) aLastFunction = theObject->GetLastFunction();
2268
2269   if (aLastFunction.IsNull()) {
2270     //There is no function which creates an object to be projected
2271     return NULL;
2272   }
2273
2274   //Add a new Projection object
2275   Handle(GEOM_Object) aResult =
2276     GetEngine()->AddObject(GEOM_PROJECTION);
2277
2278   //Add a Projection function
2279   Handle(GEOM_Function) aFunction = aResult->AddFunction
2280     (GEOMImpl_ProjectionDriver::GetID(), PROJECTION_ON_CYLINDER);
2281
2282   //Check if the function is set correctly
2283   if (aFunction->GetDriverGUID() != GEOMImpl_ProjectionDriver::GetID()) {
2284     return aResult;
2285   }
2286
2287   GEOMImpl_IProjOnCyl aProj (aFunction);
2288
2289   aProj.SetShape(aLastFunction);
2290   aProj.SetRadius(theRadius);
2291   aProj.SetStartAngle(theStartAngle);
2292   aProj.SetAngleLength(theAngleLength);
2293   aProj.SetAngleRotation(theAngleRotation);
2294
2295   //Compute the Projection
2296   try {
2297     OCC_CATCH_SIGNALS;
2298     if (!GetSolver()->ComputeFunction(aFunction)) {
2299       SetErrorCode("Projection driver failed");
2300       return aResult;
2301     }
2302   }
2303   catch (Standard_Failure& aFail) {
2304     SetErrorCode(aFail.GetMessageString());
2305     return aResult;
2306   }
2307
2308   //Make a Python command
2309   GEOM::TPythonDump(aFunction)
2310     << aResult << " = geompy.MakeProjectionOnCylinder("
2311     << theObject << ", " << theRadius << ", " << theStartAngle
2312     << ", " << theAngleLength << ", " << theAngleRotation << ")";
2313
2314   SetErrorCode(OK);
2315
2316   return aResult;
2317 }