filters_ex33.py
filters_ex34.py
filters_ex36.py
+ filters_belong2group.py
grouping_elements_ex01.py
grouping_elements_ex02.py
grouping_elements_ex03.py
--- /dev/null
+# Belong to Mesh Group criterion
+
+# create mesh
+from SMESH_mechanic import *
+
+# create a group of all faces (quadrangles) generated on sub_face3
+faces_on_face3 = mesh.MakeGroup("faces_on_face3", SMESH.FACE, SMESH.FT_BelongToGeom,'=',sub_face3)
+print "There are %s quadrangles generated on '%s' and included in the group '%s'" % ( faces_on_face3.Size(), sub_face3.GetName(), faces_on_face3.GetName() )
+
+# create a group of all the rest quadrangles, generated on other faces by combining 2 criteria:
+# - negated FT_BelongToMeshGroup to select elements not included in faces_on_face3
+# - FT_ElemGeomType to select quadrangles
+not_on_face3 = smesh.GetCriterion( SMESH.FACE, SMESH.FT_BelongToMeshGroup,'=',faces_on_face3, SMESH.FT_LogicalNOT )
+quadrangles = smesh.GetCriterion( SMESH.FACE, SMESH.FT_ElemGeomType,'=',SMESH.Geom_QUADRANGLE )
+
+rest_quads = mesh.MakeGroupByCriteria("rest_quads", [ not_on_face3, quadrangles ])
+print "'%s' group includes all the rest %s quadrangles" % ( rest_quads.GetName(), rest_quads.Size() )
+
AND and \a OR. In addition, applied filter criterion can be reverted
using logical operator \a NOT.
-Mesh filters use the functionality of \ref quality_page "mesh quality controls"
+Some filtering criteria use the functionality of \ref quality_page "mesh quality controls"
to filter mesh nodes / elements by specific characteristic (Area, Length, etc).
The functinality of mesh filters is available in both GUI and TUI
Each filter can be applicable to \b Nodes, \b Edges, \b Faces or \b
Volumes. You can combine many criteria in one filter, but they all
-must be of the same <b>Entity type</b>.
-\n The \b Add button creates a new criterion at the end of the list of
+must be of the same <b>Entity type</b>. <br>
+The \b Add button creates a new criterion at the end of the list of
criteria. The \b Insert button creates a new criterion before the
selected criterion. The \b Remove button deletes the selected
criterion. The \b Clear button deletes all criteria.
<br>
In the \b Source field you choose if the filter will be applied to
the whole \b Mesh, the <b>Initial Selection</b> or the <b>Current
-Group</b>. If \b Mesh is chosen, the elements satisfying the filter
+Dialog</b>. If \b Mesh is chosen, the elements satisfying the filter
will be selected in the 3D Viewer. If <b> Initial Selection</b> is
chosen, the filter will be applied to the selected elements and the
elements rejected by the filter will be deselected. If <b>Current
-Group</b> is chosen, the filter will be applied to the list of
+Dialog</b> is chosen, the filter will be applied to the list of
elements in the current dialog and the elements rejected
by the filter will be removed from the list.
<br>
algorithm works faster, if this is any other
shape, the algorithm works slower.
</li><li>
+<b>Belong to Mesh Group</b> selects entities included into a mesh group
+defined by <b>Threshold Value</b>.
+</li><li>
<b>Range of IDs</b> allows selection of entities with the specified
IDs.
<b>Threshold Value</b> can be, for example: "1,2,3,50-60,63,67,70-78"
\page tui_filters_page Filters usage
+\tableofcontents
+
Filters allow picking only the mesh elements satisfying to a
specific condition or a set of conditions. Filters can be used to create
or edit mesh groups, remove elements from the mesh object, control
mesh quality by different parameters, etc.
-Several filters can be combined together by using logical operators \a
-AND and \a OR. In addition, applied filter criterion can be reverted
-using logical operator \a NOT.
+Several filtering criteria can be combined together by using logical
+operators \a AND and \a OR. In addition, applied filter criterion can
+be reverted using logical operator \a NOT.
Mesh filters use the functionality of mesh quality controls to filter
mesh nodes / elements by a specific characteristic (Area, Length, etc).
\sa \ref tui_over_constrained_faces
+\section filter_belong_to_group Belong to Mesh Group
+
+Filter mesh entities (nodes or elements) included in a mesh group
+defined by threshold value:
+- element type can be any entity type, from \a SMESH.NODE to \a SMESH.VOLUME
+- functor type should be \a SMESH.FT_BelongToMeshGroup
+- threshold is mesh group object
+
+\tui_script{filters_belong2group.py}
+
\section filter_belong_to_geom Belong to Geom
Filter mesh entities (nodes or elements) which all nodes lie on the
FT_MultiConnection2D,
FT_Length,
FT_Length2D,
+ FT_BelongToMeshGroup,
FT_BelongToGeom,
FT_BelongToPlane,
FT_BelongToCylinder,
*/
interface EqualVolumes: Predicate {};
+ /*!
+ * Logical functor (predicate) "Belong To Mesh Group".
+ * Verify whether a mesh element is included into a mesh group
+ */
+ interface BelongToMeshGroup: Predicate
+ {
+ void SetGroup( in SMESH::SMESH_GroupBase theGroup );
+ void SetGroupID( in string theID ); // IOR or StoreName
+ SMESH::SMESH_GroupBase GetGroup();
+ };
+
/*!
* Logical functor (predicate) "Belong To Geometry".
* Verify whether mesh element or node belong to pointed Geom Object
/*!
* Create numerical functors
*/
- MinimumAngle CreateMinimumAngle();
- AspectRatio CreateAspectRatio();
- AspectRatio3D CreateAspectRatio3D();
- Warping CreateWarping();
- Taper CreateTaper();
- Skew CreateSkew();
- Area CreateArea();
- Volume3D CreateVolume3D();
+ MinimumAngle CreateMinimumAngle();
+ AspectRatio CreateAspectRatio();
+ AspectRatio3D CreateAspectRatio3D();
+ Warping CreateWarping();
+ Taper CreateTaper();
+ Skew CreateSkew();
+ Area CreateArea();
+ Volume3D CreateVolume3D();
MaxElementLength2D CreateMaxElementLength2D();
MaxElementLength3D CreateMaxElementLength3D();
- Length CreateLength();
- Length2D CreateLength2D();
- MultiConnection CreateMultiConnection();
- MultiConnection2D CreateMultiConnection2D();
- BallDiameter CreateBallDiameter();
+ Length CreateLength();
+ Length2D CreateLength2D();
+ MultiConnection CreateMultiConnection();
+ MultiConnection2D CreateMultiConnection2D();
+ BallDiameter CreateBallDiameter();
/*!
- * Create logical functors ( predicates )
- */
- BelongToGeom CreateBelongToGeom();
- BelongToPlane CreateBelongToPlane();
- BelongToCylinder CreateBelongToCylinder();
+ * Create logical functors ( predicates )
+ */
+ BelongToMeshGroup CreateBelongToMeshGroup();
+ BelongToGeom CreateBelongToGeom();
+ BelongToPlane CreateBelongToPlane();
+ BelongToCylinder CreateBelongToCylinder();
BelongToGenSurface CreateBelongToGenSurface();
- LyingOnGeom CreateLyingOnGeom();
+ LyingOnGeom CreateLyingOnGeom();
- FreeBorders CreateFreeBorders();
- FreeEdges CreateFreeEdges();
- FreeNodes CreateFreeNodes();
- FreeFaces CreateFreeFaces();
+ FreeBorders CreateFreeBorders();
+ FreeEdges CreateFreeEdges();
+ FreeNodes CreateFreeNodes();
+ FreeFaces CreateFreeFaces();
- EqualNodes CreateEqualNodes();
- EqualEdges CreateEqualEdges();
- EqualFaces CreateEqualFaces();
- EqualVolumes CreateEqualVolumes();
+ EqualNodes CreateEqualNodes();
+ EqualEdges CreateEqualEdges();
+ EqualFaces CreateEqualFaces();
+ EqualVolumes CreateEqualVolumes();
- RangeOfIds CreateRangeOfIds();
+ RangeOfIds CreateRangeOfIds();
- BadOrientedVolume CreateBadOrientedVolume();
- BareBorderVolume CreateBareBorderVolume();
- BareBorderFace CreateBareBorderFace();
+ BadOrientedVolume CreateBadOrientedVolume();
+ BareBorderVolume CreateBareBorderVolume();
+ BareBorderFace CreateBareBorderFace();
OverConstrainedVolume CreateOverConstrainedVolume();
OverConstrainedFace CreateOverConstrainedFace();
- LinearOrQuadratic CreateLinearOrQuadratic();
+ LinearOrQuadratic CreateLinearOrQuadratic();
- GroupColor CreateGroupColor();
- ElemGeomType CreateElemGeomType();
- ElemEntityType CreateElemEntityType();
- CoplanarFaces CreateCoplanarFaces();
- ConnectedElements CreateConnectedElements();
+ GroupColor CreateGroupColor();
+ ElemGeomType CreateElemGeomType();
+ ElemEntityType CreateElemEntityType();
+ CoplanarFaces CreateCoplanarFaces();
+ ConnectedElements CreateConnectedElements();
/*!
- * Create comparators ( predicates )
- */
+ * Create comparators ( predicates )
+ */
LessThan CreateLessThan();
MoreThan CreateMoreThan();
EqualTo CreateEqualTo();
* (corresponds to the "hue" parameter of the color - must be in range [0, 360])
*/
long GetColorNumber();
- };
+
+ /*!
+ * Returns \c true if \c this group depends on the \a other via
+ * FT_BelongToMeshGroup predicate or vice versa
+ */
+ boolean IsInDependency( in SMESH_GroupBase other );
+ };
/*!
* SMESH_Group: interface of a standalone group object
*/
interface SMESH_GroupOnFilter : SMESH_GroupBase
{
- void SetFilter( in Filter theFilter);
+ void SetFilter( in Filter theFilter) raises (SALOME::SALOME_Exception);
Filter GetFilter();
};
}
}
+/*
+ Class : BelongToMeshGroup
+ Description : Verify whether a mesh element is included into a mesh group
+*/
+BelongToMeshGroup::BelongToMeshGroup(): myGroup( 0 )
+{
+}
+
+void BelongToMeshGroup::SetGroup( SMESHDS_GroupBase* g )
+{
+ myGroup = g;
+}
+
+void BelongToMeshGroup::SetStoreName( const std::string& sn )
+{
+ myStoreName = sn;
+}
+
+void BelongToMeshGroup::SetMesh( const SMDS_Mesh* theMesh )
+{
+ if ( myGroup && myGroup->GetMesh() != theMesh )
+ {
+ myGroup = 0;
+ }
+ if ( !myGroup && !myStoreName.empty() )
+ {
+ if ( const SMESHDS_Mesh* aMesh = dynamic_cast<const SMESHDS_Mesh*>(theMesh))
+ {
+ const std::set<SMESHDS_GroupBase*>& grps = aMesh->GetGroups();
+ std::set<SMESHDS_GroupBase*>::const_iterator g = grps.begin();
+ for ( ; g != grps.end() && !myGroup; ++g )
+ if ( *g && myStoreName == (*g)->GetStoreName() )
+ myGroup = *g;
+ }
+ }
+}
+
+bool BelongToMeshGroup::IsSatisfy( long theElementId )
+{
+ return myGroup ? myGroup->Contains( theElementId ) : false;
+}
+
+SMDSAbs_ElementType BelongToMeshGroup::GetType() const
+{
+ return myGroup ? myGroup->GetType() : SMDSAbs_All;
+}
/*
- ElementsOnSurface
+ ElementsOnSurface
*/
ElementsOnSurface::ElementsOnSurface()
class SMESHDS_Mesh;
class SMESHDS_SubMesh;
+class SMESHDS_GroupBase;
class gp_Pnt;
TMapOfLink& theNonManifold,
SMDS_MeshFace* theNextFace ) const;
- void getFacesByLink( const Link& theLink,
- TVectorOfFacePtr& theFaces ) const;
+ void getFacesByLink( const Link& theLink,
+ TVectorOfFacePtr& theFaces ) const;
private:
const SMDS_Mesh* myMesh;
};
typedef boost::shared_ptr<ManifoldPart> ManifoldPartPtr;
+ /*
+ Class : BelongToMeshGroup
+ Description : Verify whether a mesh element is included into a mesh group
+ */
+ class SMESHCONTROLS_EXPORT BelongToMeshGroup : public virtual Predicate
+ {
+ public:
+ BelongToMeshGroup();
+ virtual void SetMesh( const SMDS_Mesh* theMesh );
+ virtual bool IsSatisfy( long theElementId );
+ virtual SMDSAbs_ElementType GetType() const;
+
+ void SetGroup( SMESHDS_GroupBase* g );
+ void SetStoreName( const std::string& sn );
+ const SMESHDS_GroupBase* GetGroup() const { return myGroup; }
+
+ private:
+ SMESHDS_GroupBase* myGroup;
+ std::string myStoreName;
+ };
+ typedef boost::shared_ptr<BelongToMeshGroup> BelongToMeshGroupPtr;
/*
Class : ElementsOnSurface
TMeshModifTracer myMeshModifTracer;
TColStd_MapOfInteger myIds;
SMDSAbs_ElementType myType;
- //Handle(Geom_Surface) mySurf;
TopoDS_Face mySurf;
double myToler;
bool myUseBoundaries;
/*
Class : Functor
- Description : Root of all Functors
+ Description : Root of all Functors defined in ../Controls/SMESH_ControlsDef.hxx
*/
class SMESHCONTROLS_EXPORT Functor
{
#include <LightApp_Application.h>
#include <LightApp_SelectionMgr.h>
-#include <SalomeApp_Tools.h>
-#include <SalomeApp_Study.h>
-#include <SalomeApp_IntSpinBox.h>
+#include <SalomeApp_Application.h>
#include <SalomeApp_DoubleSpinBox.h>
+#include <SalomeApp_IntSpinBox.h>
+#include <SalomeApp_Study.h>
+#include <SalomeApp_Tools.h>
#include <SALOME_ListIO.hxx>
errMsg = tr( "GROUPCOLOR_ERROR" );
}
else if (aCriterion == SMESH::FT_RangeOfIds ||
+ aCriterion == SMESH::FT_BelongToMeshGroup ||
aCriterion == SMESH::FT_BelongToGeom ||
aCriterion == SMESH::FT_BelongToPlane ||
aCriterion == SMESH::FT_BelongToCylinder ||
}
}
else if ( aCriterionType != SMESH::FT_RangeOfIds &&
+ aCriterionType != SMESH::FT_BelongToMeshGroup &&
aCriterionType != SMESH::FT_BelongToGeom &&
aCriterionType != SMESH::FT_BelongToPlane &&
aCriterionType != SMESH::FT_BelongToCylinder &&
}
}
else if (theCriterion.Type != SMESH::FT_RangeOfIds &&
+ theCriterion.Type != SMESH::FT_BelongToMeshGroup &&
theCriterion.Type != SMESH::FT_BelongToGeom &&
theCriterion.Type != SMESH::FT_BelongToPlane &&
theCriterion.Type != SMESH::FT_BelongToCylinder &&
theCriterion.Type != SMESH::FT_OverConstrainedVolume &&
theCriterion.Type != SMESH::FT_LinearOrQuadratic)
{
+ // Numberic criterion
aTable->item( theRow, 2 )->setText(QString("%1").arg(theCriterion.Threshold, 0, 'g', 15));
}
else
case SMESH::FT_Length:
case SMESH::FT_Length2D: anIsDoubleCriterion = true; break;
+ case SMESH::FT_BelongToMeshGroup: break;
+
case SMESH::FT_BelongToGeom:
case SMESH::FT_BelongToPlane:
case SMESH::FT_BelongToCylinder:
case SMESH::FT_BelongToGenSurface:
- case SMESH::FT_LyingOnGeom: nbCompareSigns = 1; isThresholdEditable = true; break;
+ case SMESH::FT_LyingOnGeom: nbCompareSigns = 0; isThresholdEditable = true; break;
- case SMESH::FT_RangeOfIds: nbCompareSigns = 1; isThresholdEditable = true; break;
+ case SMESH::FT_RangeOfIds: nbCompareSigns = 0; isThresholdEditable = true; break;
case SMESH::FT_BadOrientedVolume:
case SMESH::FT_BareBorderVolume:
if (aCriteria.isEmpty())
{
aCriteria[ SMESH::FT_RangeOfIds ] = tr("RANGE_OF_IDS");
+ aCriteria[ SMESH::FT_BelongToMeshGroup ] = tr("BELONG_TO_MESH_GROUP");
aCriteria[ SMESH::FT_BelongToGeom ] = tr("BELONG_TO_GEOM");
aCriteria[ SMESH::FT_BelongToPlane ] = tr("BELONG_TO_PLANE");
aCriteria[ SMESH::FT_BelongToCylinder ] = tr("BELONG_TO_CYLINDER");
aCriteria[ SMESH::FT_MultiConnection ] = tr("MULTI_BORDERS");
aCriteria[ SMESH::FT_Length ] = tr("LENGTH");
aCriteria[ SMESH::FT_RangeOfIds ] = tr("RANGE_OF_IDS");
+ aCriteria[ SMESH::FT_BelongToMeshGroup ] = tr("BELONG_TO_MESH_GROUP");
aCriteria[ SMESH::FT_BelongToGeom ] = tr("BELONG_TO_GEOM");
aCriteria[ SMESH::FT_BelongToPlane ] = tr("BELONG_TO_PLANE");
aCriteria[ SMESH::FT_BelongToCylinder ] = tr("BELONG_TO_CYLINDER");
aCriteria[ SMESH::FT_MaxElementLength2D ] = tr("MAX_ELEMENT_LENGTH_2D");
aCriteria[ SMESH::FT_FreeEdges ] = tr("FREE_EDGES");
aCriteria[ SMESH::FT_RangeOfIds ] = tr("RANGE_OF_IDS");
+ aCriteria[ SMESH::FT_BelongToMeshGroup ] = tr("BELONG_TO_MESH_GROUP");
aCriteria[ SMESH::FT_BelongToGeom ] = tr("BELONG_TO_GEOM");
aCriteria[ SMESH::FT_BelongToPlane ] = tr("BELONG_TO_PLANE");
aCriteria[ SMESH::FT_BelongToCylinder ] = tr("BELONG_TO_CYLINDER");
{
aCriteria[ SMESH::FT_AspectRatio3D ] = tr("ASPECT_RATIO_3D");
aCriteria[ SMESH::FT_RangeOfIds ] = tr("RANGE_OF_IDS");
+ aCriteria[ SMESH::FT_BelongToMeshGroup ] = tr("BELONG_TO_MESH_GROUP");
aCriteria[ SMESH::FT_BelongToGeom ] = tr("BELONG_TO_GEOM");
aCriteria[ SMESH::FT_LyingOnGeom ] = tr("LYING_ON_GEOM");
aCriteria[ SMESH::FT_BadOrientedVolume ] = tr("BAD_ORIENTED_VOLUME");
if (aCriteria.isEmpty())
{
aCriteria[ SMESH::FT_RangeOfIds ] = tr("RANGE_OF_IDS");
+ aCriteria[ SMESH::FT_BelongToMeshGroup ] = tr("BELONG_TO_MESH_GROUP");
aCriteria[ SMESH::FT_BelongToGeom ] = tr("BELONG_TO_GEOM");
aCriteria[ SMESH::FT_BelongToPlane ] = tr("BELONG_TO_PLANE");
aCriteria[ SMESH::FT_BelongToCylinder ] = tr("BELONG_TO_CYLINDER");
{
aCriteria[ SMESH::FT_BallDiameter ] = tr("BALL_DIAMETER");
aCriteria[ SMESH::FT_RangeOfIds ] = tr("RANGE_OF_IDS");
+ aCriteria[ SMESH::FT_BelongToMeshGroup ] = tr("BELONG_TO_MESH_GROUP");
aCriteria[ SMESH::FT_BelongToGeom ] = tr("BELONG_TO_GEOM");
aCriteria[ SMESH::FT_BelongToPlane ] = tr("BELONG_TO_PLANE");
aCriteria[ SMESH::FT_BelongToCylinder ] = tr("BELONG_TO_CYLINDER");
if (aCriteria.isEmpty())
{
aCriteria[ SMESH::FT_RangeOfIds ] = tr("RANGE_OF_IDS");
+ aCriteria[ SMESH::FT_BelongToMeshGroup ] = tr("BELONG_TO_MESH_GROUP");
aCriteria[ SMESH::FT_BelongToGeom ] = tr("BELONG_TO_GEOM");
aCriteria[ SMESH::FT_BelongToPlane ] = tr("BELONG_TO_PLANE");
aCriteria[ SMESH::FT_BelongToCylinder ] = tr("BELONG_TO_CYLINDER");
if (aCriteria.isEmpty())
{
aCriteria[ SMESH::FT_RangeOfIds ] = tr("RANGE_OF_IDS");
+ aCriteria[ SMESH::FT_BelongToMeshGroup ] = tr("BELONG_TO_MESH_GROUP");
aCriteria[ SMESH::FT_BelongToGeom ] = tr("BELONG_TO_GEOM");
aCriteria[ SMESH::FT_LyingOnGeom ] = tr("LYING_ON_GEOM");
aCriteria[ SMESH::FT_LinearOrQuadratic ] = tr("LINEAR");
mySourceWg = 0;
myTypes = theTypes;
myMesh = SMESH::SMESH_Mesh::_nil();
+ myGroup = SMESH::SMESH_GroupOnFilter::_nil();
myIObjects.Clear();
myIsSelectionChanged = false;
myToRestoreSelMode = false;
if (aType == SMESH::FT_BelongToCylinder ||
aType == SMESH::FT_BelongToPlane ||
aType == SMESH::FT_BelongToGenSurface ) {
- CORBA::Object_var anObject = SMESH::SObjectToObject(aList[ 0 ]);
- //GEOM::GEOM_Object_var aGeomObj = GEOM::GEOM_Object::_narrow(aList[ 0 ]->GetObject());
+ CORBA::Object_var anObject = SMESH::SObjectToObject(aList[ 0 ]);
GEOM::GEOM_Object_var aGeomObj = GEOM::GEOM_Object::_narrow(anObject);
if (!aGeomObj->_is_nil()) {
TopoDS_Shape aFace;
myButtons[BTN_Apply]->setEnabled(isEnable);
}
+//=======================================================================
+// name : SMESHGUI_FilterDlg::SetGroup
+// Purpose : Set a group being edited
+//=======================================================================
+void SMESHGUI_FilterDlg::SetGroup(SMESH::SMESH_GroupOnFilter_var group)
+{
+ myGroup = group;
+}
+
//=======================================================================
// name : SMESHGUI_FilterDlg::SetSelection
// Purpose : Get filtered ids
const int type = myTable->GetCriterionType(aRow);
QList<int> types;
- types << SMESH::FT_BelongToGeom << SMESH::FT_BelongToPlane
- << SMESH::FT_BelongToCylinder << SMESH::FT_BelongToGenSurface
- << SMESH::FT_LyingOnGeom << SMESH::FT_CoplanarFaces
- << SMESH::FT_ConnectedElements;
+ types << SMESH::FT_BelongToGeom << SMESH::FT_BelongToPlane
+ << SMESH::FT_BelongToCylinder << SMESH::FT_BelongToGenSurface
+ << SMESH::FT_LyingOnGeom << SMESH::FT_CoplanarFaces
+ << SMESH::FT_ConnectedElements << SMESH::FT_BelongToMeshGroup;
if ( !types.contains( type ))
return;
}
break;
}
+ case SMESH::FT_BelongToMeshGroup: // get a group name and IOR
+ {
+ SMESH::SMESH_GroupBase_var grp = SMESH::IObjectToInterface<SMESH::SMESH_GroupBase>(anIO);
+ if ( !grp->_is_nil() )
+ {
+ if ( !myMesh->_is_nil() )
+ {
+ SMESH::SMESH_Mesh_var mesh = grp->GetMesh();
+ if ( ! myMesh->_is_equivalent( mesh ))
+ return;
+ }
+ if ( !myGroup->_is_nil() && myGroup->IsInDependency( grp ))
+ return; // avoid cyclic dependencies between Groups on Filter
+
+ SalomeApp_Application* app = dynamic_cast<SalomeApp_Application*>
+ ( SUIT_Session::session()->activeApplication() );
+ if( !app ) return;
+ CORBA::String_var IOR = app->orb()->object_to_string( grp );
+
+ myTable->SetThreshold(aRow, SMESH::toQStr( grp->GetName() ));
+ myTable->SetID (aRow, IOR.in() );
+ }
+ }
default: // get a GEOM object
{
GEOM::GEOM_Object_var anObj = SMESH::IObjectToInterface<GEOM::GEOM_Object>(anIO);
myIsSelectionChanged = true;
}
+ else if ( aCriterionType == SMESH::FT_BelongToMeshGroup )
+ {
+ SMESH_TypeFilter* typeFilter = 0;
+ switch ( myTable->GetType() )
+ {
+ case SMESH::NODE : typeFilter = new SMESH_TypeFilter( SMESH::GROUP_NODE ); break;
+ case SMESH::ELEM0D : typeFilter = new SMESH_TypeFilter( SMESH::GROUP_0D ); break;
+ case SMESH::BALL : typeFilter = new SMESH_TypeFilter( SMESH::GROUP_BALL ); break;
+ case SMESH::EDGE : typeFilter = new SMESH_TypeFilter( SMESH::GROUP_EDGE ); break;
+ case SMESH::FACE : typeFilter = new SMESH_TypeFilter( SMESH::GROUP_FACE ); break;
+ case SMESH::VOLUME : typeFilter = new SMESH_TypeFilter( SMESH::GROUP_VOLUME ); break;
+ case SMESH::ALL : typeFilter = new SMESH_TypeFilter( SMESH::GROUP ); break;
+ default : typeFilter = 0;
+ }
+ if ( typeFilter )
+ mySelectionMgr->installFilter( typeFilter );
+ }
else if ( aCriterionType == SMESH::FT_ConnectedElements )
{
QList<SUIT_SelectionFilter*> fList;
void SetSelection();
void SetMesh (SMESH::SMESH_Mesh_var);
+ void SetGroup (SMESH::SMESH_GroupOnFilter_var);
void SetSourceWg( QWidget*, const bool initOnApply = true );
void SetEnabled( bool setInViewer, bool diffSources );
LightApp_SelectionMgr* mySelectionMgr;
SVTK_Selector* mySelector;
SMESH::SMESH_Mesh_var myMesh;
+ SMESH::SMESH_GroupOnFilter_var myGroup;
bool myInitSourceWgOnApply;
bool myInsertEnabled;
bool myDiffSourcesEnabled;
return;
const int type = myTable->GetCriterionType(aRow);
- QList<int> types;
- types << SMESH::FT_BelongToGeom << SMESH::FT_BelongToPlane
- << SMESH::FT_BelongToCylinder << SMESH::FT_BelongToGenSurface
- << SMESH::FT_LyingOnGeom << SMESH::FT_CoplanarFaces
- << SMESH::FT_ConnectedElements;
+ QList<int> types;
+ types << SMESH::FT_BelongToGeom << SMESH::FT_BelongToPlane
+ << SMESH::FT_BelongToCylinder << SMESH::FT_BelongToGenSurface
+ << SMESH::FT_LyingOnGeom << SMESH::FT_CoplanarFaces
+ << SMESH::FT_ConnectedElements << SMESH::FT_BelongToMeshGroup;
if ( !types.contains( type ))
return;
}
break;
}
+ case SMESH::FT_BelongToMeshGroup: // get a group name and IOR
+ {
+ myTable->SetThreshold(aRow, anIO->getName() );
+ }
default: // get a GEOM object
{
GEOM::GEOM_Object_var anObj = SMESH::IObjectToInterface<GEOM::GEOM_Object>(anIO);
}
// update a visible group accoding to a changed contents
if ( !isConversion && anActor->GetVisibility() )
+ {
SMESH::Update( anIO, true );
+ SMESH::RepaintCurrentView();
+ }
}
}
}
myFilterDlg->SetEnabled( /*setInViewer=*/isStandalone,
/*diffSources=*/isStandalone );
myFilterDlg->SetMesh( myMesh );
+ myFilterDlg->SetGroup( myGroupOnFilter );
myFilterDlg->SetSelection();
myFilterDlg->SetSourceWg( myElements, false );
-
myFilterDlg->show();
}
#include "SMESHGUI_VTKUtils.h"
#include "SMESHGUI.h"
-#include "SMESHGUI_Utils.h"
#include "SMESHGUI_Filter.h"
+#include "SMESHGUI_Utils.h"
+#include "SMDS_Mesh.hxx"
+#include "SMESH_Actor.h"
+#include "SMESH_ActorUtils.h"
+#include "SMESH_CellLabelActor.h"
#include "SMESH_ControlsDef.hxx"
-
-#include <SMESH_Actor.h>
-#include <SMESH_ActorUtils.h>
#include "SMESH_NodeLabelActor.h"
-#include "SMESH_CellLabelActor.h"
-#include <SMESH_ObjectDef.h>
-#include <SMDS_Mesh.hxx>
+#include "SMESH_ObjectDef.h"
// SALOME GUI includes
#include <SUIT_Desktop.h>
<source>OVER_CONSTRAINED_FACE</source>
<translation>Over-constrained faces</translation>
</message>
+ <message>
+ <source>BELONG_TO_MESH_GROUP</source>
+ <translation>Belong to Mesh Group</translation>
+ </message>
<message>
<source>BELONG_TO_CYLINDER</source>
<translation>Belong to Cylinder</translation>
case FT_MultiConnection2D: myStream<< "aMultiConnection2D"; break;
case FT_Length: myStream<< "aLength"; break;
case FT_Length2D: myStream<< "aLength2D"; break;
+ case FT_BelongToMeshGroup: myStream<< "aBelongToMeshGroup"; break;
case FT_BelongToGeom: myStream<< "aBelongToGeom"; break;
case FT_BelongToPlane: myStream<< "aBelongToPlane"; break;
case FT_BelongToCylinder: myStream<< "aBelongToCylinder"; break;
#include "SMDS_Mesh.hxx"
#include "SMDS_MeshElement.hxx"
#include "SMDS_MeshNode.hxx"
+#include "SMESHDS_GroupBase.hxx"
#include "SMESHDS_Mesh.hxx"
#include "SMESH_Gen_i.hxx"
#include "SMESH_Group_i.hxx"
return SMESH::FT_OverConstrainedFace;
}
+/*
+ Class : BelongToMeshGroup_i
+ Description : Verify whether a mesh element is included into a mesh group
+*/
+BelongToMeshGroup_i::BelongToMeshGroup_i()
+{
+ myBelongToMeshGroup = Controls::BelongToMeshGroupPtr( new Controls::BelongToMeshGroup() );
+ myFunctorPtr = myPredicatePtr = myBelongToMeshGroup;
+}
+
+BelongToMeshGroup_i::~BelongToMeshGroup_i()
+{
+ SetGroup( SMESH::SMESH_GroupBase::_nil() );
+}
+
+void BelongToMeshGroup_i::SetGroup( SMESH::SMESH_GroupBase_ptr theGroup )
+{
+ if ( myGroup->_is_equivalent( theGroup ))
+ return;
+
+ if ( ! myGroup->_is_nil() )
+ myGroup->UnRegister();
+
+ myGroup = SMESH_GroupBase::_duplicate( theGroup );
+
+ myBelongToMeshGroup->SetGroup( 0 );
+ if ( SMESH_GroupBase_i* gr_i = SMESH::DownCast< SMESH_GroupBase_i* >( myGroup ))
+ {
+ myBelongToMeshGroup->SetGroup( gr_i->GetGroupDS() );
+ myGroup->Register();
+ }
+}
+
+void BelongToMeshGroup_i::SetGroupID( const char* theID ) // IOR or StoreName
+{
+ myID = theID;
+ if ( strncmp( "IOR:", myID.c_str(), 4 ) == 0 ) // transient mode, no GUI
+ {
+ CORBA::Object_var obj = SMESH_Gen_i::GetORB()->string_to_object( myID.c_str() );
+ SetGroup( SMESH::SMESH_GroupBase::_narrow( obj ));
+ }
+ else if ( strncmp( ":0", myID.c_str(), 2 ) == 0 ) // transient mode + GUI
+ {
+ SMESH_Gen_i* aSMESHGen = SMESH_Gen_i::GetSMESHGen();
+ SALOMEDS::Study_var aStudy = aSMESHGen->GetCurrentStudy();
+ if ( !aStudy->_is_nil() ) {
+ SALOMEDS::SObject_wrap aSObj = aStudy->FindObjectID( myID.c_str() );
+ if ( !aSObj->_is_nil() ) {
+ CORBA::Object_var obj = aSObj->GetObject();
+ SetGroup( SMESH::SMESH_GroupBase::_narrow( obj ));
+ }
+ }
+ }
+ else if ( !myID.empty() ) // persistent mode
+ {
+ myBelongToMeshGroup->SetStoreName( myID );
+ }
+}
+
+std::string BelongToMeshGroup_i::GetGroupID()
+{
+ if ( myGroup->_is_nil() )
+ SMESH::SMESH_GroupBase_var( GetGroup() );
+
+ if ( !myGroup->_is_nil() )
+ myID = SMESH_Gen_i::GetORB()->object_to_string( myGroup );
+
+ return myID;
+}
+
+SMESH::SMESH_GroupBase_ptr BelongToMeshGroup_i::GetGroup()
+{
+ if ( myGroup->_is_nil() && myBelongToMeshGroup->GetGroup() )
+ {
+ // search for a group in a current study
+ SMESH_Gen_i* aSMESHGen = SMESH_Gen_i::GetSMESHGen();
+ if ( StudyContext* sc = aSMESHGen->GetCurrentStudyContext() )
+ {
+ int id = 1;
+ std::string ior;
+ while (true)
+ {
+ ior = sc->getIORbyId( id++ );
+ if ( ior.empty() ) break;
+ CORBA::Object_var obj = aSMESHGen->GetORB()->string_to_object( ior.c_str() );
+ if ( SMESH_GroupBase_i* g_i = SMESH::DownCast<SMESH_GroupBase_i*>( obj ))
+ if ( g_i->GetGroupDS() == myBelongToMeshGroup->GetGroup() )
+ {
+ SetGroup( g_i->_this() );
+ break;
+ }
+ }
+ }
+ }
+ return SMESH::SMESH_GroupBase::_duplicate( myGroup );
+}
+
+FunctorType BelongToMeshGroup_i::GetFunctorType()
+{
+ return SMESH::FT_BelongToMeshGroup;
+}
+
/*
Class : BelongToGeom_i
Description : Predicate for selection on geometrical support
}
+
/*
Class : LogicalBinary_i
Description : Base class for binary logical predicate
return anObj._retn();
}
+BelongToMeshGroup_ptr FilterManager_i::CreateBelongToMeshGroup()
+{
+ SMESH::BelongToMeshGroup_i* aServant = new SMESH::BelongToMeshGroup_i();
+ SMESH::BelongToMeshGroup_var anObj = aServant->_this();
+ TPythonDump()<<aServant<<" = "<<this<<".CreateBelongToMeshGroup()";
+ return anObj._retn();
+}
+
BelongToGeom_ptr FilterManager_i::CreateBelongToGeom()
{
SMESH::BelongToGeom_i* aServant = new SMESH::BelongToGeom_i();
if(!CORBA::is_nil(myMesh))
myMesh->UnRegister();
- //TPythonDump()<<this<<".UnRegister()";
+ myPredicate = 0;
+ FindBaseObjects();
}
//=======================================================================
myPredicate->GetPredicate()->SetMesh( aMesh );
TPythonDump()<<this<<".SetPredicate("<<myPredicate<<")";
}
- std::list<TPredicateChangeWaiter*>::iterator i = myWaiters.begin();
- for ( ; i != myWaiters.end(); ++i )
- (*i)->PredicateChanged();
+ NotifyerAndWaiter::Modified();
}
//=======================================================================
SALOMEDS::TMPFile_var SeqFile;
return SeqFile._retn();
}
-
-//================================================================================
-/*!
- * \brief Stores an object to be notified on change of predicate
- */
-//================================================================================
-
-void Filter_i::AddWaiter( TPredicateChangeWaiter* waiter )
+//=======================================================================
+// name : getCriteria
+// Purpose : Retrieve criterions from predicate
+//=======================================================================
+static inline void getPrediacates( Predicate_i* thePred,
+ std::vector<Predicate_i*> & thePredVec )
{
- if ( waiter )
- myWaiters.push_back( waiter );
-}
-
-//================================================================================
-/*!
- * \brief Removes an object to be notified on change of predicate
- */
-//================================================================================
+ const int aFType = thePred->GetFunctorType();
-void Filter_i::RemoveWaiter( TPredicateChangeWaiter* waiter )
-{
- myWaiters.remove( waiter );
+ switch ( aFType )
+ {
+ case FT_LogicalNOT:
+ {
+ Predicate_i* aPred = ( dynamic_cast<LogicalNOT_i*>( thePred ) )->GetPredicate_i();
+ getPrediacates( aPred, thePredVec );
+ break;
+ }
+ case FT_LogicalAND:
+ case FT_LogicalOR:
+ {
+ Predicate_i* aPred1 = ( dynamic_cast<LogicalBinary_i*>( thePred ) )->GetPredicate1_i();
+ Predicate_i* aPred2 = ( dynamic_cast<LogicalBinary_i*>( thePred ) )->GetPredicate2_i();
+ getPrediacates( aPred1, thePredVec );
+ getPrediacates( aPred2, thePredVec );
+ break;
+ }
+ default:;
+ }
+ thePredVec.push_back( thePred );
}
//=======================================================================
static inline bool getCriteria( Predicate_i* thePred,
SMESH::Filter::Criteria_out theCriteria )
{
- int aFType = thePred->GetFunctorType();
+ const int aFType = thePred->GetFunctorType();
switch ( aFType )
{
{
return true;
}
+ case FT_BelongToMeshGroup:
+ {
+ BelongToMeshGroup_i* aPred = dynamic_cast<BelongToMeshGroup_i*>( thePred );
+ SMESH::SMESH_GroupBase_var grp = aPred->GetGroup();
+ if ( !grp->_is_nil() )
+ {
+ theCriteria[ i ].ThresholdStr = grp->GetName();
+ theCriteria[ i ].ThresholdID = aPred->GetGroupID().c_str();
+ }
+ return true;
+ }
case FT_BelongToGeom:
{
BelongToGeom_i* aPred = dynamic_cast<BelongToGeom_i*>( thePred );
case SMESH::FT_EqualVolumes:
aPredicate = aFilterMgr->CreateEqualVolumes();
break;
+ case SMESH::FT_BelongToMeshGroup:
+ {
+ SMESH::BelongToMeshGroup_ptr tmpPred = aFilterMgr->CreateBelongToMeshGroup();
+ tmpPred->SetGroupID( aThresholdID );
+ aPredicate = tmpPred;
+ }
+ break;
case SMESH::FT_BelongToGeom:
{
SMESH::BelongToGeom_ptr tmpPred = aFilterMgr->CreateBelongToGeom();
}
}
+//================================================================================
+/*!
+ * \brief Find groups it depends on
+ */
+//================================================================================
+
+void Filter_i::FindBaseObjects()
+{
+ // release current groups
+ for ( size_t i = 0; i < myBaseGroups.size(); ++i )
+ if ( myBaseGroups[i] )
+ {
+ myBaseGroups[i]->RemoveModifWaiter( this );
+ myBaseGroups[i]->UnRegister();
+ }
+
+ // remember new groups
+ myBaseGroups.clear();
+ if ( myPredicate )
+ {
+ std::vector<Predicate_i*> predicates;
+ getPrediacates( myPredicate, predicates );
+ for ( size_t i = 0; i < predicates.size(); ++i )
+ if ( BelongToMeshGroup_i* bmg = dynamic_cast< BelongToMeshGroup_i* >( predicates[i] ))
+ {
+ SMESH::SMESH_GroupBase_var g = bmg->GetGroup();
+ SMESH_GroupBase_i* g_i = SMESH::DownCast< SMESH_GroupBase_i*>( g );
+ if ( g_i )
+ {
+ g_i->AddModifWaiter( this );
+ g_i->Register();
+ myBaseGroups.push_back( g_i );
+ }
+ }
+ }
+}
+
+//================================================================================
+/*!
+ * \brief When notified on removal of myBaseGroups[i], remove a reference to a
+ * group from a predicate
+ */
+//================================================================================
+
+void Filter_i::OnBaseObjModified(NotifyerAndWaiter* group, bool removed)
+{
+ if ( !removed )
+ return; // a GroupOnFilter holding this filter is notified automatically
+
+ if ( myPredicate )
+ {
+ std::vector<Predicate_i*> predicates;
+ getPrediacates( myPredicate, predicates );
+ for ( size_t i = 0; i < predicates.size(); ++i )
+ if ( BelongToMeshGroup_i* bmg = dynamic_cast< BelongToMeshGroup_i* >( predicates[i] ))
+ {
+ SMESH::SMESH_GroupBase_var g = bmg->GetGroup();
+ SMESH_GroupBase_i* g_i = SMESH::DownCast< SMESH_GroupBase_i*>( g );
+ if ( g_i == group )
+ {
+ bmg->SetGroup( SMESH::SMESH_GroupBase::_nil() );
+ bmg->SetGroupID( "" );
+ }
+ }
+ }
+
+ FindBaseObjects(); // release and update myBaseGroups;
+}
+
/*
FILTER LIBRARY
*/
{
switch ( theType )
{
- case FT_AspectRatio : return "Aspect ratio";
- case FT_Warping : return "Warping";
- case FT_MinimumAngle : return "Minimum angle";
- case FT_Taper : return "Taper";
- case FT_Skew : return "Skew";
- case FT_Area : return "Area";
- case FT_Volume3D : return "Volume3D";
- case FT_MaxElementLength2D: return "Max element length 2D";
- case FT_MaxElementLength3D: return "Max element length 3D";
- case FT_BelongToGeom : return "Belong to Geom";
- case FT_BelongToPlane : return "Belong to Plane";
- case FT_BelongToCylinder: return "Belong to Cylinder";
- case FT_BelongToGenSurface: return "Belong to Generic Surface";
- case FT_LyingOnGeom : return "Lying on Geom";
- case FT_BadOrientedVolume:return "Bad Oriented Volume";
- case FT_BareBorderVolume: return "Volumes with bare border";
- case FT_BareBorderFace : return "Faces with bare border";
- case FT_OverConstrainedVolume: return "Over-constrained Volumes";
- case FT_OverConstrainedFace : return "Over-constrained Faces";
- case FT_RangeOfIds : return "Range of IDs";
- case FT_FreeBorders : return "Free borders";
- case FT_FreeEdges : return "Free edges";
- case FT_FreeFaces : return "Free faces";
- case FT_FreeNodes : return "Free nodes";
- case FT_EqualNodes : return "Equal nodes";
- case FT_EqualEdges : return "Equal edges";
- case FT_EqualFaces : return "Equal faces";
- case FT_EqualVolumes : return "Equal volumes";
- case FT_MultiConnection : return "Borders at multi-connections";
- case FT_MultiConnection2D:return "Borders at multi-connections 2D";
- case FT_Length : return "Length";
- case FT_Length2D : return "Length 2D";
- case FT_LessThan : return "Less than";
- case FT_MoreThan : return "More than";
- case FT_EqualTo : return "Equal to";
- case FT_LogicalNOT : return "Not";
- case FT_LogicalAND : return "And";
- case FT_LogicalOR : return "Or";
- case FT_GroupColor : return "Color of Group";
- case FT_LinearOrQuadratic : return "Linear or Quadratic";
- case FT_ElemGeomType : return "Element geomtry type";
- case FT_EntityType : return "Entity type";
- case FT_Undefined : return "";
- default : return "";
+ case FT_AspectRatio : return "Aspect ratio";
+ case FT_Warping : return "Warping";
+ case FT_MinimumAngle : return "Minimum angle";
+ case FT_Taper : return "Taper";
+ case FT_Skew : return "Skew";
+ case FT_Area : return "Area";
+ case FT_Volume3D : return "Volume3D";
+ case FT_MaxElementLength2D : return "Max element length 2D";
+ case FT_MaxElementLength3D : return "Max element length 3D";
+ case FT_BelongToMeshGroup : return "Belong to Mesh Group";
+ case FT_BelongToGeom : return "Belong to Geom";
+ case FT_BelongToPlane : return "Belong to Plane";
+ case FT_BelongToCylinder : return "Belong to Cylinder";
+ case FT_BelongToGenSurface : return "Belong to Generic Surface";
+ case FT_LyingOnGeom : return "Lying on Geom";
+ case FT_BadOrientedVolume : return "Bad Oriented Volume";
+ case FT_BareBorderVolume : return "Volumes with bare border";
+ case FT_BareBorderFace : return "Faces with bare border";
+ case FT_OverConstrainedVolume : return "Over-constrained Volumes";
+ case FT_OverConstrainedFace : return "Over-constrained Faces";
+ case FT_RangeOfIds : return "Range of IDs";
+ case FT_FreeBorders : return "Free borders";
+ case FT_FreeEdges : return "Free edges";
+ case FT_FreeFaces : return "Free faces";
+ case FT_FreeNodes : return "Free nodes";
+ case FT_EqualNodes : return "Equal nodes";
+ case FT_EqualEdges : return "Equal edges";
+ case FT_EqualFaces : return "Equal faces";
+ case FT_EqualVolumes : return "Equal volumes";
+ case FT_MultiConnection : return "Borders at multi-connections";
+ case FT_MultiConnection2D :return "Borders at multi-connections 2D";
+ case FT_Length : return "Length";
+ case FT_Length2D : return "Length 2D";
+ case FT_LessThan : return "Less than";
+ case FT_MoreThan : return "More than";
+ case FT_EqualTo : return "Equal to";
+ case FT_LogicalNOT : return "Not";
+ case FT_LogicalAND : return "And";
+ case FT_LogicalOR : return "Or";
+ case FT_GroupColor : return "Color of Group";
+ case FT_LinearOrQuadratic : return "Linear or Quadratic";
+ case FT_ElemGeomType : return "Element geomtry type";
+ case FT_EntityType : return "Entity type";
+ case FT_Undefined : return "";
+ default : return "";
}
}
else if ( theStr.equals( "Volume3D" ) ) return FT_Volume3D;
else if ( theStr.equals( "Max element length 2D" ) ) return FT_MaxElementLength2D;
else if ( theStr.equals( "Max element length 3D" ) ) return FT_MaxElementLength3D;
+ else if ( theStr.equals( "Belong to Mesh Group" ) ) return FT_BelongToMeshGroup;
else if ( theStr.equals( "Belong to Geom" ) ) return FT_BelongToGeom;
else if ( theStr.equals( "Belong to Plane" ) ) return FT_BelongToPlane;
else if ( theStr.equals( "Belong to Cylinder" ) ) return FT_BelongToCylinder;
"FT_MultiConnection2D",
"FT_Length",
"FT_Length2D",
+ "FT_BelongToMeshGroup",
"FT_BelongToGeom",
"FT_BelongToPlane",
"FT_BelongToCylinder",
"FT_Undefined"};
#ifdef _DEBUG_
- // check if functName is complete, compilation failure mains that enum FunctorType changed
+ // check if functName is complete, compilation failure means that enum FunctorType changed
const int nbFunctors = sizeof(functName) / sizeof(const char*);
int _assert[( nbFunctors == SMESH::FT_Undefined + 1 ) ? 1 : -1 ];
#endif
return SMESH::FunctorType( ft );
}
+
+//================================================================================
+/*!
+ * \brief calls OnBaseObjModified(), if who != this, and myWaiters[i]->Modified(who)
+ */
+//================================================================================
+
+void NotifyerAndWaiter::Modified( bool removed, NotifyerAndWaiter* who )
+{
+ if ( who != 0 && who != this )
+ OnBaseObjModified( who, removed );
+ else
+ who = this;
+
+ std::list<NotifyerAndWaiter*> waiters = myWaiters; // myWaiters can be changed by Modified()
+ std::list<NotifyerAndWaiter*>::iterator i = waiters.begin();
+ for ( ; i != waiters.end(); ++i )
+ (*i)->Modified( removed, who );
+}
+
+//================================================================================
+/*!
+ * \brief Stores an object to be notified on change of predicate
+ */
+//================================================================================
+
+void NotifyerAndWaiter::AddModifWaiter( NotifyerAndWaiter* waiter )
+{
+ if ( waiter )
+ myWaiters.push_back( waiter );
+}
+
+//================================================================================
+/*!
+ * \brief Removes an object to be notified on change of predicate
+ */
+//================================================================================
+
+void NotifyerAndWaiter::RemoveModifWaiter( NotifyerAndWaiter* waiter )
+{
+ myWaiters.remove( waiter );
+}
+
+//================================================================================
+/*!
+ * \brief Checks if a waiter is among myWaiters, maybe nested
+ */
+//================================================================================
+
+bool NotifyerAndWaiter::ContainModifWaiter( NotifyerAndWaiter* waiter )
+{
+ bool is = ( waiter == this );
+
+ std::list<NotifyerAndWaiter*>::iterator w = myWaiters.begin();
+ for ( ; !is && w != myWaiters.end(); ++w )
+ is = (*w)->ContainModifWaiter( waiter );
+
+ return is;
+}
#include <list>
+class SMESH_GroupBase_i;
+
+
namespace SMESH
{
+ /*!
+ * \brief Object notified on change of base objects and
+ * notifying dependent objects in its turn.
+ * This interface is used to track the following dependencies:
+ * - GroupOnFiler depending on Filter predicates
+ * - Filter depending on a Group via FT_BelongToMeshGroup predicate
+ */
+ struct NotifyerAndWaiter
+ {
+ virtual void OnBaseObjModified(NotifyerAndWaiter* obj, bool removed) {};
+ // specific reaction on modification of a base object
+
+ void Modified( bool removed=false, NotifyerAndWaiter* who = 0);
+ // calls OnBaseObjModified(), if who != 0, and myWaiters[i]->Modified(who)
+
+ void AddModifWaiter ( NotifyerAndWaiter* waiter ); // adds a dependent object to notify
+ void RemoveModifWaiter ( NotifyerAndWaiter* waiter ); // CALL IT when a waiter dies!!!
+ bool ContainModifWaiter( NotifyerAndWaiter* waiter );
+ std::list<NotifyerAndWaiter*> myWaiters;
+ };
// ================================================================================
/*
FUNCTORS
FunctorType GetFunctorType();
};
+ /*
+ Class : BelongToMeshGroup_i
+ Description : Verify whether a mesh element is included into a mesh group
+ */
+ class SMESH_I_EXPORT BelongToMeshGroup_i: public virtual POA_SMESH::BelongToMeshGroup,
+ public virtual Predicate_i
+ {
+ std::string myID; // IOR or StoreName
+ SMESH::SMESH_GroupBase_var myGroup;
+ Controls::BelongToMeshGroupPtr myBelongToMeshGroup;
+ public:
+ BelongToMeshGroup_i();
+ ~BelongToMeshGroup_i();
+ void SetGroup( SMESH::SMESH_GroupBase_ptr theGroup );
+ void SetGroupID( const char* theID ); // IOR or StoreName
+ SMESH::SMESH_GroupBase_ptr GetGroup();
+
+ std::string GetGroupID();
+ FunctorType GetFunctorType();
+ //virtual void SetMesh( SMESH_Mesh_ptr theMesh );
+ };
+
/*
Class : BelongToGeom_i
Description : Predicate for selection on geometrical support
FILTER
*/
class SMESH_I_EXPORT Filter_i: public virtual POA_SMESH::Filter,
- public virtual SALOME::GenericObj_i
+ public virtual SALOME::GenericObj_i,
+ public NotifyerAndWaiter
{
public:
Filter_i();
Predicate_i* GetPredicate_i();
+ void FindBaseObjects();
+ // finds groups it depends on
+
+ virtual void OnBaseObjModified(NotifyerAndWaiter* group, bool removed);
+ // notified on change of myBaseGroups[i]
+
// =========================
// SMESH_IDSource interface
// =========================
virtual SMESH::SMESH_Mesh_ptr GetMesh();
virtual bool IsMeshInfoCorrect() { return true; }
virtual SALOMEDS::TMPFile* GetVtkUgStream();
- /*!
- * \brief Object notified on change of predicate
- */
- struct TPredicateChangeWaiter
- {
- virtual void PredicateChanged() = 0;
- };
- void AddWaiter( TPredicateChangeWaiter* waiter );
- void RemoveWaiter( TPredicateChangeWaiter* waiter );
private:
Controls::Filter myFilter;
Predicate_i* myPredicate;
SMESH_Mesh_var myMesh;
- std::list<TPredicateChangeWaiter*> myWaiters;
+ std::vector< SMESH_GroupBase_i* > myBaseGroups;
};
MultiConnection2D_ptr CreateMultiConnection2D();
BallDiameter_ptr CreateBallDiameter();
+ BelongToMeshGroup_ptr CreateBelongToMeshGroup();
BelongToGeom_ptr CreateBelongToGeom();
BelongToPlane_ptr CreateBelongToPlane();
BelongToCylinder_ptr CreateBelongToCylinder();
list< pair< SMESH_Hypothesis_i*, string > > hypDataList;
list< pair< SMESH_Mesh_i*, HDFgroup* > > meshGroupList;
+ list< SMESH::Filter_var > filters;
// get total number of top-level groups
int aNbGroups = aFile->nInternalObjects();
if ( strlen( persistStr ) > 0 ) {
filter = SMESH_GroupOnFilter_i::StringToFilter( persistStr );
predicate = SMESH_GroupOnFilter_i::GetPredicate( filter );
+ filters.push_back( filter );
}
}
Quantity_Color aColor( anRGB[0], anRGB[1], anRGB[2], Quantity_TOC_RGB );
aGroupBaseDS->SetColor( aColor );
}
-
- // Fill group with contents from MED file
- // SMESHDS_Group* aGrp = dynamic_cast<SMESHDS_Group*>( aGroupBaseDS );
- // if ( aGrp )
- // myReader.GetGroup( aGrp );
}
}
aGroup->CloseOnDisk();
ComputeStateEngine (SMESH_subMesh::SUBMESH_RESTORED);
}
+ // let filters detect dependency on mesh groups via FT_BelongToMeshGroup predicate (22877)
+ list< SMESH::Filter_var >::iterator f = filters.begin();
+ for ( ; f != filters.end(); ++f )
+ if ( SMESH::Filter_i * fi = SMESH::DownCast< SMESH::Filter_i*>( *f ))
+ fi->FindBaseObjects();
+
+
// close mesh group
if(aTopGroup)
aTopGroup->CloseOnDisk();
return true;
}
+//=============================================================================
+/*
+ * Returns \c true if \c this group depends on the \a other via
+ * FT_BelongToMeshGroup predicate or vice versa
+ */
+//=============================================================================
+
+bool SMESH_GroupBase_i::IsInDependency( SMESH::SMESH_GroupBase_ptr other )
+{
+ if ( NotifyerAndWaiter* nw = SMESH::DownCast< NotifyerAndWaiter* >( other ))
+ return ( nw->ContainModifWaiter( this ) || this->ContainModifWaiter( nw ));
+
+ return false;
+}
+
//=============================================================================
/*!
*
aGroupDS->Clear();
return;
}
+ Modified(); // notify dependent Filter with FT_BelongToMeshGroup criterion
+
MESSAGE("attempt to clear a vague group");
}
if (aGroupDS->Add(anID))
nbAdd++;
}
+ if ( nbAdd )
+ Modified(); // notify dependent Filter with FT_BelongToMeshGroup criterion
return nbAdd;
}
MESSAGE("attempt to add elements to a vague group");
if (aGroupDS->Remove(anID))
nbDel++;
}
+ if ( nbDel )
+ Modified(); // notify dependent Filter with FT_BelongToMeshGroup criterion
return nbDel;
}
MESSAGE("attempt to remove elements from a vague group");
CORBA::Long
ChangeByPredicate( SMESH::Predicate_i* thePredicate,
SMESHDS_GroupBase* theGroupBase,
+ NotifyerAndWaiter* theGroupImpl,
TFunChangeGroup theFun)
{
CORBA::Long aNb = 0;
for(; i < iEnd; i++)
if((aGroupDS->*theFun)(aSequence[i]))
aNb++;
+ if ( aNb )
+ theGroupImpl->Modified();
return aNb;
}
return aNb;
if(SMESH::Predicate_i* aPredicate = SMESH::GetPredicate(thePredicate)){
TPythonDump() << SMESH::SMESH_Group_var(_this())
<< ".AddByPredicate( " << aPredicate << " )";
- return ChangeByPredicate( aPredicate, GetGroupDS(), &SMESHDS_Group::Add );
+ return ChangeByPredicate( aPredicate, GetGroupDS(), this, &SMESHDS_Group::Add );
}
return 0;
}
if(SMESH::Predicate_i* aPredicate = SMESH::GetPredicate(thePredicate)){
TPythonDump() << SMESH::SMESH_Group_var(_this())
<< ".RemoveByPredicate( " << aPredicate << " )";
- return ChangeByPredicate(aPredicate,GetGroupDS(),&SMESHDS_Group::Remove);
+ return ChangeByPredicate(aPredicate,GetGroupDS(),this, &SMESHDS_Group::Remove);
}
return 0;
}
// Update Python script
pd << "nbAdd = " << SMESH::SMESH_Group_var(_this()) << ".AddFrom( " << theSource << " )";
- return prevNb - Size();
+ if ( prevNb != Size() )
+ Modified(); // notify dependent Filter with FT_BelongToMeshGroup criterion
+
+ return Size() - prevNb;
}
//=============================================================================
/*!
- *
+ *
*/
//=============================================================================
//================================================================================
void SMESH_GroupOnFilter_i::SetFilter(SMESH::Filter_ptr theFilter)
+ throw (SALOME::SALOME_Exception)
{
if ( myFilter->_is_equivalent( theFilter ))
return;
myFilter = SMESH::Filter::_duplicate( theFilter );
- if ( SMESHDS_GroupOnFilter* grDS = dynamic_cast< SMESHDS_GroupOnFilter*>( GetGroupDS() ))
- grDS->SetPredicate( GetPredicate( myFilter ));
+ if ( !myFilter->_is_nil() )
+ {
+ myFilter->Register();
- TPythonDump()<< SMESH::SMESH_GroupOnFilter_var(_this()) <<".SetFilter( "<<theFilter<<" )";
+ if ( SMESH::Filter_i* f = SMESH::DownCast< SMESH::Filter_i* >( myFilter ))
+ {
+ // make filter notify me about change of either a predicate or a base group
+ f->FindBaseObjects();
+
+ if ( f->ContainModifWaiter( this ) ||
+ this->ContainModifWaiter( f ))
+ {
+ SetFilter( SMESH::Filter::_nil() );
+ THROW_SALOME_CORBA_EXCEPTION( "Cyclic dependency between Groups on Filter",
+ SALOME::BAD_PARAM );
+ }
+ f->AddModifWaiter( this );
+ }
+ myFilter->SetMesh( SMESH::SMESH_Mesh::_nil() ); // to UnRegister() the mesh
+ }
- if ( myFilter )
+ if ( SMESHDS_GroupOnFilter* grDS = dynamic_cast< SMESHDS_GroupOnFilter*>( GetGroupDS() ))
{
- myFilter->SetMesh( SMESH::SMESH_Mesh::_nil() ); // to UnRegister() the mesh
- myFilter->Register();
- SMESH::DownCast< SMESH::Filter_i* >( myFilter )->AddWaiter( this );
+ grDS->SetPredicate( GetPredicate( myFilter ));
+ Modified(); // notify dependent Filter with FT_BelongToMeshGroup criterion
}
+
+ TPythonDump()<< SMESH::SMESH_GroupOnFilter_var(_this()) <<".SetFilter( "<<theFilter<<" )";
}
//================================================================================
result << criteria->length() << SEPAR;
for ( unsigned i = 0; i < criteria->length(); ++i )
{
+ SMESH::Filter::Criterion& crit = criteria[ i ];
+
+ if ( SMESH::FunctorType( crit.Type ) == SMESH::FT_BelongToMeshGroup )
+ {
+ CORBA::Object_var obj = SMESH_Gen_i::GetORB()->string_to_object( crit.ThresholdID );
+ if ( SMESH_GroupBase_i * g = SMESH::DownCast< SMESH_GroupBase_i*>( obj ))
+ if ( SMESHDS_GroupBase* gDS = g->GetGroupDS() )
+ crit.ThresholdID = gDS->GetStoreName();
+ }
// write FunctorType as string but not as number to assure correct
// persistence if enum FunctorType is modified by insertion in the middle
- SMESH::Filter::Criterion& crit = criteria[ i ];
result << SMESH::FunctorTypeToString( SMESH::FunctorType( crit.Type )) << SEPAR;
result << SMESH::FunctorTypeToString( SMESH::FunctorType( crit.Compare )) << SEPAR;
result << crit.Threshold << SEPAR;
{
if ( ! myFilter->_is_nil() )
{
- SMESH::DownCast< SMESH::Filter_i* >( myFilter )->RemoveWaiter( this );
+ SMESH::DownCast< SMESH::Filter_i* >( myFilter )->RemoveModifWaiter( this );
myFilter->UnRegister();
}
}
//================================================================================
/*!
- * \brief Method calleds when a predicate of myFilter changes
+ * \brief Method called when a predicate of myFilter changes
*/
//================================================================================
-void SMESH_GroupOnFilter_i::PredicateChanged()
+void SMESH_GroupOnFilter_i::OnBaseObjModified(NotifyerAndWaiter* filter, bool /*removed*/)
{
if ( myPreMeshInfo )
myPreMeshInfo->FullLoadFromFile();
if ( SMESHDS_GroupOnFilter* grDS = dynamic_cast< SMESHDS_GroupOnFilter*>( GetGroupDS() ))
- grDS->SetPredicate( GetPredicate( myFilter ));
+ grDS->SetPredicate( GetPredicate( myFilter )); // group resets its cache
}
// ===========
class SMESH_I_EXPORT SMESH_GroupBase_i:
public virtual POA_SMESH::SMESH_GroupBase,
- public virtual SALOME::GenericObj_i
+ public virtual SALOME::GenericObj_i,
+ public SMESH::NotifyerAndWaiter // defined in SMESH_Filter_i.hxx
{
public:
SMESH_GroupBase_i(PortableServer::POA_ptr thePOA,
*/
virtual SALOMEDS::TMPFile* GetVtkUgStream();
+ /*!
+ * Returns \c true if \c this group depends on the \a other via
+ * FT_BelongToMeshGroup predicate or vice versa
+ */
+ virtual CORBA::Boolean IsInDependency( SMESH::SMESH_GroupBase_ptr other );
+
+
// Internal C++ interface
int GetLocalID() const { return myLocalID; }
SMESH_Mesh_i* GetMeshServant() const { return myMeshServant; }
class SMESH_I_EXPORT SMESH_GroupOnFilter_i:
public virtual POA_SMESH::SMESH_GroupOnFilter,
- public SMESH_GroupBase_i,
- public SMESH::Filter_i::TPredicateChangeWaiter
+ public SMESH_GroupBase_i
{
public:
SMESH_GroupOnFilter_i( PortableServer::POA_ptr thePOA,
static SMESH_PredicatePtr GetPredicate( SMESH::Filter_ptr );
// CORBA interface implementation
- void SetFilter(SMESH::Filter_ptr theFilter);
+ void SetFilter(SMESH::Filter_ptr theFilter) throw (SALOME::SALOME_Exception);
SMESH::Filter_ptr GetFilter();
virtual SMESH::long_array* GetListOfID();
virtual SMESH::long_array* GetMeshInfo();
- // method of SMESH::Filter_i::TPredicateChangeWaiter
- virtual void PredicateChanged();
+ // method of SMESH::NotifyerAndWaiter to update self when myFilter changes
+ virtual void OnBaseObjModified(NotifyerAndWaiter* filter, bool);
private:
SMESH::Filter_var myFilter;
builder->RemoveObjectWithChildren( aGroupSO );
}
}
+ aGroup->Modified(/*removed=*/true); // notify dependent Filter with FT_BelongToMeshGroup criterion
// Remove the group from SMESH data structures
removeGroup( aGroup->GetLocalID() );
if CritType in [FT_BelongToGeom, FT_BelongToPlane, FT_BelongToGenSurface,
FT_BelongToCylinder, FT_LyingOnGeom]:
- # Checks that Threshold is GEOM object
+ # Check that Threshold is GEOM object
if isinstance(aThreshold, geomBuilder.GEOM._objref_GEOM_Object):
aCriterion.ThresholdStr = GetName(aThreshold)
aCriterion.ThresholdID = aThreshold.GetStudyEntry()
elif isinstance( aThreshold, str ):
aCriterion.ThresholdStr = aThreshold
else:
- print "Error: The Threshold should be a shape."
- return None
+ raise TypeError, "The Threshold should be a shape."
if isinstance(UnaryOp,float):
aCriterion.Tolerance = UnaryOp
UnaryOp = FT_Undefined
pass
+ elif CritType == FT_BelongToMeshGroup:
+ # Check that Threshold is a group
+ if isinstance(aThreshold, SMESH._objref_SMESH_GroupBase):
+ if aThreshold.GetType() != elementType:
+ raise ValueError, "Group type mismatches Element type"
+ aCriterion.ThresholdStr = aThreshold.GetName()
+ aCriterion.ThresholdID = salome.orb.object_to_string( aThreshold )
+ else:
+ raise TypeError, "The Threshold should be a Mesh Group"
elif CritType == FT_RangeOfIds:
- # Checks that Threshold is string
+ # Check that Threshold is string
if isinstance(aThreshold, str):
aCriterion.ThresholdStr = aThreshold
else:
- print "Error: The Threshold should be a string."
- return None
+ raise TypeError, "The Threshold should be a string."
elif CritType == FT_CoplanarFaces:
- # Checks the Threshold
+ # Check the Threshold
if isinstance(aThreshold, int):
aCriterion.ThresholdID = str(aThreshold)
elif isinstance(aThreshold, str):
raise ValueError, "Invalid ID of mesh face: '%s'"%aThreshold
aCriterion.ThresholdID = aThreshold
else:
- raise ValueError,\
+ raise TypeError,\
"The Threshold should be an ID of mesh face and not '%s'"%aThreshold
elif CritType == FT_ConnectedElements:
- # Checks the Threshold
+ # Check the Threshold
if isinstance(aThreshold, geomBuilder.GEOM._objref_GEOM_Object): # shape
aCriterion.ThresholdID = aThreshold.GetStudyEntry()
if not aCriterion.ThresholdID:
else:
aCriterion.ThresholdStr = aThreshold # hope that it's point coordinates
else:
- raise ValueError,\
+ raise TypeError,\
"The Threshold should either a VERTEX, or a node ID, "\
"or a list of point coordinates and not '%s'"%aThreshold
elif CritType == FT_ElemGeomType:
- # Checks the Threshold
+ # Check the Threshold
try:
aCriterion.Threshold = self.EnumToLong(aThreshold)
assert( aThreshold in SMESH.GeometryType._items )
if isinstance(aThreshold, int):
aCriterion.Threshold = aThreshold
else:
- print "Error: The Threshold should be an integer or SMESH.GeometryType."
- return None
+ raise TypeError, "The Threshold should be an integer or SMESH.GeometryType."
pass
pass
elif CritType == FT_EntityType:
- # Checks the Threshold
+ # Check the Threshold
try:
aCriterion.Threshold = self.EnumToLong(aThreshold)
assert( aThreshold in SMESH.EntityType._items )
if isinstance(aThreshold, int):
aCriterion.Threshold = aThreshold
else:
- print "Error: The Threshold should be an integer or SMESH.EntityType."
- return None
+ raise TypeError, "The Threshold should be an integer or SMESH.EntityType."
pass
pass
elif CritType == FT_GroupColor:
- # Checks the Threshold
+ # Check the Threshold
try:
aCriterion.ThresholdStr = self.ColorToString(aThreshold)
except:
- print "Error: The threshold value should be of SALOMEDS.Color type"
- return None
+ raise TypeError, "The threshold value should be of SALOMEDS.Color type"
pass
elif CritType in [FT_FreeBorders, FT_FreeEdges, FT_FreeNodes, FT_FreeFaces,
FT_LinearOrQuadratic, FT_BadOrientedVolume,
aThreshold = float(aThreshold)
aCriterion.Threshold = aThreshold
except:
- print "Error: The Threshold should be a number."
+ raise TypeError, "The Threshold should be a number."
return None
if Threshold == FT_LogicalNOT or UnaryOp == FT_LogicalNOT: