Salome HOME
if a shape to be rotated is a vertex, and it is located ON the Revolution Axis, then...
[modules/geom.git] / src / GEOMImpl / GEOMImpl_IShapesOperations.cxx
index 6db0d877682c98834e49c54f6896bec4c76e6d35..2d187465db7a936fd326793f2ef7b5e0b4da51e4 100644 (file)
@@ -16,8 +16,9 @@ using namespace std;
 #include "GEOMImpl_Block6Explorer.hxx"
 
 #include "GEOM_Function.hxx"
+#include "GEOM_PythonDump.hxx"
 
-#include "GEOMAlgo_FinderShapeOn.hxx"
+#include "GEOMAlgo_FinderShapeOn1.hxx"
 
 #include "utilities.h"
 #include "OpUtil.hxx"
@@ -27,6 +28,7 @@ using namespace std;
 #include <TFunction_Driver.hxx>
 #include <TFunction_Logbook.hxx>
 #include <TDataStd_Integer.hxx>
+#include <TDataStd_IntegerArray.hxx>
 #include <TDF_Tool.hxx>
 
 #include <BRepExtrema_ExtCF.hxx>
@@ -34,7 +36,9 @@ using namespace std;
 #include <BRep_Tool.hxx>
 #include <BRepGProp.hxx>
 #include <BRepAdaptor_Curve.hxx>
+#include <BRepBndLib.hxx>
 #include <BRepBuilderAPI_MakeFace.hxx>
+#include <BRepMesh_IncrementalMesh.hxx>
 
 #include <TopAbs.hxx>
 #include <TopExp.hxx>
@@ -59,11 +63,14 @@ using namespace std;
 
 #include <Geom2d_Curve.hxx>
 
+#include <Bnd_Box.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>
 
@@ -136,15 +143,8 @@ Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeEdge
   }
 
   //Make a Python command
-  TCollection_AsciiString anEntry, aDescr;
-  TDF_Tool::Entry(anEdge->GetEntry(), anEntry);
-  aDescr += (anEntry+" = IShapesOperations.MakeEdge(");
-  TDF_Tool::Entry(thePnt1->GetEntry(), anEntry);
-  aDescr += (anEntry+", ");
-  TDF_Tool::Entry(thePnt2->GetEntry(), anEntry);
-  aDescr += (anEntry+")");
-
-  aFunction->SetDescription(aDescr);
+  GEOM::TPythonDump(aFunction) << anEdge << " = geompy.MakeEdge("
+                               << thePnt1 << ", " << thePnt2 << ")";
 
   SetErrorCode(OK);
   return anEdge;
@@ -207,19 +207,8 @@ Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeFace (Handle(GEOM_Object) th
   }
 
   //Make a Python command
-  TCollection_AsciiString anEntry, aDescr;
-  TDF_Tool::Entry(aFace->GetEntry(), anEntry);
-  aDescr += anEntry;
-  aDescr += " = IShapesOperations.MakeFace(";
-  TDF_Tool::Entry(theWire->GetEntry(), anEntry);
-  aDescr += anEntry;
-  if (isPlanarWanted)
-    aDescr += ", 1)";
-
-  else
-    aDescr += ", 0)";
-
-  aFunction->SetDescription(aDescr);
+  GEOM::TPythonDump(aFunction) << aFace << " = geompy.MakeFace("
+    << theWire << ", " << (int)isPlanarWanted << ")";
 
   SetErrorCode(OK);
   return aFace;
@@ -279,28 +268,18 @@ Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeFaceWires
   }
 
   //Make a Python command
