Enable Local Size for NETGEN 3D and NETGEN 2D

This commit is contained in:
eap 2016-08-30 15:38:14 +03:00
parent 8b187bb352
commit a5c8f82089
5 changed files with 152 additions and 140 deletions

View File

@ -236,7 +236,7 @@ QFrame* NETGENPluginGUI_HypothesisCreator::buildFrame()
} }
myLocalSizeTable = 0; myLocalSizeTable = 0;
if ( !myIsONLY ) //if ( !myIsONLY )
{ {
QWidget* localSizeGroup = new QWidget(); QWidget* localSizeGroup = new QWidget();
QGridLayout* localSizeLayout = new QGridLayout(localSizeGroup); QGridLayout* localSizeLayout = new QGridLayout(localSizeGroup);

View File

@ -123,6 +123,9 @@ std::map<int,double> EdgeId2LocalSize;
std::map<int,double> FaceId2LocalSize; std::map<int,double> FaceId2LocalSize;
std::map<int,double> SolidId2LocalSize; std::map<int,double> SolidId2LocalSize;
std::vector<SMESHUtils::ControlPnt> ControlPoints;
std::set<int> ShapesWithControlPoints; // <-- allows calling SetLocalSize() several times w/o recomputing ControlPoints
//============================================================================= //=============================================================================
/*! /*!
* *
@ -152,6 +155,8 @@ NETGENPlugin_Mesher::NETGENPlugin_Mesher (SMESH_Mesh* mesh,
EdgeId2LocalSize.clear(); EdgeId2LocalSize.clear();
FaceId2LocalSize.clear(); FaceId2LocalSize.clear();
SolidId2LocalSize.clear(); SolidId2LocalSize.clear();
ControlPoints.clear();
ShapesWithControlPoints.clear();
} }
//================================================================================ //================================================================================
@ -283,23 +288,25 @@ void NETGENPlugin_Mesher::SetParameters(const NETGENPlugin_Hypothesis* hyp)
CORBA::Object_var anObject = smeshGen_i->GetNS()->Resolve("/myStudyManager"); CORBA::Object_var anObject = smeshGen_i->GetNS()->Resolve("/myStudyManager");
SALOMEDS::StudyManager_var aStudyMgr = SALOMEDS::StudyManager::_narrow(anObject); SALOMEDS::StudyManager_var aStudyMgr = SALOMEDS::StudyManager::_narrow(anObject);
SALOMEDS::Study_var myStudy = aStudyMgr->GetStudyByID(hyp->GetStudyId()); SALOMEDS::Study_var myStudy = aStudyMgr->GetStudyByID(hyp->GetStudyId());
if ( !myStudy->_is_nil() )
const NETGENPlugin_Hypothesis::TLocalSize localSizes = hyp->GetLocalSizesAndEntries();
NETGENPlugin_Hypothesis::TLocalSize::const_iterator it = localSizes.begin();
for ( ; it != localSizes.end() ; it++)
{ {
std::string entry = (*it).first; const NETGENPlugin_Hypothesis::TLocalSize localSizes = hyp->GetLocalSizesAndEntries();
double val = (*it).second; NETGENPlugin_Hypothesis::TLocalSize::const_iterator it = localSizes.begin();
// -- for ( ; it != localSizes.end() ; it++)
GEOM::GEOM_Object_var aGeomObj; {
SALOMEDS::SObject_var aSObj = myStudy->FindObjectID( entry.c_str() ); std::string entry = (*it).first;
if ( !aSObj->_is_nil() ) { double val = (*it).second;
CORBA::Object_var obj = aSObj->GetObject(); // --
aGeomObj = GEOM::GEOM_Object::_narrow(obj); GEOM::GEOM_Object_var aGeomObj;
aSObj->UnRegister(); SALOMEDS::SObject_var aSObj = myStudy->FindObjectID( entry.c_str() );
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);
} }
} }
} }
@ -558,6 +565,105 @@ namespace
// } // }
// } // }
//================================================================================
/*!
* \brief Restrict size of elements on the given edge
*/
//================================================================================
void setLocalSize(const TopoDS_Edge& edge,
double size,
netgen::Mesh& mesh)
{
if ( size <= std::numeric_limits<double>::min() )
return;
Standard_Real u1, u2;
Handle(Geom_Curve) curve = BRep_Tool::Curve(edge, u1, u2);
if ( curve.IsNull() )
{
TopoDS_Iterator vIt( edge );
if ( !vIt.More() ) return;
gp_Pnt p = BRep_Tool::Pnt( TopoDS::Vertex( vIt.Value() ));
NETGENPlugin_Mesher::RestrictLocalSize( mesh, p.XYZ(), size );
}
else
{
const int nb = (int)( 1.5 * SMESH_Algo::EdgeLength( edge ) / size );
Standard_Real delta = (u2-u1)/nb;
for(int i=0; i<nb; i++)
{
Standard_Real u = u1 + delta*i;
gp_Pnt p = curve->Value(u);
NETGENPlugin_Mesher::RestrictLocalSize( mesh, p.XYZ(), size );
netgen::Point3d pi(p.X(), p.Y(), p.Z());
double resultSize = mesh.GetH(pi);
if ( resultSize - size > 0.1*size )
// netgen does restriction iff oldH/newH > 1.2 (localh.cpp:136)
NETGENPlugin_Mesher::RestrictLocalSize( mesh, p.XYZ(), resultSize/1.201 );
}
}
}
} // namespace
//================================================================================
/*!
* \brief Set local size on shapes defined by SetParameters()
*/
//================================================================================
void NETGENPlugin_Mesher::SetLocalSize( netgen::OCCGeometry& occgeo,
netgen::Mesh& ngMesh )
{
for(std::map<int,double>::const_iterator it=EdgeId2LocalSize.begin(); it!=EdgeId2LocalSize.end(); it++)
{
int key = (*it).first;
double hi = (*it).second;
const TopoDS_Shape& shape = ShapesWithLocalSize.FindKey(key);
setLocalSize( TopoDS::Edge(shape), hi, ngMesh );
}
for(std::map<int,double>::const_iterator it=VertexId2LocalSize.begin(); it!=VertexId2LocalSize.end(); it++)
{
int key = (*it).first;
double hi = (*it).second;
const TopoDS_Shape& shape = ShapesWithLocalSize.FindKey(key);
gp_Pnt p = BRep_Tool::Pnt( TopoDS::Vertex(shape) );
NETGENPlugin_Mesher::RestrictLocalSize( ngMesh, p.XYZ(), hi );
}
for(map<int,double>::const_iterator it=FaceId2LocalSize.begin(); it!=FaceId2LocalSize.end(); it++)
{
int key = (*it).first;
double val = (*it).second;
const TopoDS_Shape& shape = ShapesWithLocalSize.FindKey(key);
int faceNgID = occgeo.fmap.FindIndex(shape);
if ( faceNgID >= 1 )
{
occgeo.SetFaceMaxH(faceNgID, val);
for ( TopExp_Explorer edgeExp( shape, TopAbs_EDGE ); edgeExp.More(); edgeExp.Next() )
setLocalSize( TopoDS::Edge( edgeExp.Current() ), val, ngMesh );
}
else if ( !ShapesWithControlPoints.count( key ))
{
SMESHUtils::createPointsSampleFromFace( TopoDS::Face( shape ), val, ControlPoints );
ShapesWithControlPoints.insert( key );
}
}
for(map<int,double>::const_iterator it=SolidId2LocalSize.begin(); it!=SolidId2LocalSize.end(); it++)
{
int key = (*it).first;
double val = (*it).second;
if ( !ShapesWithControlPoints.count( key ))
{
const TopoDS_Shape& shape = ShapesWithLocalSize.FindKey(key);
SMESHUtils::createPointsSampleFromSolid( TopoDS::Solid( shape ), val, ControlPoints );
ShapesWithControlPoints.insert( key );
}
}
if ( !ControlPoints.empty() )
{
for ( size_t i = 1; i < ControlPoints.size(); ++i )
NETGENPlugin_Mesher::RestrictLocalSize( ngMesh, ControlPoints[i].XYZ(), ControlPoints[i].Size() );
}
} }
//================================================================================ //================================================================================
@ -2283,45 +2389,6 @@ int NETGENPlugin_Mesher::FillSMesh(const netgen::OCCGeometry& occgeo,
namespace namespace
{ {
//================================================================================
/*!
* \brief Restrict size of elements on the given edge
*/
//================================================================================
void setLocalSize(const TopoDS_Edge& edge,
double size,
netgen::Mesh& mesh)
{
if ( size <= std::numeric_limits<double>::min() )
return;
Standard_Real u1, u2;
Handle(Geom_Curve) curve = BRep_Tool::Curve(edge, u1, u2);
if ( curve.IsNull() )
{
TopoDS_Iterator vIt( edge );
if ( !vIt.More() ) return;
gp_Pnt p = BRep_Tool::Pnt( TopoDS::Vertex( vIt.Value() ));
NETGENPlugin_Mesher::RestrictLocalSize( mesh, p.XYZ(), size );
}
else
{
const int nb = (int)( 1.5 * SMESH_Algo::EdgeLength( edge ) / size );
Standard_Real delta = (u2-u1)/nb;
for(int i=0; i<nb; i++)
{
Standard_Real u = u1 + delta*i;
gp_Pnt p = curve->Value(u);
NETGENPlugin_Mesher::RestrictLocalSize( mesh, p.XYZ(), size );
netgen::Point3d pi(p.X(), p.Y(), p.Z());
double resultSize = mesh.GetH(pi);
if ( resultSize - size > 0.1*size )
// netgen does restriction iff oldH/newH > 1.2 (localh.cpp:136)
NETGENPlugin_Mesher::RestrictLocalSize( mesh, p.XYZ(), resultSize/1.201 );
}
}
}
//================================================================================ //================================================================================
/*! /*!
* \brief Convert error into text * \brief Convert error into text
@ -2541,60 +2608,8 @@ bool NETGENPlugin_Mesher::Compute()
} }
else // if ( ! _simpleHyp ) else // if ( ! _simpleHyp )
{ {
// Local size on vertices and edges // Local size on shapes
// -------------------------------- SetLocalSize( occgeo, *_ngMesh );
for(std::map<int,double>::const_iterator it=EdgeId2LocalSize.begin(); it!=EdgeId2LocalSize.end(); it++)
{
int key = (*it).first;
double hi = (*it).second;
const TopoDS_Shape& shape = ShapesWithLocalSize.FindKey(key);
const TopoDS_Edge& e = TopoDS::Edge(shape);
setLocalSize( e, hi, *_ngMesh );
}
for(std::map<int,double>::const_iterator it=VertexId2LocalSize.begin(); it!=VertexId2LocalSize.end(); it++)
{
int key = (*it).first;
double hi = (*it).second;
const TopoDS_Shape& shape = ShapesWithLocalSize.FindKey(key);
const TopoDS_Vertex& v = TopoDS::Vertex(shape);
gp_Pnt p = BRep_Tool::Pnt(v);
NETGENPlugin_Mesher::RestrictLocalSize( *_ngMesh, p.XYZ(), hi );
}
for(map<int,double>::const_iterator it=FaceId2LocalSize.begin(); it!=FaceId2LocalSize.end(); it++)
{
int key = (*it).first;
double val = (*it).second;
const TopoDS_Shape& shape = ShapesWithLocalSize.FindKey(key);
int faceNgID = occgeo.fmap.FindIndex(shape);
if ( faceNgID >= 1 )
{
occgeo.SetFaceMaxH(faceNgID, val);
for ( TopExp_Explorer edgeExp( shape, TopAbs_EDGE ); edgeExp.More(); edgeExp.Next() )
setLocalSize( TopoDS::Edge( edgeExp.Current() ), val, *_ngMesh );
}
else
{
std::vector<SMESHUtils::ControlPnt> pnt;
SMESHUtils::createPointsSampleFromFace( TopoDS::Face( shape ), val, pnt );
if ( !pnt.empty() )
NETGENPlugin_Mesher::RestrictLocalSize( *_ngMesh, pnt[0].XYZ(), val );
for ( size_t i = 1; i < pnt.size(); ++i )
_ngMesh->RestrictLocalH( netgen::Point3d( pnt[i].X(), pnt[i].Y(), pnt[i].Z() ), val );
}
}
for(map<int,double>::const_iterator it=SolidId2LocalSize.begin(); it!=SolidId2LocalSize.end(); it++)
{
int key = (*it).first;
double val = (*it).second;
const TopoDS_Shape& shape = ShapesWithLocalSize.FindKey(key);
std::vector<SMESHUtils::ControlPnt> pnt;
SMESHUtils::createPointsSampleFromSolid( TopoDS::Solid( shape ), val, pnt );
if ( !pnt.empty() )
NETGENPlugin_Mesher::RestrictLocalSize( *_ngMesh, pnt[0].XYZ(), val );
for ( size_t i = 1; i < pnt.size(); ++i )
_ngMesh->RestrictLocalH( netgen::Point3d( pnt[i].X(), pnt[i].Y(), pnt[i].Z() ), val );
}
} }
// Precompute internal edges (issue 0020676) in order to // Precompute internal edges (issue 0020676) in order to
@ -3156,36 +3171,8 @@ bool NETGENPlugin_Mesher::Evaluate(MapShapeNbElems& aResMap)
} }
else // if ( ! _simpleHyp ) else // if ( ! _simpleHyp )
{ {
// Local size on vertices and edges // Local size on shapes
// -------------------------------- SetLocalSize( occgeo, *ngMesh );
for(std::map<int,double>::const_iterator it=EdgeId2LocalSize.begin(); it!=EdgeId2LocalSize.end(); it++)
{
int key = (*it).first;
double hi = (*it).second;
const TopoDS_Shape& shape = ShapesWithLocalSize.FindKey(key);
const TopoDS_Edge& e = TopoDS::Edge(shape);
setLocalSize( e, hi, *ngMesh );
}
for(std::map<int,double>::const_iterator it=VertexId2LocalSize.begin(); it!=VertexId2LocalSize.end(); it++)
{
int key = (*it).first;
double hi = (*it).second;
const TopoDS_Shape& shape = ShapesWithLocalSize.FindKey(key);
const TopoDS_Vertex& v = TopoDS::Vertex(shape);
gp_Pnt p = BRep_Tool::Pnt(v);
NETGENPlugin_Mesher::RestrictLocalSize( *ngMesh, p.XYZ(), hi );
}
for(map<int,double>::const_iterator it=FaceId2LocalSize.begin();
it!=FaceId2LocalSize.end(); it++)
{
int key = (*it).first;
double val = (*it).second;
const TopoDS_Shape& shape = ShapesWithLocalSize.FindKey(key);
int faceNgID = occgeo.fmap.FindIndex(shape);
occgeo.SetFaceMaxH(faceNgID, val);
for ( TopExp_Explorer edgeExp( shape, TopAbs_EDGE ); edgeExp.More(); edgeExp.Next() )
setLocalSize( TopoDS::Edge( edgeExp.Current() ), val, *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;
@ -3386,10 +3373,19 @@ double NETGENPlugin_Mesher::GetProgress(const SMESH_Algo* holder,
// << " " << doneTime / _totalTime / _progressTic << endl; // << " " << doneTime / _totalTime / _progressTic << endl;
} }
} }
if ( _ticTime > 0 ) if ( _ticTime > 0 )
progress = Max( *algoProgressTic * _ticTime, *algoProgress ); progress = Max( *algoProgressTic * _ticTime, *algoProgress );
if ( progress > 0 ) if ( progress > 0 )
{ {
if ( _isVolume &&
netgen::multithread.task[0] == 'D'/*elaunay meshing*/ &&
progress > voluMeshingTime )
{
progress = voluMeshingTime;
((double&) _ticTime) = voluMeshingTime / _totalTime / _progressTic;
}
((int&) *algoProgressTic )++; ((int&) *algoProgressTic )++;
((double&) *algoProgress) = progress; ((double&) *algoProgress) = progress;
} }

