Salome HOME
Merge remote-tracking branch 'remotes/origin/hydro/imps_2017_salome_83' into HEAD
[modules/geom.git] / src / GEOMImpl / GEOMImpl_I3DPrimOperations.cxx
index 2698619b1eb410d30de462255c7c66438c08c1f2..41a288f8b9aad1c81f42c248dd435066fd27dc9e 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2016  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
 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
 //
 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
 
 #include <Standard_Stream.hxx>
 
-#include <Basics_OCCTVersion.hxx>
-
 #include <GEOMImpl_I3DPrimOperations.hxx>
 
 #include "utilities.h"
@@ -31,7 +30,6 @@
 
 #include <TFunction_DriverTable.hxx>
 #include <TFunction_Driver.hxx>
-#include <TFunction_Logbook.hxx>
 #include <TDF_Tool.hxx>
 
 #include <GEOM_Function.hxx>
@@ -60,6 +58,7 @@
 #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>
@@ -74,6 +73,7 @@
 #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
@@ -87,6 +87,7 @@ GEOMImpl_I3DPrimOperations::GEOMImpl_I3DPrimOperations (GEOM_Engine* theEngine,
 : GEOM_IOperations(theEngine, theDocID)
 {
   MESSAGE("GEOMImpl_I3DPrimOperations::GEOMImpl_I3DPrimOperations");
+  myGroupOperations = new GEOMImpl_IGroupOperations(GetEngine(), GetDocID());
 }
 
 //=============================================================================
@@ -97,6 +98,7 @@ GEOMImpl_I3DPrimOperations::GEOMImpl_I3DPrimOperations (GEOM_Engine* theEngine,
 GEOMImpl_I3DPrimOperations::~GEOMImpl_I3DPrimOperations()
 {
   MESSAGE("GEOMImpl_I3DPrimOperations::~GEOMImpl_I3DPrimOperations");
+  delete myGroupOperations;
 }
 
 
@@ -127,17 +129,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;
   }
 
@@ -184,17 +183,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;
   }
 
@@ -235,17 +231,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;
   }
 
@@ -292,17 +285,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;
   }
 
@@ -350,17 +340,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;
   }
 
@@ -410,17 +397,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;
   }
 
@@ -460,17 +444,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;
   }
 
@@ -508,17 +489,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;
   }
 
@@ -530,6 +508,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(GetDocID(), 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;
+}
 
 //=============================================================================
 /*!
@@ -569,17 +592,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;
   }
 
@@ -591,6 +611,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(GetDocID(), 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;
+}
+
 
 //=============================================================================
 /*!
@@ -621,17 +699,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;
   }
 
@@ -684,17 +759,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;
   }
 
@@ -732,17 +804,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;
   }
 
@@ -787,17 +856,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;
   }
 
@@ -838,17 +904,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;
   }
 
@@ -898,17 +961,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;
   }
 
@@ -959,18 +1019,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;
   }
 
@@ -1023,18 +1080,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;
   }
 
@@ -1086,18 +1140,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;
   }
 
@@ -1151,18 +1202,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;
   }
 
@@ -1212,17 +1260,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;
   }
 
@@ -1275,17 +1320,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;
   }
 
@@ -1303,7 +1345,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);
 
@@ -1346,34 +1388,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;
@@ -1384,8 +1428,10 @@ 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);
 
@@ -1411,29 +1457,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;
 }
 
 
@@ -1474,17 +1537,14 @@ 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;
   }
 
@@ -1532,17 +1592,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;
   }
 
@@ -1559,15 +1616,19 @@ 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);
 
@@ -1579,12 +1640,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);
@@ -1595,36 +1651,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);
@@ -1694,17 +1747,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;
   }
 
@@ -1738,22 +1788,24 @@ 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
@@ -1763,16 +1815,16 @@ Handle(GEOM_Object) GEOMImpl_I3DPrimOperations::MakePipeWithDifferentSections(
 
   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;
@@ -1808,33 +1860,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;
+      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++) {
 
@@ -1866,10 +1938,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;
 }
 
 
@@ -1878,23 +1960,24 @@ 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());
 
@@ -1907,17 +1990,17 @@ Handle(GEOM_Object) GEOMImpl_I3DPrimOperations::MakePipeWithShellSections(
 
   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;
@@ -1966,7 +2049,7 @@ Handle(GEOM_Object) GEOMImpl_I3DPrimOperations::MakePipeWithShellSections(
   }
 
   if(!aSeqBases->Length())
-    return anObj;
+    return NULL;
 
   aCI.SetBases(aSeqBases);
   aCI.SetSubBases(aSeqSubBases);
@@ -1974,26 +2057,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++) {
 
@@ -2041,10 +2135,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;
 
 }
 
@@ -2054,19 +2154,20 @@ 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());
 
@@ -2077,10 +2178,10 @@ Handle(GEOM_Object) GEOMImpl_I3DPrimOperations::MakePipeShellsWithoutPath(
 
   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);
 
@@ -2117,30 +2218,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++) {
 
@@ -2172,10 +2284,16 @@ Handle(GEOM_Object) GEOMImpl_I3DPrimOperations::MakePipeShellsWithoutPath(
     }
   }
 
-  pyDump<< "])";
+  pyDump<< "]";
+
+  if (IsGenerateGroups) {
+    pyDump << ", True";
+  }
+
+  pyDump << ")";
 
   SetErrorCode(OK);
-  return aPipeDS;
+  return aSeq;
 
 }
 
@@ -2184,9 +2302,12 @@ Handle(GEOM_Object) GEOMImpl_I3DPrimOperations::MakePipeShellsWithoutPath(
  *  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);
 
@@ -2214,29 +2335,47 @@ 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(aFunction) << aPipe << " = geompy.MakePipeBiNormalAlongVector("
-    << theBase << ", " << thePath << ", " << theVec << ")";
+  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 aPipe;
+  return aSeq;
 }
 
 //=============================================================================
@@ -2244,9 +2383,12 @@ Handle(GEOM_Object) GEOMImpl_I3DPrimOperations::MakePipeBiNormalAlongVector (Han
  *  MakeThickening
  */
 //=============================================================================
