Salome HOME
PAL10324. Fix MakePartition() for the case theMaterials.IsNull()
[modules/geom.git] / src / GEOMImpl / GEOMImpl_IShapesOperations.cxx
index bbe4f5803fd6ba3366c0e9e131ff6228e6bbe966..ec50792fa6660f7f9fc7a6aa0ecd6bfdb579c7fd 100644 (file)
@@ -1,4 +1,23 @@
-using namespace std;
+// Copyright (C) 2005  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// 
+// 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.
+// 
+// This library is distributed in the hope that it will be useful 
+// but WITHOUT ANY WARRANTY; without even the implied warranty of 
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU 
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public  
+// License along with this library; if not, write to the Free Software 
+// 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 "GEOMImpl_IShapesOperations.hxx"
 
@@ -16,8 +35,10 @@ using namespace std;
 #include "GEOMImpl_Block6Explorer.hxx"
 
 #include "GEOM_Function.hxx"
+#include "GEOM_PythonDump.hxx"
 
-#include "GEOMAlgo_FinderShapeOn.hxx"
+#include "GEOMAlgo_FinderShapeOn1.hxx"
+#include "GEOMAlgo_FinderShapeOnQuad.hxx"
 
 #include "utilities.h"
 #include "OpUtil.hxx"
@@ -35,7 +56,10 @@ using namespace std;
 #include <BRep_Tool.hxx>
 #include <BRepGProp.hxx>
 #include <BRepAdaptor_Curve.hxx>
+#include <BRepAdaptor_Surface.hxx>
+#include <BRepBndLib.hxx>
 #include <BRepBuilderAPI_MakeFace.hxx>
+#include <BRepMesh_IncrementalMesh.hxx>
 
 #include <TopAbs.hxx>
 #include <TopExp.hxx>
@@ -60,15 +84,16 @@ 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 <TColStd_Array1OfReal.hxx>
+#include <TColStd_HArray1OfInteger.hxx>
 
-//#include <OSD_Timer.hxx>
+#include <vector>
 
 #include <Standard_ErrorHandler.hxx> // CAREFUL ! position of this file is critic : see Lucien PIGNOLONI / OCC
 
@@ -139,15 +164,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;
@@ -210,19 +228,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;
@@ -282,28 +289,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;
@@ -328,7 +325,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");
 }
 
 //=============================================================================
@@ -375,14 +372,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;
@@ -405,10 +396,10 @@ Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeCompound
  */
 //=============================================================================
 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeShape
-                             (list<Handle(GEOM_Object)>     theShapes,
-                              const Standard_Integer        theObjectType,
-                              const Standard_Integer        theFunctionType,
-                              const TCollection_AsciiString theMethodName)
+                             (list<Handle(GEOM_Object)>      theShapes,
+                              const Standard_Integer         theObjectType,
+                              const Standard_Integer         theFunctionType,
+                              const TCollection_AsciiString& theMethodName)
 {
   SetErrorCode(KO);
 
@@ -453,25 +444,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;
@@ -529,15 +513,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);
@@ -554,9 +531,6 @@ 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;
@@ -594,21 +568,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;
 
   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);
@@ -616,49 +584,24 @@ 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, /*append=*/true);
+  pd << "[" << anAsciiList.ToCString();
+  pd << "] = geompy.SubShapeAll" << (isSorted ? "Sorted(" : "(");
+  pd << theShape << ", " << TopAbs_ShapeEnum(theShapeType) << ")";
 
   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;
 }
 
@@ -720,23 +663,13 @@ 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();
 
   //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, /*append=*/true);
+  pd << "listSubShapeIDs = geompy.SubShapeAll";
+  pd << (isSorted ? "SortedIDs(" : "IDs(");
+  pd << theShape << ", " << TopAbs_ShapeEnum(theShapeType) << ")";
 
   SetErrorCode(OK);
   return aSeq;
@@ -757,32 +690,179 @@ 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;
 }
 
