Salome HOME
#16522 [CEA 7599] Viscous layers hypothesis: extract layers as a group
authoreap <eap@opencascade.com>
Fri, 25 Oct 2019 13:55:08 +0000 (16:55 +0300)
committereap <eap@opencascade.com>
Fri, 14 Feb 2020 15:11:56 +0000 (18:11 +0300)
21 files changed:
doc/salome/examples/defining_hypotheses_ex17.py
doc/salome/gui/SMESH/images/viscous_layers_2d_hyp.png
doc/salome/gui/SMESH/images/viscous_layers_hyp.png
doc/salome/gui/SMESH/input/additional_hypo.rst
idl/SMESH_BasicHypothesis.idl
resources/StdMeshers.xml.in
src/SMESHGUI/SMESHGUI_Hypotheses.cxx
src/SMESHGUI/SMESHGUI_Hypotheses.h
src/SMESH_SWIG/smesh_algorithm.py
src/StdMeshers/StdMeshers_ViscousLayers.cxx
src/StdMeshers/StdMeshers_ViscousLayers.hxx
src/StdMeshers/StdMeshers_ViscousLayers2D.cxx
src/StdMeshersGUI/CMakeLists.txt
src/StdMeshersGUI/StdMeshersGUI_NameCheckableGrpWdg.cxx [new file with mode: 0644]
src/StdMeshersGUI/StdMeshersGUI_NameCheckableGrpWdg.h [new file with mode: 0644]
src/StdMeshersGUI/StdMeshersGUI_StdHypothesisCreator.cxx
src/StdMeshersGUI/StdMeshers_msg_en.ts
src/StdMeshers_I/StdMeshers_ViscousLayers2D_i.cxx
src/StdMeshers_I/StdMeshers_ViscousLayers2D_i.hxx
src/StdMeshers_I/StdMeshers_ViscousLayers_i.cxx
src/StdMeshers_I/StdMeshers_ViscousLayers_i.hxx

index f2b7d8c20f4f21207ef87ac3a0e2c92ddcb80820..cadd71e24b0af4b1845677b98dc14820ee67e8d0 100644 (file)
@@ -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()
index 4ad6ee0ec4720ea1ee8c55ead9d8bcdb0cb7946f..f9b952fd7f9379a54d1640e8d1613c7c30ba4039 100644 (file)
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
index aaf9ad6588b7d531709855adedb204795e043562..b7bbffbe63787ec5983c7eea7571eb61a00b98db 100644 (file)
Binary files a/doc/salome/gui/SMESH/images/viscous_layers_hyp.png and b/doc/salome/gui/SMESH/images/viscous_layers_hyp.png differ
index c6665910dcc8a817c06fa0d7863805b0f1bb7400..6fa98f9c29687becdc4a6b4da847f2e9299285af 100644 (file)
@@ -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
 
index 1f9439f0126056287999a2c6c436d00d79b5e995..f75697977414d5f4971d1388f62722dffdde5601 100644 (file)
@@ -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();
   };
 
   /*!
index 5b7f60e4f6117820fd1e8ace67366f1e573e06d2..daf17c96a947655ac1488f875ec3dd02d03f7c31 100644 (file)
         <algo>MEFISTO_2D=Triangle(algo=smeshBuilder.MEFISTO)</algo>
         <hypo>LengthFromEdges=LengthFromEdges()</hypo>
         <hypo>MaxElementArea=MaxElementArea(SetMaxElementArea())</hypo>
-        <hypo>ViscousLayers2D=ViscousLayers2D(SetTotalThickness(),SetNumberLayers(),SetStretchFactor(),SetEdges(1),SetEdges(2))</hypo>
+        <hypo>ViscousLayers2D=ViscousLayers2D(SetTotalThickness(),SetNumberLayers(),SetStretchFactor(),SetEdges(1),SetEdges(2),SetGroupName())</hypo>
       </python-wrap>
     </algorithm>
 
       <python-wrap>
         <algo>Quadrangle_2D=Quadrangle(algo=smeshBuilder.QUADRANGLE)</algo>
         <hypo>QuadrangleParams=QuadrangleParameters(SetQuadType(),SetTriaVertex(),SetEnforcedNodes(1),SetEnforcedNodes(2),SetCorners())</hypo>
-        <hypo>ViscousLayers2D=ViscousLayers2D(SetTotalThickness(),SetNumberLayers(),SetStretchFactor(),SetIgnoreEdges())</hypo>
+        <hypo>ViscousLayers2D=ViscousLayers2D(SetTotalThickness(),SetNumberLayers(),SetStretchFactor(),SetEdges(1),SetEdges(2),SetGroupName())</hypo>
       </python-wrap>
     </algorithm>
 
                dim      ="2">
       <python-wrap>
         <algo>QuadFromMedialAxis_1D2D=Quadrangle(algo=smeshBuilder.QUAD_MA_PROJ)</algo>
-        <hypo>ViscousLayers2D=ViscousLayers2D(SetTotalThickness(),SetNumberLayers(),SetStretchFactor(),SetIgnoreEdges())</hypo>
+        <hypo>ViscousLayers2D=ViscousLayers2D(SetTotalThickness(),SetNumberLayers(),SetStretchFactor(),SetEdges(1),SetEdges(2),SetGroupName())</hypo>
         <hypo>NumberOfLayers2D=NumberOfLayers(SetNumberOfLayers())</hypo>
       </python-wrap>
     </algorithm>
                dim      ="2">
       <python-wrap>
         <algo>PolygonPerFace_2D=Polygon()</algo>
-        <hypo>ViscousLayers2D=ViscousLayers2D(SetTotalThickness(),SetNumberLayers(),SetStretchFactor(),SetIgnoreEdges())</hypo>
+        <hypo>ViscousLayers2D=ViscousLayers2D(SetTotalThickness(),SetNumberLayers(),SetStretchFactor(),SetEdges(1),SetEdges(2),SetGroupName())</hypo>
       </python-wrap>
     </algorithm>
 
                dim      ="3">
       <python-wrap>
         <algo>Hexa_3D=Hexahedron(algo=smeshBuilder.Hexa)</algo>
-        <hypo>ViscousLayers=ViscousLayers(SetTotalThickness(),SetNumberLayers(),SetStretchFactor(),SetFaces(1),SetFaces(2),SetMethod())</hypo>
+        <hypo>ViscousLayers=ViscousLayers(SetTotalThickness(),SetNumberLayers(),SetStretchFactor(),SetFaces(1),SetFaces(2),SetMethod(),SetGroupName())</hypo>
       </python-wrap>
     </algorithm>
 
index 5078f0df74452269da104514faf7822d1a44d2ca..521966bf7980d3941279a6ad2247371e311f3b28 100644 (file)
@@ -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 );
     }
   }
index 454ac1ae363717565bbdc075e68c6d7da603e776..b50f5f128c5c44e3f641ceba02b6b6fc2b145773 100644 (file)
@@ -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<StdParam>      ListOfStdParams;
index f14fa318df19182a454169ee09150ddf0b68f6ce..7603ab2bc21a965fbd0549448e2bdcd85172be7e 100644 (file)
@@ -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
 
index 075d1b46d68c1f32faaff7fac158250546923410..270330be4ed87c7136859482f8130fbd0b2191ac 100644 (file)
@@ -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
 
index 142f35b01fe35d7dbf19f96ead9da20ef277a907..7d7e362fd8863b8650647b28a49c29973b5ac756 100644 (file)
@@ -32,6 +32,8 @@
 
 #include <vector>
 
+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;
index 6248200a732fdfa3beafa93ab7f166942a85422d..a0da0d5270d76d836e93bbb17ebab63ac0ced722 100644 (file)
@@ -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
index 0b8834730210d149cae6e2dee75be59630530fb8..4393778db75d70e17609f5c11a8303ce44caeb7c 100644 (file)
@@ -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 (file)
index 0000000..5ea084b
--- /dev/null
@@ -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 <QGridLayout>
+#include <QLabel>
+#include <QLineEdit>
+
+#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 (file)
index 0000000..334df51
--- /dev/null
@@ -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 <QGroupBox>
+
+#include <omniORB4/CORBA.h>
+
+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
index d477b2fc6b81bb74c3ca5b5a542a38b4e97cb63d..f16b06011819e3d5c59ec359aed926e3fa3de51e 100644 (file)
@@ -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 <SALOMEDSClient_Study.hxx>
@@ -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;
 }
 
index 351aed8f48fb3b3855b47e5536c40840a76c073c..036b28413df4ab84bdf40d9893a629de96f42bf9 100644 (file)
@@ -59,6 +59,14 @@ this one for this mesh/sub-mesh.</translation>
         <source>EXTMETH_FACE_OFFSET</source>
         <translation>Face offset</translation>
     </message>
+    <message>
+        <source>CREATE_GROUPS_FROM_LAYERS</source>
+        <translation>Create groups from layers</translation>
+    </message>
+    <message>
+        <source>GROUP_NAME</source>
+        <translation>Group name</translation>
+    </message>
 </context>
 <context>
     <name>@default</name>
index 376f156b0fb6ded28dc1096fb9dae5413a565011..0e03a4b1f97baf4af3d72a839fcedecac0e79211 100644 (file)
@@ -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
index 49dc69c8e3bd1c7af4516c56026a1c58576ca6fd..56f557c38071becb779e9592a3e160a5a3cf63a8 100644 (file)
@@ -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();
 
index 603ef55c3e9dd77a229e317707165d8c235b77f4..ab47e172574a850d54bf25114faae11a6a83151a 100644 (file)
@@ -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
index ac5f0e1ae83e0b963bc2c8f6d730acd12925e319..47200ce7244033ac0861f69f9745a1094cc46e51 100644 (file)
@@ -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