From: eap Date: Tue, 5 Jul 2011 08:46:19 +0000 (+0000) Subject: 0021271: [CEA 473] Implement min size in netgen plugin X-Git-Tag: V6_4_0a1~15 X-Git-Url: http://git.salome-platform.org/gitweb/?a=commitdiff_plain;h=ac9fa07f93c0c64723cf8691342b10c2f5ecf82a;p=plugins%2Fnetgenplugin.git 0021271: [CEA 473] Implement min size in netgen plugin --- diff --git a/idl/NETGENPlugin_Algorithm.idl b/idl/NETGENPlugin_Algorithm.idl index 344b112..7603725 100644 --- a/idl/NETGENPlugin_Algorithm.idl +++ b/idl/NETGENPlugin_Algorithm.idl @@ -75,6 +75,9 @@ module NETGENPlugin void SetMaxSize(in double value); double GetMaxSize(); + void SetMinSize(in double value); + double GetMinSize(); + void SetSecondOrder(in boolean value); boolean GetSecondOrder(); diff --git a/src/GUI/NETGENPluginGUI_HypothesisCreator.cxx b/src/GUI/NETGENPluginGUI_HypothesisCreator.cxx index 775c7df..23433fd 100644 --- a/src/GUI/NETGENPluginGUI_HypothesisCreator.cxx +++ b/src/GUI/NETGENPluginGUI_HypothesisCreator.cxx @@ -110,6 +110,7 @@ bool NETGENPluginGUI_HypothesisCreator::checkParams(QString& msg) const storeParamsToHypo( data_old ); res = myMaxSize->isValid(msg,true) && res; + res = myMinSize->isValid(msg,true) && res; res = myGrowthRate->isValid(msg,true) && res; ; if ( myNbSegPerEdge ) res = myNbSegPerEdge->isValid(msg,true) && res; @@ -154,6 +155,12 @@ QFrame* NETGENPluginGUI_HypothesisCreator::buildFrame() aGroupLayout->addWidget( myMaxSize, row, 1 ); 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; if ( !myIsONLY ) { @@ -272,6 +279,11 @@ void NETGENPluginGUI_HypothesisCreator::retrieveParams() const else myMaxSize->setText( data.myMaxSizeVar ); + if(data.myMinSizeVar.isEmpty()) + myMinSize->setValue( data.myMinSize ); + else + myMinSize->setText( data.myMinSizeVar ); + if ( mySecondOrder ) mySecondOrder->setChecked( data.mySecondOrder ); if ( myOptimize ) @@ -339,6 +351,7 @@ QString NETGENPluginGUI_HypothesisCreator::storeParams() const storeParamsToHypo( data ); QString valStr = tr("NETGEN_MAX_SIZE") + " = " + QString::number( data.myMaxSize ) + "; "; + valStr += tr("NETGEN_MIN_SIZE") + " = " + QString::number( data.myMinSize ) + "; "; if ( data.mySecondOrder ) valStr += tr("NETGEN_SECOND_ORDER") + "; "; 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.myNbSegPerRadius = h->GetNbSegPerRadius(); 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 ) { @@ -435,6 +450,8 @@ bool NETGENPluginGUI_HypothesisCreator::storeParamsToHypo( const NetgenHypothesi aVariablesList.append(h_data.myNbSegPerEdgeVar); aVariablesList.append(h_data.myNbSegPerRadiusVar); } + h->SetMinSize( h_data.myMinSize ); + aVariablesList.append(h_data.myMinSizeVar); 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()); QMapIterator i(myLocalSizeMap); while (i.hasNext()) { @@ -484,6 +502,8 @@ bool NETGENPluginGUI_HypothesisCreator::readParamsFromWidgets( NetgenHypothesisD h_data.myName = myName ? myName->text() : ""; h_data.myMaxSize = myMaxSize->value(); h_data.myMaxSizeVar = myMaxSize->text(); + h_data.myMinSize = myMinSize->value(); + h_data.myMinSizeVar = myMinSize->text(); if ( mySecondOrder ) h_data.mySecondOrder = mySecondOrder->isChecked(); if ( myOptimize ) diff --git a/src/GUI/NETGENPluginGUI_HypothesisCreator.h b/src/GUI/NETGENPluginGUI_HypothesisCreator.h index 61bba9b..a4d832a 100644 --- a/src/GUI/NETGENPluginGUI_HypothesisCreator.h +++ b/src/GUI/NETGENPluginGUI_HypothesisCreator.h @@ -44,11 +44,11 @@ class QTableWidget; typedef struct { - double myMaxSize, myGrowthRate, myNbSegPerEdge, myNbSegPerRadius; + double myMaxSize, myMinSize, myGrowthRate, myNbSegPerEdge, myNbSegPerRadius; int myFineness; bool mySecondOrder, myAllowQuadrangles, myOptimize; QString myName; - QString myMaxSizeVar, myGrowthRateVar, myNbSegPerEdgeVar, myNbSegPerRadiusVar; + QString myMaxSizeVar, myMinSizeVar, myGrowthRateVar, myNbSegPerEdgeVar, myNbSegPerRadiusVar; } NetgenHypothesisData; /*! @@ -92,6 +92,7 @@ private: private: QLineEdit* myName; SMESHGUI_SpinBox* myMaxSize; + SMESHGUI_SpinBox* myMinSize; QCheckBox* mySecondOrder; QCheckBox* myOptimize; QComboBox* myFineness; diff --git a/src/GUI/NETGENPlugin_msg_en.ts b/src/GUI/NETGENPlugin_msg_en.ts index dd9dd70..55e4ceb 100644 --- a/src/GUI/NETGENPlugin_msg_en.ts +++ b/src/GUI/NETGENPlugin_msg_en.ts @@ -63,6 +63,10 @@ NETGEN_MAX_SIZE Max. Size + + NETGEN_MIN_SIZE + Min. Size + NETGEN_MODERATE Moderate diff --git a/src/NETGENPlugin/NETGENPlugin_Hypothesis.cxx b/src/NETGENPlugin/NETGENPlugin_Hypothesis.cxx index 0644102..9739063 100644 --- a/src/NETGENPlugin/NETGENPlugin_Hypothesis.cxx +++ b/src/NETGENPlugin/NETGENPlugin_Hypothesis.cxx @@ -27,6 +27,10 @@ // Project : SALOME // #include "NETGENPlugin_Hypothesis.hxx" + +#include "NETGENPlugin_Mesher.hxx" +#include "SMESH_Mesh.hxx" + #include using namespace std; @@ -40,6 +44,7 @@ NETGENPlugin_Hypothesis::NETGENPlugin_Hypothesis (int hypId, int studyId, SMESH_Gen * gen) : SMESH_Hypothesis(hypId, studyId, gen), _maxSize (GetDefaultMaxSize()), + _minSize (0), _growthRate (GetDefaultGrowthRate()), _nbSegPerEdge (GetDefaultNbSegPerEdge()), _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 << " " << _minSize; 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; } @@ -378,10 +401,16 @@ bool NETGENPlugin_Hypothesis::SetParametersByMesh(const SMESH_Mesh* theMesh, //================================================================================ bool NETGENPlugin_Hypothesis::SetParametersByDefaults(const TDefaults& dflts, - const SMESH_Mesh* /*theMesh*/) + const SMESH_Mesh* theMesh) { _nbSegPerEdge = dflts._nbSegments; _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; } diff --git a/src/NETGENPlugin/NETGENPlugin_Hypothesis.hxx b/src/NETGENPlugin/NETGENPlugin_Hypothesis.hxx index d025bda..ac39732 100644 --- a/src/NETGENPlugin/NETGENPlugin_Hypothesis.hxx +++ b/src/NETGENPlugin/NETGENPlugin_Hypothesis.hxx @@ -50,6 +50,9 @@ public: void SetMaxSize(double theSize); double GetMaxSize() const { return _maxSize; } + void SetMinSize(double theSize); + double GetMinSize() const { return _minSize; } + void SetSecondOrder(bool theVal); bool GetSecondOrder() const { return _secondOrder; } @@ -118,7 +121,7 @@ public: virtual bool SetParametersByDefaults(const TDefaults& dflts, const SMESH_Mesh* theMesh=0); private: - double _maxSize; + double _maxSize, _minSize; double _growthRate; double _nbSegPerEdge; double _nbSegPerRadius; diff --git a/src/NETGENPlugin/NETGENPlugin_Hypothesis_i.cxx b/src/NETGENPlugin/NETGENPlugin_Hypothesis_i.cxx index d5464a9..cd34d09 100644 --- a/src/NETGENPlugin/NETGENPlugin_Hypothesis_i.cxx +++ b/src/NETGENPlugin/NETGENPlugin_Hypothesis_i.cxx @@ -99,6 +99,35 @@ CORBA::Double NETGENPlugin_Hypothesis_i::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 diff --git a/src/NETGENPlugin/NETGENPlugin_Hypothesis_i.hxx b/src/NETGENPlugin/NETGENPlugin_Hypothesis_i.hxx index dc2a911..b8737ab 100644 --- a/src/NETGENPlugin/NETGENPlugin_Hypothesis_i.hxx +++ b/src/NETGENPlugin/NETGENPlugin_Hypothesis_i.hxx @@ -25,7 +25,6 @@ // Author : Michael Sazonov (OCN) // Date : 03/04/2006 // Project : SALOME -// $Header$ //============================================================================= // #ifndef _NETGENPlugin_Hypothesis_i_HXX_ @@ -59,6 +58,9 @@ class NETGENPLUGIN_EXPORT NETGENPlugin_Hypothesis_i: void SetMaxSize(CORBA::Double theSize); CORBA::Double GetMaxSize(); + void SetMinSize(CORBA::Double theSize); + CORBA::Double GetMinSize(); + void SetSecondOrder(CORBA::Boolean theVal); CORBA::Boolean GetSecondOrder(); diff --git a/src/NETGENPlugin/NETGENPlugin_Mesher.cxx b/src/NETGENPlugin/NETGENPlugin_Mesher.cxx index 28ecc76..f382364 100644 --- a/src/NETGENPlugin/NETGENPlugin_Mesher.cxx +++ b/src/NETGENPlugin/NETGENPlugin_Mesher.cxx @@ -49,6 +49,9 @@ #include #include +#include +#include +#include #include #include #include @@ -64,8 +67,6 @@ #include #include #include -#include -#include // Netgen include files #ifndef OCCGEOMETRY @@ -138,6 +139,7 @@ void NETGENPlugin_Mesher::defaultParameters() netgen::MeshingParameters& mparams = netgen::mparam; // maximal mesh edge size mparams.maxh = NETGENPlugin_Hypothesis::GetDefaultMaxSize(); + mparams.maxh = 0; // minimal number of segments per edge mparams.segmentsperedge = NETGENPlugin_Hypothesis::GetDefaultNbSegPerEdge(); // 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); } -//================================================================================ -/*! - * \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 = " < 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 = " <