Salome HOME
PAL10324. Fix MakePartition() for the case theMaterials.IsNull()
[modules/geom.git] / src / GEOMImpl / GEOMImpl_IShapesOperations.cxx
index 39172e1a9e3eae6f0b96ad54281e7eb51e967599..ec50792fa6660f7f9fc7a6aa0ecd6bfdb579c7fd 100644 (file)
@@ -15,7 +15,7 @@
 // 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/
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
 #include <Standard_Stream.hxx>
 
@@ -56,6 +56,7 @@
 #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 <GProp_GProps.hxx>
 #include <gp_Pnt.hxx>
 #include <gp_Lin.hxx>
+#include <TColStd_ListOfInteger.hxx>
+#include <TColStd_ListIteratorOfListOfInteger.hxx>
 #include <TColStd_Array1OfReal.hxx>
 #include <TColStd_HArray1OfInteger.hxx>
 
 #include <vector>
-//#include <iostream>
-
-//#include <OSD_Timer.hxx>
 
 #include <Standard_ErrorHandler.hxx> // CAREFUL ! position of this file is critic : see Lucien PIGNOLONI / OCC
 
@@ -325,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");
 }
 
 //=============================================================================
@@ -531,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;
@@ -571,15 +568,9 @@ 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;
@@ -603,26 +594,14 @@ Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::MakeExplode
   anAsciiList.Trunc(anAsciiList.Length() - 1);
 
   aFunction = theShape->GetLastFunction();
-  TCollection_AsciiString anOldDescr = aFunction->GetDescription();
 
-  GEOM::TPythonDump pd (aFunction);
-  pd << anOldDescr.ToCString() << "\n\t[" << anAsciiList.ToCString();
+  GEOM::TPythonDump pd (aFunction, /*append=*/true);
+  pd << "[" << anAsciiList.ToCString();
   pd << "] = geompy.SubShapeAll" << (isSorted ? "Sorted(" : "(");
-  pd << theShape << ", " << theShapeType << ")";
+  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;
 }
 
@@ -685,13 +664,12 @@ Handle(TColStd_HSequenceOfInteger) GEOMImpl_IShapesOperations::SubShapeAllIDs
   }
 
   Handle(GEOM_Function) aFunction = theShape->GetLastFunction();
-  TCollection_AsciiString anOldDescr = aFunction->GetDescription();
 
   //Make a Python command
-  GEOM::TPythonDump pd (aFunction);
-  pd << anOldDescr.ToCString() << "\n\tlistSubShapeIDs = geompy.SubShapeAll";
+  GEOM::TPythonDump pd (aFunction, /*append=*/true);
+  pd << "listSubShapeIDs = geompy.SubShapeAll";
   pd << (isSorted ? "SortedIDs(" : "IDs(");
-  pd << theShape << ", " << theShapeType << ")";
+  pd << theShape << ", " << TopAbs_ShapeEnum(theShapeType) << ")";
 
   SetErrorCode(OK);
   return aSeq;
@@ -728,6 +706,163 @@ Handle(GEOM_Object) GEOMImpl_IShapesOperations::GetSubShape
   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;
+}
+
 
 //=============================================================================
 /*!
@@ -871,11 +1006,10 @@ 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
-  GEOM::TPythonDump(aFunction) << anOldDescr.ToCString()
-    << "\n\tlistFreeFacesIDs = geompy.GetFreeFacesIDs(" << theShape << ")";
+  GEOM::TPythonDump(aFunction, /*append=*/true)
+    << "listFreeFacesIDs = geompy.GetFreeFacesIDs(" << theShape << ")";
 
   SetErrorCode(OK);
   return aSeq;
@@ -940,7 +1074,7 @@ Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::GetSharedShapes
 
   GEOM::TPythonDump(aFunction) << "[" << anAsciiList.ToCString()
     << "] = geompy.GetSharedShapes(" << theShape1 << ", "
-      << theShape2 << ", " << theShapeType << ")";
+      << theShape2 << ", " << TopAbs_ShapeEnum(theShapeType) << ")";
 
   SetErrorCode(OK);
   return aSeq;
@@ -1082,9 +1216,6 @@ Handle(TColStd_HSequenceOfInteger)
                                                     GEOMAlgo_State              theState)
 {
   Handle(TColStd_HSequenceOfInteger) aSeqOfIDs;
-//  MESSAGE("--------------------------- GetShapesOnPlane phase 1 takes:");
-//  OSD_Timer timer1;
-//  timer1.Start();
 
   // Check presence of triangulation, build if need
   if (!CheckTriangulation(theShape))
@@ -1110,19 +1241,7 @@ Handle(TColStd_HSequenceOfInteger)
   // 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();
@@ -1147,13 +1266,6 @@ Handle(TColStd_HSequenceOfInteger)
     return aSeqOfIDs;
   }
 