+//=============================================================================
+/*!
+ *  GetSubShapeIndex
+ */
+//=============================================================================
+Standard_Integer GEOMImpl_IShapesOperations::GetSubShapeIndex (Handle(GEOM_Object) theMainShape,
+                                                               Handle(GEOM_Object) theSubShape)
+{
+  SetErrorCode(KO);
+
+  TopoDS_Shape aMainShape = theMainShape->GetValue();
+  TopoDS_Shape aSubShape = theSubShape->GetValue();
+
+  if (aMainShape.IsNull() || aSubShape.IsNull()) return -1;
+
+  TopTools_IndexedMapOfShape anIndices;
+  TopExp::MapShapes(aMainShape, anIndices);
+  if (anIndices.Contains(aSubShape)) {
+    SetErrorCode(OK);
+    return anIndices.FindIndex(aSubShape);
+  }
+
+  return -1;
+}
+
+//=============================================================================
+/*!
+ *  GetTopologyIndex
+ */
+//=============================================================================
+Standard_Integer GEOMImpl_IShapesOperations::GetTopologyIndex (Handle(GEOM_Object) theMainShape,
+                                                               Handle(GEOM_Object) theSubShape)
+{
+  SetErrorCode(OK);
+
+  TopoDS_Shape aMainShape = theMainShape->GetValue();
+  TopoDS_Shape aSubShape = theSubShape->GetValue();
+
+  if (aMainShape.IsNull() || aSubShape.IsNull()) {
+    SetErrorCode("Null argument shape given");
+    return -1;
+  }
+
+  int index = 1;
+  if (aSubShape.ShapeType() == TopAbs_COMPOUND) {
+    TopoDS_Iterator it;
+    TopTools_ListOfShape CL;
+    CL.Append(aMainShape);
+    TopTools_ListIteratorOfListOfShape itC;
+    for (itC.Initialize(CL); itC.More(); itC.Next()) {
+      for (it.Initialize(itC.Value()); it.More(); it.Next()) {
+       if (it.Value().ShapeType() == TopAbs_COMPOUND) {
+         if (it.Value().IsSame(aSubShape))
+           return index;
+         else
+           index++;
+         CL.Append(it.Value());
+       }
+      }
+    }
+  } else {
+    TopExp_Explorer anExp (aMainShape, aSubShape.ShapeType());
+    TopTools_MapOfShape M;
+    for (; anExp.More(); anExp.Next()) {
+      if (M.Add(anExp.Current())) {
+       if (anExp.Current().IsSame(aSubShape))
+         return index;
+       index++;
+      }
+    }
+  }
+
+  SetErrorCode("The sub-shape does not belong to the main shape");
+  return -1;
+}
+
+//=============================================================================
+/*!
+ *  GetShapeTypeString
+ */
+//=============================================================================
+TCollection_AsciiString GEOMImpl_IShapesOperations::GetShapeTypeString (Handle(GEOM_Object) theShape)
+{
+  SetErrorCode(KO);
+
+  TCollection_AsciiString aTypeName ("Null Shape");
+
+  TopoDS_Shape aShape = theShape->GetValue();
+  if (aShape.IsNull())
+    return aTypeName;
+
+  switch (aShape.ShapeType() )
+  {
+  case TopAbs_COMPOUND:
+    aTypeName = "Compound";
+    break;
+  case  TopAbs_COMPSOLID:
+    aTypeName = "Compound Solid";
+    break;
+  case TopAbs_SOLID:
+    aTypeName = "Solid";
+    break;
+  case TopAbs_SHELL:
+    aTypeName = "Shell";
+    break;
+  case TopAbs_FACE:
+    {
+      BRepAdaptor_Surface surf (TopoDS::Face(aShape));
+      if (surf.GetType() == GeomAbs_Plane)
+       aTypeName = "Plane";
+      else if (surf.GetType() == GeomAbs_Cylinder)
+       aTypeName = "Cylindrical Face";
+      else if (surf.GetType() == GeomAbs_Sphere)
+       aTypeName = "Spherical Face";
+      else if (surf.GetType() == GeomAbs_Torus)
+       aTypeName = "Toroidal Face";
+      else if (surf.GetType() == GeomAbs_Cone)
+       aTypeName = "Conical Face";
+      else
+       aTypeName = "GEOM::FACE";
+    }
+    break;
+  case TopAbs_WIRE:
+    aTypeName = "Wire";
+    break;
+  case TopAbs_EDGE:
+    {
+      BRepAdaptor_Curve curv (TopoDS::Edge(aShape));
+      if (curv.GetType() == GeomAbs_Line) {
+       if ((Abs(curv.FirstParameter()) >= 1E6) ||
+            (Abs(curv.LastParameter()) >= 1E6))
+          aTypeName = "Line";
+       else
+         aTypeName = "Edge" ;
+      } else if (curv.GetType() == GeomAbs_Circle) {
+       if (curv.IsClosed())
+          aTypeName = "Circle";
+       else
+          aTypeName = "Arc";
+      } else {
+        aTypeName = "Edge";
+      }
+    }
+    break;
+  case TopAbs_VERTEX:
+    aTypeName = "Vertex";
+    break;
+  case TopAbs_SHAPE:
+    aTypeName = "Shape";
+    break;
+  default:
+    aTypeName = "Shape of unknown type";
+  }
+
+  return aTypeName;
+}
+
 
 //=============================================================================
 /*!
@@ -879,14 +959,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;
@@ -934,24 +1008,18 @@ Handle(TColStd_HSequenceOfInteger) GEOMImpl_IShapesOperations::GetFreeFacesIDs
   Handle(GEOM_Function) aFunction = theShape->GetLastFunction();
 
   //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, /*append=*/true)
+    << "listFreeFacesIDs = geompy.GetFreeFacesIDs(" << theShape << ")";
 
   SetErrorCode(OK);
   return aSeq;
 }
 
-//=============================================================================
-/*!
- *  GetSharedShapes
- */
-//=============================================================================
+//=======================================================================
+//function : GetSharedShapes
+//purpose  : 
+//=======================================================================
+
 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::GetSharedShapes
                                                 (Handle(GEOM_Object)    theShape1,
                                                  Handle(GEOM_Object)    theShape2,
@@ -975,6 +1043,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));
@@ -985,6 +1054,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 += ",";
     }
   }
 
@@ -993,22 +1067,14 @@ 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) + ")";
-
-  TCollection_AsciiString anOldDescr = aFunction->GetDescription();
-  anOldDescr = anOldDescr + aDescr;
-  aFunction->SetDescription(anOldDescr);
+  anAsciiList.Trunc(anAsciiList.Length() - 1);
+
+  Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
+
+  GEOM::TPythonDump(aFunction) << "[" << anAsciiList.ToCString()
+    << "] = geompy.GetSharedShapes(" << theShape1 << ", "
+      << theShape2 << ", " << TopAbs_ShapeEnum(theShapeType) << ")";
 
   SetErrorCode(OK);
   return aSeq;
@@ -1016,34 +1082,67 @@ Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::GetSharedShapes
 
 //=============================================================================
 /*!
- *  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)
+static GEOM::TPythonDump& operator<< (GEOM::TPythonDump&   theDump,
+                                      const GEOMAlgo_State theState)
 {
-  SetErrorCode(KO);
-
-  if (theShape.IsNull() || theAx1.IsNull()) return NULL;
-
-  TopoDS_Shape aShape = theShape->GetValue();
-  TopoDS_Shape anAx1  = theAx1->GetValue();
+  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;
+}
 
-  if (aShape.IsNull() || anAx1.IsNull()) return NULL;
+//=======================================================================
+//function : checkTypeShapesOn
+/*!
+ * \brief Checks if theShapeType parameter of GetShapesOnXXX() is OK
+ * \param theShapeType - the shape type to check
+ * \retval bool  - result of the check
+ */
+//=======================================================================
 
