22834: [CEA 1347] Viscous layers: be able to choose the extrusion method

This commit is contained in:
eap 2015-02-10 14:14:01 +03:00
parent 02685fae6f
commit 146533380d
23 changed files with 1539 additions and 1183 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 50 KiB

After

Width:  |  Height:  |  Size: 31 KiB

View File

@ -75,12 +75,29 @@ computations.
\image html viscous_layers_hyp.png \image html viscous_layers_hyp.png
\image html viscous_layers_2d_hyp.png
<ul> <ul>
<li><b>Name</b> - allows to define the name of the hypothesis.</li> <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>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>Number of layers</b> - defines the number of element layers.</li>
<li><b>Stretch factor</b> - defines the growth factor of element height <li><b>Stretch factor</b> - defines the growth factor of element height
from the mesh boundary inwards.</li> 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 <li><b>Specified Faces/Edges are</b> - defines how the shapes specified by
the next parameter are used. the next parameter are used.
<li><b> Faces/Edges with/without layers</b> - <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 Faces (or edges) can be selected either in the Object Browser or in
the VTK Viewer. the VTK Viewer.
\note A mesh shown in the 3D Viewer can prevent selection of faces \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 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 (edges) shown at a time is limited by the value of "Sub-shapes
preview chunk size" preference (in Preferences/Mesh/General tab). preview chunk size" preference (in Preferences/Mesh/General tab).
If faces/edges without layers are specified, the element layers are If faces/edges without layers are specified, the element layers are
not constructed on geometrical faces shared by several solids in 3D not constructed on geometrical faces shared by several solids in 3D
case and edges shared by several faces in 2D case. In other words, case and edges shared by several faces in 2D case. In other words,

View File

