22877: EDF 10054 SMESH: Add a new filter "BelongToSmeshGroup" for Create Group

This commit is contained in:
eap 2015-04-14 15:39:28 +03:00
parent 62ba95d8ac
commit 5ac2bd91a8
24 changed files with 784 additions and 207 deletions

View File

@ -95,6 +95,7 @@ SET(GOOD_TESTS
filters_ex33.py filters_ex33.py
filters_ex34.py filters_ex34.py
filters_ex36.py filters_ex36.py
filters_belong2group.py
grouping_elements_ex01.py grouping_elements_ex01.py
grouping_elements_ex02.py grouping_elements_ex02.py
grouping_elements_ex03.py grouping_elements_ex03.py

View File

@ -0,0 +1,18 @@
# 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() )

View File

@ -11,7 +11,7 @@ Several criteria can be combined together by using logical operators \a
AND and \a OR. In addition, applied filter criterion can be reverted AND and \a OR. In addition, applied filter criterion can be reverted
using logical operator \a NOT. 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). to filter mesh nodes / elements by specific characteristic (Area, Length, etc).
The functinality of mesh filters is available in both GUI and TUI The functinality of mesh filters is available in both GUI and TUI

View File

@ -24,8 +24,8 @@ menu for setting filters looks a bit differently (see the image below).
Each filter can be applicable to \b Nodes, \b Edges, \b Faces or \b 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 Volumes. You can combine many criteria in one filter, but they all
must be of the same <b>Entity type</b>. must be of the same <b>Entity type</b>. <br>
\n The \b Add button creates a new criterion at the end of the list of 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 criteria. The \b Insert button creates a new criterion before the
selected criterion. The \b Remove button deletes the selected selected criterion. The \b Remove button deletes the selected
criterion. The \b Clear button deletes all criteria. criterion. The \b Clear button deletes all criteria.
@ -43,11 +43,11 @@ selection of elements in the Viewer to the current filter.
<br> <br>
In the \b Source field you choose if the filter will be applied to 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 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 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 chosen, the filter will be applied to the selected elements and the
elements rejected by the filter will be deselected. If <b>Current 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 elements in the current dialog and the elements rejected
by the filter will be removed from the list. by the filter will be removed from the list.
<br> <br>
@ -76,6 +76,9 @@ If the threshold shape is a sub-shape of the main shape of the mesh the
algorithm works faster, if this is any other algorithm works faster, if this is any other
shape, the algorithm works slower. shape, the algorithm works slower.
</li><li> </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 <b>Range of IDs</b> allows selection of entities with the specified
IDs. IDs.
<b>Threshold Value</b> can be, for example: "1,2,3,50-60,63,67,70-78" <b>Threshold Value</b> can be, for example: "1,2,3,50-60,63,67,70-78"

View File

@ -2,14 +2,16 @@
\page tui_filters_page Filters usage \page tui_filters_page Filters usage
\tableofcontents
Filters allow picking only the mesh elements satisfying to a Filters allow picking only the mesh elements satisfying to a
specific condition or a set of conditions. Filters can be used to create specific condition or a set of conditions. Filters can be used to create
or edit mesh groups, remove elements from the mesh object, control or edit mesh groups, remove elements from the mesh object, control
mesh quality by different parameters, etc. mesh quality by different parameters, etc.
Several filters can be combined together by using logical operators \a Several filtering criteria can be combined together by using logical
AND and \a OR. In addition, applied filter criterion can be reverted operators \a AND and \a OR. In addition, applied filter criterion can
using logical operator \a NOT. be reverted using logical operator \a NOT.
Mesh filters use the functionality of mesh quality controls to filter Mesh filters use the functionality of mesh quality controls to filter
mesh nodes / elements by a specific characteristic (Area, Length, etc). mesh nodes / elements by a specific characteristic (Area, Length, etc).
@ -300,6 +302,16 @@ Filter over-constrained volumes:
\sa \ref tui_over_constrained_faces \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 \section filter_belong_to_geom Belong to Geom
Filter mesh entities (nodes or elements) which all nodes lie on the Filter mesh entities (nodes or elements) which all nodes lie on the

View File

@ -61,6 +61,7 @@ module SMESH
FT_MultiConnection2D, FT_MultiConnection2D,
FT_Length, FT_Length,
FT_Length2D, FT_Length2D,
FT_BelongToMeshGroup,
FT_BelongToGeom, FT_BelongToGeom,
FT_BelongToPlane, FT_BelongToPlane,
FT_BelongToCylinder, FT_BelongToCylinder,
@ -228,6 +229,17 @@ module SMESH
*/ */
interface EqualVolumes: Predicate {}; 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". * Logical functor (predicate) "Belong To Geometry".
* Verify whether mesh element or node belong to pointed Geom Object * Verify whether mesh element or node belong to pointed Geom Object
@ -577,6 +589,7 @@ module SMESH
/*! /*!
* Create logical functors ( predicates ) * Create logical functors ( predicates )
*/ */
BelongToMeshGroup CreateBelongToMeshGroup();
BelongToGeom CreateBelongToGeom(); BelongToGeom CreateBelongToGeom();
BelongToPlane CreateBelongToPlane(); BelongToPlane CreateBelongToPlane();
BelongToCylinder CreateBelongToCylinder(); BelongToCylinder CreateBelongToCylinder();

View File

@ -121,6 +121,12 @@ module SMESH
* (corresponds to the "hue" parameter of the color - must be in range [0, 360]) * (corresponds to the "hue" parameter of the color - must be in range [0, 360])
*/ */
long GetColorNumber(); 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 );
}; };
/*! /*!
@ -170,7 +176,7 @@ module SMESH
*/ */
interface SMESH_GroupOnFilter : SMESH_GroupBase interface SMESH_GroupOnFilter : SMESH_GroupBase
{ {
void SetFilter( in Filter theFilter); void SetFilter( in Filter theFilter) raises (SALOME::SALOME_Exception);
Filter GetFilter(); Filter GetFilter();
}; };

View File

