#16522 [CEA 7599] Viscous layers hypothesis: extract layers as a group

This commit is contained in:
eap 2019-10-25 16:55:08 +03:00
parent bda71f4197
commit 70eb9c09d0
21 changed files with 436 additions and 51 deletions

View File

@ -33,16 +33,22 @@ mesh.Segment().NumberOfSegments( 4 )
mesh.Triangle() mesh.Triangle()
mesh.Quadrangle(face1) mesh.Quadrangle(face1)
mesh.Compute()
algo3D = mesh.Tetrahedron() algo3D = mesh.Tetrahedron()
thickness = 20 thickness = 20
numberOfLayers = 10 numberOfLayers = 10
stretchFactor = 1.5 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() 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("Tetras",SMESH.VOLUME,SMESH.FT_ElemGeomType,"=",SMESH.Geom_TETRA)
mesh.MakeGroup("Pyras",SMESH.VOLUME,SMESH.FT_ElemGeomType,"=",SMESH.Geom_PYRAMID) mesh.MakeGroup("Pyras",SMESH.VOLUME,SMESH.FT_ElemGeomType,"=",SMESH.Geom_PYRAMID)
mesh.MakeGroup("Prims",SMESH.VOLUME,SMESH.FT_ElemGeomType,"=",SMESH.Geom_PENTA) 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 = smesh.Mesh(face1,"VicsousLayers2D")
mesh.Segment().NumberOfSegments( 5 ) mesh.Segment().NumberOfSegments( 5 )
# viscous layers should be created on 1 edge, as we set 3 edges to ignore # 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 ) vlHyp = mesh.Triangle().ViscousLayers2D( 2, 3, 1.5,
edgeIds, isEdgesToIgnore=True, # optional
groupName=groupName) # optional
mesh.Compute() 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 ) vlHyp.SetEdges( edgeIds, False )
mesh.Compute() mesh.Compute()

Binary file not shown.

Before

Width:  |  Height:  |  Size: 26 KiB

After

Width:  |  Height:  |  Size: 32 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 31 KiB

After

Width:  |  Height:  |  Size: 38 KiB

View File

@ -108,6 +108,8 @@ computations.
boundary faces/edges of the shape of this sub-mesh, at same time boundary faces/edges of the shape of this sub-mesh, at same time
possibly being internal faces/edges within the whole model. 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 .. image:: ../images/viscous_layers_on_submesh.png
:align: center :align: center

View File