-  TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
-  if (aShapeType != TopAbs_VERTEX &&
-      aShapeType != TopAbs_EDGE &&
-      aShapeType != TopAbs_FACE &&
-      aShapeType != TopAbs_SOLID) {
+bool GEOMImpl_IShapesOperations::checkTypeShapesOn(const Standard_Integer theShapeType)
+{
+  if (theShapeType != TopAbs_VERTEX &&
+      theShapeType != TopAbs_EDGE &&
+      theShapeType != TopAbs_FACE &&
+      theShapeType != TopAbs_SOLID) {
     SetErrorCode("Only solids, vertices, edges or faces can be found by this method");
-    return NULL;
+    return false;
   }
+  return true;
+}
 
-  // Create plane
+//=======================================================================
+//function : makePlane
+  /*!
+   * \brief Creates Geom_Plane
+    * \param theAx1 - shape object defining plane parameters
+    * \retval Handle(Geom_Surface) - resulting surface
+   */
+//=======================================================================
+
+Handle(Geom_Surface) GEOMImpl_IShapesOperations::makePlane(const TopoDS_Shape& anAx1)
+{
   if (anAx1.ShapeType() != TopAbs_EDGE) return NULL;
   TopoDS_Edge anEdge = TopoDS::Edge(anAx1);
   TopoDS_Vertex V1, V2;
@@ -1058,33 +1157,104 @@ Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::GetShapesOnPlan
     SetErrorCode("Vector with null magnitude given");
     return NULL;
   }
+  return new Geom_Plane(aLoc, aVec);
+}
+
+//=======================================================================
+//function : makeCylinder
+  /*!
+   * \brief Creates Geom_CylindricalSurface
+    * \param theAx1 - edge defining cylinder axis
+    * \param theRadius - cylinder radius
+    * \retval Handle(Geom_Surface) - resulting surface
+   */
+//=======================================================================
+
+Handle(Geom_Surface) GEOMImpl_IShapesOperations::makeCylinder(const TopoDS_Shape& anAxis,
+                                                              const Standard_Real theRadius)
+{
+  //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);
+  return new Geom_CylindricalSurface(anAx3, theRadius);
+}
+
+
+//=======================================================================
+//function : getShapesOnSurfaceIDs
+  /*!
+   * \brief Find IDs of subshapes complying with given status about surface
+    * \param theSurface - the surface to check state of subshapes against
+    * \param theShape - the shape to explore
+    * \param theShapeType - type of subshape of theShape
+    * \param theState - required state
+    * \retval Handle(TColStd_HSequenceOfInteger) - IDs of found subshapes
+   */
+//=======================================================================
+
+Handle(TColStd_HSequenceOfInteger)
+  GEOMImpl_IShapesOperations::getShapesOnSurfaceIDs(const Handle(Geom_Surface)& theSurface,
+                                                    const TopoDS_Shape&         theShape,
+                                                    TopAbs_ShapeEnum            theShapeType,
+                                                    GEOMAlgo_State              theState)
+{
+  Handle(TColStd_HSequenceOfInteger) aSeqOfIDs;
 
-  Handle(Geom_Plane) aPlane = new Geom_Plane(aLoc, aVec);
+  // Check presence of triangulation, build if need
+  if (!CheckTriangulation(theShape))
+    return aSeqOfIDs;
 
   // Call algo
-  GEOMAlgo_FinderShapeOn aFinder;
+  GEOMAlgo_FinderShapeOn1 aFinder;
   Standard_Real aTol = 0.0001; // default value
 
-  aFinder.SetShape(aShape);
+  aFinder.SetShape(theShape);
   aFinder.SetTolerance(aTol);
-  aFinder.SetSurface(aPlane);
-  aFinder.SetShapeType(aShapeType);
+  aFinder.SetSurface(theSurface);
+  aFinder.SetShapeType(theShapeType);
   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);
+
   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 : ");
     aMsg += TCollection_AsciiString(iErr);
     SetErrorCode(aMsg);
-    return NULL;
+    return aSeqOfIDs;
   }
   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,42 +1262,134 @@ Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::GetShapesOnPlan
   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;
+    SetErrorCode("Not a single sub-shape of the requested type found on the given surface");
+    return aSeqOfIDs;
   }
 
-  // Fill sequence of objects
-  TopTools_IndexedMapOfShape anIndices;
-  TopExp::MapShapes(aShape, anIndices);
+  // Fill sequence of object IDs
+  aSeqOfIDs = new TColStd_HSequenceOfInteger;
 
-  Handle(GEOM_Object) anObj;
-  Handle(TColStd_HArray1OfInteger) anArray;
-  Handle(TColStd_HSequenceOfTransient) aSeq = new TColStd_HSequenceOfTransient;
+  TopTools_IndexedMapOfShape anIndices;
+  TopExp::MapShapes(theShape, anIndices);
 
   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);
+    aSeqOfIDs->Append(id);
   }