@ -3820,6 +3820,52 @@ void ManifoldPart::getFacesByLink( const ManifoldPart::Link& theLink,
} }
} }
/*
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

View File

@ -54,6 +54,7 @@ class SMDS_Mesh;
class SMESHDS_Mesh; class SMESHDS_Mesh;
class SMESHDS_SubMesh; class SMESHDS_SubMesh;
class SMESHDS_GroupBase;
class gp_Pnt; class gp_Pnt;
@ -779,6 +780,27 @@ namespace SMESH{
}; };
typedef boost::shared_ptr<ManifoldPart> ManifoldPartPtr; 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 Class : ElementsOnSurface
@ -809,7 +831,6 @@ namespace SMESH{
TMeshModifTracer myMeshModifTracer; TMeshModifTracer myMeshModifTracer;
TColStd_MapOfInteger myIds; TColStd_MapOfInteger myIds;
SMDSAbs_ElementType myType; SMDSAbs_ElementType myType;
//Handle(Geom_Surface) mySurf;
TopoDS_Face mySurf; TopoDS_Face mySurf;
double myToler; double myToler;
bool myUseBoundaries; bool myUseBoundaries;

View File

@ -48,7 +48,7 @@ namespace SMESH{
/* /*
Class : Functor Class : Functor
Description : Root of all Functors Description : Root of all Functors defined in ../Controls/SMESH_ControlsDef.hxx
*/ */
class SMESHCONTROLS_EXPORT Functor class SMESHCONTROLS_EXPORT Functor
{ {

View File

@ -56,10 +56,11 @@
#include <LightApp_Application.h> #include <LightApp_Application.h>
#include <LightApp_SelectionMgr.h> #include <LightApp_SelectionMgr.h>
#include <SalomeApp_Tools.h> #include <SalomeApp_Application.h>
#include <SalomeApp_Study.h>
#include <SalomeApp_IntSpinBox.h>
#include <SalomeApp_DoubleSpinBox.h> #include <SalomeApp_DoubleSpinBox.h>
#include <SalomeApp_IntSpinBox.h>
#include <SalomeApp_Study.h>
#include <SalomeApp_Tools.h>
#include <SALOME_ListIO.hxx> #include <SALOME_ListIO.hxx>
@ -1134,6 +1135,7 @@ bool SMESHGUI_FilterTable::IsValid (const bool theMess, const int theEntityType)
errMsg = tr( "GROUPCOLOR_ERROR" ); errMsg = tr( "GROUPCOLOR_ERROR" );
} }
else if (aCriterion == SMESH::FT_RangeOfIds || else if (aCriterion == SMESH::FT_RangeOfIds ||
aCriterion == SMESH::FT_BelongToMeshGroup ||
aCriterion == SMESH::FT_BelongToGeom || aCriterion == SMESH::FT_BelongToGeom ||
aCriterion == SMESH::FT_BelongToPlane || aCriterion == SMESH::FT_BelongToPlane ||
aCriterion == SMESH::FT_BelongToCylinder || aCriterion == SMESH::FT_BelongToCylinder ||
@ -1283,6 +1285,7 @@ void SMESHGUI_FilterTable::GetCriterion (const int theRow,
} }
} }
else if ( aCriterionType != SMESH::FT_RangeOfIds && else if ( aCriterionType != SMESH::FT_RangeOfIds &&
aCriterionType != SMESH::FT_BelongToMeshGroup &&
aCriterionType != SMESH::FT_BelongToGeom && aCriterionType != SMESH::FT_BelongToGeom &&
aCriterionType != SMESH::FT_BelongToPlane && aCriterionType != SMESH::FT_BelongToPlane &&
aCriterionType != SMESH::FT_BelongToCylinder && aCriterionType != SMESH::FT_BelongToCylinder &&
@ -1382,6 +1385,7 @@ void SMESHGUI_FilterTable::SetCriterion (const int theRow,
} }
} }
else if (theCriterion.Type != SMESH::FT_RangeOfIds && else if (theCriterion.Type != SMESH::FT_RangeOfIds &&
theCriterion.Type != SMESH::FT_BelongToMeshGroup &&
theCriterion.Type != SMESH::FT_BelongToGeom && theCriterion.Type != SMESH::FT_BelongToGeom &&
theCriterion.Type != SMESH::FT_BelongToPlane && theCriterion.Type != SMESH::FT_BelongToPlane &&
theCriterion.Type != SMESH::FT_BelongToCylinder && theCriterion.Type != SMESH::FT_BelongToCylinder &&
@ -1398,6 +1402,7 @@ void SMESHGUI_FilterTable::SetCriterion (const int theRow,
theCriterion.Type != SMESH::FT_OverConstrainedVolume && theCriterion.Type != SMESH::FT_OverConstrainedVolume &&
theCriterion.Type != SMESH::FT_LinearOrQuadratic) theCriterion.Type != SMESH::FT_LinearOrQuadratic)
{ {
// Numberic criterion
aTable->item( theRow, 2 )->setText(QString("%1").arg(theCriterion.Threshold, 0, 'g', 15)); aTable->item( theRow, 2 )->setText(QString("%1").arg(theCriterion.Threshold, 0, 'g', 15));
} }
else else
@ -1813,13 +1818,15 @@ void SMESHGUI_FilterTable::onCriterionChanged (const int row, const int col, con
case SMESH::FT_Length: case SMESH::FT_Length:
case SMESH::FT_Length2D: anIsDoubleCriterion = true; break; case SMESH::FT_Length2D: anIsDoubleCriterion = true; break;
case SMESH::FT_BelongToMeshGroup: break;
case SMESH::FT_BelongToGeom: case SMESH::FT_BelongToGeom:
case SMESH::FT_BelongToPlane: case SMESH::FT_BelongToPlane:
case SMESH::FT_BelongToCylinder: case SMESH::FT_BelongToCylinder:
case SMESH::FT_BelongToGenSurface: 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_BadOrientedVolume:
case SMESH::FT_BareBorderVolume: case SMESH::FT_BareBorderVolume:
@ -2162,6 +2169,7 @@ const QMap<int, QString>& SMESHGUI_FilterTable::getCriteria (const int theType)
if (aCriteria.isEmpty()) if (aCriteria.isEmpty())
{ {
aCriteria[ SMESH::FT_RangeOfIds ] = tr("RANGE_OF_IDS"); 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_BelongToGeom ] = tr("BELONG_TO_GEOM");
aCriteria[ SMESH::FT_BelongToPlane ] = tr("BELONG_TO_PLANE"); aCriteria[ SMESH::FT_BelongToPlane ] = tr("BELONG_TO_PLANE");
aCriteria[ SMESH::FT_BelongToCylinder ] = tr("BELONG_TO_CYLINDER"); aCriteria[ SMESH::FT_BelongToCylinder ] = tr("BELONG_TO_CYLINDER");
@ -2183,6 +2191,7 @@ const QMap<int, QString>& SMESHGUI_FilterTable::getCriteria (const int theType)
aCriteria[ SMESH::FT_MultiConnection ] = tr("MULTI_BORDERS"); aCriteria[ SMESH::FT_MultiConnection ] = tr("MULTI_BORDERS");
aCriteria[ SMESH::FT_Length ] = tr("LENGTH"); aCriteria[ SMESH::FT_Length ] = tr("LENGTH");
aCriteria[ SMESH::FT_RangeOfIds ] = tr("RANGE_OF_IDS"); 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_BelongToGeom ] = tr("BELONG_TO_GEOM");
aCriteria[ SMESH::FT_BelongToPlane ] = tr("BELONG_TO_PLANE"); aCriteria[ SMESH::FT_BelongToPlane ] = tr("BELONG_TO_PLANE");
aCriteria[ SMESH::FT_BelongToCylinder ] = tr("BELONG_TO_CYLINDER"); aCriteria[ SMESH::FT_BelongToCylinder ] = tr("BELONG_TO_CYLINDER");
@ -2211,6 +2220,7 @@ const QMap<int, QString>& SMESHGUI_FilterTable::getCriteria (const int theType)
aCriteria[ SMESH::FT_MaxElementLength2D ] = tr("MAX_ELEMENT_LENGTH_2D"); aCriteria[ SMESH::FT_MaxElementLength2D ] = tr("MAX_ELEMENT_LENGTH_2D");
aCriteria[ SMESH::FT_FreeEdges ] = tr("FREE_EDGES"); aCriteria[ SMESH::FT_FreeEdges ] = tr("FREE_EDGES");
aCriteria[ SMESH::FT_RangeOfIds ] = tr("RANGE_OF_IDS"); 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_BelongToGeom ] = tr("BELONG_TO_GEOM");
aCriteria[ SMESH::FT_BelongToPlane ] = tr("BELONG_TO_PLANE"); aCriteria[ SMESH::FT_BelongToPlane ] = tr("BELONG_TO_PLANE");
aCriteria[ SMESH::FT_BelongToCylinder ] = tr("BELONG_TO_CYLINDER"); aCriteria[ SMESH::FT_BelongToCylinder ] = tr("BELONG_TO_CYLINDER");
@ -2238,6 +2248,7 @@ const QMap<int, QString>& SMESHGUI_FilterTable::getCriteria (const int theType)
{ {
aCriteria[ SMESH::FT_AspectRatio3D ] = tr("ASPECT_RATIO_3D"); aCriteria[ SMESH::FT_AspectRatio3D ] = tr("ASPECT_RATIO_3D");
aCriteria[ SMESH::FT_RangeOfIds ] = tr("RANGE_OF_IDS"); 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_BelongToGeom ] = tr("BELONG_TO_GEOM");
aCriteria[ SMESH::FT_LyingOnGeom ] = tr("LYING_ON_GEOM"); aCriteria[ SMESH::FT_LyingOnGeom ] = tr("LYING_ON_GEOM");
aCriteria[ SMESH::FT_BadOrientedVolume ] = tr("BAD_ORIENTED_VOLUME"); aCriteria[ SMESH::FT_BadOrientedVolume ] = tr("BAD_ORIENTED_VOLUME");
@ -2260,6 +2271,7 @@ const QMap<int, QString>& SMESHGUI_FilterTable::getCriteria (const int theType)
if (aCriteria.isEmpty()) if (aCriteria.isEmpty())
{ {
aCriteria[ SMESH::FT_RangeOfIds ] = tr("RANGE_OF_IDS"); 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_BelongToGeom ] = tr("BELONG_TO_GEOM");
aCriteria[ SMESH::FT_BelongToPlane ] = tr("BELONG_TO_PLANE"); aCriteria[ SMESH::FT_BelongToPlane ] = tr("BELONG_TO_PLANE");
aCriteria[ SMESH::FT_BelongToCylinder ] = tr("BELONG_TO_CYLINDER"); aCriteria[ SMESH::FT_BelongToCylinder ] = tr("BELONG_TO_CYLINDER");
@ -2276,6 +2288,7 @@ const QMap<int, QString>& SMESHGUI_FilterTable::getCriteria (const int theType)
{ {
aCriteria[ SMESH::FT_BallDiameter ] = tr("BALL_DIAMETER"); aCriteria[ SMESH::FT_BallDiameter ] = tr("BALL_DIAMETER");
aCriteria[ SMESH::FT_RangeOfIds ] = tr("RANGE_OF_IDS"); 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_BelongToGeom ] = tr("BELONG_TO_GEOM");
aCriteria[ SMESH::FT_BelongToPlane ] = tr("BELONG_TO_PLANE"); aCriteria[ SMESH::FT_BelongToPlane ] = tr("BELONG_TO_PLANE");
aCriteria[ SMESH::FT_BelongToCylinder ] = tr("BELONG_TO_CYLINDER"); aCriteria[ SMESH::FT_BelongToCylinder ] = tr("BELONG_TO_CYLINDER");
@ -2291,6 +2304,7 @@ const QMap<int, QString>& SMESHGUI_FilterTable::getCriteria (const int theType)
if (aCriteria.isEmpty()) if (aCriteria.isEmpty())
{ {
aCriteria[ SMESH::FT_RangeOfIds ] = tr("RANGE_OF_IDS"); 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_BelongToGeom ] = tr("BELONG_TO_GEOM");
aCriteria[ SMESH::FT_BelongToPlane ] = tr("BELONG_TO_PLANE"); aCriteria[ SMESH::FT_BelongToPlane ] = tr("BELONG_TO_PLANE");
aCriteria[ SMESH::FT_BelongToCylinder ] = tr("BELONG_TO_CYLINDER"); aCriteria[ SMESH::FT_BelongToCylinder ] = tr("BELONG_TO_CYLINDER");
@ -2306,6 +2320,7 @@ const QMap<int, QString>& SMESHGUI_FilterTable::getCriteria (const int theType)
if (aCriteria.isEmpty()) if (aCriteria.isEmpty())
{ {
aCriteria[ SMESH::FT_RangeOfIds ] = tr("RANGE_OF_IDS"); 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_BelongToGeom ] = tr("BELONG_TO_GEOM");
aCriteria[ SMESH::FT_LyingOnGeom ] = tr("LYING_ON_GEOM"); aCriteria[ SMESH::FT_LyingOnGeom ] = tr("LYING_ON_GEOM");
aCriteria[ SMESH::FT_LinearOrQuadratic ] = tr("LINEAR"); aCriteria[ SMESH::FT_LinearOrQuadratic ] = tr("LINEAR");
@ -2869,6 +2884,7 @@ void SMESHGUI_FilterDlg::Init (const QList<int>& theTypes, const bool setInViewe
mySourceWg = 0; mySourceWg = 0;
myTypes = theTypes; myTypes = theTypes;
myMesh = SMESH::SMESH_Mesh::_nil(); myMesh = SMESH::SMESH_Mesh::_nil();
myGroup = SMESH::SMESH_GroupOnFilter::_nil();
myIObjects.Clear(); myIObjects.Clear();
myIsSelectionChanged = false; myIsSelectionChanged = false;
myToRestoreSelMode = false; myToRestoreSelMode = false;
@ -3148,7 +3164,6 @@ bool SMESHGUI_FilterDlg::isValid() const
aType == SMESH::FT_BelongToPlane || aType == SMESH::FT_BelongToPlane ||
aType == SMESH::FT_BelongToGenSurface ) { aType == SMESH::FT_BelongToGenSurface ) {
CORBA::Object_var anObject = SMESH::SObjectToObject(aList[ 0 ]); CORBA::Object_var anObject = SMESH::SObjectToObject(aList[ 0 ]);
//GEOM::GEOM_Object_var aGeomObj = GEOM::GEOM_Object::_narrow(aList[ 0 ]->GetObject());
GEOM::GEOM_Object_var aGeomObj = GEOM::GEOM_Object::_narrow(anObject); GEOM::GEOM_Object_var aGeomObj = GEOM::GEOM_Object::_narrow(anObject);
if (!aGeomObj->_is_nil()) { if (!aGeomObj->_is_nil()) {
TopoDS_Shape aFace; TopoDS_Shape aFace;
@ -3252,6 +3267,15 @@ void SMESHGUI_FilterDlg::SetMesh (SMESH::SMESH_Mesh_var theMesh)
myButtons[BTN_Apply]->setEnabled(isEnable); 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 // name : SMESHGUI_FilterDlg::SetSelection
// Purpose : Get filtered ids // Purpose : Get filtered ids
@ -3662,7 +3686,7 @@ void SMESHGUI_FilterDlg::onSelectionDone()
types << SMESH::FT_BelongToGeom << SMESH::FT_BelongToPlane types << SMESH::FT_BelongToGeom << SMESH::FT_BelongToPlane
<< SMESH::FT_BelongToCylinder << SMESH::FT_BelongToGenSurface << SMESH::FT_BelongToCylinder << SMESH::FT_BelongToGenSurface
<< SMESH::FT_LyingOnGeom << SMESH::FT_CoplanarFaces << SMESH::FT_LyingOnGeom << SMESH::FT_CoplanarFaces
<< SMESH::FT_ConnectedElements; << SMESH::FT_ConnectedElements << SMESH::FT_BelongToMeshGroup;
if ( !types.contains( type )) if ( !types.contains( type ))
return; return;
@ -3694,6 +3718,29 @@ void SMESHGUI_FilterDlg::onSelectionDone()
} }
break; 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 default: // get a GEOM object
{ {
GEOM::GEOM_Object_var anObj = SMESH::IObjectToInterface<GEOM::GEOM_Object>(anIO); GEOM::GEOM_Object_var anObj = SMESH::IObjectToInterface<GEOM::GEOM_Object>(anIO);
@ -3785,6 +3832,23 @@ void SMESHGUI_FilterDlg::updateSelection()
myIsSelectionChanged = true; 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 ) else if ( aCriterionType == SMESH::FT_ConnectedElements )
{ {
QList<SUIT_SelectionFilter*> fList; QList<SUIT_SelectionFilter*> fList;

View File

@ -228,6 +228,7 @@ public:
void SetSelection(); void SetSelection();
void SetMesh (SMESH::SMESH_Mesh_var); void SetMesh (SMESH::SMESH_Mesh_var);
void SetGroup (SMESH::SMESH_GroupOnFilter_var);
void SetSourceWg( QWidget*, const bool initOnApply = true ); void SetSourceWg( QWidget*, const bool initOnApply = true );
void SetEnabled( bool setInViewer, bool diffSources ); void SetEnabled( bool setInViewer, bool diffSources );
@ -297,6 +298,7 @@ private:
LightApp_SelectionMgr* mySelectionMgr; LightApp_SelectionMgr* mySelectionMgr;
SVTK_Selector* mySelector; SVTK_Selector* mySelector;
SMESH::SMESH_Mesh_var myMesh; SMESH::SMESH_Mesh_var myMesh;
SMESH::SMESH_GroupOnFilter_var myGroup;
bool myInitSourceWgOnApply; bool myInitSourceWgOnApply;
bool myInsertEnabled; bool myInsertEnabled;
bool myDiffSourcesEnabled; bool myDiffSourcesEnabled;

View File

@ -1209,7 +1209,7 @@ void SMESHGUI_FilterLibraryDlg::onSelectionDone()
types << SMESH::FT_BelongToGeom << SMESH::FT_BelongToPlane types << SMESH::FT_BelongToGeom << SMESH::FT_BelongToPlane
<< SMESH::FT_BelongToCylinder << SMESH::FT_BelongToGenSurface << SMESH::FT_BelongToCylinder << SMESH::FT_BelongToGenSurface
<< SMESH::FT_LyingOnGeom << SMESH::FT_CoplanarFaces << SMESH::FT_LyingOnGeom << SMESH::FT_CoplanarFaces
<< SMESH::FT_ConnectedElements; << SMESH::FT_ConnectedElements << SMESH::FT_BelongToMeshGroup;
if ( !types.contains( type )) if ( !types.contains( type ))
return; return;
@ -1241,6 +1241,10 @@ void SMESHGUI_FilterLibraryDlg::onSelectionDone()
} }
break; break;
} }
case SMESH::FT_BelongToMeshGroup: // get a group name and IOR
{
myTable->SetThreshold(aRow, anIO->getName() );
}
default: // get a GEOM object default: // get a GEOM object
{ {
GEOM::GEOM_Object_var anObj = SMESH::IObjectToInterface<GEOM::GEOM_Object>(anIO); GEOM::GEOM_Object_var anObj = SMESH::IObjectToInterface<GEOM::GEOM_Object>(anIO);

View File

@ -1197,7 +1197,10 @@ bool SMESHGUI_GroupDlg::onApply()
} }
// update a visible group accoding to a changed contents // update a visible group accoding to a changed contents
if ( !isConversion && anActor->GetVisibility() ) if ( !isConversion && anActor->GetVisibility() )
{
SMESH::Update( anIO, true ); SMESH::Update( anIO, true );
SMESH::RepaintCurrentView();
}
} }
} }
} }
@ -1762,10 +1765,10 @@ void SMESHGUI_GroupDlg::setFilters()
myFilterDlg->SetEnabled( /*setInViewer=*/isStandalone, myFilterDlg->SetEnabled( /*setInViewer=*/isStandalone,
/*diffSources=*/isStandalone ); /*diffSources=*/isStandalone );
myFilterDlg->SetMesh( myMesh ); myFilterDlg->SetMesh( myMesh );
myFilterDlg->SetGroup( myGroupOnFilter );
myFilterDlg->SetSelection(); myFilterDlg->SetSelection();
myFilterDlg->SetSourceWg( myElements, false ); myFilterDlg->SetSourceWg( myElements, false );
myFilterDlg->show(); myFilterDlg->show();
} }

