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