-  
-  // The GetShapesOnPlane() doesn't change object so no new function is required.
-  Handle(GEOM_Function) aFunction = theShape->GetLastFunction();
+
+  return aSeqOfIDs;
+}
+
+//=======================================================================
+//function : getObjectsShapesOn
+/*!
+ * \brief Find shape objects and their entries by their ids
+ * \param theShapeIDs - incoming shape ids
+ * \param theShapeEntries - outgoing entries like "entry1, entry2, ..."
+ * \retval Handle(TColStd_HSequenceOfTransient) - found shape objects
+ */
+//=======================================================================
+
+Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::
+ getObjectsShapesOn(const Handle(GEOM_Object)&                theShape,
+                    const Handle(TColStd_HSequenceOfInteger)& theShapeIDs,
+                    TCollection_AsciiString &                 theShapeEntries)
+{
+  Handle(TColStd_HSequenceOfTransient) aSeq;
+
+  if ( !theShapeIDs.IsNull() && theShapeIDs->Length() > 0 )
+  {
+    aSeq = new TColStd_HSequenceOfTransient;
+    Handle(TColStd_HArray1OfInteger) anArray = new TColStd_HArray1OfInteger(1,1);
+    TCollection_AsciiString anEntry;
+    for ( int i = 1; i <= theShapeIDs->Length(); ++i )
+    {
+      anArray->SetValue(1, theShapeIDs->Value( i ));
+      Handle(GEOM_Object) anObj = GetEngine()->AddSubShape(theShape, anArray);
+      aSeq->Append( anObj );
+
+      TDF_Tool::Entry(anObj->GetEntry(), anEntry);
+      if ( i != 1 ) theShapeEntries += ",";
+      theShapeEntries += anEntry;
+    }
+  }
+  return aSeq;
+}
+
+//=======================================================================
+//function : getShapesOnSurface
+/*!
+   * \brief Find subshapes complying with given status about surface
+    * \param theSurface - the surface to check state of subshapes against
+    * \param theShape - the shape to explore
+    * \param theShapeType - type of subshape of theShape
+    * \param theState - required state
+    * \param theShapeEntries - outgoing entries like "entry1, entry2, ..."
+    * \retval Handle(TColStd_HSequenceOfInteger) - IDs of found subshapes
+ */
+//=======================================================================
+
+Handle(TColStd_HSequenceOfTransient)
+    GEOMImpl_IShapesOperations::getShapesOnSurface(const Handle(Geom_Surface)& theSurface,
+                                                   const Handle(GEOM_Object)&  theShape,
+                                                   TopAbs_ShapeEnum            theShapeType,
+                                                   GEOMAlgo_State              theState,
+                                                   TCollection_AsciiString &   theShapeEntries)
+{
+  // Find subshapes ids
+  Handle(TColStd_HSequenceOfInteger) aSeqOfIDs =
+    getShapesOnSurfaceIDs (theSurface, theShape->GetValue(), theShapeType, theState);
+  if ( aSeqOfIDs.IsNull()  || aSeqOfIDs->Length() == 0 )
+    return NULL;
+
+  return getObjectsShapesOn( theShape, aSeqOfIDs, theShapeEntries );
+}
+
+//=============================================================================
+/*!
+ *  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 ( !checkTypeShapesOn( theShapeType ))
+    return NULL;
+
+  // Create plane
+  Handle(Geom_Surface) aPlane = makePlane( anAx1 );
+  if ( aPlane.IsNull() )
+    return NULL;
+
+  // Find objects
+  TCollection_AsciiString anAsciiList;
+  Handle(TColStd_HSequenceOfTransient) aSeq;
+  aSeq = getShapesOnSurface( aPlane, theShape, aShapeType, theState, anAsciiList );
+  if ( aSeq.IsNull() || aSeq->Length() == 0 )
+    return NULL;
 
   // Make a Python command
-  TCollection_AsciiString anEntry, aDescr
-    ("\nlistShapesOnPlane = IShapesOperations.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);
+
+  Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast( aSeq->Value( 1 ));
+  Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
+
+  GEOM::TPythonDump(aFunction) << "[" << anAsciiList.ToCString()
+    << "] = geompy.GetShapesOnPlane(" << theShape << ", "
+      << aShapeType << ", " << theAx1 << ", " << theState << ")";
 
   SetErrorCode(OK);
   return aSeq;
@@ -1155,105 +1417,174 @@ Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::GetShapesOnCyli
   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");
+  if ( !checkTypeShapesOn( aShapeType ))
     return NULL;
-  }
 
-  //Axis of the cylinder
-  if (anAxis.ShapeType() != TopAbs_EDGE) {
-    SetErrorCode("Not an edge given for the axis");
+  // Create a cylinder surface
+  Handle(Geom_Surface) aCylinder = makeCylinder( anAxis, theRadius );
+  if ( aCylinder.IsNull() )
     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");
+
+  // Find objects
+  TCollection_AsciiString anAsciiList;
+  Handle(TColStd_HSequenceOfTransient) aSeq;
+  aSeq = getShapesOnSurface( aCylinder, theShape, aShapeType, theState, anAsciiList );
+  if ( aSeq.IsNull() || aSeq->Length() == 0 )
     return NULL;
-  }
+  
+  // Make a Python command
 
-  gp_Ax3 anAx3 (aLoc, aVec);
-  Handle(Geom_CylindricalSurface) aCylinder =
-    new Geom_CylindricalSurface(anAx3, theRadius);
+  Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast( aSeq->Value( 1 ));
+  Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
 
-  // Call algo
-  GEOMAlgo_FinderShapeOn aFinder;
-  Standard_Real aTol = 0.0001; // default value
+  GEOM::TPythonDump(aFunction) << "[" << anAsciiList.ToCString()
+    << "] = geompy.GetShapesOnCylinder(" << theShape << ", " << aShapeType
+      << ", " << theAxis << ", " << theRadius << ", " << theState << ")";
 
-  aFinder.SetShape(aShape);
-  aFinder.SetTolerance(aTol);
-  aFinder.SetSurface(aCylinder);
-  aFinder.SetShapeType(aShapeType);
-  aFinder.SetState(theState);
+  SetErrorCode(OK);
+  return aSeq;
+}
 
-  aFinder.Perform();
+//=============================================================================
+/*!
+ *  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);
 
-  // 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);
+  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 ( !checkTypeShapesOn( aShapeType ))
     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
+  // Center of the sphere
+  if (aCenter.ShapeType() != TopAbs_VERTEX) return NULL;
+  gp_Pnt aLoc = BRep_Tool::Pnt(TopoDS::Vertex(aCenter));
 
-  if (listSS.Extent() < 1) {
-    SetErrorCode("Not a single sub-shape of the requested type found on the given cylinder");
+  gp_Ax3 anAx3 (aLoc, gp::DZ());
+  Handle(Geom_SphericalSurface) aSphere =
+    new Geom_SphericalSurface(anAx3, theRadius);
+
+  // Find objects
+  TCollection_AsciiString anAsciiList;
+  Handle(TColStd_HSequenceOfTransient) aSeq;
+  aSeq = getShapesOnSurface( aSphere, theShape, aShapeType, theState, anAsciiList );
+  if ( aSeq.IsNull() || aSeq->Length() == 0 )
     return NULL;
-  }
+    
+  // Make a Python command
 
-  // Fill sequence of objects
-  TopTools_IndexedMapOfShape anIndices;
-  TopExp::MapShapes(aShape, anIndices);
+  Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast( aSeq->Value( 1 ));
+  Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
 
-  Handle(GEOM_Object) anObj;
-  Handle(TColStd_HArray1OfInteger) anArray;
-  Handle(TColStd_HSequenceOfTransient) aSeq = new TColStd_HSequenceOfTransient;
+  GEOM::TPythonDump(aFunction) << "[" << anAsciiList.ToCString()
+    << "] = geompy.GetShapesOnSphere(" << theShape << ", " << aShapeType
+      << ", " << theCenter << ", " << theRadius << ", " << theState << ")";
 
-  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);
-  }
+  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 ( !checkTypeShapesOn( aShapeType ))
+    return NULL;
+
+  // Create plane
+  Handle(Geom_Surface) aPlane = makePlane( anAx1 );
+  if ( aPlane.IsNull() )
+    return NULL;
+
+  // Find object IDs
+  Handle(TColStd_HSequenceOfInteger) aSeq;
+  aSeq = getShapesOnSurfaceIDs( aPlane, aShape, aShapeType, theState );
+
+  // The GetShapesOnPlaneIDs() doesn't change object so no new function is required.
+  Handle(GEOM_Function) aFunction = GEOM::GetCreatedLast(theShape,theAx1)->GetLastFunction();
+
+  // Make a Python command
+  GEOM::TPythonDump(aFunction, /*append=*/true)
+    << "listShapesOnPlane = geompy.GetShapesOnPlaneIDs"
+    << "(" << theShape << "," << aShapeType << "," << theAx1 << "," << theState << ")";
+
+  SetErrorCode(OK);
+  return aSeq;
+}
+
+//=============================================================================
+/*!
+ *  GetShapesOnCylinderIDs
+ */
+//=============================================================================
+Handle(TColStd_HSequenceOfInteger) GEOMImpl_IShapesOperations::GetShapesOnCylinderIDs
+                                          (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 ( !checkTypeShapesOn( aShapeType ))
+    return NULL;
+
+  // Create a cylinder surface
+  Handle(Geom_Surface) aCylinder = makeCylinder( anAxis, theRadius );
+  if ( aCylinder.IsNull() )
+    return NULL;
   
+  // Find object IDs
+  Handle(TColStd_HSequenceOfInteger) aSeq;
+  aSeq = getShapesOnSurfaceIDs( aCylinder, aShape, aShapeType, theState );
+
   // The GetShapesOnCylinder() doesn't change object so no new function is required.
-  Handle(GEOM_Function) aFunction = theShape->GetLastFunction();
+  Handle(GEOM_Function) aFunction = GEOM::GetCreatedLast(theShape,theAxis)->GetLastFunction();
 
   // Make a Python command
-  TCollection_AsciiString anEntry, aDescr
-    ("\nlistShapesOnCylinder = IShapesOperations.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);
+  GEOM::TPythonDump(aFunction, /*append=*/true)
+    << "listShapesOnCylinder = geompy.GetShapesOnCylinderIDs"
+    << "(" << theShape << ", " << aShapeType << ", " << theAxis << ", "
+    << theRadius << ", " << theState << ")";
 
   SetErrorCode(OK);
   return aSeq;
@@ -1261,10 +1592,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,
@@ -1281,13 +1612,8 @@ Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::GetShapesOnSphe
   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");
+  if ( !checkTypeShapesOn( aShapeType ))
     return NULL;
-  }
 
   // Center of the sphere
   if (aCenter.ShapeType() != TopAbs_VERTEX) return NULL;
@@ -1297,30 +1623,122 @@ Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::GetShapesOnSphe
   Handle(Geom_SphericalSurface) aSphere =
     new Geom_SphericalSurface(anAx3, theRadius);
 
+  // Find object IDs
+  Handle(TColStd_HSequenceOfInteger) aSeq;
+  aSeq = getShapesOnSurfaceIDs( aSphere, aShape, aShapeType, theState );
+  
+  // The GetShapesOnSphere() doesn't change object so no new function is required.
+  Handle(GEOM_Function) aFunction = GEOM::GetCreatedLast(theShape,theCenter)->GetLastFunction();
+
+  // Make a Python command
+  GEOM::TPythonDump(aFunction, /*append=*/true)
+    << "listShapesOnCylinder = geompy.GetShapesOnCylinderIDs"
+    << "(" << theShape << ", " << aShapeType << ", " << theCenter << ", "
+    << theRadius << ", " << theState << ")";
+
+  SetErrorCode(OK);
+  return aSeq;
+}
+
+//=======================================================================
+//function : getShapesOnQuadrangleIDs
+  /*!
+   * \brief Find IDs of subshapes complying with given status about quadrangle
+    * \param theShape - the shape to explore
+    * \param theShapeType - type of subshape of theShape
+    * \param theTopLeftPoint - top left quadrangle corner
+    * \param theTopRigthPoint - top right quadrangle corner
+    * \param theBottomLeftPoint - bottom left quadrangle corner
+    * \param theBottomRigthPoint - bottom right quadrangle corner
+    * \param theState - required state
+    * \retval Handle(TColStd_HSequenceOfInteger) - IDs of found subshapes
+   */
+//=======================================================================
+
+Handle(TColStd_HSequenceOfInteger)
+  GEOMImpl_IShapesOperations::getShapesOnQuadrangleIDs (const Handle(GEOM_Object)& theShape,
+                                                        const Standard_Integer     theShapeType,
+                                                        const Handle(GEOM_Object)& theTopLeftPoint,
+                                                        const Handle(GEOM_Object)& theTopRigthPoint,
+                                                        const Handle(GEOM_Object)& theBottomLeftPoint,
+                                                        const Handle(GEOM_Object)& theBottomRigthPoint,
+                                                        const GEOMAlgo_State       theState)
+{
+  SetErrorCode(KO);
+
+  if ( theShape.IsNull() ||
+       theTopLeftPoint.IsNull() ||
+       theTopRigthPoint.IsNull() ||
+       theBottomLeftPoint.IsNull() ||
+       theBottomRigthPoint.IsNull() )
+    return NULL;
+
+  TopoDS_Shape aShape = theShape->GetValue();
+  TopoDS_Shape aTL = theTopLeftPoint->GetValue();
+  TopoDS_Shape aTR = theTopRigthPoint->GetValue();
+  TopoDS_Shape aBL = theBottomLeftPoint->GetValue();
+  TopoDS_Shape aBR = theBottomRigthPoint->GetValue();
+
+  if (aShape.IsNull() ||
+      aTL.IsNull() || 
+      aTR.IsNull() || 
+      aBL.IsNull() || 
+      aBR.IsNull() ||
+      aTL.ShapeType() != TopAbs_VERTEX || 
+      aTR.ShapeType() != TopAbs_VERTEX || 
+      aBL.ShapeType() != TopAbs_VERTEX || 
+      aBR.ShapeType() != TopAbs_VERTEX )
+    return NULL;
+
+  TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
+  if ( !checkTypeShapesOn( aShapeType ))
+    return NULL;
+
+  Handle(TColStd_HSequenceOfInteger) aSeqOfIDs;
+
+  // Check presence of triangulation, build if need
+  if (!CheckTriangulation(aShape))
+    return aSeqOfIDs;
+
   // Call algo
-  GEOMAlgo_FinderShapeOn aFinder;
+  gp_Pnt aPntTL = BRep_Tool::Pnt(TopoDS::Vertex(aTL));
+  gp_Pnt aPntTR = BRep_Tool::Pnt(TopoDS::Vertex(aTR));
+  gp_Pnt aPntBL = BRep_Tool::Pnt(TopoDS::Vertex(aBL));
+  gp_Pnt aPntBR = BRep_Tool::Pnt(TopoDS::Vertex(aBR));
+
+  GEOMAlgo_FinderShapeOnQuad aFinder( aPntTL, aPntTR, aPntBL, aPntBR );
   Standard_Real aTol = 0.0001; // default value
 
   aFinder.SetShape(aShape);
   aFinder.SetTolerance(aTol);
-  aFinder.SetSurface(aSphere);
+  //aFinder.SetSurface(theSurface);
   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);