View File

@ -28,16 +28,15 @@
#include "SMESHGUI_VTKUtils.h" #include "SMESHGUI_VTKUtils.h"
#include "SMESHGUI.h" #include "SMESHGUI.h"
#include "SMESHGUI_Utils.h"
#include "SMESHGUI_Filter.h" #include "SMESHGUI_Filter.h"
#include "SMESH_ControlsDef.hxx" #include "SMESHGUI_Utils.h"
#include "SMDS_Mesh.hxx"
#include <SMESH_Actor.h> #include "SMESH_Actor.h"
#include <SMESH_ActorUtils.h> #include "SMESH_ActorUtils.h"
#include "SMESH_NodeLabelActor.h"
#include "SMESH_CellLabelActor.h" #include "SMESH_CellLabelActor.h"
#include <SMESH_ObjectDef.h> #include "SMESH_ControlsDef.hxx"
#include <SMDS_Mesh.hxx> #include "SMESH_NodeLabelActor.h"
#include "SMESH_ObjectDef.h"
// SALOME GUI includes // SALOME GUI includes
#include <SUIT_Desktop.h> #include <SUIT_Desktop.h>

View File

@ -5421,6 +5421,10 @@ Please check input data and try again</translation>
<source>OVER_CONSTRAINED_FACE</source> <source>OVER_CONSTRAINED_FACE</source>
<translation>Over-constrained faces</translation> <translation>Over-constrained faces</translation>
</message> </message>
<message>
<source>BELONG_TO_MESH_GROUP</source>
<translation>Belong to Mesh Group</translation>
</message>
<message> <message>
<source>BELONG_TO_CYLINDER</source> <source>BELONG_TO_CYLINDER</source>
<translation>Belong to Cylinder</translation> <translation>Belong to Cylinder</translation>