-  TCollection_AsciiString anEntry, aDescr;
-  TDF_Tool::Entry(aShape->GetEntry(), anEntry);
-  aDescr += (anEntry + " = IShapesOperations.MakeFaceWires([");
+  GEOM::TPythonDump pd (aFunction);
+  pd << aShape << " = geompy.MakeFaceWires([";
+
   // Shapes
   it = theShapes.begin();
   if (it != theShapes.end()) {
-    TDF_Tool::Entry((*it)->GetEntry(), anEntry);
-    it++;
-    aDescr += (anEntry+", ");
-    for (; it != theShapes.end(); it++) {
-      aDescr += ", ";
-      TDF_Tool::Entry((*it)->GetEntry(), anEntry);
-      aDescr += anEntry;
+    pd << (*it++);
+    while (it != theShapes.end()) {
+      pd << ", " << (*it++);
     }
   }
-  if (isPlanarWanted)
-    aDescr += "], 1)";
-
-  else
-    aDescr += "], 0)";
-
-  aFunction->SetDescription(aDescr);
+  pd << "], " << (int)isPlanarWanted << ")";
 
   SetErrorCode(OK);
   return aShape;
@@ -372,14 +351,8 @@ Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeSolidShell (Handle(GEOM_Obje
   }
 
   //Make a Python command
-  TCollection_AsciiString anEntry, aDescr("");
-  TDF_Tool::Entry(aSolid->GetEntry(), anEntry);
-  aDescr += anEntry;
-  aDescr += " = IShapesOperations.MakeSolidShell(";
-  TDF_Tool::Entry(theShell->GetEntry(), anEntry);
-  aDescr += (anEntry+")");
-
-  aFunction->SetDescription(aDescr);
+  GEOM::TPythonDump(aFunction) << aSolid
+    << " = geompy.MakeSolid(" << theShell << ")";
 
   SetErrorCode(OK);
   return aSolid;
@@ -450,25 +423,18 @@ Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeShape
   }
 
   //Make a Python command
-  TCollection_AsciiString anEntry, aDescr("");
-  TDF_Tool::Entry(aShape->GetEntry(), anEntry);
-  aDescr += (anEntry + " = IShapesOperations.");
-  aDescr += (theMethodName + "([");
+  GEOM::TPythonDump pd (aFunction);
+  pd << aShape << " = geompy." << theMethodName.ToCString() << "([";
+
   // Shapes
   it = theShapes.begin();
   if (it != theShapes.end()) {
-    TDF_Tool::Entry((*it)->GetEntry(), anEntry);
-    it++;
-    aDescr += (anEntry+", ");
-    for (; it != theShapes.end(); it++) {
-      aDescr += ", ";
-      TDF_Tool::Entry((*it)->GetEntry(), anEntry);
-      aDescr += anEntry;
+    pd << (*it++);
+    while (it != theShapes.end()) {
+      pd << ", " << (*it++);
     }
   }
-  aDescr += "])";
-
-  aFunction->SetDescription(aDescr);
+  pd << "])";
 
   SetErrorCode(OK);
   return aShape;
@@ -526,15 +492,8 @@ Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeGlueFaces
   }
 
   //Make a Python command
-  TCollection_AsciiString anEntry, aDescr;
-  TDF_Tool::Entry(aGlued->GetEntry(), anEntry);
-  aDescr += anEntry;
-  aDescr += " = IShapesOperations.MakeGlueFaces(";
-  TDF_Tool::Entry(theShape->GetEntry(), anEntry);
-  aDescr += anEntry + ", ";
-  aDescr += TCollection_AsciiString(theTolerance) + ")";
-
-  aFunction->SetDescription(aDescr);
+  GEOM::TPythonDump(aFunction) << aGlued << " = geompy.MakeGlueFaces("
+    << theShape << ", " << theTolerance << ")";
 
   // to provide warning
   if (!isWarning) SetErrorCode(OK);
@@ -605,7 +564,7 @@ Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::MakeExplode
   Handle(TColStd_HArray1OfInteger) anArray;
 
   TopTools_ListIteratorOfListOfShape itSub (listShape);
-  TCollection_AsciiString anAsciiList = "[", anEntry;
+  TCollection_AsciiString anAsciiList, anEntry;
   for (int index = 1; itSub.More(); itSub.Next(), ++index) {
     TopoDS_Shape aValue = itSub.Value();
     anArray = new TColStd_HArray1OfInteger(1,1);
@@ -613,35 +572,22 @@ Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::MakeExplode
     anObj = GetEngine()->AddSubShape(theShape, anArray);
     aSeq->Append(anObj);
 
+    // for python command
     TDF_Tool::Entry(anObj->GetEntry(), anEntry);
     anAsciiList += anEntry;
     anAsciiList += ",";
   }
 
-//  timer3.Stop();
-//  timer4.Start();
-
+  //Make a Python command
   anAsciiList.Trunc(anAsciiList.Length() - 1);
-  anAsciiList += "]";
-
-  anAsciiList = TCollection_AsciiString("\n") + anAsciiList;
 
-  //The explode doesn't change object so no new function is requiered.
   aFunction = theShape->GetLastFunction();
-
-  //Make a Python command
-  TCollection_AsciiString aDescr(anAsciiList);
-  TDF_Tool::Entry(theShape->GetEntry(), anEntry);
-  aDescr += " = IShapesOperations.MakeExplode(";
-  aDescr += (anEntry + ",");
-  if (isSorted)
-    aDescr += (TCollection_AsciiString(theShapeType) + ", 1)");
-  else
-    aDescr += (TCollection_AsciiString(theShapeType) + ", 0)");
-
   TCollection_AsciiString anOldDescr = aFunction->GetDescription();
-  anOldDescr = anOldDescr + aDescr;
-  aFunction->SetDescription(anOldDescr);
+
+  GEOM::TPythonDump pd (aFunction);
+  pd << anOldDescr.ToCString() << "\n\t[" << anAsciiList.ToCString();
+  pd << "] = geompy.SubShapeAll" << (isSorted ? "Sorted(" : "(");
+  pd << theShape << ", " << theShapeType << ")";
 
   SetErrorCode(OK);
 
@@ -717,23 +663,14 @@ Handle(TColStd_HSequenceOfInteger) GEOMImpl_IShapesOperations::SubShapeAllIDs
     aSeq->Append(anIndices.FindIndex(aValue));
   }
 
-  //The explode doesn't change object so no new function is required.
   Handle(GEOM_Function) aFunction = theShape->GetLastFunction();
