refs 254#: 7.5.5. Mesh generation for semi-analytical boundaries
Add "Chordal Error" parameter to NETGEN
This commit is contained in:
parent
3a149003e1
commit
1a836a25cc
@ -31,13 +31,19 @@ parameters below. You can select \a Custom to define them manually.
|
|||||||
- <b>Growth rate</b> - allows to define how much the linear dimensions of
|
- <b>Growth rate</b> - allows to define how much the linear dimensions of
|
||||||
two adjacent cells can differ (e.g. 0.3 means 30%).
|
two adjacent cells can differ (e.g. 0.3 means 30%).
|
||||||
- <b>Nb. Segs per Edge</b> - allows to define the minimum number of
|
- <b>Nb. Segs per Edge</b> - allows to define the minimum number of
|
||||||
mesh segments in which edges will be split. This parameter is used
|
mesh segments in which edges will be split. Size of elements computed using
|
||||||
only if <b>Limit Size by Surface Curvature</b> is checked.
|
this value is trimmed between <b>Min Size</b> and <b>Max Size</b>
|
||||||
|
bounds. This parameter is used only if <b>Limit Size by Surface
|
||||||
|
Curvature</b> is checked.
|
||||||
- <b>Nb Segs per Radius</b> - allows to define the size of
|
- <b>Nb Segs per Radius</b> - allows to define the size of
|
||||||
mesh segments and mesh faces in which curved edges and surfaces will
|
mesh segments and mesh faces in which curved edges and surfaces will
|
||||||
be split. This value divided by a radius of curvature gives an element
|
be split. A radius of local curvature divided by this value gives an element
|
||||||
size at a given point. This parameter is used only if <b>Limit Size by
|
size at a given point. Element size computed this way is then trimmed
|
||||||
Surface Curvature</b> is checked.
|
between <b>Min Size</b> and <b>Max Size</b> bounds. This parameter is
|
||||||
|
used only if <b>Limit Size by Surface Curvature</b> is checked.
|
||||||
|
- <b>Chordal Error</b> - allows to define the maximum distance between
|
||||||
|
the generated 2D element and the surface. Size of elements computed using
|
||||||
|
this criterion is trimmed between <b>Min Size</b> and <b>Max Size</b> bounds.
|
||||||
- <b>Limit Size by Surface Curvature</b> - if this box is checked in,
|
- <b>Limit Size by Surface Curvature</b> - if this box is checked in,
|
||||||
then size of mesh segments and mesh faces on curved edges and surfaces
|
then size of mesh segments and mesh faces on curved edges and surfaces
|
||||||
is defined using value of <b>Nb Segs per Radius</b> parameter, and
|
is defined using value of <b>Nb Segs per Radius</b> parameter, and
|
||||||
@ -87,6 +93,9 @@ section.<br>
|
|||||||
"25 25 0 25 25 200 0.3" means that along the line between points (25,
|
"25 25 0 25 25 200 0.3" means that along the line between points (25,
|
||||||
25, 0) and (25, 25, 200) size of elements should be 0.3.
|
25, 0) and (25, 25, 200) size of elements should be 0.3.
|
||||||
|
|
||||||
|
Sizes defined in the file are trimmed between <b>Min Size</b> and <b>Max Size</b>
|
||||||
|
bounds.
|
||||||
|
|
||||||
\image html netgen2d3d_simple.png
|
\image html netgen2d3d_simple.png
|
||||||
|
|
||||||
<b>NETGEN 2D simple parameters</b> and <b>NETGEN 3D simple
|
<b>NETGEN 2D simple parameters</b> and <b>NETGEN 3D simple
|
||||||
|
@ -92,6 +92,11 @@ module NETGENPlugin
|
|||||||
void SetNbSegPerEdge(in double value);
|
void SetNbSegPerEdge(in double value);
|
||||||
double GetNbSegPerEdge();
|
double GetNbSegPerEdge();
|
||||||
|
|
||||||
|
void SetChordalErrorEnabled(in boolean value);
|
||||||
|
boolean GetChordalErrorEnabled();
|
||||||
|
void SetChordalError(in double value);
|
||||||
|
double GetChordalError();
|
||||||
|
|
||||||
void SetNbSegPerRadius(in double value);
|
void SetNbSegPerRadius(in double value);
|
||||||
double GetNbSegPerRadius();
|
double GetNbSegPerRadius();
|
||||||
|
|
||||||
|
@ -177,7 +177,7 @@ QFrame* NETGENPluginGUI_HypothesisCreator::buildFrame()
|
|||||||
myFineness = new QComboBox( GroupC1 );
|
myFineness = new QComboBox( GroupC1 );
|
||||||
QStringList types;
|
QStringList types;
|
||||||
types << tr( "NETGEN_VERYCOARSE" ) << tr( "NETGEN_COARSE" ) << tr( "NETGEN_MODERATE" ) <<
|
types << tr( "NETGEN_VERYCOARSE" ) << tr( "NETGEN_COARSE" ) << tr( "NETGEN_MODERATE" ) <<
|
||||||
tr( "NETGEN_FINE" ) << tr( "NETGEN_VERYFINE" ) << tr( "NETGEN_CUSTOM" );
|
tr( "NETGEN_FINE" ) << tr( "NETGEN_VERYFINE" ) << tr( "NETGEN_CUSTOM" );
|
||||||
myFineness->addItems( types );
|
myFineness->addItems( types );
|
||||||
aGroupLayout->addWidget( myFineness, row, 1 );
|
aGroupLayout->addWidget( myFineness, row, 1 );
|
||||||
connect( myFineness, SIGNAL( activated( int ) ), this, SLOT( onFinenessChanged() ) );
|
connect( myFineness, SIGNAL( activated( int ) ), this, SLOT( onFinenessChanged() ) );
|
||||||
@ -208,6 +208,19 @@ QFrame* NETGENPluginGUI_HypothesisCreator::buildFrame()
|
|||||||
row++;
|
row++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
myChordalErrorEnabled = 0;
|
||||||
|
myChordalError = 0;
|
||||||
|
if ( myIs2D || !myIsONLY )
|
||||||
|
{
|
||||||
|
myChordalErrorEnabled = new QCheckBox( tr( "NETGEN_CHORDAL_ERROR" ), GroupC1 );
|
||||||
|
aGroupLayout->addWidget( myChordalErrorEnabled, row, 0 );
|
||||||
|
myChordalError = new SMESHGUI_SpinBox( GroupC1 );
|
||||||
|
myChordalError->RangeStepAndValidator( COORD_MIN, COORD_MAX, .1, "length_precision" );
|
||||||
|
aGroupLayout->addWidget( myChordalError, row, 1 );
|
||||||
|
connect( myChordalErrorEnabled, SIGNAL( stateChanged(int)), SLOT( onChordalErrorEnabled()));
|
||||||
|
row++;
|
||||||
|
}
|
||||||
|
|
||||||
mySurfaceCurvature = 0;
|
mySurfaceCurvature = 0;
|
||||||
if ( myIs2D || !myIsONLY )
|
if ( myIs2D || !myIsONLY )
|
||||||
{
|
{
|
||||||
@ -337,6 +350,15 @@ void NETGENPluginGUI_HypothesisCreator::retrieveParams() const
|
|||||||
else
|
else
|
||||||
myNbSegPerRadius->setText( data.myNbSegPerRadiusVar );
|
myNbSegPerRadius->setText( data.myNbSegPerRadiusVar );
|
||||||
}
|
}
|
||||||
|
if ( myChordalError )
|
||||||
|
{
|
||||||
|
myChordalErrorEnabled->setChecked( data.myChordalErrorEnabled && data.myChordalError > 0 );
|
||||||
|
if(data.myChordalErrorVar.isEmpty())
|
||||||
|
myChordalError->setValue( data.myChordalError > 0 ? data.myChordalError : 0.1 );
|
||||||
|
else
|
||||||
|
myChordalError->setText( data.myChordalErrorVar );
|
||||||
|
myChordalError->setEnabled( myChordalErrorEnabled->isChecked() );
|
||||||
|
}
|
||||||
if (myAllowQuadrangles)
|
if (myAllowQuadrangles)
|
||||||
myAllowQuadrangles->setChecked( data.myAllowQuadrangles );
|
myAllowQuadrangles->setChecked( data.myAllowQuadrangles );
|
||||||
|
|
||||||
@ -408,26 +430,28 @@ bool NETGENPluginGUI_HypothesisCreator::readParamsFromHypo( NetgenHypothesisData
|
|||||||
NETGENPlugin::NETGENPlugin_Hypothesis_var h =
|
NETGENPlugin::NETGENPlugin_Hypothesis_var h =
|
||||||
NETGENPlugin::NETGENPlugin_Hypothesis::_narrow( initParamsHypothesis() );
|
NETGENPlugin::NETGENPlugin_Hypothesis::_narrow( initParamsHypothesis() );
|
||||||
|
|
||||||
//HypothesisData* data = SMESH::GetHypothesisData( hypType() );
|
|
||||||
h_data.myName = isCreation() ? hypName() : "";
|
h_data.myName = isCreation() ? hypName() : "";
|
||||||
|
|
||||||
h_data.myMaxSize = h->GetMaxSize();
|
h_data.myMaxSize = h->GetMaxSize();
|
||||||
h_data.myMaxSizeVar = getVariableName("SetMaxSize");
|
h_data.myMaxSizeVar = getVariableName("SetMaxSize");
|
||||||
h_data.mySecondOrder = h->GetSecondOrder();
|
h_data.mySecondOrder = h->GetSecondOrder();
|
||||||
h_data.myOptimize = h->GetOptimize();
|
h_data.myOptimize = h->GetOptimize();
|
||||||
|
|
||||||
h_data.myFineness = (int) h->GetFineness();
|
h_data.myFineness = (int) h->GetFineness();
|
||||||
h_data.myGrowthRate = h->GetGrowthRate();
|
h_data.myGrowthRate = h->GetGrowthRate();
|
||||||
h_data.myGrowthRateVar = getVariableName("SetGrowthRate");
|
h_data.myGrowthRateVar = getVariableName("SetGrowthRate");
|
||||||
h_data.myNbSegPerEdge = h->GetNbSegPerEdge();
|
h_data.myNbSegPerEdge = h->GetNbSegPerEdge();
|
||||||
h_data.myNbSegPerEdgeVar = getVariableName("SetNbSegPerEdge");
|
h_data.myNbSegPerEdgeVar = getVariableName("SetNbSegPerEdge");
|
||||||
h_data.myNbSegPerRadius = h->GetNbSegPerRadius();
|
h_data.myNbSegPerRadius = h->GetNbSegPerRadius();
|
||||||
h_data.myNbSegPerRadiusVar = getVariableName("SetNbSegPerRadius");
|
h_data.myNbSegPerRadiusVar = getVariableName("SetNbSegPerRadius");
|
||||||
h_data.myMinSize = h->GetMinSize();
|
h_data.myChordalError = h->GetChordalError();
|
||||||
h_data.myMinSizeVar = getVariableName("SetMinSize");
|
h_data.myChordalErrorVar = getVariableName("SetChordalError");
|
||||||
h_data.mySurfaceCurvature = h->GetUseSurfaceCurvature();
|
h_data.myChordalErrorEnabled = h->GetChordalErrorEnabled();
|
||||||
h_data.myFuseEdges = h->GetFuseEdges();
|
h_data.myMinSize = h->GetMinSize();
|
||||||
h_data.myMeshSizeFile = h->GetMeshSizeFile();
|
h_data.myMinSizeVar = getVariableName("SetMinSize");
|
||||||
|
h_data.mySurfaceCurvature = h->GetUseSurfaceCurvature();
|
||||||
|
h_data.myFuseEdges = h->GetFuseEdges();
|
||||||
|
h_data.myMeshSizeFile = h->GetMeshSizeFile();
|
||||||
|
|
||||||
//if ( myIs2D )
|
//if ( myIs2D )
|
||||||
{
|
{
|
||||||
@ -486,6 +510,9 @@ bool NETGENPluginGUI_HypothesisCreator::storeParamsToHypo( const NetgenHypothesi
|
|||||||
h->SetVarParameter ( h_data.myNbSegPerRadiusVar.toLatin1().constData(), "SetNbSegPerRadius");
|
h->SetVarParameter ( h_data.myNbSegPerRadiusVar.toLatin1().constData(), "SetNbSegPerRadius");
|
||||||
h->SetNbSegPerRadius( h_data.myNbSegPerRadius );
|
h->SetNbSegPerRadius( h_data.myNbSegPerRadius );
|
||||||
}
|
}
|
||||||
|
h->SetVarParameter ( h_data.myChordalErrorVar.toLatin1().constData(), "SetChordalError");
|
||||||
|
h->SetChordalError ( h_data.myChordalError );
|
||||||
|
h->SetChordalErrorEnabled( h_data.myChordalErrorEnabled );
|
||||||
h->SetVarParameter ( h_data.myMinSizeVar.toLatin1().constData(), "SetMinSize");
|
h->SetVarParameter ( h_data.myMinSizeVar.toLatin1().constData(), "SetMinSize");
|
||||||
h->SetMinSize ( h_data.myMinSize );
|
h->SetMinSize ( h_data.myMinSize );
|
||||||
h->SetUseSurfaceCurvature( h_data.mySurfaceCurvature );
|
h->SetUseSurfaceCurvature( h_data.mySurfaceCurvature );
|
||||||
@ -551,8 +578,13 @@ bool NETGENPluginGUI_HypothesisCreator::readParamsFromWidgets( NetgenHypothesisD
|
|||||||
h_data.myNbSegPerEdgeVar = myNbSegPerEdge->text();
|
h_data.myNbSegPerEdgeVar = myNbSegPerEdge->text();
|
||||||
if ( myNbSegPerRadius )
|
if ( myNbSegPerRadius )
|
||||||
h_data.myNbSegPerRadiusVar = myNbSegPerRadius->text();
|
h_data.myNbSegPerRadiusVar = myNbSegPerRadius->text();
|
||||||
|
if ( myChordalError )
|
||||||
|
{
|
||||||
|
h_data.myChordalErrorVar = myChordalError->text();
|
||||||
|
h_data.myChordalError = myChordalError->value();
|
||||||
|
h_data.myChordalErrorEnabled = myChordalError->isEnabled();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
if ( myAllowQuadrangles )
|
if ( myAllowQuadrangles )
|
||||||
h_data.myAllowQuadrangles = myAllowQuadrangles->isChecked();
|
h_data.myAllowQuadrangles = myAllowQuadrangles->isChecked();
|
||||||
|
|
||||||
@ -577,6 +609,11 @@ bool NETGENPluginGUI_HypothesisCreator::readParamsFromWidgets( NetgenHypothesisD
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void NETGENPluginGUI_HypothesisCreator::onChordalErrorEnabled()
|
||||||
|
{
|
||||||
|
myChordalError->setEnabled( myChordalErrorEnabled->isChecked() );
|
||||||
|
}
|
||||||
|
|
||||||
void NETGENPluginGUI_HypothesisCreator::onSurfaceCurvatureChanged()
|
void NETGENPluginGUI_HypothesisCreator::onSurfaceCurvatureChanged()
|
||||||
{
|
{
|
||||||
bool isSurfaceCurvature = (mySurfaceCurvature ? mySurfaceCurvature->isChecked() : true);
|
bool isSurfaceCurvature = (mySurfaceCurvature ? mySurfaceCurvature->isChecked() : true);
|
||||||
@ -587,6 +624,11 @@ void NETGENPluginGUI_HypothesisCreator::onSurfaceCurvatureChanged()
|
|||||||
myNbSegPerEdge->setEnabled(isCustom && isSurfaceCurvature);
|
myNbSegPerEdge->setEnabled(isCustom && isSurfaceCurvature);
|
||||||
if ( myNbSegPerRadius )
|
if ( myNbSegPerRadius )
|
||||||
myNbSegPerRadius->setEnabled(isCustom && isSurfaceCurvature);
|
myNbSegPerRadius->setEnabled(isCustom && isSurfaceCurvature);
|
||||||
|
// if ( myChordalError )
|
||||||
|
// {
|
||||||
|
// myChordalError->setEnabled( isSurfaceCurvature );
|
||||||
|
// myChordalErrorEnabled->setEnabled( isSurfaceCurvature );
|
||||||
|
// }
|
||||||
}
|
}
|
||||||
|
|
||||||
void NETGENPluginGUI_HypothesisCreator::onFinenessChanged()
|
void NETGENPluginGUI_HypothesisCreator::onFinenessChanged()
|
||||||
|
@ -44,11 +44,11 @@ class QTableWidget;
|
|||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
double myMaxSize, myMinSize, myGrowthRate, myNbSegPerEdge, myNbSegPerRadius;
|
double myMaxSize, myMinSize, myGrowthRate, myNbSegPerEdge, myNbSegPerRadius, myChordalError;
|
||||||
int myFineness;
|
int myFineness;
|
||||||
bool mySecondOrder, myAllowQuadrangles, myOptimize, mySurfaceCurvature, myFuseEdges;
|
bool mySecondOrder, myAllowQuadrangles, myOptimize, mySurfaceCurvature, myFuseEdges, myChordalErrorEnabled;
|
||||||
QString myName, myMeshSizeFile;
|
QString myName, myMeshSizeFile;
|
||||||
QString myMaxSizeVar, myMinSizeVar, myGrowthRateVar, myNbSegPerEdgeVar, myNbSegPerRadiusVar;
|
QString myMaxSizeVar, myMinSizeVar, myGrowthRateVar, myNbSegPerEdgeVar, myNbSegPerRadiusVar, myChordalErrorVar;
|
||||||
} NetgenHypothesisData;
|
} NetgenHypothesisData;
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@ -76,6 +76,7 @@ protected:
|
|||||||
|
|
||||||
protected slots:
|
protected slots:
|
||||||
virtual void onFinenessChanged();
|
virtual void onFinenessChanged();
|
||||||
|
virtual void onChordalErrorEnabled();
|
||||||
virtual void onSurfaceCurvatureChanged();
|
virtual void onSurfaceCurvatureChanged();
|
||||||
virtual void onAddLocalSizeOnVertex();
|
virtual void onAddLocalSizeOnVertex();
|
||||||
virtual void onAddLocalSizeOnEdge();
|
virtual void onAddLocalSizeOnEdge();
|
||||||
@ -102,12 +103,14 @@ private:
|
|||||||
SMESHGUI_SpinBox* myGrowthRate;
|
SMESHGUI_SpinBox* myGrowthRate;
|
||||||
SMESHGUI_SpinBox* myNbSegPerEdge;
|
SMESHGUI_SpinBox* myNbSegPerEdge;
|
||||||
SMESHGUI_SpinBox* myNbSegPerRadius;
|
SMESHGUI_SpinBox* myNbSegPerRadius;
|
||||||
|
QCheckBox* myChordalErrorEnabled;
|
||||||
|
SMESHGUI_SpinBox* myChordalError;
|
||||||
QCheckBox* myAllowQuadrangles;
|
QCheckBox* myAllowQuadrangles;
|
||||||
QCheckBox* mySurfaceCurvature;
|
QCheckBox* mySurfaceCurvature;
|
||||||
QCheckBox* myFuseEdges;
|
QCheckBox* myFuseEdges;
|
||||||
|
|
||||||
bool myIs2D;
|
bool myIs2D; // 2D or 3D
|
||||||
bool myIsONLY;
|
bool myIsONLY; // one dim or several
|
||||||
|
|
||||||
QLineEdit* myMeshSizeFile;
|
QLineEdit* myMeshSizeFile;
|
||||||
QTableWidget* myLocalSizeTable;
|
QTableWidget* myLocalSizeTable;
|
||||||
|
@ -91,6 +91,10 @@
|
|||||||
<source>NETGEN_SEG_PER_RADIUS</source>
|
<source>NETGEN_SEG_PER_RADIUS</source>
|
||||||
<translation>Nb. Segs per Radius</translation>
|
<translation>Nb. Segs per Radius</translation>
|
||||||
</message>
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>NETGEN_CHORDAL_ERROR</source>
|
||||||
|
<translation>Chordal Error</translation>
|
||||||
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<source>NETGEN_SURFACE_CURVATURE</source>
|
<source>NETGEN_SURFACE_CURVATURE</source>
|
||||||
<translation>Limit Size by Surface Curvature</translation>
|
<translation>Limit Size by Surface Curvature</translation>
|
||||||
|
@ -221,6 +221,14 @@ class NETGEN_1D2D3D_Algorithm(NETGEN_Algorithm):
|
|||||||
if self.Parameters(): self.params.SetNbSegPerRadius(theVal)
|
if self.Parameters(): self.params.SetNbSegPerRadius(theVal)
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
## Sets @c ChordalError parameter
|
||||||
|
# @param theVal new value of the @c ChordalError parameter
|
||||||
|
def SetChordalError(self, theVal):
|
||||||
|
if self.Parameters():
|
||||||
|
self.params.SetChordalError(theVal)
|
||||||
|
self.params.SetChordalErrorEnabled( theVal > 0 )
|
||||||
|
pass
|
||||||
|
|
||||||
## Sets @c QuadAllowed flag
|
## Sets @c QuadAllowed flag
|
||||||
# @param toAllow new value of the @c QuadAllowed parameter (@c True by default)
|
# @param toAllow new value of the @c QuadAllowed parameter (@c True by default)
|
||||||
def SetQuadAllowed(self, toAllow=True):
|
def SetQuadAllowed(self, toAllow=True):
|
||||||
|
@ -43,18 +43,20 @@ using namespace std;
|
|||||||
NETGENPlugin_Hypothesis::NETGENPlugin_Hypothesis (int hypId, int studyId,
|
NETGENPlugin_Hypothesis::NETGENPlugin_Hypothesis (int hypId, int studyId,
|
||||||
SMESH_Gen * gen)
|
SMESH_Gen * gen)
|
||||||
: SMESH_Hypothesis(hypId, studyId, gen),
|
: SMESH_Hypothesis(hypId, studyId, gen),
|
||||||
_maxSize (GetDefaultMaxSize()),
|
_maxSize (GetDefaultMaxSize()),
|
||||||
_minSize (0),
|
_minSize (0),
|
||||||
_growthRate (GetDefaultGrowthRate()),
|
_growthRate (GetDefaultGrowthRate()),
|
||||||
_nbSegPerEdge (GetDefaultNbSegPerEdge()),
|
_nbSegPerEdge (GetDefaultNbSegPerEdge()),
|
||||||
_nbSegPerRadius (GetDefaultNbSegPerRadius()),
|
_nbSegPerRadius (GetDefaultNbSegPerRadius()),
|
||||||
_fineness (GetDefaultFineness()),
|
_fineness (GetDefaultFineness()),
|
||||||
_secondOrder (GetDefaultSecondOrder()),
|
_chordalErrorEnabled(GetDefaultChordalError() > 0),
|
||||||
_optimize (GetDefaultOptimize()),
|
_chordalError (GetDefaultChordalError() ),
|
||||||
_localSize (GetDefaultLocalSize()),
|
_secondOrder (GetDefaultSecondOrder()),
|
||||||
_quadAllowed (GetDefaultQuadAllowed()),
|
_optimize (GetDefaultOptimize()),
|
||||||
_surfaceCurvature(GetDefaultSurfaceCurvature()),
|
_localSize (GetDefaultLocalSize()),
|
||||||
_fuseEdges (GetDefaultFuseEdges())
|
_quadAllowed (GetDefaultQuadAllowed()),
|
||||||
|
_surfaceCurvature (GetDefaultSurfaceCurvature()),
|
||||||
|
_fuseEdges (GetDefaultFuseEdges())
|
||||||
{
|
{
|
||||||
_name = "NETGEN_Parameters";
|
_name = "NETGEN_Parameters";
|
||||||
_param_algo_dim = 3;
|
_param_algo_dim = 3;
|
||||||
@ -208,6 +210,34 @@ void NETGENPlugin_Hypothesis::SetNbSegPerRadius(double theVal)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//=============================================================================
|
||||||
|
/*!
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
//=============================================================================
|
||||||
|
void NETGENPlugin_Hypothesis::SetChordalErrorEnabled(bool theVal)
|
||||||
|
{
|
||||||
|
if (theVal != _chordalErrorEnabled)
|
||||||
|
{
|
||||||
|
_chordalErrorEnabled = theVal;
|
||||||
|
NotifySubMeshesHypothesisModification();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//=============================================================================
|
||||||
|
/*!
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
//=============================================================================
|
||||||
|
void NETGENPlugin_Hypothesis::SetChordalError(double theVal)
|
||||||
|
{
|
||||||
|
if (theVal != _chordalError)
|
||||||
|
{
|
||||||
|
_chordalError = theVal;
|
||||||
|
NotifySubMeshesHypothesisModification();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//=============================================================================
|
//=============================================================================
|
||||||
/*!
|
/*!
|
||||||
*
|
*
|
||||||
@ -351,8 +381,8 @@ ostream & NETGENPlugin_Hypothesis::SaveTo(ostream & save)
|
|||||||
if (it_sm != _localSize.end()) {
|
if (it_sm != _localSize.end()) {
|
||||||
save << " " << "__LOCALSIZE_BEGIN__";
|
save << " " << "__LOCALSIZE_BEGIN__";
|
||||||
for ( ; it_sm != _localSize.end(); ++it_sm ) {
|
for ( ; it_sm != _localSize.end(); ++it_sm ) {
|
||||||
save << " " << it_sm->first
|
save << " " << it_sm->first
|
||||||
<< " " << it_sm->second << "%#"; // "%#" is a mark of value end
|
<< " " << it_sm->second << "%#"; // "%#" is a mark of value end
|
||||||
}
|
}
|
||||||
save << " " << "__LOCALSIZE_END__";
|
save << " " << "__LOCALSIZE_END__";
|
||||||
}
|
}
|
||||||
@ -363,6 +393,8 @@ ostream & NETGENPlugin_Hypothesis::SaveTo(ostream & save)
|
|||||||
|
|
||||||
save << " " << _meshSizeFile.size() << " " << _meshSizeFile;
|
save << " " << _meshSizeFile.size() << " " << _meshSizeFile;
|
||||||
|
|
||||||
|
save << " " << ( _chordalErrorEnabled ? _chordalError : 0. );
|
||||||
|
|
||||||
return save;
|
return save;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -476,12 +508,19 @@ istream & NETGENPlugin_Hypothesis::LoadFrom(istream & load)
|
|||||||
load.get( &_meshSizeFile[0], is+1 );
|
load.get( &_meshSizeFile[0], is+1 );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
isOK = static_cast<bool>(load >> val);
|
||||||
|
if (isOK)
|
||||||
|
_chordalError = val;
|
||||||
|
else
|
||||||
|
load.clear(ios::badbit | load.rdstate());
|
||||||
|
_chordalErrorEnabled = ( _chordalError > 0 );
|
||||||
|
|
||||||
return load;
|
return load;
|
||||||
}
|
}
|
||||||
|
|
||||||
//=============================================================================
|
//=============================================================================
|
||||||
/*!
|
/*!
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
//=============================================================================
|
//=============================================================================
|
||||||
ostream & operator <<(ostream & save, NETGENPlugin_Hypothesis & hyp)
|
ostream & operator <<(ostream & save, NETGENPlugin_Hypothesis & hyp)
|
||||||
@ -491,7 +530,7 @@ ostream & operator <<(ostream & save, NETGENPlugin_Hypothesis & hyp)
|
|||||||
|
|
||||||
//=============================================================================
|
//=============================================================================
|
||||||
/*!
|
/*!
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
//=============================================================================
|
//=============================================================================
|
||||||
istream & operator >>(istream & load, NETGENPlugin_Hypothesis & hyp)
|
istream & operator >>(istream & load, NETGENPlugin_Hypothesis & hyp)
|
||||||
@ -584,6 +623,15 @@ double NETGENPlugin_Hypothesis::GetDefaultNbSegPerRadius()
|
|||||||
{
|
{
|
||||||
return 2;
|
return 2;
|
||||||
}
|
}
|
||||||
|
//=============================================================================
|
||||||
|
/*!
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
//=============================================================================
|
||||||
|
double NETGENPlugin_Hypothesis::GetDefaultChordalError()
|
||||||
|
{
|
||||||
|
return -1; // disabled by default
|
||||||
|
}
|
||||||
|
|
||||||
//=============================================================================
|
//=============================================================================
|
||||||
/*!
|
/*!
|
||||||
|
@ -83,6 +83,11 @@ public:
|
|||||||
void SetNbSegPerRadius(double theVal);
|
void SetNbSegPerRadius(double theVal);
|
||||||
double GetNbSegPerRadius() const { return _nbSegPerRadius; }
|
double GetNbSegPerRadius() const { return _nbSegPerRadius; }
|
||||||
|
|
||||||
|
void SetChordalErrorEnabled(bool value);
|
||||||
|
double GetChordalErrorEnabled() const { return _chordalErrorEnabled; }
|
||||||
|
void SetChordalError(double value);
|
||||||
|
double GetChordalError() const { return _chordalError; }
|
||||||
|
|
||||||
typedef std::map<std::string, double> TLocalSize;
|
typedef std::map<std::string, double> TLocalSize;
|
||||||
static TLocalSize GetDefaultLocalSize() { return TLocalSize(); }
|
static TLocalSize GetDefaultLocalSize() { return TLocalSize(); }
|
||||||
void SetLocalSizeOnEntry(const std::string& entry, double localSize);
|
void SetLocalSizeOnEntry(const std::string& entry, double localSize);
|
||||||
@ -109,6 +114,7 @@ public:
|
|||||||
static double GetDefaultGrowthRate();
|
static double GetDefaultGrowthRate();
|
||||||
static double GetDefaultNbSegPerEdge();
|
static double GetDefaultNbSegPerEdge();
|
||||||
static double GetDefaultNbSegPerRadius();
|
static double GetDefaultNbSegPerRadius();
|
||||||
|
static double GetDefaultChordalError();
|
||||||
static bool GetDefaultSecondOrder();
|
static bool GetDefaultSecondOrder();
|
||||||
static bool GetDefaultOptimize();
|
static bool GetDefaultOptimize();
|
||||||
static bool GetDefaultQuadAllowed();
|
static bool GetDefaultQuadAllowed();
|
||||||
@ -141,6 +147,8 @@ private:
|
|||||||
double _nbSegPerEdge;
|
double _nbSegPerEdge;
|
||||||
double _nbSegPerRadius;
|
double _nbSegPerRadius;
|
||||||
Fineness _fineness;
|
Fineness _fineness;
|
||||||
|
bool _chordalErrorEnabled;
|
||||||
|
double _chordalError;
|
||||||
bool _secondOrder;
|
bool _secondOrder;
|
||||||
bool _optimize;
|
bool _optimize;
|
||||||
TLocalSize _localSize;
|
TLocalSize _localSize;
|
||||||
|
@ -307,6 +307,36 @@ CORBA::Double NETGENPlugin_Hypothesis_i::GetNbSegPerRadius()
|
|||||||
|
|
||||||
//=============================================================================
|
//=============================================================================
|
||||||
|
|
||||||
|
void NETGENPlugin_Hypothesis_i::SetChordalErrorEnabled(CORBA::Boolean theValue)
|
||||||
|
{
|
||||||
|
if ( isToSetParameter( GetChordalErrorEnabled(), theValue, METH_SetChordalErrorEnabled ))
|
||||||
|
{
|
||||||
|
this->GetImpl()->SetChordalErrorEnabled(theValue);
|
||||||
|
SMESH::TPythonDump() << _this() << ".SetChordalErrorEnabled( " << theValue << " )";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
CORBA::Boolean NETGENPlugin_Hypothesis_i::GetChordalErrorEnabled()
|
||||||
|
{
|
||||||
|
return GetImpl()->GetChordalErrorEnabled();
|
||||||
|
}
|
||||||
|
|
||||||
|
void NETGENPlugin_Hypothesis_i::SetChordalError(CORBA::Double theValue)
|
||||||
|
{
|
||||||
|
if ( isToSetParameter( GetChordalError(), theValue, METH_SetChordalError ))
|
||||||
|
{
|
||||||
|
this->GetImpl()->SetChordalError(theValue);
|
||||||
|
SMESH::TPythonDump() << _this() << ".SetChordalError( " << SMESH::TVar(theValue) << " )";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
CORBA::Double NETGENPlugin_Hypothesis_i::GetChordalError()
|
||||||
|
{
|
||||||
|
return GetImpl()->GetChordalError();
|
||||||
|
}
|
||||||
|
|
||||||
|
//=============================================================================
|
||||||
|
|
||||||
void NETGENPlugin_Hypothesis_i::SetLocalSizeOnShape(GEOM::GEOM_Object_ptr GeomObj,
|
void NETGENPlugin_Hypothesis_i::SetLocalSizeOnShape(GEOM::GEOM_Object_ptr GeomObj,
|
||||||
CORBA::Double localSize)
|
CORBA::Double localSize)
|
||||||
throw (SALOME::SALOME_Exception)
|
throw (SALOME::SALOME_Exception)
|
||||||
|
@ -79,6 +79,11 @@ class NETGENPLUGIN_EXPORT NETGENPlugin_Hypothesis_i:
|
|||||||
void SetNbSegPerRadius(CORBA::Double theVal);
|
void SetNbSegPerRadius(CORBA::Double theVal);
|
||||||
CORBA::Double GetNbSegPerRadius();
|
CORBA::Double GetNbSegPerRadius();
|
||||||
|
|
||||||
|
void SetChordalErrorEnabled(CORBA::Boolean value);
|
||||||
|
CORBA::Boolean GetChordalErrorEnabled();
|
||||||
|
void SetChordalError(CORBA::Double value);
|
||||||
|
CORBA::Double GetChordalError();
|
||||||
|
|
||||||
void SetLocalSizeOnShape(GEOM::GEOM_Object_ptr GeomObj, CORBA::Double localSize)
|
void SetLocalSizeOnShape(GEOM::GEOM_Object_ptr GeomObj, CORBA::Double localSize)
|
||||||
throw (SALOME::SALOME_Exception);
|
throw (SALOME::SALOME_Exception);
|
||||||
void SetLocalSizeOnEntry(const char* entry, CORBA::Double localSize);
|
void SetLocalSizeOnEntry(const char* entry, CORBA::Double localSize);
|
||||||
@ -109,19 +114,21 @@ class NETGENPLUGIN_EXPORT NETGENPlugin_Hypothesis_i:
|
|||||||
// to remember whether a parameter is already set (issue 0021364)
|
// to remember whether a parameter is already set (issue 0021364)
|
||||||
enum SettingMethod
|
enum SettingMethod
|
||||||
{
|
{
|
||||||
METH_SetMaxSize = 1,
|
METH_SetMaxSize = 1,
|
||||||
METH_SetMinSize = 2,
|
METH_SetMinSize = 2,
|
||||||
METH_SetSecondOrder = 4,
|
METH_SetSecondOrder = 4,
|
||||||
METH_SetOptimize = 8,
|
METH_SetOptimize = 8,
|
||||||
METH_SetFineness = 16,
|
METH_SetFineness = 16,
|
||||||
METH_SetGrowthRate = 32,
|
METH_SetGrowthRate = 32,
|
||||||
METH_SetNbSegPerEdge = 64,
|
METH_SetNbSegPerEdge = 64,
|
||||||
METH_SetNbSegPerRadius = 128,
|
METH_SetNbSegPerRadius = 128,
|
||||||
METH_SetLocalSizeOnEntry = 256,
|
METH_SetLocalSizeOnEntry = 256,
|
||||||
METH_SetQuadAllowed = METH_SetLocalSizeOnEntry * 2,
|
METH_SetQuadAllowed = METH_SetLocalSizeOnEntry * 2,
|
||||||
METH_SetSurfaceCurvature = METH_SetQuadAllowed * 2,
|
METH_SetSurfaceCurvature = METH_SetQuadAllowed * 2,
|
||||||
METH_SetFuseEdges = METH_SetSurfaceCurvature * 2,
|
METH_SetFuseEdges = METH_SetSurfaceCurvature * 2,
|
||||||
METH_LAST = METH_SetFuseEdges
|
METH_SetChordalErrorEnabled = METH_SetFuseEdges * 2,
|
||||||
|
METH_SetChordalError = METH_SetChordalErrorEnabled * 2,
|
||||||
|
METH_LAST = METH_SetFuseEdges
|
||||||
};
|
};
|
||||||
int mySetMethodFlags;
|
int mySetMethodFlags;
|
||||||
|
|
||||||
|
@ -52,21 +52,29 @@
|
|||||||
|
|
||||||
#include <utilities.h>
|
#include <utilities.h>
|
||||||
|
|
||||||
|
#include <BRepAdaptor_Surface.hxx>
|
||||||
#include <BRepBuilderAPI_Copy.hxx>
|
#include <BRepBuilderAPI_Copy.hxx>
|
||||||
|
#include <BRepLProp_SLProps.hxx>
|
||||||
|
#include <BRepMesh_IncrementalMesh.hxx>
|
||||||
|
#include <BRep_Builder.hxx>
|
||||||
#include <BRep_Tool.hxx>
|
#include <BRep_Tool.hxx>
|
||||||
#include <Bnd_B3d.hxx>
|
#include <Bnd_B3d.hxx>
|
||||||
|
#include <GeomLib_IsPlanarSurface.hxx>
|
||||||
#include <NCollection_Map.hxx>
|
#include <NCollection_Map.hxx>
|
||||||
|
#include <Poly_Triangulation.hxx>
|
||||||
#include <Standard_ErrorHandler.hxx>
|
#include <Standard_ErrorHandler.hxx>
|
||||||
#include <Standard_ProgramError.hxx>
|
#include <Standard_ProgramError.hxx>
|
||||||
#include <TColStd_MapOfInteger.hxx>
|
#include <TColStd_MapOfInteger.hxx>
|
||||||
#include <TopExp.hxx>
|
#include <TopExp.hxx>
|
||||||
#include <TopExp_Explorer.hxx>
|
#include <TopExp_Explorer.hxx>
|
||||||
|
#include <TopLoc_Location.hxx>
|
||||||
#include <TopTools_DataMapIteratorOfDataMapOfShapeInteger.hxx>
|
#include <TopTools_DataMapIteratorOfDataMapOfShapeInteger.hxx>
|
||||||
#include <TopTools_DataMapIteratorOfDataMapOfShapeShape.hxx>
|
#include <TopTools_DataMapIteratorOfDataMapOfShapeShape.hxx>
|
||||||
#include <TopTools_DataMapOfShapeInteger.hxx>
|
#include <TopTools_DataMapOfShapeInteger.hxx>
|
||||||
#include <TopTools_DataMapOfShapeShape.hxx>
|
#include <TopTools_DataMapOfShapeShape.hxx>
|
||||||
#include <TopTools_MapOfShape.hxx>
|
#include <TopTools_MapOfShape.hxx>
|
||||||
#include <TopoDS.hxx>
|
#include <TopoDS.hxx>
|
||||||
|
#include <TopoDS_Compound.hxx>
|
||||||
|
|
||||||
// Netgen include files
|
// Netgen include files
|
||||||
#ifndef OCCGEOMETRY
|
#ifndef OCCGEOMETRY
|
||||||
@ -151,12 +159,14 @@ NETGENPlugin_Mesher::NETGENPlugin_Mesher (SMESH_Mesh* mesh,
|
|||||||
_optimize(true),
|
_optimize(true),
|
||||||
_fineness(NETGENPlugin_Hypothesis::GetDefaultFineness()),
|
_fineness(NETGENPlugin_Hypothesis::GetDefaultFineness()),
|
||||||
_isViscousLayers2D(false),
|
_isViscousLayers2D(false),
|
||||||
|
_chordalError(-1), // means disabled
|
||||||
_ngMesh(NULL),
|
_ngMesh(NULL),
|
||||||
_occgeom(NULL),
|
_occgeom(NULL),
|
||||||
_curShapeIndex(-1),
|
_curShapeIndex(-1),
|
||||||
_progressTic(1),
|
_progressTic(1),
|
||||||
_totalTime(1.0),
|
_totalTime(1.0),
|
||||||
_simpleHyp(NULL),
|
_simpleHyp(NULL),
|
||||||
|
_viscousLayersHyp(NULL),
|
||||||
_ptrToMe(NULL)
|
_ptrToMe(NULL)
|
||||||
{
|
{
|
||||||
SetDefaultParameters();
|
SetDefaultParameters();
|
||||||
@ -292,32 +302,36 @@ void NETGENPlugin_Mesher::SetParameters(const NETGENPlugin_Hypothesis* hyp)
|
|||||||
_fineness = hyp->GetFineness();
|
_fineness = hyp->GetFineness();
|
||||||
mparams.uselocalh = hyp->GetSurfaceCurvature();
|
mparams.uselocalh = hyp->GetSurfaceCurvature();
|
||||||
netgen::merge_solids = hyp->GetFuseEdges();
|
netgen::merge_solids = hyp->GetFuseEdges();
|
||||||
|
_chordalError = hyp->GetChordalErrorEnabled() ? hyp->GetChordalError() : -1.;
|
||||||
_simpleHyp = NULL;
|
_simpleHyp = NULL;
|
||||||
// mesh size file
|
// mesh size file
|
||||||
mparams.meshsizefilename= hyp->GetMeshSizeFile().empty() ? 0 : hyp->GetMeshSizeFile().c_str();
|
mparams.meshsizefilename= hyp->GetMeshSizeFile().empty() ? 0 : hyp->GetMeshSizeFile().c_str();
|
||||||
|
|
||||||
SMESH_Gen_i* smeshGen_i = SMESH_Gen_i::GetSMESHGen();
|
const NETGENPlugin_Hypothesis::TLocalSize& localSizes = hyp->GetLocalSizesAndEntries();
|
||||||
CORBA::Object_var anObject = smeshGen_i->GetNS()->Resolve("/myStudyManager");
|
if ( !localSizes.empty() )
|
||||||
SALOMEDS::StudyManager_var aStudyMgr = SALOMEDS::StudyManager::_narrow(anObject);
|
|
||||||
SALOMEDS::Study_var myStudy = aStudyMgr->GetStudyByID(hyp->GetStudyId());
|
|
||||||
if ( !myStudy->_is_nil() )
|
|
||||||
{
|
{
|
||||||
const NETGENPlugin_Hypothesis::TLocalSize localSizes = hyp->GetLocalSizesAndEntries();
|
SMESH_Gen_i* smeshGen_i = SMESH_Gen_i::GetSMESHGen();
|
||||||
NETGENPlugin_Hypothesis::TLocalSize::const_iterator it = localSizes.begin();
|
CORBA::Object_var anObject = smeshGen_i->GetNS()->Resolve("/myStudyManager");
|
||||||
for ( ; it != localSizes.end() ; it++)
|
SALOMEDS::StudyManager_var aStudyMgr = SALOMEDS::StudyManager::_narrow(anObject);
|
||||||
|
SALOMEDS::Study_var myStudy = aStudyMgr->GetStudyByID(hyp->GetStudyId());
|
||||||
|
if ( !myStudy->_is_nil() )
|
||||||
{
|
{
|
||||||
std::string entry = (*it).first;
|
NETGENPlugin_Hypothesis::TLocalSize::const_iterator it = localSizes.begin();
|
||||||
double val = (*it).second;
|
for ( ; it != localSizes.end() ; it++)
|
||||||
// --
|
{
|
||||||
GEOM::GEOM_Object_var aGeomObj;
|
std::string entry = (*it).first;
|
||||||
SALOMEDS::SObject_var aSObj = myStudy->FindObjectID( entry.c_str() );
|
double val = (*it).second;
|
||||||
if ( !aSObj->_is_nil() ) {
|
// --
|
||||||
CORBA::Object_var obj = aSObj->GetObject();
|
GEOM::GEOM_Object_var aGeomObj;
|
||||||
aGeomObj = GEOM::GEOM_Object::_narrow(obj);
|
SALOMEDS::SObject_var aSObj = myStudy->FindObjectID( entry.c_str() );
|
||||||
aSObj->UnRegister();
|
if ( !aSObj->_is_nil() ) {
|
||||||
|
CORBA::Object_var obj = aSObj->GetObject();
|
||||||
|
aGeomObj = GEOM::GEOM_Object::_narrow(obj);
|
||||||
|
aSObj->UnRegister();
|
||||||
|
}
|
||||||
|
TopoDS_Shape S = smeshGen_i->GeomObjectToShape( aGeomObj.in() );
|
||||||
|
::SetLocalSize(S, val);
|
||||||
}
|
}
|
||||||
TopoDS_Shape S = smeshGen_i->GeomObjectToShape( aGeomObj.in() );
|
|
||||||
::SetLocalSize(S, val);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -336,6 +350,17 @@ void NETGENPlugin_Mesher::SetParameters(const NETGENPlugin_SimpleHypothesis_2D*
|
|||||||
SetDefaultParameters();
|
SetDefaultParameters();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//================================================================================
|
||||||
|
/*!
|
||||||
|
* \brief Store a Viscous Layers hypothesis
|
||||||
|
*/
|
||||||
|
//================================================================================
|
||||||
|
|
||||||
|
void NETGENPlugin_Mesher::SetParameters(const StdMeshers_ViscousLayers* hyp )
|
||||||
|
{
|
||||||
|
_viscousLayersHyp = hyp;
|
||||||
|
}
|
||||||
|
|
||||||
//=============================================================================
|
//=============================================================================
|
||||||
/*!
|
/*!
|
||||||
* Link - a pair of integer numbers
|
* Link - a pair of integer numbers
|
||||||
@ -585,7 +610,8 @@ namespace
|
|||||||
|
|
||||||
void setLocalSize(const TopoDS_Edge& edge,
|
void setLocalSize(const TopoDS_Edge& edge,
|
||||||
double size,
|
double size,
|
||||||
netgen::Mesh& mesh)
|
netgen::Mesh& mesh,
|
||||||
|
const bool overrideMinH = true)
|
||||||
{
|
{
|
||||||
if ( size <= std::numeric_limits<double>::min() )
|
if ( size <= std::numeric_limits<double>::min() )
|
||||||
return;
|
return;
|
||||||
@ -596,7 +622,7 @@ namespace
|
|||||||
TopoDS_Iterator vIt( edge );
|
TopoDS_Iterator vIt( edge );
|
||||||
if ( !vIt.More() ) return;
|
if ( !vIt.More() ) return;
|
||||||
gp_Pnt p = BRep_Tool::Pnt( TopoDS::Vertex( vIt.Value() ));
|
gp_Pnt p = BRep_Tool::Pnt( TopoDS::Vertex( vIt.Value() ));
|
||||||
NETGENPlugin_Mesher::RestrictLocalSize( mesh, p.XYZ(), size );
|
NETGENPlugin_Mesher::RestrictLocalSize( mesh, p.XYZ(), size, overrideMinH );
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -606,15 +632,29 @@ namespace
|
|||||||
{
|
{
|
||||||
Standard_Real u = u1 + delta*i;
|
Standard_Real u = u1 + delta*i;
|
||||||
gp_Pnt p = curve->Value(u);
|
gp_Pnt p = curve->Value(u);
|
||||||
NETGENPlugin_Mesher::RestrictLocalSize( mesh, p.XYZ(), size );
|
NETGENPlugin_Mesher::RestrictLocalSize( mesh, p.XYZ(), size, overrideMinH );
|
||||||
netgen::Point3d pi(p.X(), p.Y(), p.Z());
|
netgen::Point3d pi(p.X(), p.Y(), p.Z());
|
||||||
double resultSize = mesh.GetH(pi);
|
double resultSize = mesh.GetH(pi);
|
||||||
if ( resultSize - size > 0.1*size )
|
if ( resultSize - size > 0.1*size )
|
||||||
// netgen does restriction iff oldH/newH > 1.2 (localh.cpp:136)
|
// netgen does restriction iff oldH/newH > 1.2 (localh.cpp:136)
|
||||||
NETGENPlugin_Mesher::RestrictLocalSize( mesh, p.XYZ(), resultSize/1.201 );
|
NETGENPlugin_Mesher::RestrictLocalSize( mesh, p.XYZ(), resultSize/1.201, overrideMinH );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//================================================================================
|
||||||
|
/*!
|
||||||
|
* \brief Return triangle size for a given chordalError and radius of curvature
|
||||||
|
*/
|
||||||
|
//================================================================================
|
||||||
|
|
||||||
|
double elemSizeForChordalError( double chordalError, double radius )
|
||||||
|
{
|
||||||
|
if ( 2 * radius < chordalError )
|
||||||
|
return 1.5 * radius;
|
||||||
|
return Sqrt( 3 ) * Sqrt( chordalError * ( 2 * radius - chordalError ));
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
//================================================================================
|
//================================================================================
|
||||||
@ -624,16 +664,19 @@ namespace
|
|||||||
//================================================================================
|
//================================================================================
|
||||||
|
|
||||||
void NETGENPlugin_Mesher::SetLocalSize( netgen::OCCGeometry& occgeo,
|
void NETGENPlugin_Mesher::SetLocalSize( netgen::OCCGeometry& occgeo,
|
||||||
netgen::Mesh& ngMesh )
|
netgen::Mesh& ngMesh)
|
||||||
{
|
{
|
||||||
for(std::map<int,double>::const_iterator it=EdgeId2LocalSize.begin(); it!=EdgeId2LocalSize.end(); it++)
|
// edges
|
||||||
|
std::map<int,double>::const_iterator it;
|
||||||
|
for( it=EdgeId2LocalSize.begin(); it!=EdgeId2LocalSize.end(); it++)
|
||||||
{
|
{
|
||||||
int key = (*it).first;
|
int key = (*it).first;
|
||||||
double hi = (*it).second;
|
double hi = (*it).second;
|
||||||
const TopoDS_Shape& shape = ShapesWithLocalSize.FindKey(key);
|
const TopoDS_Shape& shape = ShapesWithLocalSize.FindKey(key);
|
||||||
setLocalSize( TopoDS::Edge(shape), hi, ngMesh );
|
setLocalSize( TopoDS::Edge(shape), hi, ngMesh );
|
||||||
}
|
}
|
||||||
for(std::map<int,double>::const_iterator it=VertexId2LocalSize.begin(); it!=VertexId2LocalSize.end(); it++)
|
// vertices
|
||||||
|
for(it=VertexId2LocalSize.begin(); it!=VertexId2LocalSize.end(); it++)
|
||||||
{
|
{
|
||||||
int key = (*it).first;
|
int key = (*it).first;
|
||||||
double hi = (*it).second;
|
double hi = (*it).second;
|
||||||
@ -641,7 +684,8 @@ void NETGENPlugin_Mesher::SetLocalSize( netgen::OCCGeometry& occgeo,
|
|||||||
gp_Pnt p = BRep_Tool::Pnt( TopoDS::Vertex(shape) );
|
gp_Pnt p = BRep_Tool::Pnt( TopoDS::Vertex(shape) );
|
||||||
NETGENPlugin_Mesher::RestrictLocalSize( ngMesh, p.XYZ(), hi );
|
NETGENPlugin_Mesher::RestrictLocalSize( ngMesh, p.XYZ(), hi );
|
||||||
}
|
}
|
||||||
for(map<int,double>::const_iterator it=FaceId2LocalSize.begin(); it!=FaceId2LocalSize.end(); it++)
|
// faces
|
||||||
|
for(it=FaceId2LocalSize.begin(); it!=FaceId2LocalSize.end(); it++)
|
||||||
{
|
{
|
||||||
int key = (*it).first;
|
int key = (*it).first;
|
||||||
double val = (*it).second;
|
double val = (*it).second;
|
||||||
@ -659,7 +703,8 @@ void NETGENPlugin_Mesher::SetLocalSize( netgen::OCCGeometry& occgeo,
|
|||||||
ShapesWithControlPoints.insert( key );
|
ShapesWithControlPoints.insert( key );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for(map<int,double>::const_iterator it=SolidId2LocalSize.begin(); it!=SolidId2LocalSize.end(); it++)
|
//solids
|
||||||
|
for(it=SolidId2LocalSize.begin(); it!=SolidId2LocalSize.end(); it++)
|
||||||
{
|
{
|
||||||
int key = (*it).first;
|
int key = (*it).first;
|
||||||
double val = (*it).second;
|
double val = (*it).second;
|
||||||
@ -676,6 +721,146 @@ void NETGENPlugin_Mesher::SetLocalSize( netgen::OCCGeometry& occgeo,
|
|||||||
for ( size_t i = 0; i < ControlPoints.size(); ++i )
|
for ( size_t i = 0; i < ControlPoints.size(); ++i )
|
||||||
NETGENPlugin_Mesher::RestrictLocalSize( ngMesh, ControlPoints[i].XYZ(), ControlPoints[i].Size() );
|
NETGENPlugin_Mesher::RestrictLocalSize( ngMesh, ControlPoints[i].XYZ(), ControlPoints[i].Size() );
|
||||||
}
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
//================================================================================
|
||||||
|
/*!
|
||||||
|
* \brief Restrict local size to achieve a required _chordalError
|
||||||
|
*/
|
||||||
|
//================================================================================
|
||||||
|
|
||||||
|
void NETGENPlugin_Mesher::SetLocalSizeForChordalError( netgen::OCCGeometry& occgeo,
|
||||||
|
netgen::Mesh& ngMesh)
|
||||||
|
{
|
||||||
|
if ( _chordalError <= 0. )
|
||||||
|
return;
|
||||||
|
|
||||||
|
TopLoc_Location loc;
|
||||||
|
BRepLProp_SLProps surfProp( 2, 1e-6 );
|
||||||
|
const double sizeCoef = 0.95;
|
||||||
|
|
||||||
|
// find non-planar FACEs with non-constant curvature
|
||||||
|
std::vector<int> fInd;
|
||||||
|
for ( int i = 1; i <= occgeo.fmap.Extent(); ++i )
|
||||||
|
{
|
||||||
|
const TopoDS_Face& face = TopoDS::Face( occgeo.fmap( i ));
|
||||||
|
BRepAdaptor_Surface surfAd( face, false );
|
||||||
|
switch ( surfAd.GetType() )
|
||||||
|
{
|
||||||
|
case GeomAbs_Plane:
|
||||||
|
continue;
|
||||||
|
case GeomAbs_Cylinder:
|
||||||
|
case GeomAbs_Sphere:
|
||||||
|
case GeomAbs_Torus: // constant curvature
|
||||||
|
{
|
||||||
|
surfProp.SetSurface( surfAd );
|
||||||
|
surfProp.SetParameters( 0, 0 );
|
||||||
|
double maxCurv = Max( Abs( surfProp.MaxCurvature()), Abs( surfProp.MinCurvature() ));
|
||||||
|
double size = elemSizeForChordalError( _chordalError, 1 / maxCurv );
|
||||||
|
occgeo.SetFaceMaxH( i, size * sizeCoef );
|
||||||
|
// limit size one edges
|
||||||
|
TopTools_MapOfShape edgeMap;
|
||||||
|
for ( TopExp_Explorer eExp( face, TopAbs_EDGE ); eExp.More(); eExp.Next() )
|
||||||
|
if ( edgeMap.Add( eExp.Current() ))
|
||||||
|
setLocalSize( TopoDS::Edge( eExp.Current() ), size, ngMesh, /*overrideMinH=*/false );
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
Handle(Geom_Surface) surf = BRep_Tool::Surface( face, loc );
|
||||||
|
if ( GeomLib_IsPlanarSurface( surf ).IsPlanar() )
|
||||||
|
continue;
|
||||||
|
fInd.push_back( i );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// set local size
|
||||||
|
if ( !fInd.empty() )
|
||||||
|
{
|
||||||
|
BRep_Builder b;
|
||||||
|
TopoDS_Compound allFacesComp;
|
||||||
|
b.MakeCompound( allFacesComp );
|
||||||
|
for ( size_t i = 0; i < fInd.size(); ++i )
|
||||||
|
b.Add( allFacesComp, occgeo.fmap( fInd[i] ));
|
||||||
|
|
||||||
|
// copy the shape to avoid spoiling its triangulation
|
||||||
|
TopoDS_Shape allFacesCompCopy = BRepBuilderAPI_Copy( allFacesComp );
|
||||||
|
|
||||||
|
// create triangulation with desired chordal error
|
||||||
|
BRepMesh_IncrementalMesh( allFacesCompCopy,
|
||||||
|
_chordalError,
|
||||||
|
/*isRelative = */Standard_False,
|
||||||
|
/*theAngDeflection = */ 0.5,
|
||||||
|
/*isInParallel = */Standard_True);
|
||||||
|
|
||||||
|
// loop on FACEs
|
||||||
|
for ( TopExp_Explorer fExp( allFacesCompCopy, TopAbs_FACE ); fExp.More(); fExp.Next() )
|
||||||
|
{
|
||||||
|
const TopoDS_Face& face = TopoDS::Face( fExp.Current() );
|
||||||
|
Handle(Poly_Triangulation) triangulation = BRep_Tool::Triangulation ( face, loc );
|
||||||
|
if ( triangulation.IsNull() ) continue;
|
||||||
|
|
||||||
|
BRepAdaptor_Surface surf( face, false );
|
||||||
|
surfProp.SetSurface( surf );
|
||||||
|
|
||||||
|
gp_XY uv[3];
|
||||||
|
gp_XYZ p[3];
|
||||||
|
double size[3];
|
||||||
|
for ( int i = 1; i <= triangulation->NbTriangles(); ++i )
|
||||||
|
{
|
||||||
|
Standard_Integer n1,n2,n3;
|
||||||
|
triangulation->Triangles()(i).Get( n1,n2,n3 );
|
||||||
|
p [0] = triangulation->Nodes()(n1).Transformed(loc).XYZ();
|
||||||
|
p [1] = triangulation->Nodes()(n2).Transformed(loc).XYZ();
|
||||||
|
p [2] = triangulation->Nodes()(n3).Transformed(loc).XYZ();
|
||||||
|
uv[0] = triangulation->UVNodes()(n1).XY();
|
||||||
|
uv[1] = triangulation->UVNodes()(n2).XY();
|
||||||
|
uv[2] = triangulation->UVNodes()(n3).XY();
|
||||||
|
surfProp.SetParameters( uv[0].X(), uv[0].Y() );
|
||||||
|
if ( !surfProp.IsCurvatureDefined() )
|
||||||
|
break;
|
||||||
|
|
||||||
|
for ( int n = 0; n < 3; ++n ) // get size at triangle nodes
|
||||||
|
{
|
||||||
|
surfProp.SetParameters( uv[n].X(), uv[n].Y() );
|
||||||
|
double maxCurv = Max( Abs( surfProp.MaxCurvature()), Abs( surfProp.MinCurvature() ));
|
||||||
|
size[n] = elemSizeForChordalError( _chordalError, 1 / maxCurv );
|
||||||
|
}
|
||||||
|
for ( int n1 = 0; n1 < 3; ++n1 ) // limit size along each triangle edge
|
||||||
|
{
|
||||||
|
int n2 = ( n1 + 1 ) % 3;
|
||||||
|
double minSize = size[n1], maxSize = size[n2];
|
||||||
|
if ( size[n1] > size[n2] )
|
||||||
|
minSize = size[n2], maxSize = size[n1];
|
||||||
|
|
||||||
|
if ( maxSize / minSize < 1.2 ) // netgen ignores size difference < 1.2
|
||||||
|
{
|
||||||
|
ngMesh.RestrictLocalHLine ( netgen::Point3d( p[n1].X(), p[n1].Y(), p[n1].Z() ),
|
||||||
|
netgen::Point3d( p[n2].X(), p[n2].Y(), p[n2].Z() ),
|
||||||
|
sizeCoef * minSize );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
gp_XY uvVec( uv[n2] - uv[n1] );
|
||||||
|
double len = ( p[n1] - p[n2] ).Modulus();
|
||||||
|
int nb = int( len / minSize ) + 1;
|
||||||
|
for ( int j = 0; j <= nb; ++j )
|
||||||
|
{
|
||||||
|
double r = double( j ) / nb;
|
||||||
|
gp_XY uvj = uv[n1] + r * uvVec;
|
||||||
|
|
||||||
|
surfProp.SetParameters( uvj.X(), uvj.Y() );
|
||||||
|
double maxCurv = Max( Abs( surfProp.MaxCurvature()), Abs( surfProp.MinCurvature() ));
|
||||||
|
double h = elemSizeForChordalError( _chordalError, 1 / maxCurv );
|
||||||
|
|
||||||
|
const gp_Pnt& pj = surfProp.Value();
|
||||||
|
netgen::Point3d ngP( pj.X(), pj.Y(), pj.Z());
|
||||||
|
ngMesh.RestrictLocalH( ngP, h * sizeCoef );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//================================================================================
|
//================================================================================
|
||||||
@ -808,7 +993,7 @@ double NETGENPlugin_Mesher::GetDefaultMinSize(const TopoDS_Shape& geom,
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
minh = 3 * sqrt( minh ); // triangulation for visualization is rather fine
|
minh = sqrt( minh ); // triangulation for visualization is rather fine
|
||||||
//cout << "TRIANGULATION minh = " <<minh << endl;
|
//cout << "TRIANGULATION minh = " <<minh << endl;
|
||||||
}
|
}
|
||||||
if ( minh > 0.5 * maxSize )
|
if ( minh > 0.5 * maxSize )
|
||||||
@ -926,7 +1111,8 @@ bool NETGENPlugin_Mesher::FillNgMesh(netgen::OCCGeometry& occgeom,
|
|||||||
|
|
||||||
// get all nodes from connected <edges>
|
// get all nodes from connected <edges>
|
||||||
const bool isQuad = smDS->IsQuadratic();
|
const bool isQuad = smDS->IsQuadratic();
|
||||||
StdMeshers_FaceSide fSide( face, edges, _mesh, isForwad, isQuad );
|
//StdMeshers_FaceSide fSide( face, edges, _mesh, isForwad, isQuad, &helper ); -- master
|
||||||
|
StdMeshers_FaceSide fSide( face, edges, _mesh, isForwad, isQuad ); // -- V8_2_BR
|
||||||
const vector<UVPtStruct>& points = fSide.GetUVPtStruct();
|
const vector<UVPtStruct>& points = fSide.GetUVPtStruct();
|
||||||
if ( points.empty() )
|
if ( points.empty() )
|
||||||
return false; // invalid node params?
|
return false; // invalid node params?
|
||||||
@ -1054,13 +1240,6 @@ bool NETGENPlugin_Mesher::FillNgMesh(netgen::OCCGeometry& occgeom,
|
|||||||
|
|
||||||
// Find solids the geomFace bounds
|
// Find solids the geomFace bounds
|
||||||
int solidID1 = 0, solidID2 = 0;
|
int solidID1 = 0, solidID2 = 0;
|
||||||
StdMeshers_QuadToTriaAdaptor* quadAdaptor =
|
|
||||||
dynamic_cast<StdMeshers_QuadToTriaAdaptor*>( proxyMesh.get() );
|
|
||||||
if ( quadAdaptor )
|
|
||||||
{
|
|
||||||
solidID1 = occgeom.somap.FindIndex( quadAdaptor->GetShape() );
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
PShapeIteratorPtr solidIt = helper.GetAncestors( geomFace, *sm->GetFather(), TopAbs_SOLID);
|
PShapeIteratorPtr solidIt = helper.GetAncestors( geomFace, *sm->GetFather(), TopAbs_SOLID);
|
||||||
while ( const TopoDS_Shape * solid = solidIt->next() )
|
while ( const TopoDS_Shape * solid = solidIt->next() )
|
||||||
@ -1070,6 +1249,81 @@ bool NETGENPlugin_Mesher::FillNgMesh(netgen::OCCGeometry& occgeom,
|
|||||||
else solidID1 = id;
|
else solidID1 = id;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if ( proxyMesh && proxyMesh->GetProxySubMesh( geomFace ))
|
||||||
|
{
|
||||||
|
// if a proxy sub-mesh contains temporary faces, then these faces
|
||||||
|
// should be used to mesh only one SOLID
|
||||||
|
bool hasTmp = false;
|
||||||
|
smDS = proxyMesh->GetSubMesh( geomFace );
|
||||||
|
SMDS_ElemIteratorPtr faces = smDS->GetElements();
|
||||||
|
while ( faces->more() )
|
||||||
|
{
|
||||||
|
const SMDS_MeshElement* f = faces->next();
|
||||||
|
if ( proxyMesh->IsTemporary( f ))
|
||||||
|
{
|
||||||
|
hasTmp = true;
|
||||||
|
std::vector<const SMDS_MeshNode*> fNodes( f->begin_nodes(), f->end_nodes() );
|
||||||
|
std::vector<const SMDS_MeshElement*> vols;
|
||||||
|
if ( _mesh->GetMeshDS()->GetElementsByNodes( fNodes, vols, SMDSAbs_Volume ) == 1 )
|
||||||
|
{
|
||||||
|
int geomID = vols[0]->getshapeId();
|
||||||
|
const TopoDS_Shape& solid = helper.GetMeshDS()->IndexToShape( geomID );
|
||||||
|
if ( !solid.IsNull() )
|
||||||
|
solidID1 = occgeom.somap.FindIndex ( solid );
|
||||||
|
solidID2 = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// exclude faces generated by NETGEN from computation of 3D mesh
|
||||||
|
const int fID = occgeom.fmap.FindIndex( geomFace );
|
||||||
|
if ( !hasTmp ) // shrunk mesh
|
||||||
|
{
|
||||||
|
// move netgen points according to moved nodes
|
||||||
|
SMESH_subMeshIteratorPtr smIt = sm->getDependsOnIterator(/*includeSelf=*/true);
|
||||||
|
while ( smIt->more() )
|
||||||
|
{
|
||||||
|
SMESH_subMesh* sub = smIt->next();
|
||||||
|
if ( !sub->GetSubMeshDS() ) continue;
|
||||||
|
SMDS_NodeIteratorPtr nodeIt = sub->GetSubMeshDS()->GetNodes();
|
||||||
|
while ( nodeIt->more() )
|
||||||
|
{
|
||||||
|
const SMDS_MeshNode* n = nodeIt->next();
|
||||||
|
int ngID = ngNodeId( n, ngMesh, nodeNgIdMap );
|
||||||
|
netgen::MeshPoint& ngPoint = ngMesh.Point( ngID );
|
||||||
|
ngPoint(0) = n->X();
|
||||||
|
ngPoint(1) = n->Y();
|
||||||
|
ngPoint(2) = n->Z();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// remove faces near boundary to avoid their overlapping
|
||||||
|
// with shrunk faces
|
||||||
|
for ( int i = 1; i <= ngMesh.GetNSE(); ++i )
|
||||||
|
{
|
||||||
|
const netgen::Element2d& elem = ngMesh.SurfaceElement(i);
|
||||||
|
if ( elem.GetIndex() == fID )
|
||||||
|
{
|
||||||
|
for ( int iN = 0; iN < elem.GetNP(); ++iN )
|
||||||
|
if ( ngMesh[ elem[ iN ]].Type() != netgen::SURFACEPOINT )
|
||||||
|
{
|
||||||
|
ngMesh.DeleteSurfaceElement( i );
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//if ( hasTmp )
|
||||||
|
{
|
||||||
|
faceNgID++;
|
||||||
|
ngMesh.AddFaceDescriptor( netgen::FaceDescriptor( faceNgID,/*solid1=*/0,/*solid2=*/0,0 ));
|
||||||
|
for (int i = 1; i <= ngMesh.GetNSE(); ++i )
|
||||||
|
{
|
||||||
|
const netgen::Element2d& elem = ngMesh.SurfaceElement(i);
|
||||||
|
if ( elem.GetIndex() == fID )
|
||||||
|
const_cast< netgen::Element2d& >( elem ).SetIndex( faceNgID );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
// Add ng face descriptors of meshed faces
|
// Add ng face descriptors of meshed faces
|
||||||
faceNgID++;
|
faceNgID++;
|
||||||
ngMesh.AddFaceDescriptor( netgen::FaceDescriptor( faceNgID, solidID1, solidID2, 0 ));
|
ngMesh.AddFaceDescriptor( netgen::FaceDescriptor( faceNgID, solidID1, solidID2, 0 ));
|
||||||
@ -1112,8 +1366,6 @@ bool NETGENPlugin_Mesher::FillNgMesh(netgen::OCCGeometry& occgeom,
|
|||||||
cout << "SMESH face " << helper.GetMeshDS()->ShapeToIndex( geomFace )
|
cout << "SMESH face " << helper.GetMeshDS()->ShapeToIndex( geomFace )
|
||||||
<< " internal="<<isInternalFace << endl;
|
<< " internal="<<isInternalFace << endl;
|
||||||
#endif
|
#endif
|
||||||
if ( proxyMesh )
|
|
||||||
smDS = proxyMesh->GetSubMesh( geomFace );
|
|
||||||
|
|
||||||
SMDS_ElemIteratorPtr faces = smDS->GetElements();
|
SMDS_ElemIteratorPtr faces = smDS->GetElements();
|
||||||
while ( faces->more() )
|
while ( faces->more() )
|
||||||
@ -1430,10 +1682,15 @@ namespace
|
|||||||
int ngIdCloseN; //!< ng id of closest node of the closest 2d mesh element
|
int ngIdCloseN; //!< ng id of closest node of the closest 2d mesh element
|
||||||
};
|
};
|
||||||
|
|
||||||
inline double dist2(const netgen::MeshPoint& p1, const netgen::MeshPoint& p2)
|
inline double dist2( const netgen::MeshPoint& p1, const netgen::MeshPoint& p2 )
|
||||||
{
|
{
|
||||||
return gp_Pnt( NGPOINT_COORDS(p1)).SquareDistance( gp_Pnt( NGPOINT_COORDS(p2)));
|
return gp_Pnt( NGPOINT_COORDS(p1)).SquareDistance( gp_Pnt( NGPOINT_COORDS(p2)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// inline double dist2(const netgen::MeshPoint& p, const SMDS_MeshNode* n )
|
||||||
|
// {
|
||||||
|
// return gp_Pnt( NGPOINT_COORDS(p)).SquareDistance( SMESH_NodeXYZ(n));
|
||||||
|
// }
|
||||||
}
|
}
|
||||||
|
|
||||||
//================================================================================
|
//================================================================================
|
||||||
@ -2136,13 +2393,35 @@ int NETGENPlugin_Mesher::FillSMesh(const netgen::OCCGeometry& occgeo,
|
|||||||
if ( quadHelper && !quadHelper->GetIsQuadratic() && quadHelper->GetTLinkNodeMap().empty() )
|
if ( quadHelper && !quadHelper->GetIsQuadratic() && quadHelper->GetTLinkNodeMap().empty() )
|
||||||
quadHelper = 0;
|
quadHelper = 0;
|
||||||
|
|
||||||
|
int i, nbInitNod = initState._nbNodes;
|
||||||
|
if ( initState._elementsRemoved )
|
||||||
|
{
|
||||||
|
// PAL23427. Update nodeVec to track removal of netgen free points as a result
|
||||||
|
// of removal of faces in FillNgMesh() in the case of a shrunk sub-mesh
|
||||||
|
int ngID, nodeVecSize = nodeVec.size();
|
||||||
|
const double eps = std::numeric_limits<double>::min();
|
||||||
|
for ( ngID = i = 1; i < nodeVecSize; ++ngID, ++i )
|
||||||
|
{
|
||||||
|
gp_Pnt ngPnt( NGPOINT_COORDS( ngMesh.Point( ngID )));
|
||||||
|
gp_Pnt node ( SMESH_NodeXYZ ( nodeVec[ i ]));
|
||||||
|
if ( ngPnt.SquareDistance( node ) < eps )
|
||||||
|
{
|
||||||
|
nodeVec[ ngID ] = nodeVec[ i ];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
--ngID;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
nodeVec.resize( ngID );
|
||||||
|
nbInitNod = ngID - 1;
|
||||||
|
}
|
||||||
// -------------------------------------
|
// -------------------------------------
|
||||||
// Create and insert nodes into nodeVec
|
// Create and insert nodes into nodeVec
|
||||||
// -------------------------------------
|
// -------------------------------------
|
||||||
|
|
||||||
nodeVec.resize( nbNod + 1 );
|
nodeVec.resize( nbNod + 1 );
|
||||||
int i, nbInitNod = initState._nbNodes;
|
for ( i = nbInitNod+1; i <= nbNod; ++i )
|
||||||
for (i = nbInitNod+1; i <= nbNod; ++i )
|
|
||||||
{
|
{
|
||||||
const netgen::MeshPoint& ngPoint = ngMesh.Point(i);
|
const netgen::MeshPoint& ngPoint = ngMesh.Point(i);
|
||||||
SMDS_MeshNode* node = NULL;
|
SMDS_MeshNode* node = NULL;
|
||||||
@ -2503,8 +2782,6 @@ bool NETGENPlugin_Mesher::Compute()
|
|||||||
SMESH_MesherHelper quadHelper( *_mesh );
|
SMESH_MesherHelper quadHelper( *_mesh );
|
||||||
quadHelper.SetIsQuadratic( mparams.secondorder );
|
quadHelper.SetIsQuadratic( mparams.secondorder );
|
||||||
|
|
||||||
static string debugFile = "/tmp/ngMesh.py"; /* to call toPython( _ngMesh, debugFile )
|
|
||||||
while debugging netgen */
|
|
||||||
// -------------------------
|
// -------------------------
|
||||||
// Prepare OCC geometry
|
// Prepare OCC geometry
|
||||||
// -------------------------
|
// -------------------------
|
||||||
@ -2621,6 +2898,7 @@ bool NETGENPlugin_Mesher::Compute()
|
|||||||
{
|
{
|
||||||
// Local size on shapes
|
// Local size on shapes
|
||||||
SetLocalSize( occgeo, *_ngMesh );
|
SetLocalSize( occgeo, *_ngMesh );
|
||||||
|
SetLocalSizeForChordalError( occgeo, *_ngMesh );
|
||||||
}
|
}
|
||||||
|
|
||||||
// Precompute internal edges (issue 0020676) in order to
|
// Precompute internal edges (issue 0020676) in order to
|
||||||
@ -2791,7 +3069,8 @@ bool NETGENPlugin_Mesher::Compute()
|
|||||||
helper.SetSubShape( F );
|
helper.SetSubShape( F );
|
||||||
TSideVector wires =
|
TSideVector wires =
|
||||||
StdMeshers_FaceSide::GetFaceWires( F, *_mesh, /*skipMediumNodes=*/true,
|
StdMeshers_FaceSide::GetFaceWires( F, *_mesh, /*skipMediumNodes=*/true,
|
||||||
error, viscousMesh );
|
error, viscousMesh ); // -- V8_2_BR
|
||||||
|
// error, &helper, viscousMesh ); -- master
|
||||||
error = AddSegmentsToMesh( *_ngMesh, occgeo, wires, helper, nodeVec );
|
error = AddSegmentsToMesh( *_ngMesh, occgeo, wires, helper, nodeVec );
|
||||||
|
|
||||||
if ( !error ) error = SMESH_ComputeError::New();
|
if ( !error ) error = SMESH_ComputeError::New();
|
||||||
@ -2835,37 +3114,58 @@ bool NETGENPlugin_Mesher::Compute()
|
|||||||
// generate volume mesh
|
// generate volume mesh
|
||||||
// ---------------------
|
// ---------------------
|
||||||
// Fill _ngMesh with nodes and faces of computed 2D submeshes
|
// Fill _ngMesh with nodes and faces of computed 2D submeshes
|
||||||
if ( !err && _isVolume && ( !meshedSM[ MeshDim_2D ].empty() || mparams.quad ))
|
if ( !err && _isVolume &&
|
||||||
|
( !meshedSM[ MeshDim_2D ].empty() || mparams.quad || _viscousLayersHyp ))
|
||||||
{
|
{
|
||||||
// load SMESH with computed segments and faces
|
// load SMESH with computed segments and faces
|
||||||
FillSMesh( occgeo, *_ngMesh, initState, *_mesh, nodeVec, comment, &quadHelper );
|
FillSMesh( occgeo, *_ngMesh, initState, *_mesh, nodeVec, comment, &quadHelper );
|
||||||
|
|
||||||
|
// compute prismatic boundary volumes
|
||||||
|
int nbQuad = _mesh->NbQuadrangles();
|
||||||
|
SMESH_ProxyMesh::Ptr viscousMesh;
|
||||||
|
if ( _viscousLayersHyp )
|
||||||
|
{
|
||||||
|
viscousMesh = _viscousLayersHyp->Compute( *_mesh, _shape );
|
||||||
|
if ( !viscousMesh )
|
||||||
|
return false;
|
||||||
|
}
|
||||||
// compute pyramids on quadrangles
|
// compute pyramids on quadrangles
|
||||||
SMESH_ProxyMesh::Ptr proxyMesh;
|
vector<SMESH_ProxyMesh::Ptr> pyramidMeshes( occgeo.somap.Extent() );
|
||||||
if ( _mesh->NbQuadrangles() > 0 )
|
if ( nbQuad > 0 )
|
||||||
for ( int iS = 1; iS <= occgeo.somap.Extent(); ++iS )
|
for ( int iS = 1; iS <= occgeo.somap.Extent(); ++iS )
|
||||||
{
|
{
|
||||||
StdMeshers_QuadToTriaAdaptor* Adaptor = new StdMeshers_QuadToTriaAdaptor;
|
StdMeshers_QuadToTriaAdaptor* adaptor = new StdMeshers_QuadToTriaAdaptor;
|
||||||
proxyMesh.reset( Adaptor );
|
pyramidMeshes[ iS-1 ].reset( adaptor );
|
||||||
|
bool ok = adaptor->Compute( *_mesh, occgeo.somap(iS), viscousMesh.get() );
|
||||||
int nbPyrams = _mesh->NbPyramids();
|
if ( !ok )
|
||||||
Adaptor->Compute( *_mesh, occgeo.somap(iS) );
|
return false;
|
||||||
if ( nbPyrams != _mesh->NbPyramids() )
|
|
||||||
{
|
|
||||||
list< SMESH_subMesh* > quadFaceSM;
|
|
||||||
for (TopExp_Explorer face(occgeo.somap(iS), TopAbs_FACE); face.More(); face.Next())
|
|
||||||
if ( Adaptor->GetProxySubMesh( face.Current() ))
|
|
||||||
{
|
|
||||||
quadFaceSM.push_back( _mesh->GetSubMesh( face.Current() ));
|
|
||||||
meshedSM[ MeshDim_2D ].remove( quadFaceSM.back() );
|
|
||||||
}
|
|
||||||
FillNgMesh(occgeo, *_ngMesh, nodeVec, quadFaceSM, &quadHelper, proxyMesh);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
// add proxy faces to NG mesh
|
||||||
|
list< SMESH_subMesh* > viscousSM;
|
||||||
|
for ( int iS = 1; iS <= occgeo.somap.Extent(); ++iS )
|
||||||
|
{
|
||||||
|
list< SMESH_subMesh* > quadFaceSM;
|
||||||
|
for (TopExp_Explorer face(occgeo.somap(iS), TopAbs_FACE); face.More(); face.Next())
|
||||||
|
if ( pyramidMeshes[iS-1] && pyramidMeshes[iS-1]->GetProxySubMesh( face.Current() ))
|
||||||
|
{
|
||||||
|
quadFaceSM.push_back( _mesh->GetSubMesh( face.Current() ));
|
||||||
|
meshedSM[ MeshDim_2D ].remove( quadFaceSM.back() );
|
||||||
|
}
|
||||||
|
else if ( viscousMesh && viscousMesh->GetProxySubMesh( face.Current() ))
|
||||||
|
{
|
||||||
|
viscousSM.push_back( _mesh->GetSubMesh( face.Current() ));
|
||||||
|
meshedSM[ MeshDim_2D ].remove( viscousSM.back() );
|
||||||
|
}
|
||||||
|
if ( !quadFaceSM.empty() )
|
||||||
|
FillNgMesh(occgeo, *_ngMesh, nodeVec, quadFaceSM, &quadHelper, pyramidMeshes[iS-1]);
|
||||||
|
}
|
||||||
|
if ( !viscousSM.empty() )
|
||||||
|
FillNgMesh(occgeo, *_ngMesh, nodeVec, viscousSM, &quadHelper, viscousMesh );
|
||||||
|
|
||||||
// fill _ngMesh with faces of sub-meshes
|
// fill _ngMesh with faces of sub-meshes
|
||||||
err = ! ( FillNgMesh(occgeo, *_ngMesh, nodeVec, meshedSM[ MeshDim_2D ], &quadHelper));
|
err = ! ( FillNgMesh(occgeo, *_ngMesh, nodeVec, meshedSM[ MeshDim_2D ], &quadHelper));
|
||||||
initState = NETGENPlugin_ngMeshInfo(_ngMesh);
|
initState = NETGENPlugin_ngMeshInfo(_ngMesh, /*checkRemovedElems=*/true);
|
||||||
//toPython( _ngMesh, "/tmp/ngPython.py");
|
// toPython( _ngMesh );
|
||||||
}
|
}
|
||||||
if (!err && _isVolume)
|
if (!err && _isVolume)
|
||||||
{
|
{
|
||||||
@ -3166,25 +3466,25 @@ bool NETGENPlugin_Mesher::Evaluate(MapShapeNbElems& aResMap)
|
|||||||
sm->GetComputeError().reset( new SMESH_ComputeError( COMPERR_ALGO_FAILED ));
|
sm->GetComputeError().reset( new SMESH_ComputeError( COMPERR_ALGO_FAILED ));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if ( _simpleHyp )
|
// if ( _simpleHyp )
|
||||||
{
|
// {
|
||||||
// Pass 1D simple parameters to NETGEN
|
// // Pass 1D simple parameters to NETGEN
|
||||||
// --------------------------------
|
// // --------------------------------
|
||||||
int nbSeg = _simpleHyp->GetNumberOfSegments();
|
// int nbSeg = _simpleHyp->GetNumberOfSegments();
|
||||||
double segSize = _simpleHyp->GetLocalLength();
|
// double segSize = _simpleHyp->GetLocalLength();
|
||||||
for ( int iE = 1; iE <= occgeo.emap.Extent(); ++iE )
|
// for ( int iE = 1; iE <= occgeo.emap.Extent(); ++iE )
|
||||||
{
|
// {
|
||||||
const TopoDS_Edge& e = TopoDS::Edge( occgeo.emap(iE));
|
// const TopoDS_Edge& e = TopoDS::Edge( occgeo.emap(iE));
|
||||||
if ( nbSeg )
|
// if ( nbSeg )
|
||||||
segSize = SMESH_Algo::EdgeLength( e ) / ( nbSeg - 0.4 );
|
// segSize = SMESH_Algo::EdgeLength( e ) / ( nbSeg - 0.4 );
|
||||||
setLocalSize( e, segSize, *ngMesh );
|
// setLocalSize( e, segSize, *ngMesh );
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
else // if ( ! _simpleHyp )
|
// else // if ( ! _simpleHyp )
|
||||||
{
|
// {
|
||||||
// Local size on shapes
|
// // Local size on shapes
|
||||||
SetLocalSize( occgeo, *ngMesh );
|
// SetLocalSize( occgeo, *ngMesh );
|
||||||
}
|
// }
|
||||||
// calculate total nb of segments and length of edges
|
// calculate total nb of segments and length of edges
|
||||||
double fullLen = 0.0;
|
double fullLen = 0.0;
|
||||||
int fullNbSeg = 0;
|
int fullNbSeg = 0;
|
||||||
@ -3492,7 +3792,7 @@ void NETGENPlugin_Mesher::toPython( const netgen::Mesh* ngMesh )
|
|||||||
ofstream outfile( pyFile, ios::out );
|
ofstream outfile( pyFile, ios::out );
|
||||||
if ( !outfile ) return;
|
if ( !outfile ) return;
|
||||||
|
|
||||||
outfile << "import SMESH" << endl
|
outfile << "import salome, SMESH" << endl
|
||||||
<< "from salome.smesh import smeshBuilder" << endl
|
<< "from salome.smesh import smeshBuilder" << endl
|
||||||
<< "smesh = smeshBuilder.New(salome.myStudy)" << endl
|
<< "smesh = smeshBuilder.New(salome.myStudy)" << endl
|
||||||
<< "mesh = smesh.Mesh()" << endl << endl;
|
<< "mesh = smesh.Mesh()" << endl << endl;
|
||||||
@ -3556,8 +3856,9 @@ void NETGENPlugin_Mesher::toPython( const netgen::Mesh* ngMesh )
|
|||||||
*/
|
*/
|
||||||
//================================================================================
|
//================================================================================
|
||||||
|
|
||||||
NETGENPlugin_ngMeshInfo::NETGENPlugin_ngMeshInfo( netgen::Mesh* ngMesh):
|
NETGENPlugin_ngMeshInfo::NETGENPlugin_ngMeshInfo( netgen::Mesh* ngMesh,
|
||||||
_copyOfLocalH(0)
|
bool checkRemovedElems):
|
||||||
|
_elementsRemoved( false ), _copyOfLocalH(0)
|
||||||
{
|
{
|
||||||
if ( ngMesh )
|
if ( ngMesh )
|
||||||
{
|
{
|
||||||
@ -3565,6 +3866,10 @@ NETGENPlugin_ngMeshInfo::NETGENPlugin_ngMeshInfo( netgen::Mesh* ngMesh):
|
|||||||
_nbSegments = ngMesh->GetNSeg();
|
_nbSegments = ngMesh->GetNSeg();
|
||||||
_nbFaces = ngMesh->GetNSE();
|
_nbFaces = ngMesh->GetNSE();
|
||||||
_nbVolumes = ngMesh->GetNE();
|
_nbVolumes = ngMesh->GetNE();
|
||||||
|
|
||||||
|
if ( checkRemovedElems )
|
||||||
|
for ( int i = 1; i <= ngMesh->GetNSE() && !_elementsRemoved; ++i )
|
||||||
|
_elementsRemoved = ngMesh->SurfaceElement(i).IsDeleted();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -46,14 +46,15 @@ namespace nglib {
|
|||||||
#include <vector>
|
#include <vector>
|
||||||
#include <set>
|
#include <set>
|
||||||
|
|
||||||
|
class NETGENPlugin_Hypothesis;
|
||||||
|
class NETGENPlugin_Internals;
|
||||||
|
class NETGENPlugin_SimpleHypothesis_2D;
|
||||||
class SMESHDS_Mesh;
|
class SMESHDS_Mesh;
|
||||||
class SMESH_Comment;
|
class SMESH_Comment;
|
||||||
class SMESH_Mesh;
|
class SMESH_Mesh;
|
||||||
class SMESH_MesherHelper;
|
class SMESH_MesherHelper;
|
||||||
|
class StdMeshers_ViscousLayers;
|
||||||
class TopoDS_Shape;
|
class TopoDS_Shape;
|
||||||
class NETGENPlugin_Hypothesis;
|
|
||||||
class NETGENPlugin_SimpleHypothesis_2D;
|
|
||||||
class NETGENPlugin_Internals;
|
|
||||||
namespace netgen {
|
namespace netgen {
|
||||||
class OCCGeometry;
|
class OCCGeometry;
|
||||||
class Mesh;
|
class Mesh;
|
||||||
@ -66,9 +67,10 @@ namespace netgen {
|
|||||||
|
|
||||||
struct NETGENPlugin_ngMeshInfo
|
struct NETGENPlugin_ngMeshInfo
|
||||||
{
|
{
|
||||||
int _nbNodes, _nbSegments, _nbFaces, _nbVolumes;
|
int _nbNodes, _nbSegments, _nbFaces, _nbVolumes;
|
||||||
|
bool _elementsRemoved; // case where netgen can remove free nodes
|
||||||
char* _copyOfLocalH;
|
char* _copyOfLocalH;
|
||||||
NETGENPlugin_ngMeshInfo( netgen::Mesh* ngMesh=0);
|
NETGENPlugin_ngMeshInfo( netgen::Mesh* ngMesh=0, bool checkRemovedElems=false );
|
||||||
void transferLocalH( netgen::Mesh* fromMesh, netgen::Mesh* toMesh );
|
void transferLocalH( netgen::Mesh* fromMesh, netgen::Mesh* toMesh );
|
||||||
void restoreLocalH ( netgen::Mesh* ngMesh);
|
void restoreLocalH ( netgen::Mesh* ngMesh);
|
||||||
};
|
};
|
||||||
@ -120,7 +122,10 @@ class NETGENPLUGIN_EXPORT NETGENPlugin_Mesher
|
|||||||
|
|
||||||
void SetParameters(const NETGENPlugin_Hypothesis* hyp);
|
void SetParameters(const NETGENPlugin_Hypothesis* hyp);
|
||||||
void SetParameters(const NETGENPlugin_SimpleHypothesis_2D* hyp);
|
void SetParameters(const NETGENPlugin_SimpleHypothesis_2D* hyp);
|
||||||
|
void SetParameters(const StdMeshers_ViscousLayers* hyp );
|
||||||
void SetViscousLayers2DAssigned(bool isAssigned) { _isViscousLayers2D = isAssigned; }
|
void SetViscousLayers2DAssigned(bool isAssigned) { _isViscousLayers2D = isAssigned; }
|
||||||
|
|
||||||
|
void SetLocalSizeForChordalError( netgen::OCCGeometry& occgeo, netgen::Mesh& ngMesh );
|
||||||
static void SetLocalSize( netgen::OCCGeometry& occgeo, netgen::Mesh& ngMesh );
|
static void SetLocalSize( netgen::OCCGeometry& occgeo, netgen::Mesh& ngMesh );
|
||||||
|
|
||||||
bool Compute();
|
bool Compute();
|
||||||
@ -201,6 +206,7 @@ class NETGENPLUGIN_EXPORT NETGENPlugin_Mesher
|
|||||||
bool _optimize;
|
bool _optimize;
|
||||||
int _fineness;
|
int _fineness;
|
||||||
bool _isViscousLayers2D;
|
bool _isViscousLayers2D;
|
||||||
|
double _chordalError;
|
||||||
netgen::Mesh* _ngMesh;
|
netgen::Mesh* _ngMesh;
|
||||||
netgen::OCCGeometry* _occgeom;
|
netgen::OCCGeometry* _occgeom;
|
||||||
|
|
||||||
@ -210,6 +216,7 @@ class NETGENPLUGIN_EXPORT NETGENPlugin_Mesher
|
|||||||
volatile double _totalTime;
|
volatile double _totalTime;
|
||||||
|
|
||||||
const NETGENPlugin_SimpleHypothesis_2D * _simpleHyp;
|
const NETGENPlugin_SimpleHypothesis_2D * _simpleHyp;
|
||||||
|
const StdMeshers_ViscousLayers* _viscousLayersHyp;
|
||||||
|
|
||||||
// a pointer to NETGENPlugin_Mesher* field of the holder, that will be
|
// a pointer to NETGENPlugin_Mesher* field of the holder, that will be
|
||||||
// nullified at destruction of this
|
// nullified at destruction of this
|
||||||
|
@ -319,6 +319,7 @@ bool NETGENPlugin_NETGEN_2D_ONLY::Compute(SMESH_Mesh& aMesh,
|
|||||||
|
|
||||||
// set local size defined on shapes
|
// set local size defined on shapes
|
||||||
aMesher.SetLocalSize( occgeoComm, *ngMeshes[0] );
|
aMesher.SetLocalSize( occgeoComm, *ngMeshes[0] );
|
||||||
|
aMesher.SetLocalSizeForChordalError( occgeoComm, *ngMeshes[0] );
|
||||||
try {
|
try {
|
||||||
ngMeshes[0]->LoadLocalMeshSize( mparam.meshsizefilename );
|
ngMeshes[0]->LoadLocalMeshSize( mparam.meshsizefilename );
|
||||||
} catch (NgException & ex) {
|
} catch (NgException & ex) {
|
||||||
@ -460,6 +461,7 @@ bool NETGENPlugin_NETGEN_2D_ONLY::Compute(SMESH_Mesh& aMesh,
|
|||||||
bb.Increase (bb.Diam()/10);
|
bb.Increase (bb.Diam()/10);
|
||||||
ngMesh->SetLocalH (bb.PMin(), bb.PMax(), mparam.grading);
|
ngMesh->SetLocalH (bb.PMin(), bb.PMax(), mparam.grading);
|
||||||
aMesher.SetLocalSize( occgeom, *ngMesh );
|
aMesher.SetLocalSize( occgeom, *ngMesh );
|
||||||
|
aMesher.SetLocalSizeForChordalError( occgeoComm, *ngMesh );
|
||||||
try {
|
try {
|
||||||
ngMesh->LoadLocalMeshSize( mparam.meshsizefilename );
|
ngMesh->LoadLocalMeshSize( mparam.meshsizefilename );
|
||||||
} catch (NgException & ex) {
|
} catch (NgException & ex) {
|
||||||
|
Loading…
Reference in New Issue
Block a user