View File

@ -423,6 +423,7 @@ namespace SMESH
case FT_MultiConnection2D: myStream<< "aMultiConnection2D"; break; case FT_MultiConnection2D: myStream<< "aMultiConnection2D"; break;
case FT_Length: myStream<< "aLength"; break; case FT_Length: myStream<< "aLength"; break;
case FT_Length2D: myStream<< "aLength2D"; break; case FT_Length2D: myStream<< "aLength2D"; break;
case FT_BelongToMeshGroup: myStream<< "aBelongToMeshGroup"; break;
case FT_BelongToGeom: myStream<< "aBelongToGeom"; break; case FT_BelongToGeom: myStream<< "aBelongToGeom"; break;
case FT_BelongToPlane: myStream<< "aBelongToPlane"; break; case FT_BelongToPlane: myStream<< "aBelongToPlane"; break;
case FT_BelongToCylinder: myStream<< "aBelongToCylinder"; break; case FT_BelongToCylinder: myStream<< "aBelongToCylinder"; break;

View File

@ -31,6 +31,7 @@
#include "SMDS_Mesh.hxx" #include "SMDS_Mesh.hxx"
#include "SMDS_MeshElement.hxx" #include "SMDS_MeshElement.hxx"
#include "SMDS_MeshNode.hxx" #include "SMDS_MeshNode.hxx"
#include "SMESHDS_GroupBase.hxx"
#include "SMESHDS_Mesh.hxx" #include "SMESHDS_Mesh.hxx"
#include "SMESH_Gen_i.hxx" #include "SMESH_Gen_i.hxx"
#include "SMESH_Group_i.hxx" #include "SMESH_Group_i.hxx"
@ -722,6 +723,108 @@ FunctorType OverConstrainedFace_i::GetFunctorType()
return SMESH::FT_OverConstrainedFace; 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 Class : BelongToGeom_i
Description : Predicate for selection on geometrical support Description : Predicate for selection on geometrical support
@ -1772,6 +1875,7 @@ Predicate_i* LogicalNOT_i::GetPredicate_i()
} }
/* /*
Class : LogicalBinary_i Class : LogicalBinary_i
Description : Base class for binary logical predicate Description : Base class for binary logical predicate
@ -2023,6 +2127,14 @@ BallDiameter_ptr FilterManager_i::CreateBallDiameter()
return anObj._retn(); 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() BelongToGeom_ptr FilterManager_i::CreateBelongToGeom()
{ {
SMESH::BelongToGeom_i* aServant = new SMESH::BelongToGeom_i(); SMESH::BelongToGeom_i* aServant = new SMESH::BelongToGeom_i();
@ -2339,7 +2451,8 @@ Filter_i::~Filter_i()
if(!CORBA::is_nil(myMesh)) if(!CORBA::is_nil(myMesh))
myMesh->UnRegister(); myMesh->UnRegister();
//TPythonDump()<<this<<".UnRegister()"; myPredicate = 0;
FindBaseObjects();
} }
//======================================================================= //=======================================================================
@ -2361,9 +2474,7 @@ void Filter_i::SetPredicate( Predicate_ptr thePredicate )
myPredicate->GetPredicate()->SetMesh( aMesh ); myPredicate->GetPredicate()->SetMesh( aMesh );
TPythonDump()<<this<<".SetPredicate("<<myPredicate<<")"; TPythonDump()<<this<<".SetPredicate("<<myPredicate<<")";
} }
std::list<TPredicateChangeWaiter*>::iterator i = myWaiters.begin(); NotifyerAndWaiter::Modified();
for ( ; i != myWaiters.end(); ++i )
(*i)->PredicateChanged();
} }
//======================================================================= //=======================================================================
@ -2550,28 +2661,35 @@ SALOMEDS::TMPFile* Filter_i::GetVtkUgStream()
SALOMEDS::TMPFile_var SeqFile; SALOMEDS::TMPFile_var SeqFile;
return SeqFile._retn(); return SeqFile._retn();
} }
//=======================================================================
//================================================================================ // name : getCriteria
/*! // Purpose : Retrieve criterions from predicate
* \brief Stores an object to be notified on change of predicate //=======================================================================
*/ static inline void getPrediacates( Predicate_i* thePred,
//================================================================================ std::vector<Predicate_i*> & thePredVec )
void Filter_i::AddWaiter( TPredicateChangeWaiter* waiter )
{ {
if ( waiter ) const int aFType = thePred->GetFunctorType();
myWaiters.push_back( waiter );
}
//================================================================================ switch ( aFType )
/*! {
* \brief Removes an object to be notified on change of predicate case FT_LogicalNOT:
*/ {
//================================================================================ Predicate_i* aPred = ( dynamic_cast<LogicalNOT_i*>( thePred ) )->GetPredicate_i();
getPrediacates( aPred, thePredVec );
void Filter_i::RemoveWaiter( TPredicateChangeWaiter* waiter ) break;
{ }
myWaiters.remove( waiter ); 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 );
} }
//======================================================================= //=======================================================================
@ -2581,7 +2699,7 @@ void Filter_i::RemoveWaiter( TPredicateChangeWaiter* waiter )
static inline bool getCriteria( Predicate_i* thePred, static inline bool getCriteria( Predicate_i* thePred,
SMESH::Filter::Criteria_out theCriteria ) SMESH::Filter::Criteria_out theCriteria )
{ {
int aFType = thePred->GetFunctorType(); const int aFType = thePred->GetFunctorType();
switch ( aFType ) switch ( aFType )
{ {
@ -2635,6 +2753,17 @@ static inline bool getCriteria( Predicate_i* thePred,
{ {
return true; 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: case FT_BelongToGeom:
{ {
BelongToGeom_i* aPred = dynamic_cast<BelongToGeom_i*>( thePred ); BelongToGeom_i* aPred = dynamic_cast<BelongToGeom_i*>( thePred );
@ -2873,6 +3002,13 @@ CORBA::Boolean Filter_i::SetCriteria( const SMESH::Filter::Criteria& theCriteria
case SMESH::FT_EqualVolumes: case SMESH::FT_EqualVolumes:
aPredicate = aFilterMgr->CreateEqualVolumes(); aPredicate = aFilterMgr->CreateEqualVolumes();
break; break;
case SMESH::FT_BelongToMeshGroup:
{
SMESH::BelongToMeshGroup_ptr tmpPred = aFilterMgr->CreateBelongToMeshGroup();
tmpPred->SetGroupID( aThresholdID );
aPredicate = tmpPred;
}
break;
case SMESH::FT_BelongToGeom: case SMESH::FT_BelongToGeom:
{ {
SMESH::BelongToGeom_ptr tmpPred = aFilterMgr->CreateBelongToGeom(); SMESH::BelongToGeom_ptr tmpPred = aFilterMgr->CreateBelongToGeom();
@ -3136,6 +3272,75 @@ Predicate_ptr Filter_i::GetPredicate()
} }
} }
//================================================================================
/*!
* \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 FILTER LIBRARY
*/ */
@ -3202,17 +3407,18 @@ static inline LDOMString toString( CORBA::Long theType )
case FT_Skew : return "Skew"; case FT_Skew : return "Skew";
case FT_Area : return "Area"; case FT_Area : return "Area";
case FT_Volume3D : return "Volume3D"; case FT_Volume3D : return "Volume3D";
case FT_MaxElementLength2D: return "Max element length 2D"; case FT_MaxElementLength2D : return "Max element length 2D";
case FT_MaxElementLength3D: return "Max element length 3D"; 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_BelongToGeom : return "Belong to Geom";
case FT_BelongToPlane : return "Belong to Plane"; case FT_BelongToPlane : return "Belong to Plane";
case FT_BelongToCylinder: return "Belong to Cylinder"; case FT_BelongToCylinder : return "Belong to Cylinder";
case FT_BelongToGenSurface: return "Belong to Generic Surface"; case FT_BelongToGenSurface : return "Belong to Generic Surface";
case FT_LyingOnGeom : return "Lying on Geom"; case FT_LyingOnGeom : return "Lying on Geom";
case FT_BadOrientedVolume:return "Bad Oriented Volume"; case FT_BadOrientedVolume : return "Bad Oriented Volume";
case FT_BareBorderVolume: return "Volumes with bare border"; case FT_BareBorderVolume : return "Volumes with bare border";
case FT_BareBorderFace : return "Faces with bare border"; case FT_BareBorderFace : return "Faces with bare border";
case FT_OverConstrainedVolume: return "Over-constrained Volumes"; case FT_OverConstrainedVolume : return "Over-constrained Volumes";
case FT_OverConstrainedFace : return "Over-constrained Faces"; case FT_OverConstrainedFace : return "Over-constrained Faces";
case FT_RangeOfIds : return "Range of IDs"; case FT_RangeOfIds : return "Range of IDs";
case FT_FreeBorders : return "Free borders"; case FT_FreeBorders : return "Free borders";
@ -3224,7 +3430,7 @@ static inline LDOMString toString( CORBA::Long theType )
case FT_EqualFaces : return "Equal faces"; case FT_EqualFaces : return "Equal faces";
case FT_EqualVolumes : return "Equal volumes"; case FT_EqualVolumes : return "Equal volumes";
case FT_MultiConnection : return "Borders at multi-connections"; case FT_MultiConnection : return "Borders at multi-connections";
case FT_MultiConnection2D:return "Borders at multi-connections 2D"; case FT_MultiConnection2D :return "Borders at multi-connections 2D";
case FT_Length : return "Length"; case FT_Length : return "Length";
case FT_Length2D : return "Length 2D"; case FT_Length2D : return "Length 2D";
case FT_LessThan : return "Less than"; case FT_LessThan : return "Less than";
@ -3257,6 +3463,7 @@ static inline SMESH::FunctorType toFunctorType( const LDOMString& theStr )
else if ( theStr.equals( "Volume3D" ) ) return FT_Volume3D; 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 2D" ) ) return FT_MaxElementLength2D;
else if ( theStr.equals( "Max element length 3D" ) ) return FT_MaxElementLength3D; 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 Geom" ) ) return FT_BelongToGeom;
else if ( theStr.equals( "Belong to Plane" ) ) return FT_BelongToPlane; else if ( theStr.equals( "Belong to Plane" ) ) return FT_BelongToPlane;
else if ( theStr.equals( "Belong to Cylinder" ) ) return FT_BelongToCylinder; else if ( theStr.equals( "Belong to Cylinder" ) ) return FT_BelongToCylinder;
@ -3838,6 +4045,7 @@ static const char** getFunctNames()
"FT_MultiConnection2D", "FT_MultiConnection2D",
"FT_Length", "FT_Length",
"FT_Length2D", "FT_Length2D",
"FT_BelongToMeshGroup",
"FT_BelongToGeom", "FT_BelongToGeom",
"FT_BelongToPlane", "FT_BelongToPlane",
"FT_BelongToCylinder", "FT_BelongToCylinder",
@ -3865,7 +4073,7 @@ static const char** getFunctNames()
"FT_Undefined"}; "FT_Undefined"};
#ifdef _DEBUG_ #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*); const int nbFunctors = sizeof(functName) / sizeof(const char*);
int _assert[( nbFunctors == SMESH::FT_Undefined + 1 ) ? 1 : -1 ]; int _assert[( nbFunctors == SMESH::FT_Undefined + 1 ) ? 1 : -1 ];
#endif #endif
@ -3905,3 +4113,62 @@ SMESH::FunctorType SMESH::StringToFunctorType(const char* str)
return SMESH::FunctorType( ft ); 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;
}

View File

@ -41,8 +41,31 @@
#include <list> #include <list>
class SMESH_GroupBase_i;
namespace SMESH 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 FUNCTORS
@ -370,6 +393,28 @@ namespace SMESH
FunctorType GetFunctorType(); 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 Class : BelongToGeom_i
Description : Predicate for selection on geometrical support Description : Predicate for selection on geometrical support
@ -896,7 +941,8 @@ namespace SMESH
FILTER FILTER
*/ */
class SMESH_I_EXPORT Filter_i: public virtual POA_SMESH::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: public:
Filter_i(); Filter_i();
@ -943,6 +989,12 @@ namespace SMESH
Predicate_i* GetPredicate_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 // SMESH_IDSource interface
// ========================= // =========================
@ -953,22 +1005,13 @@ namespace SMESH
virtual SMESH::SMESH_Mesh_ptr GetMesh(); virtual SMESH::SMESH_Mesh_ptr GetMesh();
virtual bool IsMeshInfoCorrect() { return true; } virtual bool IsMeshInfoCorrect() { return true; }
virtual SALOMEDS::TMPFile* GetVtkUgStream(); 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: private:
Controls::Filter myFilter; Controls::Filter myFilter;
Predicate_i* myPredicate; Predicate_i* myPredicate;
SMESH_Mesh_var myMesh; SMESH_Mesh_var myMesh;
std::list<TPredicateChangeWaiter*> myWaiters; std::vector< SMESH_GroupBase_i* > myBaseGroups;
}; };
@ -1036,6 +1079,7 @@ namespace SMESH
MultiConnection2D_ptr CreateMultiConnection2D(); MultiConnection2D_ptr CreateMultiConnection2D();
BallDiameter_ptr CreateBallDiameter(); BallDiameter_ptr CreateBallDiameter();
BelongToMeshGroup_ptr CreateBelongToMeshGroup();
BelongToGeom_ptr CreateBelongToGeom(); BelongToGeom_ptr CreateBelongToGeom();
BelongToPlane_ptr CreateBelongToPlane(); BelongToPlane_ptr CreateBelongToPlane();
BelongToCylinder_ptr CreateBelongToCylinder(); BelongToCylinder_ptr CreateBelongToCylinder();

View File

@ -4073,6 +4073,7 @@ bool SMESH_Gen_i::Load( SALOMEDS::SComponent_ptr theComponent,
list< pair< SMESH_Hypothesis_i*, string > > hypDataList; list< pair< SMESH_Hypothesis_i*, string > > hypDataList;
list< pair< SMESH_Mesh_i*, HDFgroup* > > meshGroupList; list< pair< SMESH_Mesh_i*, HDFgroup* > > meshGroupList;
list< SMESH::Filter_var > filters;
// get total number of top-level groups // get total number of top-level groups
int aNbGroups = aFile->nInternalObjects(); int aNbGroups = aFile->nInternalObjects();
@ -4715,6 +4716,7 @@ bool SMESH_Gen_i::Load( SALOMEDS::SComponent_ptr theComponent,
if ( strlen( persistStr ) > 0 ) { if ( strlen( persistStr ) > 0 ) {
filter = SMESH_GroupOnFilter_i::StringToFilter( persistStr ); filter = SMESH_GroupOnFilter_i::StringToFilter( persistStr );
predicate = SMESH_GroupOnFilter_i::GetPredicate( filter ); predicate = SMESH_GroupOnFilter_i::GetPredicate( filter );
filters.push_back( filter );
} }
} }
@ -4761,11 +4763,6 @@ bool SMESH_Gen_i::Load( SALOMEDS::SComponent_ptr theComponent,
Quantity_Color aColor( anRGB[0], anRGB[1], anRGB[2], Quantity_TOC_RGB ); Quantity_Color aColor( anRGB[0], anRGB[1], anRGB[2], Quantity_TOC_RGB );
aGroupBaseDS->SetColor( aColor ); 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(); aGroup->CloseOnDisk();
@ -4824,6 +4821,13 @@ bool SMESH_Gen_i::Load( SALOMEDS::SComponent_ptr theComponent,
ComputeStateEngine (SMESH_subMesh::SUBMESH_RESTORED); 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 // close mesh group
if(aTopGroup) if(aTopGroup)
aTopGroup->CloseOnDisk(); aTopGroup->CloseOnDisk();

View File

@ -244,6 +244,21 @@ CORBA::Boolean SMESH_GroupBase_i::IsEmpty()
return true; 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;
}
//============================================================================= //=============================================================================
/*! /*!
* *
@ -264,6 +279,8 @@ void SMESH_Group_i::Clear()
aGroupDS->Clear(); aGroupDS->Clear();
return; return;
} }
Modified(); // notify dependent Filter with FT_BelongToMeshGroup criterion
MESSAGE("attempt to clear a vague group"); MESSAGE("attempt to clear a vague group");
} }
@ -308,6 +325,8 @@ CORBA::Long SMESH_Group_i::Add( const SMESH::long_array& theIDs )
if (aGroupDS->Add(anID)) if (aGroupDS->Add(anID))
nbAdd++; nbAdd++;
} }
if ( nbAdd )
Modified(); // notify dependent Filter with FT_BelongToMeshGroup criterion
return nbAdd; return nbAdd;
} }
MESSAGE("attempt to add elements to a vague group"); MESSAGE("attempt to add elements to a vague group");
@ -338,6 +357,8 @@ CORBA::Long SMESH_Group_i::Remove( const SMESH::long_array& theIDs )
if (aGroupDS->Remove(anID)) if (aGroupDS->Remove(anID))
nbDel++; nbDel++;
} }
if ( nbDel )
Modified(); // notify dependent Filter with FT_BelongToMeshGroup criterion
return nbDel; return nbDel;
} }
MESSAGE("attempt to remove elements from a vague group"); MESSAGE("attempt to remove elements from a vague group");
@ -355,6 +376,7 @@ typedef bool (SMESHDS_Group::*TFunChangeGroup)(const int);
CORBA::Long CORBA::Long
ChangeByPredicate( SMESH::Predicate_i* thePredicate, ChangeByPredicate( SMESH::Predicate_i* thePredicate,
SMESHDS_GroupBase* theGroupBase, SMESHDS_GroupBase* theGroupBase,
NotifyerAndWaiter* theGroupImpl,
TFunChangeGroup theFun) TFunChangeGroup theFun)
{ {
CORBA::Long aNb = 0; CORBA::Long aNb = 0;
@ -367,6 +389,8 @@ ChangeByPredicate( SMESH::Predicate_i* thePredicate,
for(; i < iEnd; i++) for(; i < iEnd; i++)
if((aGroupDS->*theFun)(aSequence[i])) if((aGroupDS->*theFun)(aSequence[i]))
aNb++; aNb++;
if ( aNb )
theGroupImpl->Modified();
return aNb; return aNb;
} }
return aNb; return aNb;
@ -382,7 +406,7 @@ AddByPredicate( SMESH::Predicate_ptr thePredicate )
if(SMESH::Predicate_i* aPredicate = SMESH::GetPredicate(thePredicate)){ if(SMESH::Predicate_i* aPredicate = SMESH::GetPredicate(thePredicate)){
TPythonDump() << SMESH::SMESH_Group_var(_this()) TPythonDump() << SMESH::SMESH_Group_var(_this())
<< ".AddByPredicate( " << aPredicate << " )"; << ".AddByPredicate( " << aPredicate << " )";
return ChangeByPredicate( aPredicate, GetGroupDS(), &SMESHDS_Group::Add ); return ChangeByPredicate( aPredicate, GetGroupDS(), this, &SMESHDS_Group::Add );
} }
return 0; return 0;
} }
@ -397,7 +421,7 @@ RemoveByPredicate( SMESH::Predicate_ptr thePredicate )
if(SMESH::Predicate_i* aPredicate = SMESH::GetPredicate(thePredicate)){ if(SMESH::Predicate_i* aPredicate = SMESH::GetPredicate(thePredicate)){
TPythonDump() << SMESH::SMESH_Group_var(_this()) TPythonDump() << SMESH::SMESH_Group_var(_this())
<< ".RemoveByPredicate( " << aPredicate << " )"; << ".RemoveByPredicate( " << aPredicate << " )";
return ChangeByPredicate(aPredicate,GetGroupDS(),&SMESHDS_Group::Remove); return ChangeByPredicate(aPredicate,GetGroupDS(),this, &SMESHDS_Group::Remove);
} }
return 0; return 0;
} }
@ -419,7 +443,10 @@ CORBA::Long SMESH_Group_i::AddFrom( SMESH::SMESH_IDSource_ptr theSource )
// Update Python script // Update Python script
pd << "nbAdd = " << SMESH::SMESH_Group_var(_this()) << ".AddFrom( " << theSource << " )"; 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;
} }
//============================================================================= //=============================================================================
@ -784,6 +811,7 @@ SMESH_PredicatePtr SMESH_GroupOnFilter_i::GetPredicate( SMESH::Filter_ptr filter
//================================================================================ //================================================================================
void SMESH_GroupOnFilter_i::SetFilter(SMESH::Filter_ptr theFilter) void SMESH_GroupOnFilter_i::SetFilter(SMESH::Filter_ptr theFilter)
throw (SALOME::SALOME_Exception)
{ {
if ( myFilter->_is_equivalent( theFilter )) if ( myFilter->_is_equivalent( theFilter ))
return; return;
@ -796,17 +824,34 @@ void SMESH_GroupOnFilter_i::SetFilter(SMESH::Filter_ptr theFilter)
myFilter = SMESH::Filter::_duplicate( theFilter ); myFilter = SMESH::Filter::_duplicate( theFilter );
if ( !myFilter->_is_nil() )
{
myFilter->Register();
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 ( SMESHDS_GroupOnFilter* grDS = dynamic_cast< SMESHDS_GroupOnFilter*>( GetGroupDS() )) if ( SMESHDS_GroupOnFilter* grDS = dynamic_cast< SMESHDS_GroupOnFilter*>( GetGroupDS() ))
{
grDS->SetPredicate( GetPredicate( myFilter )); grDS->SetPredicate( GetPredicate( myFilter ));
Modified(); // notify dependent Filter with FT_BelongToMeshGroup criterion
}
TPythonDump()<< SMESH::SMESH_GroupOnFilter_var(_this()) <<".SetFilter( "<<theFilter<<" )"; TPythonDump()<< SMESH::SMESH_GroupOnFilter_var(_this()) <<".SetFilter( "<<theFilter<<" )";
if ( myFilter )
{
myFilter->SetMesh( SMESH::SMESH_Mesh::_nil() ); // to UnRegister() the mesh
myFilter->Register();
SMESH::DownCast< SMESH::Filter_i* >( myFilter )->AddWaiter( this );
}
} }
//================================================================================ //================================================================================
@ -900,9 +945,17 @@ std::string SMESH_GroupOnFilter_i::FilterToString() const
result << criteria->length() << SEPAR; result << criteria->length() << SEPAR;
for ( unsigned i = 0; i < criteria->length(); ++i ) 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 // write FunctorType as string but not as number to assure correct
// persistence if enum FunctorType is modified by insertion in the middle // 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.Type )) << SEPAR;
result << SMESH::FunctorTypeToString( SMESH::FunctorType( crit.Compare )) << SEPAR; result << SMESH::FunctorTypeToString( SMESH::FunctorType( crit.Compare )) << SEPAR;
result << crit.Threshold << SEPAR; result << crit.Threshold << SEPAR;
@ -987,22 +1040,22 @@ SMESH_GroupOnFilter_i::~SMESH_GroupOnFilter_i()
{ {
if ( ! myFilter->_is_nil() ) if ( ! myFilter->_is_nil() )
{ {
SMESH::DownCast< SMESH::Filter_i* >( myFilter )->RemoveWaiter( this ); SMESH::DownCast< SMESH::Filter_i* >( myFilter )->RemoveModifWaiter( this );
myFilter->UnRegister(); 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 ) if ( myPreMeshInfo )
myPreMeshInfo->FullLoadFromFile(); myPreMeshInfo->FullLoadFromFile();
if ( SMESHDS_GroupOnFilter* grDS = dynamic_cast< SMESHDS_GroupOnFilter*>( GetGroupDS() )) if ( SMESHDS_GroupOnFilter* grDS = dynamic_cast< SMESHDS_GroupOnFilter*>( GetGroupDS() ))
grDS->SetPredicate( GetPredicate( myFilter )); grDS->SetPredicate( GetPredicate( myFilter )); // group resets its cache
} }

View File

@ -48,7 +48,8 @@ class SMESH_PreMeshInfo;
// =========== // ===========
class SMESH_I_EXPORT SMESH_GroupBase_i: class SMESH_I_EXPORT SMESH_GroupBase_i:
public virtual POA_SMESH::SMESH_GroupBase, 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: public:
SMESH_GroupBase_i(PortableServer::POA_ptr thePOA, SMESH_GroupBase_i(PortableServer::POA_ptr thePOA,
@ -100,6 +101,13 @@ class SMESH_I_EXPORT SMESH_GroupBase_i:
*/ */
virtual SALOMEDS::TMPFile* GetVtkUgStream(); 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 // Internal C++ interface
int GetLocalID() const { return myLocalID; } int GetLocalID() const { return myLocalID; }
SMESH_Mesh_i* GetMeshServant() const { return myMeshServant; } SMESH_Mesh_i* GetMeshServant() const { return myMeshServant; }
@ -173,8 +181,7 @@ class SMESH_I_EXPORT SMESH_GroupOnGeom_i:
class SMESH_I_EXPORT SMESH_GroupOnFilter_i: class SMESH_I_EXPORT SMESH_GroupOnFilter_i:
public virtual POA_SMESH::SMESH_GroupOnFilter, public virtual POA_SMESH::SMESH_GroupOnFilter,
public SMESH_GroupBase_i, public SMESH_GroupBase_i
public SMESH::Filter_i::TPredicateChangeWaiter
{ {
public: public:
SMESH_GroupOnFilter_i( PortableServer::POA_ptr thePOA, SMESH_GroupOnFilter_i( PortableServer::POA_ptr thePOA,
@ -189,13 +196,13 @@ class SMESH_I_EXPORT SMESH_GroupOnFilter_i:
static SMESH_PredicatePtr GetPredicate( SMESH::Filter_ptr ); static SMESH_PredicatePtr GetPredicate( SMESH::Filter_ptr );
// CORBA interface implementation // CORBA interface implementation
void SetFilter(SMESH::Filter_ptr theFilter); void SetFilter(SMESH::Filter_ptr theFilter) throw (SALOME::SALOME_Exception);
SMESH::Filter_ptr GetFilter(); SMESH::Filter_ptr GetFilter();
virtual SMESH::long_array* GetListOfID(); virtual SMESH::long_array* GetListOfID();
virtual SMESH::long_array* GetMeshInfo(); virtual SMESH::long_array* GetMeshInfo();
// method of SMESH::Filter_i::TPredicateChangeWaiter // method of SMESH::NotifyerAndWaiter to update self when myFilter changes
virtual void PredicateChanged(); virtual void OnBaseObjModified(NotifyerAndWaiter* filter, bool);
private: private:
SMESH::Filter_var myFilter; SMESH::Filter_var myFilter;

View File

@ -1057,6 +1057,7 @@ void SMESH_Mesh_i::RemoveGroup( SMESH::SMESH_GroupBase_ptr theGroup )
builder->RemoveObjectWithChildren( aGroupSO ); builder->RemoveObjectWithChildren( aGroupSO );
} }
} }
aGroup->Modified(/*removed=*/true); // notify dependent Filter with FT_BelongToMeshGroup criterion
// Remove the group from SMESH data structures // Remove the group from SMESH data structures
removeGroup( aGroup->GetLocalID() ); removeGroup( aGroup->GetLocalID() );

View File

@ -732,7 +732,7 @@ class smeshBuilder(object, SMESH._objref_SMESH_Gen):
if CritType in [FT_BelongToGeom, FT_BelongToPlane, FT_BelongToGenSurface, if CritType in [FT_BelongToGeom, FT_BelongToPlane, FT_BelongToGenSurface,
FT_BelongToCylinder, FT_LyingOnGeom]: FT_BelongToCylinder, FT_LyingOnGeom]:
# Checks that Threshold is GEOM object # Check that Threshold is GEOM object
if isinstance(aThreshold, geomBuilder.GEOM._objref_GEOM_Object): if isinstance(aThreshold, geomBuilder.GEOM._objref_GEOM_Object):
aCriterion.ThresholdStr = GetName(aThreshold) aCriterion.ThresholdStr = GetName(aThreshold)
aCriterion.ThresholdID = aThreshold.GetStudyEntry() aCriterion.ThresholdID = aThreshold.GetStudyEntry()
@ -745,21 +745,28 @@ class smeshBuilder(object, SMESH._objref_SMESH_Gen):
elif isinstance( aThreshold, str ): elif isinstance( aThreshold, str ):
aCriterion.ThresholdStr = aThreshold aCriterion.ThresholdStr = aThreshold
else: else:
print "Error: The Threshold should be a shape." raise TypeError, "The Threshold should be a shape."
return None
if isinstance(UnaryOp,float): if isinstance(UnaryOp,float):
aCriterion.Tolerance = UnaryOp aCriterion.Tolerance = UnaryOp
UnaryOp = FT_Undefined UnaryOp = FT_Undefined
pass 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: elif CritType == FT_RangeOfIds:
# Checks that Threshold is string # Check that Threshold is string
if isinstance(aThreshold, str): if isinstance(aThreshold, str):
aCriterion.ThresholdStr = aThreshold aCriterion.ThresholdStr = aThreshold
else: else:
print "Error: The Threshold should be a string." raise TypeError, "The Threshold should be a string."
return None
elif CritType == FT_CoplanarFaces: elif CritType == FT_CoplanarFaces:
# Checks the Threshold # Check the Threshold
if isinstance(aThreshold, int): if isinstance(aThreshold, int):
aCriterion.ThresholdID = str(aThreshold) aCriterion.ThresholdID = str(aThreshold)
elif isinstance(aThreshold, str): elif isinstance(aThreshold, str):
@ -768,10 +775,10 @@ class smeshBuilder(object, SMESH._objref_SMESH_Gen):
raise ValueError, "Invalid ID of mesh face: '%s'"%aThreshold raise ValueError, "Invalid ID of mesh face: '%s'"%aThreshold
aCriterion.ThresholdID = aThreshold aCriterion.ThresholdID = aThreshold
else: else:
raise ValueError,\ raise TypeError,\
"The Threshold should be an ID of mesh face and not '%s'"%aThreshold "The Threshold should be an ID of mesh face and not '%s'"%aThreshold
elif CritType == FT_ConnectedElements: elif CritType == FT_ConnectedElements:
# Checks the Threshold # Check the Threshold
if isinstance(aThreshold, geomBuilder.GEOM._objref_GEOM_Object): # shape if isinstance(aThreshold, geomBuilder.GEOM._objref_GEOM_Object): # shape
aCriterion.ThresholdID = aThreshold.GetStudyEntry() aCriterion.ThresholdID = aThreshold.GetStudyEntry()
if not aCriterion.ThresholdID: if not aCriterion.ThresholdID:
@ -791,11 +798,11 @@ class smeshBuilder(object, SMESH._objref_SMESH_Gen):
else: else:
aCriterion.ThresholdStr = aThreshold # hope that it's point coordinates aCriterion.ThresholdStr = aThreshold # hope that it's point coordinates
else: else:
raise ValueError,\ raise TypeError,\
"The Threshold should either a VERTEX, or a node ID, "\ "The Threshold should either a VERTEX, or a node ID, "\
"or a list of point coordinates and not '%s'"%aThreshold "or a list of point coordinates and not '%s'"%aThreshold
elif CritType == FT_ElemGeomType: elif CritType == FT_ElemGeomType:
# Checks the Threshold # Check the Threshold
try: try:
aCriterion.Threshold = self.EnumToLong(aThreshold) aCriterion.Threshold = self.EnumToLong(aThreshold)
assert( aThreshold in SMESH.GeometryType._items ) assert( aThreshold in SMESH.GeometryType._items )
@ -803,12 +810,11 @@ class smeshBuilder(object, SMESH._objref_SMESH_Gen):
if isinstance(aThreshold, int): if isinstance(aThreshold, int):
aCriterion.Threshold = aThreshold aCriterion.Threshold = aThreshold
else: else:
print "Error: The Threshold should be an integer or SMESH.GeometryType." raise TypeError, "The Threshold should be an integer or SMESH.GeometryType."
return None
pass pass
pass pass
elif CritType == FT_EntityType: elif CritType == FT_EntityType:
# Checks the Threshold # Check the Threshold
try: try:
aCriterion.Threshold = self.EnumToLong(aThreshold) aCriterion.Threshold = self.EnumToLong(aThreshold)
assert( aThreshold in SMESH.EntityType._items ) assert( aThreshold in SMESH.EntityType._items )
@ -816,18 +822,16 @@ class smeshBuilder(object, SMESH._objref_SMESH_Gen):
if isinstance(aThreshold, int): if isinstance(aThreshold, int):
aCriterion.Threshold = aThreshold aCriterion.Threshold = aThreshold
else: else:
print "Error: The Threshold should be an integer or SMESH.EntityType." raise TypeError, "The Threshold should be an integer or SMESH.EntityType."
return None
pass pass
pass pass
elif CritType == FT_GroupColor: elif CritType == FT_GroupColor:
# Checks the Threshold # Check the Threshold
try: try:
aCriterion.ThresholdStr = self.ColorToString(aThreshold) aCriterion.ThresholdStr = self.ColorToString(aThreshold)
except: except:
print "Error: The threshold value should be of SALOMEDS.Color type" raise TypeError, "The threshold value should be of SALOMEDS.Color type"
return None
pass pass
elif CritType in [FT_FreeBorders, FT_FreeEdges, FT_FreeNodes, FT_FreeFaces, elif CritType in [FT_FreeBorders, FT_FreeEdges, FT_FreeNodes, FT_FreeFaces,
FT_LinearOrQuadratic, FT_BadOrientedVolume, FT_LinearOrQuadratic, FT_BadOrientedVolume,
@ -845,7 +849,7 @@ class smeshBuilder(object, SMESH._objref_SMESH_Gen):
aThreshold = float(aThreshold) aThreshold = float(aThreshold)
aCriterion.Threshold = aThreshold aCriterion.Threshold = aThreshold
except: except:
print "Error: The Threshold should be a number." raise TypeError, "The Threshold should be a number."
return None return None
if Threshold == FT_LogicalNOT or UnaryOp == FT_LogicalNOT: if Threshold == FT_LogicalNOT or UnaryOp == FT_LogicalNOT: