Salome HOME
Merge multi-study removal branch.
[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 <Basics_OCCTVersion.hxx>
50
51 #include "utilities.h"
52 #include <OpUtil.hxx>
53 #include <Utils_ExceptHandlers.hxx>
54
55 #include <TFunction_DriverTable.hxx>
56 #include <TFunction_Driver.hxx>
57 #include <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)
81 : GEOM_IOperations(theEngine)
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(GEOM_COPY);
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(GEOM_COPY);
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(GEOM_COPY);
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(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(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(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(GEOM_COPY);
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(GEOM_COPY);
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(GEOM_COPY);
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(GEOM_COPY);
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)
1159 GEOMImpl_ITransformOperations::ProjectShapeCopy (Handle(GEOM_Object) theSource,
1160                                                  Handle(GEOM_Object) theTarget)
1161 {
1162   SetErrorCode(KO);
1163
1164   if (theSource.IsNull() || theTarget.IsNull()) return NULL;
1165
1166   Handle(GEOM_Function) aLastFunction = theSource->GetLastFunction();
1167   if (aLastFunction.IsNull()) return NULL; //There is no function which creates an object to be projected
1168
1169   Handle(GEOM_Object) aCopy;
1170
1171   TopoDS_Shape aTarget = theTarget->GetValue();
1172   if ( aTarget.IsNull() ) return NULL;
1173   if ( aTarget.ShapeType() == TopAbs_EDGE ||
1174        aTarget.ShapeType() == TopAbs_WIRE )
1175   {
1176     // a TPythonDump prevents dumping ProjectPointOnWire(),
1177     // dump of MakeProjection() is done at the end of this function
1178     GEOM::TPythonDump preventDump(aLastFunction, /*append=*/true);
1179     Standard_Integer dummy;
1180     ProjectPointOnWire( theSource, theTarget, aCopy, dummy );
1181     if ( aCopy.IsNull() || !IsDone() )
1182       return NULL;
1183   }
1184   else
1185   {
1186     //Add a new Projection object
1187     aCopy = GetEngine()->AddObject(GEOM_PROJECTION);
1188
1189     //Add a Projection function
1190     Handle(GEOM_Function) aFunction =
1191       aCopy->AddFunction(GEOMImpl_ProjectionDriver::GetID(), PROJECTION_COPY);
1192
1193     //Check if the function is set correctly
1194     if (aFunction->GetDriverGUID() != GEOMImpl_ProjectionDriver::GetID()) return NULL;
1195
1196     GEOMImpl_IMirror aTI (aFunction);
1197     aTI.SetPlane(theTarget->GetLastFunction());
1198     aTI.SetOriginal(aLastFunction);
1199
1200     //Compute the Projection
1201     try {
1202       OCC_CATCH_SIGNALS;
1203       if (!GetSolver()->ComputeFunction(aFunction)) {
1204         SetErrorCode("Projection driver failed");
1205         return NULL;
1206       }
1207     }
1208     catch (Standard_Failure) {
1209       Handle(Standard_Failure) aFail = Standard_Failure::Caught();
1210       SetErrorCode(aFail->GetMessageString());
1211       return NULL;
1212     }
1213   }
1214
1215   //Make a Python command
1216   Handle(GEOM_Function) aFunction = aCopy->GetLastFunction();
1217   GEOM::TPythonDump(aFunction) << aCopy << " = geompy.MakeProjection("
1218                                << theSource << ", " << theTarget << ")";
1219
1220   SetErrorCode(OK);
1221   return aCopy;
1222 }
1223
1224 //=============================================================================
1225 /*!
1226  *  ProjectPointOnWire
1227  */
1228 //=============================================================================
1229 Standard_Real GEOMImpl_ITransformOperations::ProjectPointOnWire
1230                                     (Handle(GEOM_Object) thePoint,
1231                                      Handle(GEOM_Object) theWire,
1232                                      Handle(GEOM_Object) &thePointOnEdge,
1233                                      Standard_Integer    &theEdgeInWireIndex)
1234 {
1235   Standard_Real aResult = -1.;
1236
1237   SetErrorCode(KO);
1238
1239   if (thePoint.IsNull() || theWire.IsNull()) {
1240     return aResult;
1241   }
1242
1243   Handle(GEOM_Function) aLastFunction = thePoint->GetLastFunction();
1244
1245   if (aLastFunction.IsNull()) {
1246     //There is no function which creates an object to be projected
1247     return aResult;
1248   }
1249
1250   //Add a new Projection object
1251   thePointOnEdge = GetEngine()->AddObject(GEOM_PROJECTION);
1252
1253   //Add a Projection function
1254   Handle(GEOM_Function) aFunction = thePointOnEdge->AddFunction
1255     (GEOMImpl_ProjectionDriver::GetID(), PROJECTION_ON_WIRE);
1256
1257   //Check if the function is set correctly
1258   if (aFunction->GetDriverGUID() != GEOMImpl_ProjectionDriver::GetID()) {
1259     return aResult;
1260   }
1261
1262   GEOMImpl_IProjection aProj (aFunction);
1263   aProj.SetPoint(aLastFunction);
1264   aProj.SetShape(theWire->GetLastFunction());
1265
1266   //Compute the Projection
1267   try {
1268     OCC_CATCH_SIGNALS;
1269     if (!GetSolver()->ComputeFunction(aFunction)) {
1270       SetErrorCode("Projection driver failed");
1271       return aResult;
1272     }
1273   }
1274   catch (Standard_Failure) {
1275     Handle(Standard_Failure) aFail = Standard_Failure::Caught();
1276     SetErrorCode(aFail->GetMessageString());
1277     return aResult;
1278   }
1279
1280   aResult            = aProj.GetU();
1281   theEdgeInWireIndex = aProj.GetIndex();
1282
1283
1284   //Make a Python command
1285   GEOM::TPythonDump(aFunction) << "(u, " << thePointOnEdge
1286     << ", EdgeInWireIndex) = geompy.MakeProjectionOnWire(" << thePoint
1287     << ", " << theWire << ")";
1288
1289   SetErrorCode(OK);
1290
1291   return aResult;
1292 }
1293
1294 //=============================================================================
1295 /*!
1296  *  ScaleShape
1297  */
1298 //=============================================================================
1299 Handle(GEOM_Object) GEOMImpl_ITransformOperations::ScaleShape
1300        (Handle(GEOM_Object) theObject, Handle(GEOM_Object) thePoint, double theFactor)
1301 {
1302   SetErrorCode(KO);
1303
1304   if (theObject.IsNull()) return NULL;
1305
1306   Handle(GEOM_Function) anOriginal = theObject->GetLastFunction();
1307   if (anOriginal.IsNull()) return NULL; //There is no function which creates an object to be scaled
1308
1309   //Add a scale function
1310   Handle(GEOM_Function) aFunction =
1311     theObject->AddFunction(GEOMImpl_ScaleDriver::GetID(), SCALE_SHAPE);
1312   if (aFunction.IsNull()) return NULL;
1313
1314   //Check if the function is set correctly
1315   if (aFunction->GetDriverGUID() != GEOMImpl_ScaleDriver::GetID()) return NULL;
1316
1317   // Set arguments
1318   GEOMImpl_IScale aTI (aFunction);
1319   aTI.SetShape(anOriginal);
1320   aTI.SetFactor(theFactor);
1321
1322   // Set point argument
1323   if (!thePoint.IsNull()) {
1324     Handle(GEOM_Function) aPF = thePoint->GetLastFunction();
1325     aTI.SetPoint(aPF);
1326   }
1327
1328   //Compute the scale
1329   try {
1330     OCC_CATCH_SIGNALS;
1331     if (!GetSolver()->ComputeFunction(aFunction)) {
1332       SetErrorCode("Scale driver failed");
1333       return NULL;
1334     }
1335   }
1336   catch (Standard_Failure) {
1337     Handle(Standard_Failure) aFail = Standard_Failure::Caught();
1338     SetErrorCode(aFail->GetMessageString());
1339     return NULL;
1340   }
1341
1342   //Make a Python command
1343   GEOM::TPythonDump(aFunction) << "geompy.Scale("
1344     << theObject << ", " << thePoint << ", " << theFactor << ")";
1345
1346   SetErrorCode(OK);
1347   return theObject;
1348 }
1349
1350 //=============================================================================
1351 /*!
1352  *  ScaleShapeCopy
1353  */
1354 //=============================================================================
1355 Handle(GEOM_Object) GEOMImpl_ITransformOperations::ScaleShapeCopy
1356        (Handle(GEOM_Object) theObject, Handle(GEOM_Object) thePoint, double theFactor)
1357 {
1358   SetErrorCode(KO);
1359
1360   if (theObject.IsNull()) return NULL;
1361
1362   Handle(GEOM_Function) anOriginal = theObject->GetLastFunction();
1363   if (anOriginal.IsNull()) return NULL; //There is no function which creates an object to be scaled
1364
1365   //Add a new Copy object
1366   Handle(GEOM_Object) aCopy = GetEngine()->AddObject(GEOM_COPY);
1367
1368   //Add a scale function
1369   Handle(GEOM_Function) aFunction =
1370     aCopy->AddFunction(GEOMImpl_ScaleDriver::GetID(), SCALE_SHAPE_COPY);
1371   if (aFunction.IsNull()) return NULL;
1372
1373   //Check if the function is set correctly
1374   if (aFunction->GetDriverGUID() != GEOMImpl_ScaleDriver::GetID()) return NULL;
1375
1376   // Set arguments
1377   GEOMImpl_IScale aTI (aFunction);
1378   aTI.SetShape(anOriginal);
1379   aTI.SetFactor(theFactor);
1380
1381   // Set point argument
1382   if (!thePoint.IsNull()) {
1383     Handle(GEOM_Function) aPF = thePoint->GetLastFunction();
1384     aTI.SetPoint(aPF);
1385   }
1386
1387   //Compute the scale
1388   try {
1389     OCC_CATCH_SIGNALS;
1390     if (!GetSolver()->ComputeFunction(aFunction)) {
1391       SetErrorCode("Scale driver failed");
1392       return NULL;
1393     }
1394   }
1395   catch (Standard_Failure) {
1396     Handle(Standard_Failure) aFail = Standard_Failure::Caught();
1397     SetErrorCode(aFail->GetMessageString());
1398     return NULL;
1399   }
1400
1401   //Make a Python command
1402   GEOM::TPythonDump(aFunction) << aCopy << " = geompy.MakeScaleTransform("
1403     << theObject << ", " << thePoint << ", " << theFactor << ")";
1404
1405   SetErrorCode(OK);
1406   return aCopy;
1407 }
1408
1409 //=============================================================================
1410 /*!
1411  *  ScaleShapeAlongAxes
1412  */
1413 //=============================================================================
1414 Handle(GEOM_Object) GEOMImpl_ITransformOperations::ScaleShapeAlongAxes (Handle(GEOM_Object) theObject,
1415                                                                         Handle(GEOM_Object) thePoint,
1416                                                                         double theFactorX,
1417                                                                         double theFactorY,
1418                                                                         double theFactorZ,
1419                                                                         bool   doCopy)
1420 {
1421   SetErrorCode(KO);
1422
1423   if (theObject.IsNull()) return NULL;
1424
1425   Handle(GEOM_Function) anOriginal = theObject->GetLastFunction();
1426   if (anOriginal.IsNull()) return NULL; //There is no function which creates an object to be scaled
1427
1428   //Add a scale function
1429   Handle(GEOM_Object) aCopy;   //Add a new Copy object
1430   Handle(GEOM_Function) aFunction;
1431   if (doCopy) {
1432     aCopy = GetEngine()->AddObject(theObject->GetType());
1433     aFunction = aCopy->AddFunction(GEOMImpl_ScaleDriver::GetID(), SCALE_SHAPE_AXES_COPY);
1434   }
1435   else {
1436     aFunction = theObject->AddFunction(GEOMImpl_ScaleDriver::GetID(), SCALE_SHAPE_AXES);
1437   }
1438   if (aFunction.IsNull()) return NULL;
1439
1440   //Check if the function is set correctly
1441   if (aFunction->GetDriverGUID() != GEOMImpl_ScaleDriver::GetID()) return NULL;
1442
1443   // Set arguments
1444   GEOMImpl_IScale aTI (aFunction);
1445   aTI.SetShape(anOriginal);
1446   aTI.SetFactorX(theFactorX);
1447   aTI.SetFactorY(theFactorY);
1448   aTI.SetFactorZ(theFactorZ);
1449
1450   // Set point (optional argument)
1451   if (!thePoint.IsNull()) {
1452     Handle(GEOM_Function) aPF = thePoint->GetLastFunction();
1453     aTI.SetPoint(aPF);
1454   }
1455
1456   //Compute the scale
1457   try {
1458     OCC_CATCH_SIGNALS;
1459     if (!GetSolver()->ComputeFunction(aFunction)) {
1460       SetErrorCode("Scale driver failed");
1461       return NULL;
1462     }
1463   }
1464   catch (Standard_Failure) {
1465     Handle(Standard_Failure) aFail = Standard_Failure::Caught();
1466     SetErrorCode(aFail->GetMessageString());
1467     return NULL;
1468   }
1469
1470   SetErrorCode(OK);
1471
1472   //Make a Python command
1473   if (doCopy) {
1474     GEOM::TPythonDump(aFunction) << aCopy << " = geompy.MakeScaleAlongAxes("
1475                                  << theObject << ", " << thePoint << ", "
1476                                  << theFactorX << ", " << theFactorY << ", " << theFactorZ << ")";
1477     return aCopy;
1478   }
1479
1480   GEOM::TPythonDump(aFunction) << "geompy.ScaleAlongAxes("
1481                                << theObject << ", " << thePoint << ", "
1482                                << theFactorX << ", " << theFactorY << ", " << theFactorZ << ")";
1483   return theObject;
1484 }
1485
1486 //=============================================================================
1487 /*!
1488  *  PositionShape
1489  */
1490 //=============================================================================
1491 Handle(GEOM_Object) GEOMImpl_ITransformOperations::PositionShape
1492         (Handle(GEOM_Object) theObject, Handle(GEOM_Object) theStartLCS, Handle(GEOM_Object) theEndLCS)
1493 {
1494   SetErrorCode(KO);
1495
1496   if (theObject.IsNull() || theEndLCS.IsNull()) return NULL;
1497
1498   Handle(GEOM_Function) anOriginal = theObject->GetLastFunction();
1499   if (anOriginal.IsNull()) return NULL; //There is no function which creates an object to be set in position
1500
1501   //Add a Position function
1502   Standard_Integer aType = POSITION_SHAPE;
1503   if (theStartLCS.IsNull()) aType = POSITION_SHAPE_FROM_GLOBAL;
1504
1505   Handle(GEOM_Function) aFunction =
1506     theObject->AddFunction(GEOMImpl_PositionDriver::GetID(), aType);
1507   if (aFunction.IsNull()) return NULL;
1508
1509   //Check if the function is set correctly
1510   if (aFunction->GetDriverGUID() != GEOMImpl_PositionDriver::GetID()) return NULL;
1511
1512   //Set operation arguments
1513   GEOMImpl_IPosition aTI (aFunction);
1514   aTI.SetShape(anOriginal);
1515   aTI.SetEndLCS(theEndLCS->GetLastFunction());
1516   if (!theStartLCS.IsNull())
1517     aTI.SetStartLCS(theObject == theStartLCS ? anOriginal : theStartLCS->GetLastFunction());
1518
1519   //Compute the Position
1520   try {
1521     OCC_CATCH_SIGNALS;
1522     if (!GetSolver()->ComputeFunction(aFunction)) {
1523       SetErrorCode("Position driver failed");
1524       return NULL;
1525     }
1526   }
1527   catch (Standard_Failure) {
1528     Handle(Standard_Failure) aFail = Standard_Failure::Caught();
1529     SetErrorCode(aFail->GetMessageString());
1530     return NULL;
1531   }
1532
1533   //Make a Python command
1534   GEOM::TPythonDump(aFunction) << "geompy.Position("
1535     << theObject << ", " << theStartLCS << ", " << theEndLCS << ")";
1536
1537   SetErrorCode(OK);
1538   return theObject;
1539 }
1540
1541 //=============================================================================
1542 /*!
1543  *  PositionShapeCopy
1544  */
1545 //=============================================================================
1546 Handle(GEOM_Object) GEOMImpl_ITransformOperations::PositionShapeCopy
1547        (Handle(GEOM_Object) theObject, Handle(GEOM_Object) theStartLCS, Handle(GEOM_Object) theEndLCS)
1548 {
1549   SetErrorCode(KO);
1550
1551   if (theObject.IsNull() || theEndLCS.IsNull()) return NULL;
1552
1553   Handle(GEOM_Function) anOriginal = theObject->GetLastFunction();
1554   if (anOriginal.IsNull()) return NULL; //There is no function which creates an object to be set in position
1555
1556   //Add a new Copy object
1557   Handle(GEOM_Object) aCopy = GetEngine()->AddObject(GEOM_COPY);
1558
1559   //Add a position function
1560   Standard_Integer aType = POSITION_SHAPE_COPY;
1561   if (theStartLCS.IsNull()) aType = POSITION_SHAPE_FROM_GLOBAL_COPY;
1562
1563   Handle(GEOM_Function) aFunction =
1564     aCopy->AddFunction(GEOMImpl_PositionDriver::GetID(), aType);
1565   if (aFunction.IsNull()) return NULL;
1566
1567   //Check if the function is set correctly
1568   if (aFunction->GetDriverGUID() != GEOMImpl_PositionDriver::GetID()) return NULL;
1569
1570   GEOMImpl_IPosition aTI (aFunction);
1571   aTI.SetShape(anOriginal);
1572   aTI.SetEndLCS(theEndLCS->GetLastFunction());
1573   if (!theStartLCS.IsNull())
1574     aTI.SetStartLCS(theStartLCS->GetLastFunction());
1575
1576   //Compute the position
1577   try {
1578     OCC_CATCH_SIGNALS;
1579     if (!GetSolver()->ComputeFunction(aFunction)) {
1580       SetErrorCode("Position driver failed");
1581       return NULL;
1582     }
1583   }
1584   catch (Standard_Failure) {
1585     Handle(Standard_Failure) aFail = Standard_Failure::Caught();
1586     SetErrorCode(aFail->GetMessageString());
1587     return NULL;
1588   }
1589
1590   //Make a Python command
1591   GEOM::TPythonDump(aFunction) << aCopy << " = geompy.MakePosition("
1592     << theObject << ", " << theStartLCS << ", " << theEndLCS << ")";
1593
1594   SetErrorCode(OK);
1595   return aCopy;
1596 }
1597
1598 //=============================================================================
1599 /*!
1600  *  PositionAlongPath
1601  */
1602 //=============================================================================
1603 Handle(GEOM_Object) GEOMImpl_ITransformOperations::PositionAlongPath
1604        (Handle(GEOM_Object) theObject, Handle(GEOM_Object) thePath,
1605         double theDistance, bool theCopy, bool theReverse)
1606 {
1607   SetErrorCode(KO);
1608
1609   if (theObject.IsNull() || thePath.IsNull()) return NULL;
1610
1611   Handle(GEOM_Function) anOriginal = theObject->GetLastFunction();
1612   if (anOriginal.IsNull()) return NULL; //There is no function which creates an object to be set in position
1613
1614   //Add a position function
1615   Handle(GEOM_Function) aFunction;
1616   Handle(GEOM_Object) aCopy;
1617
1618   if (theCopy) {
1619     aCopy = GetEngine()->AddObject(theObject->GetType());
1620     aFunction = aCopy->AddFunction(GEOMImpl_PositionDriver::GetID(), POSITION_ALONG_PATH);
1621   }
1622   else
1623     aFunction = theObject->AddFunction(GEOMImpl_PositionDriver::GetID(), POSITION_ALONG_PATH);
1624
1625   if (aFunction.IsNull()) return NULL;
1626
1627   //Check if the function is set correctly
1628   if (aFunction->GetDriverGUID() != GEOMImpl_PositionDriver::GetID()) return NULL;
1629
1630   GEOMImpl_IPosition aTI (aFunction);
1631   aTI.SetShape(anOriginal);
1632   aTI.SetPath(thePath->GetLastFunction());
1633   aTI.SetDistance(theDistance);
1634   aTI.SetReverse(theReverse);
1635
1636   //Compute the position
1637   try {
1638     OCC_CATCH_SIGNALS;
1639     if (!GetSolver()->ComputeFunction(aFunction)) {
1640       SetErrorCode("Position driver failed");
1641       return NULL;
1642     }
1643   }
1644   catch (Standard_Failure) {
1645     Handle(Standard_Failure) aFail = Standard_Failure::Caught();
1646     SetErrorCode(aFail->GetMessageString());
1647     return NULL;
1648   }
1649
1650   //Make a Python command
1651   if (theCopy) {
1652     GEOM::TPythonDump(aFunction) << aCopy << " = geompy.MakePositionAlongPath("
1653                                  << theObject << ", " << thePath << ", " << theDistance << ", " << theCopy << ", " << theReverse << ")";
1654     SetErrorCode(OK);
1655     return aCopy;
1656   }
1657
1658   GEOM::TPythonDump(aFunction) << "geompy.PositionAlongPath("
1659     << theObject << ", " << thePath << ", " << theDistance << ", " << theCopy << ", " << theReverse << ")";
1660
1661   SetErrorCode(OK);
1662   return theObject;
1663 }
1664
1665 //=============================================================================
1666 /*!
1667  *  Rotate
1668  */
1669 //=============================================================================
1670 Handle(GEOM_Object) GEOMImpl_ITransformOperations::Rotate (Handle(GEOM_Object) theObject,
1671                                                            Handle(GEOM_Object) theAxis,
1672                                                            double theAngle)
1673 {
1674   SetErrorCode(KO);
1675
1676   if (theObject.IsNull() || theAxis.IsNull()) return NULL;
1677
1678   Handle(GEOM_Function) aFunction, aLastFunction = theObject->GetLastFunction();
1679   if (aLastFunction.IsNull()) return NULL;  //There is no function which creates an object to be rotated
1680
1681   // Get last functions of the arguments
1682   Handle(GEOM_Function) anAF = theAxis->GetLastFunction();
1683
1684   //Add a rotate function
1685   aFunction = theObject->AddFunction(GEOMImpl_RotateDriver::GetID(), ROTATE);
1686
1687   if (aFunction.IsNull()) return NULL;
1688
1689   //Check if the function is set correctly
1690   if (aFunction->GetDriverGUID() != GEOMImpl_RotateDriver::GetID()) return NULL;
1691
1692   GEOMImpl_IRotate aRI(aFunction);
1693   aRI.SetAxis(anAF);
1694   aRI.SetOriginal(aLastFunction);
1695   aRI.SetAngle(theAngle);
1696
1697   //Compute the translation
1698   try {
1699     OCC_CATCH_SIGNALS;
1700     if (!GetSolver()->ComputeFunction(aFunction)) {
1701       SetErrorCode("Rotate driver failed");
1702       return NULL;
1703     }
1704   }
1705   catch (Standard_Failure) {
1706     Handle(Standard_Failure) aFail = Standard_Failure::Caught();
1707     SetErrorCode(aFail->GetMessageString());
1708     return NULL;
1709   }
1710
1711   //Make a Python command
1712   GEOM::TPythonDump(aFunction) << "geompy.Rotate(" << theObject
1713     << ", " << theAxis << ", " << theAngle * 180.0 / M_PI << "*math.pi/180.0)";
1714
1715   SetErrorCode(OK);
1716   return theObject;
1717 }
1718
1719 //=============================================================================
1720 /*!
1721  *  RotateCopy
1722  */
1723 //=============================================================================
1724 Handle(GEOM_Object) GEOMImpl_ITransformOperations::RotateCopy (Handle(GEOM_Object) theObject,
1725                                                                Handle(GEOM_Object) theAxis,
1726                                                                double theAngle)
1727 {
1728   SetErrorCode(KO);
1729
1730   if (theObject.IsNull() || theAxis.IsNull()) return NULL;
1731
1732   Handle(GEOM_Function) aFunction, aLastFunction = theObject->GetLastFunction();
1733   if (aLastFunction.IsNull()) return NULL;  //There is no function which creates an object to be rotated
1734
1735   //Add a new Copy object
1736   Handle(GEOM_Object) aCopy = GetEngine()->AddObject(GEOM_COPY);
1737
1738   //Add a rotate function
1739   aFunction = aCopy->AddFunction(GEOMImpl_RotateDriver::GetID(), ROTATE_COPY);
1740   if (aFunction.IsNull()) return NULL;
1741
1742     //Check if the function is set correctly
1743   if (aFunction->GetDriverGUID() != GEOMImpl_RotateDriver::GetID()) return NULL;
1744
1745   GEOMImpl_IRotate aRI(aFunction);
1746   aRI.SetAxis(theAxis->GetLastFunction());
1747   aRI.SetOriginal(aLastFunction);
1748   aRI.SetAngle(theAngle);
1749
1750   //Compute the translation
1751   try {
1752     OCC_CATCH_SIGNALS;
1753     if (!GetSolver()->ComputeFunction(aFunction)) {
1754       SetErrorCode("Rotate driver failed");
1755       return NULL;
1756     }
1757   }
1758   catch (Standard_Failure) {
1759     Handle(Standard_Failure) aFail = Standard_Failure::Caught();
1760     SetErrorCode(aFail->GetMessageString());
1761     return NULL;
1762   }
1763
1764   //Make a Python command
1765   GEOM::TPythonDump(aFunction) << aCopy << " = geompy.MakeRotation(" << theObject
1766     << ", " << theAxis << ", " << theAngle * 180.0 / M_PI << "*math.pi/180.0)";
1767
1768   SetErrorCode(OK);
1769   return aCopy;
1770 }
1771
1772 //=============================================================================
1773 /*!
1774  *  Rotate1D (for MultiRotate1DNbTimes)
1775  */
1776 //=============================================================================
1777 Handle(GEOM_Object) GEOMImpl_ITransformOperations::Rotate1D (Handle(GEOM_Object) theObject,
1778                                                              Handle(GEOM_Object) theAxis,
1779                                                              Standard_Integer theNbTimes)
1780 {
1781   SetErrorCode(KO);
1782
1783   if (theObject.IsNull()) return NULL;
1784
1785   Handle(GEOM_Function) aFunction, aLastFunction = theObject->GetLastFunction();
1786   if (aLastFunction.IsNull()) return NULL;  //There is no function which creates an object to be rotated
1787
1788   //Add a new Copy object
1789   Handle(GEOM_Object) aCopy = GetEngine()->AddObject(theObject->GetType());
1790
1791   //Add a rotate function
1792   aFunction = aCopy->AddFunction(GEOMImpl_RotateDriver::GetID(), ROTATE_1D);
1793   if (aFunction.IsNull()) return NULL;
1794
1795   //Check if the function is set correctly
1796   if (aFunction->GetDriverGUID() != GEOMImpl_RotateDriver::GetID()) return NULL;
1797
1798   GEOMImpl_IRotate aRI(aFunction);
1799   aRI.SetOriginal(aLastFunction);
1800   if (!theAxis.IsNull())
1801     aRI.SetAxis(theAxis->GetLastFunction());
1802   aRI.SetNbIter1(theNbTimes);
1803
1804   //Compute the translation
1805   try {
1806     OCC_CATCH_SIGNALS;
1807     if (!GetSolver()->ComputeFunction(aFunction)) {
1808       SetErrorCode("Rotate driver failed");
1809       return NULL;
1810     }
1811   }
1812   catch (Standard_Failure) {
1813     Handle(Standard_Failure) aFail = Standard_Failure::Caught();
1814     SetErrorCode(aFail->GetMessageString());
1815     return NULL;
1816   }
1817
1818   //Make a Python command
1819   GEOM::TPythonDump(aFunction) << aCopy << " = geompy.MultiRotate1DNbTimes("
1820     << theObject << ", " << theAxis << ", " << theNbTimes << ")";
1821
1822   SetErrorCode(OK);
1823   return aCopy;
1824 }
1825
1826 //=============================================================================
1827 /*!
1828  *  Rotate1D (for MultiRotate1DByStep)
1829  */
1830 //=============================================================================
1831 Handle(GEOM_Object) GEOMImpl_ITransformOperations::Rotate1D (Handle(GEOM_Object) theObject,
1832                                                              Handle(GEOM_Object) theAxis,
1833                                                              double theAngleStep,
1834                                                              Standard_Integer theNbSteps)
1835 {
1836   SetErrorCode(KO);
1837
1838   if (theObject.IsNull()) return NULL;
1839
1840   Handle(GEOM_Function) aFunction, aLastFunction = theObject->GetLastFunction();
1841   if (aLastFunction.IsNull()) return NULL;  //There is no function which creates an object to be rotated
1842
1843   //Add a new Copy object
1844   Handle(GEOM_Object) aCopy = GetEngine()->AddObject(theObject->GetType());
1845
1846   //Add a rotate function
1847   aFunction = aCopy->AddFunction(GEOMImpl_RotateDriver::GetID(), ROTATE_1D_STEP);
1848   if (aFunction.IsNull()) return NULL;
1849
1850   //Check if the function is set correctly
1851   if (aFunction->GetDriverGUID() != GEOMImpl_RotateDriver::GetID()) return NULL;
1852
1853   //Convert angle into degrees
1854   double anAngleStep = theAngleStep * 180. / M_PI;
1855
1856   GEOMImpl_IRotate aRI (aFunction);
1857   aRI.SetOriginal(aLastFunction);
1858   if (!theAxis.IsNull())
1859     aRI.SetAxis(theAxis->GetLastFunction());
1860   aRI.SetAngle(anAngleStep);
1861   aRI.SetNbIter1(theNbSteps);
1862
1863   //Compute the translation
1864   try {
1865     OCC_CATCH_SIGNALS;
1866     if (!GetSolver()->ComputeFunction(aFunction)) {
1867       SetErrorCode("Rotate driver failed");
1868       return NULL;
1869     }
1870   }
1871   catch (Standard_Failure) {
1872     Handle(Standard_Failure) aFail = Standard_Failure::Caught();
1873     SetErrorCode(aFail->GetMessageString());
1874     return NULL;
1875   }
1876
1877   //Make a Python command
1878   GEOM::TPythonDump(aFunction)
1879     << aCopy << " = geompy.MultiRotate1DByStep(" << theObject << ", "
1880     << theAxis << ", " << anAngleStep << "*math.pi/180.0, " << theNbSteps << ")";
1881
1882   SetErrorCode(OK);
1883   return aCopy;
1884 }
1885
1886 //=============================================================================
1887 /*!
1888  *  Rotate2D (for MultiRotate2DNbTimes)
1889  */
1890 //=============================================================================
1891 Handle(GEOM_Object) GEOMImpl_ITransformOperations::Rotate2D (Handle(GEOM_Object) theObject,
1892                                                              Handle(GEOM_Object) theAxis,
1893                                                              Standard_Integer theNbObjects,
1894                                                              double theRadialStep,
1895                                                              Standard_Integer theNbSteps)
1896 {
1897   SetErrorCode(KO);
1898
1899   if (theObject.IsNull()) return NULL;
1900
1901   Handle(GEOM_Function) aFunction, aLastFunction = theObject->GetLastFunction();
1902   if (aLastFunction.IsNull()) return NULL;  //There is no function which creates an object to be rotated
1903
1904   //Add a new Copy object
1905   Handle(GEOM_Object) aCopy = GetEngine()->AddObject(theObject->GetType());
1906
1907   //Add a rotate function
1908   aFunction = aCopy->AddFunction(GEOMImpl_RotateDriver::GetID(), ROTATE_2D);
1909   if (aFunction.IsNull()) return NULL;
1910
1911   //Check if the function is set correctly
1912   if (aFunction->GetDriverGUID() != GEOMImpl_RotateDriver::GetID()) return NULL;
1913
1914   double anAngle = 360. / (double)theNbObjects;
1915
1916   GEOMImpl_IRotate aRI (aFunction);
1917   aRI.SetOriginal(aLastFunction);
1918   if (!theAxis.IsNull())
1919     aRI.SetAxis(theAxis->GetLastFunction());
1920   aRI.SetAngle(anAngle);
1921   aRI.SetNbIter1(theNbObjects);
1922   aRI.SetStep(theRadialStep);
1923   aRI.SetNbIter2(theNbSteps);
1924
1925   //Compute the translation
1926   try {
1927     OCC_CATCH_SIGNALS;
1928     if (!GetSolver()->ComputeFunction(aFunction)) {
1929       SetErrorCode("Rotate driver failed");
1930       return NULL;
1931     }
1932   }
1933   catch (Standard_Failure) {
1934     Handle(Standard_Failure) aFail = Standard_Failure::Caught();
1935     SetErrorCode(aFail->GetMessageString());
1936     return NULL;
1937   }
1938
1939   //Make a Python command
1940   GEOM::TPythonDump(aFunction) << aCopy << " = geompy.MultiRotate2DNbTimes("
1941                                << theObject << ", " << theAxis << ", " << theNbObjects
1942                                << ", " << theRadialStep << ", " << theNbSteps << ")";
1943
1944   SetErrorCode(OK);
1945   return aCopy;
1946 }
1947
1948 //=============================================================================
1949 /*!
1950  *  Rotate2D (for MultiRotate2DByStep)
1951  */
1952 //=============================================================================
1953 Handle(GEOM_Object) GEOMImpl_ITransformOperations::Rotate2D (Handle(GEOM_Object) theObject,
1954                                                              Handle(GEOM_Object) theAxis,
1955                                                              double theAngleStep,
1956                                                              Standard_Integer theNbTimes1,
1957                                                              double theStep,
1958                                                              Standard_Integer theNbTimes2)
1959 {
1960   SetErrorCode(KO);
1961
1962   if (theObject.IsNull()) return NULL;
1963
1964   Handle(GEOM_Function) aFunction, aLastFunction = theObject->GetLastFunction();
1965   if (aLastFunction.IsNull()) return NULL; //There is no function which creates an object to be rotated
1966
1967   //Add a new Copy object
1968   Handle(GEOM_Object) aCopy = GetEngine()->AddObject(theObject->GetType());
1969
1970   //Add a rotate function
1971   aFunction = aCopy->AddFunction(GEOMImpl_RotateDriver::GetID(), ROTATE_2D);
1972   if (aFunction.IsNull()) return NULL;
1973
1974   //Check if the function is set correctly
1975   if (aFunction->GetDriverGUID() != GEOMImpl_RotateDriver::GetID()) return NULL;
1976
1977   //Convert angle into degrees
1978   double anAngleStep = theAngleStep * 180. / M_PI;
1979
1980   GEOMImpl_IRotate aRI (aFunction);
1981   aRI.SetOriginal(aLastFunction);
1982   if (!theAxis.IsNull())
1983     aRI.SetAxis(theAxis->GetLastFunction());
1984   aRI.SetAngle(anAngleStep);
1985   aRI.SetNbIter1(theNbTimes1);
1986   aRI.SetStep(theStep);
1987   aRI.SetNbIter2(theNbTimes2);
1988
1989   //Compute the translation
1990   try {
1991     OCC_CATCH_SIGNALS;
1992     if (!GetSolver()->ComputeFunction(aFunction)) {
1993       SetErrorCode("Rotate driver failed");
1994       return NULL;
1995     }
1996   }
1997   catch (Standard_Failure) {
1998     Handle(Standard_Failure) aFail = Standard_Failure::Caught();
1999     SetErrorCode(aFail->GetMessageString());
2000     return NULL;
2001   }
2002
2003   //Make a Python command
2004   GEOM::TPythonDump(aFunction)
2005     << aCopy << " = geompy.MultiRotate2DByStep(" << theObject << ", "
2006     << theAxis << ", " << anAngleStep << "*math.pi/180.0, "
2007     << theNbTimes1 << ", " << theStep << ", " << theNbTimes2 << ")";
2008
2009   SetErrorCode(OK);
2010   return aCopy;
2011 }
2012
2013 //=============================================================================
2014 /*!
2015  *  RotateThreePoints
2016  */
2017 //=============================================================================
2018 Handle(GEOM_Object) GEOMImpl_ITransformOperations::RotateThreePoints (Handle(GEOM_Object) theObject,
2019                                                                       Handle(GEOM_Object) theCentPoint,
2020                                                                       Handle(GEOM_Object) thePoint1,
2021                                                                       Handle(GEOM_Object) thePoint2)
2022 {
2023   SetErrorCode(KO);
2024
2025   if (theObject.IsNull() || theCentPoint.IsNull() || thePoint1.IsNull() || thePoint2.IsNull()) return NULL;
2026
2027   Handle(GEOM_Function) aFunction, aLastFunction = theObject->GetLastFunction();
2028   if (aLastFunction.IsNull()) return NULL; //There is no function which creates an object to be rotated
2029
2030   // Get last functions of the arguments
2031   Handle(GEOM_Function) aCPF = theCentPoint->GetLastFunction();
2032   Handle(GEOM_Function) aP1F = thePoint1->GetLastFunction();
2033   Handle(GEOM_Function) aP2F = thePoint2->GetLastFunction();
2034
2035
2036   //Add a rotate function
2037   aFunction = theObject->AddFunction(GEOMImpl_RotateDriver::GetID(), ROTATE_THREE_POINTS);
2038
2039   if (aFunction.IsNull()) return NULL;
2040
2041   //Check if the function is set correctly
2042   if (aFunction->GetDriverGUID() != GEOMImpl_RotateDriver::GetID()) return NULL;
2043
2044   GEOMImpl_IRotate aRI(aFunction);
2045   aRI.SetCentPoint(aCPF);
2046   aRI.SetPoint1(aP1F);
2047   aRI.SetPoint2(aP2F);
2048   aRI.SetOriginal(aLastFunction);
2049
2050   //Compute the translation
2051   try {
2052     OCC_CATCH_SIGNALS;
2053     if (!GetSolver()->ComputeFunction(aFunction)) {
2054       SetErrorCode("Rotate driver failed");
2055       return NULL;
2056     }
2057   }
2058   catch (Standard_Failure) {
2059     Handle(Standard_Failure) aFail = Standard_Failure::Caught();
2060     SetErrorCode(aFail->GetMessageString());
2061     return NULL;
2062   }
2063
2064   //Make a Python command
2065   GEOM::TPythonDump(aFunction) << "geompy.RotateThreePoints(" << theObject
2066                                << ", " << theCentPoint << ", "<<thePoint1 << ", " << thePoint2 << ")";
2067
2068   SetErrorCode(OK);
2069   return theObject;
2070 }
2071
2072 //=============================================================================
2073 /*!
2074  *  RotateThreePointsCopy
2075  */
2076 //=============================================================================
2077 Handle(GEOM_Object) GEOMImpl_ITransformOperations::RotateThreePointsCopy (Handle(GEOM_Object) theObject,
2078                                                          Handle(GEOM_Object) theCentPoint,
2079                                                          Handle(GEOM_Object) thePoint1,
2080                                                          Handle(GEOM_Object) thePoint2)
2081 {
2082   SetErrorCode(KO);
2083
2084   if (theObject.IsNull() || theCentPoint.IsNull() || thePoint1.IsNull() || thePoint2.IsNull()) return NULL;
2085
2086   Handle(GEOM_Function) aFunction, aLastFunction = theObject->GetLastFunction();
2087   if (aLastFunction.IsNull()) return NULL;  //There is no function which creates an object to be rotated
2088
2089   //Add a new Copy object
2090   Handle(GEOM_Object) aCopy = GetEngine()->AddObject(GEOM_COPY);
2091
2092   //Add a rotate function
2093   aFunction = aCopy->AddFunction(GEOMImpl_RotateDriver::GetID(), ROTATE_THREE_POINTS_COPY);
2094   if (aFunction.IsNull()) return NULL;
2095
2096     //Check if the function is set correctly
2097   if (aFunction->GetDriverGUID() != GEOMImpl_RotateDriver::GetID()) return NULL;
2098
2099   GEOMImpl_IRotate aRI(aFunction);
2100   aRI.SetCentPoint(theCentPoint->GetLastFunction());
2101   aRI.SetPoint1(thePoint1->GetLastFunction());
2102   aRI.SetPoint2(thePoint2->GetLastFunction());
2103   aRI.SetOriginal(aLastFunction);
2104
2105   //Compute the translation
2106   try {
2107     OCC_CATCH_SIGNALS;
2108     if (!GetSolver()->ComputeFunction(aFunction)) {
2109       SetErrorCode("Rotate driver failed");
2110       return NULL;
2111     }
2112   }
2113   catch (Standard_Failure) {
2114     Handle(Standard_Failure) aFail = Standard_Failure::Caught();
2115     SetErrorCode(aFail->GetMessageString());
2116     return NULL;
2117   }
2118
2119   //Make a Python command
2120   GEOM::TPythonDump(aFunction) << aCopy << " = geompy.MakeRotationThreePoints(" << theObject
2121                                << ", " << theCentPoint << ", "<<thePoint1 << ", " << thePoint2 << ")";
2122
2123   SetErrorCode(OK);
2124   return aCopy;
2125 }
2126
2127 //=============================================================================
2128 /*!
2129  *  TransformLikeOtherCopy
2130  */
2131 //=============================================================================
2132 Handle(GEOM_Object) GEOMImpl_ITransformOperations::TransformLikeOtherCopy
2133                                                 (Handle(GEOM_Object) theObject,
2134                                                  Handle(GEOM_Object) theSample)
2135 {
2136   SetErrorCode(KO);
2137
2138   if (theObject.IsNull() || theSample.IsNull()) return NULL;
2139
2140   Handle(GEOM_Function) aLastFunction = theObject->GetLastFunction();
2141   if (aLastFunction.IsNull()) return NULL; // There is no function which creates an object to be transformed
2142
2143   Handle(GEOM_Function) aSampleFunc = theSample->GetLastFunction();
2144   if (aSampleFunc.IsNull()) return NULL; // There is no function which creates a sample object
2145
2146   // Add a new Copy object
2147   Handle(GEOM_Object) aCopy = GetEngine()->AddObject(GEOM_COPY);
2148
2149   // Add a transform function (depends on theSample function)
2150   Handle(GEOM_Function) aFunction =
2151     aCopy->AddFunction(aSampleFunc->GetDriverGUID(), aSampleFunc->GetType());
2152   if (aFunction.IsNull()) return NULL;
2153
2154   // Check if the function is set correctly
2155   if (aFunction->GetDriverGUID() != aSampleFunc->GetDriverGUID()) return NULL;
2156
2157   if (aSampleFunc->GetDriverGUID() == GEOMImpl_TranslateDriver::GetID()) {
2158     switch (aSampleFunc->GetType()) {
2159     case TRANSLATE_1D:
2160       {
2161         GEOMImpl_ITranslate aRI_sample (aSampleFunc);
2162         GEOMImpl_ITranslate aRI_target (aFunction);
2163
2164         aRI_target.SetVector(aRI_sample.GetVector());
2165         aRI_target.SetStep1(aRI_sample.GetStep1());
2166         aRI_target.SetNbIter1(aRI_sample.GetNbIter1());
2167
2168         aRI_target.SetOriginal(aLastFunction);
2169       }
2170       break;
2171     case TRANSLATE_2D:
2172       {
2173         GEOMImpl_ITranslate aRI_sample (aSampleFunc);
2174         GEOMImpl_ITranslate aRI_target (aFunction);
2175
2176         aRI_target.SetVector(aRI_sample.GetVector());
2177         aRI_target.SetStep1(aRI_sample.GetStep1());
2178         aRI_target.SetNbIter1(aRI_sample.GetNbIter1());
2179
2180         aRI_target.SetVector2(aRI_sample.GetVector2());
2181         aRI_target.SetStep2(aRI_sample.GetStep2());
2182         aRI_target.SetNbIter2(aRI_sample.GetNbIter2());
2183
2184         aRI_target.SetOriginal(aLastFunction);
2185       }
2186       break;
2187     default:
2188       {
2189         SetErrorCode("Not implemented case of TransformLikeOtherCopy");
2190         return NULL;
2191       }
2192     }
2193   }
2194   else if (aSampleFunc->GetDriverGUID() == GEOMImpl_RotateDriver::GetID()) {
2195     switch (aSampleFunc->GetType()) {
2196     case ROTATE_1D:
2197       {
2198         GEOMImpl_IRotate aRI_sample (aSampleFunc);
2199         GEOMImpl_IRotate aRI_target (aFunction);
2200
2201         aRI_target.SetAxis(aRI_sample.GetAxis());
2202         aRI_target.SetNbIter1(aRI_sample.GetNbIter1());
2203
2204         aRI_target.SetOriginal(aLastFunction);
2205       }
2206       break;
2207     case ROTATE_2D:
2208       {
2209         GEOMImpl_IRotate aRI_sample (aSampleFunc);
2210         GEOMImpl_IRotate aRI_target (aFunction);
2211
2212         aRI_target.SetAxis(aRI_sample.GetAxis());
2213
2214         aRI_target.SetNbIter1(aRI_sample.GetNbIter1());
2215         aRI_target.SetNbIter2(aRI_sample.GetNbIter2());
2216
2217         aRI_target.SetAngle(aRI_sample.GetAngle());
2218         aRI_target.SetStep(aRI_sample.GetStep());
2219
2220         aRI_target.SetDir2(aRI_sample.GetDir2());
2221
2222         aRI_target.SetOriginal(aLastFunction);
2223       }
2224       break;
2225     case ROTATE_THREE_POINTS_COPY:
2226       {
2227         GEOMImpl_IRotate aRI_sample (aSampleFunc);
2228         GEOMImpl_IRotate aRI_target (aFunction);
2229
2230         aRI_target.SetCentPoint(aRI_sample.GetCentPoint());
2231         aRI_target.SetPoint1(aRI_sample.GetPoint1());
2232         aRI_target.SetPoint2(aRI_sample.GetPoint2());
2233
2234         aRI_target.SetOriginal(aLastFunction);
2235       }
2236       break;
2237     default:
2238       {
2239         SetErrorCode("Not implemented case of TransformLikeOtherCopy");
2240         return NULL;
2241       }
2242     }
2243   }
2244   else {
2245     SetErrorCode("Not implemented case of TransformLikeOtherCopy");
2246     return NULL;
2247   }
2248
2249   // Compute the transformation
2250   try {
2251     OCC_CATCH_SIGNALS;
2252     if (!GetSolver()->ComputeFunction(aFunction)) {
2253       SetErrorCode("Driver failed");
2254       return NULL;
2255     }
2256   }
2257   catch (Standard_Failure) {
2258     Handle(Standard_Failure) aFail = Standard_Failure::Caught();
2259     SetErrorCode(aFail->GetMessageString());
2260     return NULL;
2261   }
2262
2263   //Make a Python command
2264   //GEOM::TPythonDump(aFunction) << aCopy << " = geompy.TransformLikeOtherCopy("
2265   //                             << theObject << ", " << theSample << ")";
2266
2267   SetErrorCode(OK);
2268   return aCopy;
2269 }
2270
2271 //=============================================================================
2272 /*!
2273  *  MakeProjectionOnCylinder
2274  */
2275 //=============================================================================
2276 Handle(GEOM_Object) GEOMImpl_ITransformOperations::MakeProjectionOnCylinder
2277                              (const Handle(GEOM_Object) &theObject,
2278                               const Standard_Real        theRadius,
2279                               const Standard_Real        theStartAngle,
2280                               const Standard_Real        theAngleLength,
2281                               const Standard_Real        theAngleRotation)
2282 {
2283   SetErrorCode(KO);
2284
2285   if (theObject.IsNull()) {
2286     return NULL;
2287   }
2288
2289   Handle(GEOM_Function) aLastFunction = theObject->GetLastFunction();
2290
2291   if (aLastFunction.IsNull()) {
2292     //There is no function which creates an object to be projected
2293     return NULL;
2294   }
2295
2296   //Add a new Projection object
2297   Handle(GEOM_Object) aResult =
2298     GetEngine()->AddObject(GEOM_PROJECTION);
2299
2300   //Add a Projection function
2301   Handle(GEOM_Function) aFunction = aResult->AddFunction
2302     (GEOMImpl_ProjectionDriver::GetID(), PROJECTION_ON_CYLINDER);
2303
2304   //Check if the function is set correctly
2305   if (aFunction->GetDriverGUID() != GEOMImpl_ProjectionDriver::GetID()) {
2306     return aResult;
2307   }
2308
2309   GEOMImpl_IProjOnCyl aProj (aFunction);
2310
2311   aProj.SetShape(aLastFunction);
2312   aProj.SetRadius(theRadius);
2313   aProj.SetStartAngle(theStartAngle);
2314   aProj.SetAngleLength(theAngleLength);
2315   aProj.SetAngleRotation(theAngleRotation);
2316
2317   //Compute the Projection
2318   try {
2319     OCC_CATCH_SIGNALS;
2320     if (!GetSolver()->ComputeFunction(aFunction)) {
2321       SetErrorCode("Projection driver failed");
2322       return aResult;
2323     }
2324   }
2325   catch (Standard_Failure) {
2326     Handle(Standard_Failure) aFail = Standard_Failure::Caught();
2327     SetErrorCode(aFail->GetMessageString());
2328     return aResult;
2329   }
2330
2331   //Make a Python command
2332   GEOM::TPythonDump(aFunction)
2333     << aResult << " = geompy.MakeProjectionOnCylinder("
2334     << theObject << ", " << theRadius << ", " << theStartAngle
2335     << ", " << theAngleLength << ", " << theAngleRotation << ")";
2336
2337   SetErrorCode(OK);
2338
2339   return aResult;
2340 }