@ -924,6 +924,9 @@ module StdMeshers
void SetMethod( in VLExtrusionMethod how ); void SetMethod( in VLExtrusionMethod how );
VLExtrusionMethod GetMethod(); VLExtrusionMethod GetMethod();
void SetGroupName(in string name);
string GetGroupName();
}; };
/*! /*!
@ -965,6 +968,9 @@ module StdMeshers
*/ */
void SetStretchFactor(in double factor) raises (SALOME::SALOME_Exception); void SetStretchFactor(in double factor) raises (SALOME::SALOME_Exception);
double GetStretchFactor(); double GetStretchFactor();
void SetGroupName(in string name);
string GetGroupName();
}; };
/*! /*!

View File

@ -318,7 +318,7 @@
<algo>MEFISTO_2D=Triangle(algo=smeshBuilder.MEFISTO)</algo> <algo>MEFISTO_2D=Triangle(algo=smeshBuilder.MEFISTO)</algo>
<hypo>LengthFromEdges=LengthFromEdges()</hypo> <hypo>LengthFromEdges=LengthFromEdges()</hypo>
<hypo>MaxElementArea=MaxElementArea(SetMaxElementArea())</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> </python-wrap>
</algorithm> </algorithm>
@ -335,7 +335,7 @@
<python-wrap> <python-wrap>
<algo>Quadrangle_2D=Quadrangle(algo=smeshBuilder.QUADRANGLE)</algo> <algo>Quadrangle_2D=Quadrangle(algo=smeshBuilder.QUADRANGLE)</algo>
<hypo>QuadrangleParams=QuadrangleParameters(SetQuadType(),SetTriaVertex(),SetEnforcedNodes(1),SetEnforcedNodes(2),SetCorners())</hypo> <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> </python-wrap>
</algorithm> </algorithm>
@ -351,7 +351,7 @@
dim ="2"> dim ="2">
<python-wrap> <python-wrap>
<algo>QuadFromMedialAxis_1D2D=Quadrangle(algo=smeshBuilder.QUAD_MA_PROJ)</algo> <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> <hypo>NumberOfLayers2D=NumberOfLayers(SetNumberOfLayers())</hypo>
</python-wrap> </python-wrap>
</algorithm> </algorithm>
@ -367,7 +367,7 @@
dim ="2"> dim ="2">
<python-wrap> <python-wrap>
<algo>PolygonPerFace_2D=Polygon()</algo> <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> </python-wrap>
</algorithm> </algorithm>
@ -395,7 +395,7 @@
dim ="3"> dim ="3">
<python-wrap> <python-wrap>
<algo>Hexa_3D=Hexahedron(algo=smeshBuilder.Hexa)</algo> <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> </python-wrap>
</algorithm> </algorithm>

View File

@ -185,10 +185,11 @@ QFrame* SMESHGUI_GenericHypothesisCreator::buildStdFrame()
GroupC1Layout->setMargin( MARGIN ); GroupC1Layout->setMargin( MARGIN );
ListOfStdParams::const_iterator anIt = params.begin(), aLast = params.end(); 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 ); QLabel* lab = anIt->hasName() ? new QLabel( anIt->myName, GroupC1 ) : NULL;
GroupC1Layout->addWidget( lab, i, 0 ); if ( lab )
GroupC1Layout->addWidget( lab, i, 0 );
myParamLabels << lab; myParamLabels << lab;
QWidget* w = getCustomWidget( *anIt, GroupC1, i ); QWidget* w = getCustomWidget( *anIt, GroupC1, i );
@ -251,9 +252,12 @@ QFrame* SMESHGUI_GenericHypothesisCreator::buildStdFrame()
default:; default:;
} // switch( (*anIt).myValue.type() ) } // 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 ); changeWidgets().append( w );
} }
} }

View File

@ -92,6 +92,8 @@ protected:
const char* text() const { const char* text() const {
((QByteArray&) myTextAsBytes) = myText.toUtf8(); return myTextAsBytes.constData(); ((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; typedef QList<StdParam> ListOfStdParams;

View File

@ -290,7 +290,8 @@ class Mesh_Algorithm:
return shape.GetStudyEntry() return shape.GetStudyEntry()
def ViscousLayers(self, thickness, numberOfLayers, stretchFactor, 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 Defines "ViscousLayers" hypothesis to give parameters of layers of prisms to build
near mesh boundary. This hypothesis can be used by several 3D algorithms: 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 - StdMeshers.NODE_OFFSET method extrudes nodes along average normal of
surrounding mesh faces by the layers thickness. Thickness of surrounding mesh faces by the layers thickness. Thickness of
layers can be limited to avoid creation of invalid prisms. 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): if not isinstance(self.algo, SMESH._objref_SMESH_3D_Algo):
raise TypeError("ViscousLayers are supported by 3D algorithms only") raise TypeError("ViscousLayers are supported by 3D algorithms only")
if not "ViscousLayers" in self.GetCompatibleHypothesis(): if not "ViscousLayers" in self.GetCompatibleHypothesis():
@ -342,11 +352,12 @@ class Mesh_Algorithm:
hyp.SetStretchFactor( stretchFactor ) hyp.SetStretchFactor( stretchFactor )
hyp.SetFaces( faces, isFacesToIgnore ) hyp.SetFaces( faces, isFacesToIgnore )
hyp.SetMethod( extrMethod ) hyp.SetMethod( extrMethod )
hyp.SetGroupName( groupName )
self.mesh.AddHypothesis( hyp, self.geom ) self.mesh.AddHypothesis( hyp, self.geom )
return hyp return hyp
def ViscousLayers2D(self, thickness, numberOfLayers, stretchFactor, def ViscousLayers2D(self, thickness, numberOfLayers, stretchFactor,
edges=[], isEdgesToIgnore=True ): edges=[], isEdgesToIgnore=True, groupName="" ):
""" """
Defines "ViscousLayers2D" hypothesis to give parameters of layers of quadrilateral 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: 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. the value of **isEdgesToIgnore** parameter.
isEdgesToIgnore: if *True*, the Viscous layers are not generated on the isEdgesToIgnore: if *True*, the Viscous layers are not generated on the
edges specified by the previous parameter (**edges**). 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): if not isinstance(self.algo, SMESH._objref_SMESH_2D_Algo):
@ -383,6 +403,7 @@ class Mesh_Algorithm:
hyp.SetNumberLayers(numberOfLayers) hyp.SetNumberLayers(numberOfLayers)
hyp.SetStretchFactor(stretchFactor) hyp.SetStretchFactor(stretchFactor)
hyp.SetEdges(edges, isEdgesToIgnore) hyp.SetEdges(edges, isEdgesToIgnore)
hyp.SetGroupName( groupName )
self.mesh.AddHypothesis( hyp, self.geom ) self.mesh.AddHypothesis( hyp, self.geom )
return hyp return hyp

View File

@ -612,12 +612,16 @@ namespace VISCOUS_3D
_thickness = Max( _thickness, hyp->GetTotalThickness() ); _thickness = Max( _thickness, hyp->GetTotalThickness() );
_stretchFactor += hyp->GetStretchFactor(); _stretchFactor += hyp->GetStretchFactor();
_method = hyp->GetMethod(); _method = hyp->GetMethod();
if ( _groupName.empty() )
_groupName = hyp->GetGroupName();
} }
} }
double GetTotalThickness() const { return _thickness; /*_nbHyps ? _thickness / _nbHyps : 0;*/ } double GetTotalThickness() const { return _thickness; /*_nbHyps ? _thickness / _nbHyps : 0;*/ }
double GetStretchFactor() const { return _nbHyps ? _stretchFactor / _nbHyps : 0; } double GetStretchFactor() const { return _nbHyps ? _stretchFactor / _nbHyps : 0; }
int GetNumberLayers() const { return _nbLayers; } int GetNumberLayers() const { return _nbLayers; }
int GetMethod() const { return _method; } int GetMethod() const { return _method; }
bool ToCreateGroup() const { return !_groupName.empty(); }
const std::string& GetGroupName() const { return _groupName; }
bool UseSurfaceNormal() const bool UseSurfaceNormal() const
{ return _method == StdMeshers_ViscousLayers::SURF_OFFSET_SMOOTH; } { 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 ); } static bool Equals( double v1, double v2 ) { return Abs( v1 - v2 ) < 0.01 * ( v1 + v2 ); }
private: private:
int _nbLayers, _nbHyps, _method; int _nbLayers, _nbHyps, _method;
double _thickness, _stretchFactor; double _thickness, _stretchFactor;
std::string _groupName;
}; };
//-------------------------------------------------------------------------------- //--------------------------------------------------------------------------------
@ -1247,7 +1252,8 @@ namespace VISCOUS_3D
StdMeshers_ViscousLayers::StdMeshers_ViscousLayers(int hypId, SMESH_Gen* gen) StdMeshers_ViscousLayers::StdMeshers_ViscousLayers(int hypId, SMESH_Gen* gen)
:SMESH_Hypothesis(hypId, gen), :SMESH_Hypothesis(hypId, gen),
_isToIgnoreShapes(1), _nbLayers(1), _thickness(1), _stretchFactor(1), _isToIgnoreShapes(1), _nbLayers(1), _thickness(1), _stretchFactor(1),
_method( SURF_OFFSET_SMOOTH ) _method( SURF_OFFSET_SMOOTH ),
_groupName("")
{ {
_name = StdMeshers_ViscousLayers::GetHypType(); _name = StdMeshers_ViscousLayers::GetHypType();
_param_algo_dim = -3; // auxiliary hyp used by 3D algos _param_algo_dim = -3; // auxiliary hyp used by 3D algos
@ -1279,6 +1285,15 @@ void StdMeshers_ViscousLayers::SetMethod( ExtrusionMethod method )
if ( _method != method ) if ( _method != method )
_method = method, NotifySubMeshesHypothesisModification(); _method = method, NotifySubMeshesHypothesisModification();
} // -------------------------------------------------------------------------------- } // --------------------------------------------------------------------------------
void StdMeshers_ViscousLayers::SetGroupName(const std::string& name)
{
if ( _groupName != name )
{
_groupName = name;
if ( !_groupName.empty() )
NotifySubMeshesHypothesisModification();
}
} // --------------------------------------------------------------------------------
SMESH_ProxyMesh::Ptr SMESH_ProxyMesh::Ptr
StdMeshers_ViscousLayers::Compute(SMESH_Mesh& theMesh, StdMeshers_ViscousLayers::Compute(SMESH_Mesh& theMesh,
const TopoDS_Shape& theShape, const TopoDS_Shape& theShape,
@ -1333,6 +1348,9 @@ std::ostream & StdMeshers_ViscousLayers::SaveTo(std::ostream & save)
save << " " << _shapeIds[i]; save << " " << _shapeIds[i];
save << " " << !_isToIgnoreShapes; // negate to keep the behavior in old studies. save << " " << !_isToIgnoreShapes; // negate to keep the behavior in old studies.
save << " " << _method; save << " " << _method;
save << " " << _groupName.size();
if ( !_groupName.empty() )
save << " " << _groupName;
return save; return save;
} // -------------------------------------------------------------------------------- } // --------------------------------------------------------------------------------
std::istream & StdMeshers_ViscousLayers::LoadFrom(std::istream & load) std::istream & StdMeshers_ViscousLayers::LoadFrom(std::istream & load)
@ -1345,6 +1363,13 @@ std::istream & StdMeshers_ViscousLayers::LoadFrom(std::istream & load)
_isToIgnoreShapes = !shapeToTreat; _isToIgnoreShapes = !shapeToTreat;
if ( load >> method ) if ( load >> method )
_method = (ExtrusionMethod) 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 { else {
_isToIgnoreShapes = true; // old behavior _isToIgnoreShapes = true; // old behavior
@ -1378,6 +1403,36 @@ bool StdMeshers_ViscousLayers::IsShapeWithLayers(int shapeIndex) const
( std::find( _shapeIds.begin(), _shapeIds.end(), shapeIndex ) != _shapeIds.end() ); ( std::find( _shapeIds.begin(), _shapeIds.end(), shapeIndex ) != _shapeIds.end() );
return IsToIgnoreShapes() ? !isIn : isIn; 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 // END StdMeshers_ViscousLayers hypothesis
//================================================================================ //================================================================================
@ -10230,6 +10285,11 @@ bool _ViscousBuilder::refine(_SolidData& data)
const TGeomID faceID = getMeshDS()->ShapeToIndex( exp.Current() ); const TGeomID faceID = getMeshDS()->ShapeToIndex( exp.Current() );
if ( data._ignoreFaceIds.count( faceID )) if ( data._ignoreFaceIds.count( faceID ))
continue; 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 ); const bool isReversedFace = data._reversedFaceIds.count( faceID );
SMESHDS_SubMesh* fSubM = getMeshDS()->MeshElements( exp.Current() ); SMESHDS_SubMesh* fSubM = getMeshDS()->MeshElements( exp.Current() );
SMDS_ElemIteratorPtr fIt = fSubM->GetElements(); SMDS_ElemIteratorPtr fIt = fSubM->GetElements();
@ -10260,14 +10320,20 @@ bool _ViscousBuilder::refine(_SolidData& data)
if ( 0 < nnSet.size() && nnSet.size() < 3 ) if ( 0 < nnSet.size() && nnSet.size() < 3 )
continue; continue;
vols.clear();
const SMDS_MeshElement* vol;
switch ( nbNodes ) switch ( nbNodes )
{ {
case 3: // TRIA case 3: // TRIA
{ {
// PENTA // PENTA
for ( size_t iZ = 1; iZ < minZ; ++iZ ) 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 ) for ( size_t iZ = minZ; iZ < maxZ; ++iZ )
{ {
@ -10280,16 +10346,18 @@ bool _ViscousBuilder::refine(_SolidData& data)
int i2 = *degenEdgeInd.begin(); int i2 = *degenEdgeInd.begin();
int i0 = helper.WrapIndex( i2 - 1, nbNodes ); int i0 = helper.WrapIndex( i2 - 1, nbNodes );
int i1 = helper.WrapIndex( i2 + 1, nbNodes ); int i1 = helper.WrapIndex( i2 + 1, nbNodes );
helper.AddVolume( (*nnVec[i0])[iZ-1], (*nnVec[i1])[iZ-1], vol = helper.AddVolume( (*nnVec[i0])[iZ-1], (*nnVec[i1])[iZ-1],
(*nnVec[i1])[iZ ], (*nnVec[i0])[iZ ], (*nnVec[i2]).back()); (*nnVec[i1])[iZ ], (*nnVec[i0])[iZ ], (*nnVec[i2]).back());
vols.push_back( vol );
} }
else // TETRA else // TETRA
{ {
int i3 = !degenEdgeInd.count(0) ? 0 : !degenEdgeInd.count(1) ? 1 : 2; int i3 = !degenEdgeInd.count(0) ? 0 : !degenEdgeInd.count(1) ? 1 : 2;
helper.AddVolume( (*nnVec[ 0 ])[ i3 == 0 ? iZ-1 : nnVec[0]->size()-1 ], vol = helper.AddVolume( (*nnVec[ 0 ])[ i3 == 0 ? iZ-1 : nnVec[0]->size()-1 ],
(*nnVec[ 1 ])[ i3 == 1 ? iZ-1 : nnVec[1]->size()-1 ], (*nnVec[ 1 ])[ i3 == 1 ? iZ-1 : nnVec[1]->size()-1 ],
(*nnVec[ 2 ])[ i3 == 2 ? iZ-1 : nnVec[2]->size()-1 ], (*nnVec[ 2 ])[ i3 == 2 ? iZ-1 : nnVec[2]->size()-1 ],
(*nnVec[ i3 ])[ iZ ]); (*nnVec[ i3 ])[ iZ ]);
vols.push_back( vol );
} }
} }
break; // TRIA break; // TRIA
@ -10298,10 +10366,13 @@ bool _ViscousBuilder::refine(_SolidData& data)
{ {
// HEX // HEX
for ( size_t iZ = 1; iZ < minZ; ++iZ ) 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], vol = helper.AddVolume( (*nnVec[0])[iZ-1], (*nnVec[1])[iZ-1],
(*nnVec[0])[iZ], (*nnVec[1])[iZ], (*nnVec[2])[iZ-1], (*nnVec[3])[iZ-1],
(*nnVec[2])[iZ], (*nnVec[3])[iZ]); (*nnVec[0])[iZ], (*nnVec[1])[iZ],
(*nnVec[2])[iZ], (*nnVec[3])[iZ]);
vols.push_back( vol );
}
for ( size_t iZ = minZ; iZ < maxZ; ++iZ ) 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 i0 = helper.WrapIndex( i3 + 1, nbNodes );
int i1 = helper.WrapIndex( i0 + 1, nbNodes ); int i1 = helper.WrapIndex( i0 + 1, nbNodes );
const SMDS_MeshElement* vol = vol = helper.AddVolume( nnVec[i3]->back(), (*nnVec[i0])[iZ], (*nnVec[i0])[iZ-1],
helper.AddVolume( nnVec[i3]->back(), (*nnVec[i0])[iZ], (*nnVec[i0])[iZ-1], nnVec[i2]->back(), (*nnVec[i1])[iZ], (*nnVec[i1])[iZ-1]);
nnVec[i2]->back(), (*nnVec[i1])[iZ], (*nnVec[i1])[iZ-1]); vols.push_back( vol );
if ( !ok && vol ) if ( !ok && vol )
degenVols.push_back( vol ); degenVols.push_back( vol );
} }
@ -10330,15 +10401,15 @@ bool _ViscousBuilder::refine(_SolidData& data)
default: // degen HEX default: // degen HEX
{ {
const SMDS_MeshElement* vol = vol = helper.AddVolume( nnVec[0]->size() > iZ-1 ? (*nnVec[0])[iZ-1] : nnVec[0]->back(),
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[1]->size() > iZ-1 ? (*nnVec[1])[iZ-1] : nnVec[1]->back(), nnVec[2]->size() > iZ-1 ? (*nnVec[2])[iZ-1] : nnVec[2]->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[3]->size() > iZ-1 ? (*nnVec[3])[iZ-1] : nnVec[3]->back(), nnVec[0]->size() > iZ ? (*nnVec[0])[iZ] : nnVec[0]->back(),
nnVec[0]->size() > iZ ? (*nnVec[0])[iZ] : nnVec[0]->back(), nnVec[1]->size() > iZ ? (*nnVec[1])[iZ] : nnVec[1]->back(),
nnVec[1]->size() > iZ ? (*nnVec[1])[iZ] : nnVec[1]->back(), nnVec[2]->size() > iZ ? (*nnVec[2])[iZ] : nnVec[2]->back(),
nnVec[2]->size() > iZ ? (*nnVec[2])[iZ] : nnVec[2]->back(), nnVec[3]->size() > iZ ? (*nnVec[3])[iZ] : nnVec[3]->back());
nnVec[3]->size() > iZ ? (*nnVec[3])[iZ] : nnVec[3]->back()); vols.push_back( vol );
degenVols.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); return error("Not supported type of element", data._index);
} // switch ( nbNodes ) } // switch ( nbNodes )
if ( group )
for ( size_t i = 0; i < vols.size(); ++i )
group->Add( vols[ i ]);
} // while ( fIt->more() ) } // while ( fIt->more() )
} // loop on FACEs } // loop on FACEs

View File

@ -32,6 +32,8 @@
#include <vector> #include <vector>
class SMDS_MeshGroup;
/*! /*!
* \brief Hypothesis defining parameters of viscous layers * \brief Hypothesis defining parameters of viscous layers
*/ */
@ -73,6 +75,13 @@ public:
void SetMethod( ExtrusionMethod how ); void SetMethod( ExtrusionMethod how );
ExtrusionMethod GetMethod() const { return _method; } 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. // Computes temporary 2D mesh to be used by 3D algorithm.
// Return SMESH_ProxyMesh for each SOLID in theShape // Return SMESH_ProxyMesh for each SOLID in theShape
SMESH_ProxyMesh::Ptr Compute(SMESH_Mesh& theMesh, SMESH_ProxyMesh::Ptr Compute(SMESH_Mesh& theMesh,
@ -116,6 +125,7 @@ public:
double _thickness; double _thickness;
double _stretchFactor; double _stretchFactor;
ExtrusionMethod _method; ExtrusionMethod _method;
std::string _groupName;
}; };
class SMESH_subMesh; class SMESH_subMesh;

View File

@ -2402,6 +2402,17 @@ bool _ViscousBuilder2D::refine()
outerNodes.swap( innerNodes ); 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) // faces between not shared _LayerEdge's (at concave VERTEX)
for ( int isR = 0; isR < 2; ++isR ) for ( int isR = 0; isR < 2; ++isR )
{ {
@ -2413,15 +2424,22 @@ bool _ViscousBuilder2D::refine()
if ( lNodes.empty() || rNodes.empty() || lNodes.size() != rNodes.size() ) if ( lNodes.empty() || rNodes.empty() || lNodes.size() != rNodes.size() )
continue; continue;
const SMDS_MeshElement* face = 0;
for ( size_t i = 1; i < lNodes.size(); ++i ) 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 ]; const UVPtStruct& ptOnVertex = points[ isR ? L._lastPntInd : L._firstPntInd ];
if ( isReverse ) if ( isReverse )
_helper.AddFace( ptOnVertex.node, lNodes[ 0 ], rNodes[ 0 ]); face = _helper.AddFace( ptOnVertex.node, lNodes[ 0 ], rNodes[ 0 ]);
else 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 // Fill the _ProxyMeshOfFace

View File

@ -82,6 +82,7 @@ SET(_moc_HEADERS
StdMeshersGUI_CartesianParamCreator.h StdMeshersGUI_CartesianParamCreator.h
StdMeshersGUI_RadioButtonsGrpWdg.h StdMeshersGUI_RadioButtonsGrpWdg.h
StdMeshersGUI_PropagationHelperWdg.h StdMeshersGUI_PropagationHelperWdg.h
StdMeshersGUI_NameCheckableGrpWdg.h
) )
IF(SALOME_USE_PLOT2DVIEWER) IF(SALOME_USE_PLOT2DVIEWER)
@ -117,6 +118,7 @@ SET(_other_SOURCES
StdMeshersGUI_CartesianParamCreator.cxx StdMeshersGUI_CartesianParamCreator.cxx
StdMeshersGUI_RadioButtonsGrpWdg.cxx StdMeshersGUI_RadioButtonsGrpWdg.cxx
StdMeshersGUI_PropagationHelperWdg.cxx StdMeshersGUI_PropagationHelperWdg.cxx
StdMeshersGUI_NameCheckableGrpWdg.cxx
) )
IF(SALOME_USE_PLOT2DVIEWER) IF(SALOME_USE_PLOT2DVIEWER)

View File

@ -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() );
}

View File

@ -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

View File

@ -39,6 +39,7 @@
#include "StdMeshersGUI_PropagationHelperWdg.h" #include "StdMeshersGUI_PropagationHelperWdg.h"
#include "StdMeshersGUI_QuadrangleParamWdg.h" #include "StdMeshersGUI_QuadrangleParamWdg.h"
#include "StdMeshersGUI_RadioButtonsGrpWdg.h" #include "StdMeshersGUI_RadioButtonsGrpWdg.h"
#include "StdMeshersGUI_NameCheckableGrpWdg.h"
#include "StdMeshersGUI_SubShapeSelectorWdg.h" #include "StdMeshersGUI_SubShapeSelectorWdg.h"
#include <SALOMEDSClient_Study.hxx> #include <SALOMEDSClient_Study.hxx>
@ -728,6 +729,12 @@ QString StdMeshersGUI_StdHypothesisCreator::storeParams() const
{ {
h->SetFaces( idsWg->GetListOfIDs(), params[4].myValue.toInt() ); 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" ) else if( hypType()=="ViscousLayers2D" )
{ {
@ -746,6 +753,12 @@ QString StdMeshersGUI_StdHypothesisCreator::storeParams() const
{ {
h->SetEdges( idsWg->GetListOfIDs(), params[3].myValue.toInt() ); 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" ) // else if( hypType()=="QuadrangleParams" )
// { // {
@ -1250,6 +1263,19 @@ bool StdMeshersGUI_StdHypothesisCreator::stdParams( ListOfStdParams& p ) const
} }
customWidgets()->append ( idsWg ); 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" ) else if( hypType()=="ViscousLayers2D" )
{ {
@ -1308,6 +1334,19 @@ bool StdMeshersGUI_StdHypothesisCreator::stdParams( ListOfStdParams& p ) const
} }
customWidgets()->append ( idsWg ); 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 else
res = false; res = false;
@ -1574,6 +1613,10 @@ bool StdMeshersGUI_StdHypothesisCreator::getParamFromCustomWidget( StdParam & pa
param.myValue = w->checkedId(); param.myValue = w->checkedId();
return true; return true;
} }
if ( widget->inherits( "StdMeshersGUI_NameCheckableGrpWdg" ))
{
return true;
}
return false; return false;
} }

View File

@ -59,6 +59,14 @@ this one for this mesh/sub-mesh.</translation>
<source>EXTMETH_FACE_OFFSET</source> <source>EXTMETH_FACE_OFFSET</source>
<translation>Face offset</translation> <translation>Face offset</translation>
</message> </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>
<context> <context>
<name>@default</name> <name>@default</name>

View File

@ -222,6 +222,33 @@ throw ( SALOME::SALOME_Exception )
return GetImpl()->GetStretchFactor(); 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 * Get implementation

View File

@ -64,6 +64,10 @@ class STDMESHERS_I_EXPORT StdMeshers_ViscousLayers2D_i:
void SetStretchFactor(::CORBA::Double factor) throw ( SALOME::SALOME_Exception ); void SetStretchFactor(::CORBA::Double factor) throw ( SALOME::SALOME_Exception );
::CORBA::Double GetStretchFactor(); ::CORBA::Double GetStretchFactor();
void SetGroupName(const char* name);
char* GetGroupName();
// Get implementation // Get implementation
::StdMeshers_ViscousLayers2D* GetImpl(); ::StdMeshers_ViscousLayers2D* GetImpl();

View File

@ -253,6 +253,32 @@ void StdMeshers_ViscousLayers_i::SetMethod( ::StdMeshers::VLExtrusionMethod how
return (::StdMeshers::VLExtrusionMethod) GetImpl()->GetMethod(); 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 * Get implementation

View File

@ -67,10 +67,14 @@ class STDMESHERS_I_EXPORT StdMeshers_ViscousLayers_i:
void SetMethod( ::StdMeshers::VLExtrusionMethod how ); void SetMethod( ::StdMeshers::VLExtrusionMethod how );
::StdMeshers::VLExtrusionMethod GetMethod(); ::StdMeshers::VLExtrusionMethod GetMethod();
void SetGroupName(const char* name);
char* GetGroupName();
// Get implementation // Get implementation
::StdMeshers_ViscousLayers* GetImpl(); ::StdMeshers_ViscousLayers* GetImpl();
// Verify whether hypothesis supports given entity type // Verify whether hypothesis supports given entity type
CORBA::Boolean IsDimSupported( SMESH::Dimension type ); CORBA::Boolean IsDimSupported( SMESH::Dimension type );
// Methods for copying mesh definition to other geometry // Methods for copying mesh definition to other geometry