-Handle(GEOM_Object) GEOMImpl_I3DPrimOperations::MakeThickening(Handle(GEOM_Object) theObject,
-                                                              double theOffset,
-                                                              bool copy = true)
+Handle(GEOM_Object) GEOMImpl_I3DPrimOperations::MakeThickening
+                (Handle(GEOM_Object)                     theObject,
+                 const Handle(TColStd_HArray1OfInteger) &theFacesIDs,
+                 double                                  theOffset,
+                 bool                                    isCopy,
+                 bool                                    theInside)
 {
   SetErrorCode(KO);
 
@@ -2258,7 +2400,7 @@ Handle(GEOM_Object) GEOMImpl_I3DPrimOperations::MakeThickening(Handle(GEOM_Objec
   //Add a new Offset function
   Handle(GEOM_Function) aFunction;
   Handle(GEOM_Object) aCopy; 
-  if (copy)
+  if (isCopy)
   { 
     //Add a new Copy object
     aCopy = GetEngine()->AddObject(GetDocID(), theObject->GetType());
@@ -2275,38 +2417,58 @@ Handle(GEOM_Object) GEOMImpl_I3DPrimOperations::MakeThickening(Handle(GEOM_Objec
   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 {
-#if OCC_VERSION_LARGE > 0x06010000
     OCC_CATCH_SIGNALS;
-#endif
     if (!GetSolver()->ComputeFunction(aFunction)) {
       SetErrorCode("Offset 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
-  if(copy)
-  {
-    GEOM::TPythonDump(aFunction) << aCopy << " = geompy.MakeThickSolid("
-                               << theObject << ", " << theOffset << ")";
-    SetErrorCode(OK);
-    return aCopy;
+  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;
   }
-  else
-  {
-    GEOM::TPythonDump(aFunction) << "geompy.Thicken("
-                               << theObject << ", " << theOffset << ")";
-    SetErrorCode(OK);
-    return 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 aResult;
 }
 
 //=============================================================================
@@ -2347,16 +2509,13 @@ Handle(GEOM_Object) GEOMImpl_I3DPrimOperations::RestorePath (Handle(GEOM_Object)
 
   // Compute the Path value
   try {
-#if OCC_VERSION_LARGE > 0x06010000
     OCC_CATCH_SIGNALS;
-#endif
     if (!GetSolver()->ComputeFunction(aFunction)) {
       SetErrorCode("PipePath driver failed");
       return NULL;
     }
   }
-  catch (Standard_Failure) {
-    Handle(Standard_Failure) aFail = Standard_Failure::Caught();
+  catch (Standard_Failure& aFail) {
     SetErrorCode("RestorePath: inappropriate arguments given");
     return NULL;
   }
@@ -2439,16 +2598,13 @@ Handle(GEOM_Object) GEOMImpl_I3DPrimOperations::RestorePath
 
   // Compute the Path value
   try {
-#if OCC_VERSION_LARGE > 0x06010000
     OCC_CATCH_SIGNALS;
-#endif
     if (!GetSolver()->ComputeFunction(aFunction)) {
       SetErrorCode("PipePath driver failed");
       return NULL;
     }
   }
-  catch (Standard_Failure) {
-    Handle(Standard_Failure) aFail = Standard_Failure::Caught();
+  catch (Standard_Failure& aFail) {
     SetErrorCode("RestorePath: inappropriate arguments given");
     return NULL;
   }
@@ -2478,3 +2634,122 @@ Handle(GEOM_Object) GEOMImpl_I3DPrimOperations::RestorePath
   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]);
+    }
+  }
+}