+  TCollection_AsciiString anOldDescr = aFunction->GetDescription();
 
   //Make a Python command
-  TCollection_AsciiString aDescr
-    ("\nlistSubShapeAllIDs = IShapesOperations.SubShapeAllIDs(");
-  TCollection_AsciiString anEntry;
-  TDF_Tool::Entry(theShape->GetEntry(), anEntry);
-  aDescr += (anEntry + ",");
-  if (isSorted)
-    aDescr += (TCollection_AsciiString(theShapeType) + ", 1)");
-  else
-    aDescr += (TCollection_AsciiString(theShapeType) + ", 0)");
-
-  TCollection_AsciiString anOldDescr = aFunction->GetDescription();
-  anOldDescr = anOldDescr + aDescr;
-  aFunction->SetDescription(anOldDescr);
+  GEOM::TPythonDump pd (aFunction);
+  pd << anOldDescr.ToCString() << "\n\tlistSubShapeIDs = geompy.SubShapeAll";
+  pd << (isSorted ? "SortedIDs(" : "IDs(");
+  pd << theShape << ", " << theShapeType << ")";
 
   SetErrorCode(OK);
   return aSeq;
@@ -754,27 +691,17 @@ 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;
   }
 
-  //The GetSubShape() doesn't change object so no new function is requiered.
-  Handle(GEOM_Function) aFunction = theMainShape->GetLastFunction();
+  Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
 
   //Make a Python command
-  TCollection_AsciiString aDescr ("\n");
-  TCollection_AsciiString anEntry;
-  TDF_Tool::Entry(anObj->GetEntry(), anEntry);
-  aDescr += anEntry + " = IShapesOperations.GetSubShape(";
-  TDF_Tool::Entry(theMainShape->GetEntry(), anEntry);
-  aDescr += anEntry + ", ";
-  aDescr += TCollection_AsciiString(theID) + ")";
-
-  TCollection_AsciiString anOldDescr = aFunction->GetDescription();
-  anOldDescr = anOldDescr + aDescr;
-  aFunction->SetDescription(anOldDescr);
+  GEOM::TPythonDump(aFunction) << anObj << " = geompy.GetSubShape("
+                               << theMainShape << ", [" << theID << "])";
 
   SetErrorCode(OK);
   return anObj;
@@ -876,14 +803,8 @@ Handle(GEOM_Object) GEOMImpl_IShapesOperations::ReverseShape(Handle(GEOM_Object)
   }
 
   //Make a Python command
-  TCollection_AsciiString anEntry, aDescr;
-  TDF_Tool::Entry(aReversed->GetEntry(), anEntry);
-  aDescr += anEntry;
-  aDescr += " = IShapesOperations.ReverseShape(";
-  TDF_Tool::Entry(theShape->GetEntry(), anEntry);
-  aDescr += anEntry + ")";
-
-  aFunction->SetDescription(aDescr);
+  GEOM::TPythonDump(aFunction) << aReversed
+    << " = geompy.ChangeOrientation(" << theShape << ")";
 
   SetErrorCode(OK);
   return aReversed;
@@ -929,16 +850,11 @@ Handle(TColStd_HSequenceOfInteger) GEOMImpl_IShapesOperations::GetFreeFacesIDs
 
   //The explode doesn't change object so no new function is required.
   Handle(GEOM_Function) aFunction = theShape->GetLastFunction();
+  TCollection_AsciiString anOldDescr = aFunction->GetDescription();
 
   //Make a Python command
-  TCollection_AsciiString aDescr ("\nlistFreeFacesIDs = IShapesOperations.GetFreeFacesIDs(");
-  TCollection_AsciiString anEntry;
-  TDF_Tool::Entry(theShape->GetEntry(), anEntry);
-  aDescr += (anEntry + ")");
-
-  TCollection_AsciiString anOldDescr = aFunction->GetDescription();
-  anOldDescr = anOldDescr + aDescr;
-  aFunction->SetDescription(anOldDescr);
+  GEOM::TPythonDump(aFunction) << anOldDescr.ToCString()
+    << "\n\tlistFreeFacesIDs = geompy.GetFreeFacesIDs(" << theShape << ")";
 
   SetErrorCode(OK);
   return aSeq;
@@ -972,6 +888,7 @@ Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::GetSharedShapes
 
   Handle(GEOM_Object) anObj;
   Handle(TColStd_HSequenceOfTransient) aSeq = new TColStd_HSequenceOfTransient;
+  TCollection_AsciiString anAsciiList, anEntry;
 
   TopTools_MapOfShape mapShape2;
   TopExp_Explorer exp (aShape2, TopAbs_ShapeEnum(theShapeType));
@@ -982,6 +899,11 @@ Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::GetSharedShapes
       anArray->SetValue(1, anIndices.FindIndex(aSS));
       anObj = GetEngine()->AddSubShape(theShape1, anArray);
       aSeq->Append(anObj);
+
+      // for python command
+      TDF_Tool::Entry(anObj->GetEntry(), anEntry);
+      anAsciiList += anEntry;
+      anAsciiList += ",";
     }
   }
 
