Salome HOME
0020168: EDF SMESH 953: uncomplete selection with filter 'belong on geom'
authordmv <dmv@opencascade.com>
Fri, 20 Feb 2009 08:05:52 +0000 (08:05 +0000)
committerdmv <dmv@opencascade.com>
Fri, 20 Feb 2009 08:05:52 +0000 (08:05 +0000)
idl/SMESH_Filter.idl
src/Controls/SMESH_Controls.cxx
src/Controls/SMESH_ControlsDef.hxx
src/SMESHGUI/SMESHGUI_FilterDlg.cxx
src/SMESH_I/SMESH_Filter_i.cxx
src/SMESH_I/SMESH_Filter_i.hxx

index b4484531604cdb3a0dc7965ee8c7948e31f04217..01cf9f2f8084f66b28c6fcf6b14299a3693542f6 100644 (file)
@@ -151,6 +151,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();
@@ -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 2f25357cd8c2de8ff4f3f657a8a6af9733819aa8..aeb348b05e80ba3c41179098da7d194e01208b50 100644 (file)
@@ -24,6 +24,7 @@
 #include <set>
 
 #include <BRepAdaptor_Surface.hxx>
+#include <BRepClass_FaceClassifier.hxx>
 #include <BRep_Tool.hxx>
 #include <Geom_CylindricalSurface.hxx>
 #include <Geom_Plane.hxx>
@@ -35,6 +36,8 @@
 #include <TColgp_Array1OfXYZ.hxx>
 #include <TopAbs.hxx>
 #include <TopoDS.hxx>
+#include <TopoDS_Vertex.hxx>
+#include <TopoDS_Edge.hxx>
 #include <TopoDS_Face.hxx>
 #include <TopoDS_Shape.hxx>
 #include <gp_Ax3.hxx>
@@ -2681,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 dba2359587b21fbc9cf575143faf5d4971398594..8fb0cd63fbb7416351e589cfb6f91db040c49245 100644 (file)
 #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 <TopoDS_Face.hxx>
+#include <TopTools_MapOfShape.hxx>
+#include <BRepClass3d_SolidClassifier.hxx>
 
 #include "SMDSAbs_ElementType.hxx"
 #include "SMDS_MeshNode.hxx"
@@ -645,6 +648,52 @@ namespace SMESH{
     };
     
     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;
       
 
     /*
index baf6c82a65c173fd0c77228e27d31c7442cfb17f..c91babf3118318e31026c58c530a1f76210876a8 100755 (executable)
@@ -853,7 +853,9 @@ void SMESHGUI_FilterTable::SetCriterion (const int                       theRow,
   if (theCriterion.Compare == FT_EqualTo ||
        theCriterion.Type    == FT_BelongToPlane ||
        theCriterion.Type    == FT_BelongToCylinder ||
-       theCriterion.Type    == FT_BelongToGenSurface)
+       theCriterion.Type    == FT_BelongToGenSurface ||
+       theCriterion.Type    == FT_BelongToGeom ||
+       theCriterion.Type    == FT_LyingOnGeom)
   {
     QTableItem* anItem = aTable->item(theRow, 0);
     if (!myAddWidgets.contains(anItem))
@@ -996,8 +998,6 @@ void SMESHGUI_FilterTable::updateAdditionalWidget()
 
   ComboItem* anItem = ((ComboItem*)aTable->item(aRow, 0));
   bool toEnable = ((ComboItem*)aTable->item(aRow, 1))->GetValue() == FT_EqualTo &&
-                  GetCriterionType(aRow) != FT_BelongToGeom &&
-                  GetCriterionType(aRow) != FT_LyingOnGeom &&
                   GetCriterionType(aRow) != FT_RangeOfIds &&
                   GetCriterionType(aRow) != FT_FreeEdges &&
                   GetCriterionType(aRow) != FT_BadOrientedVolume;
index 68ad197b69c10624c1854be75cb1991be06ff472..a11e6336f765942b4671e7dc69aa2ba67b6d4817 100644 (file)
@@ -181,6 +181,64 @@ GetMeshDS() const
   return myMeshDS;
 }
 
+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);
+  }
+}
+
+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
@@ -271,6 +329,43 @@ GetMeshDS() const
   return myMeshDS;
 }
 
+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);
+  }
+}
+
+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,
@@ -845,6 +940,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
@@ -1089,6 +1195,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
@@ -1896,6 +2013,7 @@ static inline bool getCriteria( Predicate_i*                thePred,
       theCriteria[ i ].ThresholdStr  = aPred->GetShapeName();
       theCriteria[ i ].ThresholdID   = aPred->GetShapeID();
       theCriteria[ i ].TypeOfElement = aPred->GetElementType();
+      theCriteria[ i ].Tolerance     = aPred->GetTolerance();
 
       return true;
     }
@@ -1931,6 +2049,7 @@ static inline bool getCriteria( Predicate_i*                thePred,
       theCriteria[ i ].ThresholdStr  = aPred->GetShapeName();
       theCriteria[ i ].ThresholdID   = aPred->GetShapeID();
       theCriteria[ i ].TypeOfElement = aPred->GetElementType();
+      theCriteria[ i ].Tolerance     = aPred->GetTolerance();
 
       return true;
     }
@@ -2124,6 +2243,7 @@ CORBA::Boolean Filter_i::SetCriteria( const SMESH::Filter::Criteria& theCriteria
           SMESH::BelongToGeom_ptr tmpPred = aFilterMgr->CreateBelongToGeom();
           tmpPred->SetElementType( aTypeOfElem );
           tmpPred->SetShape( aThresholdID, aThresholdStr );
+         tmpPred->SetTolerance( aTolerance );
           aPredicate = tmpPred;
         }
         break;
@@ -2150,6 +2270,7 @@ CORBA::Boolean Filter_i::SetCriteria( const SMESH::Filter::Criteria& theCriteria
           SMESH::LyingOnGeom_ptr tmpPred = aFilterMgr->CreateLyingOnGeom();
           tmpPred->SetElementType( aTypeOfElem );
          tmpPred->SetShape( aThresholdID, aThresholdStr );
+         tmpPred->SetTolerance( aTolerance );
           aPredicate = tmpPred;
         }
         break;
index 71e942fc3c6511535f967c80b7a36a736121ebce..da6ee482c80e1a969c52fb920c1e37acb7111bbe 100644 (file)
@@ -66,11 +66,20 @@ namespace SMESH
       
       TopoDS_Shape                    GetShape();
       const SMESHDS_Mesh*             GetMeshDS() const;
+
+      void                            SetTolerance( double );
+      double                          GetTolerance();
+      
+    private:
+      virtual void                    init();
       
     private:
       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;
     
@@ -94,16 +103,26 @@ 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,
                                                const SMDS_MeshElement* theElem,
                                                TopAbs_ShapeEnum        theFindShapeEnum,
                                                TopAbs_ShapeEnum        theAvoidShapeEnum = TopAbs_SHAPE );
+
+    private:
+      virtual void                    init();
+
     private:
       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;
   }
@@ -364,6 +383,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;
@@ -462,6 +484,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;