From: eap Date: Fri, 25 Oct 2019 13:55:08 +0000 (+0300) Subject: #16522 [CEA 7599] Viscous layers hypothesis: extract layers as a group X-Git-Tag: V9_5_0a1~15 X-Git-Url: http://git.salome-platform.org/gitweb/?a=commitdiff_plain;h=70eb9c09d00f9c4b0e48d5aba70676e45e779f9c;p=modules%2Fsmesh.git #16522 [CEA 7599] Viscous layers hypothesis: extract layers as a group --- diff --git a/doc/salome/examples/defining_hypotheses_ex17.py b/doc/salome/examples/defining_hypotheses_ex17.py index f2b7d8c20..cadd71e24 100644 --- a/doc/salome/examples/defining_hypotheses_ex17.py +++ b/doc/salome/examples/defining_hypotheses_ex17.py @@ -33,16 +33,22 @@ mesh.Segment().NumberOfSegments( 4 ) mesh.Triangle() mesh.Quadrangle(face1) -mesh.Compute() algo3D = mesh.Tetrahedron() thickness = 20 numberOfLayers = 10 stretchFactor = 1.5 -layersHyp = algo3D.ViscousLayers(thickness,numberOfLayers,stretchFactor,ignoreFaces) +groupName = "Boundary layers" +layersHyp = algo3D.ViscousLayers(thickness,numberOfLayers,stretchFactor, + ignoreFaces, # optional + groupName = groupName) # optional mesh.Compute() +# retrieve boundary prisms created by mesh.Compute() +boundaryGroup = mesh.GetGroupByName( layersHyp.GetGroupName() )[0] +print( "Nb boundary prisms", boundaryGroup.Size() ) + mesh.MakeGroup("Tetras",SMESH.VOLUME,SMESH.FT_ElemGeomType,"=",SMESH.Geom_TETRA) mesh.MakeGroup("Pyras",SMESH.VOLUME,SMESH.FT_ElemGeomType,"=",SMESH.Geom_PYRAMID) mesh.MakeGroup("Prims",SMESH.VOLUME,SMESH.FT_ElemGeomType,"=",SMESH.Geom_PENTA) @@ -55,12 +61,17 @@ edgeIds = geompy.SubShapeAllIDs( face1, geompy.ShapeType["EDGE"])[:-1] mesh = smesh.Mesh(face1,"VicsousLayers2D") mesh.Segment().NumberOfSegments( 5 ) -# viscous layers should be created on 1 edge, as we set 3 edges to ignore -vlHyp = mesh.Triangle().ViscousLayers2D( 2, 3, 1.5, edgeIds, isEdgesToIgnore=True ) - +# viscous layers will be created on 1 edge, as we set 3 edges to ignore +vlHyp = mesh.Triangle().ViscousLayers2D( 2, 3, 1.5, + edgeIds, isEdgesToIgnore=True, # optional + groupName=groupName) # optional mesh.Compute() -# viscous layers should be created on 3 edges, as we pass isEdgesToIgnore=False +# retrieve boundary elements created by mesh.Compute() +quadrangles = mesh.GetGroupByName( vlHyp.GetGroupName() )[0] +print( "Nb boundary quadrangles", quadrangles.Size() ) + +# viscous layers will be created on 3 edges, as we pass isEdgesToIgnore=False vlHyp.SetEdges( edgeIds, False ) mesh.Compute() diff --git a/doc/salome/gui/SMESH/images/viscous_layers_2d_hyp.png b/doc/salome/gui/SMESH/images/viscous_layers_2d_hyp.png index 4ad6ee0ec..f9b952fd7 100644 Binary files a/doc/salome/gui/SMESH/images/viscous_layers_2d_hyp.png and b/doc/salome/gui/SMESH/images/viscous_layers_2d_hyp.png differ diff --git a/doc/salome/gui/SMESH/images/viscous_layers_hyp.png b/doc/salome/gui/SMESH/images/viscous_layers_hyp.png index aaf9ad658..b7bbffbe6 100644 Binary files a/doc/salome/gui/SMESH/images/viscous_layers_hyp.png and b/doc/salome/gui/SMESH/images/viscous_layers_hyp.png differ diff --git a/doc/salome/gui/SMESH/input/additional_hypo.rst b/doc/salome/gui/SMESH/input/additional_hypo.rst index c6665910d..6fa98f9c2 100644 --- a/doc/salome/gui/SMESH/input/additional_hypo.rst +++ b/doc/salome/gui/SMESH/input/additional_hypo.rst @@ -108,6 +108,8 @@ computations. boundary faces/edges of the shape of this sub-mesh, at same time possibly being internal faces/edges within the whole model. +* **Create groups from layers** - activates creation of a group containing elements of the layers. + .. image:: ../images/viscous_layers_on_submesh.png :align: center diff --git a/idl/SMESH_BasicHypothesis.idl b/idl/SMESH_BasicHypothesis.idl index 1f9439f01..f75697977 100644 --- a/idl/SMESH_BasicHypothesis.idl +++ b/idl/SMESH_BasicHypothesis.idl @@ -924,6 +924,9 @@ module StdMeshers void SetMethod( in VLExtrusionMethod how ); VLExtrusionMethod GetMethod(); + + void SetGroupName(in string name); + string GetGroupName(); }; /*! @@ -965,6 +968,9 @@ module StdMeshers */ void SetStretchFactor(in double factor) raises (SALOME::SALOME_Exception); double GetStretchFactor(); + + void SetGroupName(in string name); + string GetGroupName(); }; /*! diff --git a/resources/StdMeshers.xml.in b/resources/StdMeshers.xml.in index 5b7f60e4f..daf17c96a 100644 --- a/resources/StdMeshers.xml.in +++ b/resources/StdMeshers.xml.in @@ -318,7 +318,7 @@ MEFISTO_2D=Triangle(algo=smeshBuilder.MEFISTO) LengthFromEdges=LengthFromEdges() MaxElementArea=MaxElementArea(SetMaxElementArea()) - ViscousLayers2D=ViscousLayers2D(SetTotalThickness(),SetNumberLayers(),SetStretchFactor(),SetEdges(1),SetEdges(2)) + ViscousLayers2D=ViscousLayers2D(SetTotalThickness(),SetNumberLayers(),SetStretchFactor(),SetEdges(1),SetEdges(2),SetGroupName()) @@ -335,7 +335,7 @@ Quadrangle_2D=Quadrangle(algo=smeshBuilder.QUADRANGLE) QuadrangleParams=QuadrangleParameters(SetQuadType(),SetTriaVertex(),SetEnforcedNodes(1),SetEnforcedNodes(2),SetCorners()) - ViscousLayers2D=ViscousLayers2D(SetTotalThickness(),SetNumberLayers(),SetStretchFactor(),SetIgnoreEdges()) + ViscousLayers2D=ViscousLayers2D(SetTotalThickness(),SetNumberLayers(),SetStretchFactor(),SetEdges(1),SetEdges(2),SetGroupName()) @@ -351,7 +351,7 @@ dim ="2"> QuadFromMedialAxis_1D2D=Quadrangle(algo=smeshBuilder.QUAD_MA_PROJ) - ViscousLayers2D=ViscousLayers2D(SetTotalThickness(),SetNumberLayers(),SetStretchFactor(),SetIgnoreEdges()) + ViscousLayers2D=ViscousLayers2D(SetTotalThickness(),SetNumberLayers(),SetStretchFactor(),SetEdges(1),SetEdges(2),SetGroupName()) NumberOfLayers2D=NumberOfLayers(SetNumberOfLayers()) @@ -367,7 +367,7 @@ dim ="2"> PolygonPerFace_2D=Polygon() - ViscousLayers2D=ViscousLayers2D(SetTotalThickness(),SetNumberLayers(),SetStretchFactor(),SetIgnoreEdges()) + ViscousLayers2D=ViscousLayers2D(SetTotalThickness(),SetNumberLayers(),SetStretchFactor(),SetEdges(1),SetEdges(2),SetGroupName()) @@ -395,7 +395,7 @@ dim ="3"> Hexa_3D=Hexahedron(algo=smeshBuilder.Hexa) - ViscousLayers=ViscousLayers(SetTotalThickness(),SetNumberLayers(),SetStretchFactor(),SetFaces(1),SetFaces(2),SetMethod()) + ViscousLayers=ViscousLayers(SetTotalThickness(),SetNumberLayers(),SetStretchFactor(),SetFaces(1),SetFaces(2),SetMethod(),SetGroupName()) diff --git a/src/SMESHGUI/SMESHGUI_Hypotheses.cxx b/src/SMESHGUI/SMESHGUI_Hypotheses.cxx index 5078f0df7..521966bf7 100644 --- a/src/SMESHGUI/SMESHGUI_Hypotheses.cxx +++ b/src/SMESHGUI/SMESHGUI_Hypotheses.cxx @@ -185,10 +185,11 @@ QFrame* SMESHGUI_GenericHypothesisCreator::buildStdFrame() GroupC1Layout->setMargin( MARGIN ); ListOfStdParams::const_iterator anIt = params.begin(), aLast = params.end(); - for( int i=0; anIt!=aLast; anIt++, i++ ) + for( int i = 0; anIt != aLast; anIt++, i++ ) { - QLabel* lab = new QLabel( (*anIt).myName, GroupC1 ); - GroupC1Layout->addWidget( lab, i, 0 ); + QLabel* lab = anIt->hasName() ? new QLabel( anIt->myName, GroupC1 ) : NULL; + if ( lab ) + GroupC1Layout->addWidget( lab, i, 0 ); myParamLabels << lab; QWidget* w = getCustomWidget( *anIt, GroupC1, i ); @@ -251,9 +252,12 @@ QFrame* SMESHGUI_GenericHypothesisCreator::buildStdFrame() default:; } // switch( (*anIt).myValue.type() ) - if( w ) + if ( w ) { - GroupC1Layout->addWidget( w, i, 1 ); + if ( lab ) + GroupC1Layout->addWidget( w, i, 1 ); + else + GroupC1Layout->addWidget( w, i, 0, 1, 2 ); changeWidgets().append( w ); } } diff --git a/src/SMESHGUI/SMESHGUI_Hypotheses.h b/src/SMESHGUI/SMESHGUI_Hypotheses.h index 454ac1ae3..b50f5f128 100644 --- a/src/SMESHGUI/SMESHGUI_Hypotheses.h +++ b/src/SMESHGUI/SMESHGUI_Hypotheses.h @@ -92,6 +92,8 @@ protected: const char* text() const { ((QByteArray&) myTextAsBytes) = myText.toUtf8(); return myTextAsBytes.constData(); } + void setNoName() { myName.clear(); } // ==> widget occupies both columns + bool hasName() const { return !myName.isEmpty(); } }; typedef QList ListOfStdParams; diff --git a/src/SMESH_SWIG/smesh_algorithm.py b/src/SMESH_SWIG/smesh_algorithm.py index f14fa318d..7603ab2bc 100644 --- a/src/SMESH_SWIG/smesh_algorithm.py +++ b/src/SMESH_SWIG/smesh_algorithm.py @@ -290,7 +290,8 @@ class Mesh_Algorithm: return shape.GetStudyEntry() def ViscousLayers(self, thickness, numberOfLayers, stretchFactor, - faces=[], isFacesToIgnore=True, extrMethod=StdMeshers.SURF_OFFSET_SMOOTH ): + faces=[], isFacesToIgnore=True, + extrMethod=StdMeshers.SURF_OFFSET_SMOOTH, groupName=""): """ Defines "ViscousLayers" hypothesis to give parameters of layers of prisms to build near mesh boundary. This hypothesis can be used by several 3D algorithms: @@ -319,8 +320,17 @@ class Mesh_Algorithm: - StdMeshers.NODE_OFFSET method extrudes nodes along average normal of surrounding mesh faces by the layers thickness. Thickness of layers can be limited to avoid creation of invalid prisms. + groupName: name of a group to contain elements of layers. If not provided, + no group is created. The group is created upon mesh generation. + It can be retrieved by calling + :: + + group = mesh.GetGroupByName( groupName, SMESH.VOLUME )[0] + + Returns: + StdMeshers.StdMeshers_ViscousLayers hypothesis """ - + if not isinstance(self.algo, SMESH._objref_SMESH_3D_Algo): raise TypeError("ViscousLayers are supported by 3D algorithms only") if not "ViscousLayers" in self.GetCompatibleHypothesis(): @@ -342,11 +352,12 @@ class Mesh_Algorithm: hyp.SetStretchFactor( stretchFactor ) hyp.SetFaces( faces, isFacesToIgnore ) hyp.SetMethod( extrMethod ) + hyp.SetGroupName( groupName ) self.mesh.AddHypothesis( hyp, self.geom ) return hyp def ViscousLayers2D(self, thickness, numberOfLayers, stretchFactor, - edges=[], isEdgesToIgnore=True ): + edges=[], isEdgesToIgnore=True, groupName="" ): """ Defines "ViscousLayers2D" hypothesis to give parameters of layers of quadrilateral elements to build near mesh boundary. This hypothesis can be used by several 2D algorithms: @@ -361,6 +372,15 @@ class Mesh_Algorithm: the value of **isEdgesToIgnore** parameter. isEdgesToIgnore: if *True*, the Viscous layers are not generated on the edges specified by the previous parameter (**edges**). + groupName: name of a group to contain elements of layers. If not provided, + no group is created. The group is created upon mesh generation. + It can be retrieved by calling + :: + + group = mesh.GetGroupByName( groupName, SMESH.FACE )[0] + + Returns: + StdMeshers.StdMeshers_ViscousLayers2D hypothesis """ if not isinstance(self.algo, SMESH._objref_SMESH_2D_Algo): @@ -383,6 +403,7 @@ class Mesh_Algorithm: hyp.SetNumberLayers(numberOfLayers) hyp.SetStretchFactor(stretchFactor) hyp.SetEdges(edges, isEdgesToIgnore) + hyp.SetGroupName( groupName ) self.mesh.AddHypothesis( hyp, self.geom ) return hyp diff --git a/src/StdMeshers/StdMeshers_ViscousLayers.cxx b/src/StdMeshers/StdMeshers_ViscousLayers.cxx index 075d1b46d..270330be4 100644 --- a/src/StdMeshers/StdMeshers_ViscousLayers.cxx +++ b/src/StdMeshers/StdMeshers_ViscousLayers.cxx @@ -612,12 +612,16 @@ namespace VISCOUS_3D _thickness = Max( _thickness, hyp->GetTotalThickness() ); _stretchFactor += hyp->GetStretchFactor(); _method = hyp->GetMethod(); + if ( _groupName.empty() ) + _groupName = hyp->GetGroupName(); } } double GetTotalThickness() const { return _thickness; /*_nbHyps ? _thickness / _nbHyps : 0;*/ } double GetStretchFactor() const { return _nbHyps ? _stretchFactor / _nbHyps : 0; } int GetNumberLayers() const { return _nbLayers; } int GetMethod() const { return _method; } + bool ToCreateGroup() const { return !_groupName.empty(); } + const std::string& GetGroupName() const { return _groupName; } bool UseSurfaceNormal() const { return _method == StdMeshers_ViscousLayers::SURF_OFFSET_SMOOTH; } @@ -636,8 +640,9 @@ namespace VISCOUS_3D static bool Equals( double v1, double v2 ) { return Abs( v1 - v2 ) < 0.01 * ( v1 + v2 ); } private: - int _nbLayers, _nbHyps, _method; - double _thickness, _stretchFactor; + int _nbLayers, _nbHyps, _method; + double _thickness, _stretchFactor; + std::string _groupName; }; //-------------------------------------------------------------------------------- @@ -1247,7 +1252,8 @@ namespace VISCOUS_3D StdMeshers_ViscousLayers::StdMeshers_ViscousLayers(int hypId, SMESH_Gen* gen) :SMESH_Hypothesis(hypId, gen), _isToIgnoreShapes(1), _nbLayers(1), _thickness(1), _stretchFactor(1), - _method( SURF_OFFSET_SMOOTH ) + _method( SURF_OFFSET_SMOOTH ), + _groupName("") { _name = StdMeshers_ViscousLayers::GetHypType(); _param_algo_dim = -3; // auxiliary hyp used by 3D algos @@ -1279,6 +1285,15 @@ void StdMeshers_ViscousLayers::SetMethod( ExtrusionMethod method ) if ( _method != method ) _method = method, NotifySubMeshesHypothesisModification(); } // -------------------------------------------------------------------------------- +void StdMeshers_ViscousLayers::SetGroupName(const std::string& name) +{ + if ( _groupName != name ) + { + _groupName = name; + if ( !_groupName.empty() ) + NotifySubMeshesHypothesisModification(); + } +} // -------------------------------------------------------------------------------- SMESH_ProxyMesh::Ptr StdMeshers_ViscousLayers::Compute(SMESH_Mesh& theMesh, const TopoDS_Shape& theShape, @@ -1333,6 +1348,9 @@ std::ostream & StdMeshers_ViscousLayers::SaveTo(std::ostream & save) save << " " << _shapeIds[i]; save << " " << !_isToIgnoreShapes; // negate to keep the behavior in old studies. save << " " << _method; + save << " " << _groupName.size(); + if ( !_groupName.empty() ) + save << " " << _groupName; return save; } // -------------------------------------------------------------------------------- std::istream & StdMeshers_ViscousLayers::LoadFrom(std::istream & load) @@ -1345,6 +1363,13 @@ std::istream & StdMeshers_ViscousLayers::LoadFrom(std::istream & load) _isToIgnoreShapes = !shapeToTreat; if ( load >> method ) _method = (ExtrusionMethod) method; + int nameSize = 0; + if ( load >> nameSize && nameSize > 0 ) + { + _groupName.resize( nameSize ); + load.get( _groupName[0] ); // remove a white-space + load.getline( &_groupName[0], nameSize + 1 ); + } } else { _isToIgnoreShapes = true; // old behavior @@ -1378,6 +1403,36 @@ bool StdMeshers_ViscousLayers::IsShapeWithLayers(int shapeIndex) const ( std::find( _shapeIds.begin(), _shapeIds.end(), shapeIndex ) != _shapeIds.end() ); return IsToIgnoreShapes() ? !isIn : isIn; } + +// -------------------------------------------------------------------------------- +SMDS_MeshGroup* StdMeshers_ViscousLayers::CreateGroup( const std::string& theName, + SMESH_Mesh& theMesh, + SMDSAbs_ElementType theType) +{ + SMESH_Group* group = 0; + SMDS_MeshGroup* groupDS = 0; + + if ( theName.empty() ) + return groupDS; + + if ( SMESH_Mesh::GroupIteratorPtr grIt = theMesh.GetGroups() ) + while( grIt->more() && !group ) + { + group = grIt->next(); + if ( !group || + group->GetGroupDS()->GetType() != theType || + group->GetName() != theName || + !dynamic_cast< SMESHDS_Group* >( group->GetGroupDS() )) + group = 0; + } + if ( !group ) + group = theMesh.AddGroup( theType, theName.c_str() ); + + groupDS = & dynamic_cast< SMESHDS_Group* >( group->GetGroupDS() )->SMDSGroup(); + + return groupDS; +} + // END StdMeshers_ViscousLayers hypothesis //================================================================================ @@ -10230,6 +10285,11 @@ bool _ViscousBuilder::refine(_SolidData& data) const TGeomID faceID = getMeshDS()->ShapeToIndex( exp.Current() ); if ( data._ignoreFaceIds.count( faceID )) continue; + _EdgesOnShape* eos = data.GetShapeEdges( faceID ); + SMDS_MeshGroup* group = StdMeshers_ViscousLayers::CreateGroup( eos->_hyp.GetGroupName(), + *helper.GetMesh(), + SMDSAbs_Volume ); + std::vector< const SMDS_MeshElement* > vols; const bool isReversedFace = data._reversedFaceIds.count( faceID ); SMESHDS_SubMesh* fSubM = getMeshDS()->MeshElements( exp.Current() ); SMDS_ElemIteratorPtr fIt = fSubM->GetElements(); @@ -10260,14 +10320,20 @@ bool _ViscousBuilder::refine(_SolidData& data) if ( 0 < nnSet.size() && nnSet.size() < 3 ) continue; + vols.clear(); + const SMDS_MeshElement* vol; + switch ( nbNodes ) { case 3: // TRIA { // PENTA for ( size_t iZ = 1; iZ < minZ; ++iZ ) - helper.AddVolume( (*nnVec[0])[iZ-1], (*nnVec[1])[iZ-1], (*nnVec[2])[iZ-1], - (*nnVec[0])[iZ], (*nnVec[1])[iZ], (*nnVec[2])[iZ]); + { + vol = helper.AddVolume( (*nnVec[0])[iZ-1], (*nnVec[1])[iZ-1], (*nnVec[2])[iZ-1], + (*nnVec[0])[iZ], (*nnVec[1])[iZ], (*nnVec[2])[iZ]); + vols.push_back( vol ); + } for ( size_t iZ = minZ; iZ < maxZ; ++iZ ) { @@ -10280,16 +10346,18 @@ bool _ViscousBuilder::refine(_SolidData& data) int i2 = *degenEdgeInd.begin(); int i0 = helper.WrapIndex( i2 - 1, nbNodes ); int i1 = helper.WrapIndex( i2 + 1, nbNodes ); - helper.AddVolume( (*nnVec[i0])[iZ-1], (*nnVec[i1])[iZ-1], - (*nnVec[i1])[iZ ], (*nnVec[i0])[iZ ], (*nnVec[i2]).back()); + vol = helper.AddVolume( (*nnVec[i0])[iZ-1], (*nnVec[i1])[iZ-1], + (*nnVec[i1])[iZ ], (*nnVec[i0])[iZ ], (*nnVec[i2]).back()); + vols.push_back( vol ); } else // TETRA { int i3 = !degenEdgeInd.count(0) ? 0 : !degenEdgeInd.count(1) ? 1 : 2; - helper.AddVolume( (*nnVec[ 0 ])[ i3 == 0 ? iZ-1 : nnVec[0]->size()-1 ], - (*nnVec[ 1 ])[ i3 == 1 ? iZ-1 : nnVec[1]->size()-1 ], - (*nnVec[ 2 ])[ i3 == 2 ? iZ-1 : nnVec[2]->size()-1 ], - (*nnVec[ i3 ])[ iZ ]); + vol = helper.AddVolume( (*nnVec[ 0 ])[ i3 == 0 ? iZ-1 : nnVec[0]->size()-1 ], + (*nnVec[ 1 ])[ i3 == 1 ? iZ-1 : nnVec[1]->size()-1 ], + (*nnVec[ 2 ])[ i3 == 2 ? iZ-1 : nnVec[2]->size()-1 ], + (*nnVec[ i3 ])[ iZ ]); + vols.push_back( vol ); } } break; // TRIA @@ -10298,10 +10366,13 @@ bool _ViscousBuilder::refine(_SolidData& data) { // HEX for ( size_t iZ = 1; iZ < minZ; ++iZ ) - helper.AddVolume( (*nnVec[0])[iZ-1], (*nnVec[1])[iZ-1], - (*nnVec[2])[iZ-1], (*nnVec[3])[iZ-1], - (*nnVec[0])[iZ], (*nnVec[1])[iZ], - (*nnVec[2])[iZ], (*nnVec[3])[iZ]); + { + vol = helper.AddVolume( (*nnVec[0])[iZ-1], (*nnVec[1])[iZ-1], + (*nnVec[2])[iZ-1], (*nnVec[3])[iZ-1], + (*nnVec[0])[iZ], (*nnVec[1])[iZ], + (*nnVec[2])[iZ], (*nnVec[3])[iZ]); + vols.push_back( vol ); + } for ( size_t iZ = minZ; iZ < maxZ; ++iZ ) { @@ -10320,9 +10391,9 @@ bool _ViscousBuilder::refine(_SolidData& data) int i0 = helper.WrapIndex( i3 + 1, nbNodes ); int i1 = helper.WrapIndex( i0 + 1, nbNodes ); - const SMDS_MeshElement* vol = - helper.AddVolume( nnVec[i3]->back(), (*nnVec[i0])[iZ], (*nnVec[i0])[iZ-1], - nnVec[i2]->back(), (*nnVec[i1])[iZ], (*nnVec[i1])[iZ-1]); + vol = helper.AddVolume( nnVec[i3]->back(), (*nnVec[i0])[iZ], (*nnVec[i0])[iZ-1], + nnVec[i2]->back(), (*nnVec[i1])[iZ], (*nnVec[i1])[iZ-1]); + vols.push_back( vol ); if ( !ok && vol ) degenVols.push_back( vol ); } @@ -10330,15 +10401,15 @@ bool _ViscousBuilder::refine(_SolidData& data) default: // degen HEX { - const SMDS_MeshElement* vol = - helper.AddVolume( nnVec[0]->size() > iZ-1 ? (*nnVec[0])[iZ-1] : nnVec[0]->back(), - nnVec[1]->size() > iZ-1 ? (*nnVec[1])[iZ-1] : nnVec[1]->back(), - nnVec[2]->size() > iZ-1 ? (*nnVec[2])[iZ-1] : nnVec[2]->back(), - nnVec[3]->size() > iZ-1 ? (*nnVec[3])[iZ-1] : nnVec[3]->back(), - nnVec[0]->size() > iZ ? (*nnVec[0])[iZ] : nnVec[0]->back(), - nnVec[1]->size() > iZ ? (*nnVec[1])[iZ] : nnVec[1]->back(), - nnVec[2]->size() > iZ ? (*nnVec[2])[iZ] : nnVec[2]->back(), - nnVec[3]->size() > iZ ? (*nnVec[3])[iZ] : nnVec[3]->back()); + vol = helper.AddVolume( nnVec[0]->size() > iZ-1 ? (*nnVec[0])[iZ-1] : nnVec[0]->back(), + nnVec[1]->size() > iZ-1 ? (*nnVec[1])[iZ-1] : nnVec[1]->back(), + nnVec[2]->size() > iZ-1 ? (*nnVec[2])[iZ-1] : nnVec[2]->back(), + nnVec[3]->size() > iZ-1 ? (*nnVec[3])[iZ-1] : nnVec[3]->back(), + nnVec[0]->size() > iZ ? (*nnVec[0])[iZ] : nnVec[0]->back(), + nnVec[1]->size() > iZ ? (*nnVec[1])[iZ] : nnVec[1]->back(), + nnVec[2]->size() > iZ ? (*nnVec[2])[iZ] : nnVec[2]->back(), + nnVec[3]->size() > iZ ? (*nnVec[3])[iZ] : nnVec[3]->back()); + vols.push_back( vol ); degenVols.push_back( vol ); } } @@ -10349,6 +10420,11 @@ bool _ViscousBuilder::refine(_SolidData& data) return error("Not supported type of element", data._index); } // switch ( nbNodes ) + + if ( group ) + for ( size_t i = 0; i < vols.size(); ++i ) + group->Add( vols[ i ]); + } // while ( fIt->more() ) } // loop on FACEs diff --git a/src/StdMeshers/StdMeshers_ViscousLayers.hxx b/src/StdMeshers/StdMeshers_ViscousLayers.hxx index 142f35b01..7d7e362fd 100644 --- a/src/StdMeshers/StdMeshers_ViscousLayers.hxx +++ b/src/StdMeshers/StdMeshers_ViscousLayers.hxx @@ -32,6 +32,8 @@ #include +class SMDS_MeshGroup; + /*! * \brief Hypothesis defining parameters of viscous layers */ @@ -73,6 +75,13 @@ public: void SetMethod( ExtrusionMethod how ); ExtrusionMethod GetMethod() const { return _method; } + // name of a group to create + void SetGroupName(const std::string& name); + const std::string& GetGroupName() const { return _groupName; } + static SMDS_MeshGroup* CreateGroup( const std::string& theName, + SMESH_Mesh& theMesh, + SMDSAbs_ElementType theType); + // Computes temporary 2D mesh to be used by 3D algorithm. // Return SMESH_ProxyMesh for each SOLID in theShape SMESH_ProxyMesh::Ptr Compute(SMESH_Mesh& theMesh, @@ -116,6 +125,7 @@ public: double _thickness; double _stretchFactor; ExtrusionMethod _method; + std::string _groupName; }; class SMESH_subMesh; diff --git a/src/StdMeshers/StdMeshers_ViscousLayers2D.cxx b/src/StdMeshers/StdMeshers_ViscousLayers2D.cxx index 6248200a7..a0da0d527 100644 --- a/src/StdMeshers/StdMeshers_ViscousLayers2D.cxx +++ b/src/StdMeshers/StdMeshers_ViscousLayers2D.cxx @@ -2402,6 +2402,17 @@ bool _ViscousBuilder2D::refine() outerNodes.swap( innerNodes ); } + // Add faces to a group + SMDS_MeshGroup* group = StdMeshers_ViscousLayers::CreateGroup( hyp->GetGroupName(), + *_helper.GetMesh(), + SMDSAbs_Face ); + if ( group ) + { + TIDSortedElemSet::iterator fIt = L._newFaces.begin(); + for ( ; fIt != L._newFaces.end(); ++fIt ) + group->Add( *fIt ); + } + // faces between not shared _LayerEdge's (at concave VERTEX) for ( int isR = 0; isR < 2; ++isR ) { @@ -2413,15 +2424,22 @@ bool _ViscousBuilder2D::refine() if ( lNodes.empty() || rNodes.empty() || lNodes.size() != rNodes.size() ) continue; + const SMDS_MeshElement* face = 0; for ( size_t i = 1; i < lNodes.size(); ++i ) - _helper.AddFace( lNodes[ i+prev ], rNodes[ i+prev ], - rNodes[ i+cur ], lNodes[ i+cur ]); + { + face = _helper.AddFace( lNodes[ i+prev ], rNodes[ i+prev ], + rNodes[ i+cur ], lNodes[ i+cur ]); + if ( group ) + group->Add( face ); + } const UVPtStruct& ptOnVertex = points[ isR ? L._lastPntInd : L._firstPntInd ]; if ( isReverse ) - _helper.AddFace( ptOnVertex.node, lNodes[ 0 ], rNodes[ 0 ]); + face = _helper.AddFace( ptOnVertex.node, lNodes[ 0 ], rNodes[ 0 ]); else - _helper.AddFace( ptOnVertex.node, rNodes[ 0 ], lNodes[ 0 ]); + face = _helper.AddFace( ptOnVertex.node, rNodes[ 0 ], lNodes[ 0 ]); + if ( group ) + group->Add( face ); } // Fill the _ProxyMeshOfFace diff --git a/src/StdMeshersGUI/CMakeLists.txt b/src/StdMeshersGUI/CMakeLists.txt index 0b8834730..4393778db 100644 --- a/src/StdMeshersGUI/CMakeLists.txt +++ b/src/StdMeshersGUI/CMakeLists.txt @@ -82,6 +82,7 @@ SET(_moc_HEADERS StdMeshersGUI_CartesianParamCreator.h StdMeshersGUI_RadioButtonsGrpWdg.h StdMeshersGUI_PropagationHelperWdg.h + StdMeshersGUI_NameCheckableGrpWdg.h ) IF(SALOME_USE_PLOT2DVIEWER) @@ -117,6 +118,7 @@ SET(_other_SOURCES StdMeshersGUI_CartesianParamCreator.cxx StdMeshersGUI_RadioButtonsGrpWdg.cxx StdMeshersGUI_PropagationHelperWdg.cxx + StdMeshersGUI_NameCheckableGrpWdg.cxx ) IF(SALOME_USE_PLOT2DVIEWER) diff --git a/src/StdMeshersGUI/StdMeshersGUI_NameCheckableGrpWdg.cxx b/src/StdMeshersGUI/StdMeshersGUI_NameCheckableGrpWdg.cxx new file mode 100644 index 000000000..5ea084b43 --- /dev/null +++ b/src/StdMeshersGUI/StdMeshersGUI_NameCheckableGrpWdg.cxx @@ -0,0 +1,68 @@ +// Copyright (C) 2007-2019 CEA/DEN, EDF R&D, OPEN CASCADE +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// +#include "StdMeshersGUI_NameCheckableGrpWdg.h" + +#include +#include +#include + +#define SPACING 6 +#define MARGIN 11 + +//================================================================================ +/*! + * \brief Creates a QGroupBox with a given title + */ +//================================================================================ + +StdMeshersGUI_NameCheckableGrpWdg::StdMeshersGUI_NameCheckableGrpWdg( const QString& groupTitle, + const QString& nameLabel ) + : QGroupBox( groupTitle ), + myNameLineEdit( new QLineEdit( this )) +{ + setCheckable( true ); + + QLabel* label = new QLabel( nameLabel ); + + QGridLayout* layout = new QGridLayout( this ); + layout->setSpacing(SPACING); + layout->setMargin(MARGIN); + + layout->addWidget( label, 0, 0 ); + layout->addWidget( myNameLineEdit, 0, 1 ); + + connect( this, SIGNAL( toggled( bool )), myNameLineEdit, SLOT( setEnabled( bool ))); +} + +QString StdMeshersGUI_NameCheckableGrpWdg::getName() +{ + return isChecked() ? myNameLineEdit->text() : QString(); +} + +void StdMeshersGUI_NameCheckableGrpWdg::setName( CORBA::String_var name ) +{ + myNameLineEdit->setText( name.in() ); + setChecked( ! myNameLineEdit->text().isEmpty() ); +} + +void StdMeshersGUI_NameCheckableGrpWdg::setDefaultName( QString name ) +{ + myNameLineEdit->setText( name ); + setChecked( ! myNameLineEdit->text().isEmpty() ); +} diff --git a/src/StdMeshersGUI/StdMeshersGUI_NameCheckableGrpWdg.h b/src/StdMeshersGUI/StdMeshersGUI_NameCheckableGrpWdg.h new file mode 100644 index 000000000..334df51b8 --- /dev/null +++ b/src/StdMeshersGUI/StdMeshersGUI_NameCheckableGrpWdg.h @@ -0,0 +1,53 @@ +// Copyright (C) 2007-2019 CEA/DEN, EDF R&D, OPEN CASCADE +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// +#ifndef STDMESHERSGUI_NameCheckableGrpWdg_H +#define STDMESHERSGUI_NameCheckableGrpWdg_H + +// SMESH includes +#include "SMESH_StdMeshersGUI.hxx" + +// Qt includes +#include + +#include + +class QButtonGroup; +class QLineEdit; + +/*! + * \brief A QGroupBox holding several radio buttons + */ +class STDMESHERSGUI_EXPORT StdMeshersGUI_NameCheckableGrpWdg : public QGroupBox +{ + Q_OBJECT + +public: + StdMeshersGUI_NameCheckableGrpWdg(const QString& groupTitle, + const QString& nameLabel); + + QString getName(); + + void setName( CORBA::String_var name ); + void setDefaultName( QString name ); + +private: + QLineEdit* myNameLineEdit; +}; + +#endif // STDMESHERSGUI_NameCheckableGrpWdg_H diff --git a/src/StdMeshersGUI/StdMeshersGUI_StdHypothesisCreator.cxx b/src/StdMeshersGUI/StdMeshersGUI_StdHypothesisCreator.cxx index d477b2fc6..f16b06011 100644 --- a/src/StdMeshersGUI/StdMeshersGUI_StdHypothesisCreator.cxx +++ b/src/StdMeshersGUI/StdMeshersGUI_StdHypothesisCreator.cxx @@ -39,6 +39,7 @@ #include "StdMeshersGUI_PropagationHelperWdg.h" #include "StdMeshersGUI_QuadrangleParamWdg.h" #include "StdMeshersGUI_RadioButtonsGrpWdg.h" +#include "StdMeshersGUI_NameCheckableGrpWdg.h" #include "StdMeshersGUI_SubShapeSelectorWdg.h" #include @@ -728,6 +729,12 @@ QString StdMeshersGUI_StdHypothesisCreator::storeParams() const { h->SetFaces( idsWg->GetListOfIDs(), params[4].myValue.toInt() ); } + + if ( StdMeshersGUI_NameCheckableGrpWdg* nameWg = + widget< StdMeshersGUI_NameCheckableGrpWdg >( 6 )) + { + h->SetGroupName( nameWg->getName().toUtf8().data() ); + } } else if( hypType()=="ViscousLayers2D" ) { @@ -746,6 +753,12 @@ QString StdMeshersGUI_StdHypothesisCreator::storeParams() const { h->SetEdges( idsWg->GetListOfIDs(), params[3].myValue.toInt() ); } + + if ( StdMeshersGUI_NameCheckableGrpWdg* nameWg = + widget< StdMeshersGUI_NameCheckableGrpWdg >( 5 )) + { + h->SetGroupName( nameWg->getName().toUtf8().data() ); + } } // else if( hypType()=="QuadrangleParams" ) // { @@ -1250,6 +1263,19 @@ bool StdMeshersGUI_StdHypothesisCreator::stdParams( ListOfStdParams& p ) const } customWidgets()->append ( idsWg ); } + + item.setNoName(); + p.append( item ); + StdMeshersGUI_NameCheckableGrpWdg* nameWdg = + new StdMeshersGUI_NameCheckableGrpWdg( tr( "CREATE_GROUPS_FROM_LAYERS" ), + tr( "GROUP_NAME" )); + nameWdg->setName( h->GetGroupName() ); + if ( nameWdg->getName().isEmpty() ) + { + nameWdg->setDefaultName( type() ); + nameWdg->setChecked( false ); + } + customWidgets()->append ( nameWdg ); } else if( hypType()=="ViscousLayers2D" ) { @@ -1308,6 +1334,19 @@ bool StdMeshersGUI_StdHypothesisCreator::stdParams( ListOfStdParams& p ) const } customWidgets()->append ( idsWg ); } + + item.setNoName(); + p.append( item ); + StdMeshersGUI_NameCheckableGrpWdg* nameWdg = + new StdMeshersGUI_NameCheckableGrpWdg( tr( "CREATE_GROUPS_FROM_LAYERS" ), + tr( "GROUP_NAME" )); + nameWdg->setName( h->GetGroupName() ); + if ( nameWdg->getName().isEmpty() ) + { + nameWdg->setDefaultName( type() ); + nameWdg->setChecked( false ); + } + customWidgets()->append ( nameWdg ); } else res = false; @@ -1574,6 +1613,10 @@ bool StdMeshersGUI_StdHypothesisCreator::getParamFromCustomWidget( StdParam & pa param.myValue = w->checkedId(); return true; } + if ( widget->inherits( "StdMeshersGUI_NameCheckableGrpWdg" )) + { + return true; + } return false; } diff --git a/src/StdMeshersGUI/StdMeshers_msg_en.ts b/src/StdMeshersGUI/StdMeshers_msg_en.ts index 351aed8f4..036b28413 100644 --- a/src/StdMeshersGUI/StdMeshers_msg_en.ts +++ b/src/StdMeshersGUI/StdMeshers_msg_en.ts @@ -59,6 +59,14 @@ this one for this mesh/sub-mesh. EXTMETH_FACE_OFFSET Face offset + + CREATE_GROUPS_FROM_LAYERS + Create groups from layers + + + GROUP_NAME + Group name + @default diff --git a/src/StdMeshers_I/StdMeshers_ViscousLayers2D_i.cxx b/src/StdMeshers_I/StdMeshers_ViscousLayers2D_i.cxx index 376f156b0..0e03a4b1f 100644 --- a/src/StdMeshers_I/StdMeshers_ViscousLayers2D_i.cxx +++ b/src/StdMeshers_I/StdMeshers_ViscousLayers2D_i.cxx @@ -222,6 +222,33 @@ throw ( SALOME::SALOME_Exception ) return GetImpl()->GetStretchFactor(); } +//================================================================================ +/*! + * \brief Set name of a group of layers elements + */ +//================================================================================ + +void StdMeshers_ViscousLayers2D_i::SetGroupName(const char* name) +{ + if ( GetImpl()->GetGroupName() != name ) + { + GetImpl()->SetGroupName( name ); + SMESH::TPythonDump() << _this() << ".SetGroupName( '" << name << "' )"; + } +} + +//================================================================================ +/*! + * \brief Return name of a group of layers elements + */ +//================================================================================ + +char* StdMeshers_ViscousLayers2D_i::GetGroupName() +{ + return CORBA::string_dup( GetImpl()->GetGroupName().c_str() ); +} + + //============================================================================= /*! * Get implementation diff --git a/src/StdMeshers_I/StdMeshers_ViscousLayers2D_i.hxx b/src/StdMeshers_I/StdMeshers_ViscousLayers2D_i.hxx index 49dc69c8e..56f557c38 100644 --- a/src/StdMeshers_I/StdMeshers_ViscousLayers2D_i.hxx +++ b/src/StdMeshers_I/StdMeshers_ViscousLayers2D_i.hxx @@ -64,6 +64,10 @@ class STDMESHERS_I_EXPORT StdMeshers_ViscousLayers2D_i: void SetStretchFactor(::CORBA::Double factor) throw ( SALOME::SALOME_Exception ); ::CORBA::Double GetStretchFactor(); + void SetGroupName(const char* name); + char* GetGroupName(); + + // Get implementation ::StdMeshers_ViscousLayers2D* GetImpl(); diff --git a/src/StdMeshers_I/StdMeshers_ViscousLayers_i.cxx b/src/StdMeshers_I/StdMeshers_ViscousLayers_i.cxx index 603ef55c3..ab47e1725 100644 --- a/src/StdMeshers_I/StdMeshers_ViscousLayers_i.cxx +++ b/src/StdMeshers_I/StdMeshers_ViscousLayers_i.cxx @@ -253,6 +253,32 @@ void StdMeshers_ViscousLayers_i::SetMethod( ::StdMeshers::VLExtrusionMethod how return (::StdMeshers::VLExtrusionMethod) GetImpl()->GetMethod(); } +//================================================================================ +/*! + * \brief Set name of a group of layers elements + */ +//================================================================================ + +void StdMeshers_ViscousLayers_i::SetGroupName(const char* name) +{ + if ( GetImpl()->GetGroupName() != name ) + { + GetImpl()->SetGroupName( name ); + SMESH::TPythonDump() << _this() << ".SetGroupName( '" << name << "' )"; + } +} + +//================================================================================ +/*! + * \brief Return name of a group of layers elements + */ +//================================================================================ + +char* StdMeshers_ViscousLayers_i::GetGroupName() +{ + return CORBA::string_dup( GetImpl()->GetGroupName().c_str() ); +} + //============================================================================= /*! * Get implementation diff --git a/src/StdMeshers_I/StdMeshers_ViscousLayers_i.hxx b/src/StdMeshers_I/StdMeshers_ViscousLayers_i.hxx index ac5f0e1ae..47200ce72 100644 --- a/src/StdMeshers_I/StdMeshers_ViscousLayers_i.hxx +++ b/src/StdMeshers_I/StdMeshers_ViscousLayers_i.hxx @@ -67,10 +67,14 @@ class STDMESHERS_I_EXPORT StdMeshers_ViscousLayers_i: void SetMethod( ::StdMeshers::VLExtrusionMethod how ); ::StdMeshers::VLExtrusionMethod GetMethod(); + void SetGroupName(const char* name); + char* GetGroupName(); + + // Get implementation ::StdMeshers_ViscousLayers* GetImpl(); - // Verify whether hypothesis supports given entity type + // Verify whether hypothesis supports given entity type CORBA::Boolean IsDimSupported( SMESH::Dimension type ); // Methods for copying mesh definition to other geometry