]> SALOME platform Git repositories - modules/geom.git/commitdiff
Salome HOME
Some new methods implemented in BlocksOperations and in ShapesOperations; GlueFaces...
authorjfa <jfa@opencascade.com>
Fri, 24 Dec 2004 14:31:19 +0000 (14:31 +0000)
committerjfa <jfa@opencascade.com>
Fri, 24 Dec 2004 14:31:19 +0000 (14:31 +0000)
13 files changed:
idl/GEOM_Gen.idl
src/GEOMImpl/GEOMImpl_GlueDriver.cxx
src/GEOMImpl/GEOMImpl_GlueDriver.hxx
src/GEOMImpl/GEOMImpl_IBlocksOperations.cxx
src/GEOMImpl/GEOMImpl_IBlocksOperations.hxx
src/GEOMImpl/GEOMImpl_IShapesOperations.cxx
src/GEOMImpl/GEOMImpl_IShapesOperations.hxx
src/GEOM_I/GEOM_IBlocksOperations_i.cc
src/GEOM_I/GEOM_IBlocksOperations_i.hh
src/GEOM_I/GEOM_IShapesOperations_i.cc
src/GEOM_I/GEOM_IShapesOperations_i.hh
src/GEOM_SWIG/batchmode_geompy.py
src/GEOM_SWIG/geompy.py

index 63f6490501ea82950bbb3dfb40be725e2ab022a2..93020d92adb260e76409f5a155a33b9e12c03267 100644 (file)
@@ -814,6 +814,20 @@ module GEOM
                          in long        theShapeType,
                          in boolean     isSorted);
 
+    /*!
+     *  Explode a shape on subshapes of a given type.
+     *  Does the same, as the above method, but returns IDs of sub-shapes,
+     *  not GEOM_Objects. It works faster.
+     *  \param theShape Shape to be exploded.
+     *  \param theShapeType Type of sub-shapes to be retrieved.
+     *  \param isSorted If this parameter is TRUE, sub-shapes will be
+     *                  sorted by coordinates of their gravity centers.
+     *  \return List of IDs of sub-shapes of type theShapeType, contained in theShape.
+     */
+    ListOfLong SubShapeAllIDs (in GEOM_Object theShape,
+                              in long        theShapeType,
+                              in boolean     isSorted);
+
     /*!
      *  Get a sub shape defined by its unique ID inside \a theMainShape
      *  \note The sub shape GEOM_Objects can has ONLY ONE function.
@@ -842,6 +856,76 @@ module GEOM
      *  \return The reversed copy of theShape.
      */
     GEOM_Object ChangeOrientation (in GEOM_Object theShape);
+
+    /*!
+     *  Retrieve all free faces from the given shape.
+     *  Free face is a face, which is not shared between two shells of the shape.
+     *  \param theShape Shape to find free faces in.
+     *  \return List of IDs of all free faces, contained in theShape.
+     */
+    ListOfLong GetFreeFacesIDs (in GEOM_Object theShape);
+
+    /*!
+     *  Get all sub-shapes of theShape1 of the given type, shared with theShape2.
+     *  \param theShape1 Shape to find sub-shapes in.
+     *  \param theShape2 Shape to find shared sub-shapes with.
+     *  \param theShapeType Type of sub-shapes to be retrieved.
+     *  \return List of sub-shapes of theShape1, shared with theShape2.
+     */
+    ListOfGO GetSharedShapes (in GEOM_Object theShape1,
+                             in GEOM_Object theShape2,
+                             in long        theShapeType);
+
+    /*!
+     *  Get sub-shapes of theShape of the given type,
+     *  laying on the specified plane.
+     *  \param theShape Shape to find sub-shapes of.
+     *  \param theShapeType Type of sub-shapes to be retrieved.
+     *  \param thePlane Face, specifying the plane to find shapes on.
+     *  \return Group of all found sub-shapes.
+     */
+    GEOM_Object GetShapesOnPlane (in GEOM_Object theShape,
+                                 in long        theShapeType,
+                                 in GEOM_Object thePlane);
+
+    /*!
+     *  Get sub-shape of theShape of the given type,
+     *  laying on the specified cylinder.
+     *  \param theShape Shape to find sub-shapes of.
+     *  \param theShapeType Type of sub-shapes to be retrieved.
+     *  \param theAxis Vector (or line, or linear edge), specifying
+     *                 axis of the cylinder to find shapes on.
+     *  \param theRadius Radius of the cylinder to find shapes on.
+     *  \return Group of all found sub-shapes.
+     */
+    GEOM_Object GetShapesOnCylinder (in GEOM_Object theShape,
+                                    in long        theShapeType,
+                                    in GEOM_Object theAxis,
+                                    in double      theRadius);
+
+    /*!
+     *  Get sub-shape of theShape of the given type,
+     *  laying on the specified sphere.
+     *  \param theShape Shape to find sub-shapes of.
+     *  \param theShapeType Type of sub-shapes to be retrieved.
+     *  \param theCenter Point, specifying center of the sphere to find shapes on.
+     *  \param theRadius Radius of the sphere to find shapes on.
+     *  \return Group of all found sub-shapes.
+     */
+    GEOM_Object GetShapesOnSphere (in GEOM_Object theShape,
+                                  in long        theShapeType,
+                                  in GEOM_Object theCenter,
+                                  in double      theRadius);
+
+    /*!
+     *  Get sub-shape(s) of theShapeWhere, which are
+     *  coincident with \a theShapeWhat or could be a part of it.
+     *  \param theShapeWhere Shape to find sub-shapes of.
+     *  \param theShapeWhat Shape, specifying what to find.
+     *  \return Group of all found sub-shapes or a single found sub-shape.
+     */
+    GEOM_Object GetInPlace (in GEOM_Object theShapeWhere,
+                           in GEOM_Object theShapeWhat);
   };
 
   /*!
@@ -1017,10 +1101,23 @@ module GEOM
      */
     enum BCErrorType
     {
-      NOT_BLOCK,          /* Each element of the compound should be a Block */
-      INVALID_CONNECTION, /* A connection between two Blocks should be an entire face or an entire edge */
-      NOT_CONNECTED,      /* The compound should be connexe */
-      NOT_GLUED           /* The glue between two quadrangle faces should be applied */
+      /* Each element of the compound should be a Block */
+      NOT_BLOCK,
+
+      /* An element is a potential block, but has degenerated edge(s). */
+      DEGENERATED_EDGE,
+
+      /* An element is a potential block, but has seam edge(s). */
+      SEAM_EDGE,
+
+      /* A connection between two Blocks should be an entire face or an entire edge */
+      INVALID_CONNECTION,
+
+      /* The compound should be connexe */
+      NOT_CONNECTED,
+
+      /* The glue between two quadrangle faces should be applied */
+      NOT_GLUED
     };
 
     /*!
@@ -1137,6 +1234,20 @@ module GEOM
                                           in long        theDirFace1V,
                                           in long        theDirFace2V,
                                           in long        theNbTimesV);
+
+    /*!
+     *  Special operation - propagation
+     */
+
+    /*!
+     *  Build all possible propagation groups.
+     *  Propagation group is a set of all edges, opposite to one (main)
+     *  edge of this group directly or through other opposite edges.
+     *  Notion of Opposite Edge make sence only on quadrangle face.
+     *  \param theShape Shape to build propagation groups on.
+     *  \return List of GEOM_Objects, each of them is a propagation group.
+     */
+    ListOfGO Propagate (in GEOM_Object theShape);
   };
 
   /*!
index cd65a79fc71ac10499e666716f3ee531286dd314..81e330e301636a6eb7c3b6ff9350158edf615adf 100644 (file)
@@ -12,6 +12,7 @@ using namespace std;
 
 #include <TopoDS_Shape.hxx>
 #include <Standard_NullObject.hxx>
+#include <Standard_Failure.hxx>
 
 //=======================================================================
 //function : GEOMImpl_GlueDriver
@@ -31,6 +32,74 @@ const Standard_GUID& GEOMImpl_GlueDriver::GetID()
   return aGlueDriver;
 }
 
+//=======================================================================
+//function : GlueFacesWithWarnings
+//purpose  :
+//=======================================================================
+TopoDS_Shape GEOMImpl_GlueDriver::GlueFacesWithWarnings (const TopoDS_Shape& theShape,
+                                                         const Standard_Real theTolerance,
+                                                         TCollection_AsciiString& theWarning) const
+{
+  Standard_Integer iErr, iWrn;
+  TopoDS_Shape aRes;
+  GEOMAlgo_Gluer aGluer;
+
+  aGluer.SetShape(theShape);
+  aGluer.SetTolerance(theTolerance);
+  aGluer.SetCheckGeometry(Standard_True);
+
+  aGluer.Perform();
+
+  iErr = aGluer.ErrorStatus();
+  if (iErr) {
+    switch (iErr) {
+    case 2:
+      Standard_Failure::Raise("No vertices found in source shape");
+      break;
+    case 5:
+      Standard_Failure::Raise("Source shape is Null");
+      break;
+    case 6:
+      Standard_Failure::Raise("Result shape is Null");
+      break;
+    case 200:
+      Standard_Failure::Raise("Error occured during check of geometric coincidence");
+      break;
+    default:
+      {
+        // description of all errors see in GEOMAlgo_Gluer.cxx
+        TCollection_AsciiString aMsg ("Error in GEOMAlgo_Gluer with code ");
+        aMsg += TCollection_AsciiString(iErr);
+        Standard_Failure::Raise(aMsg.ToCString());
+        break;
+      }
+    }
+    return aRes;
+  }
+
+  iWrn = aGluer.WarningStatus();
+  if (iWrn) {
+    switch (iWrn) {
+    case 1:
+      {
+        Standard_Integer nbAlone = aGluer.AloneShapes();
+        theWarning = TCollection_AsciiString(nbAlone);
+        theWarning += " solids can not be glued by faces";
+      }
+      break;
+    default:
+      // description of all warnings see in GEOMAlgo_Gluer.cxx
+      theWarning = "Warning in GEOMAlgo_Gluer with code ";
+      theWarning += TCollection_AsciiString(iWrn);
+      break;
+    }
+  }
+
+  aRes = aGluer.Result();
+
+  return aRes;
+}
+
 //=======================================================================
 //function : GlueFaces
 //purpose  :
@@ -106,6 +175,7 @@ Standard_Integer GEOMImpl_GlueDriver::Execute(TFunction_Logbook& log) const
   Standard_Integer aType = aFunction->GetType();
 
   TopoDS_Shape aShape;
+  TCollection_AsciiString aWrn;
 
   if (aType == GLUE_FACES) {
     Handle(GEOM_Function) aRefBase = aCI.GetBase();
@@ -115,7 +185,7 @@ Standard_Integer GEOMImpl_GlueDriver::Execute(TFunction_Logbook& log) const
     }
 
     Standard_Real tol3d = aCI.GetTolerance();
-    aShape = GlueFaces(aShapeBase, tol3d);
+    aShape = GlueFacesWithWarnings(aShapeBase, tol3d, aWrn);
   } else {
   }
 
@@ -125,6 +195,10 @@ Standard_Integer GEOMImpl_GlueDriver::Execute(TFunction_Logbook& log) const
 
   log.SetTouched(Label());
 
+  if (!aWrn.IsEmpty()) {
+    Standard_Failure::Raise(aWrn.ToCString());
+  }
+
   return 1;
 }
 
index 489f6a11c37d82bec5cac89db546ed2767bdcb45..c8f2679cd1eeac6dbd0450eb9ced5e2b47289ff3 100644 (file)
@@ -97,6 +97,7 @@ class Handle(GEOMImpl_GlueDriver) : public Handle(TFunction_Driver) {
 #include <Standard_CString.hxx>
 #endif
 #include <TopoDS_Shape.hxx>
+#include <TCollection_AsciiString.hxx>
 
 class TColStd_SequenceOfExtendedString;
 
@@ -130,6 +131,10 @@ Standard_EXPORT ~GEOMImpl_GlueDriver() {};
 Standard_EXPORT static TopoDS_Shape GlueFaces (const TopoDS_Shape& theShape,
                                                const Standard_Real theTolerance);
 
+Standard_EXPORT TopoDS_Shape GlueFacesWithWarnings (const TopoDS_Shape& theShape,
+                                                    const Standard_Real theTolerance,
+                                                    TCollection_AsciiString& theWarning) const;
+
  // Type management
  //
 Standard_EXPORT friend Handle_Standard_Type& GEOMImpl_GlueDriver_Type_();
index 9b7aedc80d8bb867edd7ef7d32697ddf0c56c687..14b04f1739601205580e50e279f673b7a88475e4 100644 (file)
@@ -12,6 +12,11 @@ using namespace std;
 
 #include "GEOM_Function.hxx"
 
+#include "GEOMAlgo_GlueAnalyser.hxx"
+#include "GEOMAlgo_CoupleOfShapes.hxx"
+#include "GEOMAlgo_ListOfCoupleOfShapes.hxx"
+#include "GEOMAlgo_ListIteratorOfListOfCoupleOfShapes.hxx"
+
 #include "utilities.h"
 #include "OpUtil.hxx"
 #include "Utils_ExceptHandlers.hxx"
@@ -19,10 +24,13 @@ using namespace std;
 #include <TFunction_DriverTable.hxx>
 #include <TFunction_Driver.hxx>
 #include <TFunction_Logbook.hxx>
+#include <TDataStd_Integer.hxx>
 #include <TDF_Tool.hxx>
 
 #include <BRep_Tool.hxx>
+#include <BRep_Builder.hxx>
 #include <BRepTools.hxx>
+#include <BRepTools_WireExplorer.hxx>
 #include <BRepGProp.hxx>
 #include <BRepBndLib.hxx>
 #include <BRepAdaptor_Surface.hxx>
@@ -34,23 +42,33 @@ using namespace std;
 #include <TopoDS.hxx>
 #include <TopoDS_Edge.hxx>
 #include <TopoDS_Vertex.hxx>
+#include <TopoDS_Compound.hxx>
 #include <TopoDS_Iterator.hxx>
 #include <TopExp.hxx>
 #include <TopExp_Explorer.hxx>
 #include <TopTools_MapOfShape.hxx>
 #include <TopTools_Array1OfShape.hxx>
 #include <TopTools_IndexedMapOfShape.hxx>
+#include <TopTools_DataMapOfShapeInteger.hxx>
 #include <TopTools_ListIteratorOfListOfShape.hxx>
 #include <TopTools_IndexedDataMapOfShapeListOfShape.hxx>
+#include <TopTools_DataMapIteratorOfDataMapOfShapeInteger.hxx>
 
 #include <Bnd_Box.hxx>
-#include <Precision.hxx>
 #include <GProp_GProps.hxx>
+
+#include <Geom_Surface.hxx>
+#include <ShapeAnalysis_Surface.hxx>
+
 #include <TColStd_MapOfInteger.hxx>
 #include <TColStd_Array1OfReal.hxx>
 #include <TColStd_Array1OfInteger.hxx>
 #include <TColStd_Array2OfInteger.hxx>
 
+//#include <OSD_Timer.hxx>
+
+#include <Precision.hxx>
+
 #include <Standard_ErrorHandler.hxx> // CAREFUL ! position of this file is critic : see Lucien PIGNOLONI / OCC
 
 //=============================================================================
@@ -1214,6 +1232,9 @@ Handle(GEOM_Object) GEOMImpl_IBlocksOperations::GetFaceNearPoint
                                                 (Handle(GEOM_Object) theShape,
                                                  Handle(GEOM_Object) thePoint)
 {
+//  OSD_Timer timer1, timer2, timer3, timer4, timer5;
+//  timer1.Start();
+
   SetErrorCode(KO);
 
   //New object
@@ -1250,51 +1271,66 @@ Handle(GEOM_Object) GEOMImpl_IBlocksOperations::GetFaceNearPoint
 
     TopoDS_Vertex aVert = TopoDS::Vertex(anArg);
     gp_Pnt aPnt = BRep_Tool::Pnt(aVert);
+    Standard_Real PX, PY, PZ;
+    aPnt.Coord(PX, PY, PZ);
 
-    // 1. Explode blocks on faces
-    TopTools_MapOfShape mapShape;
-    Standard_Integer nbFaces = 0;
+//    timer1.Stop();
+//    timer2.Start();
+
+    // 1. Classify the point relatively each face
+    Standard_Integer nearest = 2, nbFound = 0;
+    TopTools_DataMapOfShapeInteger mapShapeDist;
     TopExp_Explorer exp (aBlockOrComp, TopAbs_FACE);
     for (; exp.More(); exp.Next()) {
-      if (mapShape.Add(exp.Current())) {
-        nbFaces++;
-      }
-    }
+      TopoDS_Shape aFace = exp.Current();
+
+      if (!mapShapeDist.IsBound(aFace)) {
+        Standard_Integer aDistance = 2;
+
+        // 1.a. Classify relatively Surface
+        Handle(Geom_Surface) aSurf = BRep_Tool::Surface(TopoDS::Face(aFace));
+        Handle(ShapeAnalysis_Surface) aSurfAna = new ShapeAnalysis_Surface (aSurf);
+        gp_Pnt2d p2dOnSurf = aSurfAna->ValueOfUV(aPnt, Precision::Confusion());
+        gp_Pnt p3dOnSurf = aSurfAna->Value(p2dOnSurf);
+        Standard_Real aDist = p3dOnSurf.Distance(aPnt);
+        if (aDist > Precision::Confusion()) {
+          // OUT of Surface
+          aDistance = 1;
+        } else {
+          // 1.b. Classify relatively the face itself
+          BRepClass_FaceClassifier FC (TopoDS::Face(aFace), p2dOnSurf, Precision::Confusion());
+          if (FC.State() == TopAbs_IN) {
+            aDistance = -1;
+          } else if (FC.State() == TopAbs_ON) {
+            aDistance = 0;
+          } else { // OUT
+            aDistance = 1;
+          }
+        }
 
-    mapShape.Clear();
-    Standard_Integer ind = 1;
-    TopTools_Array1OfShape aFaces (1, nbFaces);
-    TColStd_Array1OfInteger aDistances (1, nbFaces);
-    for (exp.Init(aBlockOrComp, TopAbs_FACE); exp.More(); exp.Next()) {
-      if (mapShape.Add(exp.Current())) {
-        TopoDS_Shape aFace = exp.Current();
-        aFaces(ind) = aFace;
-
-        // 2. Classify the point relatively each face
-        BRepClass_FaceClassifier FC (TopoDS::Face(aFace), aPnt, Precision::Confusion());
-        if (FC.State() == TopAbs_IN) {
-          aDistances(ind) = -1;
-        } else if (FC.State() == TopAbs_ON) {
-          aDistances(ind) = 0;
-        } else { // OUT
-          aDistances(ind) = 1;
+        if (aDistance < nearest) {
+          nearest = aDistance;
+          aShape = aFace;
+          nbFound = 1;
+
+          // A first found face, containing the point inside, will be returned.
+          // It is the solution, if there are no
+          // coincident or intersecting faces in the compound.
+          if (nearest == -1) break;
+
+        } else if (aDistance == nearest) {
+          nbFound++;
+        } else {
         }
-        ind++;
-      }
-    }
 
-    // 3. Define face, containing the point or having minimum distance to it
-    Standard_Integer nearest = 2, nbFound = 0;
-    for (ind = 1; ind <= nbFaces; ind++) {
-      if (aDistances(ind) < nearest) {
-        nearest = aDistances(ind);
-        aShape = aFaces(ind);
-        nbFound = 1;
-      } else if (aDistances(ind) == nearest) {
-        nbFound++;
-      } else {
-      }
+        mapShapeDist.Bind(aFace, aDistance);
+      } // if (!mapShapeDist.IsBound(aFace))
     }
+
+//    timer2.Stop();
+//    timer3.Start();
+
+    // 2. Define face, containing the point or having minimum distance to it
     if (nbFound > 1) {
       if (nearest == 0) {
         // The point is on boundary of some faces and there are
@@ -1306,40 +1342,66 @@ Handle(GEOM_Object) GEOMImpl_IBlocksOperations::GetFaceNearPoint
         // The point is outside some faces and there are
         // no faces, having the point inside or on boundary.
         // We will get a nearest face
-        Standard_Real minDist = RealLast();
-        for (ind = 1; ind <= nbFaces; ind++) {
-          if (aDistances(ind) == 1) {
-            BRepExtrema_DistShapeShape aDistTool (aVert, aFaces(ind));
-            if (!aDistTool.IsDone()) {
-              SetErrorCode("Can not find a distance from the given point to one of faces");
-              return NULL;
+        Standard_Real bigReal = RealLast();
+        Standard_Real minDist = bigReal;
+        TopTools_DataMapIteratorOfDataMapOfShapeInteger mapShapeDistIter (mapShapeDist);
+        for (; mapShapeDistIter.More(); mapShapeDistIter.Next()) {
+          if (mapShapeDistIter.Value() == 1) {
+            TopoDS_Shape aFace = mapShapeDistIter.Key();
+            Standard_Real aDist = bigReal;
+
+            // 2.a. Fast check of distance - if point projection on surface is on face
+            Handle(Geom_Surface) aSurf = BRep_Tool::Surface(TopoDS::Face(aFace));
+            Handle(ShapeAnalysis_Surface) aSurfAna = new ShapeAnalysis_Surface (aSurf);
+            gp_Pnt2d p2dOnSurf = aSurfAna->ValueOfUV(aPnt, Precision::Confusion());
+            gp_Pnt p3dOnSurf = aSurfAna->Value(p2dOnSurf);
+            aDist = p3dOnSurf.Distance(aPnt);
+
+            BRepClass_FaceClassifier FC (TopoDS::Face(aFace), p2dOnSurf, Precision::Confusion());
+            if (FC.State() == TopAbs_OUT) {
+              if (aDist < minDist) {
+                // 2.b. Slow check - if point projection on surface is outside of face
+                BRepExtrema_DistShapeShape aDistTool (aVert, aFace);
+                if (!aDistTool.IsDone()) {
+                  SetErrorCode("Can not find a distance from the given point to one of faces");
+                  return NULL;
+                }
+                aDist = aDistTool.Value();
+              } else {
+                aDist = bigReal;
+              }
             }
-            Standard_Real aDist = aDistTool.Value();
-            if (aDist < minDist) {
-              minDist = aDist;
-              aShape = aFaces(ind);
-            }
-          }
-        }
-      } else { // nearest == -1
-        // The point is inside some faces.
-        // We will get a face with nearest center
-        Standard_Real minDist = RealLast();
-        for (ind = 1; ind <= nbFaces; ind++) {
-          if (aDistances(ind) == -1) {
-            GProp_GProps aSystem;
-            BRepGProp::SurfaceProperties(aFaces(ind), aSystem);
-            gp_Pnt aCenterMass = aSystem.CentreOfMass();
 
-            Standard_Real aDist = aCenterMass.Distance(aPnt);
             if (aDist < minDist) {
               minDist = aDist;
-              aShape = aFaces(ind);
+              aShape = aFace;
             }
           }
         }
+      } else { // nearest == -1
+//        // The point is inside some faces.
+//        // We will get a face with nearest center
+//        Standard_Real minDist = RealLast();
+//        TopTools_DataMapIteratorOfDataMapOfShapeInteger mapShapeDistIter (mapShapeDist);
+//        for (; mapShapeDistIter.More(); mapShapeDistIter.Next()) {
+//          if (mapShapeDistIter.Value() == -1) {
+//            TopoDS_Shape aFace = mapShapeDistIter.Key();
+//            GProp_GProps aSystem;
+//            BRepGProp::SurfaceProperties(aFace, aSystem);
+//            gp_Pnt aCenterMass = aSystem.CentreOfMass();
+//
+//            Standard_Real aDist = aCenterMass.Distance(aPnt);
+//            if (aDist < minDist) {
+//              minDist = aDist;
+//              aShape = aFace;
+//            }
+//          }
+//        }
       }
-    }
+    } // if (nbFound > 1)
+
+//    timer3.Stop();
+//    timer4.Start();
 
     if (nbFound == 0) {
       SetErrorCode("There are no faces near the given point");
@@ -1351,6 +1413,8 @@ Handle(GEOM_Object) GEOMImpl_IBlocksOperations::GetFaceNearPoint
       anArray->SetValue(1, anIndices.FindIndex(aShape));
       aResult = GetEngine()->AddSubShape(theShape, anArray);
     }
+
+//    timer4.Stop();
   }
   catch (Standard_Failure) {
     Handle(Standard_Failure) aFail = Standard_Failure::Caught();
@@ -1358,6 +1422,8 @@ Handle(GEOM_Object) GEOMImpl_IBlocksOperations::GetFaceNearPoint
     return NULL;
   }
 
+//  timer5.Start();
+
   //The GetFaceNearPoint() doesn't change object so no new function is required.
   Handle(GEOM_Function) aFunction = theShape->GetLastFunction();
 
@@ -1375,6 +1441,16 @@ Handle(GEOM_Object) GEOMImpl_IBlocksOperations::GetFaceNearPoint
   aFunction->SetDescription(aNewDescr);
 
   SetErrorCode(OK);
+
+//  timer5.Stop();
+//
+//  cout << "Show current face times:" << endl;
+//  timer1.Show();
+//  timer2.Show();
+//  timer3.Show();
+//  timer4.Show();
+//  timer5.Show();
+
   return aResult;
 }
 
@@ -1585,7 +1661,9 @@ Standard_Boolean GEOMImpl_IBlocksOperations::IsCompoundOfBlocks
 //=============================================================================
 void AddBlocksFrom (const TopoDS_Shape&  theShape,
                     TopTools_ListOfShape& BLO,
-                    TopTools_ListOfShape& NOT)
+                    TopTools_ListOfShape& NOT,
+                    TopTools_ListOfShape& DEG,
+                    TopTools_ListOfShape& SEA)
 {
   TopAbs_ShapeEnum aType = theShape.ShapeType();
   switch (aType) {
@@ -1594,7 +1672,7 @@ void AddBlocksFrom (const TopoDS_Shape&  theShape,
     {
       TopoDS_Iterator It (theShape);
       for (; It.More(); It.Next()) {
-        AddBlocksFrom(It.Value(), BLO, NOT);
+        AddBlocksFrom(It.Value(), BLO, NOT, DEG, SEA);
       }
     }
     break;
@@ -1603,25 +1681,67 @@ void AddBlocksFrom (const TopoDS_Shape&  theShape,
       TopTools_MapOfShape mapFaces;
       TopExp_Explorer expF (theShape, TopAbs_FACE);
       Standard_Integer nbFaces = 0;
-      Standard_Integer nbEdges = 0;
+      Standard_Boolean hasNonQuadr = Standard_False;
+      Standard_Boolean hasDegenerated = Standard_False;
+      Standard_Boolean hasSeam = Standard_False;
       for (; expF.More(); expF.Next()) {
         if (mapFaces.Add(expF.Current())) {
           nbFaces++;
           if (nbFaces > 6) break;
 
           // Check number of edges in the face
+          Standard_Integer nbEdges = 0;
+          TopTools_MapOfShape mapEdges;
+
+          // get wire
           TopoDS_Shape aF = expF.Current();
-          TopExp_Explorer expE (aF, TopAbs_EDGE);
-          nbEdges = 0;
-          for (; expE.More(); expE.Next()) {
-            nbEdges++;
-            if (nbEdges > 4) break;
+          TopExp_Explorer wires (aF, TopAbs_WIRE);
+          if (!wires.More()) {
+            // no wire in the face
+            hasNonQuadr = Standard_True;
+            break;
+          }
+          TopoDS_Shape aWire = wires.Current();
+          wires.Next();
+          if (wires.More()) {
+            // multiple wires in the face
+            hasNonQuadr = Standard_True;
+            break;
+          }
+
+          // iterate on wire
+          BRepTools_WireExplorer aWE (TopoDS::Wire(aWire), TopoDS::Face(aF));
+          for (; aWE.More(); aWE.Next(), nbEdges++) {
+            if (BRep_Tool::Degenerated(aWE.Current())) {
+              // degenerated edge found
+              hasDegenerated = Standard_True;
+//              break;
+            }
+            if (mapEdges.Contains(aWE.Current())) {
+              // seam edge found
+              hasSeam = Standard_True;
+//              break;
+            }
+            mapEdges.Add(aWE.Current());
+          }
+          if (nbEdges != 4) {
+            hasNonQuadr = Standard_True;
           }
-          if (nbEdges != 4) break;
         }
       }
-      if (nbFaces == 6 && nbEdges == 4) {
-        BLO.Append(theShape);
+      if (nbFaces == 6) {
+        if (hasDegenerated || hasSeam) {
+          if (hasDegenerated) {
+            DEG.Append(theShape);
+          }
+          if (hasSeam) {
+            SEA.Append(theShape);
+          }
+        } else if (hasNonQuadr) {
+          NOT.Append(theShape);
+        } else {
+          BLO.Append(theShape);
+        }
       } else {
         NOT.Append(theShape);
       }
@@ -1649,20 +1769,13 @@ Standard_Integer BlocksRelation (const TopoDS_Shape& theBlock1,
   Bnd_Box B1, B2;
   BRepBndLib::Add(theBlock1, B1);
   BRepBndLib::Add(theBlock2, B2);
-//  BRepBndLib::AddClose(theBlock1, B1);
-//  BRepBndLib::AddClose(theBlock2, B2);
   B1.Get(Xmin1, Ymin1, Zmin1, Xmax1, Ymax1, Zmax1);
   B2.Get(Xmin2, Ymin2, Zmin2, Xmax2, Ymax2, Zmax2);
   if (Xmax2 < Xmin1 || Xmax1 < Xmin2 ||
       Ymax2 < Ymin1 || Ymax1 < Ymin2 ||
       Zmax2 < Zmin1 || Zmax1 < Zmin2) {
-//  Standard_Real prec = Precision::Confusion();
-//  if (prec < Xmin1 - Xmax2 || prec < Xmin2 - Xmax1 ||
-//      prec < Ymin1 - Ymax2 || prec < Ymin2 - Ymax1 ||
-//      prec < Zmin1 - Zmax2 || prec < Zmin2 - Zmax1) {
     return REL_NOT_CONNECTED;
   }
-  // to be done
 
   BRepExtrema_DistShapeShape dst (theBlock1, theBlock2);
   if (!dst.IsDone()) {
@@ -1863,10 +1976,10 @@ Standard_Boolean HasAnyConnection (const Standard_Integer         theBlockIndex,
 
 //=============================================================================
 /*!
- *  CheckCompoundOfBlocks
+ *  CheckCompoundOfBlocksOld
  */
 //=============================================================================