View File

@ -121,6 +121,7 @@ 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 SetViscousLayers2DAssigned(bool isAssigned) { _isViscousLayers2D = isAssigned; } void SetViscousLayers2DAssigned(bool isAssigned) { _isViscousLayers2D = isAssigned; }
static void SetLocalSize( netgen::OCCGeometry& occgeo, netgen::Mesh& ngMesh );
bool Compute(); bool Compute();

View File

@ -314,6 +314,9 @@ bool NETGENPlugin_NETGEN_2D_ONLY::Compute(SMESH_Mesh& aMesh,
ngMeshes[0]->RestrictLocalH( pi, factor * ( n1 - n2 ).Modulus() ); ngMeshes[0]->RestrictLocalH( pi, factor * ( n1 - n2 ).Modulus() );
} }
} }
// set local size defined on shapes
aMesher.SetLocalSize( occgeoComm, *ngMeshes[0] );
} }
netgen::mparam.uselocalh = toOptimize; // restore as it is used at surface optimization netgen::mparam.uselocalh = toOptimize; // restore as it is used at surface optimization
@ -449,6 +452,7 @@ bool NETGENPlugin_NETGEN_2D_ONLY::Compute(SMESH_Mesh& aMesh,
Box<3> bb = occgeom.GetBoundingBox(); Box<3> bb = occgeom.GetBoundingBox();
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 );
} }
nodeVec.clear(); nodeVec.clear();

View File

@ -433,10 +433,21 @@ bool NETGENPlugin_NETGEN_3D::compute(SMESH_Mesh& aMesh,
NETGENPlugin_Mesher aMesher( &aMesh, helper.GetSubShape(), /*isVolume=*/true ); NETGENPlugin_Mesher aMesher( &aMesh, helper.GetSubShape(), /*isVolume=*/true );
netgen::OCCGeometry occgeo; netgen::OCCGeometry occgeo;
if ( _hypParameters ) if ( _hypParameters )
{ {
aMesher.SetParameters( _hypParameters ); aMesher.SetParameters( _hypParameters );
if ( !_hypParameters->GetLocalSizesAndEntries().empty() )
{
if ( ! &ngMesh->LocalHFunction() )
{
netgen::Point3d pmin, pmax;
ngMesh->GetBox( pmin, pmax, 0 );
ngMesh->SetLocalH( pmin, pmax, _hypParameters->GetGrowthRate() );
}
aMesher.SetLocalSize( occgeo, *ngMesh );
}
if ( !_hypParameters->GetOptimize() ) if ( !_hypParameters->GetOptimize() )
endWith = netgen::MESHCONST_MESHVOLUME; endWith = netgen::MESHCONST_MESHVOLUME;
} }