From: eap Date: Tue, 14 Apr 2015 12:39:28 +0000 (+0300) Subject: 22877: EDF 10054 SMESH: Add a new filter "BelongToSmeshGroup" for Create Group X-Git-Tag: V7_6_0b1~1 X-Git-Url: http://git.salome-platform.org/gitweb/?p=modules%2Fsmesh.git;a=commitdiff_plain;h=5ac2bd91a85417fd289aea0907264cb2d155d76d 22877: EDF 10054 SMESH: Add a new filter "BelongToSmeshGroup" for Create Group --- diff --git a/doc/salome/examples/CMakeLists.txt b/doc/salome/examples/CMakeLists.txt index 8780e9389..7ee8ff5fd 100644 --- a/doc/salome/examples/CMakeLists.txt +++ b/doc/salome/examples/CMakeLists.txt @@ -95,6 +95,7 @@ SET(GOOD_TESTS filters_ex33.py filters_ex34.py filters_ex36.py + filters_belong2group.py grouping_elements_ex01.py grouping_elements_ex02.py grouping_elements_ex03.py diff --git a/doc/salome/examples/filters_belong2group.py b/doc/salome/examples/filters_belong2group.py new file mode 100644 index 000000000..889c0aef7 --- /dev/null +++ b/doc/salome/examples/filters_belong2group.py @@ -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() ) + diff --git a/doc/salome/gui/SMESH/input/about_filters.doc b/doc/salome/gui/SMESH/input/about_filters.doc index d05b8f09a..bbd596023 100644 --- a/doc/salome/gui/SMESH/input/about_filters.doc +++ b/doc/salome/gui/SMESH/input/about_filters.doc @@ -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 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 diff --git a/doc/salome/gui/SMESH/input/selection_filter_library.doc b/doc/salome/gui/SMESH/input/selection_filter_library.doc index a0e85ab81..6ab408ee1 100644 --- a/doc/salome/gui/SMESH/input/selection_filter_library.doc +++ b/doc/salome/gui/SMESH/input/selection_filter_library.doc @@ -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 Volumes. You can combine many criteria in one filter, but they all -must be of the same Entity type. -\n The \b Add button creates a new criterion at the end of the list of +must be of the same Entity type.
+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. @@ -43,11 +43,11 @@ selection of elements in the Viewer to the current filter.
In the \b Source field you choose if the filter will be applied to the whole \b Mesh, the Initial Selection or the Current -Group. If \b Mesh is chosen, the elements satisfying the filter +Dialog. If \b Mesh is chosen, the elements satisfying the filter will be selected in the 3D Viewer. If Initial Selection is chosen, the filter will be applied to the selected elements and the elements rejected by the filter will be deselected. If Current -Group is chosen, the filter will be applied to the list of +Dialog 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.
@@ -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 shape, the algorithm works slower.
  • +Belong to Mesh Group selects entities included into a mesh group +defined by Threshold Value. +
  • Range of IDs allows selection of entities with the specified IDs. Threshold Value can be, for example: "1,2,3,50-60,63,67,70-78" diff --git a/doc/salome/gui/SMESH/input/tui_filters.doc b/doc/salome/gui/SMESH/input/tui_filters.doc index 856c7fe9b..bf3a1f72e 100755 --- a/doc/salome/gui/SMESH/input/tui_filters.doc +++ b/doc/salome/gui/SMESH/input/tui_filters.doc @@ -2,14 +2,16 @@ \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). @@ -300,6 +302,16 @@ Filter over-constrained volumes: \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 diff --git a/idl/SMESH_Filter.idl b/idl/SMESH_Filter.idl index 42147a21f..738aa325e 100644 --- a/idl/SMESH_Filter.idl +++ b/idl/SMESH_Filter.idl @@ -61,6 +61,7 @@ module SMESH FT_MultiConnection2D, FT_Length, FT_Length2D, + FT_BelongToMeshGroup, FT_BelongToGeom, FT_BelongToPlane, FT_BelongToCylinder, @@ -228,6 +229,17 @@ module SMESH */ 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 @@ -559,59 +571,60 @@ module SMESH /*! * 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(); diff --git a/idl/SMESH_Group.idl b/idl/SMESH_Group.idl index db6a0f331..4941f14df 100644 --- a/idl/SMESH_Group.idl +++ b/idl/SMESH_Group.idl @@ -121,7 +121,13 @@ module SMESH * (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 @@ -170,7 +176,7 @@ module SMESH */ interface SMESH_GroupOnFilter : SMESH_GroupBase { - void SetFilter( in Filter theFilter); + void SetFilter( in Filter theFilter) raises (SALOME::SALOME_Exception); Filter GetFilter(); }; diff --git a/src/Controls/SMESH_Controls.cxx b/src/Controls/SMESH_Controls.cxx index 48c4d878d..a5739224f 100644 --- a/src/Controls/SMESH_Controls.cxx +++ b/src/Controls/SMESH_Controls.cxx @@ -3820,9 +3820,55 @@ 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(theMesh)) + { + const std::set& grps = aMesh->GetGroups(); + std::set::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() diff --git a/src/Controls/SMESH_ControlsDef.hxx b/src/Controls/SMESH_ControlsDef.hxx index 7c01c4b28..cf3a7cd98 100644 --- a/src/Controls/SMESH_ControlsDef.hxx +++ b/src/Controls/SMESH_ControlsDef.hxx @@ -54,6 +54,7 @@ class SMDS_Mesh; class SMESHDS_Mesh; class SMESHDS_SubMesh; +class SMESHDS_GroupBase; class gp_Pnt; @@ -763,8 +764,8 @@ namespace SMESH{ 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; @@ -779,6 +780,27 @@ namespace SMESH{ }; typedef boost::shared_ptr 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 BelongToMeshGroupPtr; /* Class : ElementsOnSurface @@ -809,7 +831,6 @@ namespace SMESH{ TMeshModifTracer myMeshModifTracer; TColStd_MapOfInteger myIds; SMDSAbs_ElementType myType; - //Handle(Geom_Surface) mySurf; TopoDS_Face mySurf; double myToler; bool myUseBoundaries; diff --git a/src/SMESHDS/SMESH_Controls.hxx b/src/SMESHDS/SMESH_Controls.hxx index 5b741437a..ee7c742f5 100644 --- a/src/SMESHDS/SMESH_Controls.hxx +++ b/src/SMESHDS/SMESH_Controls.hxx @@ -48,7 +48,7 @@ namespace SMESH{ /* Class : Functor - Description : Root of all Functors + Description : Root of all Functors defined in ../Controls/SMESH_ControlsDef.hxx */ class SMESHCONTROLS_EXPORT Functor { diff --git a/src/SMESHGUI/SMESHGUI_FilterDlg.cxx b/src/SMESHGUI/SMESHGUI_FilterDlg.cxx index 891b41ca5..c1b80e0d0 100755 --- a/src/SMESHGUI/SMESHGUI_FilterDlg.cxx +++ b/src/SMESHGUI/SMESHGUI_FilterDlg.cxx @@ -56,10 +56,11 @@ #include #include -#include -#include -#include +#include #include +#include +#include +#include #include @@ -1134,6 +1135,7 @@ bool SMESHGUI_FilterTable::IsValid (const bool theMess, const int theEntityType) 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 || @@ -1283,6 +1285,7 @@ void SMESHGUI_FilterTable::GetCriterion (const int theRow, } } else if ( aCriterionType != SMESH::FT_RangeOfIds && + aCriterionType != SMESH::FT_BelongToMeshGroup && aCriterionType != SMESH::FT_BelongToGeom && aCriterionType != SMESH::FT_BelongToPlane && aCriterionType != SMESH::FT_BelongToCylinder && @@ -1382,6 +1385,7 @@ void SMESHGUI_FilterTable::SetCriterion (const int theRow, } } 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 && @@ -1398,6 +1402,7 @@ void SMESHGUI_FilterTable::SetCriterion (const int theRow, 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 @@ -1813,13 +1818,15 @@ void SMESHGUI_FilterTable::onCriterionChanged (const int row, const int col, con 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: @@ -2162,6 +2169,7 @@ const QMap& SMESHGUI_FilterTable::getCriteria (const int theType) 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"); @@ -2183,6 +2191,7 @@ const QMap& SMESHGUI_FilterTable::getCriteria (const int theType) 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"); @@ -2211,6 +2220,7 @@ const QMap& SMESHGUI_FilterTable::getCriteria (const int theType) 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"); @@ -2238,6 +2248,7 @@ const QMap& SMESHGUI_FilterTable::getCriteria (const int theType) { 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"); @@ -2260,6 +2271,7 @@ const QMap& SMESHGUI_FilterTable::getCriteria (const int theType) 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"); @@ -2276,6 +2288,7 @@ const QMap& SMESHGUI_FilterTable::getCriteria (const int theType) { 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"); @@ -2291,6 +2304,7 @@ const QMap& SMESHGUI_FilterTable::getCriteria (const int theType) 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"); @@ -2306,6 +2320,7 @@ const QMap& SMESHGUI_FilterTable::getCriteria (const int theType) 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"); @@ -2869,6 +2884,7 @@ void SMESHGUI_FilterDlg::Init (const QList& theTypes, const bool setInViewe mySourceWg = 0; myTypes = theTypes; myMesh = SMESH::SMESH_Mesh::_nil(); + myGroup = SMESH::SMESH_GroupOnFilter::_nil(); myIObjects.Clear(); myIsSelectionChanged = false; myToRestoreSelMode = false; @@ -3147,8 +3163,7 @@ bool SMESHGUI_FilterDlg::isValid() const 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; @@ -3252,6 +3267,15 @@ void SMESHGUI_FilterDlg::SetMesh (SMESH::SMESH_Mesh_var theMesh) 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 @@ -3659,10 +3683,10 @@ void SMESHGUI_FilterDlg::onSelectionDone() const int type = myTable->GetCriterionType(aRow); QList 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; @@ -3694,6 +3718,29 @@ void SMESHGUI_FilterDlg::onSelectionDone() } break; } + case SMESH::FT_BelongToMeshGroup: // get a group name and IOR + { + SMESH::SMESH_GroupBase_var grp = SMESH::IObjectToInterface(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 + ( 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(anIO); @@ -3785,6 +3832,23 @@ void SMESHGUI_FilterDlg::updateSelection() 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 fList; diff --git a/src/SMESHGUI/SMESHGUI_FilterDlg.h b/src/SMESHGUI/SMESHGUI_FilterDlg.h index 0f14915ae..55d854c17 100755 --- a/src/SMESHGUI/SMESHGUI_FilterDlg.h +++ b/src/SMESHGUI/SMESHGUI_FilterDlg.h @@ -228,6 +228,7 @@ public: 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 ); @@ -297,6 +298,7 @@ private: LightApp_SelectionMgr* mySelectionMgr; SVTK_Selector* mySelector; SMESH::SMESH_Mesh_var myMesh; + SMESH::SMESH_GroupOnFilter_var myGroup; bool myInitSourceWgOnApply; bool myInsertEnabled; bool myDiffSourcesEnabled; diff --git a/src/SMESHGUI/SMESHGUI_FilterLibraryDlg.cxx b/src/SMESHGUI/SMESHGUI_FilterLibraryDlg.cxx index 2fc4c48fd..c4b0465de 100644 --- a/src/SMESHGUI/SMESHGUI_FilterLibraryDlg.cxx +++ b/src/SMESHGUI/SMESHGUI_FilterLibraryDlg.cxx @@ -1205,11 +1205,11 @@ void SMESHGUI_FilterLibraryDlg::onSelectionDone() return; const int type = myTable->GetCriterionType(aRow); - QList types; - types << SMESH::FT_BelongToGeom << SMESH::FT_BelongToPlane - << SMESH::FT_BelongToCylinder << SMESH::FT_BelongToGenSurface - << SMESH::FT_LyingOnGeom << SMESH::FT_CoplanarFaces - << SMESH::FT_ConnectedElements; + QList 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; @@ -1241,6 +1241,10 @@ void SMESHGUI_FilterLibraryDlg::onSelectionDone() } 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(anIO); diff --git a/src/SMESHGUI/SMESHGUI_GroupDlg.cxx b/src/SMESHGUI/SMESHGUI_GroupDlg.cxx index 9445167a4..2a1c5c49b 100644 --- a/src/SMESHGUI/SMESHGUI_GroupDlg.cxx +++ b/src/SMESHGUI/SMESHGUI_GroupDlg.cxx @@ -1197,7 +1197,10 @@ bool SMESHGUI_GroupDlg::onApply() } // update a visible group accoding to a changed contents if ( !isConversion && anActor->GetVisibility() ) + { SMESH::Update( anIO, true ); + SMESH::RepaintCurrentView(); + } } } } @@ -1762,10 +1765,10 @@ void SMESHGUI_GroupDlg::setFilters() myFilterDlg->SetEnabled( /*setInViewer=*/isStandalone, /*diffSources=*/isStandalone ); myFilterDlg->SetMesh( myMesh ); + myFilterDlg->SetGroup( myGroupOnFilter ); myFilterDlg->SetSelection(); myFilterDlg->SetSourceWg( myElements, false ); - myFilterDlg->show(); } diff --git a/src/SMESHGUI/SMESHGUI_VTKUtils.cxx b/src/SMESHGUI/SMESHGUI_VTKUtils.cxx index eb4df435d..bcc289cc0 100644 --- a/src/SMESHGUI/SMESHGUI_VTKUtils.cxx +++ b/src/SMESHGUI/SMESHGUI_VTKUtils.cxx @@ -28,16 +28,15 @@ #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 -#include #include "SMESH_NodeLabelActor.h" -#include "SMESH_CellLabelActor.h" -#include -#include +#include "SMESH_ObjectDef.h" // SALOME GUI includes #include diff --git a/src/SMESHGUI/SMESH_msg_en.ts b/src/SMESHGUI/SMESH_msg_en.ts index ee06a2eb4..28c62a0fe 100644 --- a/src/SMESHGUI/SMESH_msg_en.ts +++ b/src/SMESHGUI/SMESH_msg_en.ts @@ -5421,6 +5421,10 @@ Please check input data and try again OVER_CONSTRAINED_FACE Over-constrained faces + + BELONG_TO_MESH_GROUP + Belong to Mesh Group + BELONG_TO_CYLINDER Belong to Cylinder diff --git a/src/SMESH_I/SMESH_DumpPython.cxx b/src/SMESH_I/SMESH_DumpPython.cxx index dd885752e..20fea4abc 100644 --- a/src/SMESH_I/SMESH_DumpPython.cxx +++ b/src/SMESH_I/SMESH_DumpPython.cxx @@ -423,6 +423,7 @@ namespace SMESH 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; diff --git a/src/SMESH_I/SMESH_Filter_i.cxx b/src/SMESH_I/SMESH_Filter_i.cxx index 1165cc93f..7dc847a3e 100644 --- a/src/SMESH_I/SMESH_Filter_i.cxx +++ b/src/SMESH_I/SMESH_Filter_i.cxx @@ -31,6 +31,7 @@ #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" @@ -722,6 +723,108 @@ FunctorType OverConstrainedFace_i::GetFunctorType() 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( 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 @@ -1772,6 +1875,7 @@ Predicate_i* LogicalNOT_i::GetPredicate_i() } + /* Class : LogicalBinary_i Description : Base class for binary logical predicate @@ -2023,6 +2127,14 @@ BallDiameter_ptr FilterManager_i::CreateBallDiameter() return anObj._retn(); } +BelongToMeshGroup_ptr FilterManager_i::CreateBelongToMeshGroup() +{ + SMESH::BelongToMeshGroup_i* aServant = new SMESH::BelongToMeshGroup_i(); + SMESH::BelongToMeshGroup_var anObj = aServant->_this(); + TPythonDump()<UnRegister(); - //TPythonDump()<GetPredicate()->SetMesh( aMesh ); TPythonDump()<::iterator i = myWaiters.begin(); - for ( ; i != myWaiters.end(); ++i ) - (*i)->PredicateChanged(); + NotifyerAndWaiter::Modified(); } //======================================================================= @@ -2550,28 +2661,35 @@ SALOMEDS::TMPFile* Filter_i::GetVtkUgStream() 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 & 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( thePred ) )->GetPredicate_i(); + getPrediacates( aPred, thePredVec ); + break; + } + case FT_LogicalAND: + case FT_LogicalOR: + { + Predicate_i* aPred1 = ( dynamic_cast( thePred ) )->GetPredicate1_i(); + Predicate_i* aPred2 = ( dynamic_cast( 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, SMESH::Filter::Criteria_out theCriteria ) { - int aFType = thePred->GetFunctorType(); + const int aFType = thePred->GetFunctorType(); switch ( aFType ) { @@ -2635,6 +2753,17 @@ static inline bool getCriteria( Predicate_i* thePred, { return true; } + case FT_BelongToMeshGroup: + { + BelongToMeshGroup_i* aPred = dynamic_cast( 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( thePred ); @@ -2873,6 +3002,13 @@ CORBA::Boolean Filter_i::SetCriteria( const SMESH::Filter::Criteria& theCriteria 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(); @@ -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 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 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 */ @@ -3195,50 +3400,51 @@ static inline LDOMString toString( CORBA::Long theType ) { 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 ""; } } @@ -3257,6 +3463,7 @@ static inline SMESH::FunctorType toFunctorType( const LDOMString& theStr ) 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; @@ -3838,6 +4045,7 @@ static const char** getFunctNames() "FT_MultiConnection2D", "FT_Length", "FT_Length2D", + "FT_BelongToMeshGroup", "FT_BelongToGeom", "FT_BelongToPlane", "FT_BelongToCylinder", @@ -3865,7 +4073,7 @@ static const char** getFunctNames() "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 @@ -3905,3 +4113,62 @@ SMESH::FunctorType SMESH::StringToFunctorType(const char* str) 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 waiters = myWaiters; // myWaiters can be changed by Modified() + std::list::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::iterator w = myWaiters.begin(); + for ( ; !is && w != myWaiters.end(); ++w ) + is = (*w)->ContainModifWaiter( waiter ); + + return is; +} diff --git a/src/SMESH_I/SMESH_Filter_i.hxx b/src/SMESH_I/SMESH_Filter_i.hxx index 1b70ae388..92b1235b4 100644 --- a/src/SMESH_I/SMESH_Filter_i.hxx +++ b/src/SMESH_I/SMESH_Filter_i.hxx @@ -41,8 +41,31 @@ #include +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 myWaiters; + }; // ================================================================================ /* FUNCTORS @@ -370,6 +393,28 @@ namespace SMESH 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 @@ -896,7 +941,8 @@ namespace 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: Filter_i(); @@ -943,6 +989,12 @@ namespace SMESH 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 // ========================= @@ -953,22 +1005,13 @@ namespace SMESH 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 myWaiters; + std::vector< SMESH_GroupBase_i* > myBaseGroups; }; @@ -1036,6 +1079,7 @@ namespace SMESH MultiConnection2D_ptr CreateMultiConnection2D(); BallDiameter_ptr CreateBallDiameter(); + BelongToMeshGroup_ptr CreateBelongToMeshGroup(); BelongToGeom_ptr CreateBelongToGeom(); BelongToPlane_ptr CreateBelongToPlane(); BelongToCylinder_ptr CreateBelongToCylinder(); diff --git a/src/SMESH_I/SMESH_Gen_i.cxx b/src/SMESH_I/SMESH_Gen_i.cxx index 58bbe32f0..824655a87 100644 --- a/src/SMESH_I/SMESH_Gen_i.cxx +++ b/src/SMESH_I/SMESH_Gen_i.cxx @@ -4073,6 +4073,7 @@ bool SMESH_Gen_i::Load( SALOMEDS::SComponent_ptr theComponent, 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(); @@ -4715,6 +4716,7 @@ bool SMESH_Gen_i::Load( SALOMEDS::SComponent_ptr theComponent, if ( strlen( persistStr ) > 0 ) { filter = SMESH_GroupOnFilter_i::StringToFilter( persistStr ); 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 ); aGroupBaseDS->SetColor( aColor ); } - - // Fill group with contents from MED file - // SMESHDS_Group* aGrp = dynamic_cast( aGroupBaseDS ); - // if ( aGrp ) - // myReader.GetGroup( aGrp ); } } aGroup->CloseOnDisk(); @@ -4824,6 +4821,13 @@ bool SMESH_Gen_i::Load( SALOMEDS::SComponent_ptr theComponent, 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(); diff --git a/src/SMESH_I/SMESH_Group_i.cxx b/src/SMESH_I/SMESH_Group_i.cxx index 0a955a1fa..6218de9f8 100644 --- a/src/SMESH_I/SMESH_Group_i.cxx +++ b/src/SMESH_I/SMESH_Group_i.cxx @@ -244,6 +244,21 @@ CORBA::Boolean SMESH_GroupBase_i::IsEmpty() 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(); return; } + Modified(); // notify dependent Filter with FT_BelongToMeshGroup criterion + 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)) nbAdd++; } + if ( nbAdd ) + Modified(); // notify dependent Filter with FT_BelongToMeshGroup criterion return nbAdd; } 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)) nbDel++; } + if ( nbDel ) + Modified(); // notify dependent Filter with FT_BelongToMeshGroup criterion return nbDel; } MESSAGE("attempt to remove elements from a vague group"); @@ -355,6 +376,7 @@ typedef bool (SMESHDS_Group::*TFunChangeGroup)(const int); CORBA::Long ChangeByPredicate( SMESH::Predicate_i* thePredicate, SMESHDS_GroupBase* theGroupBase, + NotifyerAndWaiter* theGroupImpl, TFunChangeGroup theFun) { CORBA::Long aNb = 0; @@ -367,6 +389,8 @@ ChangeByPredicate( SMESH::Predicate_i* thePredicate, for(; i < iEnd; i++) if((aGroupDS->*theFun)(aSequence[i])) aNb++; + if ( aNb ) + theGroupImpl->Modified(); return aNb; } return aNb; @@ -382,7 +406,7 @@ AddByPredicate( SMESH::Predicate_ptr thePredicate ) 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; } @@ -397,7 +421,7 @@ RemoveByPredicate( SMESH::Predicate_ptr thePredicate ) 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; } @@ -419,12 +443,15 @@ CORBA::Long SMESH_Group_i::AddFrom( SMESH::SMESH_IDSource_ptr theSource ) // 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; } //============================================================================= /*! - * + * */ //============================================================================= @@ -784,6 +811,7 @@ SMESH_PredicatePtr SMESH_GroupOnFilter_i::GetPredicate( SMESH::Filter_ptr filter //================================================================================ void SMESH_GroupOnFilter_i::SetFilter(SMESH::Filter_ptr theFilter) + throw (SALOME::SALOME_Exception) { if ( myFilter->_is_equivalent( theFilter )) return; @@ -796,17 +824,34 @@ void SMESH_GroupOnFilter_i::SetFilter(SMESH::Filter_ptr theFilter) 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( "<( 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( "<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; @@ -987,22 +1040,22 @@ SMESH_GroupOnFilter_i::~SMESH_GroupOnFilter_i() { 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 } diff --git a/src/SMESH_I/SMESH_Group_i.hxx b/src/SMESH_I/SMESH_Group_i.hxx index 90ea264a4..867ae56eb 100644 --- a/src/SMESH_I/SMESH_Group_i.hxx +++ b/src/SMESH_I/SMESH_Group_i.hxx @@ -48,7 +48,8 @@ class SMESH_PreMeshInfo; // =========== 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, @@ -100,6 +101,13 @@ class SMESH_I_EXPORT SMESH_GroupBase_i: */ 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; } @@ -173,8 +181,7 @@ class SMESH_I_EXPORT SMESH_GroupOnGeom_i: 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, @@ -189,13 +196,13 @@ class SMESH_I_EXPORT SMESH_GroupOnFilter_i: 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; diff --git a/src/SMESH_I/SMESH_Mesh_i.cxx b/src/SMESH_I/SMESH_Mesh_i.cxx index 7649c27de..ffc80579d 100644 --- a/src/SMESH_I/SMESH_Mesh_i.cxx +++ b/src/SMESH_I/SMESH_Mesh_i.cxx @@ -1057,6 +1057,7 @@ void SMESH_Mesh_i::RemoveGroup( SMESH::SMESH_GroupBase_ptr theGroup ) builder->RemoveObjectWithChildren( aGroupSO ); } } + aGroup->Modified(/*removed=*/true); // notify dependent Filter with FT_BelongToMeshGroup criterion // Remove the group from SMESH data structures removeGroup( aGroup->GetLocalID() ); diff --git a/src/SMESH_SWIG/smeshBuilder.py b/src/SMESH_SWIG/smeshBuilder.py index 74dddbd46..b85912b6b 100644 --- a/src/SMESH_SWIG/smeshBuilder.py +++ b/src/SMESH_SWIG/smeshBuilder.py @@ -732,7 +732,7 @@ class smeshBuilder(object, SMESH._objref_SMESH_Gen): 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() @@ -745,21 +745,28 @@ class smeshBuilder(object, SMESH._objref_SMESH_Gen): 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): @@ -768,10 +775,10 @@ class smeshBuilder(object, SMESH._objref_SMESH_Gen): 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: @@ -791,11 +798,11 @@ class smeshBuilder(object, SMESH._objref_SMESH_Gen): 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 ) @@ -803,12 +810,11 @@ class smeshBuilder(object, SMESH._objref_SMESH_Gen): 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 ) @@ -816,18 +822,16 @@ class smeshBuilder(object, SMESH._objref_SMESH_Gen): 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, @@ -845,7 +849,7 @@ class smeshBuilder(object, SMESH._objref_SMESH_Gen): 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: