Salome HOME
Remove unnecessary includes
[modules/geom.git] / src / GEOMImpl / GEOMImpl_I3DPrimOperations.cxx
index dc2ab3599da8ef0093c69ea791e77131b087d851..d9f441df9c69935f268aafa473ad9167152583b3 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2021  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
@@ -6,7 +6,7 @@
 // This library is free software; you can redistribute it and/or
 // modify it under the terms of the GNU Lesser General Public
 // License as published by the Free Software Foundation; either
-// version 2.1 of the License.
+// version 2.1 of the License, or (at your option) any later version.
 //
 // This library is distributed in the hope that it will be useful,
 // but WITHOUT ANY WARRANTY; without even the implied warranty of
 
 #include <Standard_Stream.hxx>
 
-#include <Basics_OCCTVersion.hxx>
-
 #include <GEOMImpl_I3DPrimOperations.hxx>
 
 #include "utilities.h"
-#include <OpUtil.hxx>
 #include <Utils_ExceptHandlers.hxx>
 
 #include <TFunction_DriverTable.hxx>
 #include <TFunction_Driver.hxx>
-#include <TFunction_Logbook.hxx>
 #include <TDF_Tool.hxx>
 
 #include <GEOM_Function.hxx>
 #include <GEOMImpl_TorusDriver.hxx>
 #include <GEOMImpl_PrismDriver.hxx>
 #include <GEOMImpl_PipeDriver.hxx>
+#include <GEOMImpl_PipePathDriver.hxx>
 #include <GEOMImpl_RevolutionDriver.hxx>
 #include <GEOMImpl_ShapeDriver.hxx>
 #include <GEOMImpl_FillingDriver.hxx>
 #include <GEOMImpl_ThruSectionsDriver.hxx>
+#include <GEOMImpl_OffsetDriver.hxx>
 
 #include <GEOMImpl_IBox.hxx>
 #include <GEOMImpl_IFace.hxx>
 #include <GEOMImpl_IDisk.hxx>
 #include <GEOMImpl_ICylinder.hxx>
 #include <GEOMImpl_ICone.hxx>
+#include <GEOMImpl_IGroupOperations.hxx>
 #include <GEOMImpl_ISphere.hxx>
 #include <GEOMImpl_ITorus.hxx>
 #include <GEOMImpl_IPrism.hxx>
 #include <GEOMImpl_IPipeDiffSect.hxx>
 #include <GEOMImpl_IPipeShellSect.hxx>
 #include <GEOMImpl_IPipeBiNormal.hxx>
+#include <GEOMImpl_IOffset.hxx>
+#include <GEOMImpl_IPipePath.hxx>
 
 #include <Precision.hxx>
+#include <TopExp.hxx>
 
 #include <Standard_Failure.hxx>
 #include <Standard_ErrorHandler.hxx> // CAREFUL ! position of this file is critic : see Lucien PIGNOLONI / OCC
  *   constructor:
  */
 //=============================================================================
-GEOMImpl_I3DPrimOperations::GEOMImpl_I3DPrimOperations (GEOM_Engine* theEngine, int theDocID)
-: GEOM_IOperations(theEngine, theDocID)
+GEOMImpl_I3DPrimOperations::GEOMImpl_I3DPrimOperations (GEOM_Engine* theEngine)
+: GEOM_IOperations(theEngine)
 {
   MESSAGE("GEOMImpl_I3DPrimOperations::GEOMImpl_I3DPrimOperations");
+  myGroupOperations = new GEOMImpl_IGroupOperations(GetEngine());
 }
 
 //=============================================================================
