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