@@ -990,27 +912,50 @@ Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::GetSharedShapes
     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
-    ("\nlistSharedShapes = IShapesOperations.GetSharedShapes(");
-  TCollection_AsciiString anEntry;
-  TDF_Tool::Entry(theShape1->GetEntry(), anEntry);
-  aDescr += (anEntry + ",");
-  TDF_Tool::Entry(theShape2->GetEntry(), anEntry);
-  aDescr += (anEntry + ",");
-  aDescr += TCollection_AsciiString(theShapeType) + ")";
+  anAsciiList.Trunc(anAsciiList.Length() - 1);
 
-  TCollection_AsciiString anOldDescr = aFunction->GetDescription();
-  anOldDescr = anOldDescr + aDescr;
-  aFunction->SetDescription(anOldDescr);
+  Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
+
+  GEOM::TPythonDump(aFunction) << "[" << anAsciiList.ToCString()
+    << "] = geompy.GetSharedShapes(" << theShape1 << ", "
+      << theShape2 << ", " << theShapeType << ")";
 
   SetErrorCode(OK);
   return aSeq;
 }
 
+//=============================================================================
+/*!
+ *  
+ */
+//=============================================================================
+static GEOM::TPythonDump& operator<< (GEOM::TPythonDump&   theDump,
+                                      const GEOMAlgo_State theState)
+{
+  switch (theState) {
+  case GEOMAlgo_ST_IN:
+    theDump << "geompy.GEOM.ST_IN";
+    break;
+  case GEOMAlgo_ST_OUT:
+    theDump << "geompy.GEOM.ST_OUT";
+    break;
+  case GEOMAlgo_ST_ON:
+    theDump << "geompy.GEOM.ST_ON";
+    break;
+  case GEOMAlgo_ST_ONIN:
+    theDump << "geompy.GEOM.ST_ONIN";
+    break;
+  case GEOMAlgo_ST_ONOUT:
+    theDump << "geompy.GEOM.ST_ONOUT";
+    break;
+  default:
+    theDump << "geompy.GEOM.ST_UNKNOWN";
+    break;
+  }
+  return theDump;
+}
+
 //=============================================================================
 /*!
  *  GetShapesOnPlane
@@ -1024,6 +969,10 @@ Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::GetShapesOnPlan
 {
   SetErrorCode(KO);
 
+//  MESSAGE("--------------------------- GetShapesOnPlane phase 1 takes:");
+//  OSD_Timer timer1;
+//  timer1.Start();
+
   if (theShape.IsNull() || theAx1.IsNull()) return NULL;
 
   TopoDS_Shape aShape = theShape->GetValue();
@@ -1034,8 +983,9 @@ Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::GetShapesOnPlan
   TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
   if (aShapeType != TopAbs_VERTEX &&
       aShapeType != TopAbs_EDGE &&
-      aShapeType != TopAbs_FACE) {
-    SetErrorCode("Only vertices, edges or faces can be found by this method");
+      aShapeType != TopAbs_FACE &&
+      aShapeType != TopAbs_SOLID) {
+    SetErrorCode("Only solids, vertices, edges or faces can be found by this method");
     return NULL;
   }
 
@@ -1057,8 +1007,12 @@ Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::GetShapesOnPlan
 
   Handle(Geom_Plane) aPlane = new Geom_Plane(aLoc, aVec);
 
+  // Check presence of triangulation, build if need
+  if (!CheckTriangulation(aShape))
+    return NULL;
+
   // Call algo
-  GEOMAlgo_FinderShapeOn aFinder;
+  GEOMAlgo_FinderShapeOn1 aFinder;
   Standard_Real aTol = 0.0001; // default value
 
   aFinder.SetShape(aShape);
@@ -1067,11 +1021,33 @@ Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::GetShapesOnPlan
   aFinder.SetShapeType(aShapeType);
   aFinder.SetState(theState);
 
+  // Sets the minimal number of inner points for the faces that do not have own
+  // inner points at all (for e.g. rectangular planar faces have just 2 triangles).
+  // Default value=3
+  aFinder.SetNbPntsMin(3);
+  // Sets the maximal number of inner points for edges or faces.
+  // It is usefull for the cases when this number is very big (e.g =2000) to improve
+  // the performance. If this value =0, all inner points will be taken into account.
+  // Default value=0
+  aFinder.SetNbPntsMax(100);
+
+//  timer1.Stop();
+//  timer1.Show();
+
+//  MESSAGE("--------------------------- Perform on Plane takes:");
+//  timer1.Reset();
+//  timer1.Start();
   aFinder.Perform();
+//  timer1.Stop();
+//  timer1.Show();
+
+//  MESSAGE("--------------------------- GetShapesOnPlane phase 3 takes:");
+//  timer1.Reset();
+//  timer1.Start();
 
   // Interprete results
   Standard_Integer iErr = aFinder.ErrorStatus();
-  // the detailed description of error codes is in GEOMAlgo_FinderShapeOn.cxx
+  // the detailed description of error codes is in GEOMAlgo_FinderShapeOn1.cxx
   if (iErr) {
     MESSAGE(" iErr : " << iErr);
     TCollection_AsciiString aMsg (" iErr : ");
@@ -1080,7 +1056,7 @@ Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::GetShapesOnPlan
     return NULL;
   }
   Standard_Integer iWrn = aFinder.WarningStatus();
-  // the detailed description of warning codes is in GEOMAlgo_FinderShapeOn.cxx
+  // the detailed description of warning codes is in GEOMAlgo_FinderShapeOn1.cxx
   if (iWrn) {
     MESSAGE(" *** iWrn : " << iWrn);
   }
@@ -1092,6 +1068,267 @@ Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::GetShapesOnPlan
     return NULL;
   }
 
+//  timer1.Stop();
+//  timer1.Show();
+
+//  MESSAGE("--------------------------- GetShapesOnPlane phase 4 takes:");
+//  timer1.Reset();
+//  timer1.Start();
+
+  // 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;
+  TCollection_AsciiString anAsciiList, anEntry;
+
+  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);
+
+    // for python command
+    TDF_Tool::Entry(anObj->GetEntry(), anEntry);
+    anAsciiList += anEntry;
+    anAsciiList += ",";
+  }
+
+//  timer1.Stop();
+//  timer1.Show();
+
+//  MESSAGE("--------------------------- GetShapesOnPlane phase 5 takes:");
+//  timer1.Reset();
+//  timer1.Start();
+  
+  // Make a Python command
+  anAsciiList.Trunc(anAsciiList.Length() - 1);
+
+  Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
+
+  GEOM::TPythonDump(aFunction) << "[" << anAsciiList.ToCString()
+    << "] = geompy.GetShapesOnPlane(" << theShape << ", "
+      << theShapeType << ", " << theAx1 << ", " << theState << ")";
+
+  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);
+
+  // Check presence of triangulation, build if need
+  if (!CheckTriangulation(aShape))
+    return NULL;
+
+  // Call algo
+  GEOMAlgo_FinderShapeOn1 aFinder;
+  Standard_Real aTol = 0.0001; // default value
+
+  aFinder.SetShape(aShape);
+  aFinder.SetTolerance(aTol);
+  aFinder.SetSurface(aCylinder);
+  aFinder.SetShapeType(aShapeType);
+  aFinder.SetState(theState);
+
+  aFinder.SetNbPntsMin(3);
+  aFinder.SetNbPntsMax(100);
+
+  aFinder.Perform();
+
+  // Interprete results
+  Standard_Integer iErr = aFinder.ErrorStatus();
+  // the detailed description of error codes is in GEOMAlgo_FinderShapeOn1.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_FinderShapeOn1.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;
+  TCollection_AsciiString anAsciiList, anEntry;
+
+  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);
+
+    // for python command
+    TDF_Tool::Entry(anObj->GetEntry(), anEntry);
+    anAsciiList += anEntry;
+    anAsciiList += ",";
+  }
+  
+  // Make a Python command
+  anAsciiList.Trunc(anAsciiList.Length() - 1);
+
+  Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
+
+  GEOM::TPythonDump(aFunction) << "[" << anAsciiList.ToCString()
+    << "] = geompy.GetShapesOnCylinder(" << theShape << ", " << theShapeType
+      << ", " << theAxis << ", " << theRadius << ", " << theState << ")";
+
+  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);
+
+  // Check presence of triangulation, build if need
+  if (!CheckTriangulation(aShape))
+    return NULL;
+
+  // Call algo
+  GEOMAlgo_FinderShapeOn1 aFinder;
+  Standard_Real aTol = 0.0001; // default value
+
+  aFinder.SetShape(aShape);
+  aFinder.SetTolerance(aTol);
+  aFinder.SetSurface(aSphere);
+  aFinder.SetShapeType(aShapeType);
+  aFinder.SetState(theState);
+
+  aFinder.SetNbPntsMin(3);
+  aFinder.SetNbPntsMax(100);
+
+  aFinder.Perform();
+
+  // Interprete results
+  Standard_Integer iErr = aFinder.ErrorStatus();
+  // the detailed description of error codes is in GEOMAlgo_FinderShapeOn1.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_FinderShapeOn1.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);
@@ -1099,6 +1336,7 @@ Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::GetShapesOnPlan
   Handle(GEOM_Object) anObj;
   Handle(TColStd_HArray1OfInteger) anArray;
   Handle(TColStd_HSequenceOfTransient) aSeq = new TColStd_HSequenceOfTransient;
+  TCollection_AsciiString anAsciiList, anEntry;
 
   TopTools_ListIteratorOfListOfShape itSub (listSS);
   for (int index = 1; itSub.More(); itSub.Next(), ++index) {
@@ -1107,14 +1345,132 @@ Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::GetShapesOnPlan
     anArray->SetValue(1, id);
     anObj = GetEngine()->AddSubShape(theShape, anArray);
     aSeq->Append(anObj);
+
+    // for python command
+    TDF_Tool::Entry(anObj->GetEntry(), anEntry);
+    anAsciiList += anEntry;
+    anAsciiList += ",";
   }
   
+  // Make a Python command
+  anAsciiList.Trunc(anAsciiList.Length() - 1);
+
+  Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
+
+  GEOM::TPythonDump(aFunction) << "[" << anAsciiList.ToCString()
+    << "] = geompy.GetShapesOnSphere(" << theShape << ", " << theShapeType
+      << ", " << theCenter << ", " << theRadius << ", " << theState << ")";
+
+  SetErrorCode(OK);
+  return aSeq;
+}
+//=============================================================================
+/*!
+ *  GetShapesOnPlaneIDs
+ */
+//=============================================================================
+Handle(TColStd_HSequenceOfInteger) GEOMImpl_IShapesOperations::GetShapesOnPlaneIDs
+                                        (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);
+
+  // Check presence of triangulation, build if need
+  if (!CheckTriangulation(aShape))
+    return NULL;
+
+  // Call algo
+  GEOMAlgo_FinderShapeOn1 aFinder;
+  Standard_Real aTol = 0.0001; // default value
+
+  aFinder.SetShape(aShape);
+  aFinder.SetTolerance(aTol);
+  aFinder.SetSurface(aPlane);
+  aFinder.SetShapeType(aShapeType);
+  aFinder.SetState(theState);
+
+  aFinder.SetNbPntsMin(3);
+  aFinder.SetNbPntsMax(100);
+
+  aFinder.Perform();
+
+  // Interprete results
+  Standard_Integer iErr = aFinder.ErrorStatus();
+  // the detailed description of error codes is in GEOMAlgo_FinderShapeOn1.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_FinderShapeOn1.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(TColStd_HSequenceOfInteger) aSeq = new TColStd_HSequenceOfInteger;
+
+  TopTools_ListIteratorOfListOfShape itSub (listSS);
+  for (int index = 1; itSub.More(); itSub.Next(), ++index) {
+    int id = anIndices.FindIndex(itSub.Value());
+    aSeq->Append(id);
+  }
+
   // 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
