Salome HOME
IMP 0016693: EDF461: To use BelongToGeom or LyingOnGeom with non-subshape Objects.
authorjfa <jfa@opencascade.com>
Tue, 26 Aug 2008 07:55:14 +0000 (07:55 +0000)
committerjfa <jfa@opencascade.com>
Tue, 26 Aug 2008 07:55:14 +0000 (07:55 +0000)
doc/salome/gui/SMESH/input/selection_filter_library.doc
idl/SMESH_Filter.idl
src/Controls/SMESH_Controls.cxx
src/Controls/SMESH_ControlsDef.hxx
src/SMESH_I/SMESH_Filter_i.cxx
src/SMESH_I/SMESH_Filter_i.hxx

index 70dc9a65f2e169f4b8c68bf212bc915b500468f1..070f79b6a1430f3e58e4946763e91842543fe87f 100644 (file)
@@ -50,13 +50,17 @@ created. You have to select the mesh and the button will be enabled.
 
 Some criteria are applicable to all <b>Entity types</b>:
 <ul><li>
-<b>Belong to Geom</b> selects entities whose all nodes belong to a
-submesh on the shape defined by <b>Threshold Value</b>. The threshold shape
-must be sub-shape of the main shape of mesh.
-</li><li>
-<b>Lying on Geom</b> selects entities whose at least one node belongs to a
-submesh on the shape defined by <b>Threshold Value</b>. The threshold shape
-must be sub-shape of the main shape of mesh.
+<b>Belong to Geom</b> selects entities whose all nodes
+lays on the shape defined by <b>Threshold Value</b>.
+The threshold shape can be sub-shape of the main shape of mesh, in
+this case the algorithm works fast, and it also can be any other
+shape, but in this case the algorithm works slower.
+</li><li>
+<b>Lying on Geom</b> selects entities whose at least one node
+lays on the shape defined by <b>Threshold Value</b>.
+The threshold shape can be sub-shape of the main shape of mesh, in
+this case the algorithm works fast, and it also can be any other
+shape, but in this case the algorithm works slower.
 </li><li>
 <b>Range of IDs</b> allows selection of entities having certain
 IDs. <b>Threshold Value</b> can be like this: "1,2,3,50-60,63,67,70-78"