@ -857,6 +857,21 @@ module StdMeshers
void GetCopySourceMesh(out boolean toCopyMesh,out boolean toCopyGroups); 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. * interface of "Viscous Layers" hypothesis.
* This hypothesis specifies parameters of layers of prisms to build * 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); void SetStretchFactor(in double factor) raises (SALOME::SALOME_Exception);
double GetStretchFactor(); double GetStretchFactor();
void SetMethod( in VLExtrusionMethod how );
VLExtrusionMethod GetMethod();
}; };
/*! /*!

View File

@ -215,6 +215,9 @@ SET(SMESH_RESOURCES_FILES
mesh_measure_length.png mesh_measure_length.png
mesh_measure_area.png mesh_measure_area.png
mesh_measure_volume.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}) INSTALL(FILES ${SMESH_RESOURCES_FILES} DESTINATION ${SALOME_SMESH_INSTALL_RES_DATA})

View File

@ -321,7 +321,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(),SetIgnoreFaces())</hypo> <hypo>ViscousLayers=ViscousLayers(SetTotalThickness(),SetNumberLayers(),SetStretchFactor(),SetFaces(1),SetFaces(2),SetMethod())</hypo>
</python-wrap> </python-wrap>
</algorithm> </algorithm>

Binary file not shown.

After

Width:  |  Height:  |  Size: 257 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 284 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 352 B

View File

@ -566,7 +566,7 @@ bool SMESH_Algo::IsStraight( const TopoDS_Edge & E,
if ( v1Len < std::numeric_limits< double >::min() ) if ( v1Len < std::numeric_limits< double >::min() )
return false; // E seems closed return false; // E seems closed
const double tol = Min( 10 * curve.Tolerance(), v1Len * 1e-2 ); 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 ) for ( int i = 0; i < nbSamples; ++i )
{ {
const double r = ( i + 1 ) / nbSamples; const double r = ( i + 1 ) / nbSamples;

View File

@ -2777,7 +2777,7 @@ void _pyHypothesis::Process( const Handle(_pyCommand)& theCommand)
myArgCommands.push_back( theCommand ); myArgCommands.push_back( theCommand );
usedCommand = true; usedCommand = true;
while ( crMethod.myArgs.size() < i+1 ) while ( crMethod.myArgs.size() < i+1 )
crMethod.myArgs.push_back( "[]" ); crMethod.myArgs.push_back( "None" );
crMethod.myArgs[ i ] = theCommand->GetArg( crMethod.myArgNb[i] ); crMethod.myArgs[ i ] = theCommand->GetArg( crMethod.myArgNb[i] );
} }
} }

View File

@ -43,8 +43,9 @@ QUADRANGLE = "Quadrangle_2D"
## Algorithm type: Radial Quadrangle 1D-2D algorithm, see StdMeshersBuilder_RadialQuadrangle1D2D ## Algorithm type: Radial Quadrangle 1D-2D algorithm, see StdMeshersBuilder_RadialQuadrangle1D2D
RADIAL_QUAD = "RadialQuadrangle_1D2D" 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.QuadType._items: exec('%s = StdMeshers.%s'%(e,e))
for e in StdMeshers.VLExtrusionMethod._items: exec('%s = StdMeshers.%s'%(e,e))
#---------------------- #----------------------
# Algorithms # Algorithms

View File

@ -23,7 +23,7 @@
import salome import salome
from salome.geom import geomBuilder from salome.geom import geomBuilder
import SMESH import SMESH, StdMeshers
## The base class to define meshing algorithms ## The base class to define meshing algorithms
# #
@ -266,9 +266,22 @@ class Mesh_Algorithm:
# the value of \a isFacesToIgnore parameter. # the value of \a isFacesToIgnore parameter.
# @param isFacesToIgnore if \c True, the Viscous layers are not generated on the # @param isFacesToIgnore if \c True, the Viscous layers are not generated on the
# faces specified by the previous parameter (\a faces). # 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 # @ingroup l3_hypos_additi
def ViscousLayers(self, thickness, numberOfLayers, stretchFactor, 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): 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():
@ -289,6 +302,7 @@ class Mesh_Algorithm:
hyp.SetNumberLayers( numberOfLayers ) hyp.SetNumberLayers( numberOfLayers )
hyp.SetStretchFactor( stretchFactor ) hyp.SetStretchFactor( stretchFactor )
hyp.SetFaces( faces, isFacesToIgnore ) hyp.SetFaces( faces, isFacesToIgnore )
hyp.SetMethod( extrMethod )
self.mesh.AddHypothesis( hyp, self.geom ) self.mesh.AddHypothesis( hyp, self.geom )
return hyp return hyp

File diff suppressed because it is too large Load Diff

View File

@ -58,6 +58,21 @@ public:
void SetStretchFactor(double factor); void SetStretchFactor(double factor);
double GetStretchFactor() const { return _stretchFactor; } 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. // 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,
@ -81,8 +96,6 @@ public:
* \param theMesh - the built mesh * \param theMesh - the built mesh
* \param theShape - the geometry of interest * \param theShape - the geometry of interest
* \retval bool - true if parameter values have been successfully defined * \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); virtual bool SetParametersByMesh(const SMESH_Mesh* theMesh, const TopoDS_Shape& theShape);
@ -102,6 +115,7 @@ public:
int _nbLayers; int _nbLayers;
double _thickness; double _thickness;
double _stretchFactor; double _stretchFactor;
ExtrusionMethod _method;
}; };
class SMESH_subMesh; class SMESH_subMesh;

View File

@ -18,7 +18,12 @@
// //
#include "StdMeshersGUI_RadioButtonsGrpWdg.h" #include "StdMeshersGUI_RadioButtonsGrpWdg.h"
#include <QVBoxLayout> #include "SMESHGUI.h"
#include <SUIT_ResourceMgr.h>
#include <QGridLayout>
#include <QLabel>
#include <QRadioButton> #include <QRadioButton>
#include <QButtonGroup> #include <QButtonGroup>
#include <QStringList> #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->setSpacing(SPACING);
layout->setMargin(MARGIN); layout->setMargin(MARGIN);
for ( int id = 0; id < buttonLabels.size(); ++id ) for ( int id = 0; id < buttonLabels.size(); ++id )
{ {
QRadioButton* button = new QRadioButton( buttonLabels.at(id), this ); QRadioButton* button = new QRadioButton( buttonLabels.at(id), this );
layout->addWidget( button ); layout->addWidget( button, id, 0 );
myButtonGrp->addButton( button, id ); 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 );
}
}
} }
} }

View File

@ -38,7 +38,8 @@ class STDMESHERSGUI_EXPORT StdMeshersGUI_RadioButtonsGrpWdg : public QGroupBox
public: public:
StdMeshersGUI_RadioButtonsGrpWdg (const QString& title); StdMeshersGUI_RadioButtonsGrpWdg (const QString& title);
void setButtonLabels( const QStringList& buttonLabels ); void setButtonLabels( const QStringList& buttonLabels,
const QStringList& buttonIcons=QStringList());
void setChecked(int id); void setChecked(int id);

View File

@ -720,11 +720,12 @@ QString StdMeshersGUI_StdHypothesisCreator::storeParams() const
h->SetNumberLayers ( params[1].myValue.toInt() ); 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->SetStretchFactor ( params[2].myValue.toDouble() );
h->SetMethod (( StdMeshers::VLExtrusionMethod ) params[3].myValue.toInt() );
if ( StdMeshersGUI_SubShapeSelectorWdg* idsWg = 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" ) else if( hypType()=="ViscousLayers2D" )
@ -1242,6 +1243,20 @@ bool StdMeshersGUI_StdHypothesisCreator::stdParams( ListOfStdParams& p ) const
p.append( item ); p.append( item );
customWidgets()->append (0); 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 aMainEntry = SMESHGUI_GenericHypothesisCreator::getMainShapeEntry();
QString aSubEntry = SMESHGUI_GenericHypothesisCreator::getShapeEntry(); QString aSubEntry = SMESHGUI_GenericHypothesisCreator::getShapeEntry();
if ( !aMainEntry.isEmpty() ) if ( !aMainEntry.isEmpty() )

View File

@ -283,4 +283,19 @@
<translation>mesh_quadrangle_reduced.png</translation> <translation>mesh_quadrangle_reduced.png</translation>
</message> </message>
</context> </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> </TS>

View File

@ -43,6 +43,22 @@ mesh/sub-mesh.
Consider creating another hypothesis instead of using Consider creating another hypothesis instead of using
this one for this mesh/sub-mesh.</translation> this one for this mesh/sub-mesh.</translation>
</message> </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>
<context> <context>
<name>@default</name> <name>@default</name>

View File

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

View File

@ -65,6 +65,9 @@ class STDMESHERS_I_EXPORT StdMeshers_ViscousLayers_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 SetMethod( ::StdMeshers::VLExtrusionMethod how );
::StdMeshers::VLExtrusionMethod GetMethod();
// Get implementation // Get implementation
::StdMeshers_ViscousLayers* GetImpl(); ::StdMeshers_ViscousLayers* GetImpl();