-Standard_Boolean GEOMImpl_IBlocksOperations::CheckCompoundOfBlocks
+Standard_Boolean GEOMImpl_IBlocksOperations::CheckCompoundOfBlocksOld
                                                 (Handle(GEOM_Object) theCompound,
                                                  list<BCError>&      theErrors)
 {
@@ -1883,16 +1996,40 @@ Standard_Boolean GEOMImpl_IBlocksOperations::CheckCompoundOfBlocks
 
   // 1. Report non-blocks
   TopTools_ListOfShape NOT; // Not blocks
+  TopTools_ListOfShape DEG; // Hexahedral solids, having degenerated edges
+  TopTools_ListOfShape SEA; // Hexahedral solids, having seam edges
   TopTools_ListOfShape BLO; // All blocks from the given compound
-  AddBlocksFrom(aBlockOrComp, BLO, NOT);
+  AddBlocksFrom(aBlockOrComp, BLO, NOT, DEG, SEA);
 
   if (NOT.Extent() > 0) {
     isCompOfBlocks = Standard_False;
     BCError anErr;
     anErr.error = NOT_BLOCK;
-    TopTools_ListIteratorOfListOfShape NOTit (NOT);
-    for (; NOTit.More(); NOTit.Next()) {
-      anErr.incriminated.push_back(anIndices.FindIndex(NOTit.Value()));
+    TopTools_ListIteratorOfListOfShape it (NOT);
+    for (; it.More(); it.Next()) {
+      anErr.incriminated.push_back(anIndices.FindIndex(it.Value()));
+    }
+    theErrors.push_back(anErr);
+  }
+
+  if (DEG.Extent() > 0) {
+    isCompOfBlocks = Standard_False;
+    BCError anErr;
+    anErr.error = DEGENERATED_EDGE;
+    TopTools_ListIteratorOfListOfShape it (DEG);
+    for (; it.More(); it.Next()) {
+      anErr.incriminated.push_back(anIndices.FindIndex(it.Value()));
+    }
+    theErrors.push_back(anErr);
+  }
+
+  if (SEA.Extent() > 0) {
+    isCompOfBlocks = Standard_False;
+    BCError anErr;
+    anErr.error = SEAM_EDGE;
+    TopTools_ListIteratorOfListOfShape it (SEA);
+    for (; it.More(); it.Next()) {
+      anErr.incriminated.push_back(anIndices.FindIndex(it.Value()));
     }
     theErrors.push_back(anErr);
   }
@@ -2012,6 +2149,12 @@ TCollection_AsciiString GEOMImpl_IBlocksOperations::PrintBCErrors
     case NOT_BLOCK:
       aDescr += "\nNot a Blocks: ";
       break;
+    case DEGENERATED_EDGE:
+      aDescr += "\nHexahedral solids with degenerated edges: ";
+      break;
+    case SEAM_EDGE:
+      aDescr += "\nHexahedral solids with seam edges: ";
+      break;
     case INVALID_CONNECTION:
       aDescr += "\nInvalid connection between two blocks: ";
       break;
@@ -2038,6 +2181,202 @@ TCollection_AsciiString GEOMImpl_IBlocksOperations::PrintBCErrors
   return aDescr;
 }
 
+//=============================================================================
+/*!
+ *  CheckCompoundOfBlocks
+ */
+//=============================================================================
+Standard_Boolean GEOMImpl_IBlocksOperations::CheckCompoundOfBlocks
+                                              (Handle(GEOM_Object) theCompound,
+                                               list<BCError>&      theErrors)
+{
+  SetErrorCode(KO);
+
+  if (theCompound.IsNull()) return Standard_False;
+  TopoDS_Shape aBlockOrComp = theCompound->GetValue();
+
+  Standard_Boolean isCompOfBlocks = Standard_True;
+
+  // Map sub-shapes and their indices
+  TopTools_IndexedMapOfShape anIndices;
+  TopExp::MapShapes(aBlockOrComp, anIndices);
+
+  // 1. Separate blocks from non-blocks
+  TopTools_ListOfShape NOT; // Not blocks
+  TopTools_ListOfShape DEG; // Hexahedral solids, having degenerated edges
+  TopTools_ListOfShape SEA; // Hexahedral solids, having seam edges
+  TopTools_ListOfShape BLO; // All blocks from the given compound
+  AddBlocksFrom(aBlockOrComp, BLO, NOT, DEG, SEA);
+
+  // Report non-blocks
+  if (NOT.Extent() > 0) {
+    isCompOfBlocks = Standard_False;
+    BCError anErr;
+    anErr.error = NOT_BLOCK;
+    TopTools_ListIteratorOfListOfShape it (NOT);
+    for (; it.More(); it.Next()) {
+      anErr.incriminated.push_back(anIndices.FindIndex(it.Value()));
+    }
+    theErrors.push_back(anErr);
+  }
+
+  // Report solids, having degenerated edges
+  if (DEG.Extent() > 0) {
+    isCompOfBlocks = Standard_False;
+    BCError anErr;
+    anErr.error = DEGENERATED_EDGE;
+    TopTools_ListIteratorOfListOfShape it (DEG);
+    for (; it.More(); it.Next()) {
+      anErr.incriminated.push_back(anIndices.FindIndex(it.Value()));
+    }
+    theErrors.push_back(anErr);
+  }
+
+  // Report solids, having seam edges
+  if (SEA.Extent() > 0) {
+    isCompOfBlocks = Standard_False;
+    BCError anErr;
+    anErr.error = SEAM_EDGE;
+    TopTools_ListIteratorOfListOfShape it (SEA);
+    for (; it.More(); it.Next()) {
+      anErr.incriminated.push_back(anIndices.FindIndex(it.Value()));
+    }
+    theErrors.push_back(anErr);
+  }
+
+  Standard_Integer nbBlocks = BLO.Extent();
+  if (nbBlocks == 0) {
+    isCompOfBlocks = Standard_False;
+    SetErrorCode(OK);
+    return isCompOfBlocks;
+  }
+  if (nbBlocks == 1) {
+    SetErrorCode(OK);
+    return isCompOfBlocks;
+  }
+
+  // Prepare data for 2. and 3.
+  TColStd_Array2OfInteger aRelations (1, nbBlocks, 1, nbBlocks);
+  aRelations.Init(REL_NOT_CONNECTED);
+
+  TopTools_IndexedMapOfShape mapBlocks;
+
+  BRep_Builder BB;
+  TopoDS_Compound aComp;
+  BB.MakeCompound(aComp);
+
+  TopTools_ListIteratorOfListOfShape BLOit (BLO);
+  for (; BLOit.More(); BLOit.Next()) {
+    mapBlocks.Add(BLOit.Value());
+    BB.Add(aComp, BLOit.Value());
+  }
+
+  // 2. Find glued blocks (having shared faces)
+  TopTools_IndexedDataMapOfShapeListOfShape mapFaceBlocks;
+  GEOMImpl_Block6Explorer::MapShapesAndAncestors
+    (aComp, TopAbs_FACE, TopAbs_SOLID, mapFaceBlocks);
+
+  Standard_Integer prevInd = 0, curInd = 0;
+  Standard_Integer ind = 1, nbFaces = mapFaceBlocks.Extent();
+  for (; ind <= nbFaces; ind++) {
+    const TopTools_ListOfShape& aGluedBlocks = mapFaceBlocks.FindFromIndex(ind);
+    if (aGluedBlocks.Extent() > 1) { // Shared face found
+      TopTools_ListIteratorOfListOfShape aGluedBlocksIt (aGluedBlocks);
+      TopoDS_Shape prevBlock, curBlock;
+      for (; aGluedBlocksIt.More(); aGluedBlocksIt.Next()) {
+        curBlock = aGluedBlocksIt.Value();
+        if (!prevBlock.IsNull()) {
+          prevInd = mapBlocks.FindIndex(prevBlock);
+          curInd  = mapBlocks.FindIndex(curBlock);
+          aRelations.SetValue(prevInd, curInd, REL_OK);
+          aRelations.SetValue(curInd, prevInd, REL_OK);
+        }
+        prevBlock = curBlock;
+      }
+    }
+  }
+
+  // 3. Find not glued blocks
+  GEOMAlgo_GlueAnalyser aGD; 
+
+  aGD.SetShape(aComp);
+  aGD.SetTolerance(Precision::Confusion());
+  aGD.SetCheckGeometry(Standard_True);
+  aGD.Perform();
+
+  Standard_Integer iErr, iWrn;
+  iErr = aGD.ErrorStatus();
+  if (iErr) {
+    SetErrorCode("Error in GEOMAlgo_GlueAnalyser");
+    return isCompOfBlocks;
+  }
+  iWrn = aGD.WarningStatus();
+  if (iWrn) {
+    MESSAGE("Warning in GEOMAlgo_GlueAnalyser");
+  }
+
+  // Report not glued blocks
+  if (aGD.HasSolidsToGlue()) {
+    isCompOfBlocks = Standard_False;
+    Standard_Integer aSx1Ind, aSx2Ind;
+
+    const GEOMAlgo_ListOfCoupleOfShapes& aLCS = aGD.SolidsToGlue();
+    GEOMAlgo_ListIteratorOfListOfCoupleOfShapes aItCS (aLCS);
+    for (; aItCS.More(); aItCS.Next()) {
+      const GEOMAlgo_CoupleOfShapes& aCS = aItCS.Value();
+      const TopoDS_Shape& aSx1 = aCS.Shape1();
+      const TopoDS_Shape& aSx2 = aCS.Shape2();
+
+      aSx1Ind = mapBlocks.FindIndex(aSx1);
+      aSx2Ind = mapBlocks.FindIndex(aSx2);
+      aRelations.SetValue(aSx1Ind, aSx2Ind, NOT_GLUED);
+      aRelations.SetValue(aSx2Ind, aSx1Ind, NOT_GLUED);
+
+      BCError anErr;
+      anErr.error = NOT_GLUED;
+      anErr.incriminated.push_back(anIndices.FindIndex(aSx1));
+      anErr.incriminated.push_back(anIndices.FindIndex(aSx2));
+      theErrors.push_back(anErr);
+    }
+  }
+
+  // 4. Find largest set of connected (good connection or not glued) blocks
+  Standard_Integer ibl = 1;
+  TColStd_MapOfInteger aProcessedMap;
+  TColStd_MapOfInteger aLargestSet;
+  TColStd_MapOfInteger aCurrentSet;
+  for (ibl = 1; ibl <= nbBlocks; ibl++) {
+    if (!aProcessedMap.Contains(ibl)) {
+      FindConnected(ibl, aRelations, aProcessedMap, aCurrentSet);
+      if (aCurrentSet.Extent() > aLargestSet.Extent()) {
+        aLargestSet = aCurrentSet;
+      }
+    }
+  }
+
+  // 5. Report all blocks, isolated from <aLargestSet>
+  BCError anErr;
+  anErr.error = NOT_CONNECTED;
+  Standard_Boolean hasIsolated = Standard_False;
+  for (ibl = 1; ibl <= nbBlocks; ibl++) {
+    if (!aLargestSet.Contains(ibl)) {
+      aProcessedMap.Clear();
+      if (!HasAnyConnection(ibl, aLargestSet, aRelations, aProcessedMap)) {
+        // report connection absence
+        hasIsolated = Standard_True;
+        anErr.incriminated.push_back(anIndices.FindIndex(mapBlocks.FindKey(ibl)));
+      }
+    }
+  }
+  if (hasIsolated) {
+    isCompOfBlocks = Standard_False;
+    theErrors.push_back(anErr);
+  }
+
+  SetErrorCode(OK);
+  return isCompOfBlocks;
+}
+
 //=============================================================================
 /*!
  *  ExplodeCompoundOfBlocks
@@ -2153,70 +2492,80 @@ Handle(GEOM_Object) GEOMImpl_IBlocksOperations::GetBlockNearPoint
   }
   if (aBlockOrComp.ShapeType() != TopAbs_COMPOUND &&
       aBlockOrComp.ShapeType() != TopAbs_COMPSOLID) {
-    SetErrorCode("Shape is neither a block, nor a compound of blocks");
+    SetErrorCode("Shape to find block in is not a compound");
     return NULL;
   }
 
   TopoDS_Shape anArg = thePoint->GetValue();
   if (anArg.IsNull()) {
-    SetErrorCode("Null shape is given as argument");
+    SetErrorCode("Point is null");
     return NULL;
   }
   if (anArg.ShapeType() != TopAbs_VERTEX) {
-    SetErrorCode("Element for block identification is not a vertex");
+    SetErrorCode("Shape for block identification is not a vertex");
     return NULL;
   }
 
   //Compute the Block value
   try {
     TopoDS_Shape aShape;
+
     TopoDS_Vertex aVert = TopoDS::Vertex(anArg);
     gp_Pnt aPnt = BRep_Tool::Pnt(aVert);
+    Standard_Real PX, PY, PZ;
+    aPnt.Coord(PX, PY, PZ);
 
-    // 1. Explode compound on blocks
-    TopTools_MapOfShape mapShape;
-    Standard_Integer nbSolids = 0;
+    // 1. Classify the point relatively each block
+    Standard_Integer nearest = 2, nbFound = 0;
+    TopTools_DataMapOfShapeInteger mapShapeDist;
     TopExp_Explorer exp (aBlockOrComp, TopAbs_SOLID);
     for (; exp.More(); exp.Next()) {
-      if (mapShape.Add(exp.Current())) {
-        nbSolids++;
-      }
-    }
+      TopoDS_Shape aSolid = exp.Current();
+
+      if (!mapShapeDist.IsBound(aSolid)) {
+        Standard_Integer aDistance = 2;
+
+        // 1.a. Classify relatively Bounding box
+        Standard_Real Xmin, Ymin, Zmin, Xmax, Ymax, Zmax;
+        Bnd_Box BB;
+        BRepBndLib::Add(aSolid, BB);
+        BB.Get(Xmin, Ymin, Zmin, Xmax, Ymax, Zmax);
+        if (PX < Xmin || Xmax < PX ||
+            PY < Ymin || Ymax < PY ||
+            PZ < Zmin || Zmax < PZ) {
+          // OUT of bounding box
+          aDistance = 1;
+        } else {
+          // 1.b. Classify relatively the solid itself
+          BRepClass3d_SolidClassifier SC (aSolid, aPnt, Precision::Confusion());
+          if (SC.State() == TopAbs_IN) {
+            aDistance = -1;
+          } else if (SC.State() == TopAbs_ON) {
+            aDistance = 0;
+          } else { // OUT
+            aDistance = 1;
+          }
+        }
 
-    mapShape.Clear();
-    Standard_Integer ind = 1;
-    TopTools_Array1OfShape aSolids (1, nbSolids);
-    TColStd_Array1OfInteger aDistances (1, nbSolids);
-    for (exp.Init(aBlockOrComp, TopAbs_SOLID); exp.More(); exp.Next()) {
-      if (mapShape.Add(exp.Current())) {
-        TopoDS_Shape aSolid = exp.Current();
-        aSolids(ind) = aSolid;
+        if (aDistance < nearest) {
+          nearest = aDistance;
+          aShape = aSolid;
+          nbFound = 1;
 
-        // 2. Classify the point relatively each block
-        BRepClass3d_SolidClassifier SC (aSolid, aPnt, Precision::Confusion());
-        if (SC.State() == TopAbs_IN) {
-          aDistances(ind) = -1;
-        } else if (SC.State() == TopAbs_ON) {
-          aDistances(ind) = 0;
-        } else { // OUT
-          aDistances(ind) = 1;
+          // A first found block, containing the point inside, will be returned.
+          // It is the solution, if there are no intersecting blocks in the compound.
+          if (nearest == -1) break;
+
+        } else if (aDistance == nearest) {
+          nbFound++;
+        } else {
         }
-        ind++;
-      }
-    }
 
-    // 3. Define block, containing the point or having minimum distance to it
-    Standard_Integer nearest = 2, nbFound = 0;
-    for (ind = 1; ind <= nbSolids; ind++) {
-      if (aDistances(ind) < nearest) {
-        nearest = aDistances(ind);
-        aShape = aSolids(ind);
-        nbFound = 1;
-      } else if (aDistances(ind) == nearest) {
-        nbFound++;
-      } else {
-      }
+        mapShapeDist.Bind(aSolid, aDistance);
+      } // if (!mapShapeDist.IsBound(aSolid))
     }
+
+    // 2. Define block, containing the point or having minimum distance to it
     if (nbFound > 1) {
       if (nearest == 0) {
         // The point is on boundary of some blocks and there are
@@ -2229,9 +2578,11 @@ Handle(GEOM_Object) GEOMImpl_IBlocksOperations::GetBlockNearPoint
         // no blocks, having the point inside or on boundary.
         // We will get a nearest block
         Standard_Real minDist = RealLast();
-        for (ind = 1; ind <= nbSolids; ind++) {
-          if (aDistances(ind) == 1) {
-            BRepExtrema_DistShapeShape aDistTool (aVert, aSolids(ind));
+        TopTools_DataMapIteratorOfDataMapOfShapeInteger mapShapeDistIter (mapShapeDist);
+        for (; mapShapeDistIter.More(); mapShapeDistIter.Next()) {
+          if (mapShapeDistIter.Value() == 1) {
+            TopoDS_Shape aSolid = mapShapeDistIter.Key();
+            BRepExtrema_DistShapeShape aDistTool (aVert, aSolid);
             if (!aDistTool.IsDone()) {
               SetErrorCode("Can not find a distance from the given point to one of blocks");
               return NULL;
@@ -2239,29 +2590,31 @@ Handle(GEOM_Object) GEOMImpl_IBlocksOperations::GetBlockNearPoint
             Standard_Real aDist = aDistTool.Value();
             if (aDist < minDist) {
               minDist = aDist;
-              aShape = aSolids(ind);
+              aShape = aSolid;
             }
           }
         }
       } else { // nearest == -1
-        // The point is inside some blocks.
-        // We will get a block with nearest center
-        Standard_Real minDist = RealLast();
-        for (ind = 1; ind <= nbSolids; ind++) {
-          if (aDistances(ind) == -1) {
-            GProp_GProps aSystem;
-            BRepGProp::VolumeProperties(aSolids(ind), aSystem);
-            gp_Pnt aCenterMass = aSystem.CentreOfMass();
-
-            Standard_Real aDist = aCenterMass.Distance(aPnt);
-            if (aDist < minDist) {
-              minDist = aDist;
-              aShape = aSolids(ind);
-            }
-          }
-        }
+//        // The point is inside some blocks.
+//        // We will get a block with nearest center
+//        Standard_Real minDist = RealLast();
+//        TopTools_DataMapIteratorOfDataMapOfShapeInteger mapShapeDistIter (mapShapeDist);
+//        for (; mapShapeDistIter.More(); mapShapeDistIter.Next()) {
+//          if (mapShapeDistIter.Value() == -1) {
+//            TopoDS_Shape aSolid = mapShapeDistIter.Key();
+//            GProp_GProps aSystem;
+//            BRepGProp::VolumeProperties(aSolid, aSystem);
+//            gp_Pnt aCenterMass = aSystem.CentreOfMass();
+//
+//            Standard_Real aDist = aCenterMass.Distance(aPnt);
+//            if (aDist < minDist) {
+//              minDist = aDist;
+//              aShape = aSolid;
+//            }
+//          }
+//        }
       }
-    }
+    } // if (nbFound > 1)
 
     if (nbFound == 0) {
       SetErrorCode("There are no blocks near the given point");
@@ -2692,3 +3045,139 @@ Handle(GEOM_Object) GEOMImpl_IBlocksOperations::MakeMultiTransformation2D
   SetErrorCode(OK);
   return aCopy;
 }
+
+//=============================================================================
+/*!
+ *  Propagate
+ */
+//=============================================================================
+Handle(TColStd_HSequenceOfTransient) GEOMImpl_IBlocksOperations::Propagate
+                                                 (Handle(GEOM_Object) theShape)
+{
+  SetErrorCode(KO);
+
+  if (theShape.IsNull()) return NULL;
+
+  TopoDS_Shape aShape = theShape->GetValue();
+  if (aShape.IsNull()) return NULL;
+
+  TopTools_IndexedMapOfShape anIndices;
+  TopExp::MapShapes(aShape, anIndices);
+
+  TopTools_IndexedDataMapOfShapeListOfShape MEW;
+  GEOMImpl_Block6Explorer::MapShapesAndAncestors
+    (aShape, TopAbs_EDGE, TopAbs_WIRE, MEW);
+  Standard_Integer ie, nbEdges = MEW.Extent();
+
+  // Result
+  Handle(TColStd_HSequenceOfTransient) aSeq = new TColStd_HSequenceOfTransient;
+
+  TopTools_MapOfShape mapAcceptedEdges;
+
+  for (ie = 1; ie <= nbEdges; ie++) {
+    TopoDS_Shape curE = MEW.FindKey(ie);
+
+    if (mapAcceptedEdges.Contains(curE)) continue;
+
+    // Build the chain
+    TopTools_ListOfShape currentChain;
+    TopTools_ListOfShape listPrevEdges;
+
+    currentChain.Append(curE);
+    listPrevEdges.Append(curE);
+    mapAcceptedEdges.Add(curE);
+
+    // Collect all edges pass by pass
+    while (listPrevEdges.Extent() > 0) {
+      // List of edges, added to chain on this cycle pass
+      TopTools_ListOfShape listCurEdges;
+
+      // Find the next portion of edges
+      TopTools_ListIteratorOfListOfShape itE (listPrevEdges);
+      for (; itE.More(); itE.Next()) {
+        TopoDS_Shape anE = itE.Value();
+
+        // Iterate on faces, having edge <anE>
+        TopTools_ListIteratorOfListOfShape itW (MEW.FindFromKey(anE));
+        for (; itW.More(); itW.Next()) {
+          TopoDS_Shape aW = itW.Value();
+          TopoDS_Shape anOppE;
+
+          BRepTools_WireExplorer aWE (TopoDS::Wire(aW));
+          Standard_Integer nb = 1, found = 0;
+          TopTools_Array1OfShape anEdges (1,4);
+          for (; aWE.More(); aWE.Next(), nb++) {
+            if (nb > 4) {
+              found = 0;
+              break;
+            }
+            anEdges(nb) = aWE.Current();
+            if (anEdges(nb).IsSame(anE)) found = nb;
+          }
+
+          if (nb == 5 && found > 0) {
+            // Quadrangle face found, get an opposite edge
+            Standard_Integer opp = found + 2;
+            if (opp > 4) opp -= 4;
+            anOppE = anEdges(opp);
+
+            if (!mapAcceptedEdges.Contains(anOppE)) {
+              // Add found edge to the chain
+              currentChain.Append(anOppE);
+              listCurEdges.Append(anOppE);
+              mapAcceptedEdges.Add(anOppE);
+            }
+          } // if (nb == 5 && found > 0)
+        } // for (; itF.More(); itF.Next())
+      } // for (; itE.More(); itE.Next())
+
+      listPrevEdges = listCurEdges;
+    } // while (listPrevEdges.Extent() > 0)
+
+    // Store the chain in the document
+    Handle(TColStd_HArray1OfInteger) anArray =
+      new TColStd_HArray1OfInteger (1, currentChain.Extent());
+
+    // Fill array of sub-shape indices
+    TopTools_ListIteratorOfListOfShape itSub (currentChain);
+    for (int index = 1; itSub.More(); itSub.Next(), ++index) {
+      int id = anIndices.FindIndex(itSub.Value());
+      anArray->SetValue(index, id);
+    }
+
+    // Add a new group object
+    Handle(GEOM_Object) aChain = GetEngine()->AddSubShape(theShape, anArray);
+
+    // Set a GROUP type
+    aChain->SetType(GEOM_GROUP);
+
+    // Set a sub shape type
+    TDF_Label aFreeLabel = aChain->GetFreeLabel();
+    TDataStd_Integer::Set(aFreeLabel, (Standard_Integer)TopAbs_EDGE);
+
+    // Add the chain to the result
+    aSeq->Append(aChain);
+  }
+
+  if (aSeq->IsEmpty()) {
+    SetErrorCode("There are no quadrangle faces in the shape");
+    return aSeq;
+  }
+
+  // The Propagation doesn't change object so no new function is required.
+  Handle(GEOM_Function) aFunction = theShape->GetLastFunction();
+
+  // Make a Python command
+  TCollection_AsciiString aDescr
+    ("\nlistPropagationChains = IShapesOperations.Propagate(");
+  TCollection_AsciiString anEntry;
+  TDF_Tool::Entry(theShape->GetEntry(), anEntry);
+  aDescr += (anEntry + ")");
+
+  TCollection_AsciiString anOldDescr = aFunction->GetDescription();
+  anOldDescr = anOldDescr + aDescr;
+  aFunction->SetDescription(anOldDescr);
+
+  SetErrorCode(OK);
+  return aSeq;
+}
index 1ea16a0539ea67409cea8186e7e2e9074ce7c339..72742f6a60c48ff5c15bf1c8128cc65c02d0a830 100644 (file)
@@ -85,6 +85,8 @@ class GEOMImpl_IBlocksOperations : public GEOM_IOperations {
 
   enum BCErrorType {
     NOT_BLOCK,
+    DEGENERATED_EDGE,
+    SEAM_EDGE,
     INVALID_CONNECTION,
     NOT_CONNECTED,
     NOT_GLUED
@@ -95,6 +97,9 @@ class GEOMImpl_IBlocksOperations : public GEOM_IOperations {
     list<int>   incriminated;
   };
 
+  Standard_Boolean CheckCompoundOfBlocksOld (Handle(GEOM_Object) theCompound,
+                                             list<BCError>&      theErrors);
+
   Standard_Boolean CheckCompoundOfBlocks (Handle(GEOM_Object) theCompound,
                                           list<BCError>&      theErrors);
 
@@ -131,6 +136,9 @@ class GEOMImpl_IBlocksOperations : public GEOM_IOperations {
                                                  const Standard_Integer theDirFace1V,
                                                  const Standard_Integer theDirFace2V,
                                                  const Standard_Integer theNbTimesV);
+
+  // Build groups for Propagation of 1D hypotheses
+  Handle(TColStd_HSequenceOfTransient) Propagate (Handle(GEOM_Object) theShape);
 };
 
 #endif
index ee637328b3dc62bff205353889f668a4651a2ddd..0eac538b59a106a850dee67622ead31a2a5ff76e 100644 (file)
@@ -13,6 +13,8 @@ using namespace std;
 #include "GEOMImpl_IShapes.hxx"
 #include "GEOMImpl_IGlue.hxx"
 
+#include "GEOMImpl_Block6Explorer.hxx"
+
 #include "GEOM_Function.hxx"
 
 #include "utilities.h"
@@ -22,6 +24,7 @@ using namespace std;
 #include <TFunction_DriverTable.hxx>
 #include <TFunction_Driver.hxx>
 #include <TFunction_Logbook.hxx>
+#include <TDataStd_Integer.hxx>
 #include <TDF_Tool.hxx>
 
 #include <BRep_Tool.hxx>
@@ -31,6 +34,9 @@ using namespace std;
 #include <TopExp.hxx>
 #include <TopoDS.hxx>
 #include <TopoDS_Shape.hxx>
+#include <TopoDS_Face.hxx>
+#include <TopoDS_Edge.hxx>
+#include <TopoDS_Vertex.hxx>
 #include <TopoDS_Iterator.hxx>
 #include <TopExp_Explorer.hxx>
 #include <TopTools_MapOfShape.hxx>
@@ -38,11 +44,19 @@ using namespace std;
 #include <TopTools_ListIteratorOfListOfShape.hxx>
 #include <TopTools_IndexedMapOfShape.hxx>
 
+#include <Geom_Surface.hxx>
+#include <Geom_Plane.hxx>
+#include <Geom_SphericalSurface.hxx>
+#include <Geom_CylindricalSurface.hxx>
+
 #include <GProp_GProps.hxx>
 #include <gp_Pnt.hxx>
+#include <gp_Lin.hxx>
 #include <TColStd_Array1OfReal.hxx>
 #include <TColStd_HArray1OfInteger.hxx>
 
+//#include <OSD_Timer.hxx>
+
 #include <Standard_ErrorHandler.hxx> // CAREFUL ! position of this file is critic : see Lucien PIGNOLONI / OCC
 
 //=============================================================================
@@ -207,7 +221,8 @@ Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeFace (Handle(GEOM_Object) th
  */
 //=============================================================================
 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeFaceWires
-                      (list<Handle(GEOM_Object)> theShapes, bool isPlanarWanted)
+                             (list<Handle(GEOM_Object)> theShapes,
+                              const bool isPlanarWanted)
 {
   SetErrorCode(KO);
 
@@ -482,6 +497,7 @@ Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeGlueFaces
   aCI.SetTolerance(theTolerance);
 
   //Compute the sub-shape value
+  Standard_Boolean isWarning = Standard_False;
   try {
     if (!GetSolver()->ComputeFunction(aFunction)) {
       SetErrorCode("Shape driver failed to glue faces");
@@ -491,7 +507,12 @@ Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeGlueFaces
   catch (Standard_Failure) {
     Handle(Standard_Failure) aFail = Standard_Failure::Caught();
     SetErrorCode(aFail->GetMessageString());
-    return NULL;
+    // to provide warning
+    if (!aFunction->GetValue().IsNull()) {
+      isWarning = Standard_True;
+    } else {
+      return NULL;
+    }
   }
 
   //Make a Python command
@@ -505,6 +526,8 @@ Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeGlueFaces
 
   aFunction->SetDescription(aDescr);
 
+  // to provide warning
+  if (!isWarning) SetErrorCode(OK);
   SetErrorCode(OK);
   return aGlued;
 }
@@ -519,6 +542,9 @@ Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::MakeExplode
                                            const Standard_Integer theShapeType,
                                            const Standard_Boolean isSorted)
 {
+//  OSD_Timer timer1, timer2, timer3, timer4;
+//  timer1.Start();
+
   SetErrorCode(KO);
 
   if (theShape.IsNull()) return NULL;
@@ -556,9 +582,15 @@ Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::MakeExplode
     return aSeq;
   }
 
+//  timer1.Stop();
+//  timer2.Start();
+
   if (isSorted)
     SortShapes(listShape);
 
+//  timer2.Stop();
+//  timer3.Start();
+
   TopTools_IndexedMapOfShape anIndices;
   TopExp::MapShapes(aShape, anIndices);
   Handle(TColStd_HArray1OfInteger) anArray;
@@ -577,6 +609,9 @@ Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::MakeExplode
     anAsciiList += ",";
   }
 
+//  timer3.Stop();
+//  timer4.Start();
+
   anAsciiList.Trunc(anAsciiList.Length() - 1);
   anAsciiList += "]";
 
@@ -601,6 +636,97 @@ Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::MakeExplode
 
   SetErrorCode(OK);
 
+//  timer4.Stop();
+
+//  cout << "Explosure takes:" << endl;
+//  timer1.Show();
+//  cout << "Sorting takes:" << endl;
+//  timer2.Show();
+//  cout << "Sub-shapes addition takes:" << endl;
+//  timer3.Show();
+//  cout << "Update Description takes:" << endl;
+//  timer4.Show();
+
+  return aSeq;
+}
+
+//=============================================================================
+/*!
+ *  GetSubShapeAllIDs
+ */
+//=============================================================================
+Handle(TColStd_HSequenceOfInteger) GEOMImpl_IShapesOperations::SubShapeAllIDs
+                                          (Handle(GEOM_Object)    theShape,
+                                           const Standard_Integer theShapeType,
+                                           const Standard_Boolean isSorted)
+{
+  SetErrorCode(KO);
+
+  if (theShape.IsNull()) return NULL;
+  TopoDS_Shape aShape = theShape->GetValue();
+  if (aShape.IsNull()) return NULL;
+
+  Handle(TColStd_HSequenceOfInteger) aSeq = new TColStd_HSequenceOfInteger;
+  TopTools_MapOfShape mapShape;
+  TopTools_ListOfShape listShape;
+
+  if (aShape.ShapeType() == TopAbs_COMPOUND &&
+      (TopAbs_ShapeEnum(theShapeType) == TopAbs_SHAPE ||
+       TopAbs_ShapeEnum(theShapeType) == TopAbs_COMPSOLID ||
+       TopAbs_ShapeEnum(theShapeType) == TopAbs_COMPOUND)) {
+    TopoDS_Iterator It (aShape, Standard_True, Standard_True);
+    for (; It.More(); It.Next()) {
+      if (mapShape.Add(It.Value())) {
+        if (TopAbs_ShapeEnum(theShapeType) == TopAbs_SHAPE ||
+            TopAbs_ShapeEnum(theShapeType) == It.Value().ShapeType()) {
+          listShape.Append(It.Value());
+        }
+      }
+    }
+  } else {
+    TopExp_Explorer exp (aShape, TopAbs_ShapeEnum(theShapeType));
+    for (; exp.More(); exp.Next())
+      if (mapShape.Add(exp.Current()))
+       listShape.Append(exp.Current());
+  }
+
+  if (listShape.IsEmpty()) {
+    SetErrorCode("The given shape has no sub-shapes of the requested type");
+    return aSeq;
+  }
+
+  if (isSorted)
+    SortShapes(listShape);
+
+  TopTools_IndexedMapOfShape anIndices;
+  TopExp::MapShapes(aShape, anIndices);
+  Handle(TColStd_HArray1OfInteger) anArray;
+
+  TopTools_ListIteratorOfListOfShape itSub (listShape);
+  for (int index = 1; itSub.More(); itSub.Next(), ++index) {
+    TopoDS_Shape aValue = itSub.Value();
+    aSeq->Append(anIndices.FindIndex(aValue));
+  }
+
+  //The explode doesn't change object so no new function is required.
+  Handle(GEOM_Function) aFunction = theShape->GetLastFunction();
+
+  //Make a Python command
+  TCollection_AsciiString aDescr
+    ("\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);
+
+  SetErrorCode(OK);
   return aSeq;
 }
 
@@ -754,6 +880,575 @@ Handle(GEOM_Object) GEOMImpl_IShapesOperations::ReverseShape(Handle(GEOM_Object)
   return aReversed;
 }
 
+//=============================================================================
+/*!
+ *  GetFreeFacesIDs
+ */
+//=============================================================================
+Handle(TColStd_HSequenceOfInteger) GEOMImpl_IShapesOperations::GetFreeFacesIDs
+                                                 (Handle(GEOM_Object) theShape)
+{
+  SetErrorCode(KO);
+
+  if (theShape.IsNull()) return NULL;
+  TopoDS_Shape aShape = theShape->GetValue();
+  if (aShape.IsNull()) return NULL;
+
+  Handle(TColStd_HSequenceOfInteger) aSeq = new TColStd_HSequenceOfInteger;
+
+  TopTools_IndexedDataMapOfShapeListOfShape mapFaceBlocks;
+  GEOMImpl_Block6Explorer::MapShapesAndAncestors
+    (aShape, TopAbs_FACE, TopAbs_SOLID, mapFaceBlocks);
+
+  Standard_Integer ind = 1, nbFaces = mapFaceBlocks.Extent();
+
+  if (nbFaces == 0) {
+    SetErrorCode("The given shape has no faces");
+    return aSeq;
+  }
+
+  TopTools_IndexedMapOfShape anIndices;
+  TopExp::MapShapes(aShape, anIndices);
+
+  Standard_Integer id;
+  for (; ind <= nbFaces; ind++) {
+    if (mapFaceBlocks.FindFromIndex(ind).Extent() != 2) {
+      id = anIndices.FindIndex(mapFaceBlocks.FindKey(ind));
+      aSeq->Append(id);
+    }
+  }
+
+  //The explode doesn't change object so no new function is required.
+  Handle(GEOM_Function) aFunction = theShape->GetLastFunction();
+
+  //Make a Python command
+  TCollection_AsciiString aDescr ("\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);
+
+  SetErrorCode(OK);
+  return aSeq;
+}
+
+//=============================================================================
+/*!
+ *  GetSharedShapes
+ */
+//=============================================================================
+Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::GetSharedShapes
+                                                (Handle(GEOM_Object)    theShape1,
+                                                 Handle(GEOM_Object)    theShape2,
+                                                 const Standard_Integer theShapeType)
+{
+  SetErrorCode(KO);
+
+  if (theShape1.IsNull() || theShape2.IsNull()) return NULL;
+
+  TopoDS_Shape aShape1 = theShape1->GetValue();
+  TopoDS_Shape aShape2 = theShape2->GetValue();
+
+  if (aShape1.IsNull() || aShape2.IsNull()) return NULL;
+
+  TopTools_IndexedMapOfShape anIndices;
+  TopExp::MapShapes(aShape1, anIndices);
+  Handle(TColStd_HArray1OfInteger) anArray;
+
+  TopTools_IndexedMapOfShape mapShape1;
+  TopExp::MapShapes(aShape1, TopAbs_ShapeEnum(theShapeType), mapShape1);
+
+  Handle(GEOM_Object) anObj;
+  Handle(TColStd_HSequenceOfTransient) aSeq = new TColStd_HSequenceOfTransient;
+
+  TopTools_MapOfShape mapShape2;
+  TopExp_Explorer exp (aShape2, TopAbs_ShapeEnum(theShapeType));
+  for (; exp.More(); exp.Next()) {
+    TopoDS_Shape aSS = exp.Current();
+    if (mapShape2.Add(aSS) && mapShape1.Contains(aSS)) {
+      anArray = new TColStd_HArray1OfInteger(1,1);
+      anArray->SetValue(1, anIndices.FindIndex(aSS));
+      anObj = GetEngine()->AddSubShape(theShape1, anArray);
+      aSeq->Append(anObj);
+    }
+  }
+
+  if (aSeq->IsEmpty()) {
+    SetErrorCode("The given shapes have no shared sub-shapes of the requested type");
+    return aSeq;
+  }
+
+  //The explode doesn't change object so no new function is required.
+  Handle(GEOM_Function) aFunction = theShape1->GetLastFunction();
+
+  //Make a Python command
+  TCollection_AsciiString aDescr
+    ("\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);
+
+  SetErrorCode(OK);
+  return aSeq;
+}
+
+//=============================================================================
+/*!
+ *  GetShapesOnPlane
+ */
+//=============================================================================
+Handle(GEOM_Object) GEOMImpl_IShapesOperations::GetShapesOnPlane
+                                          (Handle(GEOM_Object)    theShape,
+                                           const Standard_Integer theShapeType,
+                                           Handle(GEOM_Object)    thePlane)
+{
+  SetErrorCode(KO);
+
+  if (theShape.IsNull() || thePlane.IsNull()) return NULL;
+
+  TopoDS_Shape aShape = theShape->GetValue();
+  TopoDS_Shape aPlane = thePlane->GetValue();
+
+  if (aShape.IsNull() || aPlane.IsNull()) return NULL;
+
+  TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
+  if (aShapeType != TopAbs_VERTEX &&
+      aShapeType != TopAbs_EDGE &&
+      aShapeType != TopAbs_FACE) {
+    SetErrorCode("Not implemented for the given sub-shape type");
+    return NULL;
+  }
+
+  //Get plane parameters
+  if (aPlane.IsNull() || aPlane.ShapeType() != TopAbs_FACE) return NULL;
+  TopoDS_Face aFace = TopoDS::Face(aPlane);
+  Handle(Geom_Surface) surf = BRep_Tool::Surface(aFace);
+  Handle(Geom_Plane) pln = Handle(Geom_Plane)::DownCast(surf);
+  if (pln.IsNull()) {
+    SetErrorCode("Not planar face given");
+    return NULL;
+  }
+  const gp_Ax3 pos = pln->Position();
+  const gp_Pnt loc = pos.Location();
+  const gp_Dir dir = pos.Direction();
+
+  //Find sub-shapes on the plane
+  TopTools_ListOfShape listSS;
+  TopTools_MapOfShape mapShapes;
+  TopExp_Explorer exp (aShape, aShapeType);
+  for (; exp.More(); exp.Next()) {
+    TopoDS_Shape aSS = exp.Current();
+    if (mapShapes.Add(aSS)) {
+      switch (aShapeType) {
+      case TopAbs_VERTEX:
+        {
+          TopoDS_Vertex aV = TopoDS::Vertex(aSS);
+          gp_Pnt aP = BRep_Tool::Pnt(aV);
+          gp_Vec vecToLoc (aP, loc);
+          if (vecToLoc.IsNormal(dir, Precision::Angular())) {
+            listSS.Append(aSS);
+          }
+        }
+        break;
+      case TopAbs_EDGE:
+        {
+          TopoDS_Edge anE = TopoDS::Edge(aSS);
+          Standard_Real pf, pl;
+          Handle(Geom_Curve) cur_curve = BRep_Tool::Curve(anE, pf, pl);
+          if (true) {
+            listSS.Append(aSS);
+          }
+        }
+        break;
+      case TopAbs_FACE:
+        {
+          TopoDS_Face aF = TopoDS::Face(aSS);
+          Handle(Geom_Surface) cur_surf = BRep_Tool::Surface(aF);
+          Handle(Geom_Plane) cur_pln = Handle(Geom_Plane)::DownCast(cur_surf);
+          if (!cur_pln.IsNull()) {
+            const gp_Ax3 cur_pos = cur_pln->Position();
+            const gp_Pnt cur_loc = cur_pos.Location();
+            const gp_Dir cur_dir = cur_pos.Direction();
+            gp_Vec vecToLoc (cur_loc, loc);
+            if (vecToLoc.IsNormal(dir, Precision::Angular()) &&
+                cur_dir.IsParallel(dir, Precision::Angular())) {
+              listSS.Append(aSS);
+            }
+          }
+        }
+        break;
+      default:
+        break;
+      }
+    }
+  }
+
+  //Fill array of indices
+  TopTools_IndexedMapOfShape anIndices;
+  TopExp::MapShapes(aShape, anIndices);
+
+  Handle(TColStd_HArray1OfInteger) anArray =
+    new TColStd_HArray1OfInteger (1, listSS.Extent());
+  TopTools_ListIteratorOfListOfShape itSub (listSS);
+  for (int index = 1; itSub.More(); itSub.Next(), ++index) {
+    int id = anIndices.FindIndex(itSub.Value());
+    anArray->SetValue(index, id);
+  }
+  
+  //Add a new group object
+  Handle(GEOM_Object) aGroup = GetEngine()->AddSubShape(theShape, anArray);
+
+  //Set a GROUP type
+  aGroup->SetType(GEOM_GROUP);
+
+  //Set a sub shape type
+  TDF_Label aFreeLabel = aGroup->GetFreeLabel();
+  TDataStd_Integer::Set(aFreeLabel, (Standard_Integer)theShapeType);
+  //Make a Python command
+  TCollection_AsciiString anEntry, aDescr;
+  TDF_Tool::Entry(aGroup->GetEntry(), anEntry);
+  aDescr += anEntry;
+  aDescr += " = IShapesOperations.GetShapesOnPlane(";
+  TDF_Tool::Entry(theShape->GetEntry(), anEntry);
+  aDescr += anEntry + TCollection_AsciiString(theShapeType) + ",";
+  TDF_Tool::Entry(thePlane->GetEntry(), anEntry);
+  aDescr += anEntry + ")";
+
+  Handle(GEOM_Function) aFunction = aGroup->GetFunction(1);
+  aFunction->SetDescription(aDescr);
+
+  SetErrorCode(OK);
+  return aGroup;
+}
+
+//=============================================================================
+/*!
+ *  GetShapesOnCylinder
+ */
+//=============================================================================
+Handle(GEOM_Object) GEOMImpl_IShapesOperations::GetShapesOnCylinder
+                                          (Handle(GEOM_Object)    theShape,
+                                           const Standard_Integer theShapeType,
+                                           Handle(GEOM_Object)    theAxis,
+                                           const Standard_Real    theRadius)
+{
+  SetErrorCode(KO);
+
+  if (theShape.IsNull() || theAxis.IsNull()) return NULL;
+
+  TopoDS_Shape aShape = theShape->GetValue();
+  TopoDS_Shape anAxis = theAxis->GetValue();
+
+  if (aShape.IsNull() || anAxis.IsNull()) return NULL;
+
+  TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
+  if (aShapeType != TopAbs_VERTEX &&
+      aShapeType != TopAbs_EDGE &&
+      aShapeType != TopAbs_FACE) {
+    SetErrorCode("Not implemented for the given sub-shape type");
+    return NULL;
+  }
+
+  //Axis of the cylinder
+  if (anAxis.ShapeType() != TopAbs_EDGE) {
+    SetErrorCode("Not an edge given for the axis");
+    return NULL;
+  }
+  TopoDS_Edge anEdge = TopoDS::Edge(anAxis);
+  TopoDS_Vertex V1, V2;
+  TopExp::Vertices(anEdge, V1, V2, Standard_True);
+  if (V1.IsNull() || V2.IsNull()) {
+    SetErrorCode("Bad edge given for the axis");
+    return NULL;
+  }
+  gp_Pnt loc = BRep_Tool::Pnt(V1);
+  gp_Vec aVec (loc, BRep_Tool::Pnt(V2));
+  gp_Dir dir (aVec);
+  gp_Lin aLin (loc, aVec);
+
+  //Find sub-shapes on the cylinder
+  TopTools_ListOfShape listSS;
+  TopTools_MapOfShape mapShapes;
+  TopExp_Explorer exp (aShape, aShapeType);
+  for (; exp.More(); exp.Next()) {
+    TopoDS_Shape aSS = exp.Current();
+    if (mapShapes.Add(aSS)) {
+      switch (aShapeType) {
+      case TopAbs_VERTEX:
+        {
+          TopoDS_Vertex aV = TopoDS::Vertex(aSS);
+          gp_Pnt aP = BRep_Tool::Pnt(aV);
+          if (Abs(aLin.Distance(aP) - theRadius) < Precision::Confusion()) {
+            listSS.Append(aSS);
+          }
+        }
+        break;
+      case TopAbs_EDGE:
+        {
+          TopoDS_Edge anE = TopoDS::Edge(aSS);
+          Standard_Real pf, pl;
+          Handle(Geom_Curve) cur_curve = BRep_Tool::Curve(anE, pf, pl);
+          if (true) {
+            listSS.Append(aSS);
+          }
+        }
+        break;
+      case TopAbs_FACE:
+        {
+          TopoDS_Face aF = TopoDS::Face(aSS);
+          Handle(Geom_Surface) cur_surf = BRep_Tool::Surface(aF);
+          Handle(Geom_CylindricalSurface) cur_cyl =
+            Handle(Geom_CylindricalSurface)::DownCast(cur_surf);
+          if (!cur_cyl.IsNull()) {
+            const gp_Ax3 cur_pos = cur_cyl->Position();
+            const gp_Pnt cur_loc = cur_pos.Location();
+            const gp_Dir cur_dir = cur_pos.Direction();
+            const Standard_Real cur_rad = cur_cyl->Radius();
+            gp_Vec vecToLoc (cur_loc, loc);
+            if (vecToLoc.IsParallel(dir, Precision::Angular()) &&
+                cur_dir.IsParallel(dir, Precision::Angular()) &&
+                Abs(cur_rad - theRadius) < Precision::Confusion()) {
+              listSS.Append(aSS);
+            }
+          }
+        }
+        break;
+      default:
+        break;
+      }
+    }
+  }
+
+  //Fill array of indices
+  TopTools_IndexedMapOfShape anIndices;
+  TopExp::MapShapes(aShape, anIndices);
+
+  Handle(TColStd_HArray1OfInteger) anArray =
+    new TColStd_HArray1OfInteger (1, listSS.Extent());
+  TopTools_ListIteratorOfListOfShape itSub (listSS);
+  for (int index = 1; itSub.More(); itSub.Next(), ++index) {
+    int id = anIndices.FindIndex(itSub.Value());
+    anArray->SetValue(index, id);
+  }
+  
+  //Add a new group object
+  Handle(GEOM_Object) aGroup = GetEngine()->AddSubShape(theShape, anArray);
+
+  //Set a GROUP type
+  aGroup->SetType(GEOM_GROUP);
+
+  //Set a sub shape type
+  TDF_Label aFreeLabel = aGroup->GetFreeLabel();
+  TDataStd_Integer::Set(aFreeLabel, (Standard_Integer)theShapeType);
+  //Make a Python command
+  TCollection_AsciiString anEntry, aDescr;
+  TDF_Tool::Entry(aGroup->GetEntry(), anEntry);
+  aDescr += anEntry;
+  aDescr += " = IShapesOperations.GetShapesOnCylinder(";
+  TDF_Tool::Entry(theShape->GetEntry(), anEntry);
+  aDescr += anEntry + TCollection_AsciiString(theShapeType) + ",";
+  TDF_Tool::Entry(theAxis->GetEntry(), anEntry);
+  aDescr += anEntry + TCollection_AsciiString(theRadius) + ")";
+
+  Handle(GEOM_Function) aFunction = aGroup->GetFunction(1);
+  aFunction->SetDescription(aDescr);
+
+  SetErrorCode(OK);
+  return aGroup;
+}
+
+//=============================================================================
+/*!
+ *  GetShapesOnSphere
+ */
+//=============================================================================
+Handle(GEOM_Object) GEOMImpl_IShapesOperations::GetShapesOnSphere
+                                          (Handle(GEOM_Object)    theShape,
+                                           const Standard_Integer theShapeType,
+                                           Handle(GEOM_Object)    theCenter,
+                                           const Standard_Real    theRadius)
+{
+  SetErrorCode(KO);
+
+  if (theShape.IsNull() || theCenter.IsNull()) return NULL;
+
+  TopoDS_Shape aShape  = theShape->GetValue();
+  TopoDS_Shape aCenter = theCenter->GetValue();
+
+  if (aShape.IsNull() || aCenter.IsNull()) return NULL;
+
+  TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
+  if (aShapeType != TopAbs_VERTEX &&
+      aShapeType != TopAbs_EDGE &&
+      aShapeType != TopAbs_FACE) {
+    SetErrorCode("Not implemented for the given sub-shape type");
+    return NULL;
+  }
+
+  //Center of the sphere
+  if (aCenter.ShapeType() != TopAbs_VERTEX) return NULL;
+  gp_Pnt aC = BRep_Tool::Pnt(TopoDS::Vertex(aCenter));
+
+  //Find sub-shapes on the sphere
+  TopTools_ListOfShape listSS;
+  TopTools_MapOfShape mapShapes;
+  TopExp_Explorer exp (aShape, aShapeType);
+  for (; exp.More(); exp.Next()) {
+    TopoDS_Shape aSS = exp.Current();
+    if (mapShapes.Add(aSS)) {
+      switch (aShapeType) {
+      case TopAbs_VERTEX:
+        {
+          TopoDS_Vertex aV = TopoDS::Vertex(aSS);
+          gp_Pnt aP = BRep_Tool::Pnt(aV);
+          if (Abs(aP.Distance(aC) - theRadius) < Precision::Confusion()) {
+            listSS.Append(aSS);
+          }
+        }
+        break;
+      case TopAbs_EDGE:
+        {
+          TopoDS_Edge anE = TopoDS::Edge(aSS);
+          Standard_Real pf, pl;
+          Handle(Geom_Curve) cur_curve = BRep_Tool::Curve(anE, pf, pl);
+          if (true) {
+            listSS.Append(aSS);
+          }
+        }
+        break;
+      case TopAbs_FACE:
+        {
+          TopoDS_Face aF = TopoDS::Face(aSS);
+          Handle(Geom_Surface) cur_surf = BRep_Tool::Surface(aF);
+          Handle(Geom_SphericalSurface) cur_sph =
+            Handle(Geom_SphericalSurface)::DownCast(cur_surf);
+          if (!cur_sph.IsNull()) {
+            const gp_Ax3 cur_pos = cur_sph->Position();
+            const gp_Pnt cur_loc = cur_pos.Location();
+            const Standard_Real cur_rad = cur_sph->Radius();
+            if (cur_loc.Distance(aC) < Precision::Confusion() &&
+                Abs(cur_rad - theRadius) < Precision::Confusion()) {
+              listSS.Append(aSS);
+            }
+          }
+        }
+        break;
+      default:
+        break;
+      }
+    }
+  }
+
+  //Fill array of indices
+  TopTools_IndexedMapOfShape anIndices;
+  TopExp::MapShapes(aShape, anIndices);
+
+  Handle(TColStd_HArray1OfInteger) anArray =
+    new TColStd_HArray1OfInteger (1, listSS.Extent());
+  TopTools_ListIteratorOfListOfShape itSub (listSS);
+  for (int index = 1; itSub.More(); itSub.Next(), ++index) {
+    int id = anIndices.FindIndex(itSub.Value());
+    anArray->SetValue(index, id);
+  }
+  
+  //Add a new group object
+  Handle(GEOM_Object) aGroup = GetEngine()->AddSubShape(theShape, anArray);
+
+  //Set a GROUP type
+  aGroup->SetType(GEOM_GROUP);
+
+  //Set a sub shape type
+  TDF_Label aFreeLabel = aGroup->GetFreeLabel();
+  TDataStd_Integer::Set(aFreeLabel, (Standard_Integer)theShapeType);
+  //Make a Python command
+  TCollection_AsciiString anEntry, aDescr;
+  TDF_Tool::Entry(aGroup->GetEntry(), anEntry);
+  aDescr += anEntry;
+  aDescr += " = IShapesOperations.GetShapesOnSphere(";
+  TDF_Tool::Entry(theShape->GetEntry(), anEntry);
+  aDescr += anEntry + TCollection_AsciiString(theShapeType) + ",";
+  TDF_Tool::Entry(theCenter->GetEntry(), anEntry);
+  aDescr += anEntry + TCollection_AsciiString(theRadius) + ")";
+
+  Handle(GEOM_Function) aFunction = aGroup->GetFunction(1);
+  aFunction->SetDescription(aDescr);
+
+  SetErrorCode(OK);
+  return aGroup;
+}
+
+//=============================================================================
+/*!
+ *  GetInPlace
+ */
+//=============================================================================
+Handle(GEOM_Object) GEOMImpl_IShapesOperations::GetInPlace
+                                          (Handle(GEOM_Object) theShapeWhere,
+                                           Handle(GEOM_Object) theShapeWhat)
+{
+  SetErrorCode(KO);
+
+  if (theShapeWhere.IsNull() || theShapeWhat.IsNull()) return NULL;
+
+  TopoDS_Shape aWhere = theShapeWhere->GetValue();
+  TopoDS_Shape aWhat  = theShapeWhat->GetValue();
+
+  if (aWhere.IsNull() || aWhat.IsNull()) return NULL;
+
+  //Fill array of indices
+  TopTools_IndexedMapOfShape anIndices;
+  TopExp::MapShapes(aWhere, anIndices);
+
+//  Handle(TColStd_HArray1OfInteger) anArray =
+//    new TColStd_HArray1OfInteger (1, listSS.Extent());
+//  TopTools_ListIteratorOfListOfShape itSub (listSS);
+//  for (int index = 1; itSub.More(); itSub.Next(), ++index) {
+//    int id = anIndices.FindIndex(itSub.Value());
+//    anArray->SetValue(index, id);
+//  }
+//  
+//  //Add a new group object
+//  Handle(GEOM_Object) aGroup = GetEngine()->AddSubShape(theShape, anArray);
+//
+//  //Set a GROUP type
+//  aGroup->SetType(GEOM_GROUP);
+//
+//  //Set a sub shape type
+//  TDF_Label aFreeLabel = aGroup->GetFreeLabel();
+//  TDataStd_Integer::Set(aFreeLabel, (Standard_Integer)theShapeType);
+// 
+//  //Make a Python command
+//  TCollection_AsciiString anEntry, aDescr;
+//  TDF_Tool::Entry(aGroup->GetEntry(), anEntry);
+//  aDescr += anEntry;
+//  aDescr += " = IShapesOperations.GetInPlace(";
+//  TDF_Tool::Entry(theShapeWhere->GetEntry(), anEntry);
+//  aDescr += anEntry + ",";
+//  TDF_Tool::Entry(theShapeWhat->GetEntry(), anEntry);
+//  aDescr += anEntry + ")";
+//
+//  Handle(GEOM_Function) aFunction = aGroup->GetFunction(1);
+//  aFunction->SetDescription(aDescr);
+
+//  SetErrorCode(OK);
+//  return aGroup;
+  SetErrorCode("Not implemented");
+  return NULL;
+}
+
 
 //=======================================================================
 //function : SortShapes
index 9ae51717aabdd950c8957d3a73fa77f596117e6c..469f8854114796af483141f9b3de0ce7015d00a3 100644 (file)
@@ -6,6 +6,7 @@
 
 #include <TopTools_ListOfShape.hxx>
 #include <TColStd_HSequenceOfTransient.hxx>
+#include <TColStd_HSequenceOfInteger.hxx>
 
 #include <list>
 
@@ -23,9 +24,10 @@ class GEOMImpl_IShapesOperations : public GEOM_IOperations {
 
   Handle(GEOM_Object) MakeWire (list<Handle(GEOM_Object)> theEdgesAndWires);
 
-  Handle(GEOM_Object) MakeFace (Handle(GEOM_Object) theWire, bool isPlanarWanted);
+  Handle(GEOM_Object) MakeFace (Handle(GEOM_Object) theWire, const bool isPlanarWanted);
 
-  Handle(GEOM_Object) MakeFaceWires (list<Handle(GEOM_Object)> theWires, bool isPlanarWanted);
+  Handle(GEOM_Object) MakeFaceWires (list<Handle(GEOM_Object)> theWires,
+                                     const bool isPlanarWanted);
 
   Handle(GEOM_Object) MakeShell (list<Handle(GEOM_Object)> theShapes);
 
@@ -42,6 +44,10 @@ class GEOMImpl_IShapesOperations : public GEOM_IOperations {
                                                     const Standard_Integer theShapeType,
                                                     const Standard_Boolean isSorted);
 
+  Handle(TColStd_HSequenceOfInteger) SubShapeAllIDs (Handle(GEOM_Object)    theShape,
+                                                     const Standard_Integer theShapeType,
+                                                     const Standard_Boolean isSorted);
+
   Handle(GEOM_Object) GetSubShape (Handle(GEOM_Object)    theMainShape,
                                    const Standard_Integer theID);
 
@@ -50,6 +56,29 @@ class GEOMImpl_IShapesOperations : public GEOM_IOperations {
 
   Handle(GEOM_Object) ReverseShape(Handle(GEOM_Object) theShapes);
 
+  Handle(TColStd_HSequenceOfInteger) GetFreeFacesIDs (Handle(GEOM_Object) theShape);
+
+  Handle(TColStd_HSequenceOfTransient) GetSharedShapes (Handle(GEOM_Object)    theShape1,
+                                                        Handle(GEOM_Object)    theShape2,
+                                                        const Standard_Integer theShapeType);
+
+  Handle(GEOM_Object) GetShapesOnPlane (Handle(GEOM_Object)    theShape,
+                                        const Standard_Integer theShapeType,
+                                        Handle(GEOM_Object)    thePlane);
+
+  Handle(GEOM_Object) GetShapesOnCylinder (Handle(GEOM_Object)    theShape,
+                                           const Standard_Integer theShapeType,
+                                           Handle(GEOM_Object)    theAxis,
+                                           const Standard_Real    theRadius);
+
+  Handle(GEOM_Object) GetShapesOnSphere (Handle(GEOM_Object)    theShape,
+                                         const Standard_Integer theShapeType,
+                                         Handle(GEOM_Object)    theCenter,
+                                         const Standard_Real    theRadius);
+
+  Handle(GEOM_Object) GetInPlace (Handle(GEOM_Object) theShapeWhere,
+                                  Handle(GEOM_Object) theShapeWhat);
+
   static void SortShapes (TopTools_ListOfShape& SL);
 
  private:
index a5aeb7ee86e9ed60dd5d40aafec8a3473d110dfe..58f0f7c0ea40b5e521b09242eb4976526afffed7 100644 (file)
@@ -657,6 +657,12 @@ CORBA::Boolean GEOM_IBlocksOperations_i::CheckCompoundOfBlocks
     case GEOMImpl_IBlocksOperations::NOT_BLOCK:
       anError->error = GEOM::GEOM_IBlocksOperations::NOT_BLOCK;
       break;
+    case GEOMImpl_IBlocksOperations::DEGENERATED_EDGE:
+      anError->error = GEOM::GEOM_IBlocksOperations::DEGENERATED_EDGE;
+      break;
+    case GEOMImpl_IBlocksOperations::SEAM_EDGE:
+      anError->error = GEOM::GEOM_IBlocksOperations::SEAM_EDGE;
+      break;
     case GEOMImpl_IBlocksOperations::INVALID_CONNECTION:
       anError->error = GEOM::GEOM_IBlocksOperations::INVALID_CONNECTION;
       break;
@@ -720,6 +726,12 @@ char* GEOM_IBlocksOperations_i::PrintBCErrors
     case GEOM::GEOM_IBlocksOperations::NOT_BLOCK:
       errStruct.error = GEOMImpl_IBlocksOperations::NOT_BLOCK;
       break;
+    case GEOM::GEOM_IBlocksOperations::DEGENERATED_EDGE:
+      errStruct.error = GEOMImpl_IBlocksOperations::DEGENERATED_EDGE;
+      break;
+    case GEOM::GEOM_IBlocksOperations::SEAM_EDGE:
+      errStruct.error = GEOMImpl_IBlocksOperations::SEAM_EDGE;
+      break;
     case GEOM::GEOM_IBlocksOperations::INVALID_CONNECTION:
       errStruct.error = GEOMImpl_IBlocksOperations::INVALID_CONNECTION;
       break;
@@ -937,3 +949,37 @@ GEOM::GEOM_Object_ptr GEOM_IBlocksOperations_i::MakeMultiTransformation2D
 
   return GetObject(anObject);
 }
+
+//=============================================================================
+/*!
+ *  Propagate
+ */
+//=============================================================================
+GEOM::ListOfGO* GEOM_IBlocksOperations_i::Propagate (GEOM::GEOM_Object_ptr theShape)
+{
+  GEOM::ListOfGO_var aSeq = new GEOM::ListOfGO;
+
+  //Set a not done flag
+  GetOperations()->SetNotDone();
+
+  if (theShape == NULL) return aSeq._retn();
+
+  //Get the reference Shape
+  Handle(GEOM_Object) aShape = GetOperations()->GetEngine()->GetObject
+    (theShape->GetStudyID(), theShape->GetEntry());
+
+  if (aShape.IsNull()) return aSeq._retn();
+
+  //Get the Propagation chains
+  Handle(TColStd_HSequenceOfTransient) aHSeq =
+    GetOperations()->Propagate(aShape);
+  if (!GetOperations()->IsDone() || aHSeq.IsNull())
+    return aSeq._retn();
+
+  Standard_Integer aLength = aHSeq->Length();
+  aSeq->length(aLength);
+  for (Standard_Integer i = 1; i <= aLength; i++)
+    aSeq[i-1] = GetObject(Handle(GEOM_Object)::DownCast(aHSeq->Value(i)));
+
+  return aSeq._retn();
+}
index 32c5085dabe31232af8ef05c4f33c7e941113fe4..ff06a1c64eb81df4741ca9b3536f8a37d484db38 100644 (file)
@@ -119,6 +119,9 @@ class GEOM_IBlocksOperations_i :
                                                   const CORBA::Long     theDirFace2V,
                                                   const CORBA::Long     theNbTimesV);
 
+  // Build groups for Propagation of 1D hypotheses
+  GEOM::ListOfGO* Propagate (GEOM::GEOM_Object_ptr theShape);
+
   ::GEOMImpl_IBlocksOperations* GetOperations()
   { return (::GEOMImpl_IBlocksOperations*)GetImpl(); }
 };
index 4f8236d4afaaee996ad96063a01f1025de8b186a..9bfdf7f6b873244366374d2595e7774e34205735 100644 (file)
@@ -108,7 +108,8 @@ GEOM::GEOM_Object_ptr GEOM_IShapesOperations_i::MakeWire
  */
 //=============================================================================
 GEOM::GEOM_Object_ptr GEOM_IShapesOperations_i::MakeFace
-                      (GEOM::GEOM_Object_ptr theWire, CORBA::Boolean isPlanarWanted)
+                      (GEOM::GEOM_Object_ptr theWire,
+                      const CORBA::Boolean  isPlanarWanted)
 {
   GEOM::GEOM_Object_var aGEOMObject;
 
@@ -138,7 +139,7 @@ GEOM::GEOM_Object_ptr GEOM_IShapesOperations_i::MakeFace
 //=============================================================================
 GEOM::GEOM_Object_ptr GEOM_IShapesOperations_i::MakeFaceWires
                                          (const GEOM::ListOfGO& theWires,
-                                         CORBA::Boolean        isPlanarWanted)
+                                         const CORBA::Boolean  isPlanarWanted)
 {
   GEOM::GEOM_Object_var aGEOMObject;
 
@@ -323,10 +324,12 @@ GEOM::GEOM_Object_ptr GEOM_IShapesOperations_i::MakeGlueFaces
 
   if (aShape.IsNull()) return aGEOMObject._retn();
 
-  //Perform the glueing
+  //Perform the gluing
   Handle(GEOM_Object) anObject =
     GetOperations()->MakeGlueFaces(aShape, theTolerance);
-  if (!GetOperations()->IsDone() || anObject.IsNull())
+  //if (!GetOperations()->IsDone() || anObject.IsNull())
+  // to allow warning
+  if (anObject.IsNull())
     return aGEOMObject._retn();
 
   return GetObject(anObject);
@@ -342,10 +345,15 @@ GEOM::ListOfGO* GEOM_IShapesOperations_i::MakeExplode (GEOM::GEOM_Object_ptr the
                                                       const CORBA::Boolean  isSorted)
 {
   GEOM::ListOfGO_var aSeq = new GEOM::ListOfGO;
-  if (theShape == NULL)  return aSeq._retn();
-  Handle(GEOM_Object) aShape =   GetOperations()->GetEngine()->GetObject(theShape->GetStudyID(), theShape->GetEntry());
-  Handle(TColStd_HSequenceOfTransient) aHSeq = GetOperations()->MakeExplode(aShape, theShapeType, isSorted);
-  if (!GetOperations()->IsDone() || aHSeq.IsNull()) return aSeq._retn();
+  if (theShape == NULL) return aSeq._retn();
+
+  Handle(GEOM_Object) aShape = GetOperations()->GetEngine()->GetObject
+    (theShape->GetStudyID(), theShape->GetEntry());
+
+  Handle(TColStd_HSequenceOfTransient) aHSeq =
+    GetOperations()->MakeExplode(aShape, theShapeType, isSorted);
+  if (!GetOperations()->IsDone() || aHSeq.IsNull())
+    return aSeq._retn();
 
   Standard_Integer aLength = aHSeq->Length();
   aSeq->length(aLength);
@@ -355,6 +363,33 @@ GEOM::ListOfGO* GEOM_IShapesOperations_i::MakeExplode (GEOM::GEOM_Object_ptr the
   return aSeq._retn();
 }
 
+//=============================================================================
+/*!
+ *  SubShapeAllIDs
+ */
+//=============================================================================
+GEOM::ListOfLong* GEOM_IShapesOperations_i::SubShapeAllIDs (GEOM::GEOM_Object_ptr theShape,
+                                                           const CORBA::Long     theShapeType,
+                                                           const CORBA::Boolean  isSorted)
+{
+  GEOM::ListOfLong_var aSeq = new GEOM::ListOfLong;
+  if (theShape == NULL) return aSeq._retn();
+
+  Handle(GEOM_Object) aShape = GetOperations()->GetEngine()->GetObject
+    (theShape->GetStudyID(), theShape->GetEntry());
+
+  Handle(TColStd_HSequenceOfInteger) aHSeq =
+    GetOperations()->SubShapeAllIDs(aShape, theShapeType, isSorted);
+  if (!GetOperations()->IsDone() || aHSeq.IsNull()) return aSeq._retn();
+
+  Standard_Integer aLength = aHSeq->Length();
+  aSeq->length(aLength);
+  for (Standard_Integer i = 1; i <= aLength; i++)
+    aSeq[i-1] = aHSeq->Value(i);
+
+  return aSeq._retn();
+}
+
 //=============================================================================
 /*!
  *  GetSubShape
@@ -422,7 +457,7 @@ CORBA::Long GEOM_IShapesOperations_i::NumberOfEdges (GEOM::GEOM_Object_ptr theSh
 
 //=============================================================================
 /*!
- *  ReverseOrientation
+ *  ChangeOrientation
  */
 //=============================================================================
 GEOM::GEOM_Object_ptr GEOM_IShapesOperations_i::ChangeOrientation
@@ -449,3 +484,207 @@ GEOM::GEOM_Object_ptr GEOM_IShapesOperations_i::ChangeOrientation
   return GetObject(anObject);
 }
 
+//=============================================================================
+/*!
+ *  GetFreeFacesIDs
+ */
+//=============================================================================
+GEOM::ListOfLong* GEOM_IShapesOperations_i::GetFreeFacesIDs (GEOM::GEOM_Object_ptr theShape)
+{
+  GEOM::ListOfLong_var aSeq = new GEOM::ListOfLong;
+  if (theShape == NULL) return aSeq._retn();
+
+  Handle(GEOM_Object) aShape = GetOperations()->GetEngine()->GetObject
+    (theShape->GetStudyID(), theShape->GetEntry());
+
+  Handle(TColStd_HSequenceOfInteger) aHSeq =
+    GetOperations()->GetFreeFacesIDs(aShape);
+  if (!GetOperations()->IsDone() || aHSeq.IsNull()) return aSeq._retn();
+
+  Standard_Integer aLength = aHSeq->Length();
+  aSeq->length(aLength);
+  for (Standard_Integer i = 1; i <= aLength; i++)
+    aSeq[i-1] = aHSeq->Value(i);
+
+  return aSeq._retn();
+}
+
+//=============================================================================
+/*!
+ *  GetSharedShapes
+ */
+//=============================================================================
+GEOM::ListOfGO* GEOM_IShapesOperations_i::GetSharedShapes
+                                          (GEOM::GEOM_Object_ptr theShape1,
+                                          GEOM::GEOM_Object_ptr theShape2,
+                                          const CORBA::Long     theShapeType)
+{
+  GEOM::ListOfGO_var aSeq = new GEOM::ListOfGO;
+  if (theShape1 == NULL ||
+      theShape2 == NULL) return aSeq._retn();
+
+  Handle(GEOM_Object) aShape1 = GetOperations()->GetEngine()->GetObject
+    (theShape1->GetStudyID(), theShape1->GetEntry());
+  Handle(GEOM_Object) aShape2 = GetOperations()->GetEngine()->GetObject
+    (theShape2->GetStudyID(), theShape2->GetEntry());
+
+  if (aShape1.IsNull() ||
+      aShape2.IsNull()) return aSeq._retn();
+
+  Handle(TColStd_HSequenceOfTransient) aHSeq =
+    GetOperations()->GetSharedShapes(aShape1, aShape2, theShapeType);
+  if (!GetOperations()->IsDone() || aHSeq.IsNull())
+    return aSeq._retn();
+
+  Standard_Integer aLength = aHSeq->Length();
+  aSeq->length(aLength);
+  for (Standard_Integer i = 1; i <= aLength; i++)
+    aSeq[i-1] = GetObject(Handle(GEOM_Object)::DownCast(aHSeq->Value(i)));
+
+  return aSeq._retn();
+}
+
+//=============================================================================
+/*!
+ *  GetShapesOnPlane
+ */
+//=============================================================================
+GEOM::GEOM_Object_ptr GEOM_IShapesOperations_i::GetShapesOnPlane
+                                                (GEOM::GEOM_Object_ptr theShape,
+                                                const CORBA::Long     theShapeType,
+                                                GEOM::GEOM_Object_ptr thePlane)
+{
+  GEOM::GEOM_Object_var aGEOMObject;
+
+  //Set a not done flag
+  GetOperations()->SetNotDone();
+
+  if (theShape == NULL ||
+      thePlane == NULL) return aGEOMObject._retn();
+
+  //Get the reference objects
+  Handle(GEOM_Object) aShape = GetOperations()->GetEngine()->GetObject
+    (theShape->GetStudyID(), theShape->GetEntry());
+  Handle(GEOM_Object) aPlane = GetOperations()->GetEngine()->GetObject
+    (thePlane->GetStudyID(), thePlane->GetEntry());
+
+  if (aShape.IsNull() ||
+      aPlane.IsNull()) return aGEOMObject._retn();
+
+  //Get Shapes On Plane
+  Handle(GEOM_Object) anObject =
+    GetOperations()->GetShapesOnPlane(aShape, theShapeType, aPlane);
+  if (!GetOperations()->IsDone() || anObject.IsNull())
+    return aGEOMObject._retn();
+
+  return GetObject(anObject);
+}
+
+//=============================================================================
+/*!
+ *  GetShapesOnCylinder
+ */
+//=============================================================================
+GEOM::GEOM_Object_ptr GEOM_IShapesOperations_i::GetShapesOnCylinder
+                                                (GEOM::GEOM_Object_ptr theShape,
+                                                const CORBA::Long     theShapeType,
+                                                GEOM::GEOM_Object_ptr theAxis,
+                                                const CORBA::Double   theRadius)
+{
+  GEOM::GEOM_Object_var aGEOMObject;
+
+  //Set a not done flag
+  GetOperations()->SetNotDone();
+
+  if (theShape == NULL ||
+      theAxis == NULL) return aGEOMObject._retn();
+
+  //Get the reference objects
+  Handle(GEOM_Object) aShape = GetOperations()->GetEngine()->GetObject
+    (theShape->GetStudyID(), theShape->GetEntry());
+  Handle(GEOM_Object) anAxis = GetOperations()->GetEngine()->GetObject
+    (theAxis->GetStudyID(), theAxis->GetEntry());
+
+  if (aShape.IsNull() ||
+      anAxis.IsNull()) return aGEOMObject._retn();
+
+  //Get Shapes On Cylinder
+  Handle(GEOM_Object) anObject =
+    GetOperations()->GetShapesOnCylinder(aShape, theShapeType, anAxis, theRadius);
+  if (!GetOperations()->IsDone() || anObject.IsNull())
+    return aGEOMObject._retn();
+
+  return GetObject(anObject);
+}
+
+//=============================================================================
+/*!
+ *  GetShapesOnSphere
+ */
+//=============================================================================
+GEOM::GEOM_Object_ptr GEOM_IShapesOperations_i::GetShapesOnSphere
+                                                (GEOM::GEOM_Object_ptr theShape,
+                                                const CORBA::Long     theShapeType,
+                                                GEOM::GEOM_Object_ptr theCenter,
+                                                const CORBA::Double   theRadius)
+{
+  GEOM::GEOM_Object_var aGEOMObject;
+
+  //Set a not done flag
+  GetOperations()->SetNotDone();
+
+  if (theShape == NULL ||
+      theCenter == NULL) return aGEOMObject._retn();
+
+  //Get the reference objects
+  Handle(GEOM_Object) aShape = GetOperations()->GetEngine()->GetObject
+    (theShape->GetStudyID(), theShape->GetEntry());
+  Handle(GEOM_Object) aCenter = GetOperations()->GetEngine()->GetObject
+    (theCenter->GetStudyID(), theCenter->GetEntry());
+
+  if (aShape.IsNull() ||
+      aCenter.IsNull()) return aGEOMObject._retn();
+
+  //Get Shapes On Sphere
+  Handle(GEOM_Object) anObject =
+    GetOperations()->GetShapesOnSphere(aShape, theShapeType, aCenter, theRadius);
+  if (!GetOperations()->IsDone() || anObject.IsNull())
+    return aGEOMObject._retn();
+
+  return GetObject(anObject);
+}
+
+//=============================================================================
+/*!
+ *  GetInPlace
+ */
+//=============================================================================
+GEOM::GEOM_Object_ptr GEOM_IShapesOperations_i::GetInPlace
+                                          (GEOM::GEOM_Object_ptr theShapeWhere,
+                                          GEOM::GEOM_Object_ptr theShapeWhat)
+{
+  GEOM::GEOM_Object_var aGEOMObject;
+
+  //Set a not done flag
+  GetOperations()->SetNotDone();
+
+  if (theShapeWhere == NULL ||
+      theShapeWhat == NULL) return aGEOMObject._retn();
+
+  //Get the reference objects
+  Handle(GEOM_Object) aShapeWhere = GetOperations()->GetEngine()->GetObject
+    (theShapeWhere->GetStudyID(), theShapeWhere->GetEntry());
+  Handle(GEOM_Object) aShapeWhat = GetOperations()->GetEngine()->GetObject
+    (theShapeWhat->GetStudyID(), theShapeWhat->GetEntry());
+
+  if (aShapeWhere.IsNull() ||
+      aShapeWhat.IsNull()) return aGEOMObject._retn();
+
+  //Get Shapes in place of aShapeWhat
+  Handle(GEOM_Object) anObject =
+    GetOperations()->GetInPlace(aShapeWhere, aShapeWhat);
+  if (!GetOperations()->IsDone() || anObject.IsNull())
+    return aGEOMObject._retn();
+
+  return GetObject(anObject);
+}
index 4a63bb1f5e30f4ffe7a4e6f3ac00d6bf5cd5050c..dea3af3294999a3f731425ab1da7fbed36921422 100644 (file)
@@ -16,7 +16,8 @@ class GEOM_IShapesOperations_i :
     public virtual GEOM_IOperations_i
 {
  public:
-  GEOM_IShapesOperations_i (PortableServer::POA_ptr thePOA, GEOM::GEOM_Gen_ptr theEngine,
+  GEOM_IShapesOperations_i (PortableServer::POA_ptr       thePOA,
+                           GEOM::GEOM_Gen_ptr            theEngine,
                            ::GEOMImpl_IShapesOperations* theImpl);
   ~GEOM_IShapesOperations_i();
 
@@ -26,10 +27,10 @@ class GEOM_IShapesOperations_i :
   GEOM::GEOM_Object_ptr MakeWire (const GEOM::ListOfGO& theEdgesAndWires);
 
   GEOM::GEOM_Object_ptr MakeFace (GEOM::GEOM_Object_ptr theWire,
-                                 CORBA::Boolean isPlanarWanted);
+                                 const CORBA::Boolean  isPlanarWanted);
 
   GEOM::GEOM_Object_ptr MakeFaceWires (const GEOM::ListOfGO& theWires,
-                                      CORBA::Boolean isPlanarWanted);
+                                      const CORBA::Boolean  isPlanarWanted);
 
   GEOM::GEOM_Object_ptr MakeShell (const GEOM::ListOfGO& theFacesAndShells);
 
@@ -43,8 +44,12 @@ class GEOM_IShapesOperations_i :
                                       const CORBA::Double   theTolerance);
 
   GEOM::ListOfGO* MakeExplode (GEOM::GEOM_Object_ptr theShape,
-                              const CORBA::Long theShapeType,
-                              const CORBA::Boolean isSorted);
+                              const CORBA::Long     theShapeType,
+                              const CORBA::Boolean  isSorted);
+
+  GEOM::ListOfLong* SubShapeAllIDs (GEOM::GEOM_Object_ptr theShape,
+                                   const CORBA::Long     theShapeType,
+                                   const CORBA::Boolean  isSorted);
 
   GEOM::GEOM_Object_ptr GetSubShape (GEOM::GEOM_Object_ptr theMainShape,
                                     const CORBA::Long     theID);
@@ -54,6 +59,29 @@ class GEOM_IShapesOperations_i :
 
   GEOM::GEOM_Object_ptr ChangeOrientation (GEOM::GEOM_Object_ptr theShape);
 
+  GEOM::ListOfLong* GetFreeFacesIDs (GEOM::GEOM_Object_ptr theShape);
+
+  GEOM::ListOfGO* GetSharedShapes (GEOM::GEOM_Object_ptr theShape1,
+                                  GEOM::GEOM_Object_ptr theShape2,
+                                  const CORBA::Long     theShapeType);
+
+  GEOM::GEOM_Object_ptr GetShapesOnPlane (GEOM::GEOM_Object_ptr theShape,
+                                         const CORBA::Long     theShapeType,
+                                         GEOM::GEOM_Object_ptr thePlane);
+
+  GEOM::GEOM_Object_ptr GetShapesOnCylinder (GEOM::GEOM_Object_ptr theShape,
+                                            const CORBA::Long     theShapeType,
+                                            GEOM::GEOM_Object_ptr theAxis,
+                                            const CORBA::Double   theRadius);
+
+  GEOM::GEOM_Object_ptr GetShapesOnSphere (GEOM::GEOM_Object_ptr theShape,
+                                          const CORBA::Long     theShapeType,
+                                          GEOM::GEOM_Object_ptr theCenter,
+                                          const CORBA::Double   theRadius);
+
+  GEOM::GEOM_Object_ptr GetInPlace (GEOM::GEOM_Object_ptr theShapeWhere,
+                                   GEOM::GEOM_Object_ptr theShapeWhat);
+
   ::GEOMImpl_IShapesOperations* GetOperations()
   { return (::GEOMImpl_IShapesOperations*)GetImpl(); }
 };
index ab0a90fe8afb168e814d2cd85e83974091ddc2d7..38f410ae6ccbefb59cf5f0cb42f4995674d224b0 100644 (file)
@@ -408,12 +408,24 @@ def SubShapeAll(aShape, aType):
       print "MakeExplode : ", ShapesOp.GetErrorCode()
     return ListObj
 
+def SubShapeAllIDs(aShape, aType):
+    ListObj = ShapesOp.SubShapeAllIDs(aShape,aType,0)
+    if ShapesOp.IsDone() == 0:
+      print "SubShapeAllIDs : ", ShapesOp.GetErrorCode()
+    return ListObj
+
 def SubShapeAllSorted(aShape,aType):
     ListObj = ShapesOp.MakeExplode(aShape,aType,1)
     if ShapesOp.IsDone() == 0:
       print "MakeExplode : ", ShapesOp.GetErrorCode()
     return ListObj
 
+def SubShapeAllSortedIDs(aShape, aType):
+    ListIDs = ShapesOp.SubShapeAllIDs(aShape,aType,1)
+    if ShapesOp.IsDone() == 0:
+      print "SubShapeAllSortedIDs : ", ShapesOp.GetErrorCode()
+    return ListObj
+
 # Obtain a compound of sub-shapes of <aShape>,
 # selected by they indices in list of all sub-shapes of type <aType>
 def SubShape(aShape, aType, ListOfInd):
index b2bc785ac69b0a8927bf45944fd863d1c5136b73..b7b8d46583582d727a0c4d97923fff33a7fa470b 100644 (file)
@@ -793,6 +793,17 @@ def SubShapeAll(aShape, aType):
       print "MakeExplode : ", ShapesOp.GetErrorCode()
     return ListObj
 
+#     *  Explode a shape on subshapes of a given type.
+#     *  \param theShape Shape to be exploded.
+#     *  \param theShapeType Type of sub-shapes to be retrieved.
+#     *  \return List of IDs of sub-shapes.
+#
+def SubShapeAllIDs(aShape, aType):
+    ListObj = ShapesOp.SubShapeAllIDs(aShape,aType,0)
+    if ShapesOp.IsDone() == 0:
+      print "SubShapeAllIDs : ", ShapesOp.GetErrorCode()
+    return ListObj
+
 #     *  Explode a shape on subshapes of a given type.
 #     *  Sub-shapes will be sorted by coordinates of their gravity centers.
 #     *  \param theShape Shape to be exploded.
@@ -807,6 +818,18 @@ def SubShapeAllSorted(aShape, aType):
       print "MakeExplode : ", ShapesOp.GetErrorCode()
     return ListObj
 
+#     *  Explode a shape on subshapes of a given type.
+#     *  Sub-shapes will be sorted by coordinates of their gravity centers.
+#     *  \param theShape Shape to be exploded.
+#     *  \param theShapeType Type of sub-shapes to be retrieved.
+#     *  \return List of IDs of sub-shapes.
+#
+def SubShapeAllSortedIDs(aShape, aType):
+    ListIDs = ShapesOp.SubShapeAllIDs(aShape,aType,1)
+    if ShapesOp.IsDone() == 0:
+      print "SubShapeAllSortedIDs : ", ShapesOp.GetErrorCode()
+    return ListObj
+
 #     *  Obtain a compound of sub-shapes of <aShape>,
 #     *  selected by they indices in list of all sub-shapes of type <aType>.
 #     *  Each index is in range [1, Nb_Sub-Shapes_Of_Given_Type]