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