0021271: [CEA 473] Implement min size in netgen plugin

This commit is contained in:
eap 2011-07-05 08:46:19 +00:00
parent 5acc32009d
commit ac9fa07f93
12 changed files with 286 additions and 137 deletions

View File

@ -75,6 +75,9 @@ module NETGENPlugin
void SetMaxSize(in double value); void SetMaxSize(in double value);
double GetMaxSize(); double GetMaxSize();
void SetMinSize(in double value);
double GetMinSize();
void SetSecondOrder(in boolean value); void SetSecondOrder(in boolean value);
boolean GetSecondOrder(); boolean GetSecondOrder();

View File

@ -110,6 +110,7 @@ bool NETGENPluginGUI_HypothesisCreator::checkParams(QString& msg) const
storeParamsToHypo( data_old ); storeParamsToHypo( data_old );
res = myMaxSize->isValid(msg,true) && res; res = myMaxSize->isValid(msg,true) && res;
res = myMinSize->isValid(msg,true) && res;
res = myGrowthRate->isValid(msg,true) && res; ; res = myGrowthRate->isValid(msg,true) && res; ;
if ( myNbSegPerEdge ) if ( myNbSegPerEdge )
res = myNbSegPerEdge->isValid(msg,true) && res; res = myNbSegPerEdge->isValid(msg,true) && res;
@ -154,6 +155,12 @@ QFrame* NETGENPluginGUI_HypothesisCreator::buildFrame()
aGroupLayout->addWidget( myMaxSize, row, 1 ); aGroupLayout->addWidget( myMaxSize, row, 1 );
row++; row++;
aGroupLayout->addWidget( new QLabel( tr( "NETGEN_MIN_SIZE" ), GroupC1 ), row, 0 );
myMinSize = new SMESHGUI_SpinBox( GroupC1 );
myMinSize->RangeStepAndValidator( 0.0, 1e+06, 10., "length_precision" );
aGroupLayout->addWidget( myMinSize, row, 1 );
row++;
mySecondOrder = 0; mySecondOrder = 0;
if ( !myIsONLY ) if ( !myIsONLY )
{ {
@ -272,6 +279,11 @@ void NETGENPluginGUI_HypothesisCreator::retrieveParams() const
else else
myMaxSize->setText( data.myMaxSizeVar ); myMaxSize->setText( data.myMaxSizeVar );
if(data.myMinSizeVar.isEmpty())
myMinSize->setValue( data.myMinSize );
else
myMinSize->setText( data.myMinSizeVar );
if ( mySecondOrder ) if ( mySecondOrder )
mySecondOrder->setChecked( data.mySecondOrder ); mySecondOrder->setChecked( data.mySecondOrder );
if ( myOptimize ) if ( myOptimize )
@ -339,6 +351,7 @@ QString NETGENPluginGUI_HypothesisCreator::storeParams() const
storeParamsToHypo( data ); storeParamsToHypo( data );
QString valStr = tr("NETGEN_MAX_SIZE") + " = " + QString::number( data.myMaxSize ) + "; "; QString valStr = tr("NETGEN_MAX_SIZE") + " = " + QString::number( data.myMaxSize ) + "; ";
valStr += tr("NETGEN_MIN_SIZE") + " = " + QString::number( data.myMinSize ) + "; ";
if ( data.mySecondOrder ) if ( data.mySecondOrder )
valStr += tr("NETGEN_SECOND_ORDER") + "; "; valStr += tr("NETGEN_SECOND_ORDER") + "; ";
if ( data.myOptimize ) if ( data.myOptimize )
@ -375,6 +388,8 @@ bool NETGENPluginGUI_HypothesisCreator::readParamsFromHypo( NetgenHypothesisData
h_data.myNbSegPerEdgeVar = (aParameters->length() > 2) ? QString(aParameters[2].in()) : QString(""); h_data.myNbSegPerEdgeVar = (aParameters->length() > 2) ? QString(aParameters[2].in()) : QString("");
h_data.myNbSegPerRadius = h->GetNbSegPerRadius(); h_data.myNbSegPerRadius = h->GetNbSegPerRadius();
h_data.myNbSegPerRadiusVar = (aParameters->length() > 3) ? QString(aParameters[3].in()) : QString(""); h_data.myNbSegPerRadiusVar = (aParameters->length() > 3) ? QString(aParameters[3].in()) : QString("");
h_data.myMinSize = h->GetMinSize();
h_data.myMinSizeVar = (aParameters->length() > 4) ? QString(aParameters[4].in()) : QString("");
if ( myIs2D ) if ( myIs2D )
{ {
@ -435,6 +450,8 @@ bool NETGENPluginGUI_HypothesisCreator::storeParamsToHypo( const NetgenHypothesi
aVariablesList.append(h_data.myNbSegPerEdgeVar); aVariablesList.append(h_data.myNbSegPerEdgeVar);
aVariablesList.append(h_data.myNbSegPerRadiusVar); aVariablesList.append(h_data.myNbSegPerRadiusVar);
} }
h->SetMinSize( h_data.myMinSize );
aVariablesList.append(h_data.myMinSizeVar);
if ( myIs2D ) if ( myIs2D )
{ {
@ -452,6 +469,7 @@ bool NETGENPluginGUI_HypothesisCreator::storeParamsToHypo( const NetgenHypothesi
h->SetParameters(aVariablesList.join(":").toLatin1().constData()); h->SetParameters(aVariablesList.join(":").toLatin1().constData());
h->SetParameters(aVariablesList.join(":").toLatin1().constData()); h->SetParameters(aVariablesList.join(":").toLatin1().constData());
} }
h->SetParameters(aVariablesList.join(":").toLatin1().constData());
QMapIterator<QString,QString> i(myLocalSizeMap); QMapIterator<QString,QString> i(myLocalSizeMap);
while (i.hasNext()) { while (i.hasNext()) {
@ -484,6 +502,8 @@ bool NETGENPluginGUI_HypothesisCreator::readParamsFromWidgets( NetgenHypothesisD
h_data.myName = myName ? myName->text() : ""; h_data.myName = myName ? myName->text() : "";
h_data.myMaxSize = myMaxSize->value(); h_data.myMaxSize = myMaxSize->value();
h_data.myMaxSizeVar = myMaxSize->text(); h_data.myMaxSizeVar = myMaxSize->text();
h_data.myMinSize = myMinSize->value();
h_data.myMinSizeVar = myMinSize->text();
if ( mySecondOrder ) if ( mySecondOrder )
h_data.mySecondOrder = mySecondOrder->isChecked(); h_data.mySecondOrder = mySecondOrder->isChecked();
if ( myOptimize ) if ( myOptimize )

View File

@ -44,11 +44,11 @@ class QTableWidget;
typedef struct typedef struct
{ {
double myMaxSize, myGrowthRate, myNbSegPerEdge, myNbSegPerRadius; double myMaxSize, myMinSize, myGrowthRate, myNbSegPerEdge, myNbSegPerRadius;
int myFineness; int myFineness;
bool mySecondOrder, myAllowQuadrangles, myOptimize; bool mySecondOrder, myAllowQuadrangles, myOptimize;
QString myName; QString myName;
QString myMaxSizeVar, myGrowthRateVar, myNbSegPerEdgeVar, myNbSegPerRadiusVar; QString myMaxSizeVar, myMinSizeVar, myGrowthRateVar, myNbSegPerEdgeVar, myNbSegPerRadiusVar;
} NetgenHypothesisData; } NetgenHypothesisData;
/*! /*!
@ -92,6 +92,7 @@ private:
private: private:
QLineEdit* myName; QLineEdit* myName;
SMESHGUI_SpinBox* myMaxSize; SMESHGUI_SpinBox* myMaxSize;
SMESHGUI_SpinBox* myMinSize;
QCheckBox* mySecondOrder; QCheckBox* mySecondOrder;
QCheckBox* myOptimize; QCheckBox* myOptimize;
QComboBox* myFineness; QComboBox* myFineness;

View File

@ -63,6 +63,10 @@
<source>NETGEN_MAX_SIZE</source> <source>NETGEN_MAX_SIZE</source>
<translation>Max. Size</translation> <translation>Max. Size</translation>
</message> </message>
<message>
<source>NETGEN_MIN_SIZE</source>
<translation>Min. Size</translation>
</message>
<message> <message>
<source>NETGEN_MODERATE</source> <source>NETGEN_MODERATE</source>
<translation>Moderate</translation> <translation>Moderate</translation>

View File

@ -27,6 +27,10 @@
// Project : SALOME // Project : SALOME
// //
#include "NETGENPlugin_Hypothesis.hxx" #include "NETGENPlugin_Hypothesis.hxx"
#include "NETGENPlugin_Mesher.hxx"
#include "SMESH_Mesh.hxx"
#include <utilities.h> #include <utilities.h>
using namespace std; using namespace std;
@ -40,6 +44,7 @@ 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),
_growthRate (GetDefaultGrowthRate()), _growthRate (GetDefaultGrowthRate()),
_nbSegPerEdge (GetDefaultNbSegPerEdge()), _nbSegPerEdge (GetDefaultNbSegPerEdge()),
_nbSegPerRadius(GetDefaultNbSegPerRadius()), _nbSegPerRadius(GetDefaultNbSegPerRadius()),
@ -67,6 +72,20 @@ void NETGENPlugin_Hypothesis::SetMaxSize(double theSize)
} }
} }
//=============================================================================
/*!
*
*/
//=============================================================================
void NETGENPlugin_Hypothesis::SetMinSize(double theSize)
{
if (theSize != _minSize)
{
_minSize = theSize;
NotifySubMeshesHypothesisModification();
}
}
//============================================================================= //=============================================================================
/*! /*!
* *
@ -248,6 +267,7 @@ ostream & NETGENPlugin_Hypothesis::SaveTo(ostream & save)
} }
save << " " << "__LOCALSIZE_END__"; save << " " << "__LOCALSIZE_END__";
} }
save << " " << _minSize;
return save; return save;
} }
@ -332,6 +352,9 @@ istream & NETGENPlugin_Hypothesis::LoadFrom(istream & load)
} }
} }
if ( !hasLocalSize && !option_or_sm.empty() )
_minSize = atof( option_or_sm.c_str() );
return load; return load;
} }
@ -378,10 +401,16 @@ bool NETGENPlugin_Hypothesis::SetParametersByMesh(const SMESH_Mesh* theMesh,
//================================================================================ //================================================================================
bool NETGENPlugin_Hypothesis::SetParametersByDefaults(const TDefaults& dflts, bool NETGENPlugin_Hypothesis::SetParametersByDefaults(const TDefaults& dflts,
const SMESH_Mesh* /*theMesh*/) const SMESH_Mesh* theMesh)
{ {
_nbSegPerEdge = dflts._nbSegments; _nbSegPerEdge = dflts._nbSegments;
_maxSize = dflts._elemLength; _maxSize = dflts._elemLength;
if ( dflts._shape && !dflts._shape->IsNull() )
_minSize = NETGENPlugin_Mesher::GetDefaultMinSize( *dflts._shape, _maxSize );
else if ( theMesh && theMesh->HasShapeToMesh() )
_minSize = NETGENPlugin_Mesher::GetDefaultMinSize( theMesh->GetShapeToMesh(), _maxSize );
return _nbSegPerEdge && _maxSize > 0; return _nbSegPerEdge && _maxSize > 0;
} }

View File

@ -50,6 +50,9 @@ public:
void SetMaxSize(double theSize); void SetMaxSize(double theSize);
double GetMaxSize() const { return _maxSize; } double GetMaxSize() const { return _maxSize; }
void SetMinSize(double theSize);
double GetMinSize() const { return _minSize; }
void SetSecondOrder(bool theVal); void SetSecondOrder(bool theVal);
bool GetSecondOrder() const { return _secondOrder; } bool GetSecondOrder() const { return _secondOrder; }
@ -118,7 +121,7 @@ public:
virtual bool SetParametersByDefaults(const TDefaults& dflts, const SMESH_Mesh* theMesh=0); virtual bool SetParametersByDefaults(const TDefaults& dflts, const SMESH_Mesh* theMesh=0);
private: private:
double _maxSize; double _maxSize, _minSize;
double _growthRate; double _growthRate;
double _nbSegPerEdge; double _nbSegPerEdge;
double _nbSegPerRadius; double _nbSegPerRadius;

View File

@ -99,6 +99,35 @@ CORBA::Double NETGENPlugin_Hypothesis_i::GetMaxSize()
return this->GetImpl()->GetMaxSize(); return this->GetImpl()->GetMaxSize();
} }
//=============================================================================
/*!
* NETGENPlugin_Hypothesis_i::SetMinSize
*
* Set MinSize
*/
//=============================================================================
void NETGENPlugin_Hypothesis_i::SetMinSize (CORBA::Double theValue)
{
MESSAGE("NETGENPlugin_Hypothesis_i::SetMinSize");
ASSERT(myBaseImpl);
this->GetImpl()->SetMinSize(theValue);
SMESH::TPythonDump() << _this() << ".SetMinSize( " << theValue << " )";
}
//=============================================================================
/*!
* NETGENPlugin_Hypothesis_i::GetMinSize
*
* Get MinSize
*/
//=============================================================================
CORBA::Double NETGENPlugin_Hypothesis_i::GetMinSize()
{
MESSAGE("NETGENPlugin_Hypothesis_i::GetMinSize");
ASSERT(myBaseImpl);
return this->GetImpl()->GetMinSize();
}
//============================================================================= //=============================================================================
/*! /*!
* NETGENPlugin_Hypothesis_i::SetSecondOrder * NETGENPlugin_Hypothesis_i::SetSecondOrder

View File

@ -25,7 +25,6 @@
// Author : Michael Sazonov (OCN) // Author : Michael Sazonov (OCN)
// Date : 03/04/2006 // Date : 03/04/2006
// Project : SALOME // Project : SALOME
// $Header$
//============================================================================= //=============================================================================
// //
#ifndef _NETGENPlugin_Hypothesis_i_HXX_ #ifndef _NETGENPlugin_Hypothesis_i_HXX_
@ -59,6 +58,9 @@ class NETGENPLUGIN_EXPORT NETGENPlugin_Hypothesis_i:
void SetMaxSize(CORBA::Double theSize); void SetMaxSize(CORBA::Double theSize);
CORBA::Double GetMaxSize(); CORBA::Double GetMaxSize();
void SetMinSize(CORBA::Double theSize);
CORBA::Double GetMinSize();
void SetSecondOrder(CORBA::Boolean theVal); void SetSecondOrder(CORBA::Boolean theVal);
CORBA::Boolean GetSecondOrder(); CORBA::Boolean GetSecondOrder();

View File

@ -49,6 +49,9 @@
#include <limits> #include <limits>
#include <BRep_Tool.hxx> #include <BRep_Tool.hxx>
#include <Bnd_B3d.hxx>
#include <GCPnts_AbscissaPoint.hxx>
#include <GeomAdaptor_Curve.hxx>
#include <NCollection_Map.hxx> #include <NCollection_Map.hxx>
#include <OSD_File.hxx> #include <OSD_File.hxx>
#include <OSD_Path.hxx> #include <OSD_Path.hxx>
@ -64,8 +67,6 @@
#include <TopTools_ListIteratorOfListOfShape.hxx> #include <TopTools_ListIteratorOfListOfShape.hxx>
#include <TopTools_MapOfShape.hxx> #include <TopTools_MapOfShape.hxx>
#include <TopoDS.hxx> #include <TopoDS.hxx>
#include <GeomAdaptor_Curve.hxx>
#include <GCPnts_AbscissaPoint.hxx>
// Netgen include files // Netgen include files
#ifndef OCCGEOMETRY #ifndef OCCGEOMETRY
@ -138,6 +139,7 @@ void NETGENPlugin_Mesher::defaultParameters()
netgen::MeshingParameters& mparams = netgen::mparam; netgen::MeshingParameters& mparams = netgen::mparam;
// maximal mesh edge size // maximal mesh edge size
mparams.maxh = NETGENPlugin_Hypothesis::GetDefaultMaxSize(); mparams.maxh = NETGENPlugin_Hypothesis::GetDefaultMaxSize();
mparams.maxh = 0;
// minimal number of segments per edge // minimal number of segments per edge
mparams.segmentsperedge = NETGENPlugin_Hypothesis::GetDefaultNbSegPerEdge(); mparams.segmentsperedge = NETGENPlugin_Hypothesis::GetDefaultNbSegPerEdge();
// rate of growth of size between elements // rate of growth of size between elements
@ -276,136 +278,6 @@ Standard_Boolean IsEqual(const Link& aLink1, const Link& aLink2)
aLink1.n1 == aLink2.n2 && aLink1.n2 == aLink2.n1); aLink1.n1 == aLink2.n2 && aLink1.n2 == aLink2.n1);
} }
//================================================================================
/*!
* \brief Initialize netgen::OCCGeometry with OCCT shape
*/
//================================================================================
void NETGENPlugin_Mesher::PrepareOCCgeometry(netgen::OCCGeometry& occgeo,
const TopoDS_Shape& shape,
SMESH_Mesh& mesh,
list< SMESH_subMesh* > * meshedSM,
NETGENPlugin_Internals* intern)
{
BRepTools::Clean (shape);
try {
#if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
OCC_CATCH_SIGNALS;
#endif
BRepMesh_IncrementalMesh e(shape, 0.01, true);
} catch (Standard_Failure) {
}
Bnd_Box bb;
BRepBndLib::Add (shape, bb);
double x1,y1,z1,x2,y2,z2;
bb.Get (x1,y1,z1,x2,y2,z2);
MESSAGE("shape bounding box:\n" <<
"(" << x1 << " " << y1 << " " << z1 << ") " <<
"(" << x2 << " " << y2 << " " << z2 << ")");
netgen::Point<3> p1 = netgen::Point<3> (x1,y1,z1);
netgen::Point<3> p2 = netgen::Point<3> (x2,y2,z2);
occgeo.boundingbox = netgen::Box<3> (p1,p2);
occgeo.shape = shape;
occgeo.changed = 1;
// fill maps of shapes of occgeo with not yet meshed subshapes
// get root submeshes
list< SMESH_subMesh* > rootSM;
if ( SMESH_subMesh* sm = mesh.GetSubMeshContaining( shape )) {
rootSM.push_back( sm );
}
else {
for ( TopoDS_Iterator it( shape ); it.More(); it.Next() )
rootSM.push_back( mesh.GetSubMesh( it.Value() ));
}
// add subshapes of empty submeshes
list< SMESH_subMesh* >::iterator rootIt = rootSM.begin(), rootEnd = rootSM.end();
for ( ; rootIt != rootEnd; ++rootIt ) {
SMESH_subMesh * root = *rootIt;
SMESH_subMeshIteratorPtr smIt = root->getDependsOnIterator(/*includeSelf=*/true,
/*complexShapeFirst=*/true);
// to find a right orientation of subshapes (PAL20462)
TopTools_IndexedMapOfShape subShapes;
TopExp::MapShapes(root->GetSubShape(), subShapes);
while ( smIt->more() )
{
SMESH_subMesh* sm = smIt->next();
TopoDS_Shape shape = sm->GetSubShape();
if ( intern && intern->isShapeToPrecompute( shape ))
continue;
if ( !meshedSM || sm->IsEmpty() )
{
if ( shape.ShapeType() != TopAbs_VERTEX )
shape = subShapes( subShapes.FindIndex( shape ));// shape -> index -> oriented shape
if ( shape.Orientation() >= TopAbs_INTERNAL )
shape.Orientation( TopAbs_FORWARD ); // isuue 0020676
switch ( shape.ShapeType() ) {
case TopAbs_FACE : occgeo.fmap.Add( shape ); break;
case TopAbs_EDGE : occgeo.emap.Add( shape ); break;
case TopAbs_VERTEX: occgeo.vmap.Add( shape ); break;
case TopAbs_SOLID :occgeo.somap.Add( shape ); break;
default:;
}
}
// collect submeshes of meshed shapes
else if (meshedSM)
{
const int dim = SMESH_Gen::GetShapeDim( shape );
meshedSM[ dim ].push_back( sm );
}
}
}
occgeo.facemeshstatus.SetSize (occgeo.fmap.Extent());
occgeo.facemeshstatus = 0;
#ifdef NETGEN_NEW
occgeo.face_maxh.SetSize(occgeo.fmap.Extent());
occgeo.face_maxh = netgen::mparam.maxh;
occgeo.face_maxh_modified.SetSize(occgeo.fmap.Extent());
occgeo.face_maxh_modified = 0;
#endif
// { // set netgen::mparam.minh
// TopLoc_Location loc;
// int i1, i2, i3;
// const int* pi[4] = { &i1, &i2, &i3, &i1 };
// double maxh = 1e100;
// for ( int i = 0; i < occgeo.fmap.Extent(); ++i )
// {
// Handle(Poly_Triangulation) triangulation =
// BRep_Tool::Triangulation ( TopoDS::Face( occgeo.fmap(i+1) ), loc);
// if ( triangulation.IsNull() ) continue;
// const TColgp_Array1OfPnt& points = triangulation->Nodes();
// const Poly_Array1OfTriangle& trias = triangulation->Triangles();
// for ( int iT = trias.Lower(); iT <= trias.Upper(); ++iT )
// {
// trias(iT).Get( i1, i2, i3 );
// for ( int j = 0; j < 3; ++j )
// {
// double dist2 = points(*pi[j]).SquareDistance( points( *pi[j+1] ));
// if ( dist2 < maxh )
// maxh = dist2;
// }
// }
// }
// maxh = sqrt( maxh );
// if ( maxh > 0.5 * occgeo.boundingbox.Diam() ) // no or too rough triangulation
// {
// netgen::mparam.minh = occgeo.boundingbox.Diam()*1e-24;
// cout << "DEFAULT mparams.minh = " <<netgen::mparam.minh << endl;
// }
// else
// {
// netgen::mparam.minh = maxh * 2;
// cout << "TRIANGULATION mparams.minh = " <<netgen::mparam.minh << endl;
// }
// }
}
namespace namespace
{ {
//================================================================================ //================================================================================
@ -532,6 +404,179 @@ namespace
} }
return edges; return edges;
} }
//================================================================================
/*!
* \brief Make triangulation of a shape precise enough
*/
//================================================================================
void updateTriangulation( const TopoDS_Shape& shape )
{
static set< Poly_Triangulation* > updated;
TopLoc_Location loc;
TopExp_Explorer fExp( shape, TopAbs_FACE );
for ( ; fExp.More(); fExp.Next() )
{
Handle(Poly_Triangulation) triangulation =
BRep_Tool::Triangulation ( TopoDS::Face( fExp.Current() ), loc);
if ( triangulation.IsNull() ||
updated.insert( triangulation.operator->() ).second )
{
BRepTools::Clean (shape);
try {
#if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
OCC_CATCH_SIGNALS;
#endif
BRepMesh_IncrementalMesh e(shape, 0.01, true);
}
catch (Standard_Failure)
{
updated.erase( triangulation.operator->() );
}
}
}
}
}
//================================================================================
/*!
* \brief Initialize netgen::OCCGeometry with OCCT shape
*/
//================================================================================
void NETGENPlugin_Mesher::PrepareOCCgeometry(netgen::OCCGeometry& occgeo,
const TopoDS_Shape& shape,
SMESH_Mesh& mesh,
list< SMESH_subMesh* > * meshedSM,
NETGENPlugin_Internals* intern)
{
updateTriangulation( shape );
Bnd_Box bb;
BRepBndLib::Add (shape, bb);
double x1,y1,z1,x2,y2,z2;
bb.Get (x1,y1,z1,x2,y2,z2);
MESSAGE("shape bounding box:\n" <<
"(" << x1 << " " << y1 << " " << z1 << ") " <<
"(" << x2 << " " << y2 << " " << z2 << ")");
netgen::Point<3> p1 = netgen::Point<3> (x1,y1,z1);
netgen::Point<3> p2 = netgen::Point<3> (x2,y2,z2);
occgeo.boundingbox = netgen::Box<3> (p1,p2);
occgeo.shape = shape;
occgeo.changed = 1;
// fill maps of shapes of occgeo with not yet meshed subshapes
// get root submeshes
list< SMESH_subMesh* > rootSM;
if ( SMESH_subMesh* sm = mesh.GetSubMeshContaining( shape )) {
rootSM.push_back( sm );
}
else {
for ( TopoDS_Iterator it( shape ); it.More(); it.Next() )
rootSM.push_back( mesh.GetSubMesh( it.Value() ));
}
// add subshapes of empty submeshes
list< SMESH_subMesh* >::iterator rootIt = rootSM.begin(), rootEnd = rootSM.end();
for ( ; rootIt != rootEnd; ++rootIt ) {
SMESH_subMesh * root = *rootIt;
SMESH_subMeshIteratorPtr smIt = root->getDependsOnIterator(/*includeSelf=*/true,
/*complexShapeFirst=*/true);
// to find a right orientation of subshapes (PAL20462)
TopTools_IndexedMapOfShape subShapes;
TopExp::MapShapes(root->GetSubShape(), subShapes);
while ( smIt->more() )
{
SMESH_subMesh* sm = smIt->next();
TopoDS_Shape shape = sm->GetSubShape();
if ( intern && intern->isShapeToPrecompute( shape ))
continue;
if ( !meshedSM || sm->IsEmpty() )
{
if ( shape.ShapeType() != TopAbs_VERTEX )
shape = subShapes( subShapes.FindIndex( shape ));// shape -> index -> oriented shape
if ( shape.Orientation() >= TopAbs_INTERNAL )
shape.Orientation( TopAbs_FORWARD ); // isuue 0020676
switch ( shape.ShapeType() ) {
case TopAbs_FACE : occgeo.fmap.Add( shape ); break;
case TopAbs_EDGE : occgeo.emap.Add( shape ); break;
case TopAbs_VERTEX: occgeo.vmap.Add( shape ); break;
case TopAbs_SOLID :occgeo.somap.Add( shape ); break;
default:;
}
}
// collect submeshes of meshed shapes
else if (meshedSM)
{
const int dim = SMESH_Gen::GetShapeDim( shape );
meshedSM[ dim ].push_back( sm );
}
}
}
occgeo.facemeshstatus.SetSize (occgeo.fmap.Extent());
occgeo.facemeshstatus = 0;
#ifdef NETGEN_NEW
occgeo.face_maxh.SetSize(occgeo.fmap.Extent());
occgeo.face_maxh = netgen::mparam.maxh;
occgeo.face_maxh_modified.SetSize(occgeo.fmap.Extent());
occgeo.face_maxh_modified = 0;
#endif
}
//================================================================================
/*!
* \brief Return a default min size value suitable for the given geometry.
*/
//================================================================================
double NETGENPlugin_Mesher::GetDefaultMinSize(const TopoDS_Shape& geom,
const double maxSize)
{
updateTriangulation( geom );
TopLoc_Location loc;
int i1, i2, i3;
const int* pi[4] = { &i1, &i2, &i3, &i1 };
double minh = 1e100;
Bnd_B3d bb;
TopExp_Explorer fExp( geom, TopAbs_FACE );
for ( ; fExp.More(); fExp.Next() )
{
Handle(Poly_Triangulation) triangulation =
BRep_Tool::Triangulation ( TopoDS::Face( fExp.Current() ), loc);
if ( triangulation.IsNull() ) continue;
const TColgp_Array1OfPnt& points = triangulation->Nodes();
const Poly_Array1OfTriangle& trias = triangulation->Triangles();
for ( int iT = trias.Lower(); iT <= trias.Upper(); ++iT )
{
trias(iT).Get( i1, i2, i3 );
for ( int j = 0; j < 3; ++j )
{
double dist2 = points(*pi[j]).SquareDistance( points( *pi[j+1] ));
if ( dist2 < minh )
minh = dist2;
bb.Add( points(*pi[j]));
}
}
}
if ( minh > 0.25 * bb.SquareExtent() ) // simple geometry, rough triangulation
{
minh = 1e-3 * sqrt( bb.SquareExtent());
//cout << "BND BOX minh = " <<minh << endl;
}
else
{
minh = 3 * sqrt( minh ); // triangulation for visualization is rather fine
//cout << "TRIANGULATION minh = " <<minh << endl;
}
if ( minh > 0.5 * maxSize )
minh = maxSize / 3.;
return minh;
} }
//================================================================================ //================================================================================
@ -1761,6 +1806,9 @@ bool NETGENPlugin_Mesher::Compute()
mparams.maxh = _simpleHyp->GetLocalLength(); mparams.maxh = _simpleHyp->GetLocalLength();
} }
if ( _simpleHyp || mparams.minh == 0.0 )
mparams.minh = GetDefaultMinSize( _shape, mparams.maxh );
// Let netgen create ngMesh and calculate element size on not meshed shapes // Let netgen create ngMesh and calculate element size on not meshed shapes
char *optstr = 0; char *optstr = 0;
int startWith = netgen::MESHCONST_ANALYSE; int startWith = netgen::MESHCONST_ANALYSE;
@ -2195,6 +2243,7 @@ bool NETGENPlugin_Mesher::Evaluate(MapShapeNbElems& aResMap)
// nb of segments // nb of segments
mparams.segmentsperedge = nbSeg + 0.1; mparams.segmentsperedge = nbSeg + 0.1;
mparams.maxh = occgeo.boundingbox.Diam(); mparams.maxh = occgeo.boundingbox.Diam();
mparams.minh = GetDefaultMinSize( _shape, mparams.maxh );
mparams.grading = 0.01; mparams.grading = 0.01;
} }
else { else {

View File

@ -94,6 +94,9 @@ class NETGENPLUGIN_EXPORT NETGENPlugin_Mesher
std::list< SMESH_subMesh* > * meshedSM=0, std::list< SMESH_subMesh* > * meshedSM=0,
NETGENPlugin_Internals* internalShapes=0); NETGENPlugin_Internals* internalShapes=0);
static double GetDefaultMinSize(const TopoDS_Shape& shape,
const double maxSize);
static int FillSMesh(const netgen::OCCGeometry& occgeom, static int FillSMesh(const netgen::OCCGeometry& occgeom,
const netgen::Mesh& ngMesh, const netgen::Mesh& ngMesh,
const NETGENPlugin_ngMeshInfo& initState, const NETGENPlugin_ngMeshInfo& initState,

View File

@ -444,6 +444,7 @@ bool NETGENPlugin_NETGEN_2D_ONLY::Compute(SMESH_Mesh& aMesh,
edgeLength = occgeo.GetBoundingBox().Diam(); edgeLength = occgeo.GetBoundingBox().Diam();
netgen::mparam.maxh = edgeLength; netgen::mparam.maxh = edgeLength;
netgen::mparam.minh = aMesher.GetDefaultMinSize( aShape, netgen::mparam.maxh );
netgen::mparam.quad = _hypQuadranglePreference ? 1 : 0; netgen::mparam.quad = _hypQuadranglePreference ? 1 : 0;
netgen::mparam.grading = 0.7; // very coarse mesh by default netgen::mparam.grading = 0.7; // very coarse mesh by default
} }

View File

@ -374,6 +374,11 @@ bool NETGENPlugin_NETGEN_3D::compute(SMESH_Mesh& aMesh,
netgen::mparam.maxh = Dist(pmin, pmax)/2; netgen::mparam.maxh = Dist(pmin, pmax)/2;
} }
if ( !_hypParameters && aMesh.HasShapeToMesh() )
{
netgen::mparam.minh = aMesher.GetDefaultMinSize( helper.GetSubShape(), netgen::mparam.maxh );
}
try try
{ {
#if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100 #if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100