22834: [CEA 1347] Viscous layers: be able to choose the extrusion method
BIN
doc/salome/gui/SMESH/images/viscous_layers_2d_hyp.png
Normal file
After Width: | Height: | Size: 26 KiB |
BIN
doc/salome/gui/SMESH/images/viscous_layers_extrusion_method.png
Normal file
After Width: | Height: | Size: 4.8 KiB |
Before Width: | Height: | Size: 50 KiB After Width: | Height: | Size: 31 KiB |
@ -75,12 +75,29 @@ computations.
|
||||
|
||||
\image html viscous_layers_hyp.png
|
||||
|
||||
\image html viscous_layers_2d_hyp.png
|
||||
|
||||
<ul>
|
||||
<li><b>Name</b> - allows to define the name of the hypothesis.</li>
|
||||
<li><b>Total thickness</b> - gives the total thickness of element layers.</li>
|
||||
<li><b>Number of layers</b> - defines the number of element layers.</li>
|
||||
<li><b>Stretch factor</b> - defines the growth factor of element height
|
||||
from the mesh boundary inwards.</li>
|
||||
<li><b>Extrusion method</b> (available in 3D only) - defines how
|
||||
position of nodes are found during prism construction and how
|
||||
creation of distorted and intersecting prisms is prevented.
|
||||
<ul><li><b>Surface offset + smooth</b> method extrudes nodes along normal
|
||||
to underlying geometrical surface. Smoothing of internal surface of
|
||||
element layers is possible to avoid creation of invalid prisms.</li>
|
||||
<li><b>Face offset</b> method extrudes nodes along average normal of
|
||||
surrounding mesh faces till intersection with a neighbor mesh face
|
||||
translated along its own normal by the layers thickness. Thickness
|
||||
of layers can be limited to avoid creation of invalid prisms.</li>
|
||||
<li><b>Node offset</b> 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.</li>
|
||||
\image html viscous_layers_extrusion_method.png "Prisms created by the tree extrusion methods at the same other parameters"
|
||||
</ul></li>
|
||||
<li><b>Specified Faces/Edges are</b> - defines how the shapes specified by
|
||||
the next parameter are used.
|
||||
<li><b> Faces/Edges with/without layers</b> -
|
||||
@ -90,11 +107,15 @@ computations.
|
||||
Faces (or edges) can be selected either in the Object Browser or in
|
||||
the VTK Viewer.
|
||||
\note A mesh shown in the 3D Viewer can prevent selection of faces
|
||||
and edges, just hide the mesh to avoid this. To avoid a long wait when a
|
||||
and edges, just hide the mesh to avoid this. Sometimes a face to
|
||||
select is hidden by other faces, in this case consider creating a
|
||||
group of faces you want to select in the Geometry module.<br>
|
||||
To avoid a long wait when a
|
||||
geometry with many faces (or edges) is displayed, the number of faces
|
||||
(edges) shown at a time is limited by the value of "Sub-shapes
|
||||
preview chunk size" preference (in Preferences/Mesh/General tab).
|
||||
|
||||
|
||||
If faces/edges without layers are specified, the element layers are
|
||||
not constructed on geometrical faces shared by several solids in 3D
|
||||
case and edges shared by several faces in 2D case. In other words,
|
||||
|
@ -857,6 +857,21 @@ module StdMeshers
|
||||
void GetCopySourceMesh(out boolean toCopyMesh,out boolean toCopyGroups);
|
||||
};
|
||||
|
||||
/*!
|
||||
* Method of computing translation of a node at Viscous Layers construction
|
||||
*/
|
||||
enum VLExtrusionMethod {
|
||||
// node is translated along normal to a surface with possible further smoothing
|
||||
SURF_OFFSET_SMOOTH,
|
||||
// node is translated along the average normal of surrounding faces till
|
||||
// intersection with a neighbor face translated along its own normal
|
||||
// by the layers thickness
|
||||
FACE_OFFSET,
|
||||
// node is translated along the average normal of surrounding faces
|
||||
// by the layers thickness
|
||||
NODE_OFFSET
|
||||
};
|
||||
|
||||
/*!
|
||||
* interface of "Viscous Layers" hypothesis.
|
||||
* This hypothesis specifies parameters of layers of prisms to build
|
||||
@ -896,6 +911,9 @@ module StdMeshers
|
||||
*/
|
||||
void SetStretchFactor(in double factor) raises (SALOME::SALOME_Exception);
|
||||
double GetStretchFactor();
|
||||
|
||||
void SetMethod( in VLExtrusionMethod how );
|
||||
VLExtrusionMethod GetMethod();
|
||||
};
|
||||
|
||||
/*!
|
||||
|
@ -215,6 +215,9 @@ SET(SMESH_RESOURCES_FILES
|
||||
mesh_measure_length.png
|
||||
mesh_measure_area.png
|
||||
mesh_measure_volume.png
|
||||
mesh_extmeth_node_offset.png
|
||||
mesh_extmeth_surf_offset_smooth.png
|
||||
mesh_extmeth_face_offset.png
|
||||
)
|
||||
|
||||
INSTALL(FILES ${SMESH_RESOURCES_FILES} DESTINATION ${SALOME_SMESH_INSTALL_RES_DATA})
|
||||
|
@ -321,7 +321,7 @@
|
||||
dim ="3">
|
||||
<python-wrap>
|
||||
<algo>Hexa_3D=Hexahedron(algo=smeshBuilder.Hexa)</algo>
|
||||
<hypo>ViscousLayers=ViscousLayers(SetTotalThickness(),SetNumberLayers(),SetStretchFactor(),SetIgnoreFaces())</hypo>
|
||||
<hypo>ViscousLayers=ViscousLayers(SetTotalThickness(),SetNumberLayers(),SetStretchFactor(),SetFaces(1),SetFaces(2),SetMethod())</hypo>
|
||||
</python-wrap>
|
||||
</algorithm>
|
||||
|
||||
|
BIN
resources/mesh_extmeth_face_offset.png
Normal file
After Width: | Height: | Size: 257 B |
BIN
resources/mesh_extmeth_node_offset.png
Normal file
After Width: | Height: | Size: 284 B |
BIN
resources/mesh_extmeth_surf_offset_smooth.png
Normal file
After Width: | Height: | Size: 352 B |
@ -566,7 +566,7 @@ bool SMESH_Algo::IsStraight( const TopoDS_Edge & E,
|
||||
if ( v1Len < std::numeric_limits< double >::min() )
|
||||
return false; // E seems closed
|
||||
const double tol = Min( 10 * curve.Tolerance(), v1Len * 1e-2 );
|
||||
const int nbSamples = 7;
|
||||
const double nbSamples = 7;
|
||||
for ( int i = 0; i < nbSamples; ++i )
|
||||
{
|
||||
const double r = ( i + 1 ) / nbSamples;
|
||||
|
@ -2777,7 +2777,7 @@ void _pyHypothesis::Process( const Handle(_pyCommand)& theCommand)
|
||||
myArgCommands.push_back( theCommand );
|
||||
usedCommand = true;
|
||||
while ( crMethod.myArgs.size() < i+1 )
|
||||
crMethod.myArgs.push_back( "[]" );
|
||||
crMethod.myArgs.push_back( "None" );
|
||||
crMethod.myArgs[ i ] = theCommand->GetArg( crMethod.myArgNb[i] );
|
||||
}
|
||||
}
|
||||
|
@ -43,8 +43,9 @@ QUADRANGLE = "Quadrangle_2D"
|
||||
## Algorithm type: Radial Quadrangle 1D-2D algorithm, see StdMeshersBuilder_RadialQuadrangle1D2D
|
||||
RADIAL_QUAD = "RadialQuadrangle_1D2D"
|
||||
|
||||
# import items of enum QuadType
|
||||
# import items of enums
|
||||
for e in StdMeshers.QuadType._items: exec('%s = StdMeshers.%s'%(e,e))
|
||||
for e in StdMeshers.VLExtrusionMethod._items: exec('%s = StdMeshers.%s'%(e,e))
|
||||
|
||||
#----------------------
|
||||
# Algorithms
|
||||
|
@ -23,7 +23,7 @@
|
||||
|
||||
import salome
|
||||
from salome.geom import geomBuilder
|
||||
import SMESH
|
||||
import SMESH, StdMeshers
|
||||
|
||||
## The base class to define meshing algorithms
|
||||
#
|
||||
@ -266,9 +266,22 @@ class Mesh_Algorithm:
|
||||
# the value of \a isFacesToIgnore parameter.
|
||||
# @param isFacesToIgnore if \c True, the Viscous layers are not generated on the
|
||||
# faces specified by the previous parameter (\a faces).
|
||||
# @param extrMethod extrusion method defines how position of nodes are found during
|
||||
# prism construction and how creation of distorted and intersecting prisms is
|
||||
# prevented. Possible values are:
|
||||
# - StdMeshers.SURF_OFFSET_SMOOTH (default) method extrudes nodes along normal
|
||||
# to underlying geometrical surface. Smoothing of internal surface of
|
||||
# element layers can be used to avoid creation of invalid prisms.
|
||||
# - StdMeshers.FACE_OFFSET method extrudes nodes along average normal of
|
||||
# surrounding mesh faces till intersection with a neighbor mesh face
|
||||
# translated along its own normal by the layers thickness. Thickness
|
||||
# of layers can be limited to avoid creation of invalid prisms.
|
||||
# - 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.
|
||||
# @ingroup l3_hypos_additi
|
||||
def ViscousLayers(self, thickness, numberOfLayers, stretchFactor,
|
||||
faces=[], isFacesToIgnore=True ):
|
||||
faces=[], isFacesToIgnore=True, extrMethod=StdMeshers.SURF_OFFSET_SMOOTH ):
|
||||
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():
|
||||
@ -285,10 +298,11 @@ class Mesh_Algorithm:
|
||||
hyp = self.Hypothesis("ViscousLayers",
|
||||
[thickness, numberOfLayers, stretchFactor, faces, isFacesToIgnore],
|
||||
toAdd=False)
|
||||
hyp.SetTotalThickness(thickness)
|
||||
hyp.SetNumberLayers(numberOfLayers)
|
||||
hyp.SetStretchFactor(stretchFactor)
|
||||
hyp.SetFaces(faces, isFacesToIgnore)
|
||||
hyp.SetTotalThickness( thickness )
|
||||
hyp.SetNumberLayers( numberOfLayers )
|
||||
hyp.SetStretchFactor( stretchFactor )
|
||||
hyp.SetFaces( faces, isFacesToIgnore )
|
||||
hyp.SetMethod( extrMethod )
|
||||
self.mesh.AddHypothesis( hyp, self.geom )
|
||||
return hyp
|
||||
|
||||
|
@ -58,6 +58,21 @@ public:
|
||||
void SetStretchFactor(double factor);
|
||||
double GetStretchFactor() const { return _stretchFactor; }
|
||||
|
||||
// Method of computing node translation
|
||||
enum ExtrusionMethod {
|
||||
// node is translated along normal to a surface with possible further smoothing
|
||||
SURF_OFFSET_SMOOTH,
|
||||
// node is translated along the average normal of surrounding faces till
|
||||
// intersection with a neighbor face translated along its own normal
|
||||
// by the layers thickness
|
||||
FACE_OFFSET,
|
||||
// node is translated along the average normal of surrounding faces
|
||||
// by the layers thickness
|
||||
NODE_OFFSET
|
||||
};
|
||||
void SetMethod( ExtrusionMethod how );
|
||||
ExtrusionMethod GetMethod() const { return _method; }
|
||||
|
||||
// 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,
|
||||
@ -81,8 +96,6 @@ public:
|
||||
* \param theMesh - the built mesh
|
||||
* \param theShape - the geometry of interest
|
||||
* \retval bool - true if parameter values have been successfully defined
|
||||
*
|
||||
* Just return false as this hypothesis does not have parameters values
|
||||
*/
|
||||
virtual bool SetParametersByMesh(const SMESH_Mesh* theMesh, const TopoDS_Shape& theShape);
|
||||
|
||||
@ -102,6 +115,7 @@ public:
|
||||
int _nbLayers;
|
||||
double _thickness;
|
||||
double _stretchFactor;
|
||||
ExtrusionMethod _method;
|
||||
};
|
||||
|
||||
class SMESH_subMesh;
|
||||
|
@ -18,7 +18,12 @@
|
||||
//
|
||||
#include "StdMeshersGUI_RadioButtonsGrpWdg.h"
|
||||
|
||||
#include <QVBoxLayout>
|
||||
#include "SMESHGUI.h"
|
||||
|
||||
#include <SUIT_ResourceMgr.h>
|
||||
|
||||
#include <QGridLayout>
|
||||
#include <QLabel>
|
||||
#include <QRadioButton>
|
||||
#include <QButtonGroup>
|
||||
#include <QStringList>
|
||||
@ -44,17 +49,28 @@ StdMeshersGUI_RadioButtonsGrpWdg::StdMeshersGUI_RadioButtonsGrpWdg( const QStrin
|
||||
*/
|
||||
//================================================================================
|
||||
|
||||
void StdMeshersGUI_RadioButtonsGrpWdg::setButtonLabels( const QStringList& buttonLabels )
|
||||
void StdMeshersGUI_RadioButtonsGrpWdg::setButtonLabels( const QStringList& buttonLabels,
|
||||
const QStringList& buttonIcons )
|
||||
{
|
||||
QVBoxLayout* layout = new QVBoxLayout( this );
|
||||
QGridLayout* layout = new QGridLayout( this );
|
||||
layout->setSpacing(SPACING);
|
||||
layout->setMargin(MARGIN);
|
||||
|
||||
for ( int id = 0; id < buttonLabels.size(); ++id )
|
||||
{
|
||||
QRadioButton* button = new QRadioButton( buttonLabels.at(id), this );
|
||||
layout->addWidget( button );
|
||||
layout->addWidget( button, id, 0 );
|
||||
myButtonGrp->addButton( button, id );
|
||||
|
||||
if ( id < buttonIcons.count() )
|
||||
{
|
||||
QPixmap pmi (SMESHGUI::resourceMgr()->loadPixmap("SMESH", buttonIcons.at(id)));
|
||||
if ( !pmi.isNull() ) {
|
||||
QLabel* pixLabel = new QLabel( this );
|
||||
pixLabel->setPixmap( pmi );
|
||||
layout->addWidget( pixLabel, id, 1 );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -38,7 +38,8 @@ class STDMESHERSGUI_EXPORT StdMeshersGUI_RadioButtonsGrpWdg : public QGroupBox
|
||||
public:
|
||||
StdMeshersGUI_RadioButtonsGrpWdg (const QString& title);
|
||||
|
||||
void setButtonLabels( const QStringList& buttonLabels );
|
||||
void setButtonLabels( const QStringList& buttonLabels,
|
||||
const QStringList& buttonIcons=QStringList());
|
||||
|
||||
void setChecked(int id);
|
||||
|
||||
|
@ -714,17 +714,18 @@ QString StdMeshersGUI_StdHypothesisCreator::storeParams() const
|
||||
StdMeshers::StdMeshers_ViscousLayers_var h =
|
||||
StdMeshers::StdMeshers_ViscousLayers::_narrow( hypothesis() );
|
||||
|
||||
h->SetVarParameter( params[0].text(), "SetTotalThickness" );
|
||||
h->SetVarParameter ( params[0].text(), "SetTotalThickness" );
|
||||
h->SetTotalThickness( params[0].myValue.toDouble() );
|
||||
h->SetVarParameter( params[1].text(), "SetNumberLayers" );
|
||||
h->SetVarParameter ( params[1].text(), "SetNumberLayers" );
|
||||
h->SetNumberLayers ( params[1].myValue.toInt() );
|
||||
h->SetVarParameter( params[2].text(), "SetStretchFactor" );
|
||||
h->SetVarParameter ( params[2].text(), "SetStretchFactor" );
|
||||
h->SetStretchFactor ( params[2].myValue.toDouble() );
|
||||
h->SetMethod (( StdMeshers::VLExtrusionMethod ) params[3].myValue.toInt() );
|
||||
|
||||
if ( StdMeshersGUI_SubShapeSelectorWdg* idsWg =
|
||||
widget< StdMeshersGUI_SubShapeSelectorWdg >( 4 ))
|
||||
widget< StdMeshersGUI_SubShapeSelectorWdg >( 5 ))
|
||||
{
|
||||
h->SetFaces( idsWg->GetListOfIDs(), params[3].myValue.toInt() );
|
||||
h->SetFaces( idsWg->GetListOfIDs(), params[4].myValue.toInt() );
|
||||
}
|
||||
}
|
||||
else if( hypType()=="ViscousLayers2D" )
|
||||
@ -732,11 +733,11 @@ QString StdMeshersGUI_StdHypothesisCreator::storeParams() const
|
||||
StdMeshers::StdMeshers_ViscousLayers2D_var h =
|
||||
StdMeshers::StdMeshers_ViscousLayers2D::_narrow( hypothesis() );
|
||||
|
||||
h->SetVarParameter( params[0].text(), "SetTotalThickness" );
|
||||
h->SetVarParameter ( params[0].text(), "SetTotalThickness" );
|
||||
h->SetTotalThickness( params[0].myValue.toDouble() );
|
||||
h->SetVarParameter( params[1].text(), "SetNumberLayers" );
|
||||
h->SetVarParameter ( params[1].text(), "SetNumberLayers" );
|
||||
h->SetNumberLayers ( params[1].myValue.toInt() );
|
||||
h->SetVarParameter( params[2].text(), "SetStretchFactor" );
|
||||
h->SetVarParameter ( params[2].text(), "SetStretchFactor" );
|
||||
h->SetStretchFactor ( params[2].myValue.toDouble() );
|
||||
|
||||
if ( StdMeshersGUI_SubShapeSelectorWdg* idsWg =
|
||||
@ -1242,6 +1243,20 @@ bool StdMeshersGUI_StdHypothesisCreator::stdParams( ListOfStdParams& p ) const
|
||||
p.append( item );
|
||||
customWidgets()->append (0);
|
||||
|
||||
item.myName = tr( "EXTRUSION_METHOD" );
|
||||
p.append( item );
|
||||
StdMeshersGUI_RadioButtonsGrpWdg* methodWdg = new StdMeshersGUI_RadioButtonsGrpWdg("");
|
||||
methodWdg->setButtonLabels ( QStringList()
|
||||
<< tr("EXTMETH_SURF_OFFSET_SMOOTH")
|
||||
<< tr("EXTMETH_FACE_OFFSET")
|
||||
<< tr("EXTMETH_NODE_OFFSET"),
|
||||
QStringList()
|
||||
<< tr("ICON_EXTMETH_SURF_OFFSET_SMOOTH")
|
||||
<< tr("ICON_EXTMETH_FACE_OFFSET")
|
||||
<< tr("ICON_EXTMETH_NODE_OFFSET"));
|
||||
methodWdg->setChecked( (int) h->GetMethod() );
|
||||
customWidgets()->append( methodWdg );
|
||||
|
||||
QString aMainEntry = SMESHGUI_GenericHypothesisCreator::getMainShapeEntry();
|
||||
QString aSubEntry = SMESHGUI_GenericHypothesisCreator::getShapeEntry();
|
||||
if ( !aMainEntry.isEmpty() )
|
||||
|
@ -283,4 +283,19 @@
|
||||
<translation>mesh_quadrangle_reduced.png</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>StdMeshersGUI_StdHypothesisCreator</name>
|
||||
<message>
|
||||
<source>ICON_EXTMETH_SURF_OFFSET_SMOOTH</source>
|
||||
<translation>mesh_extmeth_surf_offset_smooth.png</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>ICON_EXTMETH_NODE_OFFSET</source>
|
||||
<translation>mesh_extmeth_node_offset.png</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>ICON_EXTMETH_FACE_OFFSET</source>
|
||||
<translation>mesh_extmeth_face_offset.png</translation>
|
||||
</message>
|
||||
</context>
|
||||
</TS>
|
||||
|
@ -43,6 +43,22 @@ mesh/sub-mesh.
|
||||
Consider creating another hypothesis instead of using
|
||||
this one for this mesh/sub-mesh.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>EXTMETH_SURF_OFFSET_SMOOTH</source>
|
||||
<translation>Surface offset + smooth</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>EXTRUSION_METHOD</source>
|
||||
<translation>Extrusion method</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>EXTMETH_NODE_OFFSET</source>
|
||||
<translation>Node offset</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>EXTMETH_FACE_OFFSET</source>
|
||||
<translation>Face offset</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>@default</name>
|
||||
|
@ -230,6 +230,33 @@ throw ( SALOME::SALOME_Exception )
|
||||
return GetImpl()->GetStretchFactor();
|
||||
}
|
||||
|
||||
//================================================================================
|
||||
/*!
|
||||
* \brief Set Method of computing translation of a node
|
||||
*/
|
||||
//================================================================================
|
||||
|
||||
void StdMeshers_ViscousLayers_i::SetMethod( ::StdMeshers::VLExtrusionMethod how )
|
||||
{
|
||||
GetImpl()->SetMethod( ::StdMeshers_ViscousLayers::ExtrusionMethod( how ));
|
||||
const char* methNames[3] = { "SURF_OFFSET_SMOOTH",
|
||||
"FACE_OFFSET",
|
||||
"NODE_OFFSET" };
|
||||
if ( how >= 0 && how < 3 )
|
||||
SMESH::TPythonDump() << _this() << ".SetMethod( StdMeshers." << methNames[ how ]<< " )";
|
||||
}
|
||||
|
||||
//================================================================================
|
||||
/*!
|
||||
* \brief Return Method of computing translation of a node
|
||||
*/
|
||||
//================================================================================
|
||||
|
||||
::StdMeshers::VLExtrusionMethod StdMeshers_ViscousLayers_i::GetMethod()
|
||||
{
|
||||
return (::StdMeshers::VLExtrusionMethod) GetImpl()->GetMethod();
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
/*!
|
||||
* Get implementation
|
||||
|
@ -65,6 +65,9 @@ class STDMESHERS_I_EXPORT StdMeshers_ViscousLayers_i:
|
||||
void SetStretchFactor(::CORBA::Double factor) throw ( SALOME::SALOME_Exception );
|
||||
::CORBA::Double GetStretchFactor();
|
||||
|
||||
void SetMethod( ::StdMeshers::VLExtrusionMethod how );
|
||||
::StdMeshers::VLExtrusionMethod GetMethod();
|
||||
|
||||
// Get implementation
|
||||
::StdMeshers_ViscousLayers* GetImpl();
|
||||
|
||||
|