+
   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 : ");
     aMsg += TCollection_AsciiString(iErr);
     SetErrorCode(aMsg);
-    return NULL;
+    return aSeqOfIDs;
   }
   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);
   }
@@ -1328,53 +1746,232 @@ Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::GetShapesOnSphe
   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;
+    SetErrorCode("Not a single sub-shape of the requested type found on the given surface");
+    return aSeqOfIDs;
   }
 
-  // Fill sequence of objects
+  // Fill sequence of object IDs
+  aSeqOfIDs = new TColStd_HSequenceOfInteger;
+
   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);
+    aSeqOfIDs->Append(id);
   }
-  
-  // The GetShapesOnSphere() doesn't change object so no new function is required.
-  Handle(GEOM_Function) aFunction = theShape->GetLastFunction();
+  return aSeqOfIDs;
+}
+
+//=======================================================================
+//function : GetShapesOnQuadrangle
+  /*!
+   * \brief Find subshapes complying with given status about quadrangle
+    * \param theShape - the shape to explore
+    * \param theShapeType - type of subshape of theShape
+    * \param theTopLeftPoint - top left quadrangle corner
+    * \param theTopRigthPoint - top right quadrangle corner
+    * \param theBottomLeftPoint - bottom left quadrangle corner
+    * \param theBottomRigthPoint - bottom right quadrangle corner
+    * \param theState - required state
+    * \retval Handle(TColStd_HSequenceOfInteger) - IDs of found subshapes
+   */
+//=======================================================================
+
+Handle(TColStd_HSequenceOfTransient)
+    GEOMImpl_IShapesOperations::GetShapesOnQuadrangle (const Handle(GEOM_Object)& theShape,
+                                                       const Standard_Integer     theShapeType,
+                                                       const Handle(GEOM_Object)& theTopLeftPoint,
+                                                       const Handle(GEOM_Object)& theTopRigthPoint,
+                                                       const Handle(GEOM_Object)& theBottomLeftPoint,
+                                                       const Handle(GEOM_Object)& theBottomRigthPoint,
+                                                       const GEOMAlgo_State       theState)
+{
+  // Find indices
+  Handle(TColStd_HSequenceOfInteger) aSeqOfIDs =
+    getShapesOnQuadrangleIDs( theShape,
+                              theShapeType,
+                              theTopLeftPoint,
+                              theTopRigthPoint,
+                              theBottomLeftPoint,
+                              theBottomRigthPoint,
+                              theState);
+  if ( aSeqOfIDs.IsNull() || aSeqOfIDs->IsEmpty() )
+    return NULL;
+
+  // Find objects by indices
+  TCollection_AsciiString anAsciiList;
+  Handle(TColStd_HSequenceOfTransient) aSeq;
+  aSeq = getObjectsShapesOn( theShape, aSeqOfIDs, anAsciiList );
+  if ( aSeq.IsNull() || aSeq->IsEmpty() )
+    return NULL;
 
   // Make a Python command
-  TCollection_AsciiString anEntry, aDescr
-    ("\nlistShapesOnSphere = IShapesOperations.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);
+
+  Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast( aSeq->Value( 1 ));
+  Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
+
+  GEOM::TPythonDump(aFunction)
+    << "[" << anAsciiList.ToCString() << "] = geompy.GetShapesOnQuadrangle("
+    << theShape << ", "
+    << TopAbs_ShapeEnum(theShapeType) << ", "
+    << theTopLeftPoint << ", "
+    << theTopRigthPoint << ", "
+    << theBottomLeftPoint << ", "
+    << theBottomRigthPoint << ", "
+    << theState << ")";
 
   SetErrorCode(OK);
   return aSeq;
 }
 
+//=======================================================================
+//function : GetShapesOnQuadrangleIDs
+  /*!
+   * \brief Find IDs of subshapes complying with given status about quadrangle
+    * \param theShape - the shape to explore
+    * \param theShapeType - type of subshape of theShape
+    * \param theTopLeftPoint - top left quadrangle corner
+    * \param theTopRigthPoint - top right quadrangle corner
+    * \param theBottomLeftPoint - bottom left quadrangle corner
+    * \param theBottomRigthPoint - bottom right quadrangle corner
+    * \param theState - required state
+    * \retval Handle(TColStd_HSequenceOfInteger) - IDs of found subshapes
+   */
+//=======================================================================
+
+Handle(TColStd_HSequenceOfInteger)
+  GEOMImpl_IShapesOperations::GetShapesOnQuadrangleIDs (const Handle(GEOM_Object)& theShape,
+                                                        const Standard_Integer     theShapeType,
+                                                        const Handle(GEOM_Object)& theTopLeftPoint,
+                                                        const Handle(GEOM_Object)& theTopRigthPoint,
+                                                        const Handle(GEOM_Object)& theBottomLeftPoint,
+                                                        const Handle(GEOM_Object)& theBottomRigthPoint,
+                                                        const GEOMAlgo_State       theState)
+{
+  // Find indices
+  Handle(TColStd_HSequenceOfInteger) aSeqOfIDs =
+    getShapesOnQuadrangleIDs( theShape,
+                              theShapeType,
+                              theTopLeftPoint,
+                              theTopRigthPoint,
+                              theBottomLeftPoint,
+                              theBottomRigthPoint,
+                              theState);
+  if ( aSeqOfIDs.IsNull() || aSeqOfIDs->IsEmpty() )
+    return NULL;
+
+  // Make a Python command
+
+  // The GetShapesOnCylinder() doesn't change object so no new function is required.
+  Handle(GEOM_Object) lastObj = GEOM::GetCreatedLast(theShape,theTopLeftPoint);
+  lastObj = GEOM::GetCreatedLast(lastObj,theTopRigthPoint);
+  lastObj = GEOM::GetCreatedLast(lastObj,theBottomRigthPoint);
+  lastObj = GEOM::GetCreatedLast(lastObj,theBottomLeftPoint);
+  Handle(GEOM_Function) aFunction = lastObj->GetLastFunction();
+
+  GEOM::TPythonDump(aFunction, /*append=*/true)
+    << "listShapesOnQuadrangle = geompy.GetShapesOnQuadrangleIDs("
+    << theShape << ", "
+    << TopAbs_ShapeEnum(theShapeType) << ", "
+    << theTopLeftPoint << ", "
+    << theTopRigthPoint << ", "
+    << theBottomLeftPoint << ", "
+    << theBottomRigthPoint << ", "
+    << theState << ")";
+
+  SetErrorCode(OK);
+  return aSeqOfIDs;
+}
+
+
 //=============================================================================
 /*!
  *  GetInPlace
  */
 //=============================================================================
+static void SimplifyWhat (TopoDS_Shape& theWhat,
+                          TopTools_IndexedMapOfShape& theArgumentIndices,
+                          TColStd_ListOfInteger& theSimpleSubWhat)
+{
+  TopTools_MapOfShape mapShape;
+  TopoDS_Iterator It (theWhat, Standard_True, Standard_True);
+  for (; It.More(); It.Next()) {
+    if (mapShape.Add(It.Value())) {
+      TopoDS_Shape curSh = It.Value();
+      if (curSh.ShapeType() == TopAbs_COMPOUND ||
+          curSh.ShapeType() == TopAbs_COMPSOLID) {
+        SimplifyWhat(curSh, theArgumentIndices, theSimpleSubWhat);
+      } else {
+        theSimpleSubWhat.Append(theArgumentIndices.FindIndex(curSh));
+      }
+    }
+  }
+}
+
+static bool GetInPlaceOfCompound (Handle(GEOM_Function)& theWhereFunction,
+                                  TopoDS_Shape& theWhat,
+                                  TColStd_ListOfInteger& theModifiedArray)
+{
+  bool isFoundAny = false;
+  TopTools_MapOfShape mapShape;
+  TopoDS_Iterator It (theWhat, Standard_True, Standard_True);
+  for (; It.More(); It.Next()) {
+    if (mapShape.Add(It.Value())) {
+      TopoDS_Shape curWhat = It.Value();
+      if (curWhat.ShapeType() == TopAbs_COMPOUND ||
+          curWhat.ShapeType() == TopAbs_COMPSOLID) {
+        // Recursive call for compound or compsolid
+        if (GetInPlaceOfCompound(theWhereFunction, curWhat, theModifiedArray))
+          isFoundAny = true;
+      } else {
+        // Try to find for "simple" shape
+        bool isFound = false;
+
+        TDF_LabelSequence aLabelSeq;
+        theWhereFunction->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(curWhat)) {
+            isFound = Standard_True;
+            Standard_Integer aWhatIndex = anArgumentIndices.FindIndex(curWhat);
+
+            // Find corresponding label in history
+            TDF_Label anArgumentHistoryLabel =
+              theWhereFunction->GetArgumentHistoryEntry(anArgumentRefLabel, Standard_False);
+            if (!anArgumentHistoryLabel.IsNull()) {
+              TDF_Label aWhatHistoryLabel = anArgumentHistoryLabel.FindChild(aWhatIndex, Standard_False);
+              if (!aWhatHistoryLabel.IsNull()) {
+                Handle(TDataStd_IntegerArray) anIntegerArray;
+                if (aWhatHistoryLabel.FindAttribute(TDataStd_IntegerArray::GetID(), anIntegerArray)) {
+                  Standard_Integer imod, aModifLen = anIntegerArray->Array()->Length();
+                  for (imod = 1; imod <= aModifLen; imod++) {
+                    theModifiedArray.Append(anIntegerArray->Array()->Value(imod));
+                  }
+                }
+              }
+            }
+          }
+        }
+        if (isFound)
+          isFoundAny = true;
+      }
+    }
+  }
+  return isFoundAny;
+}
+
 Handle(GEOM_Object) GEOMImpl_IShapesOperations::GetInPlace
                                           (Handle(GEOM_Object) theShapeWhere,
                                            Handle(GEOM_Object) theShapeWhat)
