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