-    ("\nlistShapesOnPlane = IShapesOperations.GetShapesOnPlane(");
+    ("\nlistShapesOnPlane = IShapesOperations.GetShapesOnPlaneIDs(");
   TDF_Tool::Entry(theShape->GetEntry(), anEntry);
   aDescr += anEntry + TCollection_AsciiString(theShapeType) + ",";
   TDF_Tool::Entry(theAx1->GetEntry(), anEntry);
@@ -1131,10 +1487,10 @@ Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::GetShapesOnPlan
 
 //=============================================================================
 /*!
- *  GetShapesOnCylinder
+ *  GetShapesOnCylinderIDs
  */
 //=============================================================================
-Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::GetShapesOnCylinder
+Handle(TColStd_HSequenceOfInteger) GEOMImpl_IShapesOperations::GetShapesOnCylinderIDs
                                           (const Handle(GEOM_Object)& theShape,
                                            const Standard_Integer     theShapeType,
                                            const Handle(GEOM_Object)& theAxis,
@@ -1153,8 +1509,9 @@ Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::GetShapesOnCyli
   TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
   if (aShapeType != TopAbs_VERTEX &&
       aShapeType != TopAbs_EDGE &&
-      aShapeType != TopAbs_FACE) {
-    SetErrorCode("Only vertices, edges or faces can be found by this method");
+      aShapeType != TopAbs_FACE &&
+      aShapeType != TopAbs_SOLID) {
+    SetErrorCode("Only solids, vertices, edges or faces can be found by this method");
     return NULL;
   }
 
@@ -1181,8 +1538,12 @@ Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::GetShapesOnCyli
   Handle(Geom_CylindricalSurface) aCylinder =
     new Geom_CylindricalSurface(anAx3, theRadius);
 
+  // Check presence of triangulation, build if need
+  if (!CheckTriangulation(aShape))
+    return NULL;
+
   // Call algo
-  GEOMAlgo_FinderShapeOn aFinder;
+  GEOMAlgo_FinderShapeOn1 aFinder;
   Standard_Real aTol = 0.0001; // default value
 
   aFinder.SetShape(aShape);
@@ -1191,11 +1552,14 @@ Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::GetShapesOnCyli
   aFinder.SetShapeType(aShapeType);
   aFinder.SetState(theState);
 
+  aFinder.SetNbPntsMin(3);
+  aFinder.SetNbPntsMax(100);
+
   aFinder.Perform();
 
   // Interprete results
   Standard_Integer iErr = aFinder.ErrorStatus();
-  // the detailed description of error codes is in GEOMAlgo_FinderShapeOn.cxx
+  // the detailed description of error codes is in GEOMAlgo_FinderShapeOn1.cxx
   if (iErr) {
     MESSAGE(" iErr : " << iErr);
     TCollection_AsciiString aMsg (" iErr : ");
@@ -1204,7 +1568,7 @@ Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::GetShapesOnCyli
     return NULL;
   }
   Standard_Integer iWrn = aFinder.WarningStatus();
-  // the detailed description of warning codes is in GEOMAlgo_FinderShapeOn.cxx
+  // the detailed description of warning codes is in GEOMAlgo_FinderShapeOn1.cxx
   if (iWrn) {
     MESSAGE(" *** iWrn : " << iWrn);
   }
@@ -1220,17 +1584,12 @@ Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::GetShapesOnCyli
   TopTools_IndexedMapOfShape anIndices;
   TopExp::MapShapes(aShape, anIndices);
 
-  Handle(GEOM_Object) anObj;
-  Handle(TColStd_HArray1OfInteger) anArray;
-  Handle(TColStd_HSequenceOfTransient) aSeq = new TColStd_HSequenceOfTransient;
+  Handle(TColStd_HSequenceOfInteger) aSeq = new TColStd_HSequenceOfInteger;
 
   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);