@@ -1443,28 +2040,78 @@ Handle(GEOM_Object) GEOMImpl_IShapesOperations::GetInPlace
 
         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;
+          // Check, if the sought shape is Compound or Compsolid.
+          // In that case we will try to find history for its sub-shapes
+          if (aWhat.ShapeType() == TopAbs_COMPOUND ||
+              aWhat.ShapeType() == TopAbs_COMPSOLID) {
+            TColStd_ListOfInteger aSimpleSubWhat, aModifiedList;
+            SimplifyWhat(aWhat, anArgumentIndices, aSimpleSubWhat);
+            TColStd_ListIteratorOfListOfInteger anIterSub (aSimpleSubWhat);
+            for (; anIterSub.More(); anIterSub.Next()) {
+              Standard_Integer aSubWhatIndex = anIterSub.Value();
+              TDF_Label aSubWhatHistoryLabel =
+                anArgumentHistoryLabel.FindChild(aSubWhatIndex, Standard_False);
+              if (!aSubWhatHistoryLabel.IsNull()) {
+                Handle(TDataStd_IntegerArray) anIntegerArray;
+                if (aSubWhatHistoryLabel.FindAttribute(TDataStd_IntegerArray::GetID(), anIntegerArray)) {
+                  for (Standard_Integer isub = 1; isub <= anIntegerArray->Length(); isub++) {
+                    aModifiedList.Append(anIntegerArray->Value(isub));
+                  }
+                }
+              }
+            }
+            if (aModifiedList.Extent() > 0) {
+              Handle(TColStd_HArray1OfInteger) aModifiedArraySub =
+                new TColStd_HArray1OfInteger (1, aModifiedList.Extent());
+              TColStd_ListIteratorOfListOfInteger anIterModif (aModifiedList);
+              for (Standard_Integer imod = 1; anIterModif.More(); anIterModif.Next(), imod++) {
+                aModifiedArraySub->SetValue(imod, anIterModif.Value());
+              }
+              aModifiedArray = aModifiedArraySub;
+            } else {
+              // Removed entity
+              SetErrorCode(OK);
+              return NULL;
+            }
+          } else {
+            // Removed entity
+            SetErrorCode(OK);
+            return NULL;
+          }
+        } else {
+          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;
+      // try compound element by element
+      if (aWhat.ShapeType() == TopAbs_COMPOUND ||
+          aWhat.ShapeType() == TopAbs_COMPSOLID) {
+        TColStd_ListOfInteger aModifiedList;
+        isFound = GetInPlaceOfCompound(aWhereFunction, aWhat, aModifiedList);
+        if (isFound) {
+          aModifiedArray = new TColStd_HArray1OfInteger (1, aModifiedList.Extent());
+          TColStd_ListIteratorOfListOfInteger anIterModif (aModifiedList);
+          for (Standard_Integer imod = 1; anIterModif.More(); anIterModif.Next(), imod++) {
+            aModifiedArray->SetValue(imod, anIterModif.Value());
+          }
+        }
+      }
+      if (!isFound) {
+        SetErrorCode("The sought shape does not belong to any operation argument.");
+        return NULL;
+      }
     }
   }
 
@@ -1482,17 +2129,10 @@ Handle(GEOM_Object) GEOMImpl_IShapesOperations::GetInPlace
   }
 
   //Make a Python command
-  TCollection_AsciiString anEntry, aDescr;
-  TDF_Tool::Entry(aResult->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 = aResult->GetFunction(1);
-  aFunction->SetDescription(aDescr);
+
+  GEOM::TPythonDump(aFunction) << aResult << " = geompy.GetInPlace("
+    << theShapeWhere << ", " << theShapeWhat << ")";
 
   SetErrorCode(OK);
   return aResult;
@@ -1535,6 +2175,7 @@ void GEOMImpl_IShapesOperations::SortShapes(TopTools_ListOfShape& SL)
     MidXYZ.SetValue(Index,
                    GPoint.X()*999 + GPoint.Y()*99 + GPoint.Z()*0.9);
   }
+
   // Sorting
   Standard_Integer aTemp;
   Standard_Boolean exchange, Sort = Standard_True;
@@ -1562,3 +2203,37 @@ 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)
+{
+  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;
+    Standard_Real aHLRAngle = 0.349066;
+
+    BRepMesh_IncrementalMesh Inc (aShape, aDeflection, Standard_False, aHLRAngle);
+  }
+
+  return true;
+}