diff --git a/doc/salome/gui/SMESH/input/selection_filter_library.doc b/doc/salome/gui/SMESH/input/selection_filter_library.doc
index 70dc9a65f..070f79b6a 100644
--- a/doc/salome/gui/SMESH/input/selection_filter_library.doc
+++ b/doc/salome/gui/SMESH/input/selection_filter_library.doc
@@ -50,13 +50,17 @@ created. You have to select the mesh and the button will be enabled.
Some criteria are applicable to all Entity types:
-
-Belong to Geom selects entities whose all nodes belong to a
-submesh on the shape defined by Threshold Value. The threshold shape
-must be sub-shape of the main shape of mesh.
+Belong to Geom selects entities whose all nodes
+lays on the shape defined by Threshold Value.
+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.
-
-Lying on Geom selects entities whose at least one node belongs to a
-submesh on the shape defined by Threshold Value. The threshold shape
-must be sub-shape of the main shape of mesh.
+Lying on Geom selects entities whose at least one node
+lays on the shape defined by Threshold Value.
+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.
-
Range of IDs allows selection of entities having certain
IDs. Threshold Value can be like this: "1,2,3,50-60,63,67,70-78"
diff --git a/idl/SMESH_Filter.idl b/idl/SMESH_Filter.idl
index fcb5a9936..acffc1425 100644
--- a/idl/SMESH_Filter.idl
+++ b/idl/SMESH_Filter.idl
@@ -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();
diff --git a/src/Controls/SMESH_Controls.cxx b/src/Controls/SMESH_Controls.cxx
index 86ca96202..3350a966e 100644
--- a/src/Controls/SMESH_Controls.cxx
+++ b/src/Controls/SMESH_Controls.cxx
@@ -22,19 +22,27 @@
#include
#include
+#include
#include
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
#include
#include
#include
+
#include
#include
#include
#include
#include
-#include
-#include
-#include
-#include
+
#include
#include
#include
@@ -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());
+}
diff --git a/src/Controls/SMESH_ControlsDef.hxx b/src/Controls/SMESH_ControlsDef.hxx
index 84500897a..9eea42566 100644
--- a/src/Controls/SMESH_ControlsDef.hxx
+++ b/src/Controls/SMESH_ControlsDef.hxx
@@ -23,14 +23,19 @@
#include
#include