Salome HOME
63ac920fa2b06c4da87dbdd79887060daa02cb43
[modules/geom.git] / src / GEOMImpl / GEOMImpl_I3DPrimOperations.cxx
1 // Copyright (C) 2007-2023  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_I3DPrimOperations.hxx>
26
27 #include "utilities.h"
28 #include <Utils_ExceptHandlers.hxx>
29
30 #include <TFunction_DriverTable.hxx>
31 #include <TFunction_Driver.hxx>
32 #include <TDF_Tool.hxx>
33
34 #include <GEOM_Function.hxx>
35 #include <GEOM_PythonDump.hxx>
36
37 #include <GEOMImpl_Types.hxx>
38
39 #include <GEOMImpl_BoxDriver.hxx>
40 #include <GEOMImpl_FaceDriver.hxx>
41 #include <GEOMImpl_DiskDriver.hxx>
42 #include <GEOMImpl_CylinderDriver.hxx>
43 #include <GEOMImpl_ConeDriver.hxx>
44 #include <GEOMImpl_SphereDriver.hxx>
45 #include <GEOMImpl_TorusDriver.hxx>
46 #include <GEOMImpl_PrismDriver.hxx>
47 #include <GEOMImpl_PipeDriver.hxx>
48 #include <GEOMImpl_PipePathDriver.hxx>
49 #include <GEOMImpl_RevolutionDriver.hxx>
50 #include <GEOMImpl_ShapeDriver.hxx>
51 #include <GEOMImpl_FillingDriver.hxx>
52 #include <GEOMImpl_ThruSectionsDriver.hxx>
53 #include <GEOMImpl_OffsetDriver.hxx>
54
55 #include <GEOMImpl_IBox.hxx>
56 #include <GEOMImpl_IFace.hxx>
57 #include <GEOMImpl_IDisk.hxx>
58 #include <GEOMImpl_ICylinder.hxx>
59 #include <GEOMImpl_ICone.hxx>
60 #include <GEOMImpl_IGroupOperations.hxx>
61 #include <GEOMImpl_ISphere.hxx>
62 #include <GEOMImpl_ITorus.hxx>
63 #include <GEOMImpl_IPrism.hxx>
64 #include <GEOMImpl_IPipe.hxx>
65 #include <GEOMImpl_IRevolution.hxx>
66 #include <GEOMImpl_IFilling.hxx>
67 #include <GEOMImpl_IThruSections.hxx>
68 #include <GEOMImpl_IPipeDiffSect.hxx>
69 #include <GEOMImpl_IPipeShellSect.hxx>
70 #include <GEOMImpl_IPipeBiNormal.hxx>
71 #include <GEOMImpl_IOffset.hxx>
72 #include <GEOMImpl_IPipePath.hxx>
73
74 #include <Precision.hxx>
75 #include <TopExp.hxx>
76
77 #include <Standard_Failure.hxx>
78 #include <Standard_ErrorHandler.hxx> // CAREFUL ! position of this file is critic : see Lucien PIGNOLONI / OCC
79
80 //=============================================================================
81 /*!
82  *   constructor:
83  */
84 //=============================================================================
85 GEOMImpl_I3DPrimOperations::GEOMImpl_I3DPrimOperations (GEOM_Engine* theEngine)
86 : GEOM_IOperations(theEngine)
87 {
88   MESSAGE("GEOMImpl_I3DPrimOperations::GEOMImpl_I3DPrimOperations");
89   myGroupOperations = new GEOMImpl_IGroupOperations(GetEngine());
90 }
91
92 //=============================================================================
93 /*!
94  *  destructor
95  */
96 //=============================================================================
97 GEOMImpl_I3DPrimOperations::~GEOMImpl_I3DPrimOperations()
98 {
99   MESSAGE("GEOMImpl_I3DPrimOperations::~GEOMImpl_I3DPrimOperations");
100   delete myGroupOperations;
101 }
102
103
104 //=============================================================================
105 /*!
106  *  MakeBoxDXDYDZ
107  */
108 //=============================================================================
109 Handle(GEOM_Object) GEOMImpl_I3DPrimOperations::MakeBoxDXDYDZ (double theDX, double theDY, double theDZ)
110 {
111   SetErrorCode(KO);
112
113   //Add a new Box object
114   Handle(GEOM_Object) aBox = GetEngine()->AddObject(GEOM_BOX);
115
116   //Add a new Box function with DX_DY_DZ parameters
117   Handle(GEOM_Function) aFunction = aBox->AddFunction(GEOMImpl_BoxDriver::GetID(), BOX_DX_DY_DZ);
118   if (aFunction.IsNull()) return NULL;
119
120   //Check if the function is set correctly
121   if (aFunction->GetDriverGUID() != GEOMImpl_BoxDriver::GetID()) return NULL;
122
123   GEOMImpl_IBox aBI (aFunction);
124
125   aBI.SetDX(theDX);
126   aBI.SetDY(theDY);
127   aBI.SetDZ(theDZ);
128
129   //Compute the box value
130   try {
131     OCC_CATCH_SIGNALS;
132     if (!GetSolver()->ComputeFunction(aFunction)) {
133       SetErrorCode("Box driver failed");
134       return NULL;
135     }
136   }
137   catch (Standard_Failure& aFail) {
138     SetErrorCode(aFail.GetMessageString());
139     return NULL;
140   }
141
142   //Make a Python command
143   GEOM::TPythonDump(aFunction) << aBox << " = geompy.MakeBoxDXDYDZ("
144     << theDX << ", " << theDY << ", " << theDZ << ")";
145
146   SetErrorCode(OK);
147   return aBox;
148 }
149
150
151 //=============================================================================
152 /*!
153  *  MakeBoxTwoPnt
154  */
155 //=============================================================================
156 Handle(GEOM_Object) GEOMImpl_I3DPrimOperations::MakeBoxTwoPnt (Handle(GEOM_Object) thePnt1,
157                                                                Handle(GEOM_Object) thePnt2)
158 {
159   SetErrorCode(KO);
160
161   if (thePnt1.IsNull() || thePnt2.IsNull()) return NULL;
162
163   //Add a new Box object
164   Handle(GEOM_Object) aBox = GetEngine()->AddObject(GEOM_BOX);
165
166   //Add a new Box function for creation a box relatively to two points
167   Handle(GEOM_Function) aFunction = aBox->AddFunction(GEOMImpl_BoxDriver::GetID(), BOX_TWO_PNT);
168   if (aFunction.IsNull()) return NULL;
169
170   //Check if the function is set correctly
171   if (aFunction->GetDriverGUID() != GEOMImpl_BoxDriver::GetID()) return aBox;
172
173   GEOMImpl_IBox aBI (aFunction);
174
175   Handle(GEOM_Function) aRefFunction1 = thePnt1->GetLastFunction();
176   Handle(GEOM_Function) aRefFunction2 = thePnt2->GetLastFunction();
177
178   if (aRefFunction1.IsNull() || aRefFunction2.IsNull()) return aBox;
179
180   aBI.SetRef1(aRefFunction1);
181   aBI.SetRef2(aRefFunction2);
182
183   //Compute the Box value
184   try {
185     OCC_CATCH_SIGNALS;
186     if (!GetSolver()->ComputeFunction(aFunction)) {
187       SetErrorCode("Box driver failed");
188       return NULL;
189     }
190   }
191   catch (Standard_Failure& aFail) {
192     SetErrorCode(aFail.GetMessageString());
193     return NULL;
194   }
195
196   //Make a Python command
197   GEOM::TPythonDump(aFunction) << aBox << " = geompy.MakeBoxTwoPnt("
198     << thePnt1 << ", " << thePnt2 << ")";
199
200   SetErrorCode(OK);
201   return aBox;
202 }
203
204 //=============================================================================
205 /*!
206  *  MakeFaceHW
207  */
208 //=============================================================================
209 Handle(GEOM_Object) GEOMImpl_I3DPrimOperations::MakeFaceHW (double theH, double theW, int theOrientation)
210 {
211   SetErrorCode(KO);
212
213   if (theH == 0 || theW == 0) return NULL;
214
215   //Add a new Face object
216   Handle(GEOM_Object) aFace = GetEngine()->AddObject(GEOM_FACE);
217
218   //Add a new Box function for creation a box relatively to two points
219   Handle(GEOM_Function) aFunction = aFace->AddFunction(GEOMImpl_FaceDriver::GetID(), FACE_H_W);
220   if (aFunction.IsNull()) return NULL;
221
222   //Check if the function is set correctly
223   if (aFunction->GetDriverGUID() != GEOMImpl_FaceDriver::GetID()) return aFace;
224
225   GEOMImpl_IFace aFI (aFunction);
226
227   aFI.SetH(theH);
228   aFI.SetW(theW);
229   aFI.SetOrientation(theOrientation);
230
231   //Compute the Face
232   try {
233     OCC_CATCH_SIGNALS;
234     if (!GetSolver()->ComputeFunction(aFunction)) {
235       SetErrorCode("Face 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) << aFace << " = geompy.MakeFaceHW("
246     << theH << ", " << theW << ", " << theOrientation << ")";
247
248   SetErrorCode(OK);
249   return aFace;
250 }
251
252 //=============================================================================
253 /*!
254  *  MakeFaceObjHW
255  */
256 //=============================================================================
257 Handle(GEOM_Object) GEOMImpl_I3DPrimOperations::MakeFaceObjHW (Handle(GEOM_Object) theObj,
258                                                                double theH, double theW)
259 {
260   SetErrorCode(KO);
261
262   if (theObj.IsNull()) return NULL;
263
264   //Add a new Face object
265   Handle(GEOM_Object) aFace = GetEngine()->AddObject(GEOM_FACE);
266
267   //Add a new Box function for creation a box relatively to two points
268   Handle(GEOM_Function) aFunction = aFace->AddFunction(GEOMImpl_FaceDriver::GetID(), FACE_OBJ_H_W);
269   if (aFunction.IsNull()) return NULL;
270
271   //Check if the function is set correctly
272   if (aFunction->GetDriverGUID() != GEOMImpl_FaceDriver::GetID()) return aFace;
273
274   GEOMImpl_IFace aFI (aFunction);
275
276   Handle(GEOM_Function) aRefFunction1 = theObj->GetLastFunction();
277
278   if (aRefFunction1.IsNull())
279     return aFace;
280
281   aFI.SetRef1(aRefFunction1);
282   aFI.SetH(theH);
283   aFI.SetW(theW);
284
285   //Compute the Face
286   try {
287     OCC_CATCH_SIGNALS;
288     if (!GetSolver()->ComputeFunction(aFunction)) {
289       SetErrorCode("Face driver failed");
290       return NULL;
291     }
292   }
293   catch (Standard_Failure& aFail) {
294     SetErrorCode(aFail.GetMessageString());
295     return NULL;
296   }
297
298   //Make a Python command
299   GEOM::TPythonDump(aFunction) << aFace << " = geompy.MakeFaceObjHW("
300     << theObj << ", " << theH << ", " << theW << ")";
301
302   SetErrorCode(OK);
303   return aFace;
304 }
305
306 //=============================================================================
307 /*!
308  *  MakeDiskPntVecR
309  */
310 //=============================================================================
311 Handle(GEOM_Object) GEOMImpl_I3DPrimOperations::MakeDiskPntVecR
312       (Handle(GEOM_Object) thePnt, Handle(GEOM_Object) theVec, double theR)
313 {
314   SetErrorCode(KO);
315
316   if (thePnt.IsNull() || theVec.IsNull()) return NULL;
317
318   //Add a new Disk object
319   Handle(GEOM_Object) aDisk = GetEngine()->AddObject(GEOM_FACE);
320
321   //Add a new Disk function for creation a disk relatively to point and vector
322   Handle(GEOM_Function) aFunction =
323     aDisk->AddFunction(GEOMImpl_DiskDriver::GetID(), DISK_PNT_VEC_R);
324   if (aFunction.IsNull()) return NULL;
325
326   //Check if the function is set correctly
327   if (aFunction->GetDriverGUID() != GEOMImpl_DiskDriver::GetID()) return NULL;
328
329   GEOMImpl_IDisk aCI (aFunction);
330
331   Handle(GEOM_Function) aRefPnt = thePnt->GetLastFunction();
332   Handle(GEOM_Function) aRefVec = theVec->GetLastFunction();
333
334   if (aRefPnt.IsNull() || aRefVec.IsNull()) return NULL;
335
336   aCI.SetCenter(aRefPnt);
337   aCI.SetVector(aRefVec);
338   aCI.SetRadius(theR);
339
340   //Compute the Disk value
341   try {
342     OCC_CATCH_SIGNALS;
343     if (!GetSolver()->ComputeFunction(aFunction)) {
344       SetErrorCode("Disk driver failed");
345       return NULL;
346     }
347   }
348   catch (Standard_Failure& aFail) {
349     SetErrorCode(aFail.GetMessageString());
350     return NULL;
351   }
352
353   //Make a Python command
354   GEOM::TPythonDump(aFunction) << aDisk << " = geompy.MakeDiskPntVecR("
355     << thePnt << ", " << theVec << ", " << theR << ")";
356
357   SetErrorCode(OK);
358   return aDisk;
359 }
360
361 //=============================================================================
362 /*!
363  *  MakeDiskThreePnt
364  */
365 //=============================================================================
366 Handle(GEOM_Object) GEOMImpl_I3DPrimOperations::MakeDiskThreePnt (Handle(GEOM_Object) thePnt1,
367                                                                   Handle(GEOM_Object) thePnt2,
368                                                                   Handle(GEOM_Object) thePnt3)
369 {
370   SetErrorCode(KO);
371
372   if (thePnt1.IsNull() || thePnt2.IsNull() || thePnt3.IsNull()) return NULL;
373
374   //Add a new Disk object
375   Handle(GEOM_Object) aDisk = GetEngine()->AddObject(GEOM_FACE);
376
377   //Add a new Disk function for creation a disk relatively to three points
378   Handle(GEOM_Function) aFunction =
379     aDisk->AddFunction(GEOMImpl_DiskDriver::GetID(), DISK_THREE_PNT);
380   if (aFunction.IsNull()) return NULL;
381
382   //Check if the function is set correctly
383   if (aFunction->GetDriverGUID() != GEOMImpl_DiskDriver::GetID()) return NULL;
384
385   GEOMImpl_IDisk aCI (aFunction);
386
387   Handle(GEOM_Function) aRefPnt1 = thePnt1->GetLastFunction();
388   Handle(GEOM_Function) aRefPnt2 = thePnt2->GetLastFunction();
389   Handle(GEOM_Function) aRefPnt3 = thePnt3->GetLastFunction();
390
391   if (aRefPnt1.IsNull() || aRefPnt2.IsNull() || aRefPnt3.IsNull()) return NULL;
392
393   aCI.SetPoint1(aRefPnt1);
394   aCI.SetPoint2(aRefPnt2);
395   aCI.SetPoint3(aRefPnt3);
396
397   //Compute the Disk value
398   try {
399     OCC_CATCH_SIGNALS;
400     if (!GetSolver()->ComputeFunction(aFunction)) {
401       SetErrorCode("Disk driver failed");
402       return NULL;
403     }
404   }
405   catch (Standard_Failure& aFail) {
406     SetErrorCode(aFail.GetMessageString());
407     return NULL;
408   }
409
410   //Make a Python command
411   GEOM::TPythonDump(aFunction) << aDisk << " = geompy.MakeDiskThreePnt("
412     << thePnt1 << ", " << thePnt2 << ", " << thePnt3 << ")";
413
414   SetErrorCode(OK);
415   return aDisk;
416 }
417
418 //=============================================================================
419 /*!
420  *  MakeDiskR
421  */
422 //=============================================================================
423 Handle(GEOM_Object) GEOMImpl_I3DPrimOperations::MakeDiskR (double theR, int theOrientation)
424 {
425   SetErrorCode(KO);
426
427   if (theR == 0 ) return NULL;
428
429   //Add a new Disk object
430   Handle(GEOM_Object) aDisk = GetEngine()->AddObject(GEOM_FACE);
431
432   //Add a new Box function for creation a box relatively to two points
433   Handle(GEOM_Function) aFunction = aDisk->AddFunction(GEOMImpl_DiskDriver::GetID(), DISK_R);
434   if (aFunction.IsNull()) return NULL;
435
436   //Check if the function is set correctly
437   if (aFunction->GetDriverGUID() != GEOMImpl_DiskDriver::GetID()) return aDisk;
438
439   GEOMImpl_IDisk aDI (aFunction);
440
441   aDI.SetRadius(theR);
442   aDI.SetOrientation(theOrientation);
443
444   //Compute the Disk
445   try {
446     OCC_CATCH_SIGNALS;
447     if (!GetSolver()->ComputeFunction(aFunction)) {
448       SetErrorCode("Disk driver failed");
449       return NULL;
450     }
451   }
452   catch (Standard_Failure& aFail) {
453     SetErrorCode(aFail.GetMessageString());
454     return NULL;
455   }
456
457   //Make a Python command
458   GEOM::TPythonDump(aFunction) << aDisk << " = geompy.MakeDiskR("
459     << theR << ", " << theOrientation << ")";
460
461   SetErrorCode(OK);
462   return aDisk;
463 }
464
465 //=============================================================================
466 /*!
467  *  MakeCylinderRH
468  */
469 //=============================================================================
470 Handle(GEOM_Object) GEOMImpl_I3DPrimOperations::MakeCylinderRH (double theR, double theH)
471 {
472   SetErrorCode(KO);
473
474   //Add a new Cylinder object
475   Handle(GEOM_Object) aCylinder = GetEngine()->AddObject(GEOM_CYLINDER);
476
477   //Add a new Cylinder function with R and H parameters
478   Handle(GEOM_Function) aFunction = aCylinder->AddFunction(GEOMImpl_CylinderDriver::GetID(), CYLINDER_R_H);
479   if (aFunction.IsNull()) return NULL;
480
481   //Check if the function is set correctly
482   if (aFunction->GetDriverGUID() != GEOMImpl_CylinderDriver::GetID()) return NULL;
483
484   GEOMImpl_ICylinder aCI (aFunction);
485
486   aCI.SetR(theR);
487   aCI.SetH(theH);
488
489   //Compute the Cylinder value
490   try {
491     OCC_CATCH_SIGNALS;
492     if (!GetSolver()->ComputeFunction(aFunction)) {
493       SetErrorCode("Cylinder driver failed");
494       return NULL;
495     }
496   }
497   catch (Standard_Failure& aFail) {
498     SetErrorCode(aFail.GetMessageString());
499     return NULL;
500   }
501
502   //Make a Python command
503   GEOM::TPythonDump(aFunction) << aCylinder
504     << " = geompy.MakeCylinderRH(" << theR << ", " << theH << ")";
505
506   SetErrorCode(OK);
507   return aCylinder;
508 }
509
510 //=============================================================================
511 /*!
512  *  MakeCylinderRHA
513  */
514 //=============================================================================
515 Handle(GEOM_Object) GEOMImpl_I3DPrimOperations::MakeCylinderRHA (double theR, double theH, double theA)
516 {
517   SetErrorCode(KO);
518
519   //Add a new Cylinder object
520   Handle(GEOM_Object) aCylinder = GetEngine()->AddObject(GEOM_CYLINDER);
521
522   //Add a new Cylinder function with R and H parameters
523   Handle(GEOM_Function) aFunction = aCylinder->AddFunction(GEOMImpl_CylinderDriver::GetID(), CYLINDER_R_H_A);
524   if (aFunction.IsNull()) return NULL;
525
526   //Check if the function is set correctly
527   if (aFunction->GetDriverGUID() != GEOMImpl_CylinderDriver::GetID()) return NULL;
528
529   GEOMImpl_ICylinder aCI (aFunction);
530
531   aCI.SetR(theR);
532   aCI.SetH(theH);
533   aCI.SetA(theA);
534
535   //Compute the Cylinder value
536   try {
537     OCC_CATCH_SIGNALS;
538     if (!GetSolver()->ComputeFunction(aFunction)) {
539       SetErrorCode("Cylinder driver failed");
540       return NULL;
541     }
542   }
543   catch (Standard_Failure& aFail) {
544     SetErrorCode(aFail.GetMessageString());
545     return NULL;
546   }
547
548   //Make a Python command
549   GEOM::TPythonDump(aFunction) << aCylinder
550     << " = geompy.MakeCylinderRHA(" << theR << ", " << theH << ", " << theA*180./M_PI << "*math.pi/180.)";
551
552   SetErrorCode(OK);
553   return aCylinder;
554 }
555
556 //=============================================================================
557 /*!
558  *  MakeCylinderPntVecRH
559  */
560 //=============================================================================
561 Handle(GEOM_Object) GEOMImpl_I3DPrimOperations::MakeCylinderPntVecRH (Handle(GEOM_Object) thePnt,
562                                                                       Handle(GEOM_Object) theVec,
563                                                                       double theR, double theH)
564 {
565   SetErrorCode(KO);
566
567   if (thePnt.IsNull() || theVec.IsNull()) return NULL;
568
569   //Add a new Cylinder object
570   Handle(GEOM_Object) aCylinder = GetEngine()->AddObject(GEOM_CYLINDER);
571
572   //Add a new Cylinder function for creation a cylinder relatively to point and vector
573   Handle(GEOM_Function) aFunction =
574     aCylinder->AddFunction(GEOMImpl_CylinderDriver::GetID(), CYLINDER_PNT_VEC_R_H);
575   if (aFunction.IsNull()) return NULL;
576
577   //Check if the function is set correctly
578   if (aFunction->GetDriverGUID() != GEOMImpl_CylinderDriver::GetID()) return NULL;
579
580   GEOMImpl_ICylinder aCI (aFunction);
581
582   Handle(GEOM_Function) aRefPnt = thePnt->GetLastFunction();
583   Handle(GEOM_Function) aRefVec = theVec->GetLastFunction();
584
585   if (aRefPnt.IsNull() || aRefVec.IsNull()) return NULL;
586
587   aCI.SetPoint(aRefPnt);
588   aCI.SetVector(aRefVec);
589   aCI.SetR(theR);
590   aCI.SetH(theH);
591
592   //Compute the Cylinder value
593   try {
594     OCC_CATCH_SIGNALS;
595     if (!GetSolver()->ComputeFunction(aFunction)) {
596       SetErrorCode("Cylinder driver failed");
597       return NULL;
598     }
599   }
600   catch (Standard_Failure& aFail) {
601     SetErrorCode(aFail.GetMessageString());
602     return NULL;
603   }
604
605   //Make a Python command
606   GEOM::TPythonDump(aFunction) << aCylinder << " = geompy.MakeCylinder("
607     << thePnt << ", " << theVec << ", " << theR << ", " << theH << ")";
608
609   SetErrorCode(OK);
610   return aCylinder;
611 }
612
613 //=============================================================================
614 /*!
615  *  MakeCylinderPntVecRHA
616  */
617 //=============================================================================
618 Handle(GEOM_Object) GEOMImpl_I3DPrimOperations::MakeCylinderPntVecRHA (Handle(GEOM_Object) thePnt,
619                                                                        Handle(GEOM_Object) theVec,
620                                                                        double theR, double theH, double theA)
621 {
622   SetErrorCode(KO);
623
624   if (thePnt.IsNull() || theVec.IsNull()) return NULL;
625
626   //Add a new Cylinder object
627   Handle(GEOM_Object) aCylinder = GetEngine()->AddObject(GEOM_CYLINDER);
628
629   //Add a new Cylinder function for creation a cylinder relatively to point and vector
630   Handle(GEOM_Function) aFunction =
631     aCylinder->AddFunction(GEOMImpl_CylinderDriver::GetID(), CYLINDER_PNT_VEC_R_H_A);
632   if (aFunction.IsNull()) return NULL;
633
634   //Check if the function is set correctly
635   if (aFunction->GetDriverGUID() != GEOMImpl_CylinderDriver::GetID()) return NULL;
636
637   GEOMImpl_ICylinder aCI (aFunction);
638
639   Handle(GEOM_Function) aRefPnt = thePnt->GetLastFunction();
640   Handle(GEOM_Function) aRefVec = theVec->GetLastFunction();
641
642   if (aRefPnt.IsNull() || aRefVec.IsNull()) return NULL;
643
644   aCI.SetPoint(aRefPnt);
645   aCI.SetVector(aRefVec);
646   aCI.SetR(theR);
647   aCI.SetH(theH);
648   aCI.SetA(theA);
649
650   //Compute the Cylinder value
651   try {
652     OCC_CATCH_SIGNALS;
653     if (!GetSolver()->ComputeFunction(aFunction)) {
654       SetErrorCode("Cylinder driver failed");
655       return NULL;
656     }
657   }
658   catch (Standard_Failure& aFail) {
659     SetErrorCode(aFail.GetMessageString());
660     return NULL;
661   }
662
663   //Make a Python command
664   GEOM::TPythonDump(aFunction) << aCylinder << " = geompy.MakeCylinderA("
665     << thePnt << ", " << theVec << ", " << theR << ", " << theH << ", " << theA*180./M_PI << "*math.pi/180.)";
666
667   SetErrorCode(OK);
668   return aCylinder;
669 }
670
671
672 //=============================================================================
673 /*!
674  *  MakeConeR1R2H
675  */
676 //=============================================================================
677 Handle(GEOM_Object) GEOMImpl_I3DPrimOperations::MakeConeR1R2H (double theR1, double theR2,
678                                                                double theH)
679 {
680   SetErrorCode(KO);
681
682   //Add a new Cone object
683   Handle(GEOM_Object) aCone = GetEngine()->AddObject(GEOM_CONE);
684
685   //Add a new Cone function with R and H parameters
686   Handle(GEOM_Function) aFunction =
687     aCone->AddFunction(GEOMImpl_ConeDriver::GetID(), CONE_R1_R2_H);
688   if (aFunction.IsNull()) return NULL;
689
690   //Check if the function is set correctly
691   if (aFunction->GetDriverGUID() != GEOMImpl_ConeDriver::GetID()) return NULL;
692
693   GEOMImpl_ICone aCI (aFunction);
694
695   aCI.SetR1(theR1);
696   aCI.SetR2(theR2);
697   aCI.SetH(theH);
698
699   //Compute the Cone value
700   try {
701     OCC_CATCH_SIGNALS;
702     if (!GetSolver()->ComputeFunction(aFunction)) {
703       SetErrorCode("Cone driver failed");
704       return NULL;
705     }
706   }
707   catch (Standard_Failure& aFail) {
708     SetErrorCode(aFail.GetMessageString());
709     return NULL;
710   }
711
712   //Make a Python command
713   GEOM::TPythonDump(aFunction) << aCone << " = geompy.MakeConeR1R2H("
714     << theR1 << ", " << theR2 << ", " << theH << ")";
715
716   SetErrorCode(OK);
717   return aCone;
718 }
719
720
721 //=============================================================================
722 /*!
723  *  MakeConePntVecR1R2H
724  */
725 //=============================================================================
726 Handle(GEOM_Object) GEOMImpl_I3DPrimOperations::MakeConePntVecR1R2H (Handle(GEOM_Object) thePnt,
727                                                                      Handle(GEOM_Object) theVec,
728                                                                      double theR1, double theR2,
729                                                                      double theH)
730 {
731   SetErrorCode(KO);
732
733   if (thePnt.IsNull() || theVec.IsNull()) return NULL;
734
735   //Add a new Cone object
736   Handle(GEOM_Object) aCone = GetEngine()->AddObject(GEOM_CONE);
737
738   //Add a new Cone function for creation a cone relatively to point and vector
739   Handle(GEOM_Function) aFunction =
740     aCone->AddFunction(GEOMImpl_ConeDriver::GetID(), CONE_PNT_VEC_R1_R2_H);
741   if (aFunction.IsNull()) return NULL;
742
743   //Check if the function is set correctly
744   if (aFunction->GetDriverGUID() != GEOMImpl_ConeDriver::GetID()) return NULL;
745
746   GEOMImpl_ICone aCI (aFunction);
747
748   Handle(GEOM_Function) aRefPnt = thePnt->GetLastFunction();
749   Handle(GEOM_Function) aRefVec = theVec->GetLastFunction();
750
751   if (aRefPnt.IsNull() || aRefVec.IsNull()) return NULL;
752
753   aCI.SetPoint(aRefPnt);
754   aCI.SetVector(aRefVec);
755   aCI.SetR1(theR1);
756   aCI.SetR2(theR2);
757   aCI.SetH(theH);
758
759   //Compute the Cone value
760   try {
761     OCC_CATCH_SIGNALS;
762     if (!GetSolver()->ComputeFunction(aFunction)) {
763       SetErrorCode("Cone driver failed");
764       return NULL;
765     }
766   }
767   catch (Standard_Failure& aFail) {
768     SetErrorCode(aFail.GetMessageString());
769     return NULL;
770   }
771
772   //Make a Python command
773   GEOM::TPythonDump(aFunction) << aCone << " = geompy.MakeCone(" << thePnt
774     << ", " << theVec << ", " << theR1 << ", " << theR2 << ", " << theH << ")";
775
776   SetErrorCode(OK);
777   return aCone;
778 }
779
780
781 //=============================================================================
782 /*!
783  *  MakeSphereR
784  */
785 //=============================================================================
786 Handle(GEOM_Object) GEOMImpl_I3DPrimOperations::MakeSphereR (double theR)
787 {
788   SetErrorCode(KO);
789
790   //Add a new Sphere object
791   Handle(GEOM_Object) aSphere = GetEngine()->AddObject(GEOM_SPHERE);
792
793   //Add a new Sphere function with R parameter
794   Handle(GEOM_Function) aFunction = aSphere->AddFunction(GEOMImpl_SphereDriver::GetID(), SPHERE_R);
795   if (aFunction.IsNull()) return NULL;
796
797   //Check if the function is set correctly
798   if (aFunction->GetDriverGUID() != GEOMImpl_SphereDriver::GetID()) return NULL;
799
800   GEOMImpl_ISphere aCI (aFunction);
801
802   aCI.SetR(theR);
803
804   //Compute the Sphere value
805   try {
806     OCC_CATCH_SIGNALS;
807     if (!GetSolver()->ComputeFunction(aFunction)) {
808       SetErrorCode("Sphere driver failed");
809       return NULL;
810     }
811   }
812   catch (Standard_Failure& aFail) {
813     SetErrorCode(aFail.GetMessageString());
814     return NULL;
815   }
816
817   //Make a Python command
818   GEOM::TPythonDump(aFunction) << aSphere << " = geompy.MakeSphereR(" << theR << ")";
819
820   SetErrorCode(OK);
821   return aSphere;
822 }
823
824
825 //=============================================================================
826 /*!
827  *  MakeSpherePntR
828  */
829 //=============================================================================
830 Handle(GEOM_Object) GEOMImpl_I3DPrimOperations::MakeSpherePntR (Handle(GEOM_Object) thePnt,
831                                                                 double theR)
832 {
833   SetErrorCode(KO);
834
835   if (thePnt.IsNull()) return NULL;
836
837   //Add a new Point object
838   Handle(GEOM_Object) aSphere = GetEngine()->AddObject(GEOM_SPHERE);
839
840   //Add a new Sphere function for creation a sphere relatively to point
841   Handle(GEOM_Function) aFunction = aSphere->AddFunction(GEOMImpl_SphereDriver::GetID(), SPHERE_PNT_R);
842   if (aFunction.IsNull()) return NULL;
843
844   //Check if the function is set correctly
845   if (aFunction->GetDriverGUID() != GEOMImpl_SphereDriver::GetID()) return NULL;
846
847   GEOMImpl_ISphere aCI (aFunction);
848
849   Handle(GEOM_Function) aRefPnt = thePnt->GetLastFunction();
850
851   if (aRefPnt.IsNull()) return NULL;
852
853   aCI.SetPoint(aRefPnt);
854   aCI.SetR(theR);
855
856   //Compute the Sphere value
857   try {
858     OCC_CATCH_SIGNALS;
859     if (!GetSolver()->ComputeFunction(aFunction)) {
860       SetErrorCode("Sphere driver failed");
861       return NULL;
862     }
863   }
864   catch (Standard_Failure& aFail) {
865     SetErrorCode(aFail.GetMessageString());
866     return NULL;
867   }
868
869   //Make a Python command
870   GEOM::TPythonDump(aFunction) << aSphere
871     << " = geompy.MakeSpherePntR(" << thePnt << ", " << theR << ")";
872
873   SetErrorCode(OK);
874   return aSphere;
875 }
876
877
878 //=============================================================================
879 /*!
880  *  MakeTorusRR
881  */
882 //=============================================================================
883 Handle(GEOM_Object) GEOMImpl_I3DPrimOperations::MakeTorusRR
884                                            (double theRMajor, double theRMinor)
885 {
886   SetErrorCode(KO);
887
888   //Add a new Torus object
889   Handle(GEOM_Object) anEll = GetEngine()->AddObject(GEOM_TORUS);
890
891   //Add a new Torus function
892   Handle(GEOM_Function) aFunction =
893     anEll->AddFunction(GEOMImpl_TorusDriver::GetID(), TORUS_RR);
894   if (aFunction.IsNull()) return NULL;
895
896   //Check if the function is set correctly
897   if (aFunction->GetDriverGUID() != GEOMImpl_TorusDriver::GetID()) return NULL;
898
899   GEOMImpl_ITorus aCI (aFunction);
900
901   aCI.SetRMajor(theRMajor);
902   aCI.SetRMinor(theRMinor);
903
904   //Compute the Torus value
905   try {
906     OCC_CATCH_SIGNALS;
907     if (!GetSolver()->ComputeFunction(aFunction)) {
908       SetErrorCode("Torus driver failed");
909       return NULL;
910     }
911   }
912   catch (Standard_Failure& aFail) {
913     SetErrorCode(aFail.GetMessageString());
914     return NULL;
915   }
916
917   //Make a Python command
918   GEOM::TPythonDump(aFunction) << anEll << " = geompy.MakeTorusRR("
919     << theRMajor << ", " << theRMinor << ")";
920
921   SetErrorCode(OK);
922   return anEll;
923 }
924
925 //=============================================================================
926 /*!
927  *  MakeTorusPntVecRR
928  */
929 //=============================================================================
930 Handle(GEOM_Object) GEOMImpl_I3DPrimOperations::MakeTorusPntVecRR
931                        (Handle(GEOM_Object) thePnt, Handle(GEOM_Object) theVec,
932                         double theRMajor, double theRMinor)
933 {
934   SetErrorCode(KO);
935
936   if (thePnt.IsNull() || theVec.IsNull()) return NULL;
937
938   //Add a new Torus object
939   Handle(GEOM_Object) anEll = GetEngine()->AddObject(GEOM_TORUS);
940
941   //Add a new Torus function
942   Handle(GEOM_Function) aFunction =
943     anEll->AddFunction(GEOMImpl_TorusDriver::GetID(), TORUS_PNT_VEC_RR);
944   if (aFunction.IsNull()) return NULL;
945
946   //Check if the function is set correctly
947   if (aFunction->GetDriverGUID() != GEOMImpl_TorusDriver::GetID()) return NULL;
948
949   GEOMImpl_ITorus aCI (aFunction);
950
951   Handle(GEOM_Function) aRefPnt = thePnt->GetLastFunction();
952   Handle(GEOM_Function) aRefVec = theVec->GetLastFunction();
953
954   if (aRefPnt.IsNull() || aRefVec.IsNull()) return NULL;
955
956   aCI.SetCenter(aRefPnt);
957   aCI.SetVector(aRefVec);
958   aCI.SetRMajor(theRMajor);
959   aCI.SetRMinor(theRMinor);
960
961   //Compute the Torus value
962   try {
963     OCC_CATCH_SIGNALS;
964     if (!GetSolver()->ComputeFunction(aFunction)) {
965       SetErrorCode("Torus driver failed");
966       return NULL;
967     }
968   }
969   catch (Standard_Failure& aFail) {
970     SetErrorCode(aFail.GetMessageString());
971     return NULL;
972   }
973
974   //Make a Python command
975   GEOM::TPythonDump(aFunction) << anEll << " = geompy.MakeTorus(" << thePnt
976     << ", " << theVec << ", " << theRMajor << ", " << theRMinor << ")";
977
978   SetErrorCode(OK);
979   return anEll;
980 }
981
982
983 //=============================================================================
984 /*!
985  *  MakePrismVecH
986  */
987 //=============================================================================
988 Handle(GEOM_Object) GEOMImpl_I3DPrimOperations::MakePrismVecH (Handle(GEOM_Object) theBase,
989                                                                Handle(GEOM_Object) theVec,
990                                                                double theH, double theScaleFactor)
991 {
992   SetErrorCode(KO);
993
994   if (theBase.IsNull() || theVec.IsNull()) return NULL;
995
996   //Add a new Prism object
997   Handle(GEOM_Object) aPrism = GetEngine()->AddObject(GEOM_PRISM);
998
999   //Add a new Prism function for creation a Prism relatively to vector
1000   Handle(GEOM_Function) aFunction =
1001     aPrism->AddFunction(GEOMImpl_PrismDriver::GetID(), PRISM_BASE_VEC_H);
1002   if (aFunction.IsNull()) return NULL;
1003
1004   //Check if the function is set correctly
1005   if (aFunction->GetDriverGUID() != GEOMImpl_PrismDriver::GetID()) return NULL;
1006
1007   GEOMImpl_IPrism aCI (aFunction);
1008
1009   Handle(GEOM_Function) aRefBase = theBase->GetLastFunction();
1010   Handle(GEOM_Function) aRefVec  = theVec->GetLastFunction();
1011
1012   if (aRefBase.IsNull() || aRefVec.IsNull()) return NULL;
1013
1014   aCI.SetBase(aRefBase);
1015   aCI.SetVector(aRefVec);
1016   aCI.SetH(theH);
1017   aCI.SetScale(theScaleFactor);
1018
1019   //Compute the Prism value
1020   try {
1021     OCC_CATCH_SIGNALS;
1022     if (!GetSolver()->ComputeFunction(aFunction)) {
1023       //SetErrorCode("Prism driver failed");
1024       SetErrorCode("Extrusion can not be created, check input data");
1025       return NULL;
1026     }
1027   }
1028   catch (Standard_Failure& aFail) {
1029     SetErrorCode(aFail.GetMessageString());
1030     return NULL;
1031   }
1032
1033   //Make a Python command
1034   GEOM::TPythonDump pd (aFunction);
1035   pd << aPrism << " = geompy.MakePrismVecH(" << theBase << ", " << theVec << ", " << theH;
1036   if (theScaleFactor > Precision::Confusion())
1037     pd << ", " << theScaleFactor << ")";
1038   else
1039     pd << ")";
1040
1041   SetErrorCode(OK);
1042   return aPrism;
1043 }
1044
1045 //=============================================================================
1046 /*!
1047  *  MakePrismVecH2Ways
1048  */
1049 //=============================================================================
1050 Handle(GEOM_Object) GEOMImpl_I3DPrimOperations::MakePrismVecH2Ways (Handle(GEOM_Object) theBase,
1051                                                                     Handle(GEOM_Object) theVec,
1052                                                                     double theH)
1053 {
1054   SetErrorCode(KO);
1055
1056   if (theBase.IsNull() || theVec.IsNull()) return NULL;
1057
1058   //Add a new Prism object
1059   Handle(GEOM_Object) aPrism = GetEngine()->AddObject(GEOM_PRISM);
1060
1061   //Add a new Prism function for creation a Prism relatively to vector
1062   Handle(GEOM_Function) aFunction =
1063     aPrism->AddFunction(GEOMImpl_PrismDriver::GetID(), PRISM_BASE_VEC_H_2WAYS);
1064   if (aFunction.IsNull()) return NULL;
1065
1066   //Check if the function is set correctly
1067   if (aFunction->GetDriverGUID() != GEOMImpl_PrismDriver::GetID()) return NULL;
1068
1069   GEOMImpl_IPrism aCI (aFunction);
1070
1071   Handle(GEOM_Function) aRefBase = theBase->GetLastFunction();
1072   Handle(GEOM_Function) aRefVec  = theVec->GetLastFunction();
1073
1074   if (aRefBase.IsNull() || aRefVec.IsNull()) return NULL;
1075
1076   aCI.SetBase(aRefBase);
1077   aCI.SetVector(aRefVec);
1078   aCI.SetH(theH);
1079
1080   //Compute the Prism value
1081   try {
1082     OCC_CATCH_SIGNALS;
1083     if (!GetSolver()->ComputeFunction(aFunction)) {
1084       //SetErrorCode("Prism driver failed");
1085       SetErrorCode("Extrusion can not be created, check input data");
1086       return NULL;
1087     }
1088   }
1089   catch (Standard_Failure& aFail) {
1090     SetErrorCode(aFail.GetMessageString());
1091     return NULL;
1092   }
1093
1094   //Make a Python command
1095   GEOM::TPythonDump(aFunction) << aPrism << " = geompy.MakePrismVecH2Ways("
1096     << theBase << ", " << theVec << ", " << theH << ")";
1097
1098   SetErrorCode(OK);
1099   return aPrism;
1100 }
1101
1102 //=============================================================================
1103 /*!
1104  *  MakePrismTwoPnt
1105  */
1106 //=============================================================================
1107 Handle(GEOM_Object) GEOMImpl_I3DPrimOperations::MakePrismTwoPnt
1108        (Handle(GEOM_Object) theBase,
1109         Handle(GEOM_Object) thePoint1, Handle(GEOM_Object) thePoint2,
1110         double theScaleFactor)
1111 {
1112   SetErrorCode(KO);
1113
1114   if (theBase.IsNull() || thePoint1.IsNull() || thePoint2.IsNull()) return NULL;
1115
1116   //Add a new Prism object
1117   Handle(GEOM_Object) aPrism = GetEngine()->AddObject(GEOM_PRISM);
1118
1119   //Add a new Prism function for creation a Prism relatively to two points
1120   Handle(GEOM_Function) aFunction =
1121     aPrism->AddFunction(GEOMImpl_PrismDriver::GetID(), PRISM_BASE_TWO_PNT);
1122   if (aFunction.IsNull()) return NULL;
1123
1124   //Check if the function is set correctly
1125   if (aFunction->GetDriverGUID() != GEOMImpl_PrismDriver::GetID()) return NULL;
1126
1127   GEOMImpl_IPrism aCI (aFunction);
1128
1129   Handle(GEOM_Function) aRefBase = theBase->GetLastFunction();
1130   Handle(GEOM_Function) aRefPnt1 = thePoint1->GetLastFunction();
1131   Handle(GEOM_Function) aRefPnt2 = thePoint2->GetLastFunction();
1132
1133   if (aRefBase.IsNull() || aRefPnt1.IsNull() || aRefPnt2.IsNull()) return NULL;
1134
1135   aCI.SetBase(aRefBase);
1136   aCI.SetFirstPoint(aRefPnt1);
1137   aCI.SetLastPoint(aRefPnt2);
1138   aCI.SetScale(theScaleFactor);
1139
1140   //Compute the Prism value
1141   try {
1142     OCC_CATCH_SIGNALS;
1143     if (!GetSolver()->ComputeFunction(aFunction)) {
1144       //SetErrorCode("Prism driver failed");
1145       SetErrorCode("Extrusion can not be created, check input data");
1146       return NULL;
1147     }
1148   }
1149   catch (Standard_Failure& aFail) {
1150     SetErrorCode(aFail.GetMessageString());
1151     return NULL;
1152   }
1153
1154   //Make a Python command
1155   GEOM::TPythonDump pd (aFunction);
1156   pd << aPrism << " = geompy.MakePrism(" << theBase << ", " << thePoint1 << ", " << thePoint2;
1157   if (theScaleFactor > Precision::Confusion())
1158     pd << ", " << theScaleFactor << ")";
1159   else
1160     pd << ")";
1161
1162   SetErrorCode(OK);
1163   return aPrism;
1164 }
1165
1166 //=============================================================================
1167 /*!
1168  *  MakePrismTwoPnt2Ways
1169  */
1170 //=============================================================================
1171 Handle(GEOM_Object) GEOMImpl_I3DPrimOperations::MakePrismTwoPnt2Ways
1172        (Handle(GEOM_Object) theBase,
1173         Handle(GEOM_Object) thePoint1, Handle(GEOM_Object) thePoint2)
1174 {
1175   SetErrorCode(KO);
1176
1177   if (theBase.IsNull() || thePoint1.IsNull() || thePoint2.IsNull()) return NULL;
1178
1179   //Add a new Prism object
1180   Handle(GEOM_Object) aPrism = GetEngine()->AddObject(GEOM_PRISM);
1181
1182   //Add a new Prism function for creation a Prism relatively to two points
1183   Handle(GEOM_Function) aFunction =
1184     aPrism->AddFunction(GEOMImpl_PrismDriver::GetID(), PRISM_BASE_TWO_PNT_2WAYS);
1185   if (aFunction.IsNull()) return NULL;
1186
1187   //Check if the function is set correctly
1188   if (aFunction->GetDriverGUID() != GEOMImpl_PrismDriver::GetID()) return NULL;
1189
1190   GEOMImpl_IPrism aCI (aFunction);
1191
1192   Handle(GEOM_Function) aRefBase = theBase->GetLastFunction();
1193   Handle(GEOM_Function) aRefPnt1 = thePoint1->GetLastFunction();
1194   Handle(GEOM_Function) aRefPnt2 = thePoint2->GetLastFunction();
1195
1196   if (aRefBase.IsNull() || aRefPnt1.IsNull() || aRefPnt2.IsNull()) return NULL;
1197
1198   aCI.SetBase(aRefBase);
1199   aCI.SetFirstPoint(aRefPnt1);
1200   aCI.SetLastPoint(aRefPnt2);
1201
1202   //Compute the Prism value
1203   try {
1204     OCC_CATCH_SIGNALS;
1205     if (!GetSolver()->ComputeFunction(aFunction)) {
1206       //SetErrorCode("Prism driver failed");
1207       SetErrorCode("Extrusion can not be created, check input data");
1208       return NULL;
1209     }
1210   }
1211   catch (Standard_Failure& aFail) {
1212     SetErrorCode(aFail.GetMessageString());
1213     return NULL;
1214   }
1215
1216   //Make a Python command
1217   GEOM::TPythonDump(aFunction) << aPrism << " = geompy.MakePrism2Ways("
1218     << theBase << ", " << thePoint1 << ", " << thePoint2 << ")";
1219
1220   SetErrorCode(OK);
1221   return aPrism;
1222 }
1223
1224 //=============================================================================
1225 /*!
1226  *  MakePrismDXDYDZ
1227  */
1228 //=============================================================================
1229 Handle(GEOM_Object) GEOMImpl_I3DPrimOperations::MakePrismDXDYDZ
1230        (Handle(GEOM_Object) theBase, double theDX, double theDY, double theDZ,
1231         double theScaleFactor)
1232 {
1233   SetErrorCode(KO);
1234
1235   if (theBase.IsNull()) return NULL;
1236
1237   //Add a new Prism object
1238   Handle(GEOM_Object) aPrism = GetEngine()->AddObject(GEOM_PRISM);
1239
1240   //Add a new Prism function for creation a Prism by DXDYDZ
1241   Handle(GEOM_Function) aFunction =
1242     aPrism->AddFunction(GEOMImpl_PrismDriver::GetID(), PRISM_BASE_DXDYDZ);
1243   if (aFunction.IsNull()) return NULL;
1244
1245   //Check if the function is set correctly
1246   if (aFunction->GetDriverGUID() != GEOMImpl_PrismDriver::GetID()) return NULL;
1247
1248   GEOMImpl_IPrism aCI (aFunction);
1249
1250   Handle(GEOM_Function) aRefBase = theBase->GetLastFunction();
1251
1252   if (aRefBase.IsNull()) return NULL;
1253
1254   aCI.SetBase(aRefBase);
1255   aCI.SetDX(theDX);
1256   aCI.SetDY(theDY);
1257   aCI.SetDZ(theDZ);
1258   aCI.SetScale(theScaleFactor);
1259
1260   //Compute the Prism value
1261   try {
1262     OCC_CATCH_SIGNALS;
1263     if (!GetSolver()->ComputeFunction(aFunction)) {
1264       SetErrorCode("Extrusion can not be created, check input data");
1265       return NULL;
1266     }
1267   }
1268   catch (Standard_Failure& aFail) {
1269     SetErrorCode(aFail.GetMessageString());
1270     return NULL;
1271   }
1272
1273   //Make a Python command
1274   GEOM::TPythonDump pd (aFunction);
1275   pd << aPrism << " = geompy.MakePrismDXDYDZ("
1276      << theBase << ", " << theDX << ", " << theDY << ", " << theDZ;
1277   if (theScaleFactor > Precision::Confusion())
1278     pd << ", " << theScaleFactor << ")";
1279   else
1280     pd << ")";
1281
1282   SetErrorCode(OK);
1283   return aPrism;
1284 }
1285
1286 //=============================================================================
1287 /*!
1288  *  MakePrismDXDYDZ_2WAYS
1289  */
1290 //=============================================================================
1291 Handle(GEOM_Object) GEOMImpl_I3DPrimOperations::MakePrismDXDYDZ2Ways
1292        (Handle(GEOM_Object) theBase, double theDX, double theDY, double theDZ)
1293 {
1294   SetErrorCode(KO);
1295
1296   if (theBase.IsNull()) return NULL;
1297
1298   //Add a new Prism object
1299   Handle(GEOM_Object) aPrism = GetEngine()->AddObject(GEOM_PRISM);
1300
1301   //Add a new Prism function for creation a Prism by DXDYDZ
1302   Handle(GEOM_Function) aFunction =
1303     aPrism->AddFunction(GEOMImpl_PrismDriver::GetID(), PRISM_BASE_DXDYDZ_2WAYS);
1304   if (aFunction.IsNull()) return NULL;
1305
1306   //Check if the function is set correctly
1307   if (aFunction->GetDriverGUID() != GEOMImpl_PrismDriver::GetID()) return NULL;
1308
1309   GEOMImpl_IPrism aCI (aFunction);
1310
1311   Handle(GEOM_Function) aRefBase = theBase->GetLastFunction();
1312
1313   if (aRefBase.IsNull()) return NULL;
1314
1315   aCI.SetBase(aRefBase);
1316   aCI.SetDX(theDX);
1317   aCI.SetDY(theDY);
1318   aCI.SetDZ(theDZ);
1319
1320   //Compute the Prism value
1321   try {
1322     OCC_CATCH_SIGNALS;
1323     if (!GetSolver()->ComputeFunction(aFunction)) {
1324       SetErrorCode("Extrusion can not be created, check input data");
1325       return NULL;
1326     }
1327   }
1328   catch (Standard_Failure& aFail) {
1329     SetErrorCode(aFail.GetMessageString());
1330     return NULL;
1331   }
1332
1333   //Make a Python command
1334   GEOM::TPythonDump(aFunction) << aPrism << " = geompy.MakePrismDXDYDZ2Ways("
1335     << theBase << ", " << theDX << ", " << theDY << ", " << theDZ << ")";
1336
1337   SetErrorCode(OK);
1338   return aPrism;
1339 }
1340
1341 //=============================================================================
1342 /*!
1343  *  MakeDraftPrism
1344  */
1345 //=============================================================================
1346 Handle(GEOM_Object) GEOMImpl_I3DPrimOperations::MakeDraftPrism
1347        (Handle(GEOM_Object) theInitShape ,Handle(GEOM_Object) theBase, double theHeight, double theAngle, bool theFuse, bool theInvert)
1348 {
1349   SetErrorCode(KO);
1350
1351   if (theBase.IsNull() || theInitShape.IsNull()) return NULL;
1352
1353   Handle(GEOM_Object) aPrism = NULL;
1354   
1355   if ( theFuse )
1356   {
1357     //Add a new Extruded Boss object  
1358     aPrism = GetEngine()->AddObject(GEOM_EXTRUDED_BOSS);
1359   }
1360   else
1361   { 
1362     //Add a new Extruded Cut object  
1363     aPrism = GetEngine()->AddObject(GEOM_EXTRUDED_CUT);
1364   }
1365   
1366   //Add a new Prism function for the creation of a Draft Prism feature
1367   Handle(GEOM_Function) aFunction = 
1368     aPrism->AddFunction(GEOMImpl_PrismDriver::GetID(), DRAFT_PRISM_FEATURE);
1369   if (aFunction.IsNull()) return NULL;
1370   
1371   //Check if the function is set correctly
1372   if (aFunction->GetDriverGUID() != GEOMImpl_PrismDriver::GetID()) return NULL;
1373   
1374   GEOMImpl_IPrism aCI (aFunction);
1375
1376   Handle(GEOM_Function) aRefInit = theInitShape->GetLastFunction();
1377   Handle(GEOM_Function) aRefBase = theBase->GetLastFunction();
1378  
1379   if (aRefBase.IsNull() || aRefInit.IsNull()) return NULL;
1380   
1381   // Set parameters 
1382   aCI.SetBase(aRefBase);
1383   aCI.SetInitShape(aRefInit);
1384   aCI.SetH(theHeight);
1385   aCI.SetDraftAngle(theAngle);
1386   if ( theFuse )
1387     aCI.SetFuseFlag(1);
1388   else
1389     aCI.SetFuseFlag(0);
1390   aCI.SetInvertFlag(theInvert);
1391   
1392   //Compute the Draft Prism Feature value
1393   try {
1394     OCC_CATCH_SIGNALS;
1395     if (!GetSolver()->ComputeFunction(aFunction)) {
1396       SetErrorCode("Extrusion can not be created, check input data");
1397       return NULL;
1398     }
1399   }
1400   catch (Standard_Failure& aFail) {
1401     SetErrorCode(aFail.GetMessageString());
1402     return NULL;
1403   }
1404   
1405   //Make a Python command
1406   GEOM::TPythonDump pd (aFunction);
1407   if(theFuse)
1408   {
1409     pd << aPrism << " = geompy.MakeExtrudedBoss(" << theInitShape << ", " << theBase << ", "
1410       << theHeight << ", " << theAngle;
1411   }
1412   else
1413   {   
1414     pd << aPrism << " = geompy.MakeExtrudedCut(" << theInitShape << ", " << theBase << ", "
1415       << theHeight << ", " << theAngle;
1416   }
1417   if (theInvert)
1418     pd << ", " << theInvert;
1419   pd << ")";
1420
1421   SetErrorCode(OK);
1422   return aPrism;
1423 }
1424
1425 //=============================================================================
1426 /*!
1427  *  MakePipe
1428  */
1429 //=============================================================================
1430 Handle(TColStd_HSequenceOfTransient) GEOMImpl_I3DPrimOperations::MakePipe
1431                             (const Handle(GEOM_Object) &theBase,
1432                              const Handle(GEOM_Object) &thePath,
1433                              const bool                 IsGenerateGroups)
1434 {
1435   SetErrorCode(KO);
1436
1437   if (theBase.IsNull() || thePath.IsNull()) return NULL;
1438
1439   //Add a new Pipe object
1440   Handle(GEOM_Object) aPipe = GetEngine()->AddObject(GEOM_PIPE);
1441
1442   //Add a new Pipe function
1443   Handle(GEOM_Function) aFunction =
1444     aPipe->AddFunction(GEOMImpl_PipeDriver::GetID(), PIPE_BASE_PATH);
1445   if (aFunction.IsNull()) return NULL;
1446
1447   //Check if the function is set correctly
1448   if (aFunction->GetDriverGUID() != GEOMImpl_PipeDriver::GetID()) return NULL;
1449
1450   GEOMImpl_IPipe aCI (aFunction);
1451
1452   Handle(GEOM_Function) aRefBase = theBase->GetLastFunction();
1453   Handle(GEOM_Function) aRefPath = thePath->GetLastFunction();
1454
1455   if (aRefBase.IsNull() || aRefPath.IsNull()) return NULL;
1456
1457   aCI.SetBase(aRefBase);
1458   aCI.SetPath(aRefPath);
1459   aCI.SetGenerateGroups(IsGenerateGroups);
1460
1461   //Compute the Pipe value
1462   try {
1463     OCC_CATCH_SIGNALS;
1464     if (!GetSolver()->ComputeFunction(aFunction)) {
1465       SetErrorCode("Pipe driver failed");
1466       return NULL;
1467     }
1468   }
1469   catch (Standard_Failure& aFail) {
1470     SetErrorCode(aFail.GetMessageString());
1471     return NULL;
1472   }
1473
1474   // Create the sequence of objects.
1475   Handle(TColStd_HSequenceOfTransient) aSeq = new TColStd_HSequenceOfTransient;
1476
1477   aSeq->Append(aPipe);
1478   createGroups(aPipe, &aCI, aSeq);
1479
1480   //Make a Python command
1481   GEOM::TPythonDump pyDump(aFunction);
1482
1483   if (IsGenerateGroups) {
1484     pyDump << aSeq;
1485   } else {
1486     pyDump << aPipe;
1487   }
1488
1489   pyDump << " = geompy.MakePipe(" << theBase << ", " << thePath;
1490
1491   if (IsGenerateGroups) {
1492     pyDump << ", True";
1493   }
1494
1495   pyDump << ")";
1496
1497   SetErrorCode(OK);
1498   return aSeq;
1499 }
1500
1501
1502 //=============================================================================
1503 /*!
1504  *  MakeRevolutionAxisAngle
1505  */
1506 //=============================================================================
1507 Handle(GEOM_Object) GEOMImpl_I3DPrimOperations::MakeRevolutionAxisAngle (Handle(GEOM_Object) theBase,
1508                                                                          Handle(GEOM_Object) theAxis,
1509                                                                          double theAngle)
1510 {
1511   SetErrorCode(KO);
1512
1513   if (theBase.IsNull() || theAxis.IsNull()) return NULL;
1514
1515   //Add a new Revolution object
1516   Handle(GEOM_Object) aRevolution = GetEngine()->AddObject(GEOM_REVOLUTION);
1517
1518   //Add a new Revolution function for creation a revolution relatively to axis
1519   Handle(GEOM_Function) aFunction =
1520     aRevolution->AddFunction(GEOMImpl_RevolutionDriver::GetID(), REVOLUTION_BASE_AXIS_ANGLE);
1521   if (aFunction.IsNull()) return NULL;
1522
1523   //Check if the function is set correctly
1524   if (aFunction->GetDriverGUID() != GEOMImpl_RevolutionDriver::GetID()) return NULL;
1525
1526   GEOMImpl_IRevolution aCI (aFunction);
1527
1528   Handle(GEOM_Function) aRefBase = theBase->GetLastFunction();
1529   Handle(GEOM_Function) aRefAxis = theAxis->GetLastFunction();
1530
1531   if (aRefBase.IsNull() || aRefAxis.IsNull()) return NULL;
1532
1533   aCI.SetBase(aRefBase);
1534   aCI.SetAxis(aRefAxis);
1535   aCI.SetAngle(theAngle);
1536
1537   //Compute the Revolution value
1538   try {
1539     OCC_CATCH_SIGNALS;
1540     if (!GetSolver()->ComputeFunction(aFunction)) {
1541       SetErrorCode("Revolution driver failed");
1542       return NULL;
1543     }
1544   }
1545   catch (Standard_Failure& aFail) {
1546     SetErrorCode(aFail.GetMessageString());
1547     return NULL;
1548   }
1549
1550   //Make a Python command
1551   GEOM::TPythonDump(aFunction) << aRevolution << " = geompy.MakeRevolution("
1552     << theBase << ", " << theAxis << ", " << theAngle * 180.0 / M_PI << "*math.pi/180.0)";
1553   
1554   SetErrorCode(OK);
1555   return aRevolution;
1556 }
1557
1558 //=============================================================================
1559 /*!
1560  *  MakeRevolutionAxisAngle2Ways
1561  */
1562 //=============================================================================
1563 Handle(GEOM_Object) GEOMImpl_I3DPrimOperations::MakeRevolutionAxisAngle2Ways
1564                    (Handle(GEOM_Object) theBase, Handle(GEOM_Object) theAxis, double theAngle)
1565 {
1566   SetErrorCode(KO);
1567
1568   if (theBase.IsNull() || theAxis.IsNull()) return NULL;
1569
1570   //Add a new Revolution object
1571   Handle(GEOM_Object) aRevolution = GetEngine()->AddObject(GEOM_REVOLUTION);
1572
1573   //Add a new Revolution function for creation a revolution relatively to axis
1574   Handle(GEOM_Function) aFunction =
1575     aRevolution->AddFunction(GEOMImpl_RevolutionDriver::GetID(), REVOLUTION_BASE_AXIS_ANGLE_2WAYS);
1576   if (aFunction.IsNull()) return NULL;
1577
1578   //Check if the function is set correctly
1579   if (aFunction->GetDriverGUID() != GEOMImpl_RevolutionDriver::GetID()) return NULL;
1580
1581   GEOMImpl_IRevolution aCI (aFunction);
1582
1583   Handle(GEOM_Function) aRefBase = theBase->GetLastFunction();
1584   Handle(GEOM_Function) aRefAxis = theAxis->GetLastFunction();
1585
1586   if (aRefBase.IsNull() || aRefAxis.IsNull()) return NULL;
1587
1588   aCI.SetBase(aRefBase);
1589   aCI.SetAxis(aRefAxis);
1590   aCI.SetAngle(theAngle);
1591
1592   //Compute the Revolution value
1593   try {
1594     OCC_CATCH_SIGNALS;
1595     if (!GetSolver()->ComputeFunction(aFunction)) {
1596       SetErrorCode("Revolution driver failed");
1597       return NULL;
1598     }
1599   }
1600   catch (Standard_Failure& aFail) {
1601     SetErrorCode(aFail.GetMessageString());
1602     return NULL;
1603   }
1604
1605   //Make a Python command
1606   GEOM::TPythonDump(aFunction) << aRevolution << " = geompy.MakeRevolution2Ways("
1607     << theBase << ", " << theAxis << ", " << theAngle * 180.0 / M_PI << "*math.pi/180.0)";
1608
1609   SetErrorCode(OK);
1610   return aRevolution;
1611 }
1612
1613 //=============================================================================
1614 /*!
1615  *  MakeFilling
1616  */
1617 //=============================================================================
1618 Handle(GEOM_Object)
1619 GEOMImpl_I3DPrimOperations::MakeFilling (std::list< Handle(GEOM_Object)> & theContours,
1620                                          int theMinDeg, int theMaxDeg,
1621                                          double theTol2D, double theTol3D, int theNbIter,
1622                                          int theMethod, bool isApprox)
1623 {
1624   SetErrorCode(KO);
1625
1626   Handle(TColStd_HSequenceOfTransient) contours = GEOM_Object::GetLastFunctions( theContours );
1627   if ( contours.IsNull() || contours->IsEmpty() ) {
1628     SetErrorCode("NULL argument shape");
1629     return NULL;
1630   }
1631   //Add a new Filling object
1632   Handle(GEOM_Object) aFilling = GetEngine()->AddObject(GEOM_FILLING);
1633
1634   //Add a new Filling function for creation a filling  from a compound
1635   Handle(GEOM_Function) aFunction = aFilling->AddFunction(GEOMImpl_FillingDriver::GetID(), BASIC_FILLING);
1636   if (aFunction.IsNull()) return NULL;
1637
1638   //Check if the function is set correctly
1639   if (aFunction->GetDriverGUID() != GEOMImpl_FillingDriver::GetID()) return NULL;
1640
1641   GEOMImpl_IFilling aFI (aFunction);
1642   aFI.SetShapes(contours);
1643   aFI.SetMinDeg(theMinDeg);
1644   aFI.SetMaxDeg(theMaxDeg);
1645   aFI.SetTol2D(theTol2D);
1646   aFI.SetTol3D(theTol3D);
1647   aFI.SetNbIter(theNbIter);
1648   aFI.SetApprox(isApprox);
1649   aFI.SetMethod(theMethod);
1650
1651   //Compute the Solid value
1652   try {
1653     OCC_CATCH_SIGNALS;
1654     if (!GetSolver()->ComputeFunction(aFunction)) {
1655       SetErrorCode("Filling driver failed");
1656       return NULL;
1657     }
1658   }
1659   catch (Standard_Failure& aFail) {
1660     if (strcmp(aFail.GetMessageString(), "Geom_BSplineSurface") == 0)
1661       SetErrorCode("B-Spline surface construction failed");
1662     else
1663       SetErrorCode(aFail.GetMessageString());
1664     return NULL;
1665   }
1666
1667   //Make a Python command
1668   GEOM::TPythonDump pd (aFunction);
1669   pd << aFilling << " = geompy.MakeFilling(" << theContours ;
1670   if ( theMinDeg != 2 )   pd << ", theMinDeg=" << theMinDeg ;
1671   if ( theMaxDeg != 5 )   pd << ", theMaxDeg=" << theMaxDeg ;
1672   if ( fabs(theTol2D-0.0001) > Precision::Confusion() )
1673   {                       pd << ", theTol2D=" << theTol2D ; }
1674   if ( fabs(theTol3D-0.0001) > Precision::Confusion() )
1675   {                       pd << ", theTol3D=" << theTol3D ; }
1676   if ( theNbIter != 0 )   pd << ", theNbIter=" << theNbIter ;
1677   if ( theMethod==1 )     pd << ", theMethod=GEOM.FOM_UseOri";
1678   else if( theMethod==2 ) pd << ", theMethod=GEOM.FOM_AutoCorrect";
1679   if ( isApprox )         pd << ", isApprox=" << isApprox ;
1680   pd << ")";
1681
1682   SetErrorCode(OK);
1683   return aFilling;
1684 }
1685
1686 //=============================================================================
1687 /*!
1688  *  MakeThruSections
1689  */
1690 //=============================================================================
1691 Handle(GEOM_Object) GEOMImpl_I3DPrimOperations::MakeThruSections(
1692                                                 const Handle(TColStd_HSequenceOfTransient)& theSeqSections,
1693                                                 bool theModeSolid,
1694                                                 double thePreci,
1695                                                 bool theRuled)
1696 {
1697   Handle(GEOM_Object) anObj;
1698   SetErrorCode(KO);
1699   if(theSeqSections.IsNull())
1700     return anObj;
1701
1702   Standard_Integer nbObj = theSeqSections->Length();
1703   if (!nbObj)
1704     return anObj;
1705
1706   //Add a new ThruSections object
1707   Handle(GEOM_Object) aThruSect = GetEngine()->AddObject(GEOM_THRUSECTIONS);
1708
1709
1710   //Add a new ThruSections function
1711
1712   int aTypeFunc = (theRuled ? THRUSECTIONS_RULED : THRUSECTIONS_SMOOTHED);
1713   Handle(GEOM_Function) aFunction =
1714     aThruSect->AddFunction(GEOMImpl_ThruSectionsDriver::GetID(), aTypeFunc);
1715   if (aFunction.IsNull()) return anObj;
1716
1717   //Check if the function is set correctly
1718   if (aFunction->GetDriverGUID() != GEOMImpl_ThruSectionsDriver::GetID()) return NULL;
1719
1720   GEOMImpl_IThruSections aCI (aFunction);
1721
1722   Handle(TColStd_HSequenceOfTransient) aSeqSections = new TColStd_HSequenceOfTransient;
1723
1724   Standard_Integer i =1;
1725   for( ; i <= nbObj; i++) {
1726
1727     Handle(Standard_Transient) anItem = theSeqSections->Value(i);
1728     if(anItem.IsNull())
1729       continue;
1730
1731     Handle(GEOM_Object) aSectObj = Handle(GEOM_Object)::DownCast(anItem);
1732     if(!aSectObj.IsNull())
1733     {
1734       Handle(GEOM_Function) aRefSect = aSectObj->GetLastFunction();
1735       if(!aRefSect.IsNull())
1736         aSeqSections->Append(aRefSect);
1737     }
1738   }
1739
1740   if(!aSeqSections->Length())
1741     return anObj;
1742
1743   aCI.SetSections(aSeqSections);
1744   aCI.SetSolidMode(theModeSolid);
1745   aCI.SetPrecision(thePreci);
1746
1747   //Compute the ThruSections value
1748   try {
1749     OCC_CATCH_SIGNALS;
1750     if (!GetSolver()->ComputeFunction(aFunction)) {
1751       SetErrorCode("ThruSections driver failed");
1752       return anObj;
1753     }
1754   }
1755   catch (Standard_Failure& aFail) {
1756     SetErrorCode(aFail.GetMessageString());
1757     return anObj;
1758   }
1759
1760   //Make a Python command
1761   GEOM::TPythonDump pyDump(aFunction);
1762   pyDump << aThruSect << " = geompy.MakeThruSections([";
1763
1764   for(i =1 ; i <= nbObj; i++) {
1765
1766     Handle(Standard_Transient) anItem = theSeqSections->Value(i);
1767     if(anItem.IsNull())
1768       continue;
1769
1770     Handle(GEOM_Object) aSectObj = Handle(GEOM_Object)::DownCast(anItem);
1771     if(!aSectObj.IsNull()) {
1772       pyDump<< aSectObj;
1773       if(i < nbObj)
1774         pyDump<<", ";
1775     }
1776   }
1777
1778   pyDump<< "],"<<theModeSolid << "," << thePreci <<","<< theRuled <<")";
1779
1780   SetErrorCode(OK);
1781   return aThruSect;
1782 }
1783
1784
1785 //=============================================================================
1786 /*!
1787  *  MakePipeWithDifferentSections
1788  */
1789 //=============================================================================
1790 Handle(TColStd_HSequenceOfTransient)
1791   GEOMImpl_I3DPrimOperations::MakePipeWithDifferentSections
1792               (const Handle(TColStd_HSequenceOfTransient) &theBases,
1793                const Handle(TColStd_HSequenceOfTransient) &theLocations,
1794                const Handle(GEOM_Object)                  &thePath,
1795                const bool                                  theWithContact,
1796                const bool                                  theWithCorrections,
1797                const bool                                  IsBySteps,
1798                const bool                                  IsGenerateGroups)
1799 {
1800   SetErrorCode(KO);
1801   if(theBases.IsNull())
1802     return NULL;
1803
1804   Standard_Integer nbBases = theBases->Length();
1805
1806   if (!nbBases)
1807     return NULL;
1808
1809   Standard_Integer nbLocs =  (theLocations.IsNull() ? 0 :theLocations->Length());
1810   //Add a new Pipe object
1811   Handle(GEOM_Object) aPipeDS = GetEngine()->AddObject(GEOM_PIPE);
1812
1813   //Add a new Pipe function
1814
1815   Handle(GEOM_Function) aFunction =
1816     aPipeDS->AddFunction(GEOMImpl_PipeDriver::GetID(), PIPE_DIFFERENT_SECTIONS);
1817   if (aFunction.IsNull()) return NULL;
1818
1819   //Check if the function is set correctly
1820   if (aFunction->GetDriverGUID() != GEOMImpl_PipeDriver::GetID()) return NULL;
1821
1822   GEOMImpl_IPipeDiffSect aCI (aFunction);
1823
1824   Handle(GEOM_Function) aRefPath = thePath->GetLastFunction();
1825   if(aRefPath.IsNull())
1826     return NULL;
1827
1828   Handle(TColStd_HSequenceOfTransient) aSeqBases = new TColStd_HSequenceOfTransient;
1829   Handle(TColStd_HSequenceOfTransient) aSeqLocs = new TColStd_HSequenceOfTransient;
1830
1831   Standard_Integer i =1;
1832   for( ; i <= nbBases; i++) {
1833
1834     Handle(Standard_Transient) anItem = theBases->Value(i);
1835     if(anItem.IsNull())
1836       continue;
1837
1838     Handle(GEOM_Object) aBase = Handle(GEOM_Object)::DownCast(anItem);
1839     if(aBase.IsNull())
1840       continue;
1841     Handle(GEOM_Function) aRefBase = aBase->GetLastFunction();
1842     if(aRefBase.IsNull())
1843       continue;
1844     if(nbLocs)
1845     {
1846       Handle(Standard_Transient) anItemLoc = theLocations->Value(i);
1847       if(anItemLoc.IsNull())
1848         continue;
1849
1850       Handle(GEOM_Object) aLoc = Handle(GEOM_Object)::DownCast(anItemLoc);
1851       if(aLoc.IsNull())
1852         continue;
1853       Handle(GEOM_Function) aRefLoc = aLoc->GetLastFunction();
1854       if(aRefLoc.IsNull())
1855         continue;
1856       aSeqLocs->Append(aRefLoc);
1857     }
1858     aSeqBases->Append(aRefBase);
1859   }
1860
1861   if(!aSeqBases->Length())
1862     return NULL;
1863
1864   aCI.SetBases(aSeqBases);
1865   aCI.SetLocations(aSeqLocs);
1866   aCI.SetPath(aRefPath);
1867
1868   if (!IsBySteps) {
1869     aCI.SetWithContactMode(theWithContact);
1870     aCI.SetWithCorrectionMode(theWithCorrections);
1871   }
1872
1873   aCI.SetIsBySteps(IsBySteps);
1874   aCI.SetGenerateGroups(IsGenerateGroups);
1875
1876   //Compute the Pipe value
1877   try {
1878     OCC_CATCH_SIGNALS;
1879     if (!GetSolver()->ComputeFunction(aFunction)) {
1880       SetErrorCode("Pipe with different section driver failed");
1881       return NULL;
1882     }
1883   }
1884   catch (Standard_Failure& aFail) {
1885     SetErrorCode(aFail.GetMessageString());
1886     return NULL;
1887   }
1888
1889   // Create the sequence of objects.
1890   Handle(TColStd_HSequenceOfTransient) aSeq = new TColStd_HSequenceOfTransient;
1891
1892   aSeq->Append(aPipeDS);
1893   createGroups(aPipeDS, &aCI, aSeq);
1894
1895   //Make a Python command
1896   GEOM::TPythonDump pyDump(aFunction);
1897
1898   if (IsGenerateGroups) {
1899     pyDump << aSeq;
1900   } else {
1901     pyDump << aPipeDS;
1902   }
1903
1904   if (IsBySteps) {
1905     pyDump << " = geompy.MakePipeWithDifferentSectionsBySteps([";
1906   } else {
1907     pyDump << " = geompy.MakePipeWithDifferentSections([";
1908   }
1909
1910   for(i =1 ; i <= nbBases; i++) {
1911
1912     Handle(Standard_Transient) anItem = theBases->Value(i);
1913     if(anItem.IsNull())
1914       continue;
1915
1916     Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast(anItem);
1917     if(!anObj.IsNull()) {
1918       pyDump<< anObj;
1919       if(i < nbBases)
1920         pyDump<<", ";
1921     }
1922   }
1923
1924   pyDump<< "], [";
1925
1926   for(i =1 ; i <= nbLocs; i++) {
1927
1928     Handle(Standard_Transient) anItem = theLocations->Value(i);
1929     if(anItem.IsNull())
1930       continue;
1931
1932     Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast(anItem);
1933     if(!anObj.IsNull()) {
1934       pyDump<< anObj;
1935       if(i < nbLocs)
1936         pyDump<<", ";
1937     }
1938   }
1939
1940   pyDump<< "], "<<thePath;
1941
1942   if (!IsBySteps) {
1943     pyDump<<","<<theWithContact << "," << theWithCorrections;
1944   }
1945
1946   if (IsGenerateGroups) {
1947     pyDump << ", True";
1948   }
1949
1950   pyDump << ")";
1951
1952   SetErrorCode(OK);
1953   return aSeq;
1954 }
1955
1956
1957 //=============================================================================
1958 /*!
1959  *  MakePipeWithShellSections
1960  */
1961 //=============================================================================
1962 Handle(TColStd_HSequenceOfTransient)
1963       GEOMImpl_I3DPrimOperations::MakePipeWithShellSections
1964               (const Handle(TColStd_HSequenceOfTransient) &theBases,
1965                const Handle(TColStd_HSequenceOfTransient) &theSubBases,
1966                const Handle(TColStd_HSequenceOfTransient) &theLocations,
1967                const Handle(GEOM_Object)                  &thePath,
1968                const bool                                  theWithContact,
1969                const bool                                  theWithCorrections,
1970                const bool                                  IsGenerateGroups)
1971 {
1972   SetErrorCode(KO);
1973   if(theBases.IsNull())
1974     return NULL;
1975
1976   Standard_Integer nbBases = theBases->Length();
1977
1978   if (!nbBases)
1979     return NULL;
1980
1981   Standard_Integer nbSubBases =  (theSubBases.IsNull() ? 0 :theSubBases->Length());
1982
1983   Standard_Integer nbLocs =  (theLocations.IsNull() ? 0 :theLocations->Length());
1984
1985   //Add a new Pipe object
1986   Handle(GEOM_Object) aPipeDS = GetEngine()->AddObject(GEOM_PIPE);
1987
1988   //Add a new Pipe function
1989
1990   Handle(GEOM_Function) aFunction =
1991     aPipeDS->AddFunction(GEOMImpl_PipeDriver::GetID(), PIPE_SHELL_SECTIONS);
1992   if (aFunction.IsNull()) return NULL;
1993
1994   //Check if the function is set correctly
1995   if (aFunction->GetDriverGUID() != GEOMImpl_PipeDriver::GetID()) return NULL;
1996
1997   //GEOMImpl_IPipeDiffSect aCI (aFunction);
1998   GEOMImpl_IPipeShellSect aCI (aFunction);
1999
2000   Handle(GEOM_Function) aRefPath = thePath->GetLastFunction();
2001   if(aRefPath.IsNull())
2002     return NULL;
2003
2004   Handle(TColStd_HSequenceOfTransient) aSeqBases = new TColStd_HSequenceOfTransient;
2005   Handle(TColStd_HSequenceOfTransient) aSeqSubBases = new TColStd_HSequenceOfTransient;
2006   Handle(TColStd_HSequenceOfTransient) aSeqLocs = new TColStd_HSequenceOfTransient;
2007
2008   Standard_Integer i =1;
2009   for( ; i <= nbBases; i++) {
2010
2011     Handle(Standard_Transient) anItem = theBases->Value(i);
2012     if(anItem.IsNull())
2013       continue;
2014     Handle(GEOM_Object) aBase = Handle(GEOM_Object)::DownCast(anItem);
2015     if(aBase.IsNull())
2016       continue;
2017     Handle(GEOM_Function) aRefBase = aBase->GetLastFunction();
2018     if(aRefBase.IsNull())
2019       continue;
2020
2021     if( nbSubBases >= nbBases ) {
2022       Handle(Standard_Transient) aSubItem = theSubBases->Value(i);
2023       if(aSubItem.IsNull())
2024         continue;
2025       Handle(GEOM_Object) aSubBase = Handle(GEOM_Object)::DownCast(aSubItem);
2026       if(aSubBase.IsNull())
2027         continue;
2028       Handle(GEOM_Function) aRefSubBase = aSubBase->GetLastFunction();
2029       if(aRefSubBase.IsNull())
2030         continue;
2031       aSeqSubBases->Append(aRefSubBase);
2032     }
2033
2034     if(nbLocs) {
2035       Handle(Standard_Transient) anItemLoc = theLocations->Value(i);
2036       if(anItemLoc.IsNull())
2037         continue;
2038       Handle(GEOM_Object) aLoc = Handle(GEOM_Object)::DownCast(anItemLoc);
2039       if(aLoc.IsNull())
2040         continue;
2041       Handle(GEOM_Function) aRefLoc = aLoc->GetLastFunction();
2042       if(aRefLoc.IsNull())
2043         continue;
2044       aSeqLocs->Append(aRefLoc);
2045     }
2046
2047     aSeqBases->Append(aRefBase);
2048   }
2049
2050   if(!aSeqBases->Length())
2051     return NULL;
2052
2053   aCI.SetBases(aSeqBases);
2054   aCI.SetSubBases(aSeqSubBases);
2055   aCI.SetLocations(aSeqLocs);
2056   aCI.SetPath(aRefPath);
2057   aCI.SetWithContactMode(theWithContact);
2058   aCI.SetWithCorrectionMode(theWithCorrections);
2059   aCI.SetGenerateGroups(IsGenerateGroups);
2060
2061   //Compute the Pipe value
2062   try {
2063     OCC_CATCH_SIGNALS;
2064     if (!GetSolver()->ComputeFunction(aFunction)) {
2065       SetErrorCode("Pipe with shell sections driver failed");
2066       return NULL;
2067     }
2068   }
2069   catch (Standard_Failure& aFail) {
2070     SetErrorCode(aFail.GetMessageString());
2071     return NULL;
2072   }
2073
2074   // Create the sequence of objects.
2075   Handle(TColStd_HSequenceOfTransient) aSeq = new TColStd_HSequenceOfTransient;
2076
2077   aSeq->Append(aPipeDS);
2078   createGroups(aPipeDS, &aCI, aSeq);
2079
2080   //Make a Python command
2081   GEOM::TPythonDump pyDump(aFunction);
2082
2083   if (IsGenerateGroups) {
2084     pyDump << aSeq;
2085   } else {
2086     pyDump << aPipeDS;
2087   }
2088
2089   pyDump << " = geompy.MakePipeWithShellSections([";
2090
2091   for(i =1 ; i <= nbBases; i++) {
2092
2093     Handle(Standard_Transient) anItem = theBases->Value(i);
2094     if(anItem.IsNull())
2095       continue;
2096
2097     Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast(anItem);
2098     if(!anObj.IsNull()) {
2099       pyDump<< anObj;
2100       if(i < nbBases)
2101         pyDump<<", ";
2102     }
2103   }
2104
2105   pyDump<< "], [";
2106
2107   for(i =1 ; i <= nbSubBases; i++) {
2108
2109     Handle(Standard_Transient) anItem = theSubBases->Value(i);
2110     if(anItem.IsNull())
2111       continue;
2112
2113     Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast(anItem);
2114     if(!anObj.IsNull()) {
2115       pyDump<< anObj;
2116       if(i < nbBases)
2117         pyDump<<", ";
2118     }
2119   }
2120
2121   pyDump<< "], [";
2122
2123   for(i =1 ; i <= nbLocs; i++) {
2124
2125     Handle(Standard_Transient) anItem = theLocations->Value(i);
2126     if(anItem.IsNull())
2127       continue;
2128
2129     Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast(anItem);
2130     if(!anObj.IsNull()) {
2131       pyDump<< anObj;
2132       if(i < nbLocs)
2133         pyDump<<", ";
2134     }
2135   }
2136
2137   pyDump<< "], "<<thePath<<","<<theWithContact << "," << theWithCorrections;
2138
2139   if (IsGenerateGroups) {
2140     pyDump << ", True";
2141   }
2142
2143   pyDump << ")";
2144
2145   SetErrorCode(OK);
2146   return aSeq;
2147
2148 }
2149
2150
2151 //=============================================================================
2152 /*!
2153  *  MakePipeShellsWithoutPath
2154  */
2155 //=============================================================================
2156 Handle(TColStd_HSequenceOfTransient)
2157       GEOMImpl_I3DPrimOperations::MakePipeShellsWithoutPath
2158               (const Handle(TColStd_HSequenceOfTransient) &theBases,
2159                const Handle(TColStd_HSequenceOfTransient) &theLocations,
2160                const bool                                  IsGenerateGroups)
2161 {
2162   SetErrorCode(KO);
2163   if(theBases.IsNull())
2164     return NULL;
2165
2166   Standard_Integer nbBases = theBases->Length();
2167
2168   if (!nbBases)
2169     return NULL;
2170
2171   Standard_Integer nbLocs =  (theLocations.IsNull() ? 0 :theLocations->Length());
2172
2173   //Add a new Pipe object
2174   Handle(GEOM_Object) aPipeDS = GetEngine()->AddObject(GEOM_PIPE);
2175
2176   //Add a new Pipe function
2177
2178   Handle(GEOM_Function) aFunction =
2179     aPipeDS->AddFunction(GEOMImpl_PipeDriver::GetID(), PIPE_SHELLS_WITHOUT_PATH);
2180   if (aFunction.IsNull()) return NULL;
2181
2182   //Check if the function is set correctly
2183   if (aFunction->GetDriverGUID() != GEOMImpl_PipeDriver::GetID()) return NULL;
2184
2185   GEOMImpl_IPipeShellSect aCI (aFunction);
2186
2187   Handle(TColStd_HSequenceOfTransient) aSeqBases = new TColStd_HSequenceOfTransient;
2188   Handle(TColStd_HSequenceOfTransient) aSeqLocs = new TColStd_HSequenceOfTransient;
2189
2190   Standard_Integer i =1;
2191   for( ; i <= nbBases; i++) {
2192
2193     Handle(Standard_Transient) anItem = theBases->Value(i);
2194     if(anItem.IsNull())
2195       continue;
2196     Handle(GEOM_Object) aBase = Handle(GEOM_Object)::DownCast(anItem);
2197     if(aBase.IsNull())
2198       continue;
2199     Handle(GEOM_Function) aRefBase = aBase->GetLastFunction();
2200     if(aRefBase.IsNull())
2201       continue;
2202
2203     if(nbLocs) {
2204       Handle(Standard_Transient) anItemLoc = theLocations->Value(i);
2205       if(anItemLoc.IsNull())
2206         continue;
2207       Handle(GEOM_Object) aLoc = Handle(GEOM_Object)::DownCast(anItemLoc);
2208       if(aLoc.IsNull())
2209         continue;
2210       Handle(GEOM_Function) aRefLoc = aLoc->GetLastFunction();
2211       if(aRefLoc.IsNull())
2212         continue;
2213       aSeqLocs->Append(aRefLoc);
2214     }
2215
2216     aSeqBases->Append(aRefBase);
2217   }
2218
2219   if(!aSeqBases->Length())
2220     return NULL;
2221
2222   aCI.SetBases(aSeqBases);
2223   aCI.SetLocations(aSeqLocs);
2224   aCI.SetGenerateGroups(IsGenerateGroups);
2225
2226   //Compute the Pipe value
2227   try {
2228     OCC_CATCH_SIGNALS;
2229     if (!GetSolver()->ComputeFunction(aFunction)) {
2230       SetErrorCode("Pipe with shell sections without path driver failed");
2231       return NULL;
2232     }
2233   }
2234   catch (Standard_Failure& aFail) {
2235     SetErrorCode(aFail.GetMessageString());
2236     return NULL;
2237   }
2238
2239   // Create the sequence of objects.
2240   Handle(TColStd_HSequenceOfTransient) aSeq = new TColStd_HSequenceOfTransient;
2241
2242   aSeq->Append(aPipeDS);
2243   createGroups(aPipeDS, &aCI, aSeq);
2244
2245   //Make a Python command
2246   GEOM::TPythonDump pyDump(aFunction);
2247
2248   if (IsGenerateGroups) {
2249     pyDump << aSeq;
2250   } else {
2251     pyDump << aPipeDS;
2252   }
2253
2254   pyDump << " = geompy.MakePipeShellsWithoutPath([";
2255
2256   for(i =1 ; i <= nbBases; i++) {
2257
2258     Handle(Standard_Transient) anItem = theBases->Value(i);
2259     if(anItem.IsNull())
2260       continue;
2261
2262     Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast(anItem);
2263     if(!anObj.IsNull()) {
2264       pyDump<< anObj;
2265       if(i < nbBases)
2266         pyDump<<", ";
2267     }
2268   }
2269
2270   pyDump<< "], [";
2271
2272   for(i =1 ; i <= nbLocs; i++) {
2273
2274     Handle(Standard_Transient) anItem = theLocations->Value(i);
2275     if(anItem.IsNull())
2276       continue;
2277
2278     Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast(anItem);
2279     if(!anObj.IsNull()) {
2280       pyDump<< anObj;
2281       if(i < nbLocs)
2282         pyDump<<", ";
2283     }
2284   }
2285
2286   pyDump<< "]";
2287
2288   if (IsGenerateGroups) {
2289     pyDump << ", True";
2290   }
2291
2292   pyDump << ")";
2293
2294   SetErrorCode(OK);
2295   return aSeq;
2296
2297 }
2298
2299 //=============================================================================
2300 /*!
2301  *  MakePipeBiNormalAlongVector
2302  */
2303 //=============================================================================
2304 Handle(TColStd_HSequenceOfTransient)
2305   GEOMImpl_I3DPrimOperations::MakePipeBiNormalAlongVector
2306                 (const Handle(GEOM_Object) &theBase,
2307                  const Handle(GEOM_Object) &thePath,
2308                  const Handle(GEOM_Object) &theVec,
2309                  const bool                 IsGenerateGroups)
2310 {
2311   SetErrorCode(KO);
2312
2313   if (theBase.IsNull() || thePath.IsNull() || theVec.IsNull()) return NULL;
2314
2315   //Add a new Pipe object
2316   Handle(GEOM_Object) aPipe = GetEngine()->AddObject(GEOM_PIPE);
2317
2318   //Add a new Pipe function
2319   Handle(GEOM_Function) aFunction =
2320     aPipe->AddFunction(GEOMImpl_PipeDriver::GetID(), PIPE_BI_NORMAL_ALONG_VECTOR);
2321   if (aFunction.IsNull()) return NULL;
2322
2323   //Check if the function is set correctly
2324   if (aFunction->GetDriverGUID() != GEOMImpl_PipeDriver::GetID()) return NULL;
2325
2326   GEOMImpl_IPipeBiNormal aCI (aFunction);
2327
2328   Handle(GEOM_Function) aRefBase = theBase->GetLastFunction();
2329   Handle(GEOM_Function) aRefPath = thePath->GetLastFunction();
2330   Handle(GEOM_Function) aRefVec  = theVec->GetLastFunction();
2331
2332   if (aRefBase.IsNull() || aRefPath.IsNull() || aRefVec.IsNull()) return NULL;
2333
2334   aCI.SetBase(aRefBase);
2335   aCI.SetPath(aRefPath);
2336   aCI.SetVector(aRefVec);
2337   aCI.SetGenerateGroups(IsGenerateGroups);
2338
2339   //Compute the Pipe value
2340   try {
2341     OCC_CATCH_SIGNALS;
2342     if (!GetSolver()->ComputeFunction(aFunction)) {
2343       SetErrorCode("Pipe driver failed");
2344       return NULL;
2345     }
2346   }
2347   catch (Standard_Failure& aFail) {
2348     SetErrorCode(aFail.GetMessageString());
2349     return NULL;
2350   }
2351
2352   // Create the sequence of objects.
2353   Handle(TColStd_HSequenceOfTransient) aSeq = new TColStd_HSequenceOfTransient;
2354
2355   aSeq->Append(aPipe);
2356   createGroups(aPipe, &aCI, aSeq);
2357
2358   //Make a Python command
2359   GEOM::TPythonDump pyDump(aFunction);
2360
2361   if (IsGenerateGroups) {
2362     pyDump << aSeq;
2363   } else {
2364     pyDump << aPipe;
2365   }
2366
2367   pyDump << " = geompy.MakePipeBiNormalAlongVector("
2368          << theBase << ", " << thePath << ", " << theVec;
2369
2370   if (IsGenerateGroups) {
2371     pyDump << ", True";
2372   }
2373
2374   pyDump << ")";
2375
2376   SetErrorCode(OK);
2377   return aSeq;
2378 }
2379
2380 //=============================================================================
2381 /*!
2382  *  MakeThickening
2383  */
2384 //=============================================================================
2385 Handle(GEOM_Object) GEOMImpl_I3DPrimOperations::MakeThickening
2386                 (Handle(GEOM_Object)                     theObject,
2387                  const Handle(TColStd_HArray1OfInteger) &theFacesIDs,
2388                  double                                  theOffset,
2389                  bool                                    isCopy,
2390                  bool                                    theInside)
2391 {
2392   SetErrorCode(KO);
2393
2394   if (theObject.IsNull()) return NULL;
2395
2396   Handle(GEOM_Function) anOriginal = theObject->GetLastFunction();
2397   if (anOriginal.IsNull()) return NULL; //There is no function which creates an object to be offset
2398
2399   //Add a new Offset function
2400   Handle(GEOM_Function) aFunction;
2401   Handle(GEOM_Object) aCopy; 
2402   if (isCopy)
2403   { 
2404     //Add a new Copy object
2405     aCopy = GetEngine()->AddObject(theObject->GetType());
2406     aFunction = aCopy->AddFunction(GEOMImpl_OffsetDriver::GetID(), OFFSET_THICKENING_COPY);
2407   }
2408   else
2409     aFunction = theObject->AddFunction(GEOMImpl_OffsetDriver::GetID(), OFFSET_THICKENING);
2410   
2411   if (aFunction.IsNull()) return NULL;
2412
2413   //Check if the function is set correctly
2414   if (aFunction->GetDriverGUID() != GEOMImpl_OffsetDriver::GetID()) return NULL;
2415
2416   GEOMImpl_IOffset aTI (aFunction);
2417   aTI.SetShape(anOriginal);
2418   aTI.SetValue(theOffset);
2419   aTI.SetParam(theInside);
2420
2421   if (theFacesIDs.IsNull() == Standard_False) {
2422     aTI.SetFaceIDs(theFacesIDs);
2423   }
2424
2425   //Compute the offset
2426   try {
2427     OCC_CATCH_SIGNALS;
2428     if (!GetSolver()->ComputeFunction(aFunction)) {
2429       SetErrorCode("Offset driver failed");
2430       return NULL;
2431     }
2432   }
2433   catch (Standard_Failure& aFail) {
2434     SetErrorCode(aFail.GetMessageString());
2435     return NULL;
2436   }
2437
2438   //Make a Python command
2439   GEOM::TPythonDump   pd (aFunction);
2440   Handle(GEOM_Object) aResult; 
2441
2442   if (isCopy) {
2443     pd << aCopy << " = geompy.MakeThickSolid("
2444        << theObject << ", " << theOffset;
2445     aResult = aCopy;
2446   } else {
2447     pd << "geompy.Thicken(" << theObject << ", " << theOffset;
2448     aResult = theObject;
2449   }
2450
2451   pd << ", [";
2452   if (theFacesIDs.IsNull() == Standard_False) {
2453     // Dump faces IDs.
2454     Standard_Integer i;
2455
2456     for (i = theFacesIDs->Lower(); i < theFacesIDs->Upper(); ++i) {
2457       pd << theFacesIDs->Value(i) << ", ";
2458     }
2459     // Dump the last value.
2460     pd << theFacesIDs->Value(i);
2461   }
2462   pd << "]";
2463
2464   if (theInside)
2465     pd << ", " << theInside;
2466
2467   pd << ")";
2468   SetErrorCode(OK);
2469
2470   return aResult;
2471 }
2472
2473 //=============================================================================
2474 /*!
2475  *  RestorePath
2476  */
2477 //=============================================================================
2478 Handle(GEOM_Object) GEOMImpl_I3DPrimOperations::RestorePath (Handle(GEOM_Object) theShape,
2479                                                              Handle(GEOM_Object) theBase1,
2480                                                              Handle(GEOM_Object) theBase2)
2481 {
2482   SetErrorCode(KO);
2483
2484   if (theShape.IsNull() || theBase1.IsNull() || theBase2.IsNull()) return NULL;
2485
2486   // Add a new Path object
2487   Handle(GEOM_Object) aPath = GetEngine()->AddObject(GEOM_PIPE_PATH);
2488
2489   // Add a new Path function
2490   Handle(GEOM_Function) aFunction =
2491     aPath->AddFunction(GEOMImpl_PipePathDriver::GetID(), PIPE_PATH_TWO_BASES);
2492   if (aFunction.IsNull()) return NULL;
2493
2494   // Check if the function is set correctly
2495   if (aFunction->GetDriverGUID() != GEOMImpl_PipePathDriver::GetID()) return NULL;
2496
2497   GEOMImpl_IPipePath aCI (aFunction);
2498
2499   Handle(GEOM_Function) aRefShape = theShape->GetLastFunction();
2500   Handle(GEOM_Function) aRefBase1 = theBase1->GetLastFunction();
2501   Handle(GEOM_Function) aRefBase2 = theBase2->GetLastFunction();
2502
2503   if (aRefShape.IsNull() || aRefBase1.IsNull() || aRefBase2.IsNull()) return NULL;
2504
2505   aCI.SetShape(aRefShape);
2506   aCI.SetBase1(aRefBase1);
2507   aCI.SetBase2(aRefBase2);
2508
2509   // Compute the Path value
2510   try {
2511     OCC_CATCH_SIGNALS;
2512     if (!GetSolver()->ComputeFunction(aFunction)) {
2513       SetErrorCode("PipePath driver failed");
2514       return NULL;
2515     }
2516   }
2517   catch (Standard_Failure& aFail) {
2518     SetErrorCode("RestorePath: inappropriate arguments given");
2519     return NULL;
2520   }
2521
2522   // Make a Python command
2523   GEOM::TPythonDump(aFunction) << aPath << " = geompy.RestorePath("
2524     << theShape << ", " << theBase1 << ", " << theBase2 << ")";
2525
2526   SetErrorCode(OK);
2527   return aPath;
2528 }
2529
2530 //=============================================================================
2531 /*!
2532  *  RestorePath
2533  */
2534 //=============================================================================
2535 Handle(GEOM_Object) GEOMImpl_I3DPrimOperations::RestorePath
2536                          (Handle(GEOM_Object) theShape,
2537                           const Handle(TColStd_HSequenceOfTransient)& theBase1,
2538                           const Handle(TColStd_HSequenceOfTransient)& theBase2)
2539 {
2540   SetErrorCode(KO);
2541
2542   if (theShape.IsNull() || theBase1.IsNull() || theBase2.IsNull()) return NULL;
2543
2544   Standard_Integer nbBases1 = theBase1->Length();
2545   Standard_Integer nbBases2 = theBase2->Length();
2546
2547   if (!nbBases1 || !nbBases2)
2548     return NULL;
2549
2550   // Add a new Path object
2551   Handle(GEOM_Object) aPath = GetEngine()->AddObject(GEOM_PIPE_PATH);
2552
2553   // Add a new Path function
2554   Handle(GEOM_Function) aFunction =
2555     aPath->AddFunction(GEOMImpl_PipePathDriver::GetID(), PIPE_PATH_TWO_SEQS);
2556   if (aFunction.IsNull()) return NULL;
2557
2558   // Check if the function is set correctly
2559   if (aFunction->GetDriverGUID() != GEOMImpl_PipePathDriver::GetID()) return NULL;
2560
2561   GEOMImpl_IPipePath aCI (aFunction);
2562
2563   Handle(GEOM_Function) aRefShape = theShape->GetLastFunction();
2564   if (aRefShape.IsNull()) return NULL;
2565
2566   Handle(TColStd_HSequenceOfTransient) aSeqBases1 = new TColStd_HSequenceOfTransient;
2567   Handle(TColStd_HSequenceOfTransient) aSeqBases2 = new TColStd_HSequenceOfTransient;
2568
2569   Standard_Integer i;
2570   for (i = 1; i <= nbBases1; i++) {
2571     Handle(Standard_Transient) anItem = theBase1->Value(i);
2572     if (!anItem.IsNull()) {
2573       Handle(GEOM_Object) aBase = Handle(GEOM_Object)::DownCast(anItem);
2574       if (!aBase.IsNull()) {
2575         Handle(GEOM_Function) aRefBase = aBase->GetLastFunction();
2576         if (!aRefBase.IsNull())
2577           aSeqBases1->Append(aRefBase);
2578       }
2579     }
2580   }
2581   for (i = 1; i <= nbBases2; i++) {
2582     Handle(Standard_Transient) anItem = theBase2->Value(i);
2583     if (!anItem.IsNull()) {
2584       Handle(GEOM_Object) aBase = Handle(GEOM_Object)::DownCast(anItem);
2585       if (!aBase.IsNull()) {
2586         Handle(GEOM_Function) aRefBase = aBase->GetLastFunction();
2587         if (!aRefBase.IsNull())
2588           aSeqBases2->Append(aRefBase);
2589       }
2590     }
2591   }
2592   if (!aSeqBases1->Length() || !aSeqBases2->Length()) return NULL;
2593
2594   aCI.SetShape(aRefShape);
2595   aCI.SetBaseSeq1(aSeqBases1);
2596   aCI.SetBaseSeq2(aSeqBases2);
2597
2598   // Compute the Path value
2599   try {
2600     OCC_CATCH_SIGNALS;
2601     if (!GetSolver()->ComputeFunction(aFunction)) {
2602       SetErrorCode("PipePath driver failed");
2603       return NULL;
2604     }
2605   }
2606   catch (Standard_Failure& aFail) {
2607     SetErrorCode("RestorePath: inappropriate arguments given");
2608     return NULL;
2609   }
2610
2611   // Make a Python command
2612   GEOM::TPythonDump pyDump (aFunction);
2613   pyDump << aPath << " = geompy.RestorePathEdges(" << theShape << ", [";
2614   for (i = 1; i <= nbBases1; i++) {
2615     Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast(theBase1->Value(i));
2616     if (!anObj.IsNull()) {
2617       pyDump << anObj;
2618       if (i < nbBases1)
2619         pyDump << ", ";
2620     }
2621   }
2622   pyDump<< "], [";
2623   for (i = 1; i <= nbBases2; i++) {
2624     Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast(theBase2->Value(i));
2625     if (!anObj.IsNull()) {
2626       pyDump << anObj;
2627       if (i < nbBases2)
2628         pyDump << ", ";
2629     }
2630   }
2631   pyDump << "])";
2632
2633   SetErrorCode(OK);
2634   return aPath;
2635 }
2636
2637 //=============================================================================
2638 /*!
2639  *  createGroup
2640  */
2641 //=============================================================================
2642 Handle(GEOM_Object) GEOMImpl_I3DPrimOperations::createGroup
2643                   (const Handle(GEOM_Object)              &theBaseObject,
2644                    const Handle(TColStd_HArray1OfInteger) &theGroupIDs,
2645                    const TCollection_AsciiString          &theName,
2646                    const TopTools_IndexedMapOfShape       &theIndices)
2647 {
2648   if (theBaseObject.IsNull() || theGroupIDs.IsNull()) {
2649     return NULL;
2650   }
2651
2652   // Get the Shape type.
2653   const Standard_Integer anID      = theGroupIDs->Value(theGroupIDs->Lower());
2654   const Standard_Integer aNbShapes = theIndices.Extent();
2655
2656   if (anID < 1 || anID > aNbShapes) {
2657     return NULL;
2658   }
2659
2660   const TopoDS_Shape aSubShape = theIndices.FindKey(anID);
2661
2662   if (aSubShape.IsNull()) {
2663     return NULL;
2664   }
2665
2666   // Create a group.
2667   const TopAbs_ShapeEnum aGroupType = aSubShape.ShapeType();
2668   Handle(GEOM_Object)    aGroup     =
2669     myGroupOperations->CreateGroup(theBaseObject, aGroupType);
2670
2671   if (aGroup.IsNull() == Standard_False) {
2672     aGroup->GetLastFunction()->SetDescription("");
2673     aGroup->SetName(theName.ToCString());
2674
2675     Handle(TColStd_HSequenceOfInteger) aSeqIDs = new TColStd_HSequenceOfInteger;
2676     Standard_Integer                   i;
2677
2678     for (i = theGroupIDs->Lower(); i <= theGroupIDs->Upper(); ++i) {
2679       // Get and check the index.
2680       const Standard_Integer anIndex = theGroupIDs->Value(i);
2681
2682       if (anIndex < 1 || anIndex > aNbShapes) {
2683         return NULL;
2684       }
2685
2686       // Get and check the sub-shape.
2687       const TopoDS_Shape aSubShape = theIndices.FindKey(anIndex);
2688
2689       if (aSubShape.IsNull()) {
2690         return NULL;
2691       }
2692
2693       // Check the shape type.
2694       if (aSubShape.ShapeType() != aGroupType) {
2695         return NULL;
2696       }
2697
2698       aSeqIDs->Append(anIndex);
2699     }
2700
2701     myGroupOperations->UnionIDs(aGroup, aSeqIDs);
2702     aGroup->GetLastFunction()->SetDescription("");
2703   }
2704
2705   return aGroup;
2706 }
2707
2708 //=============================================================================
2709 /*!
2710  *  createGroups
2711  */
2712 //=============================================================================
2713 void GEOMImpl_I3DPrimOperations::createGroups
2714                    (const Handle(GEOM_Object)                  &theBaseObject,
2715                           GEOMImpl_IPipe                       *thePipe,
2716                           Handle(TColStd_HSequenceOfTransient) &theSequence)
2717 {
2718   if (theBaseObject.IsNull() || thePipe == NULL || theSequence.IsNull()) {
2719     return;
2720   }
2721
2722   TopoDS_Shape aShape = theBaseObject->GetValue();
2723
2724   if (aShape.IsNull()) {
2725     return;
2726   }
2727
2728   TopTools_IndexedMapOfShape       anIndices;
2729   Handle(TColStd_HArray1OfInteger) aGroupIDs;
2730   TopoDS_Shape                     aShapeType;
2731   const Standard_Integer           aNbGroups = 5;
2732   Handle(GEOM_Object)              aGrps[aNbGroups];
2733   Standard_Integer                 i;
2734
2735   TopExp::MapShapes(aShape, anIndices);
2736
2737   // Create groups.
2738   aGroupIDs = thePipe->GetGroupDown();
2739   aGrps[0]  = createGroup(theBaseObject, aGroupIDs, "GROUP_DOWN", anIndices);
2740   aGroupIDs = thePipe->GetGroupUp();
2741   aGrps[1]  = createGroup(theBaseObject, aGroupIDs, "GROUP_UP", anIndices);
2742   aGroupIDs = thePipe->GetGroupSide1();
2743   aGrps[2]  = createGroup(theBaseObject, aGroupIDs, "GROUP_SIDE1", anIndices);
2744   aGroupIDs = thePipe->GetGroupSide2();
2745   aGrps[3]  = createGroup(theBaseObject, aGroupIDs, "GROUP_SIDE2", anIndices);
2746   aGroupIDs = thePipe->GetGroupOther();
2747   aGrps[4]  = createGroup(theBaseObject, aGroupIDs, "GROUP_OTHER", anIndices);
2748
2749   for (i = 0; i < aNbGroups; ++i) {
2750     if (aGrps[i].IsNull() == Standard_False) {
2751       theSequence->Append(aGrps[i]);
2752     }
2753   }
2754 }