Salome HOME
Dump Python
[modules/geom.git] / src / GEOMImpl / GEOMImpl_IShapesOperations.cxx
index ee637328b3dc62bff205353889f668a4651a2ddd..d8991212334f26f665e2f9494a9509c1dc895bcf 100644 (file)
@@ -13,8 +13,12 @@ using namespace std;
 #include "GEOMImpl_IShapes.hxx"
 #include "GEOMImpl_IGlue.hxx"
 
+#include "GEOMImpl_Block6Explorer.hxx"
+
 #include "GEOM_Function.hxx"
 
+#include "GEOMAlgo_FinderShapeOn.hxx"
+
 #include "utilities.h"
 #include "OpUtil.hxx"
 #include "Utils_ExceptHandlers.hxx"
@@ -22,26 +26,49 @@ using namespace std;
 #include <TFunction_DriverTable.hxx>
 #include <TFunction_Driver.hxx>
 #include <TFunction_Logbook.hxx>
+#include <TDataStd_Integer.hxx>
+#include <TDataStd_IntegerArray.hxx>
 #include <TDF_Tool.hxx>
 
+#include <BRepExtrema_ExtCF.hxx>
+
 #include <BRep_Tool.hxx>
 #include <BRepGProp.hxx>
+#include <BRepAdaptor_Curve.hxx>
+#include <BRepBuilderAPI_MakeFace.hxx>
 
 #include <TopAbs.hxx>
 #include <TopExp.hxx>
 #include <TopoDS.hxx>
 #include <TopoDS_Shape.hxx>
+#include <TopoDS_Face.hxx>
+#include <TopoDS_Edge.hxx>
+#include <TopoDS_Vertex.hxx>
 #include <TopoDS_Iterator.hxx>
 #include <TopExp_Explorer.hxx>
+#include <TopLoc_Location.hxx>
 #include <TopTools_MapOfShape.hxx>
 #include <TopTools_Array1OfShape.hxx>
 #include <TopTools_ListIteratorOfListOfShape.hxx>
 #include <TopTools_IndexedMapOfShape.hxx>
 
+#include <Geom_Surface.hxx>
+#include <Geom_Plane.hxx>
+#include <Geom_SphericalSurface.hxx>
+#include <Geom_CylindricalSurface.hxx>
+#include <GeomAdaptor_Surface.hxx>
+
+#include <Geom2d_Curve.hxx>
+
 #include <GProp_GProps.hxx>
 #include <gp_Pnt.hxx>
+#include <gp_Lin.hxx>
 #include <TColStd_Array1OfReal.hxx>
 #include <TColStd_HArray1OfInteger.hxx>
+#include <TColStd_ListOfInteger.hxx>
+#include <TColStd_ListIteratorOfListOfInteger.hxx>
+
+//#include <OSD_Timer.hxx>
 
 #include <Standard_ErrorHandler.hxx> // CAREFUL ! position of this file is critic : see Lucien PIGNOLONI / OCC
 
@@ -114,7 +141,7 @@ Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeEdge
   //Make a Python command
   TCollection_AsciiString anEntry, aDescr;
   TDF_Tool::Entry(anEdge->GetEntry(), anEntry);
-  aDescr += (anEntry+" = IShapesOperations.MakeEdge(");
+  aDescr += (anEntry+" = geompy.MakeEdge(");
   TDF_Tool::Entry(thePnt1->GetEntry(), anEntry);
   aDescr += (anEntry+", ");
   TDF_Tool::Entry(thePnt2->GetEntry(), anEntry);