-//  timer1.Stop();
-//  timer1.Show();
-
-//  MESSAGE("--------------------------- GetShapesOnPlane phase 4 takes:");
-//  timer1.Reset();
-//  timer1.Start();
-
   // Fill sequence of object IDs
   aSeqOfIDs = new TColStd_HSequenceOfInteger;
 
@@ -1165,8 +1277,7 @@ Handle(TColStd_HSequenceOfInteger)
     int id = anIndices.FindIndex(itSub.Value());
     aSeqOfIDs->Append(id);
   }
-//  timer1.Stop();
-//  timer1.Show();
+
   return aSeqOfIDs;
 }
 
@@ -1248,10 +1359,6 @@ 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();
@@ -1275,13 +1382,6 @@ Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::GetShapesOnPlan
   if ( aSeq.IsNull() || aSeq->Length() == 0 )
     return NULL;
 
-//  timer1.Stop();
-//  timer1.Show();
-
-//  MESSAGE("--------------------------- GetShapesOnPlane phase 5 takes:");
-//  timer1.Reset();
-//  timer1.Start();
-
   // Make a Python command
 
   Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast( aSeq->Value( 1 ));
@@ -1289,7 +1389,7 @@ Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::GetShapesOnPlan
 
   GEOM::TPythonDump(aFunction) << "[" << anAsciiList.ToCString()
     << "] = geompy.GetShapesOnPlane(" << theShape << ", "
-      << theShapeType << ", " << theAx1 << ", " << theState << ")";
+      << aShapeType << ", " << theAx1 << ", " << theState << ")";
 
   SetErrorCode(OK);
   return aSeq;
@@ -1338,7 +1438,7 @@ Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::GetShapesOnCyli
   Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
 
   GEOM::TPythonDump(aFunction) << "[" << anAsciiList.ToCString()
-    << "] = geompy.GetShapesOnCylinder(" << theShape << ", " << theShapeType
+    << "] = geompy.GetShapesOnCylinder(" << theShape << ", " << aShapeType
       << ", " << theAxis << ", " << theRadius << ", " << theState << ")";
 
   SetErrorCode(OK);
@@ -1391,31 +1491,13 @@ Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::GetShapesOnSphe
   Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
 
   GEOM::TPythonDump(aFunction) << "[" << anAsciiList.ToCString()
-    << "] = geompy.GetShapesOnSphere(" << theShape << ", " << theShapeType
+    << "] = geompy.GetShapesOnSphere(" << theShape << ", " << aShapeType
       << ", " << theCenter << ", " << theRadius << ", " << theState << ")";
 
   SetErrorCode(OK);
   return aSeq;
 }
 
-//=======================================================================
-//function : getCreatedLast
-  /*!
-   * \brief Select the object created last
-    * \param theObj1 - Object 1
-    * \param theObj2 - Object 2
-    * \retval Handle(GEOM_Object) - selected object
-   */
-//=======================================================================
-
-Handle(GEOM_Object) GEOMImpl_IShapesOperations::getCreatedLast(const Handle(GEOM_Object)& theObj1,
-                                                               const Handle(GEOM_Object)& theObj2)
-{
-  if ( theObj1.IsNull() ) return theObj2;
-  if ( theObj2.IsNull() ) return theObj1;
-  return ( theObj1->GetEntry().Tag() > theObj2->GetEntry().Tag() ) ? theObj1 : theObj2;
-}
-
 //=============================================================================
 /*!
  *  GetShapesOnPlaneIDs
@@ -1450,13 +1532,12 @@ Handle(TColStd_HSequenceOfInteger) GEOMImpl_IShapesOperations::GetShapesOnPlaneI
   aSeq = getShapesOnSurfaceIDs( aPlane, aShape, aShapeType, theState );
 
   // The GetShapesOnPlaneIDs() doesn't change object so no new function is required.
-  Handle(GEOM_Function) aFunction = getCreatedLast(theShape,theAx1)->GetLastFunction();
+  Handle(GEOM_Function) aFunction = GEOM::GetCreatedLast(theShape,theAx1)->GetLastFunction();
 
   // Make a Python command
-  const bool append = true;
-  GEOM::TPythonDump(aFunction,append)
+  GEOM::TPythonDump(aFunction, /*append=*/true)
     << "listShapesOnPlane = geompy.GetShapesOnPlaneIDs"