index fcb5a993682e38c48b15730bc2712e031273f84c..acffc1425d2c1b2dd6c49bfa7f764431e77241d3 100644 (file)
@@ -136,21 +136,26 @@ module SMESH
   };
 
   /*!
-  * Logical functor (predicate) "Bad Oriented Volume".
-  * Verify whether a mesh volume is incorrectly oriented from
-  * the point of view of MED convention
-  */
+   * Logical functor (predicate) "Bad Oriented Volume".
+   * Verify whether a mesh volume is incorrectly oriented from
+   * the point of view of MED convention
+   */
   interface BadOrientedVolume: Predicate {};
 
   /*!
-  * Logical functor (predicate) "Belong To Geometry".
-  * Verify whether mesh element or node belong to pointed Geom Object
-  */
+   * Logical functor (predicate) "Belong To Geometry".
+   * Verify whether mesh element or node belong to pointed Geom Object
+   */
   interface BelongToGeom: Predicate
   {
     void SetGeom( in GEOM::GEOM_Object theGeom );
     void SetElementType( in ElementType theType );
 
+    /*! The tolerance is used only if there is no submesh on the shape
+     */
+    void    SetTolerance( in double theToler );
+    double  GetTolerance();
+
     void   SetShapeName( in string theName );
     void   SetShape( in string theID, in string theName );
     string GetShapeName();
@@ -214,6 +219,11 @@ module SMESH
     void SetGeom( in GEOM::GEOM_Object theGeom );
     void SetElementType( in ElementType theType );
 
+    /*! The tolerance is used only if there is no submesh on the shape
+     */
+    void    SetTolerance( in double theToler );
+    double  GetTolerance();
+
     void   SetShapeName( in string theName );
     void   SetShape( in string theID, in string theName );
     string GetShapeName();    
index 86ca962023589bd2eb5451aef60484367c4d8cd8..3350a966e13e11683ec755f1ee08b10ab7285cf7 100644 (file)
 #include <set>
 
 #include <BRepAdaptor_Surface.hxx>
+#include <BRepClass_FaceClassifier.hxx>
 #include <BRep_Tool.hxx>
+
+#include <TopAbs.hxx>
+#include <TopoDS.hxx>
+#include <TopoDS_Edge.hxx>
+#include <TopoDS_Face.hxx>
+#include <TopoDS_Shape.hxx>
+#include <TopoDS_Vertex.hxx>
+#include <TopoDS_Iterator.hxx>
+
 #include <Geom_CylindricalSurface.hxx>
 #include <Geom_Plane.hxx>
 #include <Geom_Surface.hxx>
+
 #include <Precision.hxx>
 #include <TColStd_MapIteratorOfMapOfInteger.hxx>
 #include <TColStd_MapOfInteger.hxx>
 #include <TColStd_SequenceOfAsciiString.hxx>
 #include <TColgp_Array1OfXYZ.hxx>
-#include <TopAbs.hxx>
-#include <TopoDS.hxx>
-#include <TopoDS_Face.hxx>
-#include <TopoDS_Shape.hxx>
+
 #include <gp_Ax3.hxx>
 #include <gp_Cylinder.hxx>
 #include <gp_Dir.hxx>
@@ -51,7 +59,6 @@
 #include "SMDS_QuadraticFaceOfNodes.hxx"
 #include "SMDS_QuadraticEdge.hxx"
 
-
 /*
                             AUXILIARY METHODS
 */
@@ -2614,7 +2621,7 @@ void ElementsOnSurface::process()
 
   if ( myType == SMDSAbs_Edge || myType == SMDSAbs_All )
   {
-    myIds.ReSize( myMesh->NbEdges() );
+    myIds.ReSize( myIds.Extent() + myMesh->NbEdges() );
     SMDS_EdgeIteratorPtr anIter = myMesh->edgesIterator();
     for(; anIter->more(); )
       process( anIter->next() );
@@ -2677,3 +2684,250 @@ bool ElementsOnSurface::isOnSurface( const SMDS_MeshNode* theNode )
 
   return isOn;
 }
+
+
+/*
+  ElementsOnShape
+*/
+
+ElementsOnShape::ElementsOnShape()
+  : myMesh(0),
+    myType(SMDSAbs_All),
+    myToler(Precision::Confusion()),
+    myAllNodesFlag(false)
+{
+  myCurShapeType = TopAbs_SHAPE;
+}
+
+ElementsOnShape::~ElementsOnShape()
+{
+}
+
+void ElementsOnShape::SetMesh (const SMDS_Mesh* theMesh)
+{
+  if (myMesh != theMesh) {
+    myMesh = theMesh;
+    SetShape(myShape, myType);
+  }
+}
+
+bool ElementsOnShape::IsSatisfy (long theElementId)
+{
+  return myIds.Contains(theElementId);
+}
+
+SMDSAbs_ElementType ElementsOnShape::GetType() const
+{
+  return myType;
+}
+
+void ElementsOnShape::SetTolerance (const double theToler)
+{
+  if (myToler != theToler) {
+    myToler = theToler;
+    SetShape(myShape, myType);
+  }
+}
+
+double ElementsOnShape::GetTolerance() const
+{
+  return myToler;
+}
+
+void ElementsOnShape::SetAllNodes (bool theAllNodes)
+{
+  if (myAllNodesFlag != theAllNodes) {
+    myAllNodesFlag = theAllNodes;
+    SetShape(myShape, myType);
+  }
+}
+
+void ElementsOnShape::SetShape (const TopoDS_Shape&       theShape,
+                                const SMDSAbs_ElementType theType)
+{
+  myType = theType;
+  myShape = theShape;
+  myIds.Clear();
+
+  if (myMesh == 0) return;
+
+  switch (myType)
+  {
+  case SMDSAbs_All:
+    myIds.ReSize(myMesh->NbEdges() + myMesh->NbFaces() + myMesh->NbVolumes());
+    break;
+  case SMDSAbs_Node:
+    myIds.ReSize(myMesh->NbNodes());
+    break;
+  case SMDSAbs_Edge:
+    myIds.ReSize(myMesh->NbEdges());
+    break;
+  case SMDSAbs_Face:
+    myIds.ReSize(myMesh->NbFaces());
+    break;
+  case SMDSAbs_Volume:
+    myIds.ReSize(myMesh->NbVolumes());
+    break;
+  default:
+    break;
+  }
+
+  myShapesMap.Clear();
+  addShape(myShape);
+}
+
+void ElementsOnShape::addShape (const TopoDS_Shape& theShape)
+{
+  if (theShape.IsNull() || myMesh == 0)
+    return;
+
+  if (!myShapesMap.Add(theShape)) return;
+
+  myCurShapeType = theShape.ShapeType();
+  switch (myCurShapeType)
+  {
+  case TopAbs_COMPOUND:
+  case TopAbs_COMPSOLID:
+  case TopAbs_SHELL:
+  case TopAbs_WIRE:
+    {
+      TopoDS_Iterator anIt (theShape, Standard_True, Standard_True);
+      for (; anIt.More(); anIt.Next()) addShape(anIt.Value());
+    }
+    break;
+  case TopAbs_SOLID:
+    {
+      myCurSC.Load(theShape);
+      process();
+    }
+    break;
+  case TopAbs_FACE:
+    {
+      TopoDS_Face aFace = TopoDS::Face(theShape);
+      BRepAdaptor_Surface SA (aFace, true);
+      Standard_Real
+        u1 = SA.FirstUParameter(),
+        u2 = SA.LastUParameter(),
+        v1 = SA.FirstVParameter(),
+        v2 = SA.LastVParameter();
+      Handle(Geom_Surface) surf = BRep_Tool::Surface(aFace);
+      myCurProjFace.Init(surf, u1,u2, v1,v2);
+      myCurFace = aFace;
+      process();
+    }
+    break;
+  case TopAbs_EDGE:
+    {
+      TopoDS_Edge anEdge = TopoDS::Edge(theShape);
+      Standard_Real u1, u2;
+      Handle(Geom_Curve) curve = BRep_Tool::Curve(anEdge, u1, u2);
+      myCurProjEdge.Init(curve, u1, u2);
+      process();
+    }
+    break;
+  case TopAbs_VERTEX:
+    {
+      TopoDS_Vertex aV = TopoDS::Vertex(theShape);
+      myCurPnt = BRep_Tool::Pnt(aV);
+      process();
+    }
+    break;
+  default:
+    break;
+  }
+}
+
+void ElementsOnShape::process()
+{
+  if (myShape.IsNull() || myMesh == 0)
+    return;
+
+  if (myType == SMDSAbs_Node)
+  {
+    SMDS_NodeIteratorPtr anIter = myMesh->nodesIterator();
+    while (anIter->more())
+      process(anIter->next());
+  }
+  else
+  {
+    if (myType == SMDSAbs_Edge || myType == SMDSAbs_All)
+    {
+      SMDS_EdgeIteratorPtr anIter = myMesh->edgesIterator();
+      while (anIter->more())
+        process(anIter->next());
+    }
+
+    if (myType == SMDSAbs_Face || myType == SMDSAbs_All)
+    {
+      SMDS_FaceIteratorPtr anIter = myMesh->facesIterator();
+      while (anIter->more()) {
+        process(anIter->next());
+      }
+    }
+
+    if (myType == SMDSAbs_Volume || myType == SMDSAbs_All)
+    {
+      SMDS_VolumeIteratorPtr anIter = myMesh->volumesIterator();
+      while (anIter->more())
+        process(anIter->next());
+    }
+  }
+}
+
+void ElementsOnShape::process (const SMDS_MeshElement* theElemPtr)
+{
+  if (myShape.IsNull())
+    return;
+
+  SMDS_ElemIteratorPtr aNodeItr = theElemPtr->nodesIterator();
+  bool isSatisfy = myAllNodesFlag;
+
+  while (aNodeItr->more() && (isSatisfy == myAllNodesFlag))
+  {
+    SMDS_MeshNode* aNode = (SMDS_MeshNode*)aNodeItr->next();
+    gp_Pnt aPnt (aNode->X(), aNode->Y(), aNode->Z());
+
+    switch (myCurShapeType)
+    {
+    case TopAbs_SOLID:
+      {
+        myCurSC.Perform(aPnt, myToler);
+        isSatisfy = (myCurSC.State() == TopAbs_IN || myCurSC.State() == TopAbs_ON);
+      }
+      break;
+    case TopAbs_FACE:
+      {
+        myCurProjFace.Perform(aPnt);
+        isSatisfy = (myCurProjFace.IsDone() && myCurProjFace.LowerDistance() <= myToler);
+        if (isSatisfy)
+        {
+          // check relatively the face
+          Quantity_Parameter u, v;
+          myCurProjFace.LowerDistanceParameters(u, v);
+          gp_Pnt2d aProjPnt (u, v);
+          BRepClass_FaceClassifier aClsf (myCurFace, aProjPnt, myToler);
+          isSatisfy = (aClsf.State() == TopAbs_IN || aClsf.State() == TopAbs_ON);
+        }
+      }
+      break;
+    case TopAbs_EDGE:
+      {
+        myCurProjEdge.Perform(aPnt);
+        isSatisfy = (myCurProjEdge.NbPoints() > 0 && myCurProjEdge.LowerDistance() <= myToler);
+      }
+      break;
+    case TopAbs_VERTEX:
+      {
+        isSatisfy = (aPnt.Distance(myCurPnt) <= myToler);
+      }
+      break;
+    default:
+      {
+        isSatisfy = false;
+      }
+    }
+  }
+
+  if (isSatisfy)
+    myIds.Add(theElemPtr->GetID());
+}
index 84500897a096fcac9ae6f7d7e2d7831f6b079255..9eea42566c7965b2da861976d4c49ee4637f226a 100644 (file)
 #include <set>
 #include <map>
 #include <vector>
+
 #include <boost/shared_ptr.hpp>
+
 #include <gp_XYZ.hxx>
-//#include <Geom_Surface.hxx>
 #include <GeomAPI_ProjectPointOnSurf.hxx>
+#include <GeomAPI_ProjectPointOnCurve.hxx>
 #include <TColStd_SequenceOfInteger.hxx>
 #include <TColStd_MapOfInteger.hxx>
 #include <TCollection_AsciiString.hxx>
+#include <TopAbs.hxx>
 #include <TopoDS_Face.hxx>
+#include <TopTools_MapOfShape.hxx>
+#include <BRepClass3d_SolidClassifier.hxx>
 
 #include "SMDSAbs_ElementType.hxx"
 #include "SMDS_MeshNode.hxx"
@@ -56,7 +61,6 @@ class SMESHDS_Mesh;
 class SMESHDS_SubMesh;
 
 class gp_Pnt;
-//class TopoDS_Shape;
 
 namespace SMESH{
   namespace Controls{
@@ -131,17 +135,17 @@ namespace SMESH{
       long  GetPrecision() const;
       void  SetPrecision( const long thePrecision );
       
-      bool GetPoints(const int theId, 
+      bool GetPoints(const int theId,
                     TSequenceOfXYZ& theRes) const;
-      static bool GetPoints(const SMDS_MeshElement* theElem, 
+      static bool GetPoints(const SMDS_MeshElement* theElem,
                            TSequenceOfXYZ& theRes);
     protected:
       const SMDS_Mesh* myMesh;
       const SMDS_MeshElement* myCurrElement;
       long       myPrecision;
     };
-  
-  
+
+
     /*
       Class       : Volume
       Description : Functor calculating volume of 3D mesh element
@@ -216,8 +220,8 @@ namespace SMESH{
       virtual double GetBadRate( double Value, int nbNodes ) const;
       virtual SMDSAbs_ElementType GetType() const;
     };
-    
-  
+
+
     /*
       Class       : Skew
       Description : Functor for calculating skew in degrees
@@ -228,8 +232,8 @@ namespace SMESH{
       virtual double GetBadRate( double Value, int nbNodes ) const;
       virtual SMDSAbs_ElementType GetType() const;
     };
-  
-    
+
+
     /*
       Class       : Area
       Description : Functor for calculating area
@@ -252,7 +256,7 @@ namespace SMESH{
       virtual double GetBadRate( double Value, int nbNodes ) const;
       virtual SMDSAbs_ElementType GetType() const;
     };
-  
+
     /*
       Class       : Length2D
       Description : Functor for calculating length of edge
@@ -270,7 +274,6 @@ namespace SMESH{
       };
       typedef std::set<Value> TValues;
       void GetValues(TValues& theValues);
-      
     };
     typedef boost::shared_ptr<Length2D> Length2DPtr;
 
@@ -318,7 +321,6 @@ namespace SMESH{
       virtual bool IsSatisfy( long theElementId ) = 0;
       virtual SMDSAbs_ElementType GetType() const = 0;
     };
-    
   
   
     /*
@@ -331,7 +333,7 @@ namespace SMESH{
       virtual void SetMesh( const SMDS_Mesh* theMesh );
       virtual bool IsSatisfy( long theElementId );
       virtual SMDSAbs_ElementType GetType() const;
-            
+
     protected:
       const SMDS_Mesh* myMesh;
     };
@@ -604,7 +606,7 @@ namespace SMESH{
 
     };
     typedef boost::shared_ptr<ManifoldPart> ManifoldPartPtr;
-                         
+
 
     /*
       Class       : ElementsOnSurface
@@ -641,9 +643,56 @@ namespace SMESH{
       bool                  myUseBoundaries;
       GeomAPI_ProjectPointOnSurf myProjector;
     };
-    
+
     typedef boost::shared_ptr<ElementsOnSurface> ElementsOnSurfacePtr;
-      
+
+
+    /*
+      Class       : ElementsOnShape
+      Description : Predicate elements that lying on indicated shape
+                    (1D, 2D or 3D)
+    */
+    class SMESHCONTROLS_EXPORT ElementsOnShape : public virtual Predicate
+    {
+    public:
+      ElementsOnShape();
+      ~ElementsOnShape();
+
+      virtual void SetMesh (const SMDS_Mesh* theMesh);
+      virtual bool IsSatisfy (long theElementId);
+      virtual SMDSAbs_ElementType GetType() const;
+
+      void    SetTolerance (const double theToler);
+      double  GetTolerance() const;
+      void    SetAllNodes (bool theAllNodes);
+      bool    GetAllNodes() const { return myAllNodesFlag; }
+      void    SetShape (const TopoDS_Shape& theShape,
+                        const SMDSAbs_ElementType theType);
+
+    private:
+      void    addShape (const TopoDS_Shape& theShape);
+      void    process();
+      void    process (const SMDS_MeshElement* theElem);
+
+    private:
+      const SMDS_Mesh*      myMesh;
+      TColStd_MapOfInteger  myIds;
+      SMDSAbs_ElementType   myType;
+      TopoDS_Shape          myShape;
+      double                myToler;
+      bool                  myAllNodesFlag;
+
+      TopTools_MapOfShape         myShapesMap;
+      TopAbs_ShapeEnum            myCurShapeType; // type of current sub-shape
+      BRepClass3d_SolidClassifier myCurSC;        // current SOLID
+      GeomAPI_ProjectPointOnSurf  myCurProjFace;  // current FACE
+      TopoDS_Face                 myCurFace;      // current FACE
+      GeomAPI_ProjectPointOnCurve myCurProjEdge;  // current EDGE
+      gp_Pnt                      myCurPnt;       // current VERTEX
+    };
+
+    typedef boost::shared_ptr<ElementsOnShape> ElementsOnShapePtr;
+
 
     /*
       FILTER
@@ -656,21 +705,21 @@ namespace SMESH{
 
       typedef std::vector<long> TIdSequence;
 
-      virtual 
+      virtual
       void
       GetElementsId( const SMDS_Mesh* theMesh,
                     TIdSequence& theSequence );
 
       static
       void
-      GetElementsId( const SMDS_Mesh* theMesh, 
+      GetElementsId( const SMDS_Mesh* theMesh,
                     PredicatePtr thePredicate,
                     TIdSequence& theSequence );
       
     protected:
       PredicatePtr myPredicate;
     };
-  };  
+  };
 };
 
 
index f03eef26daa0b7c0574311abc48192fe476d8bba..a2fc21cdbc0686d192c824164d893cba1c1fd0b3 100644 (file)
@@ -17,7 +17,7 @@
 //  License along with this library; if not, write to the Free Software
 //  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
 //
-// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//  See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
 //
 //
@@ -58,6 +58,7 @@
 #include <TopoDS.hxx>
 #include <TopoDS_Face.hxx>
 #include <TopoDS_Shape.hxx>
+#include <TopTools_IndexedMapOfShape.hxx>
 
 using namespace SMESH;
 using namespace SMESH::Controls;
@@ -75,23 +76,73 @@ namespace SMESH
 
 /*
   Class       : BelongToGeom
-  Description : Predicate for verifying whether entiy belong to
+  Description : Predicate for verifying whether entity belongs to
                 specified geometrical support
 */
 
 Controls::BelongToGeom::BelongToGeom()
-: myMeshDS(NULL),
-  myType(SMDSAbs_All)
+  : myMeshDS(NULL),
+    myType(SMDSAbs_All),
+    myIsSubshape(false),
+    myTolerance(Precision::Confusion())
 {}
 
 void Controls::BelongToGeom::SetMesh( const SMDS_Mesh* theMesh )
 {
   myMeshDS = dynamic_cast<const SMESHDS_Mesh*>(theMesh);
+  init();
 }
 
 void Controls::BelongToGeom::SetGeom( const TopoDS_Shape& theShape )
 {
   myShape = theShape;
+  init();
+}
+
+static bool IsSubShape (const TopTools_IndexedMapOfShape& theMap,
+                        const TopoDS_Shape& theShape)
+{
+  if (theMap.Contains(theShape)) return true;
+
+  if (theShape.ShapeType() == TopAbs_COMPOUND ||
+      theShape.ShapeType() == TopAbs_COMPSOLID)
+  {
+    TopoDS_Iterator anIt (theShape, Standard_True, Standard_True);
+    for (; anIt.More(); anIt.Next())
+    {
+      if (!IsSubShape(theMap, anIt.Value())) {
+        return false;
+      }
+    }
+    return true;
+  }
+
+  return false;
+}
+
+void Controls::BelongToGeom::init()
+{
+  if (!myMeshDS || myShape.IsNull()) return;
+
+  // is subshape of main shape?
+  TopoDS_Shape aMainShape = myMeshDS->ShapeToMesh();
+  if (aMainShape.IsNull()) {
+    myIsSubshape = false;
+  }
+  else {
+    TopTools_IndexedMapOfShape aMap;
+    TopExp::MapShapes(aMainShape, aMap);
+    myIsSubshape = IsSubShape(aMap, myShape);
+  }
+
+  if (!myIsSubshape)
+  {
+    myElementsOnShapePtr.reset(new Controls::ElementsOnShape());
+    myElementsOnShapePtr->SetTolerance(myTolerance);
+    myElementsOnShapePtr->SetAllNodes(true); // belong, while false means "lays on"
+    myElementsOnShapePtr->SetMesh(myMeshDS);
+    myElementsOnShapePtr->SetShape(myShape, myType);
+  }
 }
 
 static bool IsContains( const SMESHDS_Mesh*     theMeshDS,
@@ -114,12 +165,18 @@ static bool IsContains( const SMESHDS_Mesh*     theMeshDS,
   return false;
 }
 
-bool Controls::BelongToGeom::IsSatisfy( long theId )
+bool Controls::BelongToGeom::IsSatisfy (long theId)
 {
-  if ( myMeshDS == 0 || myShape.IsNull() )
+  if (myMeshDS == 0 || myShape.IsNull())
     return false;
 
-  if( myType == SMDSAbs_Node )
+  if (!myIsSubshape)
+  {
+    return myElementsOnShapePtr->IsSatisfy(theId);
+  }
+
+  // Case of submesh
+  if (myType == SMDSAbs_Node)
   {
     if( const SMDS_MeshNode* aNode = myMeshDS->FindNode( theId ) )
     {
@@ -161,9 +218,10 @@ bool Controls::BelongToGeom::IsSatisfy( long theId )
   return false;
 }
 
-void Controls::BelongToGeom::SetType( SMDSAbs_ElementType theType )
+void Controls::BelongToGeom::SetType (SMDSAbs_ElementType theType)
 {
   myType = theType;
+  init();
 }
 
 SMDSAbs_ElementType Controls::BelongToGeom::GetType() const
@@ -176,13 +234,23 @@ TopoDS_Shape Controls::BelongToGeom::GetShape()
   return myShape;
 }
 
-const SMESHDS_Mesh*
-Controls::BelongToGeom::
-GetMeshDS() const
+const SMESHDS_Mesh* Controls::BelongToGeom::GetMeshDS() const
 {
   return myMeshDS;
 }
 
+void Controls::BelongToGeom::SetTolerance (double theTolerance)
+{
+  myTolerance = theTolerance;
+  if (!myIsSubshape)
+    init();
+}
+
+double Controls::BelongToGeom::GetTolerance()
+{
+  return myTolerance;
+}
+
 /*
   Class       : LyingOnGeom
   Description : Predicate for verifying whether entiy lying or partially lying on
@@ -190,18 +258,47 @@ GetMeshDS() const
 */
 
 Controls::LyingOnGeom::LyingOnGeom()
-: myMeshDS(NULL),
-  myType(SMDSAbs_All)
+  : myMeshDS(NULL),
+    myType(SMDSAbs_All),
+    myIsSubshape(false),
+    myTolerance(Precision::Confusion())
 {}
 
 void Controls::LyingOnGeom::SetMesh( const SMDS_Mesh* theMesh )
 {
   myMeshDS = dynamic_cast<const SMESHDS_Mesh*>(theMesh);
+  init();
 }
 
 void Controls::LyingOnGeom::SetGeom( const TopoDS_Shape& theShape )
 {
   myShape = theShape;
+  init();
+}
+
+void Controls::LyingOnGeom::init()
+{
+  if (!myMeshDS || myShape.IsNull()) return;
+
+  // is subshape of main shape?
+  TopoDS_Shape aMainShape = myMeshDS->ShapeToMesh();
+  if (aMainShape.IsNull()) {
+    myIsSubshape = false;
+  }
+  else {
+    TopTools_IndexedMapOfShape aMap;
+    TopExp::MapShapes(aMainShape, aMap);
+    myIsSubshape = IsSubShape(aMap, myShape);
+  }
+
+  if (!myIsSubshape)
+  {
+    myElementsOnShapePtr.reset(new Controls::ElementsOnShape());
+    myElementsOnShapePtr->SetTolerance(myTolerance);
+    myElementsOnShapePtr->SetAllNodes(false); // lays on, while true means "belong"
+    myElementsOnShapePtr->SetMesh(myMeshDS);
+    myElementsOnShapePtr->SetShape(myShape, myType);
+  }
 }
 
 bool Controls::LyingOnGeom::IsSatisfy( long theId )
@@ -209,6 +306,12 @@ bool Controls::LyingOnGeom::IsSatisfy( long theId )
   if ( myMeshDS == 0 || myShape.IsNull() )
     return false;
 
+  if (!myIsSubshape)
+  {
+    return myElementsOnShapePtr->IsSatisfy(theId);
+  }
+
+  // Case of submesh
   if( myType == SMDSAbs_Node )
   {
     if( const SMDS_MeshNode* aNode = myMeshDS->FindNode( theId ) )
@@ -254,6 +357,7 @@ bool Controls::LyingOnGeom::IsSatisfy( long theId )
 void Controls::LyingOnGeom::SetType( SMDSAbs_ElementType theType )
 {
   myType = theType;
+  init();
 }
 
 SMDSAbs_ElementType Controls::LyingOnGeom::GetType() const
@@ -266,13 +370,23 @@ TopoDS_Shape Controls::LyingOnGeom::GetShape()
   return myShape;
 }
 
-const SMESHDS_Mesh*
-Controls::LyingOnGeom::
-GetMeshDS() const
+const SMESHDS_Mesh* Controls::LyingOnGeom::GetMeshDS() const
 {
   return myMeshDS;
 }
 
+void Controls::LyingOnGeom::SetTolerance (double theTolerance)
+{
+  myTolerance = theTolerance;
+  if (!myIsSubshape)
+    init();
+}
+
+double Controls::LyingOnGeom::GetTolerance()
+{
+  return myTolerance;
+}
+
 bool Controls::LyingOnGeom::Contains( const SMESHDS_Mesh*     theMeshDS,
                                       const TopoDS_Shape&     theShape,
                                       const SMDS_MeshElement* theElem,
@@ -847,6 +961,17 @@ char* BelongToGeom_i::GetShapeID()
   return CORBA::string_dup( myShapeID );
 }
 
+void BelongToGeom_i::SetTolerance( CORBA::Double theToler )
+{
+  myBelongToGeomPtr->SetTolerance( theToler );
+  TPythonDump()<<this<<".SetTolerance("<<theToler<<")";
+}
+
+CORBA::Double BelongToGeom_i::GetTolerance()
+{
+  return myBelongToGeomPtr->GetTolerance();
+}
+
 /*
   Class       : BelongToSurface_i
   Description : Predicate for selection on geometrical support
@@ -1091,6 +1216,17 @@ char* LyingOnGeom_i::GetShapeID()
   return CORBA::string_dup( myShapeID );
 }
 
+void LyingOnGeom_i::SetTolerance( CORBA::Double theToler )
+{
+  myLyingOnGeomPtr->SetTolerance( theToler );
+  TPythonDump()<<this<<".SetTolerance("<<theToler<<")";
+}
+
+CORBA::Double LyingOnGeom_i::GetTolerance()
+{
+  return myLyingOnGeomPtr->GetTolerance();
+}
+
 /*
   Class       : FreeBorders_i
   Description : Predicate for free borders
index f52f44785576cad94c188e95451002989408d503..1939ddab7a35cefc0237177815010a58c0c1e8e7 100644 (file)
@@ -46,7 +46,7 @@ namespace SMESH
 
   namespace Controls
   {
-    
+
     /*
       Class       : BelongToGeom
       Description : Predicate for verifying whether entiy belong to
@@ -56,25 +56,33 @@ namespace SMESH
     {
     public:
       BelongToGeom();
-      
+
       virtual void                    SetMesh( const SMDS_Mesh* theMesh );
       virtual void                    SetGeom( const TopoDS_Shape& theShape );
-      
+
       virtual bool                    IsSatisfy( long theElementId );
-      
+
       virtual void                    SetType( SMDSAbs_ElementType theType );
       virtual                         SMDSAbs_ElementType GetType() const;
-      
+
       TopoDS_Shape                    GetShape();
       const SMESHDS_Mesh*             GetMeshDS() const;
-      
+
+      void                            SetTolerance( double );
+      double                          GetTolerance();
+
     private:
+      virtual void                    init();
+
       TopoDS_Shape                    myShape;
       const SMESHDS_Mesh*             myMeshDS;
       SMDSAbs_ElementType             myType;
+      bool                            myIsSubshape;
+      double                          myTolerance;          // only if myIsSubshape == false
+      Controls::ElementsOnShapePtr    myElementsOnShapePtr; // only if myIsSubshape == false
     };
     typedef boost::shared_ptr<BelongToGeom> BelongToGeomPtr;
-    
+
     /*
       Class       : LyingOnGeom
       Description : Predicate for verifying whether entiy lying or partially lying on
@@ -95,6 +103,9 @@ namespace SMESH
       
       TopoDS_Shape                    GetShape();
       const SMESHDS_Mesh*             GetMeshDS() const;
+
+      void                            SetTolerance( double );
+      double                          GetTolerance();
       
       virtual bool                    Contains( const SMESHDS_Mesh*     theMeshDS,
                                                const TopoDS_Shape&     theShape,
@@ -102,9 +113,14 @@ namespace SMESH
                                                TopAbs_ShapeEnum        theFindShapeEnum,
                                                TopAbs_ShapeEnum        theAvoidShapeEnum = TopAbs_SHAPE );
     private:
+      virtual void                    init();
+
       TopoDS_Shape                    myShape;
       const SMESHDS_Mesh*             myMeshDS;
       SMDSAbs_ElementType             myType;
+      bool                            myIsSubshape;
+      double                          myTolerance;          // only if myIsSubshape == false
+      Controls::ElementsOnShapePtr    myElementsOnShapePtr; // only if myIsSubshape == false
     };
     typedef boost::shared_ptr<LyingOnGeom> LyingOnGeomPtr;
   }
@@ -365,6 +381,9 @@ namespace SMESH
     void                            SetShape( const char* theID, const char* theName );
     char*                           GetShapeName();
     char*                           GetShapeID();
+
+    void                            SetTolerance( CORBA::Double );
+    CORBA::Double                   GetTolerance();
     
   protected:
     Controls::BelongToGeomPtr       myBelongToGeomPtr;
@@ -463,6 +482,9 @@ namespace SMESH
     void                            SetShape( const char* theID, const char* theName );
     char*                           GetShapeName();
     char*                           GetShapeID();
+
+    void                            SetTolerance( CORBA::Double );
+    CORBA::Double                   GetTolerance();
     
   protected:
     Controls::LyingOnGeomPtr        myLyingOnGeomPtr;