netgenplugin/src/NETGENPlugin/NETGENPlugin_Hypothesis.cxx
2020-12-08 19:02:50 +03:00

680 lines
18 KiB
C++

// Copyright (C) 2007-2020 CEA/DEN, EDF R&D, OPEN CASCADE
//
// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2.1 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
//
// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
//
// NETGENPlugin : C++ implementation
// File : NETGENPlugin_Hypothesis.cxx
// Author : Michael Sazonov (OCN)
// Date : 28/03/2006
// Project : SALOME
//
#include "NETGENPlugin_Hypothesis.hxx"
#include "NETGENPlugin_Mesher.hxx"
#include "SMESH_Mesh.hxx"
#include <utilities.h>
using namespace std;
//=============================================================================
/*!
*
*/
//=============================================================================
NETGENPlugin_Hypothesis::NETGENPlugin_Hypothesis (int hypId, SMESH_Gen * gen)
: SMESH_Hypothesis(hypId, gen),
_fineness (GetDefaultFineness()),
_secondOrder (GetDefaultSecondOrder()),
_quadAllowed (GetDefaultQuadAllowed()),
_maxSize (GetDefaultMaxSize()),
_minSize (0),
_growthRate (GetDefaultGrowthRate()),
_nbSegPerRadius (GetDefaultNbSegPerRadius()),
_nbSegPerEdge (GetDefaultNbSegPerEdge()),
_chordalErrorEnabled(GetDefaultChordalError() > 0),
_chordalError (GetDefaultChordalError() ),
_optimize (GetDefaultOptimize()),
_nbSurfOptSteps (GetDefaultNbSurfOptSteps()),
_nbVolOptSteps (GetDefaultNbVolOptSteps()),
_elemSizeWeight (GetDefaultElemSizeWeight()),
_worstElemMeasure (GetDefaultWorstElemMeasure()),
_surfaceCurvature (GetDefaultSurfaceCurvature()),
_useDelauney (GetDefaultUseDelauney()),
_checkOverlapping (GetDefaultCheckOverlapping()),
_checkChartBoundary (GetDefaultCheckChartBoundary()),
_fuseEdges (GetDefaultFuseEdges())
{
_name = "NETGEN_Parameters";
_param_algo_dim = 3;
}
//=============================================================================
/*!
*
*/
//=============================================================================
void NETGENPlugin_Hypothesis::SetMaxSize(double theSize)
{
if (theSize != _maxSize)
{
_maxSize = theSize;
NotifySubMeshesHypothesisModification();
}
}
//=============================================================================
/*!
*
*/
//=============================================================================
void NETGENPlugin_Hypothesis::SetMinSize(double theSize)
{
if (theSize != _minSize)
{
_minSize = theSize;
NotifySubMeshesHypothesisModification();
}
}
//=============================================================================
/*!
*
*/
//=============================================================================
void NETGENPlugin_Hypothesis::SetSecondOrder(bool theVal)
{
if (theVal != _secondOrder)
{
_secondOrder = theVal;
NotifySubMeshesHypothesisModification();
}
}
//=============================================================================
/*!
*
*/
//=============================================================================
void NETGENPlugin_Hypothesis::SetOptimize(bool theVal)
{
if (theVal != _optimize)
{
_optimize = theVal;
NotifySubMeshesHypothesisModification();
}
}
//=============================================================================
/*!
*
*/
//=============================================================================
void NETGENPlugin_Hypothesis::SetFineness(Fineness theFineness)
{
if (theFineness != _fineness)
{
_fineness = theFineness;
// the predefined values are taken from NETGEN 4.5 sources
switch (_fineness)
{
case VeryCoarse:
_growthRate = 0.7;
_nbSegPerEdge = 0.3;
_nbSegPerRadius = 1;
break;
case Coarse:
_growthRate = 0.5;
_nbSegPerEdge = 0.5;
_nbSegPerRadius = 1.5;
break;
case Fine:
_growthRate = 0.2;
_nbSegPerEdge = 2;
_nbSegPerRadius = 3;
break;
case VeryFine:
_growthRate = 0.1;
_nbSegPerEdge = 3;
_nbSegPerRadius = 5;
break;
case UserDefined:
break;
case Moderate:
default:
_growthRate = 0.3;
_nbSegPerEdge = 1;
_nbSegPerRadius = 2;
break;
}
NotifySubMeshesHypothesisModification();
}
}
//=============================================================================
/*!
*
*/
//=============================================================================
void NETGENPlugin_Hypothesis::SetGrowthRate(double theRate)
{
if (theRate != _growthRate)
{
_growthRate = theRate;
_fineness = UserDefined;
NotifySubMeshesHypothesisModification();
}
}
//=============================================================================
/*!
*
*/
//=============================================================================
void NETGENPlugin_Hypothesis::SetNbSegPerEdge(double theVal)
{
if (theVal != _nbSegPerEdge)
{
_nbSegPerEdge = theVal;
_fineness = UserDefined;
NotifySubMeshesHypothesisModification();
}
}
//=============================================================================
/*!
*
*/
//=============================================================================
void NETGENPlugin_Hypothesis::SetNbSegPerRadius(double theVal)
{
if (theVal != _nbSegPerRadius)
{
_nbSegPerRadius = theVal;
_fineness = UserDefined;
NotifySubMeshesHypothesisModification();
}
}
//=============================================================================
/*!
*
*/
//=============================================================================
void NETGENPlugin_Hypothesis::SetChordalErrorEnabled(bool theVal)
{
if (theVal != _chordalErrorEnabled)
{
_chordalErrorEnabled = theVal;
NotifySubMeshesHypothesisModification();
}
}
//=============================================================================
/*!
*
*/
//=============================================================================
void NETGENPlugin_Hypothesis::SetChordalError(double theVal)
{
if (theVal != _chordalError)
{
_chordalError = theVal;
NotifySubMeshesHypothesisModification();
}
}
//=============================================================================
/*!
*
*/
//=============================================================================
void NETGENPlugin_Hypothesis::SetLocalSizeOnEntry(const std::string& entry, double localSize)
{
if(_localSize[entry] != localSize)
{
_localSize[entry] = localSize;
NotifySubMeshesHypothesisModification();
}
}
//=============================================================================
/*!
*
*/
//=============================================================================
double NETGENPlugin_Hypothesis::GetLocalSizeOnEntry(const std::string& entry)
{
TLocalSize::iterator it = _localSize.find( entry );
if ( it != _localSize.end() )
return it->second;
else
return -1.0;
}
//=============================================================================
/*!
*
*/
//=============================================================================
void NETGENPlugin_Hypothesis::UnsetLocalSizeOnEntry(const std::string& entry)
{
_localSize.erase(entry);
NotifySubMeshesHypothesisModification();
}
//=============================================================================
/*!
*
*/
//=============================================================================
void NETGENPlugin_Hypothesis::SetMeshSizeFile(const std::string& fileName)
{
if ( fileName != _meshSizeFile )
{
_meshSizeFile = fileName;
NotifySubMeshesHypothesisModification();
}
}
//=============================================================================
/*!
*
*/
//=============================================================================
void NETGENPlugin_Hypothesis::SetQuadAllowed(bool theVal)
{
if (theVal != _quadAllowed)
{
_quadAllowed = theVal;
NotifySubMeshesHypothesisModification();
}
}
//=============================================================================
/*!
*
*/
//=============================================================================
void NETGENPlugin_Hypothesis::SetSurfaceCurvature(bool theVal)
{
if (theVal != _surfaceCurvature)
{
_surfaceCurvature = theVal;
NotifySubMeshesHypothesisModification();
}
}
//=============================================================================
/*!
*
*/
//=============================================================================
void NETGENPlugin_Hypothesis::SetFuseEdges(bool theVal)
{
if (theVal != _fuseEdges)
{
_fuseEdges = theVal;
NotifySubMeshesHypothesisModification();
}
}
//=======================================================================
//function : SetNbSurfOptSteps
//purpose :
//=======================================================================
void NETGENPlugin_Hypothesis::SetNbSurfOptSteps( int theVal )
{
if (theVal != _nbSurfOptSteps)
{
_nbSurfOptSteps = theVal;
NotifySubMeshesHypothesisModification();
}
}
//=======================================================================
//function : SetNbVolOptSteps
//purpose :
//=======================================================================
void NETGENPlugin_Hypothesis::SetNbVolOptSteps( int theVal )
{
if (theVal != _nbVolOptSteps)
{
_nbVolOptSteps = theVal;
NotifySubMeshesHypothesisModification();
}
}
//=======================================================================
//function : SetElemSizeWeight
//purpose :
//=======================================================================
void NETGENPlugin_Hypothesis::SetElemSizeWeight( double theVal )
{
if (theVal != _elemSizeWeight)
{
_elemSizeWeight = theVal;
NotifySubMeshesHypothesisModification();
}
}
//=======================================================================
//function : SetWorstElemMeasure
//purpose :
//=======================================================================
void NETGENPlugin_Hypothesis::SetWorstElemMeasure( int theVal )
{
if (theVal != _worstElemMeasure)
{
_worstElemMeasure = theVal;
NotifySubMeshesHypothesisModification();
}
}
//=======================================================================
//function : SetUseDelauney
//purpose :
//=======================================================================
void NETGENPlugin_Hypothesis::SetUseDelauney( bool theVal )
{
if (theVal != _useDelauney )
{
_useDelauney = theVal;
NotifySubMeshesHypothesisModification();
}
}
//=======================================================================
//function : SetCheckOverlapping
//purpose :
//=======================================================================
void NETGENPlugin_Hypothesis::SetCheckOverlapping( bool theVal )
{
if (theVal != _checkOverlapping )
{
_checkOverlapping = theVal;
NotifySubMeshesHypothesisModification();
}
}
//=======================================================================
//function : SetCheckChartBoundary
//purpose :
//=======================================================================
void NETGENPlugin_Hypothesis::SetCheckChartBoundary( bool theVal )
{
if (theVal != _checkChartBoundary)
{
_checkChartBoundary = theVal;
NotifySubMeshesHypothesisModification();
}
}
//=============================================================================
/*!
*
*/
//=============================================================================
ostream & NETGENPlugin_Hypothesis::SaveTo(ostream & save)
{
save << _maxSize << " " << _fineness;
if (_fineness == UserDefined)
save << " " << _growthRate << " " << _nbSegPerEdge << " " << _nbSegPerRadius;
save << " " << (int)_secondOrder << " " << (int)_optimize;
TLocalSize::iterator it_sm = _localSize.begin();
if (it_sm != _localSize.end()) {
save << " " << "__LOCALSIZE_BEGIN__";
for ( ; it_sm != _localSize.end(); ++it_sm ) {
save << " " << it_sm->first
<< " " << it_sm->second << "%#"; // "%#" is a mark of value end
}
save << " " << "__LOCALSIZE_END__";
}
save << " " << _minSize;
save << " " << _quadAllowed;
save << " " << _surfaceCurvature;
save << " " << _fuseEdges;
save << " " << _meshSizeFile.size() << " " << _meshSizeFile;
save << " " << ( _chordalErrorEnabled ? _chordalError : 0. );
// added for option set completion
save << " " << _nbSurfOptSteps;
save << " " << _nbVolOptSteps;
save << " " << _elemSizeWeight;
save << " " << _worstElemMeasure;
save << " " << _useDelauney;
save << " " << _checkOverlapping;
save << " " << _checkChartBoundary;
return save;
}
//=============================================================================
/*!
*
*/
//=============================================================================
istream & NETGENPlugin_Hypothesis::LoadFrom(istream & load)
{
bool isOK = true;
int is;
double val;
isOK = static_cast<bool>(load >> val);
if (isOK)
_maxSize = val;
else
load.clear(ios::badbit | load.rdstate());
isOK = static_cast<bool>(load >> is);
if (isOK)
SetFineness((Fineness) is);
else
load.clear(ios::badbit | load.rdstate());
if (_fineness == UserDefined)
{
isOK = static_cast<bool>(load >> val);
if (isOK)
_growthRate = val;
else
load.clear(ios::badbit | load.rdstate());
isOK = static_cast<bool>(load >> val);
if (isOK)
_nbSegPerEdge = val;
else
load.clear(ios::badbit | load.rdstate());
isOK = static_cast<bool>(load >> val);
if (isOK)
_nbSegPerRadius = val;
else
load.clear(ios::badbit | load.rdstate());
}
isOK = static_cast<bool>(load >> is);
if (isOK)
_secondOrder = (bool) is;
else
load.clear(ios::badbit | load.rdstate());
isOK = static_cast<bool>(load >> is);
if (isOK)
_optimize = (bool) is;
else
load.clear(ios::badbit | load.rdstate());
std::string option_or_sm;
bool hasLocalSize = false;
isOK = static_cast<bool>(load >> option_or_sm);
if (isOK)
if (option_or_sm == "__LOCALSIZE_BEGIN__")
hasLocalSize = true;
std::string smEntry, smValue;
while (isOK && hasLocalSize) {
isOK = static_cast<bool>(load >> smEntry);
if (isOK) {
if (smEntry == "__LOCALSIZE_END__")
break;
isOK = static_cast<bool>(load >> smValue);
}
if (isOK) {
std::istringstream tmp(smValue);
double val;
tmp >> val;
_localSize[ smEntry ] = val;
}
}
if ( !hasLocalSize && !option_or_sm.empty() )
_minSize = atof( option_or_sm.c_str() );
else
load >> _minSize;
isOK = static_cast<bool>( load >> is );
if ( isOK )
_quadAllowed = (bool) is;
else
_quadAllowed = GetDefaultQuadAllowed();
isOK = static_cast<bool>( load >> is );
if ( isOK )
_surfaceCurvature = (bool) is;
else
_surfaceCurvature = GetDefaultSurfaceCurvature();
isOK = static_cast<bool>( load >> is );
if ( isOK )
_fuseEdges = (bool) is;
else
_fuseEdges = GetDefaultFuseEdges();
isOK = static_cast<bool>( load >> is >> std::ws ); // size of meshSizeFile
if ( isOK && is > 0 )
{
_meshSizeFile.resize( is );
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 );
// added for option set completion
isOK = static_cast<bool>( load >> is );
if ( isOK )
_nbSurfOptSteps = is;
isOK = static_cast<bool>( load >> is );
if ( isOK )
_nbVolOptSteps = is;
isOK = static_cast<bool>( load >> val );
if ( isOK )
_elemSizeWeight = val;
isOK = static_cast<bool>( load >> is );
if ( isOK )
_worstElemMeasure = is;
isOK = static_cast<bool>( load >> is );
if ( isOK )
_useDelauney = (bool) is;
isOK = static_cast<bool>( load >> is );
if ( isOK )
_checkOverlapping = (bool) is;
isOK = static_cast<bool>( load >> is );
if ( isOK )
_checkChartBoundary = (bool) is;
return load;
}
//================================================================================
/*!
* \brief Does nothing
* \param theMesh - the built mesh
* \param theShape - the geometry of interest
* \retval bool - always false
*/
//================================================================================
bool NETGENPlugin_Hypothesis::SetParametersByMesh(const SMESH_Mesh* /*theMesh*/,
const TopoDS_Shape& /*theShape*/)
{
return false;
}
//================================================================================
/*!
* \brief Initialize my parameter values by default parameters.
* \retval bool - true if parameter values have been successfully defined
*/
//================================================================================
bool NETGENPlugin_Hypothesis::SetParametersByDefaults(const TDefaults& dflts,
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 );
if ( dflts._way == SMESH_Hypothesis::BY_AVERAGE_LENGTH )
{
_minSize = dflts._elemLength / 100.;
_nbSegPerEdge = 1;
_chordalError = dflts._elemLength / 2.;
_chordalErrorEnabled = true;
_quadAllowed = dflts._quadDominated;
}
return _nbSegPerEdge && _maxSize > 0;
}