-    << "(" << theShape << "," << theShapeType << "," << theAx1 << "," << theState << ")";
+    << "(" << theShape << "," << aShapeType << "," << theAx1 << "," << theState << ")";
 
   SetErrorCode(OK);
   return aSeq;
@@ -1497,13 +1578,12 @@ Handle(TColStd_HSequenceOfInteger) GEOMImpl_IShapesOperations::GetShapesOnCylind
   aSeq = getShapesOnSurfaceIDs( aCylinder, aShape, aShapeType, theState );
 
   // The GetShapesOnCylinder() doesn't change object so no new function is required.
-  Handle(GEOM_Function) aFunction = getCreatedLast(theShape,theAxis)->GetLastFunction();
+  Handle(GEOM_Function) aFunction = GEOM::GetCreatedLast(theShape,theAxis)->GetLastFunction();
 
   // Make a Python command
-  const bool append = true;
-  GEOM::TPythonDump(aFunction,append)
+  GEOM::TPythonDump(aFunction, /*append=*/true)
     << "listShapesOnCylinder = geompy.GetShapesOnCylinderIDs"
-    << "(" << theShape << ", " << theShapeType << ", " << theAxis << ", "
+    << "(" << theShape << ", " << aShapeType << ", " << theAxis << ", "
     << theRadius << ", " << theState << ")";
 
   SetErrorCode(OK);
@@ -1548,13 +1628,12 @@ Handle(TColStd_HSequenceOfInteger) GEOMImpl_IShapesOperations::GetShapesOnSphere
   aSeq = getShapesOnSurfaceIDs( aSphere, aShape, aShapeType, theState );
   
   // The GetShapesOnSphere() doesn't change object so no new function is required.
-  Handle(GEOM_Function) aFunction = getCreatedLast(theShape,theCenter)->GetLastFunction();
+  Handle(GEOM_Function) aFunction = GEOM::GetCreatedLast(theShape,theCenter)->GetLastFunction();
 
   // Make a Python command
-  const bool append = true;
-  GEOM::TPythonDump(aFunction,append)
+  GEOM::TPythonDump(aFunction, /*append=*/true)
     << "listShapesOnCylinder = geompy.GetShapesOnCylinderIDs"
-    << "(" << theShape << ", " << theShapeType << ", " << theCenter << ", "
+    << "(" << theShape << ", " << aShapeType << ", " << theCenter << ", "
     << theRadius << ", " << theState << ")";
 
   SetErrorCode(OK);
@@ -1736,7 +1815,7 @@ Handle(TColStd_HSequenceOfTransient)
   GEOM::TPythonDump(aFunction)
     << "[" << anAsciiList.ToCString() << "] = geompy.GetShapesOnQuadrangle("
     << theShape << ", "
-    << theShapeType << ", "
+    << TopAbs_ShapeEnum(theShapeType) << ", "
     << theTopLeftPoint << ", "
     << theTopRigthPoint << ", "
     << theBottomLeftPoint << ", "
@@ -1786,17 +1865,16 @@ Handle(TColStd_HSequenceOfInteger)
   // Make a Python command
 
   // The GetShapesOnCylinder() doesn't change object so no new function is required.
-  Handle(GEOM_Object) lastObj = getCreatedLast(theShape,theTopLeftPoint);
-  lastObj = getCreatedLast(lastObj,theTopRigthPoint);
-  lastObj = getCreatedLast(lastObj,theBottomRigthPoint);
-  lastObj = getCreatedLast(lastObj,theBottomLeftPoint);
+  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();
 
-  const bool append = true;
-  GEOM::TPythonDump(aFunction,append)
+  GEOM::TPythonDump(aFunction, /*append=*/true)
     << "listShapesOnQuadrangle = geompy.GetShapesOnQuadrangleIDs("
     << theShape << ", "
-    << theShapeType << ", "
+    << TopAbs_ShapeEnum(theShapeType) << ", "
     << theTopLeftPoint << ", "
     << theTopRigthPoint << ", "
     << theBottomLeftPoint << ", "
@@ -1813,6 +1891,87 @@ Handle(TColStd_HSequenceOfInteger)
  *  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)
@@ -1881,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;
+      }
     }
   }
 
@@ -1966,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;
@@ -2000,11 +2210,6 @@ void GEOMImpl_IShapesOperations::SortShapes(TopTools_ListOfShape& SL)
 //=======================================================================
 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");
@@ -2025,15 +2230,10 @@ bool GEOMImpl_IShapesOperations::CheckTriangulation (const TopoDS_Shape& aShape)
 
     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;
 }