X-Git-Url: http://git.salome-platform.org/gitweb/?p=modules%2Fsmesh.git;a=blobdiff_plain;f=src%2FStdMeshers%2FStdMeshers_NumberOfSegments.cxx;h=44ac15909556441460b8eb169bfee02e39b2ad42;hp=c16c1373ba4bca2d1bb8caa65d758a1a68c7be50;hb=8672ad3e7621ac25fffa8517599afa84ffea509a;hpb=9ed19e02e901a0d6dc2d44b2251051ac1eaf000e diff --git a/src/StdMeshers/StdMeshers_NumberOfSegments.cxx b/src/StdMeshers/StdMeshers_NumberOfSegments.cxx index c16c1373b..44ac15909 100644 --- a/src/StdMeshers/StdMeshers_NumberOfSegments.cxx +++ b/src/StdMeshers/StdMeshers_NumberOfSegments.cxx @@ -29,6 +29,12 @@ using namespace std; #include "StdMeshers_NumberOfSegments.hxx" +#include +#include +#include +#include + +const double PRECISION = 1e-7; //============================================================================= /*! @@ -37,12 +43,15 @@ using namespace std; //============================================================================= StdMeshers_NumberOfSegments::StdMeshers_NumberOfSegments(int hypId, int studyId, - SMESH_Gen * gen):SMESH_Hypothesis(hypId, studyId, gen) + SMESH_Gen * gen) + : SMESH_Hypothesis(hypId, studyId, gen), + _numberOfSegments(1), + _distrType(DT_Regular), + _scaleFactor(1.), + _expMode(false) { - _numberOfSegments = 1; - _scaleFactor = 1.0; - _name = "NumberOfSegments"; - _param_algo_dim = 1; + _name = "NumberOfSegments"; + _param_algo_dim = 1; } //============================================================================= @@ -85,31 +94,261 @@ int StdMeshers_NumberOfSegments::GetNumberOfSegments() const return _numberOfSegments; } -//============================================================================= +//================================================================================ /*! - * + * */ -//============================================================================= +//================================================================================ + +void StdMeshers_NumberOfSegments::SetDistrType(DistrType typ) + throw(SALOME_Exception) +{ + if (typ < DT_Regular || typ > DT_ExprFunc) + throw SALOME_Exception(LOCALIZED("distribution type is out of range")); + + if (typ != _distrType) + { + _distrType = typ; + NotifySubMeshesHypothesisModification(); + } +} + +//================================================================================ +/*! + * + */ +//================================================================================ + +StdMeshers_NumberOfSegments::DistrType StdMeshers_NumberOfSegments::GetDistrType() const +{ + return _distrType; +} + +//================================================================================ +/*! + * + */ +//================================================================================ void StdMeshers_NumberOfSegments::SetScaleFactor(double scaleFactor) -throw(SALOME_Exception) + throw(SALOME_Exception) { - if (scaleFactor < 0) - throw SALOME_Exception(LOCALIZED("scale factor must be positive")); - _scaleFactor = scaleFactor; + if (_distrType != DT_Scale) + throw SALOME_Exception(LOCALIZED("not a scale distribution")); + if (scaleFactor < PRECISION) + throw SALOME_Exception(LOCALIZED("scale factor must be positive")); + if (fabs(scaleFactor - 1.0) < PRECISION) + throw SALOME_Exception(LOCALIZED("scale factor must not be equal to 1")); - NotifySubMeshesHypothesisModification(); + if (fabs(_scaleFactor - scaleFactor) > PRECISION) + { + _scaleFactor = scaleFactor; + NotifySubMeshesHypothesisModification(); + } } -//============================================================================= +//================================================================================ /*! - * + * */ -//============================================================================= +//================================================================================ double StdMeshers_NumberOfSegments::GetScaleFactor() const + throw(SALOME_Exception) { - return _scaleFactor; + if (_distrType != DT_Scale) + throw SALOME_Exception(LOCALIZED("not a scale distribution")); + return _scaleFactor; +} + +//================================================================================ +/*! + * + */ +//================================================================================ + +void StdMeshers_NumberOfSegments::SetTableFunction(const std::vector& table) + throw(SALOME_Exception) +{ + if (_distrType != DT_TabFunc) + throw SALOME_Exception(LOCALIZED("not a table function distribution")); + if ( (table.size() % 2) != 0 ) + throw SALOME_Exception(LOCALIZED("odd size of vector of table function")); + + int i; + double prev = -PRECISION; + bool isSame = table.size() == _table.size(); + + for (i=0; i < table.size()/2; i++) { + double par = table[i*2]; + double val = table[i*2+1]; + if ( par<0 || par > 1) + throw SALOME_Exception(LOCALIZED("parameter of table function is out of range [0,1]")); + if ( fabs(par-prev) PRECISION || fabs(val - oldval) > PRECISION) + isSame = false; + } + prev = par; + } + + if (!isSame) + { + _table = table; + NotifySubMeshesHypothesisModification(); + } +} + +//================================================================================ +/*! + * + */ +//================================================================================ + +const std::vector& StdMeshers_NumberOfSegments::GetTableFunction() const + throw(SALOME_Exception) +{ + if (_distrType != DT_TabFunc) + throw SALOME_Exception(LOCALIZED("not a table function distribution")); + return _table; +} + +//================================================================================ +/*! check if only 't' is unknown variable in expression + */ +//================================================================================ +bool isCorrect( const Handle( Expr_GeneralExpression )& expr ) +{ + if( expr.IsNull() ) + return true; + + bool res = true; + for( int i=1, n=expr->NbSubExpressions(); i<=n && res; i++ ) + { + Handle( Expr_GeneralExpression ) subexpr = expr->SubExpression( i ); + Handle( Expr_NamedUnknown ) name = Handle( Expr_NamedUnknown )::DownCast( subexpr ); + if( !name.IsNull() ) + { + if( name->GetName()!="t" ) + res = false; + } + else + res = isCorrect( subexpr ); + } + return res; +} + +//================================================================================ +/*! this function parses the expression 'str' in order to check if syntax is correct + * ( result in 'syntax' ) and if only 't' is unknown variable in expression ( result in 'args' ) + */ +//================================================================================ +void casProcess( const TCollection_AsciiString& str, bool& syntax, bool& args ) +{ + // check validity of expression + syntax = false; + args = false; + try + { + Handle( ExprIntrp_GenExp ) gen = ExprIntrp_GenExp::Create(); + gen->Process( str ); + + if( gen->IsDone() ) + { + syntax = true; + args = isCorrect( gen->Expression() ); + } + } + catch (Standard_Failure) + { + } +} + +//================================================================================ +/*! + * + */ +//================================================================================ + +void StdMeshers_NumberOfSegments::SetExpressionFunction(const char* expr) + throw(SALOME_Exception) +{ + if (_distrType != DT_ExprFunc) + throw SALOME_Exception(LOCALIZED("not an expression function distribution")); + + // remove white spaces + TCollection_AsciiString str((Standard_CString)expr); + str.RemoveAll(' '); + str.RemoveAll('\t'); + str.RemoveAll('\r'); + str.RemoveAll('\n'); + + bool syntax, args; + casProcess( str, syntax, args ); + if( !syntax ) + throw SALOME_Exception(LOCALIZED("invalid expression syntax")); + if( !args ) + throw SALOME_Exception(LOCALIZED("only 't' may be used as function argument")); + + string func(str.ToCString()); + if (_func != func) + { + _func = func; + NotifySubMeshesHypothesisModification(); + } +} + +//================================================================================ +/*! + * + */ +//================================================================================ + +const char* StdMeshers_NumberOfSegments::GetExpressionFunction() const + throw(SALOME_Exception) +{ + if (_distrType != DT_ExprFunc) + throw SALOME_Exception(LOCALIZED("not an expression function distribution")); + return _func.c_str(); +} + +//================================================================================ +/*! + * + */ +//================================================================================ + +void StdMeshers_NumberOfSegments::SetExponentMode(bool isExp) + throw(SALOME_Exception) +{ + if (_distrType != DT_TabFunc && _distrType != DT_ExprFunc) + throw SALOME_Exception(LOCALIZED("not a functional distribution")); + + if (isExp != _expMode) + { + _expMode = isExp; + NotifySubMeshesHypothesisModification(); + } +} + +//================================================================================ +/*! + * + */ +//================================================================================ + +bool StdMeshers_NumberOfSegments::IsExponentMode() const + throw(SALOME_Exception) +{ + if (_distrType != DT_TabFunc && _distrType != DT_ExprFunc) + throw SALOME_Exception(LOCALIZED("not a functional distribution")); + return _expMode; } //============================================================================= @@ -120,7 +359,29 @@ double StdMeshers_NumberOfSegments::GetScaleFactor() const ostream & StdMeshers_NumberOfSegments::SaveTo(ostream & save) { - save << this->_numberOfSegments << " " << this->_scaleFactor; + save << _numberOfSegments << " " << (int)_distrType; + switch (_distrType) + { + case DT_Scale: + save << " " << _scaleFactor; + break; + case DT_TabFunc: + int i; + save << " " << _table.size(); + for (i=0; i < _table.size(); i++) + save << " " << _table[i]; + break; + case DT_ExprFunc: + save << " " << _func; + break; + case DT_Regular: + default: + break; + } + + if (_distrType == DT_TabFunc || _distrType == DT_ExprFunc) + save << " " << (int)_expMode; + return save; } @@ -134,17 +395,81 @@ istream & StdMeshers_NumberOfSegments::LoadFrom(istream & load) { bool isOK = true; int a; + + // read number of segments isOK = (load >> a); if (isOK) - this->_numberOfSegments = a; + _numberOfSegments = a; else load.clear(ios::badbit | load.rdstate()); - double b; - isOK = (load >> b); + + // read ditribution type + isOK = (load >> a); if (isOK) - this->_scaleFactor = b; + { + if (a < DT_Regular || a > DT_ExprFunc) + _distrType = DT_Regular; + else + _distrType = (DistrType) a; + } else load.clear(ios::badbit | load.rdstate()); + + // parameters of distribution + double b; + switch (_distrType) + { + case DT_Scale: + { + isOK = (load >> b); + if (isOK) + _scaleFactor = b; + else + load.clear(ios::badbit | load.rdstate()); + } + break; + case DT_TabFunc: + { + isOK = (load >> a); + if (isOK) + _table.resize(a, 0.); + else + load.clear(ios::badbit | load.rdstate()); + int i; + for (i=0; i < _table.size(); i++) + { + isOK = (load >> b); + if (isOK) + _table[i] = b; + else + load.clear(ios::badbit | load.rdstate()); + } + } + break; + case DT_ExprFunc: + { + string str; + isOK = (load >> str); + if (isOK) + _func = str; + else + load.clear(ios::badbit | load.rdstate()); + } + break; + case DT_Regular: + default: + break; + } + + if (_distrType == DT_TabFunc || _distrType == DT_ExprFunc) + { + isOK = (load >> a); + if (isOK) + _expMode = (bool) a; + else + load.clear(ios::badbit | load.rdstate()); + } + return load; }