+    aSeq->Append(id);
   }
   
   // The GetShapesOnCylinder() doesn't change object so no new function is required.
@@ -1238,7 +1597,7 @@ Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::GetShapesOnCyli
 
   // Make a Python command
   TCollection_AsciiString anEntry, aDescr
-    ("\nlistShapesOnCylinder = IShapesOperations.GetShapesOnCylinder(");
+    ("\nlistShapesOnCylinder = IShapesOperations.GetShapesOnCylinderIDs(");
   TDF_Tool::Entry(theShape->GetEntry(), anEntry);
   aDescr += anEntry + TCollection_AsciiString(theShapeType) + ",";
   TDF_Tool::Entry(theAxis->GetEntry(), anEntry);
@@ -1256,10 +1615,10 @@ Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::GetShapesOnCyli
 
 //=============================================================================
 /*!
- *  GetShapesOnSphere
+ *  GetShapesOnSphereIDs
  */
 //=============================================================================
-Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::GetShapesOnSphere
+Handle(TColStd_HSequenceOfInteger) GEOMImpl_IShapesOperations::GetShapesOnSphereIDs
                                           (const Handle(GEOM_Object)& theShape,
                                            const Standard_Integer     theShapeType,
                                            const Handle(GEOM_Object)& theCenter,
@@ -1278,8 +1637,9 @@ Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::GetShapesOnSphe
   TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
   if (aShapeType != TopAbs_VERTEX &&
       aShapeType != TopAbs_EDGE &&
-      aShapeType != TopAbs_FACE) {
-    SetErrorCode("Only vertices, edges or faces can be found by this method");
+      aShapeType != TopAbs_FACE &&
+      aShapeType != TopAbs_SOLID) {
+    SetErrorCode("Only solids, vertices, edges or faces can be found by this method");
     return NULL;
   }
 
@@ -1291,8 +1651,12 @@ Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::GetShapesOnSphe
   Handle(Geom_SphericalSurface) aSphere =
     new Geom_SphericalSurface(anAx3, theRadius);
 
+  // Check presence of triangulation, build if need
+  if (!CheckTriangulation(aShape))
+    return NULL;
+
   // Call algo
-  GEOMAlgo_FinderShapeOn aFinder;
+  GEOMAlgo_FinderShapeOn1 aFinder;
   Standard_Real aTol = 0.0001; // default value
 
   aFinder.SetShape(aShape);
@@ -1301,11 +1665,14 @@ Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::GetShapesOnSphe
   aFinder.SetShapeType(aShapeType);
   aFinder.SetState(theState);
 
+  aFinder.SetNbPntsMin(3);
+  aFinder.SetNbPntsMax(100);
+
   aFinder.Perform();
 
   // Interprete results
   Standard_Integer iErr = aFinder.ErrorStatus();
-  // the detailed description of error codes is in GEOMAlgo_FinderShapeOn.cxx
+  // the detailed description of error codes is in GEOMAlgo_FinderShapeOn1.cxx
   if (iErr) {
     MESSAGE(" iErr : " << iErr);
     TCollection_AsciiString aMsg (" iErr : ");
@@ -1314,7 +1681,7 @@ Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::GetShapesOnSphe
     return NULL;
   }
   Standard_Integer iWrn = aFinder.WarningStatus();
-  // the detailed description of warning codes is in GEOMAlgo_FinderShapeOn.cxx
+  // the detailed description of warning codes is in GEOMAlgo_FinderShapeOn1.cxx
   if (iWrn) {
     MESSAGE(" *** iWrn : " << iWrn);
   }
@@ -1330,17 +1697,12 @@ Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::GetShapesOnSphe
   TopTools_IndexedMapOfShape anIndices;
   TopExp::MapShapes(aShape, anIndices);
 
-  Handle(GEOM_Object) anObj;
-  Handle(TColStd_HArray1OfInteger) anArray;
-  Handle(TColStd_HSequenceOfTransient) aSeq = new TColStd_HSequenceOfTransient;
+  Handle(TColStd_HSequenceOfInteger) aSeq = new TColStd_HSequenceOfInteger;
 
   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);