@@ -186,12 +213,11 @@ Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeFace (Handle(GEOM_Object) th
   TCollection_AsciiString anEntry, aDescr;
   TDF_Tool::Entry(aFace->GetEntry(), anEntry);
   aDescr += anEntry;
-  aDescr += " = IShapesOperations.MakeFace(";
+  aDescr += " = geompy.MakeFace(";
   TDF_Tool::Entry(theWire->GetEntry(), anEntry);
   aDescr += anEntry;
   if (isPlanarWanted)
     aDescr += ", 1)";
-
   else
     aDescr += ", 0)";
 
@@ -207,7 +233,8 @@ Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeFace (Handle(GEOM_Object) th
  */
 //=============================================================================
 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeFaceWires
-                      (list<Handle(GEOM_Object)> theShapes, bool isPlanarWanted)
+                             (list<Handle(GEOM_Object)> theShapes,
+                              const bool isPlanarWanted)
 {
   SetErrorCode(KO);
 
@@ -256,13 +283,13 @@ Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeFaceWires
   //Make a Python command
   TCollection_AsciiString anEntry, aDescr;
   TDF_Tool::Entry(aShape->GetEntry(), anEntry);
-  aDescr += (anEntry + " = IShapesOperations.MakeFaceWires([");
+  aDescr += (anEntry + " = geompy.MakeFaceWires([");
   // Shapes
   it = theShapes.begin();
   if (it != theShapes.end()) {
     TDF_Tool::Entry((*it)->GetEntry(), anEntry);
+    aDescr += anEntry;
     it++;
-    aDescr += (anEntry+", ");
     for (; it != theShapes.end(); it++) {
       aDescr += ", ";
       TDF_Tool::Entry((*it)->GetEntry(), anEntry);
@@ -300,7 +327,7 @@ Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeShell
 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeSolidShells
                              (list<Handle(GEOM_Object)> theShapes)
 {
-  return MakeShape(theShapes, GEOM_SOLID, SOLID_SHELLS, "MakeSolidShells");
+  return MakeShape(theShapes, GEOM_SOLID, SOLID_SHELLS, "MakeSolid");
 }
 
 //=============================================================================
@@ -350,7 +377,7 @@ Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeSolidShell (Handle(GEOM_Obje
   TCollection_AsciiString anEntry, aDescr("");
   TDF_Tool::Entry(aSolid->GetEntry(), anEntry);
   aDescr += anEntry;
-  aDescr += " = IShapesOperations.MakeSolidShell(";
+  aDescr += " = geompy.MakeSolid(";
   TDF_Tool::Entry(theShell->GetEntry(), anEntry);
   aDescr += (anEntry+")");
 
@@ -427,14 +454,14 @@ Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeShape
   //Make a Python command
   TCollection_AsciiString anEntry, aDescr("");
   TDF_Tool::Entry(aShape->GetEntry(), anEntry);
-  aDescr += (anEntry + " = IShapesOperations.");
+  aDescr += (anEntry + " = geompy.");
   aDescr += (theMethodName + "([");
   // Shapes
   it = theShapes.begin();
   if (it != theShapes.end()) {
     TDF_Tool::Entry((*it)->GetEntry(), anEntry);
+    aDescr += anEntry;
     it++;
-    aDescr += (anEntry+", ");
     for (; it != theShapes.end(); it++) {
       aDescr += ", ";
       TDF_Tool::Entry((*it)->GetEntry(), anEntry);
@@ -482,6 +509,7 @@ Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeGlueFaces
   aCI.SetTolerance(theTolerance);
 
   //Compute the sub-shape value
+  Standard_Boolean isWarning = Standard_False;
   try {
     if (!GetSolver()->ComputeFunction(aFunction)) {
       SetErrorCode("Shape driver failed to glue faces");
@@ -491,21 +519,27 @@ Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeGlueFaces
   catch (Standard_Failure) {
     Handle(Standard_Failure) aFail = Standard_Failure::Caught();
     SetErrorCode(aFail->GetMessageString());
-    return NULL;
+    // to provide warning
+    if (!aFunction->GetValue().IsNull()) {
+      isWarning = Standard_True;
+    } else {
+      return NULL;
+    }
   }
 
   //Make a Python command
   TCollection_AsciiString anEntry, aDescr;
   TDF_Tool::Entry(aGlued->GetEntry(), anEntry);
   aDescr += anEntry;
-  aDescr += " = IShapesOperations.MakeGlueFaces(";
+  aDescr += " = geompy.MakeGlueFaces(";
   TDF_Tool::Entry(theShape->GetEntry(), anEntry);
   aDescr += anEntry + ", ";
   aDescr += TCollection_AsciiString(theTolerance) + ")";
 
   aFunction->SetDescription(aDescr);
 
-  SetErrorCode(OK);
+  // to provide warning
+  if (!isWarning) SetErrorCode(OK);
   return aGlued;
 }
 
@@ -519,6 +553,9 @@ Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::MakeExplode
                                            const Standard_Integer theShapeType,
                                            const Standard_Boolean isSorted)
 {
+//  OSD_Timer timer1, timer2, timer3, timer4;
+//  timer1.Start();
+
   SetErrorCode(KO);
 
   if (theShape.IsNull()) return NULL;
@@ -556,9 +593,15 @@ Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::MakeExplode
     return aSeq;
   }
 
+//  timer1.Stop();
+//  timer2.Start();
+
   if (isSorted)
     SortShapes(listShape);
 
+//  timer2.Stop();
+//  timer3.Start();
+
   TopTools_IndexedMapOfShape anIndices;
   TopExp::MapShapes(aShape, anIndices);
   Handle(TColStd_HArray1OfInteger) anArray;
@@ -577,10 +620,13 @@ Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::MakeExplode
     anAsciiList += ",";
   }
 
+//  timer3.Stop();
+//  timer4.Start();
+
   anAsciiList.Trunc(anAsciiList.Length() - 1);
   anAsciiList += "]";
 
-  anAsciiList = TCollection_AsciiString("\n") + anAsciiList;
+  anAsciiList = TCollection_AsciiString("\n\t") + anAsciiList;
 
   //The explode doesn't change object so no new function is requiered.
   aFunction = theShape->GetLastFunction();
@@ -588,7 +634,100 @@ Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::MakeExplode
   //Make a Python command
   TCollection_AsciiString aDescr(anAsciiList);
   TDF_Tool::Entry(theShape->GetEntry(), anEntry);
-  aDescr += " = IShapesOperations.MakeExplode(";
+  if (isSorted)
+    aDescr += " = geompy.SubShapeAllSorted( ";
+  else
+    aDescr += " = geompy.SubShapeAll( ";
+  aDescr += (anEntry + ", ");
+  aDescr += theShapeType;
+  aDescr += " )";
+
+  TCollection_AsciiString anOldDescr = aFunction->GetDescription();
+  anOldDescr = anOldDescr + aDescr;
+  aFunction->SetDescription(anOldDescr);
+
+  SetErrorCode(OK);
+
+//  timer4.Stop();
+
+//  cout << "Explosure takes:" << endl;
+//  timer1.Show();
+//  cout << "Sorting takes:" << endl;
+//  timer2.Show();
+//  cout << "Sub-shapes addition takes:" << endl;
+//  timer3.Show();
+//  cout << "Update Description takes:" << endl;
+//  timer4.Show();
+
+  return aSeq;
+}
+
+//=============================================================================
+/*!
+ *  GetSubShapeAllIDs
+ */
+//=============================================================================
+Handle(TColStd_HSequenceOfInteger) GEOMImpl_IShapesOperations::SubShapeAllIDs
+                                          (Handle(GEOM_Object)    theShape,
+                                           const Standard_Integer theShapeType,
+                                           const Standard_Boolean isSorted)
+{
+  SetErrorCode(KO);
+
+  if (theShape.IsNull()) return NULL;
+  TopoDS_Shape aShape = theShape->GetValue();
+  if (aShape.IsNull()) return NULL;
+
+  Handle(TColStd_HSequenceOfInteger) aSeq = new TColStd_HSequenceOfInteger;
+  TopTools_MapOfShape mapShape;
+  TopTools_ListOfShape listShape;
+
+  if (aShape.ShapeType() == TopAbs_COMPOUND &&
+      (TopAbs_ShapeEnum(theShapeType) == TopAbs_SHAPE ||
+       TopAbs_ShapeEnum(theShapeType) == TopAbs_COMPSOLID ||
+       TopAbs_ShapeEnum(theShapeType) == TopAbs_COMPOUND)) {
+    TopoDS_Iterator It (aShape, Standard_True, Standard_True);
+    for (; It.More(); It.Next()) {
+      if (mapShape.Add(It.Value())) {
+        if (TopAbs_ShapeEnum(theShapeType) == TopAbs_SHAPE ||
+            TopAbs_ShapeEnum(theShapeType) == It.Value().ShapeType()) {
+          listShape.Append(It.Value());
+        }
+      }
+    }
+  } else {
+    TopExp_Explorer exp (aShape, TopAbs_ShapeEnum(theShapeType));
+    for (; exp.More(); exp.Next())
+      if (mapShape.Add(exp.Current()))
+       listShape.Append(exp.Current());
+  }
+
+  if (listShape.IsEmpty()) {
+    SetErrorCode("The given shape has no sub-shapes of the requested type");
+    return aSeq;
+  }
+
+  if (isSorted)
+    SortShapes(listShape);
+
+  TopTools_IndexedMapOfShape anIndices;
+  TopExp::MapShapes(aShape, anIndices);
+  Handle(TColStd_HArray1OfInteger) anArray;
+
+  TopTools_ListIteratorOfListOfShape itSub (listShape);
+  for (int index = 1; itSub.More(); itSub.Next(), ++index) {
+    TopoDS_Shape aValue = itSub.Value();
+    aSeq->Append(anIndices.FindIndex(aValue));
+  }
+
+  //The explode doesn't change object so no new function is required.
+  Handle(GEOM_Function) aFunction = theShape->GetLastFunction();
+
+  //Make a Python command
+  TCollection_AsciiString aDescr
+    ("\n\tlistSubShapeAllIDs = geompy.SubShapeAllIDs(");
+  TCollection_AsciiString anEntry;
+  TDF_Tool::Entry(theShape->GetEntry(), anEntry);
   aDescr += (anEntry + ",");
   if (isSorted)
     aDescr += (TCollection_AsciiString(theShapeType) + ", 1)");
@@ -600,7 +739,6 @@ Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::MakeExplode
   aFunction->SetDescription(anOldDescr);
 
   SetErrorCode(OK);
-
   return aSeq;
 }
 
@@ -619,7 +757,7 @@ Handle(GEOM_Object) GEOMImpl_IShapesOperations::GetSubShape
 
   Handle(TColStd_HArray1OfInteger) anArray = new TColStd_HArray1OfInteger(1,1);
   anArray->SetValue(1, theID);
-  Handle(GEOM_Object) anObj = GetEngine()->AddSubShape(theMainShape, anArray);
+  Handle(GEOM_Object) anObj = GetEngine()->AddSubShape(theMainShape, anArray,true);
   if (anObj.IsNull()) {
     SetErrorCode("Can not get a sub-shape with the given ID");
     return NULL;
@@ -629,13 +767,12 @@ Handle(GEOM_Object) GEOMImpl_IShapesOperations::GetSubShape
   Handle(GEOM_Function) aFunction = theMainShape->GetLastFunction();
 
   //Make a Python command
-  TCollection_AsciiString aDescr ("\n");
+  TCollection_AsciiString aDescr ("\n\t");
   TCollection_AsciiString anEntry;
   TDF_Tool::Entry(anObj->GetEntry(), anEntry);
-  aDescr += anEntry + " = IShapesOperations.GetSubShape(";
+  aDescr += anEntry + " = geompy.GetSubShape(";
   TDF_Tool::Entry(theMainShape->GetEntry(), anEntry);
-  aDescr += anEntry + ", ";
-  aDescr += TCollection_AsciiString(theID) + ")";
+  aDescr += anEntry + ", [" + theID + "])";
 
   TCollection_AsciiString anOldDescr = aFunction->GetDescription();
   anOldDescr = anOldDescr + aDescr;
@@ -744,7 +881,7 @@ Handle(GEOM_Object) GEOMImpl_IShapesOperations::ReverseShape(Handle(GEOM_Object)
   TCollection_AsciiString anEntry, aDescr;
   TDF_Tool::Entry(aReversed->GetEntry(), anEntry);
   aDescr += anEntry;
-  aDescr += " = IShapesOperations.ReverseShape(";
+  aDescr += " = geompy.ChangeOrientation(";
   TDF_Tool::Entry(theShape->GetEntry(), anEntry);
   aDescr += anEntry + ")";
 
@@ -754,6 +891,611 @@ Handle(GEOM_Object) GEOMImpl_IShapesOperations::ReverseShape(Handle(GEOM_Object)
   return aReversed;
 }
 
+//=============================================================================
+/*!
+ *  GetFreeFacesIDs
+ */
+//=============================================================================
+Handle(TColStd_HSequenceOfInteger) GEOMImpl_IShapesOperations::GetFreeFacesIDs
+                                                 (Handle(GEOM_Object) theShape)
+{
+  SetErrorCode(KO);
+
+  if (theShape.IsNull()) return NULL;
+  TopoDS_Shape aShape = theShape->GetValue();
+  if (aShape.IsNull()) return NULL;
+
+  Handle(TColStd_HSequenceOfInteger) aSeq = new TColStd_HSequenceOfInteger;
+
+  TopTools_IndexedDataMapOfShapeListOfShape mapFaceBlocks;
+  GEOMImpl_Block6Explorer::MapShapesAndAncestors
+    (aShape, TopAbs_FACE, TopAbs_SOLID, mapFaceBlocks);
+
+  Standard_Integer ind = 1, nbFaces = mapFaceBlocks.Extent();
+
+  if (nbFaces == 0) {
+    SetErrorCode("The given shape has no faces");
+    return aSeq;
+  }
+
+  TopTools_IndexedMapOfShape anIndices;
+  TopExp::MapShapes(aShape, anIndices);
+
+  Standard_Integer id;
+  for (; ind <= nbFaces; ind++) {
+    if (mapFaceBlocks.FindFromIndex(ind).Extent() != 2) {
+      id = anIndices.FindIndex(mapFaceBlocks.FindKey(ind));
+      aSeq->Append(id);
+    }
+  }
+
+  //The explode doesn't change object so no new function is required.
+  Handle(GEOM_Function) aFunction = theShape->GetLastFunction();
+
+  //Make a Python command
+  TCollection_AsciiString aDescr ("\n\tlistFreeFacesIDs = geompy.GetFreeFacesIDs(");
+  TCollection_AsciiString anEntry;
+  TDF_Tool::Entry(theShape->GetEntry(), anEntry);
+  aDescr += (anEntry + ")");
+
+  TCollection_AsciiString anOldDescr = aFunction->GetDescription();
+  anOldDescr = anOldDescr + aDescr;
+  aFunction->SetDescription(anOldDescr);
+
+  SetErrorCode(OK);
+  return aSeq;
+}
+
+//=============================================================================
+/*!
+ *  GetSharedShapes
+ */
+//=============================================================================
+Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::GetSharedShapes
+                                                (Handle(GEOM_Object)    theShape1,
+                                                 Handle(GEOM_Object)    theShape2,
+                                                 const Standard_Integer theShapeType)
+{
+  SetErrorCode(KO);
+
+  if (theShape1.IsNull() || theShape2.IsNull()) return NULL;
+
+  TopoDS_Shape aShape1 = theShape1->GetValue();
+  TopoDS_Shape aShape2 = theShape2->GetValue();
+
+  if (aShape1.IsNull() || aShape2.IsNull()) return NULL;
+
+  TopTools_IndexedMapOfShape anIndices;
+  TopExp::MapShapes(aShape1, anIndices);
+  Handle(TColStd_HArray1OfInteger) anArray;
+
+  TopTools_IndexedMapOfShape mapShape1;
+  TopExp::MapShapes(aShape1, TopAbs_ShapeEnum(theShapeType), mapShape1);
+
+  Handle(GEOM_Object) anObj;
+  Handle(TColStd_HSequenceOfTransient) aSeq = new TColStd_HSequenceOfTransient;
+
+  TopTools_MapOfShape mapShape2;
+  TopExp_Explorer exp (aShape2, TopAbs_ShapeEnum(theShapeType));
+  for (; exp.More(); exp.Next()) {
+    TopoDS_Shape aSS = exp.Current();
+    if (mapShape2.Add(aSS) && mapShape1.Contains(aSS)) {
+      anArray = new TColStd_HArray1OfInteger(1,1);
+      anArray->SetValue(1, anIndices.FindIndex(aSS));
+      anObj = GetEngine()->AddSubShape(theShape1, anArray);
+      aSeq->Append(anObj);
+    }
+  }
+
+  if (aSeq->IsEmpty()) {
+    SetErrorCode("The given shapes have no shared sub-shapes of the requested type");
+    return aSeq;
+  }
+
+  //The explode doesn't change object so no new function is required.
+  Handle(GEOM_Function) aFunction = theShape1->GetLastFunction();
+
+  //Make a Python command
+  TCollection_AsciiString aDescr
+    ("\n\tlistSharedShapes = geompy.GetSharedShapes(");
+  TCollection_AsciiString anEntry;
+  TDF_Tool::Entry(theShape1->GetEntry(), anEntry);
+  aDescr += (anEntry + ",");
+  TDF_Tool::Entry(theShape2->GetEntry(), anEntry);
+  aDescr += (anEntry + ",");
+  aDescr += TCollection_AsciiString(theShapeType) + ")";
+
+  TCollection_AsciiString anOldDescr = aFunction->GetDescription();
+  anOldDescr = anOldDescr + aDescr;
+  aFunction->SetDescription(anOldDescr);
+
+  SetErrorCode(OK);
+  return aSeq;
+}
+
+//=============================================================================
+/*!
+ *  GetShapesOnPlane
+ */
+//=============================================================================
+Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::GetShapesOnPlane
+                                        (const Handle(GEOM_Object)& theShape,
+                                         const Standard_Integer     theShapeType,
+                                         const Handle(GEOM_Object)& theAx1,
+                                         const GEOMAlgo_State       theState)
+{
+  SetErrorCode(KO);
+
+  if (theShape.IsNull() || theAx1.IsNull()) return NULL;
+
+  TopoDS_Shape aShape = theShape->GetValue();
+  TopoDS_Shape anAx1  = theAx1->GetValue();
+
+  if (aShape.IsNull() || anAx1.IsNull()) return NULL;
+
+  TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
+  if (aShapeType != TopAbs_VERTEX &&
+      aShapeType != TopAbs_EDGE &&
+      aShapeType != TopAbs_FACE &&
+      aShapeType != TopAbs_SOLID) {
+    SetErrorCode("Only solids, vertices, edges or faces can be found by this method");
+    return NULL;
+  }
+
+  // Create plane
+  if (anAx1.ShapeType() != TopAbs_EDGE) return NULL;
+  TopoDS_Edge anEdge = TopoDS::Edge(anAx1);
+  TopoDS_Vertex V1, V2;
+  TopExp::Vertices(anEdge, V1, V2, Standard_True);
+  if (V1.IsNull() || V2.IsNull()) {
+    SetErrorCode("Bad edge given for the plane normal vector");
+    return NULL;
+  }
+  gp_Pnt aLoc = BRep_Tool::Pnt(V1);
+  gp_Vec aVec (aLoc, BRep_Tool::Pnt(V2));
+  if (aVec.Magnitude() < Precision::Confusion()) {
+    SetErrorCode("Vector with null magnitude given");
+    return NULL;
+  }
+
+  Handle(Geom_Plane) aPlane = new Geom_Plane(aLoc, aVec);
+
+  // Call algo
+  GEOMAlgo_FinderShapeOn aFinder;
+  Standard_Real aTol = 0.0001; // default value
+
+  aFinder.SetShape(aShape);
+  aFinder.SetTolerance(aTol);
+  aFinder.SetSurface(aPlane);
+  aFinder.SetShapeType(aShapeType);
+  aFinder.SetState(theState);
+
+  aFinder.Perform();
+
+  // Interprete results
+  Standard_Integer iErr = aFinder.ErrorStatus();
+  // the detailed description of error codes is in GEOMAlgo_FinderShapeOn.cxx
+  if (iErr) {
+    MESSAGE(" iErr : " << iErr);
+    TCollection_AsciiString aMsg (" iErr : ");
+    aMsg += TCollection_AsciiString(iErr);
+    SetErrorCode(aMsg);
+    return NULL;
+  }
+  Standard_Integer iWrn = aFinder.WarningStatus();
+  // the detailed description of warning codes is in GEOMAlgo_FinderShapeOn.cxx
+  if (iWrn) {
+    MESSAGE(" *** iWrn : " << iWrn);
+  }
+
+  const TopTools_ListOfShape& listSS = aFinder.Shapes(); // the result
+
+  if (listSS.Extent() < 1) {
+    SetErrorCode("Not a single sub-shape of the requested type found on the given plane");
+    return NULL;
+  }
+
+  // Fill sequence of objects
+  TopTools_IndexedMapOfShape anIndices;
+  TopExp::MapShapes(aShape, anIndices);
+
+  Handle(GEOM_Object) anObj;
+  Handle(TColStd_HArray1OfInteger) anArray;
+  Handle(TColStd_HSequenceOfTransient) aSeq = new TColStd_HSequenceOfTransient;
+
+  TopTools_ListIteratorOfListOfShape itSub (listSS);
+  for (int index = 1; itSub.More(); itSub.Next(), ++index) {
+    int id = anIndices.FindIndex(itSub.Value());
+    anArray = new TColStd_HArray1OfInteger(1,1);
+    anArray->SetValue(1, id);
+    anObj = GetEngine()->AddSubShape(theShape, anArray);
+    aSeq->Append(anObj);
+  }
+  
+  // The GetShapesOnPlane() doesn't change object so no new function is required.
+  Handle(GEOM_Function) aFunction = theShape->GetLastFunction();
+
+  // Make a Python command
+  TCollection_AsciiString anEntry, aDescr
+    ("\n\tlistShapesOnPlane = geompy.GetShapesOnPlane(");
+  TDF_Tool::Entry(theShape->GetEntry(), anEntry);
+  aDescr += anEntry + TCollection_AsciiString(theShapeType) + ",";
+  TDF_Tool::Entry(theAx1->GetEntry(), anEntry);
+  aDescr += anEntry + ",";
+  aDescr += TCollection_AsciiString(theState) + ")";
+
+  TCollection_AsciiString anOldDescr = aFunction->GetDescription();
+  anOldDescr += aDescr;
+  aFunction->SetDescription(anOldDescr);
+
+  SetErrorCode(OK);
+  return aSeq;
+}
+
+//=============================================================================
+/*!
+ *  GetShapesOnCylinder
+ */
+//=============================================================================
+Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::GetShapesOnCylinder
+                                          (const Handle(GEOM_Object)& theShape,
+                                           const Standard_Integer     theShapeType,
+                                           const Handle(GEOM_Object)& theAxis,
+                                           const Standard_Real        theRadius,
+                                           const GEOMAlgo_State       theState)
+{
+  SetErrorCode(KO);
+
+  if (theShape.IsNull() || theAxis.IsNull()) return NULL;
+
+  TopoDS_Shape aShape = theShape->GetValue();
+  TopoDS_Shape anAxis = theAxis->GetValue();
+
+  if (aShape.IsNull() || anAxis.IsNull()) return NULL;
+
+  TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
+  if (aShapeType != TopAbs_VERTEX &&
+      aShapeType != TopAbs_EDGE &&
+      aShapeType != TopAbs_FACE &&
+      aShapeType != TopAbs_SOLID) {
+    SetErrorCode("Only solids, vertices, edges or faces can be found by this method");
+    return NULL;
+  }
+
+  //Axis of the cylinder
+  if (anAxis.ShapeType() != TopAbs_EDGE) {
+    SetErrorCode("Not an edge given for the axis");
+    return NULL;
+  }
+  TopoDS_Edge anEdge = TopoDS::Edge(anAxis);
+  TopoDS_Vertex V1, V2;
+  TopExp::Vertices(anEdge, V1, V2, Standard_True);
+  if (V1.IsNull() || V2.IsNull()) {
+    SetErrorCode("Bad edge given for the axis");
+    return NULL;
+  }
+  gp_Pnt aLoc = BRep_Tool::Pnt(V1);
+  gp_Vec aVec (aLoc, BRep_Tool::Pnt(V2));
+  if (aVec.Magnitude() < Precision::Confusion()) {
+    SetErrorCode("Vector with null magnitude given");
+    return NULL;
+  }
+
+  gp_Ax3 anAx3 (aLoc, aVec);
+  Handle(Geom_CylindricalSurface) aCylinder =
+    new Geom_CylindricalSurface(anAx3, theRadius);
+
+  // Call algo
+  GEOMAlgo_FinderShapeOn aFinder;
+  Standard_Real aTol = 0.0001; // default value
+
+  aFinder.SetShape(aShape);
+  aFinder.SetTolerance(aTol);
+  aFinder.SetSurface(aCylinder);
+  aFinder.SetShapeType(aShapeType);
+  aFinder.SetState(theState);
+
+  aFinder.Perform();
+
+  // Interprete results
+  Standard_Integer iErr = aFinder.ErrorStatus();
+  // the detailed description of error codes is in GEOMAlgo_FinderShapeOn.cxx
+  if (iErr) {
+    MESSAGE(" iErr : " << iErr);
+    TCollection_AsciiString aMsg (" iErr : ");
+    aMsg += TCollection_AsciiString(iErr);
+    SetErrorCode(aMsg);
+    return NULL;
+  }
+  Standard_Integer iWrn = aFinder.WarningStatus();
+  // the detailed description of warning codes is in GEOMAlgo_FinderShapeOn.cxx
+  if (iWrn) {
+    MESSAGE(" *** iWrn : " << iWrn);
+  }
+
+  const TopTools_ListOfShape& listSS = aFinder.Shapes(); // the result
+
+  if (listSS.Extent() < 1) {
+    SetErrorCode("Not a single sub-shape of the requested type found on the given cylinder");
+    return NULL;
+  }
+
+  // Fill sequence of objects
+  TopTools_IndexedMapOfShape anIndices;
+  TopExp::MapShapes(aShape, anIndices);
+
+  Handle(GEOM_Object) anObj;
+  Handle(TColStd_HArray1OfInteger) anArray;
+  Handle(TColStd_HSequenceOfTransient) aSeq = new TColStd_HSequenceOfTransient;
+
+  TopTools_ListIteratorOfListOfShape itSub (listSS);
+  for (int index = 1; itSub.More(); itSub.Next(), ++index) {
+    int id = anIndices.FindIndex(itSub.Value());
+    anArray = new TColStd_HArray1OfInteger(1,1);
+    anArray->SetValue(1, id);
+    anObj = GetEngine()->AddSubShape(theShape, anArray);
+    aSeq->Append(anObj);
+  }
+  
+  // The GetShapesOnCylinder() doesn't change object so no new function is required.
+  Handle(GEOM_Function) aFunction = theShape->GetLastFunction();
+
+  // Make a Python command
+  TCollection_AsciiString anEntry, aDescr
+    ("\n\tlistShapesOnCylinder = geompy.GetShapesOnCylinder(");
+  TDF_Tool::Entry(theShape->GetEntry(), anEntry);
+  aDescr += anEntry + TCollection_AsciiString(theShapeType) + ",";
+  TDF_Tool::Entry(theAxis->GetEntry(), anEntry);
+  aDescr += anEntry + ",";
+  aDescr += TCollection_AsciiString(theRadius) + ",";
+  aDescr += TCollection_AsciiString(theState) + ")";
+
+  TCollection_AsciiString anOldDescr = aFunction->GetDescription();
+  anOldDescr += aDescr;
+  aFunction->SetDescription(anOldDescr);
+
+  SetErrorCode(OK);
+  return aSeq;
+}
+
+//=============================================================================
+/*!
+ *  GetShapesOnSphere
+ */
+//=============================================================================
+Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::GetShapesOnSphere
+                                          (const Handle(GEOM_Object)& theShape,
+                                           const Standard_Integer     theShapeType,
+                                           const Handle(GEOM_Object)& theCenter,
+                                           const Standard_Real        theRadius,
+                                           const GEOMAlgo_State       theState)
+{
+  SetErrorCode(KO);
+
+  if (theShape.IsNull() || theCenter.IsNull()) return NULL;
+
+  TopoDS_Shape aShape  = theShape->GetValue();
+  TopoDS_Shape aCenter = theCenter->GetValue();
+
+  if (aShape.IsNull() || aCenter.IsNull()) return NULL;
+
+  TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
+  if (aShapeType != TopAbs_VERTEX &&
+      aShapeType != TopAbs_EDGE &&
+      aShapeType != TopAbs_FACE &&
+      aShapeType != TopAbs_SOLID) {
+    SetErrorCode("Only solids, vertices, edges or faces can be found by this method");
+    return NULL;
+  }
+
+  // Center of the sphere
+  if (aCenter.ShapeType() != TopAbs_VERTEX) return NULL;
+  gp_Pnt aLoc = BRep_Tool::Pnt(TopoDS::Vertex(aCenter));
+
+  gp_Ax3 anAx3 (aLoc, gp::DZ());
+  Handle(Geom_SphericalSurface) aSphere =
+    new Geom_SphericalSurface(anAx3, theRadius);
+
+  // Call algo
+  GEOMAlgo_FinderShapeOn aFinder;
+  Standard_Real aTol = 0.0001; // default value
+
+  aFinder.SetShape(aShape);
+  aFinder.SetTolerance(aTol);
+  aFinder.SetSurface(aSphere);
+  aFinder.SetShapeType(aShapeType);
+  aFinder.SetState(theState);
+
+  aFinder.Perform();
+
+  // Interprete results
+  Standard_Integer iErr = aFinder.ErrorStatus();
+  // the detailed description of error codes is in GEOMAlgo_FinderShapeOn.cxx
+  if (iErr) {
+    MESSAGE(" iErr : " << iErr);
+    TCollection_AsciiString aMsg (" iErr : ");
+    aMsg += TCollection_AsciiString(iErr);
+    SetErrorCode(aMsg);
+    return NULL;
+  }
+  Standard_Integer iWrn = aFinder.WarningStatus();
+  // the detailed description of warning codes is in GEOMAlgo_FinderShapeOn.cxx
+  if (iWrn) {
+    MESSAGE(" *** iWrn : " << iWrn);
+  }
+
+  const TopTools_ListOfShape& listSS = aFinder.Shapes(); // the result
+
+  if (listSS.Extent() < 1) {
+    SetErrorCode("Not a single sub-shape of the requested type found on the given sphere");
+    return NULL;
+  }
+
+  // Fill sequence of objects
+  TopTools_IndexedMapOfShape anIndices;
+  TopExp::MapShapes(aShape, anIndices);
+
+  Handle(GEOM_Object) anObj;
+  Handle(TColStd_HArray1OfInteger) anArray;
+  Handle(TColStd_HSequenceOfTransient) aSeq = new TColStd_HSequenceOfTransient;
+
+  TopTools_ListIteratorOfListOfShape itSub (listSS);
+  for (int index = 1; itSub.More(); itSub.Next(), ++index) {
+    int id = anIndices.FindIndex(itSub.Value());
+    anArray = new TColStd_HArray1OfInteger(1,1);
+    anArray->SetValue(1, id);
+    anObj = GetEngine()->AddSubShape(theShape, anArray);
+    aSeq->Append(anObj);
+  }
+  
+  // The GetShapesOnSphere() doesn't change object so no new function is required.
+  Handle(GEOM_Function) aFunction = theShape->GetLastFunction();
+
+  // Make a Python command
+  TCollection_AsciiString anEntry, aDescr
+    ("\n\tlistShapesOnSphere = geompy.GetShapesOnSphere(");
+  TDF_Tool::Entry(theShape->GetEntry(), anEntry);
+  aDescr += anEntry + TCollection_AsciiString(theShapeType) + ",";
+  TDF_Tool::Entry(theCenter->GetEntry(), anEntry);
+  aDescr += anEntry + ",";
+  aDescr += TCollection_AsciiString(theRadius) + ",";
+  aDescr += TCollection_AsciiString(theState) + ")";
+
+  TCollection_AsciiString anOldDescr = aFunction->GetDescription();
+  anOldDescr += aDescr;
+  aFunction->SetDescription(anOldDescr);
+
+  SetErrorCode(OK);
+  return aSeq;
+}
+
+//=============================================================================
+/*!
+ *  GetInPlace
+ */
+//=============================================================================
+Handle(GEOM_Object) GEOMImpl_IShapesOperations::GetInPlace
+                                          (Handle(GEOM_Object) theShapeWhere,
+                                           Handle(GEOM_Object) theShapeWhat)
+{
+  SetErrorCode(KO);
+
+  if (theShapeWhere.IsNull() || theShapeWhat.IsNull()) return NULL;
+
+  TopoDS_Shape aWhere = theShapeWhere->GetValue();
+  TopoDS_Shape aWhat  = theShapeWhat->GetValue();
+
+  if (aWhere.IsNull() || aWhat.IsNull()) return NULL;
+
+  //Fill array of indices
+  Handle(TColStd_HArray1OfInteger) aModifiedArray;
+
+  Handle(GEOM_Function) aWhereFunction = theShapeWhere->GetLastFunction();
+
+  TopTools_IndexedMapOfShape aWhereIndices;
+  TopExp::MapShapes(aWhere, aWhereIndices);
+
+  if (aWhereIndices.Contains(aWhat)) {
+
+    // entity was not changed by the operation
+    Standard_Integer aWhatIndex = aWhereIndices.FindIndex(aWhat);
+    aModifiedArray = new TColStd_HArray1OfInteger(1,1);
+    aModifiedArray->SetValue(1, aWhatIndex);
+
+  } else {
+
+    TDF_Label aHistoryLabel = aWhereFunction->GetHistoryEntry(Standard_False);
+    if (aHistoryLabel.IsNull()) {
+      SetErrorCode("Modifications history does not exist for the shape under consideration.");
+      return NULL;
+    }
+
+    // search in history for all argument shapes
+    Standard_Boolean isFound = Standard_False;
+
+    TDF_LabelSequence aLabelSeq;
+    aWhereFunction->GetDependency(aLabelSeq);
+    Standard_Integer nbArg = aLabelSeq.Length();
+
+    for (Standard_Integer iarg = 1; iarg <= nbArg && !isFound; iarg++) {
+
+      TDF_Label anArgumentRefLabel = aLabelSeq.Value(iarg);
+
+      Handle(GEOM_Object) anArgumentObject = GEOM_Object::GetReferencedObject(anArgumentRefLabel);
+      TopoDS_Shape anArgumentShape = anArgumentObject->GetValue();
+
+      TopTools_IndexedMapOfShape anArgumentIndices;
+      TopExp::MapShapes(anArgumentShape, anArgumentIndices);
+
+      if (anArgumentIndices.Contains(aWhat)) {
+        isFound = Standard_True;
+        Standard_Integer aWhatIndex = anArgumentIndices.FindIndex(aWhat);
+
+        // Find corresponding label in history
+        TDF_Label anArgumentHistoryLabel =
+          aWhereFunction->GetArgumentHistoryEntry(anArgumentRefLabel, Standard_False);
+        if (anArgumentHistoryLabel.IsNull()) {
+          // Lost History of operation argument. Possibly, all its entities was removed.
+          SetErrorCode(OK);
+          return NULL;
+        }
+
+        TDF_Label aWhatHistoryLabel = anArgumentHistoryLabel.FindChild(aWhatIndex, Standard_False);
+        if (aWhatHistoryLabel.IsNull()) {
+          // Removed entity
+          SetErrorCode(OK);
+          return NULL;
+        }
+
+        Handle(TDataStd_IntegerArray) anIntegerArray;
+        if (!aWhatHistoryLabel.FindAttribute(TDataStd_IntegerArray::GetID(), anIntegerArray)) {
+          SetErrorCode("Error: Empty modifications history for the sought shape.");
+          return NULL;
+        }
+
+        aModifiedArray = anIntegerArray->Array();
+        if (aModifiedArray->Length() == 0) {
+          SetErrorCode("Error: Empty modifications history for the sought shape.");
+          return NULL;
+        }
+      }
+    }
+
+    if (!isFound) {
+      SetErrorCode("The sought shape does not belong to any operation argument.");
+      return NULL;
+    }
+  }
+
+  //Add a new object
+  Handle(GEOM_Object) aResult = GetEngine()->AddSubShape(theShapeWhere, aModifiedArray);
+
+  if (aModifiedArray->Length() > 1) {
+    //Set a GROUP type
+    aResult->SetType(GEOM_GROUP);
+
+    //Set a sub shape type
+    TDF_Label aFreeLabel = aResult->GetFreeLabel();
+    TopAbs_ShapeEnum aShapeType = aWhat.ShapeType();
+    TDataStd_Integer::Set(aFreeLabel, (Standard_Integer)aShapeType);
+  }
+
+  //Make a Python command
+  TCollection_AsciiString anEntry, aDescr;
+  TDF_Tool::Entry(aResult->GetEntry(), anEntry);
+  aDescr += anEntry;
+  aDescr += " = geompy.GetInPlace(";
+  TDF_Tool::Entry(theShapeWhere->GetEntry(), anEntry);
+  aDescr += anEntry + ",";
+  TDF_Tool::Entry(theShapeWhat->GetEntry(), anEntry);
+  aDescr += anEntry + ")";
+
+  Handle(GEOM_Function) aFunction = aResult->GetFunction(1);
+  aFunction->SetDescription(aDescr);
+
+  SetErrorCode(OK);
+  return aResult;
+}
 
 //=======================================================================
 //function : SortShapes