@@ -94,6 +97,7 @@ GEOMImpl_I3DPrimOperations::GEOMImpl_I3DPrimOperations (GEOM_Engine* theEngine,
 GEOMImpl_I3DPrimOperations::~GEOMImpl_I3DPrimOperations()
 {
   MESSAGE("GEOMImpl_I3DPrimOperations::~GEOMImpl_I3DPrimOperations");
+  delete myGroupOperations;
 }
 
 
@@ -107,7 +111,7 @@ Handle(GEOM_Object) GEOMImpl_I3DPrimOperations::MakeBoxDXDYDZ (double theDX, dou
   SetErrorCode(KO);
 
   //Add a new Box object
-  Handle(GEOM_Object) aBox = GetEngine()->AddObject(GetDocID(), GEOM_BOX);
+  Handle(GEOM_Object) aBox = GetEngine()->AddObject(GEOM_BOX);
 
   //Add a new Box function with DX_DY_DZ parameters
   Handle(GEOM_Function) aFunction = aBox->AddFunction(GEOMImpl_BoxDriver::GetID(), BOX_DX_DY_DZ);
@@ -124,17 +128,14 @@ Handle(GEOM_Object) GEOMImpl_I3DPrimOperations::MakeBoxDXDYDZ (double theDX, dou
 
   //Compute the box value
   try {
-#if OCC_VERSION_LARGE > 0x06010000
     OCC_CATCH_SIGNALS;
-#endif
     if (!GetSolver()->ComputeFunction(aFunction)) {
       SetErrorCode("Box driver failed");
       return NULL;
     }
   }
-  catch (Standard_Failure) {
-    Handle(Standard_Failure) aFail = Standard_Failure::Caught();
-    SetErrorCode(aFail->GetMessageString());
+  catch (Standard_Failure& aFail) {
+    SetErrorCode(aFail.GetMessageString());
     return NULL;
   }
 
@@ -160,7 +161,7 @@ Handle(GEOM_Object) GEOMImpl_I3DPrimOperations::MakeBoxTwoPnt (Handle(GEOM_Objec
   if (thePnt1.IsNull() || thePnt2.IsNull()) return NULL;
 
   //Add a new Box object
-  Handle(GEOM_Object) aBox = GetEngine()->AddObject(GetDocID(), GEOM_BOX);
+  Handle(GEOM_Object) aBox = GetEngine()->AddObject(GEOM_BOX);
 
   //Add a new Box function for creation a box relatively to two points
   Handle(GEOM_Function) aFunction = aBox->AddFunction(GEOMImpl_BoxDriver::GetID(), BOX_TWO_PNT);
@@ -181,17 +182,14 @@ Handle(GEOM_Object) GEOMImpl_I3DPrimOperations::MakeBoxTwoPnt (Handle(GEOM_Objec
 
   //Compute the Box value
   try {
-#if OCC_VERSION_LARGE > 0x06010000
     OCC_CATCH_SIGNALS;
-#endif
     if (!GetSolver()->ComputeFunction(aFunction)) {
       SetErrorCode("Box driver failed");
       return NULL;
     }
   }
-  catch (Standard_Failure) {
-    Handle(Standard_Failure) aFail = Standard_Failure::Caught();
-    SetErrorCode(aFail->GetMessageString());
+  catch (Standard_Failure& aFail) {
+    SetErrorCode(aFail.GetMessageString());
     return NULL;
   }
 
@@ -215,7 +213,7 @@ Handle(GEOM_Object) GEOMImpl_I3DPrimOperations::MakeFaceHW (double theH, double
   if (theH == 0 || theW == 0) return NULL;
 
   //Add a new Face object
-  Handle(GEOM_Object) aFace = GetEngine()->AddObject(GetDocID(), GEOM_FACE);
+  Handle(GEOM_Object) aFace = GetEngine()->AddObject(GEOM_FACE);
 
   //Add a new Box function for creation a box relatively to two points
   Handle(GEOM_Function) aFunction = aFace->AddFunction(GEOMImpl_FaceDriver::GetID(), FACE_H_W);
@@ -232,17 +230,14 @@ Handle(GEOM_Object) GEOMImpl_I3DPrimOperations::MakeFaceHW (double theH, double
 
   //Compute the Face
   try {
-#if OCC_VERSION_LARGE > 0x06010000
     OCC_CATCH_SIGNALS;
-#endif
     if (!GetSolver()->ComputeFunction(aFunction)) {
       SetErrorCode("Face driver failed");
       return NULL;
     }
   }
-  catch (Standard_Failure) {
-    Handle(Standard_Failure) aFail = Standard_Failure::Caught();
-    SetErrorCode(aFail->GetMessageString());
+  catch (Standard_Failure& aFail) {
+    SetErrorCode(aFail.GetMessageString());
     return NULL;
   }
 
@@ -267,7 +262,7 @@ Handle(GEOM_Object) GEOMImpl_I3DPrimOperations::MakeFaceObjHW (Handle(GEOM_Objec
   if (theObj.IsNull()) return NULL;
 
   //Add a new Face object
-  Handle(GEOM_Object) aFace = GetEngine()->AddObject(GetDocID(), GEOM_FACE);
+  Handle(GEOM_Object) aFace = GetEngine()->AddObject(GEOM_FACE);
 
   //Add a new Box function for creation a box relatively to two points
   Handle(GEOM_Function) aFunction = aFace->AddFunction(GEOMImpl_FaceDriver::GetID(), FACE_OBJ_H_W);
@@ -289,17 +284,14 @@ Handle(GEOM_Object) GEOMImpl_I3DPrimOperations::MakeFaceObjHW (Handle(GEOM_Objec
 
   //Compute the Face
   try {
-#if OCC_VERSION_LARGE > 0x06010000
     OCC_CATCH_SIGNALS;
-#endif
     if (!GetSolver()->ComputeFunction(aFunction)) {
       SetErrorCode("Face driver failed");
       return NULL;
     }
   }
-  catch (Standard_Failure) {
-    Handle(Standard_Failure) aFail = Standard_Failure::Caught();
-    SetErrorCode(aFail->GetMessageString());
+  catch (Standard_Failure& aFail) {
+    SetErrorCode(aFail.GetMessageString());
     return NULL;
   }
 
@@ -324,7 +316,7 @@ Handle(GEOM_Object) GEOMImpl_I3DPrimOperations::MakeDiskPntVecR
   if (thePnt.IsNull() || theVec.IsNull()) return NULL;
 
   //Add a new Disk object
-  Handle(GEOM_Object) aDisk = GetEngine()->AddObject(GetDocID(), GEOM_FACE);
+  Handle(GEOM_Object) aDisk = GetEngine()->AddObject(GEOM_FACE);
 
   //Add a new Disk function for creation a disk relatively to point and vector
   Handle(GEOM_Function) aFunction =
@@ -347,17 +339,14 @@ Handle(GEOM_Object) GEOMImpl_I3DPrimOperations::MakeDiskPntVecR
 
   //Compute the Disk value
   try {
-#if OCC_VERSION_LARGE > 0x06010000
     OCC_CATCH_SIGNALS;
-#endif
     if (!GetSolver()->ComputeFunction(aFunction)) {
       SetErrorCode("Disk driver failed");
       return NULL;
     }
   }
-  catch (Standard_Failure) {
-    Handle(Standard_Failure) aFail = Standard_Failure::Caught();
-    SetErrorCode(aFail->GetMessageString());
+  catch (Standard_Failure& aFail) {
+    SetErrorCode(aFail.GetMessageString());
     return NULL;
   }
 
@@ -383,7 +372,7 @@ Handle(GEOM_Object) GEOMImpl_I3DPrimOperations::MakeDiskThreePnt (Handle(GEOM_Ob
   if (thePnt1.IsNull() || thePnt2.IsNull() || thePnt3.IsNull()) return NULL;
 
   //Add a new Disk object
-  Handle(GEOM_Object) aDisk = GetEngine()->AddObject(GetDocID(), GEOM_FACE);
+  Handle(GEOM_Object) aDisk = GetEngine()->AddObject(GEOM_FACE);
 
   //Add a new Disk function for creation a disk relatively to three points
   Handle(GEOM_Function) aFunction =
@@ -407,17 +396,14 @@ Handle(GEOM_Object) GEOMImpl_I3DPrimOperations::MakeDiskThreePnt (Handle(GEOM_Ob
 
   //Compute the Disk value
   try {
-#if OCC_VERSION_LARGE > 0x06010000
     OCC_CATCH_SIGNALS;
-#endif
     if (!GetSolver()->ComputeFunction(aFunction)) {
       SetErrorCode("Disk driver failed");
       return NULL;
     }
   }
-  catch (Standard_Failure) {
-    Handle(Standard_Failure) aFail = Standard_Failure::Caught();
-    SetErrorCode(aFail->GetMessageString());
+  catch (Standard_Failure& aFail) {
+    SetErrorCode(aFail.GetMessageString());
     return NULL;
   }
 
@@ -441,7 +427,7 @@ Handle(GEOM_Object) GEOMImpl_I3DPrimOperations::MakeDiskR (double theR, int theO
   if (theR == 0 ) return NULL;
 
   //Add a new Disk object
-  Handle(GEOM_Object) aDisk = GetEngine()->AddObject(GetDocID(), GEOM_FACE);
+  Handle(GEOM_Object) aDisk = GetEngine()->AddObject(GEOM_FACE);
 
   //Add a new Box function for creation a box relatively to two points
   Handle(GEOM_Function) aFunction = aDisk->AddFunction(GEOMImpl_DiskDriver::GetID(), DISK_R);
@@ -457,17 +443,14 @@ Handle(GEOM_Object) GEOMImpl_I3DPrimOperations::MakeDiskR (double theR, int theO
 
   //Compute the Disk
   try {
-#if OCC_VERSION_LARGE > 0x06010000
     OCC_CATCH_SIGNALS;
-#endif
     if (!GetSolver()->ComputeFunction(aFunction)) {
       SetErrorCode("Disk driver failed");
       return NULL;
     }
   }
-  catch (Standard_Failure) {
-    Handle(Standard_Failure) aFail = Standard_Failure::Caught();
-    SetErrorCode(aFail->GetMessageString());
+  catch (Standard_Failure& aFail) {
+    SetErrorCode(aFail.GetMessageString());
     return NULL;
   }
 
@@ -489,7 +472,7 @@ Handle(GEOM_Object) GEOMImpl_I3DPrimOperations::MakeCylinderRH (double theR, dou
   SetErrorCode(KO);
 
   //Add a new Cylinder object
-  Handle(GEOM_Object) aCylinder = GetEngine()->AddObject(GetDocID(), GEOM_CYLINDER);
+  Handle(GEOM_Object) aCylinder = GetEngine()->AddObject(GEOM_CYLINDER);
 
   //Add a new Cylinder function with R and H parameters
   Handle(GEOM_Function) aFunction = aCylinder->AddFunction(GEOMImpl_CylinderDriver::GetID(), CYLINDER_R_H);
@@ -505,17 +488,14 @@ Handle(GEOM_Object) GEOMImpl_I3DPrimOperations::MakeCylinderRH (double theR, dou
 
   //Compute the Cylinder value
   try {
-#if OCC_VERSION_LARGE > 0x06010000
     OCC_CATCH_SIGNALS;
-#endif
     if (!GetSolver()->ComputeFunction(aFunction)) {
       SetErrorCode("Cylinder driver failed");
       return NULL;
     }
   }
-  catch (Standard_Failure) {
-    Handle(Standard_Failure) aFail = Standard_Failure::Caught();
-    SetErrorCode(aFail->GetMessageString());
+  catch (Standard_Failure& aFail) {
+    SetErrorCode(aFail.GetMessageString());
     return NULL;
   }
 
@@ -527,6 +507,51 @@ Handle(GEOM_Object) GEOMImpl_I3DPrimOperations::MakeCylinderRH (double theR, dou
   return aCylinder;
 }
 
+//=============================================================================
+/*!
+ *  MakeCylinderRHA
+ */
+//=============================================================================
+Handle(GEOM_Object) GEOMImpl_I3DPrimOperations::MakeCylinderRHA (double theR, double theH, double theA)
+{
+  SetErrorCode(KO);
+
+  //Add a new Cylinder object
+  Handle(GEOM_Object) aCylinder = GetEngine()->AddObject(GEOM_CYLINDER);
+
+  //Add a new Cylinder function with R and H parameters
+  Handle(GEOM_Function) aFunction = aCylinder->AddFunction(GEOMImpl_CylinderDriver::GetID(), CYLINDER_R_H_A);
+  if (aFunction.IsNull()) return NULL;
+
+  //Check if the function is set correctly
+  if (aFunction->GetDriverGUID() != GEOMImpl_CylinderDriver::GetID()) return NULL;
+
+  GEOMImpl_ICylinder aCI (aFunction);
+
+  aCI.SetR(theR);
+  aCI.SetH(theH);
+  aCI.SetA(theA);
+
+  //Compute the Cylinder value
+  try {
+    OCC_CATCH_SIGNALS;
+    if (!GetSolver()->ComputeFunction(aFunction)) {
+      SetErrorCode("Cylinder driver failed");
+      return NULL;
+    }
+  }
+  catch (Standard_Failure& aFail) {
+    SetErrorCode(aFail.GetMessageString());
+    return NULL;
+  }
+
+  //Make a Python command
+  GEOM::TPythonDump(aFunction) << aCylinder
+    << " = geompy.MakeCylinderRHA(" << theR << ", " << theH << ", " << theA*180./M_PI << "*math.pi/180.)";
+
+  SetErrorCode(OK);
+  return aCylinder;
+}
 
 //=============================================================================
 /*!
@@ -542,7 +567,7 @@ Handle(GEOM_Object) GEOMImpl_I3DPrimOperations::MakeCylinderPntVecRH (Handle(GEO
   if (thePnt.IsNull() || theVec.IsNull()) return NULL;
 
   //Add a new Cylinder object
-  Handle(GEOM_Object) aCylinder = GetEngine()->AddObject(GetDocID(), GEOM_CYLINDER);
+  Handle(GEOM_Object) aCylinder = GetEngine()->AddObject(GEOM_CYLINDER);
 
   //Add a new Cylinder function for creation a cylinder relatively to point and vector
   Handle(GEOM_Function) aFunction =
@@ -566,17 +591,14 @@ Handle(GEOM_Object) GEOMImpl_I3DPrimOperations::MakeCylinderPntVecRH (Handle(GEO
 
   //Compute the Cylinder value
   try {
-#if OCC_VERSION_LARGE > 0x06010000
     OCC_CATCH_SIGNALS;
-#endif
     if (!GetSolver()->ComputeFunction(aFunction)) {
       SetErrorCode("Cylinder driver failed");
       return NULL;
     }
   }
-  catch (Standard_Failure) {
-    Handle(Standard_Failure) aFail = Standard_Failure::Caught();
-    SetErrorCode(aFail->GetMessageString());
+  catch (Standard_Failure& aFail) {
+    SetErrorCode(aFail.GetMessageString());
     return NULL;
   }
 
@@ -588,6 +610,64 @@ Handle(GEOM_Object) GEOMImpl_I3DPrimOperations::MakeCylinderPntVecRH (Handle(GEO
   return aCylinder;
 }
 
+//=============================================================================
+/*!
+ *  MakeCylinderPntVecRHA
+ */
+//=============================================================================
+Handle(GEOM_Object) GEOMImpl_I3DPrimOperations::MakeCylinderPntVecRHA (Handle(GEOM_Object) thePnt,
+                                                                       Handle(GEOM_Object) theVec,
+                                                                       double theR, double theH, double theA)
+{
+  SetErrorCode(KO);
+
+  if (thePnt.IsNull() || theVec.IsNull()) return NULL;
+
+  //Add a new Cylinder object
+  Handle(GEOM_Object) aCylinder = GetEngine()->AddObject(GEOM_CYLINDER);
+
+  //Add a new Cylinder function for creation a cylinder relatively to point and vector
+  Handle(GEOM_Function) aFunction =
+    aCylinder->AddFunction(GEOMImpl_CylinderDriver::GetID(), CYLINDER_PNT_VEC_R_H_A);
+  if (aFunction.IsNull()) return NULL;
+
+  //Check if the function is set correctly
+  if (aFunction->GetDriverGUID() != GEOMImpl_CylinderDriver::GetID()) return NULL;
+
+  GEOMImpl_ICylinder aCI (aFunction);
+
+  Handle(GEOM_Function) aRefPnt = thePnt->GetLastFunction();
+  Handle(GEOM_Function) aRefVec = theVec->GetLastFunction();
+
+  if (aRefPnt.IsNull() || aRefVec.IsNull()) return NULL;
+
+  aCI.SetPoint(aRefPnt);
+  aCI.SetVector(aRefVec);
+  aCI.SetR(theR);
+  aCI.SetH(theH);
+  aCI.SetA(theA);
+
+  //Compute the Cylinder value
+  try {
+    OCC_CATCH_SIGNALS;
+    if (!GetSolver()->ComputeFunction(aFunction)) {
+      SetErrorCode("Cylinder driver failed");
+      return NULL;
+    }
+  }
+  catch (Standard_Failure& aFail) {
+    SetErrorCode(aFail.GetMessageString());
+    return NULL;
+  }
+
+  //Make a Python command
+  GEOM::TPythonDump(aFunction) << aCylinder << " = geompy.MakeCylinderA("
+    << thePnt << ", " << theVec << ", " << theR << ", " << theH << ", " << theA*180./M_PI << "*math.pi/180.)";
+
+  SetErrorCode(OK);
+  return aCylinder;
+}
+
 
 //=============================================================================
 /*!
@@ -600,7 +680,7 @@ Handle(GEOM_Object) GEOMImpl_I3DPrimOperations::MakeConeR1R2H (double theR1, dou
   SetErrorCode(KO);
 
   //Add a new Cone object
-  Handle(GEOM_Object) aCone = GetEngine()->AddObject(GetDocID(), GEOM_CONE);
+  Handle(GEOM_Object) aCone = GetEngine()->AddObject(GEOM_CONE);
 
   //Add a new Cone function with R and H parameters
   Handle(GEOM_Function) aFunction =
@@ -618,17 +698,14 @@ Handle(GEOM_Object) GEOMImpl_I3DPrimOperations::MakeConeR1R2H (double theR1, dou
 
   //Compute the Cone value
   try {
-#if OCC_VERSION_LARGE > 0x06010000
     OCC_CATCH_SIGNALS;
-#endif
     if (!GetSolver()->ComputeFunction(aFunction)) {
       SetErrorCode("Cone driver failed");
       return NULL;
     }
   }
-  catch (Standard_Failure) {
-    Handle(Standard_Failure) aFail = Standard_Failure::Caught();
-    SetErrorCode(aFail->GetMessageString());
+  catch (Standard_Failure& aFail) {
+    SetErrorCode(aFail.GetMessageString());
     return NULL;
   }
 
@@ -656,7 +733,7 @@ Handle(GEOM_Object) GEOMImpl_I3DPrimOperations::MakeConePntVecR1R2H (Handle(GEOM
   if (thePnt.IsNull() || theVec.IsNull()) return NULL;
 
   //Add a new Cone object
-  Handle(GEOM_Object) aCone = GetEngine()->AddObject(GetDocID(), GEOM_CONE);
+  Handle(GEOM_Object) aCone = GetEngine()->AddObject(GEOM_CONE);
 
   //Add a new Cone function for creation a cone relatively to point and vector
   Handle(GEOM_Function) aFunction =
@@ -681,17 +758,14 @@ Handle(GEOM_Object) GEOMImpl_I3DPrimOperations::MakeConePntVecR1R2H (Handle(GEOM
 
   //Compute the Cone value
   try {
-#if OCC_VERSION_LARGE > 0x06010000
     OCC_CATCH_SIGNALS;
-#endif
     if (!GetSolver()->ComputeFunction(aFunction)) {
       SetErrorCode("Cone driver failed");
       return NULL;
     }
   }
-  catch (Standard_Failure) {
-    Handle(Standard_Failure) aFail = Standard_Failure::Caught();
-    SetErrorCode(aFail->GetMessageString());
+  catch (Standard_Failure& aFail) {
+    SetErrorCode(aFail.GetMessageString());
     return NULL;
   }
 
@@ -714,7 +788,7 @@ Handle(GEOM_Object) GEOMImpl_I3DPrimOperations::MakeSphereR (double theR)
   SetErrorCode(KO);
 
   //Add a new Sphere object
-  Handle(GEOM_Object) aSphere = GetEngine()->AddObject(GetDocID(), GEOM_SPHERE);
+  Handle(GEOM_Object) aSphere = GetEngine()->AddObject(GEOM_SPHERE);
 
   //Add a new Sphere function with R parameter
   Handle(GEOM_Function) aFunction = aSphere->AddFunction(GEOMImpl_SphereDriver::GetID(), SPHERE_R);
@@ -729,17 +803,14 @@ Handle(GEOM_Object) GEOMImpl_I3DPrimOperations::MakeSphereR (double theR)
 
   //Compute the Sphere value
   try {
-#if OCC_VERSION_LARGE > 0x06010000
     OCC_CATCH_SIGNALS;
-#endif
     if (!GetSolver()->ComputeFunction(aFunction)) {
       SetErrorCode("Sphere driver failed");
       return NULL;
     }
   }
-  catch (Standard_Failure) {
-    Handle(Standard_Failure) aFail = Standard_Failure::Caught();
-    SetErrorCode(aFail->GetMessageString());
+  catch (Standard_Failure& aFail) {
+    SetErrorCode(aFail.GetMessageString());
     return NULL;
   }
 
@@ -764,7 +835,7 @@ Handle(GEOM_Object) GEOMImpl_I3DPrimOperations::MakeSpherePntR (Handle(GEOM_Obje
   if (thePnt.IsNull()) return NULL;
 
   //Add a new Point object
-  Handle(GEOM_Object) aSphere = GetEngine()->AddObject(GetDocID(), GEOM_SPHERE);
+  Handle(GEOM_Object) aSphere = GetEngine()->AddObject(GEOM_SPHERE);
 
   //Add a new Sphere function for creation a sphere relatively to point
   Handle(GEOM_Function) aFunction = aSphere->AddFunction(GEOMImpl_SphereDriver::GetID(), SPHERE_PNT_R);
@@ -784,17 +855,14 @@ Handle(GEOM_Object) GEOMImpl_I3DPrimOperations::MakeSpherePntR (Handle(GEOM_Obje
 
   //Compute the Sphere value
   try {
-#if OCC_VERSION_LARGE > 0x06010000
     OCC_CATCH_SIGNALS;
-#endif
     if (!GetSolver()->ComputeFunction(aFunction)) {
       SetErrorCode("Sphere driver failed");
       return NULL;
     }
   }
-  catch (Standard_Failure) {
-    Handle(Standard_Failure) aFail = Standard_Failure::Caught();
-    SetErrorCode(aFail->GetMessageString());
+  catch (Standard_Failure& aFail) {
+    SetErrorCode(aFail.GetMessageString());
     return NULL;
   }
 
@@ -818,7 +886,7 @@ Handle(GEOM_Object) GEOMImpl_I3DPrimOperations::MakeTorusRR
   SetErrorCode(KO);
 
   //Add a new Torus object
-  Handle(GEOM_Object) anEll = GetEngine()->AddObject(GetDocID(), GEOM_TORUS);
+  Handle(GEOM_Object) anEll = GetEngine()->AddObject(GEOM_TORUS);
 
   //Add a new Torus function
   Handle(GEOM_Function) aFunction =
@@ -835,17 +903,14 @@ Handle(GEOM_Object) GEOMImpl_I3DPrimOperations::MakeTorusRR
 
   //Compute the Torus value
   try {
-#if OCC_VERSION_LARGE > 0x06010000
     OCC_CATCH_SIGNALS;
-#endif
     if (!GetSolver()->ComputeFunction(aFunction)) {
       SetErrorCode("Torus driver failed");
       return NULL;
     }
   }
-  catch (Standard_Failure) {
-    Handle(Standard_Failure) aFail = Standard_Failure::Caught();
-    SetErrorCode(aFail->GetMessageString());
+  catch (Standard_Failure& aFail) {
+    SetErrorCode(aFail.GetMessageString());
     return NULL;
   }
 
@@ -871,7 +936,7 @@ Handle(GEOM_Object) GEOMImpl_I3DPrimOperations::MakeTorusPntVecRR
   if (thePnt.IsNull() || theVec.IsNull()) return NULL;
 
   //Add a new Torus object
-  Handle(GEOM_Object) anEll = GetEngine()->AddObject(GetDocID(), GEOM_TORUS);
+  Handle(GEOM_Object) anEll = GetEngine()->AddObject(GEOM_TORUS);
 
   //Add a new Torus function
   Handle(GEOM_Function) aFunction =
@@ -895,17 +960,14 @@ Handle(GEOM_Object) GEOMImpl_I3DPrimOperations::MakeTorusPntVecRR
 
   //Compute the Torus value
   try {
-#if OCC_VERSION_LARGE > 0x06010000
     OCC_CATCH_SIGNALS;
-#endif
     if (!GetSolver()->ComputeFunction(aFunction)) {
       SetErrorCode("Torus driver failed");
       return NULL;
     }
   }
-  catch (Standard_Failure) {
-    Handle(Standard_Failure) aFail = Standard_Failure::Caught();
-    SetErrorCode(aFail->GetMessageString());
+  catch (Standard_Failure& aFail) {
+    SetErrorCode(aFail.GetMessageString());
     return NULL;
   }
 
@@ -932,7 +994,7 @@ Handle(GEOM_Object) GEOMImpl_I3DPrimOperations::MakePrismVecH (Handle(GEOM_Objec
   if (theBase.IsNull() || theVec.IsNull()) return NULL;
 
   //Add a new Prism object
-  Handle(GEOM_Object) aPrism = GetEngine()->AddObject(GetDocID(), GEOM_PRISM);
+  Handle(GEOM_Object) aPrism = GetEngine()->AddObject(GEOM_PRISM);
 
   //Add a new Prism function for creation a Prism relatively to vector
   Handle(GEOM_Function) aFunction =
@@ -956,18 +1018,15 @@ Handle(GEOM_Object) GEOMImpl_I3DPrimOperations::MakePrismVecH (Handle(GEOM_Objec
 
   //Compute the Prism value
   try {
-#if OCC_VERSION_LARGE > 0x06010000
     OCC_CATCH_SIGNALS;
-#endif
     if (!GetSolver()->ComputeFunction(aFunction)) {
       //SetErrorCode("Prism driver failed");
       SetErrorCode("Extrusion can not be created, check input data");
       return NULL;
     }
   }
-  catch (Standard_Failure) {
-    Handle(Standard_Failure) aFail = Standard_Failure::Caught();
-    SetErrorCode(aFail->GetMessageString());
+  catch (Standard_Failure& aFail) {
+    SetErrorCode(aFail.GetMessageString());
     return NULL;
   }
 
@@ -997,7 +1056,7 @@ Handle(GEOM_Object) GEOMImpl_I3DPrimOperations::MakePrismVecH2Ways (Handle(GEOM_
   if (theBase.IsNull() || theVec.IsNull()) return NULL;
 
   //Add a new Prism object
-  Handle(GEOM_Object) aPrism = GetEngine()->AddObject(GetDocID(), GEOM_PRISM);
+  Handle(GEOM_Object) aPrism = GetEngine()->AddObject(GEOM_PRISM);
 
   //Add a new Prism function for creation a Prism relatively to vector
   Handle(GEOM_Function) aFunction =
@@ -1020,18 +1079,15 @@ Handle(GEOM_Object) GEOMImpl_I3DPrimOperations::MakePrismVecH2Ways (Handle(GEOM_
 
   //Compute the Prism value
   try {
-#if OCC_VERSION_LARGE > 0x06010000
     OCC_CATCH_SIGNALS;
-#endif
     if (!GetSolver()->ComputeFunction(aFunction)) {
       //SetErrorCode("Prism driver failed");
       SetErrorCode("Extrusion can not be created, check input data");
       return NULL;
     }
   }
-  catch (Standard_Failure) {
-    Handle(Standard_Failure) aFail = Standard_Failure::Caught();
-    SetErrorCode(aFail->GetMessageString());
+  catch (Standard_Failure& aFail) {
+    SetErrorCode(aFail.GetMessageString());
     return NULL;
   }
 
@@ -1058,7 +1114,7 @@ Handle(GEOM_Object) GEOMImpl_I3DPrimOperations::MakePrismTwoPnt
   if (theBase.IsNull() || thePoint1.IsNull() || thePoint2.IsNull()) return NULL;
 
   //Add a new Prism object
-  Handle(GEOM_Object) aPrism = GetEngine()->AddObject(GetDocID(), GEOM_PRISM);
+  Handle(GEOM_Object) aPrism = GetEngine()->AddObject(GEOM_PRISM);
 
   //Add a new Prism function for creation a Prism relatively to two points
   Handle(GEOM_Function) aFunction =
@@ -1083,18 +1139,15 @@ Handle(GEOM_Object) GEOMImpl_I3DPrimOperations::MakePrismTwoPnt
 
   //Compute the Prism value
   try {
-#if OCC_VERSION_LARGE > 0x06010000
     OCC_CATCH_SIGNALS;
-#endif
     if (!GetSolver()->ComputeFunction(aFunction)) {
       //SetErrorCode("Prism driver failed");
       SetErrorCode("Extrusion can not be created, check input data");
       return NULL;
     }
   }
-  catch (Standard_Failure) {
-    Handle(Standard_Failure) aFail = Standard_Failure::Caught();
-    SetErrorCode(aFail->GetMessageString());
+  catch (Standard_Failure& aFail) {
+    SetErrorCode(aFail.GetMessageString());
     return NULL;
   }
 
@@ -1124,7 +1177,7 @@ Handle(GEOM_Object) GEOMImpl_I3DPrimOperations::MakePrismTwoPnt2Ways
   if (theBase.IsNull() || thePoint1.IsNull() || thePoint2.IsNull()) return NULL;
 
   //Add a new Prism object
-  Handle(GEOM_Object) aPrism = GetEngine()->AddObject(GetDocID(), GEOM_PRISM);
+  Handle(GEOM_Object) aPrism = GetEngine()->AddObject(GEOM_PRISM);
 
   //Add a new Prism function for creation a Prism relatively to two points
   Handle(GEOM_Function) aFunction =
@@ -1148,18 +1201,15 @@ Handle(GEOM_Object) GEOMImpl_I3DPrimOperations::MakePrismTwoPnt2Ways
 
   //Compute the Prism value
   try {
-#if OCC_VERSION_LARGE > 0x06010000
     OCC_CATCH_SIGNALS;
-#endif
     if (!GetSolver()->ComputeFunction(aFunction)) {
       //SetErrorCode("Prism driver failed");
       SetErrorCode("Extrusion can not be created, check input data");
       return NULL;
     }
   }
-  catch (Standard_Failure) {
-    Handle(Standard_Failure) aFail = Standard_Failure::Caught();
-    SetErrorCode(aFail->GetMessageString());
+  catch (Standard_Failure& aFail) {
+    SetErrorCode(aFail.GetMessageString());
     return NULL;
   }
 
@@ -1185,7 +1235,7 @@ Handle(GEOM_Object) GEOMImpl_I3DPrimOperations::MakePrismDXDYDZ
   if (theBase.IsNull()) return NULL;
 
   //Add a new Prism object
-  Handle(GEOM_Object) aPrism = GetEngine()->AddObject(GetDocID(), GEOM_PRISM);
+  Handle(GEOM_Object) aPrism = GetEngine()->AddObject(GEOM_PRISM);
 
   //Add a new Prism function for creation a Prism by DXDYDZ
   Handle(GEOM_Function) aFunction =
@@ -1209,17 +1259,14 @@ Handle(GEOM_Object) GEOMImpl_I3DPrimOperations::MakePrismDXDYDZ
 
   //Compute the Prism value
   try {
-#if OCC_VERSION_LARGE > 0x06010000
     OCC_CATCH_SIGNALS;
-#endif
     if (!GetSolver()->ComputeFunction(aFunction)) {
       SetErrorCode("Extrusion can not be created, check input data");
       return NULL;
     }
   }
-  catch (Standard_Failure) {
-    Handle(Standard_Failure) aFail = Standard_Failure::Caught();
-    SetErrorCode(aFail->GetMessageString());
+  catch (Standard_Failure& aFail) {
+    SetErrorCode(aFail.GetMessageString());
     return NULL;
   }
 
@@ -1249,7 +1296,7 @@ Handle(GEOM_Object) GEOMImpl_I3DPrimOperations::MakePrismDXDYDZ2Ways
   if (theBase.IsNull()) return NULL;
 
   //Add a new Prism object
-  Handle(GEOM_Object) aPrism = GetEngine()->AddObject(GetDocID(), GEOM_PRISM);
+  Handle(GEOM_Object) aPrism = GetEngine()->AddObject(GEOM_PRISM);
 
   //Add a new Prism function for creation a Prism by DXDYDZ
   Handle(GEOM_Function) aFunction =
@@ -1272,17 +1319,14 @@ Handle(GEOM_Object) GEOMImpl_I3DPrimOperations::MakePrismDXDYDZ2Ways
 
   //Compute the Prism value
   try {
-#if OCC_VERSION_LARGE > 0x06010000
     OCC_CATCH_SIGNALS;
-#endif
     if (!GetSolver()->ComputeFunction(aFunction)) {
       SetErrorCode("Extrusion can not be created, check input data");
       return NULL;
     }
   }
-  catch (Standard_Failure) {
-    Handle(Standard_Failure) aFail = Standard_Failure::Caught();
-    SetErrorCode(aFail->GetMessageString());
+  catch (Standard_Failure& aFail) {
+    SetErrorCode(aFail.GetMessageString());
     return NULL;
   }
 
@@ -1300,7 +1344,7 @@ Handle(GEOM_Object) GEOMImpl_I3DPrimOperations::MakePrismDXDYDZ2Ways
  */
 //=============================================================================
 Handle(GEOM_Object) GEOMImpl_I3DPrimOperations::MakeDraftPrism
-       (Handle(GEOM_Object) theInitShape ,Handle(GEOM_Object) theBase, double theHeight, double theAngle, bool theFuse)
+       (Handle(GEOM_Object) theInitShape ,Handle(GEOM_Object) theBase, double theHeight, double theAngle, bool theFuse, bool theInvert)
 {
   SetErrorCode(KO);
 
@@ -1311,12 +1355,12 @@ Handle(GEOM_Object) GEOMImpl_I3DPrimOperations::MakeDraftPrism
   if ( theFuse )
   {
     //Add a new Extruded Boss object  
-    aPrism = GetEngine()->AddObject(GetDocID(), GEOM_EXTRUDED_BOSS);
+    aPrism = GetEngine()->AddObject(GEOM_EXTRUDED_BOSS);
   }
   else
   { 
     //Add a new Extruded Cut object  
-    aPrism = GetEngine()->AddObject(GetDocID(), GEOM_EXTRUDED_CUT);
+    aPrism = GetEngine()->AddObject(GEOM_EXTRUDED_CUT);
   }
   
   //Add a new Prism function for the creation of a Draft Prism feature
@@ -1343,34 +1387,36 @@ Handle(GEOM_Object) GEOMImpl_I3DPrimOperations::MakeDraftPrism
     aCI.SetFuseFlag(1);
   else
     aCI.SetFuseFlag(0);
+  aCI.SetInvertFlag(theInvert);
   
   //Compute the Draft Prism Feature value
   try {
-#if OCC_VERSION_LARGE > 0x06010000
     OCC_CATCH_SIGNALS;
-#endif
     if (!GetSolver()->ComputeFunction(aFunction)) {
       SetErrorCode("Extrusion can not be created, check input data");
       return NULL;
     }
   }
-  catch (Standard_Failure) {
-    Handle(Standard_Failure) aFail = Standard_Failure::Caught();
-    SetErrorCode(aFail->GetMessageString());
+  catch (Standard_Failure& aFail) {
+    SetErrorCode(aFail.GetMessageString());
     return NULL;
   }
   
   //Make a Python command
+  GEOM::TPythonDump pd (aFunction);
   if(theFuse)
   {
-    GEOM::TPythonDump(aFunction) << aPrism << " = geompy.MakeExtrudedBoss("
-      << theInitShape << ", " << theBase << ", " << theHeight << ", " << theAngle << ")";
+    pd << aPrism << " = geompy.MakeExtrudedBoss(" << theInitShape << ", " << theBase << ", "
+      << theHeight << ", " << theAngle;
   }
   else
   {   
-    GEOM::TPythonDump(aFunction) << aPrism << " = geompy.MakeExtrudedCut("
-      << theInitShape << ", " << theBase << ", " << theHeight << ", " << theAngle << ")";
+    pd << aPrism << " = geompy.MakeExtrudedCut(" << theInitShape << ", " << theBase << ", "
+      << theHeight << ", " << theAngle;
   }
+  if (theInvert)
+    pd << ", " << theInvert;
+  pd << ")";
 
   SetErrorCode(OK);
   return aPrism;
@@ -1381,15 +1427,17 @@ Handle(GEOM_Object) GEOMImpl_I3DPrimOperations::MakeDraftPrism
  *  MakePipe
  */
 //=============================================================================
-Handle(GEOM_Object) GEOMImpl_I3DPrimOperations::MakePipe (Handle(GEOM_Object) theBase,
-                                                          Handle(GEOM_Object) thePath)
+Handle(TColStd_HSequenceOfTransient) GEOMImpl_I3DPrimOperations::MakePipe
+                            (const Handle(GEOM_Object) &theBase,
+                             const Handle(GEOM_Object) &thePath,
+                             const bool                 IsGenerateGroups)
 {
   SetErrorCode(KO);
 
   if (theBase.IsNull() || thePath.IsNull()) return NULL;
 
   //Add a new Pipe object
-  Handle(GEOM_Object) aPipe = GetEngine()->AddObject(GetDocID(), GEOM_PIPE);
+  Handle(GEOM_Object) aPipe = GetEngine()->AddObject(GEOM_PIPE);
 
   //Add a new Pipe function
   Handle(GEOM_Function) aFunction =
@@ -1408,29 +1456,46 @@ Handle(GEOM_Object) GEOMImpl_I3DPrimOperations::MakePipe (Handle(GEOM_Object) th
 
   aCI.SetBase(aRefBase);
   aCI.SetPath(aRefPath);
+  aCI.SetGenerateGroups(IsGenerateGroups);
 
   //Compute the Pipe value
   try {
-#if OCC_VERSION_LARGE > 0x06010000
     OCC_CATCH_SIGNALS;
-#endif
     if (!GetSolver()->ComputeFunction(aFunction)) {
       SetErrorCode("Pipe driver failed");
       return NULL;
     }
   }
-  catch (Standard_Failure) {
-    Handle(Standard_Failure) aFail = Standard_Failure::Caught();
-    SetErrorCode(aFail->GetMessageString());
+  catch (Standard_Failure& aFail) {
+    SetErrorCode(aFail.GetMessageString());
     return NULL;
   }
 
+  // Create the sequence of objects.
+  Handle(TColStd_HSequenceOfTransient) aSeq = new TColStd_HSequenceOfTransient;
+
+  aSeq->Append(aPipe);
+  createGroups(aPipe, &aCI, aSeq);
+
   //Make a Python command
-  GEOM::TPythonDump(aFunction) << aPipe << " = geompy.MakePipe("
-    << theBase << ", " << thePath << ")";
+  GEOM::TPythonDump pyDump(aFunction);
+
+  if (IsGenerateGroups) {
+    pyDump << aSeq;
+  } else {
+    pyDump << aPipe;
+  }
+
+  pyDump << " = geompy.MakePipe(" << theBase << ", " << thePath;
+
+  if (IsGenerateGroups) {
+    pyDump << ", True";
+  }
+
+  pyDump << ")";
 
   SetErrorCode(OK);
-  return aPipe;
+  return aSeq;
 }
 
 
@@ -1448,7 +1513,7 @@ Handle(GEOM_Object) GEOMImpl_I3DPrimOperations::MakeRevolutionAxisAngle (Handle(
   if (theBase.IsNull() || theAxis.IsNull()) return NULL;
 
   //Add a new Revolution object
-  Handle(GEOM_Object) aRevolution = GetEngine()->AddObject(GetDocID(), GEOM_REVOLUTION);
+  Handle(GEOM_Object) aRevolution = GetEngine()->AddObject(GEOM_REVOLUTION);
 
   //Add a new Revolution function for creation a revolution relatively to axis
   Handle(GEOM_Function) aFunction =
@@ -1471,24 +1536,21 @@ Handle(GEOM_Object) GEOMImpl_I3DPrimOperations::MakeRevolutionAxisAngle (Handle(
 
   //Compute the Revolution value
   try {
-#if OCC_VERSION_LARGE > 0x06010000
     OCC_CATCH_SIGNALS;
-#endif
     if (!GetSolver()->ComputeFunction(aFunction)) {
       SetErrorCode("Revolution driver failed");
       return NULL;
     }
   }
-  catch (Standard_Failure) {
-    Handle(Standard_Failure) aFail = Standard_Failure::Caught();
-    SetErrorCode(aFail->GetMessageString());
+  catch (Standard_Failure& aFail) {
+    SetErrorCode(aFail.GetMessageString());
     return NULL;
   }
 
   //Make a Python command
   GEOM::TPythonDump(aFunction) << aRevolution << " = geompy.MakeRevolution("
     << theBase << ", " << theAxis << ", " << theAngle * 180.0 / M_PI << "*math.pi/180.0)";
-
+  
   SetErrorCode(OK);
   return aRevolution;
 }
@@ -1506,7 +1568,7 @@ Handle(GEOM_Object) GEOMImpl_I3DPrimOperations::MakeRevolutionAxisAngle2Ways
   if (theBase.IsNull() || theAxis.IsNull()) return NULL;
 
   //Add a new Revolution object
-  Handle(GEOM_Object) aRevolution = GetEngine()->AddObject(GetDocID(), GEOM_REVOLUTION);
+  Handle(GEOM_Object) aRevolution = GetEngine()->AddObject(GEOM_REVOLUTION);
 
   //Add a new Revolution function for creation a revolution relatively to axis
   Handle(GEOM_Function) aFunction =
@@ -1529,17 +1591,14 @@ Handle(GEOM_Object) GEOMImpl_I3DPrimOperations::MakeRevolutionAxisAngle2Ways
 
   //Compute the Revolution value
   try {
-#if OCC_VERSION_LARGE > 0x06010000
     OCC_CATCH_SIGNALS;
-#endif
     if (!GetSolver()->ComputeFunction(aFunction)) {
       SetErrorCode("Revolution driver failed");
       return NULL;
     }
   }
-  catch (Standard_Failure) {
-    Handle(Standard_Failure) aFail = Standard_Failure::Caught();
-    SetErrorCode(aFail->GetMessageString());
+  catch (Standard_Failure& aFail) {
+    SetErrorCode(aFail.GetMessageString());
     return NULL;
   }
 
@@ -1556,17 +1615,21 @@ Handle(GEOM_Object) GEOMImpl_I3DPrimOperations::MakeRevolutionAxisAngle2Ways
  *  MakeFilling
  */
 //=============================================================================
-Handle(GEOM_Object) GEOMImpl_I3DPrimOperations::MakeFilling
-       (Handle(GEOM_Object) theShape, int theMinDeg, int theMaxDeg,
-        double theTol2D, double theTol3D, int theNbIter,
-        int theMethod, bool isApprox)
+Handle(GEOM_Object)
+GEOMImpl_I3DPrimOperations::MakeFilling (std::list< Handle(GEOM_Object)> & theContours,
+                                         int theMinDeg, int theMaxDeg,
+                                         double theTol2D, double theTol3D, int theNbIter,
+                                         int theMethod, bool isApprox)
 {
   SetErrorCode(KO);
 
-  if (theShape.IsNull()) return NULL;
-
+  Handle(TColStd_HSequenceOfTransient) contours = GEOM_Object::GetLastFunctions( theContours );
+  if ( contours.IsNull() || contours->IsEmpty() ) {
+    SetErrorCode("NULL argument shape");
+    return NULL;
+  }
   //Add a new Filling object
-  Handle(GEOM_Object) aFilling = GetEngine()->AddObject(GetDocID(), GEOM_FILLING);
+  Handle(GEOM_Object) aFilling = GetEngine()->AddObject(GEOM_FILLING);
 
   //Add a new Filling function for creation a filling  from a compound
   Handle(GEOM_Function) aFunction = aFilling->AddFunction(GEOMImpl_FillingDriver::GetID(), BASIC_FILLING);
@@ -1576,12 +1639,7 @@ Handle(GEOM_Object) GEOMImpl_I3DPrimOperations::MakeFilling
   if (aFunction->GetDriverGUID() != GEOMImpl_FillingDriver::GetID()) return NULL;
 
   GEOMImpl_IFilling aFI (aFunction);
-
-  Handle(GEOM_Function) aRefShape = theShape->GetLastFunction();
-
-  if (aRefShape.IsNull()) return NULL;
-
-  aFI.SetShape(aRefShape);
+  aFI.SetShapes(contours);
   aFI.SetMinDeg(theMinDeg);
   aFI.SetMaxDeg(theMaxDeg);
   aFI.SetTol2D(theTol2D);
@@ -1592,36 +1650,33 @@ Handle(GEOM_Object) GEOMImpl_I3DPrimOperations::MakeFilling
 
   //Compute the Solid value
   try {
-#if OCC_VERSION_LARGE > 0x06010000
     OCC_CATCH_SIGNALS;
-#endif
     if (!GetSolver()->ComputeFunction(aFunction)) {
       SetErrorCode("Filling driver failed");
       return NULL;
     }
   }
-  catch (Standard_Failure) {
-    Handle(Standard_Failure) aFail = Standard_Failure::Caught();
-    if (strcmp(aFail->GetMessageString(), "Geom_BSplineSurface") == 0)
+  catch (Standard_Failure& aFail) {
+    if (strcmp(aFail.GetMessageString(), "Geom_BSplineSurface") == 0)
       SetErrorCode("B-Spline surface construction failed");
     else
-      SetErrorCode(aFail->GetMessageString());
+      SetErrorCode(aFail.GetMessageString());
     return NULL;
   }
 
   //Make a Python command
   GEOM::TPythonDump pd (aFunction);
-  pd << aFilling << " = geompy.MakeFilling(" << theShape ;
+  pd << aFilling << " = geompy.MakeFilling(" << theContours ;
   if ( theMinDeg != 2 )   pd << ", theMinDeg=" << theMinDeg ;
   if ( theMaxDeg != 5 )   pd << ", theMaxDeg=" << theMaxDeg ;
   if ( fabs(theTol2D-0.0001) > Precision::Confusion() )
-                          pd << ", theTol2D=" << theTol2D ;
+  {                       pd << ", theTol2D=" << theTol2D ; }
   if ( fabs(theTol3D-0.0001) > Precision::Confusion() )
-                          pd << ", theTol3D=" << theTol3D ;
+  {                       pd << ", theTol3D=" << theTol3D ; }
   if ( theNbIter != 0 )   pd << ", theNbIter=" << theNbIter ;
   if ( theMethod==1 )     pd << ", theMethod=GEOM.FOM_UseOri";
   else if( theMethod==2 ) pd << ", theMethod=GEOM.FOM_AutoCorrect";
-  if(isApprox)            pd << ", isApprox=" << isApprox ;
+  if ( isApprox )         pd << ", isApprox=" << isApprox ;
   pd << ")";
 
   SetErrorCode(OK);
@@ -1649,7 +1704,7 @@ Handle(GEOM_Object) GEOMImpl_I3DPrimOperations::MakeThruSections(
     return anObj;
 
   //Add a new ThruSections object
-  Handle(GEOM_Object) aThruSect = GetEngine()->AddObject(GetDocID(), GEOM_THRUSECTIONS);
+  Handle(GEOM_Object) aThruSect = GetEngine()->AddObject(GEOM_THRUSECTIONS);
 
 
   //Add a new ThruSections function
@@ -1691,17 +1746,14 @@ Handle(GEOM_Object) GEOMImpl_I3DPrimOperations::MakeThruSections(
 
   //Compute the ThruSections value
   try {
-#if OCC_VERSION_LARGE > 0x06010000
     OCC_CATCH_SIGNALS;
-#endif
     if (!GetSolver()->ComputeFunction(aFunction)) {
       SetErrorCode("ThruSections driver failed");
       return anObj;
     }
   }
-  catch (Standard_Failure) {
-    Handle(Standard_Failure) aFail = Standard_Failure::Caught();
-    SetErrorCode(aFail->GetMessageString());
+  catch (Standard_Failure& aFail) {
+    SetErrorCode(aFail.GetMessageString());
     return anObj;
   }
 
@@ -1735,41 +1787,43 @@ Handle(GEOM_Object) GEOMImpl_I3DPrimOperations::MakeThruSections(
  *  MakePipeWithDifferentSections
  */
 //=============================================================================
-Handle(GEOM_Object) GEOMImpl_I3DPrimOperations::MakePipeWithDifferentSections(
-                const Handle(TColStd_HSequenceOfTransient)& theBases,
-                const Handle(TColStd_HSequenceOfTransient)& theLocations,
-                const Handle(GEOM_Object)& thePath,
-                bool theWithContact,
-                bool theWithCorrections)
+Handle(TColStd_HSequenceOfTransient)
+  GEOMImpl_I3DPrimOperations::MakePipeWithDifferentSections
+              (const Handle(TColStd_HSequenceOfTransient) &theBases,
+               const Handle(TColStd_HSequenceOfTransient) &theLocations,
+               const Handle(GEOM_Object)                  &thePath,
+               const bool                                  theWithContact,
+               const bool                                  theWithCorrections,
+               const bool                                  IsBySteps,
+               const bool                                  IsGenerateGroups)
 {
-  Handle(GEOM_Object) anObj;
   SetErrorCode(KO);
   if(theBases.IsNull())
-    return anObj;
+    return NULL;
 
   Standard_Integer nbBases = theBases->Length();
 
   if (!nbBases)
-    return anObj;
+    return NULL;
 
   Standard_Integer nbLocs =  (theLocations.IsNull() ? 0 :theLocations->Length());
   //Add a new Pipe object
-  Handle(GEOM_Object) aPipeDS = GetEngine()->AddObject(GetDocID(), GEOM_PIPE);
+  Handle(GEOM_Object) aPipeDS = GetEngine()->AddObject(GEOM_PIPE);
 
   //Add a new Pipe function
 
   Handle(GEOM_Function) aFunction =
     aPipeDS->AddFunction(GEOMImpl_PipeDriver::GetID(), PIPE_DIFFERENT_SECTIONS);
-  if (aFunction.IsNull()) return anObj;
+  if (aFunction.IsNull()) return NULL;
 
   //Check if the function is set correctly
-  if (aFunction->GetDriverGUID() != GEOMImpl_PipeDriver::GetID()) return anObj;
+  if (aFunction->GetDriverGUID() != GEOMImpl_PipeDriver::GetID()) return NULL;
 
   GEOMImpl_IPipeDiffSect aCI (aFunction);
 
   Handle(GEOM_Function) aRefPath = thePath->GetLastFunction();
   if(aRefPath.IsNull())
-    return anObj;
+    return NULL;
 
   Handle(TColStd_HSequenceOfTransient) aSeqBases = new TColStd_HSequenceOfTransient;
   Handle(TColStd_HSequenceOfTransient) aSeqLocs = new TColStd_HSequenceOfTransient;
@@ -1805,33 +1859,53 @@ Handle(GEOM_Object) GEOMImpl_I3DPrimOperations::MakePipeWithDifferentSections(
   }
 
   if(!aSeqBases->Length())
-    return anObj;
+    return NULL;
 
   aCI.SetBases(aSeqBases);
   aCI.SetLocations(aSeqLocs);
   aCI.SetPath(aRefPath);
-  aCI.SetWithContactMode(theWithContact);
-  aCI.SetWithCorrectionMode(theWithCorrections);
+
+  if (!IsBySteps) {
+    aCI.SetWithContactMode(theWithContact);
+    aCI.SetWithCorrectionMode(theWithCorrections);
+  }
+
+  aCI.SetIsBySteps(IsBySteps);
+  aCI.SetGenerateGroups(IsGenerateGroups);
 
   //Compute the Pipe value
   try {
-#if OCC_VERSION_LARGE > 0x06010000
     OCC_CATCH_SIGNALS;
-#endif
     if (!GetSolver()->ComputeFunction(aFunction)) {
-      SetErrorCode("Pipe with defferent section driver failed");
-      return anObj;
+      SetErrorCode("Pipe with different section driver failed");
+      return NULL;
     }
   }
-  catch (Standard_Failure) {
-    Handle(Standard_Failure) aFail = Standard_Failure::Caught();
-    SetErrorCode(aFail->GetMessageString());
-    return anObj;
+  catch (Standard_Failure& aFail) {
+    SetErrorCode(aFail.GetMessageString());
+    return NULL;
   }
 
+  // Create the sequence of objects.
+  Handle(TColStd_HSequenceOfTransient) aSeq = new TColStd_HSequenceOfTransient;
+
+  aSeq->Append(aPipeDS);
+  createGroups(aPipeDS, &aCI, aSeq);
+
   //Make a Python command
   GEOM::TPythonDump pyDump(aFunction);
-  pyDump << aPipeDS << " = geompy.MakePipeWithDifferentSections([";
+
+  if (IsGenerateGroups) {
+    pyDump << aSeq;
+  } else {
+    pyDump << aPipeDS;
+  }
+
+  if (IsBySteps) {
+    pyDump << " = geompy.MakePipeWithDifferentSectionsBySteps([";
+  } else {
+    pyDump << " = geompy.MakePipeWithDifferentSections([";
+  }
 
   for(i =1 ; i <= nbBases; i++) {
 
@@ -1863,10 +1937,20 @@ Handle(GEOM_Object) GEOMImpl_I3DPrimOperations::MakePipeWithDifferentSections(
     }
   }
 
-  pyDump<< "], "<<thePath<<","<<theWithContact << "," << theWithCorrections<<")";
+  pyDump<< "], "<<thePath;
+
+  if (!IsBySteps) {
+    pyDump<<","<<theWithContact << "," << theWithCorrections;
+  }
+
+  if (IsGenerateGroups) {
+    pyDump << ", True";
+  }
+
+  pyDump << ")";
 
   SetErrorCode(OK);
-  return aPipeDS;
+  return aSeq;
 }
 
 
@@ -1875,46 +1959,47 @@ Handle(GEOM_Object) GEOMImpl_I3DPrimOperations::MakePipeWithDifferentSections(
  *  MakePipeWithShellSections
  */
 //=============================================================================
-Handle(GEOM_Object) GEOMImpl_I3DPrimOperations::MakePipeWithShellSections(
-                const Handle(TColStd_HSequenceOfTransient)& theBases,
-                const Handle(TColStd_HSequenceOfTransient)& theSubBases,
-                const Handle(TColStd_HSequenceOfTransient)& theLocations,
-                const Handle(GEOM_Object)& thePath,
-                bool theWithContact,
-                bool theWithCorrections)
+Handle(TColStd_HSequenceOfTransient)
+      GEOMImpl_I3DPrimOperations::MakePipeWithShellSections
+              (const Handle(TColStd_HSequenceOfTransient) &theBases,
+               const Handle(TColStd_HSequenceOfTransient) &theSubBases,
+               const Handle(TColStd_HSequenceOfTransient) &theLocations,
+               const Handle(GEOM_Object)                  &thePath,
+               const bool                                  theWithContact,
+               const bool                                  theWithCorrections,
+               const bool                                  IsGenerateGroups)
 {
-  Handle(GEOM_Object) anObj;
   SetErrorCode(KO);
   if(theBases.IsNull())
-    return anObj;
+    return NULL;
 
   Standard_Integer nbBases = theBases->Length();
 
   if (!nbBases)
-    return anObj;
+    return NULL;
 
   Standard_Integer nbSubBases =  (theSubBases.IsNull() ? 0 :theSubBases->Length());
 
   Standard_Integer nbLocs =  (theLocations.IsNull() ? 0 :theLocations->Length());
 
   //Add a new Pipe object
-  Handle(GEOM_Object) aPipeDS = GetEngine()->AddObject(GetDocID(), GEOM_PIPE);
+  Handle(GEOM_Object) aPipeDS = GetEngine()->AddObject(GEOM_PIPE);
 
   //Add a new Pipe function
 
   Handle(GEOM_Function) aFunction =
     aPipeDS->AddFunction(GEOMImpl_PipeDriver::GetID(), PIPE_SHELL_SECTIONS);
-  if (aFunction.IsNull()) return anObj;
+  if (aFunction.IsNull()) return NULL;
 
   //Check if the function is set correctly
-  if (aFunction->GetDriverGUID() != GEOMImpl_PipeDriver::GetID()) return anObj;
+  if (aFunction->GetDriverGUID() != GEOMImpl_PipeDriver::GetID()) return NULL;
 
   //GEOMImpl_IPipeDiffSect aCI (aFunction);
   GEOMImpl_IPipeShellSect aCI (aFunction);
 
   Handle(GEOM_Function) aRefPath = thePath->GetLastFunction();
   if(aRefPath.IsNull())
-    return anObj;
+    return NULL;
 
   Handle(TColStd_HSequenceOfTransient) aSeqBases = new TColStd_HSequenceOfTransient;
   Handle(TColStd_HSequenceOfTransient) aSeqSubBases = new TColStd_HSequenceOfTransient;
@@ -1963,7 +2048,7 @@ Handle(GEOM_Object) GEOMImpl_I3DPrimOperations::MakePipeWithShellSections(
   }
 
   if(!aSeqBases->Length())
-    return anObj;
+    return NULL;
 
   aCI.SetBases(aSeqBases);
   aCI.SetSubBases(aSeqSubBases);
@@ -1971,26 +2056,37 @@ Handle(GEOM_Object) GEOMImpl_I3DPrimOperations::MakePipeWithShellSections(
   aCI.SetPath(aRefPath);
   aCI.SetWithContactMode(theWithContact);
   aCI.SetWithCorrectionMode(theWithCorrections);
+  aCI.SetGenerateGroups(IsGenerateGroups);
 
   //Compute the Pipe value
   try {
-#if OCC_VERSION_LARGE > 0x06010000
     OCC_CATCH_SIGNALS;
-#endif
     if (!GetSolver()->ComputeFunction(aFunction)) {
       SetErrorCode("Pipe with shell sections driver failed");
-      return anObj;
+      return NULL;
     }
   }
-  catch (Standard_Failure) {
-    Handle(Standard_Failure) aFail = Standard_Failure::Caught();
-    SetErrorCode(aFail->GetMessageString());
-    return anObj;
+  catch (Standard_Failure& aFail) {
+    SetErrorCode(aFail.GetMessageString());
+    return NULL;
   }
 
+  // Create the sequence of objects.
+  Handle(TColStd_HSequenceOfTransient) aSeq = new TColStd_HSequenceOfTransient;
+
+  aSeq->Append(aPipeDS);
+  createGroups(aPipeDS, &aCI, aSeq);
+
   //Make a Python command
   GEOM::TPythonDump pyDump(aFunction);
-  pyDump << aPipeDS << " = geompy.MakePipeWithShellSections([";
+
+  if (IsGenerateGroups) {
+    pyDump << aSeq;
+  } else {
+    pyDump << aPipeDS;
+  }
+
+  pyDump << " = geompy.MakePipeWithShellSections([";
 
   for(i =1 ; i <= nbBases; i++) {
 
@@ -2038,10 +2134,16 @@ Handle(GEOM_Object) GEOMImpl_I3DPrimOperations::MakePipeWithShellSections(
     }
   }
 
-  pyDump<< "], "<<thePath<<","<<theWithContact << "," << theWithCorrections<<")";
+  pyDump<< "], "<<thePath<<","<<theWithContact << "," << theWithCorrections;
+
+  if (IsGenerateGroups) {
+    pyDump << ", True";
+  }
+
+  pyDump << ")";
 
   SetErrorCode(OK);
-  return aPipeDS;
+  return aSeq;
 
 }
 
@@ -2051,33 +2153,34 @@ Handle(GEOM_Object) GEOMImpl_I3DPrimOperations::MakePipeWithShellSections(
  *  MakePipeShellsWithoutPath
  */
 //=============================================================================
-Handle(GEOM_Object) GEOMImpl_I3DPrimOperations::MakePipeShellsWithoutPath(
-                const Handle(TColStd_HSequenceOfTransient)& theBases,
-                const Handle(TColStd_HSequenceOfTransient)& theLocations)
+Handle(TColStd_HSequenceOfTransient)
+      GEOMImpl_I3DPrimOperations::MakePipeShellsWithoutPath
+              (const Handle(TColStd_HSequenceOfTransient) &theBases,
+               const Handle(TColStd_HSequenceOfTransient) &theLocations,
+               const bool                                  IsGenerateGroups)
 {
-  Handle(GEOM_Object) anObj;
   SetErrorCode(KO);
   if(theBases.IsNull())
-    return anObj;
+    return NULL;
 
   Standard_Integer nbBases = theBases->Length();
 
   if (!nbBases)
-    return anObj;
+    return NULL;
 
   Standard_Integer nbLocs =  (theLocations.IsNull() ? 0 :theLocations->Length());
 
   //Add a new Pipe object
-  Handle(GEOM_Object) aPipeDS = GetEngine()->AddObject(GetDocID(), GEOM_PIPE);
+  Handle(GEOM_Object) aPipeDS = GetEngine()->AddObject(GEOM_PIPE);
 
   //Add a new Pipe function
 
   Handle(GEOM_Function) aFunction =
     aPipeDS->AddFunction(GEOMImpl_PipeDriver::GetID(), PIPE_SHELLS_WITHOUT_PATH);
-  if (aFunction.IsNull()) return anObj;
+  if (aFunction.IsNull()) return NULL;
 
   //Check if the function is set correctly
-  if (aFunction->GetDriverGUID() != GEOMImpl_PipeDriver::GetID()) return anObj;
+  if (aFunction->GetDriverGUID() != GEOMImpl_PipeDriver::GetID()) return NULL;
 
   GEOMImpl_IPipeShellSect aCI (aFunction);
 
@@ -2114,30 +2217,41 @@ Handle(GEOM_Object) GEOMImpl_I3DPrimOperations::MakePipeShellsWithoutPath(
   }
 
   if(!aSeqBases->Length())
-    return anObj;
+    return NULL;
 
   aCI.SetBases(aSeqBases);
   aCI.SetLocations(aSeqLocs);
+  aCI.SetGenerateGroups(IsGenerateGroups);
 
   //Compute the Pipe value
   try {
-#if OCC_VERSION_LARGE > 0x06010000
     OCC_CATCH_SIGNALS;
-#endif
     if (!GetSolver()->ComputeFunction(aFunction)) {
       SetErrorCode("Pipe with shell sections without path driver failed");
-      return anObj;
+      return NULL;
     }
   }
-  catch (Standard_Failure) {
-    Handle(Standard_Failure) aFail = Standard_Failure::Caught();
-    SetErrorCode(aFail->GetMessageString());
-    return anObj;
+  catch (Standard_Failure& aFail) {
+    SetErrorCode(aFail.GetMessageString());
+    return NULL;
   }
 
+  // Create the sequence of objects.
+  Handle(TColStd_HSequenceOfTransient) aSeq = new TColStd_HSequenceOfTransient;
+
+  aSeq->Append(aPipeDS);
+  createGroups(aPipeDS, &aCI, aSeq);
+
   //Make a Python command
   GEOM::TPythonDump pyDump(aFunction);
-  pyDump << aPipeDS << " = geompy.MakePipeShellsWithoutPath([";
+
+  if (IsGenerateGroups) {
+    pyDump << aSeq;
+  } else {
+    pyDump << aPipeDS;
+  }
+
+  pyDump << " = geompy.MakePipeShellsWithoutPath([";
 
   for(i =1 ; i <= nbBases; i++) {
 
@@ -2169,29 +2283,37 @@ Handle(GEOM_Object) GEOMImpl_I3DPrimOperations::MakePipeShellsWithoutPath(
     }
   }
 
-  pyDump<< "])";
+  pyDump<< "]";
+
+  if (IsGenerateGroups) {
+    pyDump << ", True";
+  }
+
+  pyDump << ")";
 
   SetErrorCode(OK);
-  return aPipeDS;
+  return aSeq;
 
 }
 
-
 //=============================================================================
 /*!
  *  MakePipeBiNormalAlongVector
  */
 //=============================================================================
-Handle(GEOM_Object) GEOMImpl_I3DPrimOperations::MakePipeBiNormalAlongVector (Handle(GEOM_Object) theBase,
-                                                                             Handle(GEOM_Object) thePath,
-                                                                             Handle(GEOM_Object) theVec)
+Handle(TColStd_HSequenceOfTransient)
+  GEOMImpl_I3DPrimOperations::MakePipeBiNormalAlongVector
+                (const Handle(GEOM_Object) &theBase,
+                 const Handle(GEOM_Object) &thePath,
+                 const Handle(GEOM_Object) &theVec,
+                 const bool                 IsGenerateGroups)
 {
   SetErrorCode(KO);
 
   if (theBase.IsNull() || thePath.IsNull() || theVec.IsNull()) return NULL;
 
   //Add a new Pipe object
-  Handle(GEOM_Object) aPipe = GetEngine()->AddObject(GetDocID(), GEOM_PIPE);
+  Handle(GEOM_Object) aPipe = GetEngine()->AddObject(GEOM_PIPE);
 
   //Add a new Pipe function
   Handle(GEOM_Function) aFunction =
@@ -2212,27 +2334,421 @@ Handle(GEOM_Object) GEOMImpl_I3DPrimOperations::MakePipeBiNormalAlongVector (Han
   aCI.SetBase(aRefBase);
   aCI.SetPath(aRefPath);
   aCI.SetVector(aRefVec);
+  aCI.SetGenerateGroups(IsGenerateGroups);
 
   //Compute the Pipe value
   try {
-#if OCC_VERSION_LARGE > 0x06010000
     OCC_CATCH_SIGNALS;
-#endif
     if (!GetSolver()->ComputeFunction(aFunction)) {
       SetErrorCode("Pipe driver failed");
       return NULL;
     }
   }
-  catch (Standard_Failure) {
-    Handle(Standard_Failure) aFail = Standard_Failure::Caught();
-    SetErrorCode(aFail->GetMessageString());
+  catch (Standard_Failure& aFail) {
+    SetErrorCode(aFail.GetMessageString());
+    return NULL;
+  }
+
+  // Create the sequence of objects.
+  Handle(TColStd_HSequenceOfTransient) aSeq = new TColStd_HSequenceOfTransient;
+
+  aSeq->Append(aPipe);
+  createGroups(aPipe, &aCI, aSeq);
+
+  //Make a Python command
+  GEOM::TPythonDump pyDump(aFunction);
+
+  if (IsGenerateGroups) {
+    pyDump << aSeq;
+  } else {
+    pyDump << aPipe;
+  }
+
+  pyDump << " = geompy.MakePipeBiNormalAlongVector("
+         << theBase << ", " << thePath << ", " << theVec;
+
+  if (IsGenerateGroups) {
+    pyDump << ", True";
+  }
+
+  pyDump << ")";
+
+  SetErrorCode(OK);
+  return aSeq;
+}
+
+//=============================================================================
+/*!
+ *  MakeThickening
+ */
+//=============================================================================
+Handle(GEOM_Object) GEOMImpl_I3DPrimOperations::MakeThickening
+                (Handle(GEOM_Object)                     theObject,
+                 const Handle(TColStd_HArray1OfInteger) &theFacesIDs,
+                 double                                  theOffset,
+                 bool                                    isCopy,
+                 bool                                    theInside)
+{
+  SetErrorCode(KO);
+
+  if (theObject.IsNull()) return NULL;
+
+  Handle(GEOM_Function) anOriginal = theObject->GetLastFunction();
+  if (anOriginal.IsNull()) return NULL; //There is no function which creates an object to be offset
+
+  //Add a new Offset function
+  Handle(GEOM_Function) aFunction;
+  Handle(GEOM_Object) aCopy; 
+  if (isCopy)
+  { 
+    //Add a new Copy object
+    aCopy = GetEngine()->AddObject(theObject->GetType());
+    aFunction = aCopy->AddFunction(GEOMImpl_OffsetDriver::GetID(), OFFSET_THICKENING_COPY);
+  }
+  else
+    aFunction = theObject->AddFunction(GEOMImpl_OffsetDriver::GetID(), OFFSET_THICKENING);
+  
+  if (aFunction.IsNull()) return NULL;
+
+  //Check if the function is set correctly
+  if (aFunction->GetDriverGUID() != GEOMImpl_OffsetDriver::GetID()) return NULL;
+
+  GEOMImpl_IOffset aTI (aFunction);
+  aTI.SetShape(anOriginal);
+  aTI.SetValue(theOffset);
+  aTI.SetParam(theInside);
+
+  if (theFacesIDs.IsNull() == Standard_False) {
+    aTI.SetFaceIDs(theFacesIDs);
+  }
+
+  //Compute the offset
+  try {
+    OCC_CATCH_SIGNALS;
+    if (!GetSolver()->ComputeFunction(aFunction)) {
+      SetErrorCode("Offset driver failed");
+      return NULL;
+    }
+  }
+  catch (Standard_Failure& aFail) {
+    SetErrorCode(aFail.GetMessageString());
     return NULL;
   }
 
   //Make a Python command
-  GEOM::TPythonDump(aFunction) << aPipe << " = geompy.MakePipeBiNormalAlongVector("
-    << theBase << ", " << thePath << ", " << theVec << ")";
+  GEOM::TPythonDump   pd (aFunction);
+  Handle(GEOM_Object) aResult; 
+
+  if (isCopy) {
+    pd << aCopy << " = geompy.MakeThickSolid("
+       << theObject << ", " << theOffset;
+    aResult = aCopy;
+  } else {
+    pd << "geompy.Thicken(" << theObject << ", " << theOffset;
+    aResult = theObject;
+  }
+
+  pd << ", [";
+  if (theFacesIDs.IsNull() == Standard_False) {
+    // Dump faces IDs.
+    Standard_Integer i;
 
+    for (i = theFacesIDs->Lower(); i < theFacesIDs->Upper(); ++i) {
+      pd << theFacesIDs->Value(i) << ", ";
+    }
+    // Dump the last value.
+    pd << theFacesIDs->Value(i);
+  }
+  pd << "]";
+
+  if (theInside)
+    pd << ", " << theInside;
+
+  pd << ")";
   SetErrorCode(OK);
-  return aPipe;
+
+  return aResult;
+}
+
+//=============================================================================
+/*!
+ *  RestorePath
+ */
+//=============================================================================
+Handle(GEOM_Object) GEOMImpl_I3DPrimOperations::RestorePath (Handle(GEOM_Object) theShape,
+                                                             Handle(GEOM_Object) theBase1,
+                                                             Handle(GEOM_Object) theBase2)
+{
+  SetErrorCode(KO);
+
+  if (theShape.IsNull() || theBase1.IsNull() || theBase2.IsNull()) return NULL;
+
+  // Add a new Path object
+  Handle(GEOM_Object) aPath = GetEngine()->AddObject(GEOM_PIPE_PATH);
+
+  // Add a new Path function
+  Handle(GEOM_Function) aFunction =
+    aPath->AddFunction(GEOMImpl_PipePathDriver::GetID(), PIPE_PATH_TWO_BASES);
+  if (aFunction.IsNull()) return NULL;
+
+  // Check if the function is set correctly
+  if (aFunction->GetDriverGUID() != GEOMImpl_PipePathDriver::GetID()) return NULL;
+
+  GEOMImpl_IPipePath aCI (aFunction);
+
+  Handle(GEOM_Function) aRefShape = theShape->GetLastFunction();
+  Handle(GEOM_Function) aRefBase1 = theBase1->GetLastFunction();
+  Handle(GEOM_Function) aRefBase2 = theBase2->GetLastFunction();
+
+  if (aRefShape.IsNull() || aRefBase1.IsNull() || aRefBase2.IsNull()) return NULL;
+
+  aCI.SetShape(aRefShape);
+  aCI.SetBase1(aRefBase1);
+  aCI.SetBase2(aRefBase2);
+
+  // Compute the Path value
+  try {
+    OCC_CATCH_SIGNALS;
+    if (!GetSolver()->ComputeFunction(aFunction)) {
+      SetErrorCode("PipePath driver failed");
+      return NULL;
+    }
+  }
+  catch (Standard_Failure& aFail) {
+    SetErrorCode("RestorePath: inappropriate arguments given");
+    return NULL;
+  }
+
+  // Make a Python command
+  GEOM::TPythonDump(aFunction) << aPath << " = geompy.RestorePath("
+    << theShape << ", " << theBase1 << ", " << theBase2 << ")";
+
+  SetErrorCode(OK);
+  return aPath;
+}
+
+//=============================================================================
+/*!
+ *  RestorePath
+ */
+//=============================================================================
+Handle(GEOM_Object) GEOMImpl_I3DPrimOperations::RestorePath
+                         (Handle(GEOM_Object) theShape,
+                          const Handle(TColStd_HSequenceOfTransient)& theBase1,
+                          const Handle(TColStd_HSequenceOfTransient)& theBase2)
+{
+  SetErrorCode(KO);
+
+  if (theShape.IsNull() || theBase1.IsNull() || theBase2.IsNull()) return NULL;
+
+  Standard_Integer nbBases1 = theBase1->Length();
+  Standard_Integer nbBases2 = theBase2->Length();
+
+  if (!nbBases1 || !nbBases2)
+    return NULL;
+
+  // Add a new Path object
+  Handle(GEOM_Object) aPath = GetEngine()->AddObject(GEOM_PIPE_PATH);
+
+  // Add a new Path function
+  Handle(GEOM_Function) aFunction =
+    aPath->AddFunction(GEOMImpl_PipePathDriver::GetID(), PIPE_PATH_TWO_SEQS);
+  if (aFunction.IsNull()) return NULL;
+
+  // Check if the function is set correctly
+  if (aFunction->GetDriverGUID() != GEOMImpl_PipePathDriver::GetID()) return NULL;
+
+  GEOMImpl_IPipePath aCI (aFunction);
+
+  Handle(GEOM_Function) aRefShape = theShape->GetLastFunction();
+  if (aRefShape.IsNull()) return NULL;
+
+  Handle(TColStd_HSequenceOfTransient) aSeqBases1 = new TColStd_HSequenceOfTransient;
+  Handle(TColStd_HSequenceOfTransient) aSeqBases2 = new TColStd_HSequenceOfTransient;
+
+  Standard_Integer i;
+  for (i = 1; i <= nbBases1; i++) {
+    Handle(Standard_Transient) anItem = theBase1->Value(i);
+    if (!anItem.IsNull()) {
+      Handle(GEOM_Object) aBase = Handle(GEOM_Object)::DownCast(anItem);
+      if (!aBase.IsNull()) {
+        Handle(GEOM_Function) aRefBase = aBase->GetLastFunction();
+        if (!aRefBase.IsNull())
+          aSeqBases1->Append(aRefBase);
+      }
+    }
+  }
+  for (i = 1; i <= nbBases2; i++) {
+    Handle(Standard_Transient) anItem = theBase2->Value(i);
+    if (!anItem.IsNull()) {
+      Handle(GEOM_Object) aBase = Handle(GEOM_Object)::DownCast(anItem);
+      if (!aBase.IsNull()) {
+        Handle(GEOM_Function) aRefBase = aBase->GetLastFunction();
+        if (!aRefBase.IsNull())
+          aSeqBases2->Append(aRefBase);
+      }
+    }
+  }
+  if (!aSeqBases1->Length() || !aSeqBases2->Length()) return NULL;
+
+  aCI.SetShape(aRefShape);
+  aCI.SetBaseSeq1(aSeqBases1);
+  aCI.SetBaseSeq2(aSeqBases2);
+
+  // Compute the Path value
+  try {
+    OCC_CATCH_SIGNALS;
+    if (!GetSolver()->ComputeFunction(aFunction)) {
+      SetErrorCode("PipePath driver failed");
+      return NULL;
+    }
+  }
+  catch (Standard_Failure& aFail) {
+    SetErrorCode("RestorePath: inappropriate arguments given");
+    return NULL;
+  }
+
+  // Make a Python command
+  GEOM::TPythonDump pyDump (aFunction);
+  pyDump << aPath << " = geompy.RestorePathEdges(" << theShape << ", [";
+  for (i = 1; i <= nbBases1; i++) {
+    Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast(theBase1->Value(i));
+    if (!anObj.IsNull()) {
+      pyDump << anObj;
+      if (i < nbBases1)
+        pyDump << ", ";
+    }
+  }
+  pyDump<< "], [";
+  for (i = 1; i <= nbBases2; i++) {
+    Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast(theBase2->Value(i));
+    if (!anObj.IsNull()) {
+      pyDump << anObj;
+      if (i < nbBases2)
+        pyDump << ", ";
+    }
+  }
+  pyDump << "])";
+
+  SetErrorCode(OK);
+  return aPath;
+}
+
+//=============================================================================
+/*!
+ *  createGroup
+ */
+//=============================================================================
+Handle(GEOM_Object) GEOMImpl_I3DPrimOperations::createGroup
+                  (const Handle(GEOM_Object)              &theBaseObject,
+                   const Handle(TColStd_HArray1OfInteger) &theGroupIDs,
+                   const TCollection_AsciiString          &theName,
+                   const TopTools_IndexedMapOfShape       &theIndices)
+{
+  if (theBaseObject.IsNull() || theGroupIDs.IsNull()) {
+    return NULL;
+  }
+
+  // Get the Shape type.
+  const Standard_Integer anID      = theGroupIDs->Value(theGroupIDs->Lower());
+  const Standard_Integer aNbShapes = theIndices.Extent();
+
+  if (anID < 1 || anID > aNbShapes) {
+    return NULL;
+  }
+
+  const TopoDS_Shape aSubShape = theIndices.FindKey(anID);
+
+  if (aSubShape.IsNull()) {
+    return NULL;
+  }
+
+  // Create a group.
+  const TopAbs_ShapeEnum aGroupType = aSubShape.ShapeType();
+  Handle(GEOM_Object)    aGroup     =
+    myGroupOperations->CreateGroup(theBaseObject, aGroupType);
+
+  if (aGroup.IsNull() == Standard_False) {
+    aGroup->GetLastFunction()->SetDescription("");
+    aGroup->SetName(theName.ToCString());
+
+    Handle(TColStd_HSequenceOfInteger) aSeqIDs = new TColStd_HSequenceOfInteger;
+    Standard_Integer                   i;
+
+    for (i = theGroupIDs->Lower(); i <= theGroupIDs->Upper(); ++i) {
+      // Get and check the index.
+      const Standard_Integer anIndex = theGroupIDs->Value(i);
+
+      if (anIndex < 1 || anIndex > aNbShapes) {
+        return NULL;
+      }
+
+      // Get and check the sub-shape.
+      const TopoDS_Shape aSubShape = theIndices.FindKey(anIndex);
+
+      if (aSubShape.IsNull()) {
+        return NULL;
+      }
+
+      // Check the shape type.
+      if (aSubShape.ShapeType() != aGroupType) {
+        return NULL;
+      }
+
+      aSeqIDs->Append(anIndex);
+    }
+
+    myGroupOperations->UnionIDs(aGroup, aSeqIDs);
+    aGroup->GetLastFunction()->SetDescription("");
+  }
+
+  return aGroup;
+}
+
+//=============================================================================
+/*!
+ *  createGroups
+ */
+//=============================================================================
+void GEOMImpl_I3DPrimOperations::createGroups
+                   (const Handle(GEOM_Object)                  &theBaseObject,
+                          GEOMImpl_IPipe                       *thePipe,
+                          Handle(TColStd_HSequenceOfTransient) &theSequence)
+{
+  if (theBaseObject.IsNull() || thePipe == NULL || theSequence.IsNull()) {
+    return;
+  }
+
+  TopoDS_Shape aShape = theBaseObject->GetValue();
+
+  if (aShape.IsNull()) {
+    return;
+  }
+
+  TopTools_IndexedMapOfShape       anIndices;
+  Handle(TColStd_HArray1OfInteger) aGroupIDs;
+  TopoDS_Shape                     aShapeType;
+  const Standard_Integer           aNbGroups = 5;
+  Handle(GEOM_Object)              aGrps[aNbGroups];
+  Standard_Integer                 i;
+
+  TopExp::MapShapes(aShape, anIndices);
+
+  // Create groups.
+  aGroupIDs = thePipe->GetGroupDown();
+  aGrps[0]  = createGroup(theBaseObject, aGroupIDs, "GROUP_DOWN", anIndices);
+  aGroupIDs = thePipe->GetGroupUp();
+  aGrps[1]  = createGroup(theBaseObject, aGroupIDs, "GROUP_UP", anIndices);
+  aGroupIDs = thePipe->GetGroupSide1();
+  aGrps[2]  = createGroup(theBaseObject, aGroupIDs, "GROUP_SIDE1", anIndices);
+  aGroupIDs = thePipe->GetGroupSide2();
+  aGrps[3]  = createGroup(theBaseObject, aGroupIDs, "GROUP_SIDE2", anIndices);
+  aGroupIDs = thePipe->GetGroupOther();
+  aGrps[4]  = createGroup(theBaseObject, aGroupIDs, "GROUP_OTHER", anIndices);
+
+  for (i = 0; i < aNbGroups; ++i) {
+    if (aGrps[i].IsNull() == Standard_False) {
+      theSequence->Append(aGrps[i]);
+    }
+  }
 }