+    aSeq->Append(id);
   }
   
   // The GetShapesOnSphere() doesn't change object so no new function is required.
@@ -1348,7 +1710,7 @@ Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::GetShapesOnSphe
 
   // Make a Python command
   TCollection_AsciiString anEntry, aDescr
-    ("\nlistShapesOnSphere = IShapesOperations.GetShapesOnSphere(");
+    ("\nlistShapesOnSphere = IShapesOperations.GetShapesOnSphereIDs(");
   TDF_Tool::Entry(theShape->GetEntry(), anEntry);
   aDescr += anEntry + TCollection_AsciiString(theShapeType) + ",";
   TDF_Tool::Entry(theCenter->GetEntry(), anEntry);
@@ -1383,46 +1745,107 @@ Handle(GEOM_Object) GEOMImpl_IShapesOperations::GetInPlace
   if (aWhere.IsNull() || aWhat.IsNull()) return NULL;
 
   //Fill array of indices
-  TopTools_IndexedMapOfShape anIndices;
-  TopExp::MapShapes(aWhere, anIndices);
-
-//  Handle(TColStd_HArray1OfInteger) anArray =
-//    new TColStd_HArray1OfInteger (1, listSS.Extent());
-//  TopTools_ListIteratorOfListOfShape itSub (listSS);
-//  for (int index = 1; itSub.More(); itSub.Next(), ++index) {
-//    int id = anIndices.FindIndex(itSub.Value());
-//    anArray->SetValue(index, id);
-//  }
-//  
-//  //Add a new group object
-//  Handle(GEOM_Object) aGroup = GetEngine()->AddSubShape(theShape, anArray);
-//
-//  //Set a GROUP type
-//  aGroup->SetType(GEOM_GROUP);
-//
-//  //Set a sub shape type
-//  TDF_Label aFreeLabel = aGroup->GetFreeLabel();
-//  TDataStd_Integer::Set(aFreeLabel, (Standard_Integer)theShapeType);
-// 
-//  //Make a Python command
-//  TCollection_AsciiString anEntry, aDescr;
-//  TDF_Tool::Entry(aGroup->GetEntry(), anEntry);
-//  aDescr += anEntry;
-//  aDescr += " = IShapesOperations.GetInPlace(";
-//  TDF_Tool::Entry(theShapeWhere->GetEntry(), anEntry);
-//  aDescr += anEntry + ",";
-//  TDF_Tool::Entry(theShapeWhat->GetEntry(), anEntry);
-//  aDescr += anEntry + ")";
-//
-//  Handle(GEOM_Function) aFunction = aGroup->GetFunction(1);
-//  aFunction->SetDescription(aDescr);
+  Handle(TColStd_HArray1OfInteger) aModifiedArray;
 
