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