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