-//  SetErrorCode(OK);
-//  return aGroup;
-  SetErrorCode("Not yet implemented");
-  return NULL;
-}
+  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
+  Handle(GEOM_Function) aFunction = aResult->GetFunction(1);
+
+  GEOM::TPythonDump(aFunction) << aResult << " = geompy.GetInPlace("
+    << theShapeWhere << ", " << theShapeWhat << ")";
+
+  SetErrorCode(OK);
+  return aResult;
+}
 
 //=======================================================================
 //function : SortShapes
@@ -1488,3 +1911,47 @@ void GEOMImpl_IShapesOperations::SortShapes(TopTools_ListOfShape& SL)
   for (Index=1; Index <= MaxShapes; Index++)
     SL.Append( aShapes( OrderInd(Index) ));
 }
+
+//=======================================================================
+//function : CheckTriangulation
+//purpose  :
+//=======================================================================
+bool GEOMImpl_IShapesOperations::CheckTriangulation (const TopoDS_Shape& aShape)
+{
+//  MESSAGE("CheckTriangulation");
+//
+//  OSD_Timer timer1;
+//  timer1.Start();
+
+  TopExp_Explorer exp (aShape, TopAbs_FACE);
+  if (!exp.More()) {
+    SetErrorCode("Shape without faces given");
+    return false;
+  }
+
+  TopLoc_Location aTopLoc;
+  Handle(Poly_Triangulation) aTRF;
+  aTRF = BRep_Tool::Triangulation(TopoDS::Face(exp.Current()), aTopLoc);
+  if (aTRF.IsNull()) {
+    // calculate deflection
+    Standard_Real aDeviationCoefficient = 0.001;
+
+    Bnd_Box B;
+    BRepBndLib::Add(aShape, B);
+    Standard_Real aXmin, aYmin, aZmin, aXmax, aYmax, aZmax;
+    B.Get(aXmin, aYmin, aZmin, aXmax, aYmax, aZmax);
+
+    Standard_Real dx = aXmax - aXmin, dy = aYmax - aYmin, dz = aZmax - aZmin;
+    Standard_Real aDeflection = Max(Max(dx, dy), dz) * aDeviationCoefficient * 4;
+
+//    MESSAGE("Deflection = " << aDeflection);
+
+    Standard_Real aHLRAngle = 0.349066;
+
+    BRepMesh_IncrementalMesh Inc (aShape, aDeflection, Standard_False, aHLRAngle);
+  }
+//  timer1.Stop();
+//  timer1.Show();
+
+  return true;
+}