From 5c5e1f2368ca2b3388f657ae028b2a6b5ce8ae36 Mon Sep 17 00:00:00 2001 From: eap Date: Thu, 11 Aug 2016 16:44:16 +0300 Subject: [PATCH] 23303: [EDF 12024] Filter for nodes connectivity --- doc/salome/examples/CMakeLists.txt | 1 + doc/salome/examples/filters_node_nb_conn.py | 9 + doc/salome/gui/SMESH/images/ctrlinfo.png | Bin 31374 -> 43536 bytes doc/salome/gui/SMESH/input/mesh_infos.doc | 8 +- .../SMESH/input/selection_filter_library.doc | 4 + doc/salome/gui/SMESH/input/tui_filters.doc | 10 + idl/SMESH_Filter.idl | 3 + src/Controls/SMESH_Controls.cxx | 36 +++ src/Controls/SMESH_ControlsDef.hxx | 11 + src/OBJECT/SMESH_Actor.cxx | 251 +++++++++++------- src/OBJECT/SMESH_Actor.h | 2 +- src/SMESHGUI/SMESHGUI.cxx | 14 +- src/SMESHGUI/SMESHGUI_FilterDlg.cxx | 2 + src/SMESHGUI/SMESHGUI_MeshInfo.cxx | 164 +++++++----- src/SMESHGUI/SMESHGUI_MeshInfo.h | 3 +- src/SMESHGUI/SMESHGUI_Operations.h | 1 + src/SMESHGUI/SMESH_msg_en.ts | 24 ++ src/SMESH_I/SMESH_2smeshpy.cxx | 10 +- src/SMESH_I/SMESH_DumpPython.cxx | 5 +- src/SMESH_I/SMESH_Filter_i.cxx | 27 ++ src/SMESH_I/SMESH_Filter_i.hxx | 13 + src/SMESH_SWIG/smeshBuilder.py | 4 + 22 files changed, 427 insertions(+), 175 deletions(-) create mode 100644 doc/salome/examples/filters_node_nb_conn.py diff --git a/doc/salome/examples/CMakeLists.txt b/doc/salome/examples/CMakeLists.txt index 3bafa17c6..4e35dc496 100644 --- a/doc/salome/examples/CMakeLists.txt +++ b/doc/salome/examples/CMakeLists.txt @@ -98,6 +98,7 @@ SET(GOOD_TESTS filters_ex37.py filters_ex38.py filters_ex39.py + filters_node_nb_conn.py filters_belong2group.py grouping_elements_ex01.py grouping_elements_ex02.py diff --git a/doc/salome/examples/filters_node_nb_conn.py b/doc/salome/examples/filters_node_nb_conn.py new file mode 100644 index 000000000..c7f73f13d --- /dev/null +++ b/doc/salome/examples/filters_node_nb_conn.py @@ -0,0 +1,9 @@ +# Number of connectivities of a node + +# create a mesh +from SMESH_mechanic import * + +# get nodes connected to more than 6 tetrahedra +conn_nb_filter = smesh.GetFilter(SMESH.NODE, SMESH.FT_NodeConnectivityNumber,'>', 6 ) +ids = mesh.GetIdsFromFilter( conn_nb_filter ) +print "Number of nodes connected to more than 6 tetrahedra:", len(ids) diff --git a/doc/salome/gui/SMESH/images/ctrlinfo.png b/doc/salome/gui/SMESH/images/ctrlinfo.png index 9cdad0ac8aaf0a203136918f36f2452cbe2f773b..497adcd95ef8fcfbe252c18659c598f9dbfa0130 100644 GIT binary patch literal 43536 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 Information, select your mesh, sub-mesh or group in the Object Browser and invoke Mesh Information -item from the \b Mesh menu or click "Mesh Information" button +item from the \b Mesh menu or from the context menu, or click "Mesh Information" button in the toolbar.
\image html image49.png @@ -60,7 +60,7 @@ information about the selected mesh node(s) or element(s), namely: - Gravity center (X, Y, Z coordinates); - Connectivity information (connected nodes); double click in a line of a node reveals the information about this node; - - Quality controls (area, aspect ration, volume, etc.); + - Quality controls (area, aspect ratio, volume, etc.); - Position on a shape (for meshes built on a geometry); - Groups information (names of groups the element belongs to). @@ -132,6 +132,7 @@ The Quality Info tab provides overall information about mesh quality cont - Name; - Nodes information: - Number of free nodes; + - Maximal number of elements connected to a node; - Number of double nodes; - Edges information: - Number of double edges; @@ -161,9 +162,6 @@ via the "Mesh information" preferences (zero value means that there is no limit) The button \b "Dump" allows printing the information displayed in the dialog box to a .txt file. -In case you get Mesh Information via a TUI script, the information is -displayed in the Python Console. - See the \ref tui_viewing_mesh_infos "TUI Example". */ diff --git a/doc/salome/gui/SMESH/input/selection_filter_library.doc b/doc/salome/gui/SMESH/input/selection_filter_library.doc index 145c48fec..03438c490 100644 --- a/doc/salome/gui/SMESH/input/selection_filter_library.doc +++ b/doc/salome/gui/SMESH/input/selection_filter_library.doc @@ -144,6 +144,10 @@ The following criteria allow selecting mesh Nodes: Double nodes selects a node coincident with other nodes (within a given Tolerance). See also \ref tui_double_nodes_control "Double Nodes quality control". +
  • +Connectivity number selects nodes with a number of connected +elements, which is more, less or equal to the predefined Threshold + Value. Elements of the highest dimension are countered only.
  • diff --git a/doc/salome/gui/SMESH/input/tui_filters.doc b/doc/salome/gui/SMESH/input/tui_filters.doc index 5a958d9a2..3c115293e 100755 --- a/doc/salome/gui/SMESH/input/tui_filters.doc +++ b/doc/salome/gui/SMESH/input/tui_filters.doc @@ -209,6 +209,16 @@ filters mesh nodes which are coincident with other nodes (within a given toleran \tui_script{filters_ex17.py} +\section filter_node_nb_conn Node connectivity number + +filters nodes according to a number of elements of highest dimension connected to a node: +- element type should be \a SMESH.NODE +- functor type should be \a SMESH.FT_NodeConnectivityNumber +- threshold is an integer value (number of elements) + +\tui_script{filters_node_nb_conn.py} + + \section filter_borders_multiconnection Borders at multi-connection filters 1D mesh elements (segments) according to the specified number of diff --git a/idl/SMESH_Filter.idl b/idl/SMESH_Filter.idl index 7625bba24..f5c564522 100644 --- a/idl/SMESH_Filter.idl +++ b/idl/SMESH_Filter.idl @@ -61,6 +61,7 @@ module SMESH FT_MultiConnection2D, FT_Length, FT_Length2D, + FT_NodeConnectivityNumber, FT_BelongToMeshGroup, FT_BelongToGeom, FT_BelongToPlane, @@ -162,6 +163,7 @@ module SMESH Values GetValues(); }; interface BallDiameter : NumericalFunctor{}; + interface NodeConnectivityNumber : NumericalFunctor{}; /*! @@ -586,6 +588,7 @@ module SMESH MultiConnection CreateMultiConnection(); MultiConnection2D CreateMultiConnection2D(); BallDiameter CreateBallDiameter(); + NodeConnectivityNumber CreateNodeConnectivityNumber(); /*! * Create logical functors ( predicates ) */ diff --git a/src/Controls/SMESH_Controls.cxx b/src/Controls/SMESH_Controls.cxx index 9a8589d92..bf8c097c0 100644 --- a/src/Controls/SMESH_Controls.cxx +++ b/src/Controls/SMESH_Controls.cxx @@ -2116,6 +2116,42 @@ SMDSAbs_ElementType BallDiameter::GetType() const return SMDSAbs_Ball; } +//================================================================================ +/* + Class : NodeConnectivityNumber + Description : Functor returning number of elements connected to a node +*/ +//================================================================================ + +double NodeConnectivityNumber::GetValue( long theId ) +{ + double nb = 0; + + if ( const SMDS_MeshNode* node = myMesh->FindNode( theId )) + { + SMDSAbs_ElementType type; + if ( myMesh->NbVolumes() > 0 ) + type = SMDSAbs_Volume; + else if ( myMesh->NbFaces() > 0 ) + type = SMDSAbs_Face; + else if ( myMesh->NbEdges() > 0 ) + type = SMDSAbs_Edge; + else + return 0; + nb = node->NbInverseElements( type ); + } + return nb; +} + +double NodeConnectivityNumber::GetBadRate( double Value, int /*nbNodes*/ ) const +{ + return Value; +} + +SMDSAbs_ElementType NodeConnectivityNumber::GetType() const +{ + return SMDSAbs_Node; +} /* PREDICATES diff --git a/src/Controls/SMESH_ControlsDef.hxx b/src/Controls/SMESH_ControlsDef.hxx index 97b135048..830d43b81 100644 --- a/src/Controls/SMESH_ControlsDef.hxx +++ b/src/Controls/SMESH_ControlsDef.hxx @@ -351,6 +351,17 @@ namespace SMESH{ virtual SMDSAbs_ElementType GetType() const; }; + /* + Class : NodeConnectivityNumber + Description : Functor returning number of elements connected to a node + */ + class SMESHCONTROLS_EXPORT NodeConnectivityNumber: public virtual NumericalFunctor{ + public: + virtual double GetValue( long theNodeId ); + virtual double GetBadRate( double Value, int nbNodes ) const; + virtual SMDSAbs_ElementType GetType() const; + }; + /* PREDICATES diff --git a/src/OBJECT/SMESH_Actor.cxx b/src/OBJECT/SMESH_Actor.cxx index 4006b506d..34c956b5c 100644 --- a/src/OBJECT/SMESH_Actor.cxx +++ b/src/OBJECT/SMESH_Actor.cxx @@ -694,7 +694,8 @@ void SMESH_ActorDef::SetCellsFontProperties( SMESH::LabelFont theFamily, int the } } -bool SMESH_ActorDef::GetPointsLabeled() { +bool SMESH_ActorDef::GetPointsLabeled() +{ return myNodeActor && myNodeActor->GetPointsLabeled(); } @@ -719,7 +720,8 @@ void SMESH_ActorDef::SetCellsLabeled(bool theIsCellsLabeled) } -bool SMESH_ActorDef::GetCellsLabeled() { +bool SMESH_ActorDef::GetCellsLabeled() +{ bool result = false; if(my3DActor) result = result || my3DActor->GetCellsLabeled(); @@ -789,17 +791,13 @@ bool SMESH_ActorDef::GetFacesOrientation3DVectors() } -void -SMESH_ActorDef:: -SetControlMode(eControl theMode) +void SMESH_ActorDef::SetControlMode(eControl theMode) { SetControlMode(theMode,true); } -void -SMESH_ActorDef:: -SetControlMode( eControl theMode, bool theCheckEntityMode ) +void SMESH_ActorDef::SetControlMode( eControl theMode, bool theCheckEntityMode ) { vtkLookupTable* lookupTable = static_cast(myScalarBarActor->GetLookupTable()); bool isLogarithmic = lookupTable->GetScale() == VTK_SCALE_LOG10; @@ -982,6 +980,12 @@ SetControlMode( eControl theMode, bool theCheckEntityMode ) myControlActor = my2DActor; break; } + case eNodeConnectivityNb: + { + myFunctor.reset( new SMESH::Controls::NodeConnectivityNumber() ); + myControlActor = myNodeActor; + break; + } default: return; } @@ -989,7 +993,7 @@ SetControlMode( eControl theMode, bool theCheckEntityMode ) vtkUnstructuredGrid* aGrid = myControlActor->GetUnstructuredGrid(); vtkIdType aNbCells = aGrid->GetNumberOfCells(); bool aShowOnlyScalarBarTitle = false; - if(aNbCells){ + if(aNbCells) { myControlMode = theMode; switch(myControlMode){ case eFreeNodes: @@ -1029,6 +1033,15 @@ SetControlMode( eControl theMode, bool theCheckEntityMode ) } if(theCheckEntityMode) { + // if(myControlActor == myNodeActor) { + // if ( myControlMode == eNodeConnectivityNb ) { + // if (!myIsEntityModeCache){ + // myEntityModeCache = GetEntityMode(); + // myIsEntityModeCache=true; + // } + // SetEntityMode(0); + // } + // } if(myControlActor == my1DActor) { if (!myIsEntityModeCache){ myEntityModeCache = GetEntityMode(); @@ -1090,9 +1103,8 @@ SetControlMode( eControl theMode, bool theCheckEntityMode ) Update(); } -int -SMESH_ActorDef:: -GetNumberControlEntities(){ +int SMESH_ActorDef::GetNumberControlEntities() +{ SMESH_DeviceActor* anAct = NULL; switch(myControlMode){ case eFreeNodes: @@ -1115,12 +1127,13 @@ GetNumberControlEntities(){ case eCoincidentElems3D: anAct = my3DExtActor; break; + default:; } return (anAct) ? anAct->GetUnstructuredGrid()->GetNumberOfCells() : -1; } -void SMESH_ActorDef::AddToRender(vtkRenderer* theRenderer){ - +void SMESH_ActorDef::AddToRender(vtkRenderer* theRenderer) +{ theRenderer->AddActor(myBaseActor); theRenderer->AddActor(myNodeExtActor); theRenderer->AddActor(my1DExtActor); @@ -1143,7 +1156,8 @@ void SMESH_ActorDef::AddToRender(vtkRenderer* theRenderer){ SALOME_Actor::AddToRender(theRenderer); } -void SMESH_ActorDef::RemoveFromRender(vtkRenderer* theRenderer){ +void SMESH_ActorDef::RemoveFromRender(vtkRenderer* theRenderer) +{ SALOME_Actor::RemoveFromRender(theRenderer); theRenderer->RemoveActor(myBaseActor); @@ -1170,9 +1184,9 @@ void SMESH_ActorDef::RemoveFromRender(vtkRenderer* theRenderer){ bool SMESH_ActorDef::Init(TVisualObjPtr theVisualObj, - const char* theEntry, - const char* theName, - int theIsClear) + const char* theEntry, + const char* theName, + int theIsClear) { Handle(SALOME_InteractiveObject) anIO = new SALOME_InteractiveObject(theEntry,"SMESH",theName); setIO(anIO); @@ -1258,17 +1272,20 @@ bool SMESH_ActorDef::Init(TVisualObjPtr theVisualObj, } -double* SMESH_ActorDef::GetBounds(){ +double* SMESH_ActorDef::GetBounds() +{ return myNodeActor->GetBounds(); } -vtkDataSet* SMESH_ActorDef::GetInput(){ +vtkDataSet* SMESH_ActorDef::GetInput() +{ return GetUnstructuredGrid(); } -void SMESH_ActorDef::SetTransform(VTKViewer_Transform* theTransform){ +void SMESH_ActorDef::SetTransform(VTKViewer_Transform* theTransform) +{ Superclass::SetTransform(theTransform); myNodeActor->SetTransform(theTransform); @@ -1294,27 +1311,32 @@ void SMESH_ActorDef::SetTransform(VTKViewer_Transform* theTransform){ } -void SMESH_ActorDef::SetMapper(vtkMapper* theMapper){ +void SMESH_ActorDef::SetMapper(vtkMapper* theMapper) +{ vtkLODActor::SetMapper(theMapper); } -void SMESH_ActorDef::ShallowCopy(vtkProp *prop){ +void SMESH_ActorDef::ShallowCopy(vtkProp *prop) +{ SALOME_Actor::ShallowCopy(prop); } -vtkMapper* SMESH_ActorDef::GetMapper(){ +vtkMapper* SMESH_ActorDef::GetMapper() +{ return myPickableActor->GetMapper(); } -vtkUnstructuredGrid* SMESH_ActorDef::GetUnstructuredGrid(){ +vtkUnstructuredGrid* SMESH_ActorDef::GetUnstructuredGrid() +{ return myVisualObj->GetUnstructuredGrid(); } -bool SMESH_ActorDef::IsInfinitive(){ +bool SMESH_ActorDef::IsInfinitive() +{ vtkDataSet *aDataSet = myPickableActor->GetUnstructuredGrid(); myIsInfinite = aDataSet->GetNumberOfCells() == 0 || ( aDataSet->GetNumberOfCells() == 1 && @@ -1323,18 +1345,21 @@ bool SMESH_ActorDef::IsInfinitive(){ } -void SMESH_ActorDef::SetIsShrunkable(bool theShrunkable){ +void SMESH_ActorDef::SetIsShrunkable(bool theShrunkable) +{ if ( myIsShrinkable == theShrunkable ) return; myIsShrinkable = theShrunkable; Modified(); } -double SMESH_ActorDef::GetShrinkFactor(){ +double SMESH_ActorDef::GetShrinkFactor() +{ return myBaseActor->GetShrinkFactor(); } -void SMESH_ActorDef::SetShrinkFactor(double theValue){ +void SMESH_ActorDef::SetShrinkFactor(double theValue) +{ myBaseActor->SetShrinkFactor(theValue); my1DActor->SetShrinkFactor(theValue); @@ -1350,7 +1375,8 @@ void SMESH_ActorDef::SetShrinkFactor(double theValue){ Modified(); } -void SMESH_ActorDef::SetShrink() { +void SMESH_ActorDef::SetShrink() +{ if(!myIsShrinkable) return; myBaseActor->SetShrink(); @@ -1368,7 +1394,8 @@ void SMESH_ActorDef::SetShrink() { Modified(); } -void SMESH_ActorDef::UnShrink(){ +void SMESH_ActorDef::UnShrink() +{ if(!myIsShrunk) return; myBaseActor->UnShrink(); @@ -1387,30 +1414,36 @@ void SMESH_ActorDef::UnShrink(){ } -int SMESH_ActorDef::GetNodeObjId(int theVtkID){ +int SMESH_ActorDef::GetNodeObjId(int theVtkID) +{ return myPickableActor->GetNodeObjId(theVtkID); } -double* SMESH_ActorDef::GetNodeCoord(int theObjID){ +double* SMESH_ActorDef::GetNodeCoord(int theObjID) +{ return myPickableActor->GetNodeCoord(theObjID); } -int SMESH_ActorDef::GetElemObjId(int theVtkID){ +int SMESH_ActorDef::GetElemObjId(int theVtkID) +{ return myPickableActor->GetElemObjId(theVtkID); } -vtkCell* SMESH_ActorDef::GetElemCell(int theObjID){ +vtkCell* SMESH_ActorDef::GetElemCell(int theObjID) +{ return myPickableActor->GetElemCell(theObjID); } -void SMESH_ActorDef::SetVisibility(int theMode){ +void SMESH_ActorDef::SetVisibility(int theMode) +{ SetVisibility(theMode,true); } -void SMESH_ActorDef::SetVisibility(int theMode, bool theIsUpdateRepersentation){ +void SMESH_ActorDef::SetVisibility(int theMode, bool theIsUpdateRepersentation) +{ SALOME_Actor::SetVisibility(theMode); myNodeActor->VisibilityOff(); @@ -1436,8 +1469,8 @@ void SMESH_ActorDef::SetVisibility(int theMode, bool theIsUpdateRepersentation){ if(theIsUpdateRepersentation) SetRepresentation(GetRepresentation()); - if(myControlMode != eNone){ - switch(myControlMode){ + if(myControlMode != eNone) { + switch(myControlMode) { case eFreeNodes: case eCoincidentNodes: myNodeExtActor->VisibilityOn(); @@ -1462,6 +1495,7 @@ void SMESH_ActorDef::SetVisibility(int theMode, bool theIsUpdateRepersentation){ case eMultiConnection2D: my1DExtActor->VisibilityOn(); break; + default:; } if(myControlActor->GetUnstructuredGrid()->GetNumberOfCells()) myScalarBarActor->VisibilityOn(); @@ -1777,19 +1811,22 @@ void SMESH_ActorDef::SetRepresentation (int theMode) } -void SMESH_ActorDef::SetPointRepresentation(bool theIsPointsVisible){ +void SMESH_ActorDef::SetPointRepresentation(bool theIsPointsVisible) +{ if ( myIsPointsVisible == theIsPointsVisible ) return; myIsPointsVisible = theIsPointsVisible; SetRepresentation(GetRepresentation()); } -bool SMESH_ActorDef::GetPointRepresentation(){ +bool SMESH_ActorDef::GetPointRepresentation() +{ return myIsPointsVisible || myNodeActor->GetPointsLabeled(); } -void SMESH_ActorDef::UpdateHighlight(){ +void SMESH_ActorDef::UpdateHighlight() +{ myHighlitableActor->SetHighlited(false); myHighlitableActor->SetVisibility(false); bool anIsVisible = GetVisibility(); @@ -1832,7 +1869,8 @@ void SMESH_ActorDef::UpdateHighlight(){ } -void SMESH_ActorDef::highlight(bool theHighlight){ +void SMESH_ActorDef::highlight(bool theHighlight) +{ if ( myIsHighlighted == theHighlight ) return; myIsHighlighted = theHighlight; @@ -1840,7 +1878,8 @@ void SMESH_ActorDef::highlight(bool theHighlight){ } -void SMESH_ActorDef::SetPreSelected(bool thePreselect){ +void SMESH_ActorDef::SetPreSelected(bool thePreselect) +{ if ( myIsPreselected == thePreselect ) return; myIsPreselected = thePreselect; @@ -1873,7 +1912,8 @@ int SMESH_ActorDef::RenderTranslucentGeometry(vtkViewport *vp) } -void SMESH_ActorDef::Render(vtkRenderer *ren){ +void SMESH_ActorDef::Render(vtkRenderer *ren) +{ unsigned long aTime = myTimeStamp->GetMTime(); unsigned long anObjTime = myVisualObj->GetUnstructuredGrid()->GetMTime(); unsigned long aClippingTime = myImplicitBoolean->GetMTime(); @@ -1882,7 +1922,8 @@ void SMESH_ActorDef::Render(vtkRenderer *ren){ } -void SMESH_ActorDef::Update(){ +void SMESH_ActorDef::Update() +{ if(MYDEBUG) MESSAGE("SMESH_ActorDef::Update"); if(GetControlMode() != eNone) { @@ -1926,14 +1967,16 @@ void SMESH_ActorDef::Update(){ } -void SMESH_ActorDef::ReleaseGraphicsResources(vtkWindow *renWin){ +void SMESH_ActorDef::ReleaseGraphicsResources(vtkWindow *renWin) +{ SALOME_Actor::ReleaseGraphicsResources(renWin); myPickableActor->ReleaseGraphicsResources(renWin); } -static void GetColor(vtkProperty *theProperty, double& r,double& g,double& b){ +static void GetColor(vtkProperty *theProperty, double& r,double& g,double& b) +{ double* aColor = theProperty->GetColor(); r = aColor[0]; g = aColor[1]; @@ -1941,7 +1984,8 @@ static void GetColor(vtkProperty *theProperty, double& r,double& g,double& b){ } -void SMESH_ActorDef::SetOpacity(double theValue){ +void SMESH_ActorDef::SetOpacity(double theValue) +{ mySurfaceProp->SetOpacity(theValue); myBackSurfaceProp->SetOpacity(theValue); myNormalVProp->SetOpacity(theValue); @@ -1956,12 +2000,14 @@ void SMESH_ActorDef::SetOpacity(double theValue){ } -double SMESH_ActorDef::GetOpacity(){ +double SMESH_ActorDef::GetOpacity() +{ return mySurfaceProp->GetOpacity(); } -void SMESH_ActorDef::SetSufaceColor(double r,double g,double b, int delta){ +void SMESH_ActorDef::SetSufaceColor(double r,double g,double b, int delta) +{ mySurfaceProp->SetColor(r,g,b); my2DExtProp->SetColor(1.0-r,1.0-g,1.0-b); if( SMESH_GroupObj* aGroupObj = dynamic_cast( myVisualObj.get() ) ) @@ -1974,12 +2020,14 @@ void SMESH_ActorDef::SetSufaceColor(double r,double g,double b, int delta){ Modified(); } -void SMESH_ActorDef::GetSufaceColor(double& r,double& g,double& b, int& delta){ +void SMESH_ActorDef::GetSufaceColor(double& r,double& g,double& b, int& delta) +{ ::GetColor(mySurfaceProp,r,g,b); delta = myDeltaBrightness; } -void SMESH_ActorDef::SetVolumeColor(double r,double g,double b, int delta){ +void SMESH_ActorDef::SetVolumeColor(double r,double g,double b, int delta) +{ myNormalVProp->SetColor(r,g,b); my3DExtProp->SetColor(1.0-r,1.0-g,1.0-b); if( SMESH_GroupObj* aGroupObj = dynamic_cast( myVisualObj.get() ) ) @@ -1992,12 +2040,14 @@ void SMESH_ActorDef::SetVolumeColor(double r,double g,double b, int delta){ Modified(); } -void SMESH_ActorDef::GetVolumeColor(double& r,double& g,double& b, int& delta){ +void SMESH_ActorDef::GetVolumeColor(double& r,double& g,double& b, int& delta) +{ ::GetColor(myNormalVProp,r,g,b); delta = myDeltaVBrightness; } -void SMESH_ActorDef::SetEdgeColor(double r,double g,double b){ +void SMESH_ActorDef::SetEdgeColor(double r,double g,double b) +{ myEdgeProp->SetColor(r,g,b); my1DProp->SetColor(r,g,b); my1DExtProp->SetColor(1.0-r,1.0-g,1.0-b); @@ -2007,21 +2057,25 @@ void SMESH_ActorDef::SetEdgeColor(double r,double g,double b){ Modified(); } -void SMESH_ActorDef::GetEdgeColor(double& r,double& g,double& b){ +void SMESH_ActorDef::GetEdgeColor(double& r,double& g,double& b) +{ ::GetColor(myEdgeProp,r,g,b); } -void SMESH_ActorDef::SetOutlineColor(double r,double g,double b){ +void SMESH_ActorDef::SetOutlineColor(double r,double g,double b) +{ myOutLineProp->SetColor(r,g,b); Modified(); } -void SMESH_ActorDef::GetOutlineColor(double& r,double& g,double& b){ +void SMESH_ActorDef::GetOutlineColor(double& r,double& g,double& b) +{ ::GetColor(myOutLineProp,r,g,b); } -void SMESH_ActorDef::SetNodeColor(double r,double g,double b){ +void SMESH_ActorDef::SetNodeColor(double r,double g,double b) +{ myNodeProp->SetColor(r,g,b); myNodeExtProp->SetColor(1.0-r,1.0-g,1.0-b); if( SMESH_GroupObj* aGroupObj = dynamic_cast( myVisualObj.get() ) ) @@ -2030,11 +2084,13 @@ void SMESH_ActorDef::SetNodeColor(double r,double g,double b){ Modified(); } -void SMESH_ActorDef::GetNodeColor(double& r,double& g,double& b){ +void SMESH_ActorDef::GetNodeColor(double& r,double& g,double& b) +{ ::GetColor(myNodeProp,r,g,b); } -void SMESH_ActorDef::Set0DColor(double r,double g,double b){ +void SMESH_ActorDef::Set0DColor(double r,double g,double b) +{ my0DProp->SetColor(r,g,b); if( SMESH_GroupObj* aGroupObj = dynamic_cast( myVisualObj.get() ) ) if( aGroupObj->GetElementType() == SMDSAbs_0DElement ) @@ -2042,11 +2098,13 @@ void SMESH_ActorDef::Set0DColor(double r,double g,double b){ Modified(); } -void SMESH_ActorDef::Get0DColor(double& r,double& g,double& b){ +void SMESH_ActorDef::Get0DColor(double& r,double& g,double& b) +{ ::GetColor(my0DProp,r,g,b); } -void SMESH_ActorDef::SetBallColor(double r,double g,double b){ +void SMESH_ActorDef::SetBallColor(double r,double g,double b) +{ myBallProp->SetColor(r,g,b); if( SMESH_GroupObj* aGroupObj = dynamic_cast( myVisualObj.get() ) ) if( aGroupObj->GetElementType() == SMDSAbs_Ball ) @@ -2054,35 +2112,42 @@ void SMESH_ActorDef::SetBallColor(double r,double g,double b){ Modified(); } -void SMESH_ActorDef::GetBallColor(double& r,double& g,double& b){ +void SMESH_ActorDef::GetBallColor(double& r,double& g,double& b) +{ ::GetColor(myBallProp,r,g,b); } -void SMESH_ActorDef::SetHighlightColor(double r,double g,double b){ +void SMESH_ActorDef::SetHighlightColor(double r,double g,double b) +{ myHighlightProp->SetColor(r,g,b); Modified(); } -void SMESH_ActorDef::GetHighlightColor(double& r,double& g,double& b){ +void SMESH_ActorDef::GetHighlightColor(double& r,double& g,double& b) +{ ::GetColor(myHighlightProp,r,g,b); } -void SMESH_ActorDef::SetPreHighlightColor(double r,double g,double b){ +void SMESH_ActorDef::SetPreHighlightColor(double r,double g,double b) +{ myPreselectProp->SetColor(r,g,b); Modified(); } -void SMESH_ActorDef::GetPreHighlightColor(double& r,double& g,double& b){ +void SMESH_ActorDef::GetPreHighlightColor(double& r,double& g,double& b) +{ ::GetColor(myPreselectProp,r,g,b); } -double SMESH_ActorDef::GetLineWidth(){ +double SMESH_ActorDef::GetLineWidth() +{ return myEdgeProp->GetLineWidth(); } -void SMESH_ActorDef::SetLineWidth(double theVal){ +void SMESH_ActorDef::SetLineWidth(double theVal) +{ myEdgeProp->SetLineWidth(theVal); my1DProp->SetLineWidth(theVal + aLineWidthInc); @@ -2106,7 +2171,8 @@ void SMESH_ActorDef::SetOutlineWidth(double theVal) Modified(); } -void SMESH_ActorDef::Set0DSize(double theVal){ +void SMESH_ActorDef::Set0DSize(double theVal) +{ my0DProp->SetPointSize(theVal); myHighlightProp->SetPointSize(theVal); myPreselectProp->SetPointSize(theVal); @@ -2121,11 +2187,13 @@ void SMESH_ActorDef::Set0DSize(double theVal){ Modified(); } -double SMESH_ActorDef::Get0DSize(){ +double SMESH_ActorDef::Get0DSize() +{ return my0DProp->GetPointSize(); } -void SMESH_ActorDef::SetBallSize(double theVal){ +void SMESH_ActorDef::SetBallSize(double theVal) +{ myBallProp->SetPointSize(theVal); if(SMESH_SVTKActor* aCustom = SMESH_SVTKActor::SafeDownCast( myHighlightActor )) { @@ -2138,7 +2206,8 @@ void SMESH_ActorDef::SetBallSize(double theVal){ Modified(); } -double SMESH_ActorDef::GetBallSize(){ +double SMESH_ActorDef::GetBallSize() +{ return myBallProp->GetPointSize(); } @@ -2165,15 +2234,12 @@ int SMESH_ActorDef::GetObjDimension( const int theObjId ) return myVisualObj->GetElemDimension( theObjId ); } -bool -SMESH_ActorDef:: -IsImplicitFunctionUsed() const +bool SMESH_ActorDef::IsImplicitFunctionUsed() const { return myBaseActor->IsImplicitFunctionUsed(); } -void -SMESH_ActorDef::SetImplicitFunctionUsed(bool theIsImplicitFunctionUsed) +void SMESH_ActorDef::SetImplicitFunctionUsed(bool theIsImplicitFunctionUsed) { myNodeActor->SetImplicitFunctionUsed(theIsImplicitFunctionUsed); myBaseActor->SetImplicitFunctionUsed(theIsImplicitFunctionUsed); @@ -2195,8 +2261,7 @@ SMESH_ActorDef::SetImplicitFunctionUsed(bool theIsImplicitFunctionUsed) my3DExtActor->SetImplicitFunctionUsed(theIsImplicitFunctionUsed); } -vtkIdType -SMESH_ActorDef::AddClippingPlane(vtkPlane* thePlane) +vtkIdType SMESH_ActorDef::AddClippingPlane(vtkPlane* thePlane) { if(thePlane){ myImplicitBoolean->GetFunction()->AddItem(thePlane); @@ -2208,15 +2273,13 @@ SMESH_ActorDef::AddClippingPlane(vtkPlane* thePlane) return myCippingPlaneCont.size(); } -void -SMESH_ActorDef::AddOpenGLClippingPlane(vtkPlane* thePlane) +void SMESH_ActorDef::AddOpenGLClippingPlane(vtkPlane* thePlane) { if(thePlane) myPlaneCollection->AddItem( thePlane ); } -void -SMESH_ActorDef::SetOpenGLClippingPlane() +void SMESH_ActorDef::SetOpenGLClippingPlane() { // before use this method you must add clipping planes using method // SMESH_ActorDef::AddOpenGLClippingPlane(vtkPlane* thePlane) @@ -2267,9 +2330,7 @@ SMESH_ActorDef::SetOpenGLClippingPlane() Modified(); } -void -SMESH_ActorDef:: -RemoveAllClippingPlanes() +void SMESH_ActorDef::RemoveAllClippingPlanes() { myPlaneCollection->RemoveAllItems(); myImplicitBoolean->GetFunction()->RemoveAllItems(); @@ -2279,16 +2340,12 @@ RemoveAllClippingPlanes() myNodeActor->UpdateLabels(); } -vtkIdType -SMESH_ActorDef:: -GetNumberOfClippingPlanes() +vtkIdType SMESH_ActorDef::GetNumberOfClippingPlanes() { return myCippingPlaneCont.size(); } -vtkPlane* -SMESH_ActorDef:: -GetClippingPlane(vtkIdType theID) +vtkPlane* SMESH_ActorDef::GetClippingPlane(vtkIdType theID) { if ( theID >= (vtkIdType)myCippingPlaneCont.size() ) return NULL; @@ -2437,7 +2494,7 @@ void SMESH_ActorDef::UpdateDistribution() SMESH_VisualObjDef::TEntityList elems; if ( ! dynamic_cast(myVisualObj.get())) dynamic_cast(myVisualObj.get())->GetEntities( fun->GetType(), elems ); - std::vector elemIds; + std::vector elemIds; elemIds.reserve( elems.size() ); for ( SMESH_VisualObjDef::TEntityList::iterator e = elems.begin(); e != elems.end(); ++e) elemIds.push_back( (*e)->GetID()); vtkLookupTable* lookupTable = static_cast(myScalarBarActor->GetLookupTable()); @@ -2493,8 +2550,8 @@ void SMESH_ActorDef::SetMarkerTexture( int theMarkerId, VTK::MarkerTexture theMa } #ifndef DISABLE_PLOT2DVIEWER -SPlot2d_Histogram* SMESH_ActorDef::UpdatePlot2Histogram() { - +SPlot2d_Histogram* SMESH_ActorDef::UpdatePlot2Histogram() +{ if(my2dHistogram) my2dHistogram->clearAllPoints(); diff --git a/src/OBJECT/SMESH_Actor.h b/src/OBJECT/SMESH_Actor.h index abe27bb4e..f49d55cbb 100644 --- a/src/OBJECT/SMESH_Actor.h +++ b/src/OBJECT/SMESH_Actor.h @@ -146,7 +146,7 @@ class SMESHOBJECT_EXPORT SMESH_Actor: public SALOME_Actor eMinimumAngle, eWarping, eSkew, eAspectRatio3D, eMultiConnection2D, eVolume3D, eMaxElementLength2D, eMaxElementLength3D, eBareBorderFace, eBareBorderVolume, eOverConstrainedFace, eOverConstrainedVolume, eCoincidentNodes, - eCoincidentElems1D, eCoincidentElems2D, eCoincidentElems3D }; + eCoincidentElems1D, eCoincidentElems2D, eCoincidentElems3D, eNodeConnectivityNb }; virtual void SetControlMode(eControl theMode) = 0; virtual eControl GetControlMode() = 0; virtual SMESH::Controls::FunctorPtr GetFunctor() = 0; diff --git a/src/SMESHGUI/SMESHGUI.cxx b/src/SMESHGUI/SMESHGUI.cxx index 701fc9127..4c7911769 100644 --- a/src/SMESHGUI/SMESHGUI.cxx +++ b/src/SMESHGUI/SMESHGUI.cxx @@ -1142,6 +1142,8 @@ namespace type = QObject::tr( "EQUAL_FACE" ); else if ( dynamic_cast< SMESH::Controls::CoincidentElements3D* >( f.get() ) ) type = QObject::tr( "EQUAL_VOLUME" ); + else if ( dynamic_cast< SMESH::Controls::NodeConnectivityNumber* >( f.get() ) ) + type = QObject::tr( "NODE_CONNECTIVITY_NB" ); return type; } @@ -1636,6 +1638,7 @@ namespace ActionControl.Bind( 0, SMESH_Actor::eNone ); ActionControl.Bind( SMESHOp::OpFreeNode, SMESH_Actor::eFreeNodes ); ActionControl.Bind( SMESHOp::OpEqualNode, SMESH_Actor::eCoincidentNodes ); + ActionControl.Bind( SMESHOp::OpNodeConnectivityNb, SMESH_Actor::eNodeConnectivityNb ); ActionControl.Bind( SMESHOp::OpFreeEdge, SMESH_Actor::eFreeEdges ); ActionControl.Bind( SMESHOp::OpFreeBorder, SMESH_Actor::eFreeBorders ); ActionControl.Bind( SMESHOp::OpLength, SMESH_Actor::eLength ); @@ -3577,6 +3580,7 @@ bool SMESHGUI::OnGUIEvent( int theCommandID ) // CONTROLS case SMESHOp::OpFreeNode: case SMESHOp::OpEqualNode: + case SMESHOp::OpNodeConnectivityNb: case SMESHOp::OpFreeEdge: case SMESHOp::OpFreeBorder: case SMESHOp::OpLength: @@ -3869,6 +3873,7 @@ void SMESHGUI::initialize( CAM_Application* app ) //update createSMESHAction( SMESHOp::OpFreeNode, "FREE_NODE", "ICON_FREE_NODE", 0, true ); createSMESHAction( SMESHOp::OpEqualNode, "EQUAL_NODE", "ICON_EQUAL_NODE", 0, true ); + createSMESHAction( SMESHOp::OpNodeConnectivityNb, "NODE_CONNECTIVITY_NB", "ICON_NODE_CONN_NB", 0, true ); createSMESHAction( SMESHOp::OpFreeEdge, "FREE_EDGE", "ICON_FREE_EDGE", 0, true ); createSMESHAction( SMESHOp::OpFreeBorder, "FREE_BORDER", "ICON_FREE_EDGE_2D", 0, true ); createSMESHAction( SMESHOp::OpLength, "LENGTH", "ICON_LENGTH", 0, true ); @@ -4002,7 +4007,8 @@ void SMESHGUI::initialize( CAM_Application* app ) createSMESHAction( SMESHOp::OpSortChild, "SORT_CHILD_ITEMS" ); QList aCtrlActions; - aCtrlActions << SMESHOp::OpFreeNode << SMESHOp::OpEqualNode // node controls + aCtrlActions << SMESHOp::OpFreeNode << SMESHOp::OpEqualNode + << SMESHOp::OpNodeConnectivityNb // node controls << SMESHOp::OpFreeEdge << SMESHOp::OpFreeBorder << SMESHOp::OpLength << SMESHOp::OpConnection << SMESHOp::OpEqualEdge // edge controls << SMESHOp::OpFreeFace << SMESHOp::OpLength2D << SMESHOp::OpConnection2D @@ -4099,6 +4105,7 @@ void SMESHGUI::initialize( CAM_Application* app ) createMenu( SMESHOp::OpFreeNode, nodeId, -1 ); createMenu( SMESHOp::OpEqualNode, nodeId, -1 ); + //createMenu( SMESHOp::OpNodeConnectivityNb, nodeId, -1 ); createMenu( SMESHOp::OpFreeBorder, edgeId, -1 ); createMenu( SMESHOp::OpLength, edgeId, -1 ); createMenu( SMESHOp::OpConnection, edgeId, -1 ); @@ -4244,6 +4251,7 @@ void SMESHGUI::initialize( CAM_Application* app ) createTool( SMESHOp::OpFreeNode, ctrl0dTb ); createTool( SMESHOp::OpEqualNode, ctrl0dTb ); + //createTool( SMESHOp::OpNodeConnectivityNb, ctrl0dTb ); createTool( SMESHOp::OpFreeBorder, ctrl1dTb ); createTool( SMESHOp::OpLength, ctrl1dTb ); @@ -4586,6 +4594,10 @@ void SMESHGUI::initialize( CAM_Application* app ) popupMgr()->setRule( action( SMESHOp::OpEqualNode ), aMeshInVtkHasNodes, QtxPopupMgr::VisibleRule ); popupMgr()->setRule( action( SMESHOp::OpEqualNode ), "controlMode = 'eCoincidentNodes'", QtxPopupMgr::ToggleRule); + // popupMgr()->insert( action( SMESHOp::OpNodeConnectivityNb ), aSubId, -1 ); + // popupMgr()->setRule( action( SMESHOp::OpNodeConnectivityNb ), aMeshInVtkHasNodes, QtxPopupMgr::VisibleRule ); + // popupMgr()->setRule( action( SMESHOp::OpNodeConnectivityNb ), "controlMode = 'eNodeConnectivityNb'", QtxPopupMgr::ToggleRule ); + aSubId = popupMgr()->insert( tr( "MEN_EDGE_CTRL" ), anId, -1 ); // EDGE CONTROLS popupMgr()->insert( action( SMESHOp::OpFreeBorder ), aSubId, -1 ); diff --git a/src/SMESHGUI/SMESHGUI_FilterDlg.cxx b/src/SMESHGUI/SMESHGUI_FilterDlg.cxx index b55632f0a..240523d4c 100755 --- a/src/SMESHGUI/SMESHGUI_FilterDlg.cxx +++ b/src/SMESHGUI/SMESHGUI_FilterDlg.cxx @@ -1823,6 +1823,7 @@ void SMESHGUI_FilterTable::onCriterionChanged (const int row, const int col, con case SMESH::FT_EqualFaces: case SMESH::FT_EqualVolumes: break; + case SMESH::FT_NodeConnectivityNumber: case SMESH::FT_MultiConnection: case SMESH::FT_MultiConnection2D: anIsIntCriterion = true; nbCompareSigns = 3; break; @@ -2190,6 +2191,7 @@ const QMap& SMESHGUI_FilterTable::getCriteria (const int theType) aCriteria[ SMESH::FT_GroupColor ] = tr("GROUP_COLOR"); aCriteria[ SMESH::FT_EqualNodes ] = tr("EQUAL_NODE"); aCriteria[ SMESH::FT_ConnectedElements ] = tr("CONNECTED_ELEMS"); + aCriteria[ SMESH::FT_NodeConnectivityNumber ] = tr("NODE_CONN_NUMBER"); } return aCriteria; } diff --git a/src/SMESHGUI/SMESHGUI_MeshInfo.cxx b/src/SMESHGUI/SMESHGUI_MeshInfo.cxx index b0b1a6ed7..4d7f87a98 100644 --- a/src/SMESHGUI/SMESHGUI_MeshInfo.cxx +++ b/src/SMESHGUI/SMESHGUI_MeshInfo.cxx @@ -3225,6 +3225,11 @@ SMESHGUI_CtrlInfo::SMESHGUI_CtrlInfo( QWidget* parent ) myWidgets << aNodesFree; myPredicates << aFilterMgr->CreateFreeNodes(); // + QLabel* aNodesNbConnLab = new QLabel( tr( "MAX_NODE_CONNECTIVITY" ), this ); + QLabel* aNodesNbConn = createField(); + myWidgets << aNodesNbConn; + myNodeConnFunctor = aFilterMgr->CreateNodeConnectivityNumber(); + // QLabel* aNodesDoubleLab = new QLabel( tr( "NUMBER_OF_THE_DOUBLE_NODES" ), this ); QLabel* aNodesDouble = createField(); myWidgets << aNodesDouble; @@ -3274,47 +3279,52 @@ SMESHGUI_CtrlInfo::SMESHGUI_CtrlInfo( QWidget* parent ) aFreeNodesBtn->setIcon(aComputeIcon); myButtons << aFreeNodesBtn; //0 + QToolButton* aNodesNbConnBtn = new QToolButton( this ); + aNodesNbConnBtn->setIcon(aComputeIcon); + myButtons << aNodesNbConnBtn; //1 + QToolButton* aDoubleNodesBtn = new QToolButton( this ); aDoubleNodesBtn->setIcon(aComputeIcon); - myButtons << aDoubleNodesBtn; //1 + myButtons << aDoubleNodesBtn; //2 QToolButton* aDoubleEdgesBtn = new QToolButton( this ); aDoubleEdgesBtn->setIcon(aComputeIcon); - myButtons << aDoubleEdgesBtn; //2 + myButtons << aDoubleEdgesBtn; //3 QToolButton* aDoubleFacesBtn = new QToolButton( this ); aDoubleFacesBtn->setIcon(aComputeIcon); - myButtons << aDoubleFacesBtn; //3 + myButtons << aDoubleFacesBtn; //4 QToolButton* aOverContFacesBtn = new QToolButton( this ); aOverContFacesBtn->setIcon(aComputeIcon); - myButtons << aOverContFacesBtn; //4 + myButtons << aOverContFacesBtn; //5 QToolButton* aComputeFaceBtn = new QToolButton( this ); aComputeFaceBtn->setIcon(aComputeIcon); - myButtons << aComputeFaceBtn; //5 + myButtons << aComputeFaceBtn; //6 QToolButton* aDoubleVolumesBtn = new QToolButton( this ); aDoubleVolumesBtn->setIcon(aComputeIcon); - myButtons << aDoubleVolumesBtn; //6 + myButtons << aDoubleVolumesBtn; //7 QToolButton* aOverContVolumesBtn = new QToolButton( this ); aOverContVolumesBtn->setIcon(aComputeIcon); - myButtons << aOverContVolumesBtn; //7 + myButtons << aOverContVolumesBtn; //8 QToolButton* aComputeVolumeBtn = new QToolButton( this ); aComputeVolumeBtn->setIcon(aComputeIcon); - myButtons << aComputeVolumeBtn; //8 + myButtons << aComputeVolumeBtn; //9 connect( aComputeFaceBtn, SIGNAL( clicked() ), this, SLOT( computeAspectRatio() ) ); connect( aComputeVolumeBtn, SIGNAL( clicked() ), this, SLOT( computeAspectRatio3D() ) ); - connect( aFreeNodesBtn, SIGNAL( clicked() ), this, SLOT( computeFreeNodesInfo() ) ); - connect( aDoubleNodesBtn, SIGNAL( clicked() ), this, SLOT( computeDoubleNodesInfo() ) ); - connect( aDoubleEdgesBtn, SIGNAL( clicked() ), this, SLOT( computeDoubleEdgesInfo() ) ); - connect( aDoubleFacesBtn, SIGNAL( clicked() ), this, SLOT( computeDoubleFacesInfo() ) ); + connect( aFreeNodesBtn, SIGNAL( clicked() ), this, SLOT( computeFreeNodesInfo() ) ); + connect( aNodesNbConnBtn, SIGNAL( clicked() ), this, SLOT( computeNodesNbConnInfo() ) ); + connect( aDoubleNodesBtn, SIGNAL( clicked() ), this, SLOT( computeDoubleNodesInfo() ) ); + connect( aDoubleEdgesBtn, SIGNAL( clicked() ), this, SLOT( computeDoubleEdgesInfo() ) ); + connect( aDoubleFacesBtn, SIGNAL( clicked() ), this, SLOT( computeDoubleFacesInfo() ) ); connect( aOverContFacesBtn, SIGNAL( clicked() ), this, SLOT( computeOverConstrainedFacesInfo() ) ); connect( aDoubleVolumesBtn, SIGNAL( clicked() ), this, SLOT( computeDoubleVolumesInfo() ) ); - connect( aOverContVolumesBtn, SIGNAL( clicked() ), this, SLOT( computeOverConstrainedVolumesInfo() ) ); + connect( aOverContVolumesBtn,SIGNAL( clicked() ), this, SLOT( computeOverConstrainedVolumesInfo() ) ); connect( myToleranceWidget, SIGNAL(valueChanged(double)), this, SLOT( setTolerance( double ))); setFontAttributes( aNameLab ); @@ -3329,35 +3339,38 @@ SMESHGUI_CtrlInfo::SMESHGUI_CtrlInfo( QWidget* parent ) myMainLayout->addWidget( aNodesFreeLab, 2, 0 ); //3 myMainLayout->addWidget( aNodesFree, 2, 1 ); //4 myMainLayout->addWidget( aFreeNodesBtn, 2, 2 ); //5 - myMainLayout->addWidget( aNodesDoubleLab, 3, 0 ); //6 - myMainLayout->addWidget( aNodesDouble, 3, 1 ); //7 - myMainLayout->addWidget( aDoubleNodesBtn, 3, 2 ); //8 - myMainLayout->addWidget( aToleranceLab, 4, 0 ); //9 - myMainLayout->addWidget( myToleranceWidget, 4, 1 ); //10 - myMainLayout->addWidget( anEdgesLab, 5, 0, 1, 3 ); //11 - myMainLayout->addWidget( anEdgesDoubleLab, 6, 0 ); //12 - myMainLayout->addWidget( anEdgesDouble, 6, 1 ); //13 - myMainLayout->addWidget( aDoubleEdgesBtn, 6, 2 ); //14 - myMainLayout->addWidget( aFacesLab, 7, 0, 1, 3 ); //15 - myMainLayout->addWidget( aFacesDoubleLab, 8, 0 ); //16 - myMainLayout->addWidget( aFacesDouble, 8, 1 ); //17 - myMainLayout->addWidget( aDoubleFacesBtn, 8, 2 ); //18 - myMainLayout->addWidget( aFacesOverLab, 9, 0 ); //19 - myMainLayout->addWidget( aFacesOver, 9, 1 ); //20 - myMainLayout->addWidget( aOverContFacesBtn, 9, 2 ); //21 - myMainLayout->addWidget( anAspectRatioLab, 10, 0 ); //22 - myMainLayout->addWidget( aComputeFaceBtn, 10, 2 ); //23 - myMainLayout->addWidget( myPlot, 11, 0, 1, 3 );//24 - myMainLayout->addWidget( aVolumesLab, 12, 0, 1, 3 );//25 - myMainLayout->addWidget( aVolumesDoubleLab, 13, 0 ); //26 - myMainLayout->addWidget( aVolumesDouble, 13, 1 ); //27 - myMainLayout->addWidget( aDoubleVolumesBtn, 13, 2 ); //28 - myMainLayout->addWidget( aVolumesOverLab, 14, 0 ); //28 - myMainLayout->addWidget( aVolumesOver, 14, 1 ); //30 - myMainLayout->addWidget( aOverContVolumesBtn,14, 2 ); //31 - myMainLayout->addWidget( anAspectRatio3DLab, 15, 0 ); //32 - myMainLayout->addWidget( aComputeVolumeBtn, 15, 2 ); //33 - myMainLayout->addWidget( myPlot3D, 16, 0, 1, 3 );//34 + myMainLayout->addWidget( aNodesNbConnLab, 3, 0 ); //6 + myMainLayout->addWidget( aNodesNbConn, 3, 1 ); //7 + myMainLayout->addWidget( aNodesNbConnBtn, 3, 2 ); //8 + myMainLayout->addWidget( aNodesDoubleLab, 4, 0 ); //9 + myMainLayout->addWidget( aNodesDouble, 4, 1 ); //10 + myMainLayout->addWidget( aDoubleNodesBtn, 4, 2 ); //11 + myMainLayout->addWidget( aToleranceLab, 5, 0 ); //12 + myMainLayout->addWidget( myToleranceWidget, 5, 1 ); //13 + myMainLayout->addWidget( anEdgesLab, 6, 0, 1, 3 ); //14 + myMainLayout->addWidget( anEdgesDoubleLab, 7, 0 ); //15 + myMainLayout->addWidget( anEdgesDouble, 7, 1 ); //16 + myMainLayout->addWidget( aDoubleEdgesBtn, 7, 2 ); //17 + myMainLayout->addWidget( aFacesLab, 8, 0, 1, 3 ); //18 + myMainLayout->addWidget( aFacesDoubleLab, 9, 0 ); //19 + myMainLayout->addWidget( aFacesDouble, 9, 1 ); //20 + myMainLayout->addWidget( aDoubleFacesBtn, 9, 2 ); //21 + myMainLayout->addWidget( aFacesOverLab, 10, 0 ); //22 + myMainLayout->addWidget( aFacesOver, 10, 1 ); //23 + myMainLayout->addWidget( aOverContFacesBtn, 10, 2 ); //24 + myMainLayout->addWidget( anAspectRatioLab, 11, 0 ); //25 + myMainLayout->addWidget( aComputeFaceBtn, 11, 2 ); //26 + myMainLayout->addWidget( myPlot, 12, 0, 1, 3 );//27 + myMainLayout->addWidget( aVolumesLab, 13, 0, 1, 3 );//28 + myMainLayout->addWidget( aVolumesDoubleLab, 14, 0 ); //29 + myMainLayout->addWidget( aVolumesDouble, 14, 1 ); //30 + myMainLayout->addWidget( aDoubleVolumesBtn, 14, 2 ); //31 + myMainLayout->addWidget( aVolumesOverLab, 15, 0 ); //32 + myMainLayout->addWidget( aVolumesOver, 15, 1 ); //33 + myMainLayout->addWidget( aOverContVolumesBtn,15, 2 ); //34 + myMainLayout->addWidget( anAspectRatio3DLab, 16, 0 ); //35 + myMainLayout->addWidget( aComputeVolumeBtn, 16, 2 ); //36 + myMainLayout->addWidget( myPlot3D, 17, 0, 1, 3 );//37 myMainLayout->setColumnStretch( 0, 0 ); myMainLayout->setColumnStretch( 1, 5 ); @@ -3460,6 +3473,7 @@ void SMESHGUI_CtrlInfo::showInfo( SMESH::SMESH_IDSource_ptr obj ) if ( Max( (int)nbNodes, (int)nbElems ) <= ctrlLimit ) { // free nodes computeFreeNodesInfo(); + computeNodesNbConnInfo(); // double nodes if ( Max( (int)mesh->NbNodes(), (int)mesh->NbElements() ) <= ctrlLimit ) computeDoubleNodesInfo(); @@ -3467,10 +3481,11 @@ void SMESHGUI_CtrlInfo::showInfo( SMESH::SMESH_IDSource_ptr obj ) else { myButtons[0]->setEnabled( true ); myButtons[1]->setEnabled( true ); + myButtons[2]->setEnabled( true ); } } else { - for( int i=2; i<=10; i++) + for( int i=2; i<=11; i++) myMainLayout->itemAt(i)->widget()->setVisible( false ); } @@ -3480,7 +3495,7 @@ void SMESHGUI_CtrlInfo::showInfo( SMESH::SMESH_IDSource_ptr obj ) if( nbElemsByType[ SMESH::EDGE ] <= ctrlLimit ) computeDoubleEdgesInfo(); else - myButtons[2]->setEnabled( true ); + myButtons[3]->setEnabled( true ); } else { for( int i=11; i<=14; i++) @@ -3498,19 +3513,19 @@ void SMESHGUI_CtrlInfo::showInfo( SMESH::SMESH_IDSource_ptr obj ) computeAspectRatio(); } else { - myButtons[3]->setEnabled( true ); myButtons[4]->setEnabled( true ); myButtons[5]->setEnabled( true ); + myButtons[6]->setEnabled( true ); } #ifdef DISABLE_PLOT2DVIEWER - myMainLayout->setRowStretch(11,0); - for( int i=22; i<=24; i++) + myMainLayout->setRowStretch(12,0); + for( int i=25; i<=27; i++) myMainLayout->itemAt(i)->widget()->setVisible( false ); #endif } else { - myMainLayout->setRowStretch(11,0); - for( int i=15; i<=24; i++) + myMainLayout->setRowStretch(12,0); + for( int i=18; i<=27; i++) myMainLayout->itemAt(i)->widget()->setVisible( false ); } @@ -3525,19 +3540,19 @@ void SMESHGUI_CtrlInfo::showInfo( SMESH::SMESH_IDSource_ptr obj ) computeAspectRatio3D(); } else { - myButtons[6]->setEnabled( true ); myButtons[7]->setEnabled( true ); myButtons[8]->setEnabled( true ); + myButtons[9]->setEnabled( true ); } #ifdef DISABLE_PLOT2DVIEWER - myMainLayout->setRowStretch(16,0); - for( int i=32; i<=34; i++) + myMainLayout->setRowStretch(17,0); + for( int i=35; i<=37; i++) myMainLayout->itemAt(i)->widget()->setVisible( false ); #endif } else { - myMainLayout->setRowStretch(16,0); - for( int i=25; i<=34; i++) + myMainLayout->setRowStretch(17,0); + for( int i=28; i<=37; i++) myMainLayout->itemAt(i)->widget()->setVisible( false ); } } @@ -3583,38 +3598,58 @@ void SMESHGUI_CtrlInfo::computeFreeNodesInfo() void SMESHGUI_CtrlInfo::computeDoubleNodesInfo() { - computeNb( SMESH::FT_EqualNodes, 1, 2 ); + computeNb( SMESH::FT_EqualNodes, 2, 3 ); } void SMESHGUI_CtrlInfo::computeDoubleEdgesInfo() { - computeNb( SMESH::FT_EqualEdges, 2, 3 ); + computeNb( SMESH::FT_EqualEdges, 3, 4 ); } void SMESHGUI_CtrlInfo::computeDoubleFacesInfo() { - computeNb( SMESH::FT_EqualFaces, 3, 4 ); + computeNb( SMESH::FT_EqualFaces, 4, 5 ); } void SMESHGUI_CtrlInfo::computeOverConstrainedFacesInfo() { - computeNb( SMESH::FT_OverConstrainedFace, 4, 5 ); + computeNb( SMESH::FT_OverConstrainedFace, 5, 6 ); } void SMESHGUI_CtrlInfo::computeDoubleVolumesInfo() { - computeNb( SMESH::FT_EqualVolumes, 6, 6 ); + computeNb( SMESH::FT_EqualVolumes, 7, 7 ); } void SMESHGUI_CtrlInfo::computeOverConstrainedVolumesInfo() { - computeNb( SMESH::FT_OverConstrainedVolume, 7, 7 ); + computeNb( SMESH::FT_OverConstrainedVolume, 8, 8 ); +} + +void SMESHGUI_CtrlInfo::computeNodesNbConnInfo() +{ + myButtons[ 1 ]->setEnabled( false ); + myWidgets[ 2 ]->setText( "" ); + SMESH::SMESH_Mesh_var mesh = myObject->GetMesh(); + if ( mesh->_is_nil() ) return; + if ( !mesh->IsLoaded() ) + { + mesh->Load(); + this->showInfo( myObject ); // try to show all values + if ( !myWidgets[ 2 ]->text().isEmpty() ) + return; // already computed + } + myNodeConnFunctor->SetMesh( mesh ); + SMESH::Histogram_var histogram = + myNodeConnFunctor->GetLocalHistogram( 1, /*isLogarithmic=*/false, myObject ); + + myWidgets[ 2 ]->setText( QString::number( histogram[0].max )); } void SMESHGUI_CtrlInfo::computeAspectRatio() { #ifndef DISABLE_PLOT2DVIEWER - myButtons[5]->setEnabled( false ); + myButtons[6]->setEnabled( false ); if ( myObject->_is_nil() ) return; @@ -3633,7 +3668,7 @@ void SMESHGUI_CtrlInfo::computeAspectRatio() void SMESHGUI_CtrlInfo::computeAspectRatio3D() { #ifndef DISABLE_PLOT2DVIEWER - myButtons[8]->setEnabled( false ); + myButtons[9]->setEnabled( false ); if ( myObject->_is_nil() ) return; @@ -3654,9 +3689,9 @@ void SMESHGUI_CtrlInfo::computeAspectRatio3D() */ void SMESHGUI_CtrlInfo::clearInternal() { - for( int i=0; i<=34; i++) + for( int i=0; i<=35; i++) myMainLayout->itemAt(i)->widget()->setVisible( true ); - for( int i=0; i<=8; i++) + for( int i=0; i<=9; i++) myButtons[i]->setEnabled( false ); myPlot->detachItems(); myPlot3D->detachItems(); @@ -3734,7 +3769,6 @@ void SMESHGUI_CtrlInfo::saveInfo( QTextStream &out ) { /*! \brief Constructor \param parent parent widget - \param page specifies the dialog page to be shown at the start-up */ SMESHGUI_CtrlInfoDlg::SMESHGUI_CtrlInfoDlg( QWidget* parent ) : QDialog( parent ) diff --git a/src/SMESHGUI/SMESHGUI_MeshInfo.h b/src/SMESHGUI/SMESHGUI_MeshInfo.h index c8f8108f4..dd1af5c02 100644 --- a/src/SMESHGUI/SMESHGUI_MeshInfo.h +++ b/src/SMESHGUI/SMESHGUI_MeshInfo.h @@ -324,6 +324,7 @@ private slots: void computeAspectRatio(); void computeAspectRatio3D(); void computeFreeNodesInfo(); + void computeNodesNbConnInfo(); void computeDoubleNodesInfo(); void computeDoubleEdgesInfo(); void computeDoubleFacesInfo(); @@ -345,7 +346,7 @@ private: QwtPlot* myPlot3D; QList myButtons; QList myPredicates; - TNumFunctor myAspectRatio, myAspectRatio3D; + TNumFunctor myAspectRatio, myAspectRatio3D, myNodeConnFunctor; }; class SMESHGUI_EXPORT SMESHGUI_MeshInfoDlg : public QDialog diff --git a/src/SMESHGUI/SMESHGUI_Operations.h b/src/SMESHGUI/SMESHGUI_Operations.h index 784940e90..df810f7df 100644 --- a/src/SMESHGUI/SMESHGUI_Operations.h +++ b/src/SMESHGUI/SMESHGUI_Operations.h @@ -98,6 +98,7 @@ namespace SMESHOp { // Controls -----------------------//-------------------------------- OpFreeNode = 3000, // MENU CONTROLS - FREE NODES OpEqualNode = 3001, // MENU CONTROLS - DOUBLE NODES + OpNodeConnectivityNb = 3002, // MENU CONTROLS - NODE CONNECTIVITY NUMBER OpFreeEdge = 3100, // MENU CONTROLS - FREE EDGES OpFreeBorder = 3101, // MENU CONTROLS - FREE BORDERS OpLength = 3102, // MENU CONTROLS - LENGTH diff --git a/src/SMESHGUI/SMESH_msg_en.ts b/src/SMESHGUI/SMESH_msg_en.ts index 648dcbc20..55a8f48b0 100644 --- a/src/SMESHGUI/SMESH_msg_en.ts +++ b/src/SMESHGUI/SMESH_msg_en.ts @@ -67,6 +67,10 @@ FREE_NODES Free nodes + + NODE_CONNECTIVITY_NB + Node connectivity number + FREE_EDGES Free edges @@ -624,6 +628,10 @@ MEN_FREE_NODE Free Nodes + + MEN_NODE_CONNECTIVITY_NB + Node connectivity number + MEN_FREE_FACES Free Faces @@ -3190,6 +3198,10 @@ Use Display Entity menu command to show them. STB_FREE_NODE Free Nodes + + STB_NODE_CONNECTIVITY_NB + Node connectivity number + STB_FREE_FACES Free Faces @@ -3862,6 +3874,10 @@ Use Display Entity menu command to show them. TOP_FREE_NODE Free Nodes + + TOP_NODE_CONNECTIVITY_NB + Node connectivity number + TOP_FREE_FACES Free Faces @@ -5664,6 +5680,10 @@ Please check input data and try again CONNECTED_ELEMS Elements of a domain + + NODE_CONN_NUMBER + Connectivity number + NUMBEROFNODESINELEMENT Number Of Nodes In Element @@ -7714,6 +7734,10 @@ as they are of improper type: NUMBER_OF_THE_FREE_NODES Number of the free nodes + + MAX_NODE_CONNECTIVITY + Max. number of connected elements + DOUBLE_NODES_TOLERANCE Double nodes tolerance diff --git a/src/SMESH_I/SMESH_2smeshpy.cxx b/src/SMESH_I/SMESH_2smeshpy.cxx index 416f43b6f..d5dadd0e1 100644 --- a/src/SMESH_I/SMESH_2smeshpy.cxx +++ b/src/SMESH_I/SMESH_2smeshpy.cxx @@ -292,6 +292,8 @@ namespace { // - FT_ConnectedElements = 39 // v 7.6.0: FT_Undefined == 47, new items: // - FT_BelongToMeshGroup = 22 + // v 8.1.0: FT_Undefined == 48, new items: + // - FT_NodeConnectivityNumber= 22 // // It's necessary to continue recording this history and to fill // undef2newItems (see below) accordingly. @@ -313,6 +315,7 @@ namespace { undef2newItems[ 45 ].push_back( 36 ); undef2newItems[ 46 ].push_back( 39 ); undef2newItems[ 47 ].push_back( 22 ); + undef2newItems[ 48 ].push_back( 22 ); ASSERT( undef2newItems.rbegin()->first == SMESH::FT_Undefined ); } @@ -1564,7 +1567,7 @@ void _pyGen::CheckObjectIsReCreated( Handle(_pyObject)& theObj ) const bool isHyp = theObj->IsKind( STANDARD_TYPE( _pyHypothesis )); Handle(_pyObject) existing; if( isHyp ) - existing = Handle(_pyObject)::DownCast( FindHyp( theObj->GetID() ) ); + existing = FindHyp( theObj->GetID() ); else existing = FindObject( theObj->GetID() ); if ( !existing.IsNull() && existing != theObj ) @@ -1622,9 +1625,10 @@ Handle(_pyObject) _pyGen::FindObject( const _pyID& theObjID ) const return id_obj->second; } { - map< _pyID, Handle(_pyMesh) >::const_iterator id_obj = myMeshes.find( theObjID ); + _pyGen* me = const_cast< _pyGen* >( this ); + map< _pyID, Handle(_pyMesh) >::iterator id_obj = me->myMeshes.find( theObjID ); if ( id_obj != myMeshes.end() ) - return Handle(_pyObject)::DownCast( id_obj->second ); + return id_obj->second; } // { // map< _pyID, Handle(_pyMeshEditor) >::const_iterator id_obj = myMeshEditors.find( theObjID ); diff --git a/src/SMESH_I/SMESH_DumpPython.cxx b/src/SMESH_I/SMESH_DumpPython.cxx index 599c51e4e..540144b66 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_NodeConnectivityNumber:myStream<< "aNodeConnectivityNumber";break; case FT_BelongToMeshGroup: myStream<< "aBelongToMeshGroup"; break; case FT_BelongToGeom: myStream<< "aBelongToGeom"; break; case FT_BelongToPlane: myStream<< "aBelongToPlane"; break; @@ -448,8 +449,8 @@ namespace SMESH case FT_LogicalNOT: myStream<< "aLogicalNOT"; break; case FT_LogicalAND: myStream<< "aLogicalAND"; break; case FT_LogicalOR: myStream<< "aLogicalOR"; break; - case FT_Undefined: - default: myStream<< "anUndefined"; break; + case FT_Undefined: myStream<< "anUndefined"; break; + //default: -- commented to have a compilation warning } myStream<_this(); + TPythonDump()<CreateBallDiameter(); break; + case SMESH::FT_NodeConnectivityNumber: + aFunctor = aFilterMgr->CreateNodeConnectivityNumber(); + break; // Predicates @@ -4052,6 +4078,7 @@ static const char** getFunctNames() "FT_MultiConnection2D", "FT_Length", "FT_Length2D", + "FT_NodeConnectivityNumber", "FT_BelongToMeshGroup", "FT_BelongToGeom", "FT_BelongToPlane", diff --git a/src/SMESH_I/SMESH_Filter_i.hxx b/src/SMESH_I/SMESH_Filter_i.hxx index feaca7cb0..b9d290c47 100644 --- a/src/SMESH_I/SMESH_Filter_i.hxx +++ b/src/SMESH_I/SMESH_Filter_i.hxx @@ -311,6 +311,18 @@ namespace SMESH FunctorType GetFunctorType(); }; + /* + Class : NodeConnectivityNumber_i + Description : Functor returning diameter of a ball element + */ + class SMESH_I_EXPORT NodeConnectivityNumber_i: public virtual POA_SMESH::NodeConnectivityNumber, + public virtual NumericalFunctor_i + { + public: + NodeConnectivityNumber_i(); + FunctorType GetFunctorType(); + }; + /* PREDICATES @@ -1075,6 +1087,7 @@ namespace SMESH MaxElementLength3D_ptr CreateMaxElementLength3D(); Length_ptr CreateLength(); Length2D_ptr CreateLength2D(); + NodeConnectivityNumber_ptr CreateNodeConnectivityNumber(); MultiConnection_ptr CreateMultiConnection(); MultiConnection2D_ptr CreateMultiConnection2D(); BallDiameter_ptr CreateBallDiameter(); diff --git a/src/SMESH_SWIG/smeshBuilder.py b/src/SMESH_SWIG/smeshBuilder.py index a37bffc80..e257a4d6b 100644 --- a/src/SMESH_SWIG/smeshBuilder.py +++ b/src/SMESH_SWIG/smeshBuilder.py @@ -964,6 +964,10 @@ class smeshBuilder(object, SMESH._objref_SMESH_Gen): functor = aFilterMgr.CreateLength() elif theCriterion == FT_Length2D: functor = aFilterMgr.CreateLength2D() + elif theCriterion == FT_NodeConnectivityNumber: + functor = aFilterMgr.CreateNodeConnectivityNumber() + elif theCriterion == FT_BallDiameter: + functor = aFilterMgr.CreateBallDiameter() else: print "Error: given parameter is not numerical functor type." aFilterMgr.UnRegister() -- 2.39.2