X-Git-Url: http://git.salome-platform.org/gitweb/?p=modules%2Fsmesh.git;a=blobdiff_plain;f=src%2FStdMeshers%2FStdMeshers_NumberOfSegments.cxx;h=927e96d02ab10ac89622854ab2d5ea09a4c4d350;hp=ecceafd146ce1e0d1a890961321ba1853ea775e4;hb=9d73526fbc8ecc160281df9046ad4aed0b57e779;hpb=2ad752b10cb247a162b27593121a7ae13173258d diff --git a/src/StdMeshers/StdMeshers_NumberOfSegments.cxx b/src/StdMeshers/StdMeshers_NumberOfSegments.cxx index ecceafd14..927e96d02 100644 --- a/src/StdMeshers/StdMeshers_NumberOfSegments.cxx +++ b/src/StdMeshers/StdMeshers_NumberOfSegments.cxx @@ -1,45 +1,54 @@ -// SMESH SMESH : implementaion of SMESH idl descriptions +// Copyright (C) 2007-2016 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 // -// Copyright (C) 2003 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. -// -// 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.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org +// 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 +// + +// SMESH SMESH : implementaion of SMESH idl descriptions // File : StdMeshers_NumberOfSegments.cxx // Moved here from SMESH_NumberOfSegments.cxx // Author : Paul RASCLE, EDF // Module : SMESH -// $Header$ - -using namespace std; +// #include "StdMeshers_NumberOfSegments.hxx" -#include -#include + +#include "SMESHDS_Mesh.hxx" +#include "SMESHDS_SubMesh.hxx" +#include "SMESH_Comment.hxx" +#include "SMESH_Mesh.hxx" +#include "StdMeshers_Distribution.hxx" + #include -#include -#include -#include -#include -#include #include +#include #include +#include +#include +#include +#include +#include + +#include + +using namespace StdMeshers; +using namespace std; const double PRECISION = 1e-7; @@ -49,13 +58,14 @@ const double PRECISION = 1e-7; */ //============================================================================= -StdMeshers_NumberOfSegments::StdMeshers_NumberOfSegments(int hypId, int studyId, - SMESH_Gen * gen) +StdMeshers_NumberOfSegments::StdMeshers_NumberOfSegments(int hypId, + int studyId, + SMESH_Gen * gen) : SMESH_Hypothesis(hypId, studyId, gen), - _numberOfSegments(1), + _numberOfSegments(15),//issue 19923 _distrType(DT_Regular), _scaleFactor(1.), - _expMode(false) + _convMode(1) //cut negative by default { _name = "NumberOfSegments"; _param_algo_dim = 1; @@ -71,6 +81,31 @@ StdMeshers_NumberOfSegments::~StdMeshers_NumberOfSegments() { } +//============================================================================= +/*! + * + */ +//============================================================================= +const vector& +StdMeshers_NumberOfSegments::BuildDistributionExpr( const char* expr,int nbSeg,int conv ) + throw ( SALOME_Exception ) +{ + if( !buildDistribution( TCollection_AsciiString( ( Standard_CString )expr ), conv, 0.0, 1.0, nbSeg, _distr, 1E-4 ) ) + _distr.resize( 0 ); + return _distr; +} + +const vector& +StdMeshers_NumberOfSegments::BuildDistributionTab( const vector& tab, + int nbSeg, + int conv ) + throw ( SALOME_Exception ) +{ + if( !buildDistribution( tab, conv, 0.0, 1.0, nbSeg, _distr, 1E-4 ) ) + _distr.resize( 0 ); + return _distr; +} + //============================================================================= /*! * @@ -80,14 +115,13 @@ StdMeshers_NumberOfSegments::~StdMeshers_NumberOfSegments() void StdMeshers_NumberOfSegments::SetNumberOfSegments(int segmentsNumber) throw(SALOME_Exception) { - int oldNumberOfSegments = _numberOfSegments; - if (segmentsNumber <= 0) - throw - SALOME_Exception(LOCALIZED("number of segments must be positive")); - _numberOfSegments = segmentsNumber; - - if (oldNumberOfSegments != _numberOfSegments) - NotifySubMeshesHypothesisModification(); + int oldNumberOfSegments = _numberOfSegments; + if (segmentsNumber <= 0) + throw SALOME_Exception(LOCALIZED("number of segments must be positive")); + _numberOfSegments = segmentsNumber; + + if (oldNumberOfSegments != _numberOfSegments) + NotifySubMeshesHypothesisModification(); } //============================================================================= @@ -98,7 +132,7 @@ throw(SALOME_Exception) int StdMeshers_NumberOfSegments::GetNumberOfSegments() const { - return _numberOfSegments; + return _numberOfSegments; } //================================================================================ @@ -140,14 +174,17 @@ StdMeshers_NumberOfSegments::DistrType StdMeshers_NumberOfSegments::GetDistrType void StdMeshers_NumberOfSegments::SetScaleFactor(double scaleFactor) throw(SALOME_Exception) { - 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")); - if (fabs(_scaleFactor - scaleFactor) > PRECISION) + if (_distrType != DT_Scale) + _distrType = DT_Scale; + +// commented by mpa for IPAL 52986 +// if ( fabs(scaleFactor - 1.0) < PRECISION ) +// _distrType = DT_Regular; + + if ( fabs(_scaleFactor - scaleFactor) > PRECISION ) { _scaleFactor = scaleFactor; NotifySubMeshesHypothesisModification(); @@ -156,7 +193,7 @@ void StdMeshers_NumberOfSegments::SetScaleFactor(double scaleFactor) //================================================================================ /*! - * + * */ //================================================================================ @@ -170,39 +207,55 @@ double StdMeshers_NumberOfSegments::GetScaleFactor() const //================================================================================ /*! - * + * */ //================================================================================ -void StdMeshers_NumberOfSegments::SetTableFunction(const std::vector& table) +void StdMeshers_NumberOfSegments::SetTableFunction(const vector& table) throw(SALOME_Exception) { if (_distrType != DT_TabFunc) - throw SALOME_Exception(LOCALIZED("not a table function distribution")); + _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(); bool pos = false; - for (i=0; i < table.size()/2; i++) { + for ( size_t i = 0; i < table.size() / 2; i++ ) + { double par = table[i*2]; double val = table[i*2+1]; - if ( par<0 || par > 1) + if( _convMode==0 ) + { + try { + OCC_CATCH_SIGNALS; + val = pow( 10.0, val ); + } + catch(Standard_Failure) { + Handle(Standard_Failure) aFail = Standard_Failure::Caught(); + throw SALOME_Exception( LOCALIZED( "invalid value")); + return; + } + } + else if( _convMode==1 && val<0.0 ) + val = 0.0; + + if ( par < 0 || par > 1) throw SALOME_Exception(LOCALIZED("parameter of table function is out of range [0,1]")); - if ( fabs(par-prev)PRECISION ) + if( val > PRECISION ) pos = true; if (isSame) { double oldpar = _table[i*2]; double oldval = _table[i*2+1]; - if (fabs(par - oldpar) > PRECISION || fabs(val - oldval) > PRECISION) + if ( fabs(par - oldpar) > PRECISION || fabs(val - oldval) > PRECISION ) isSame = false; } prev = par; @@ -211,7 +264,7 @@ void StdMeshers_NumberOfSegments::SetTableFunction(const std::vector& ta if( !pos ) throw SALOME_Exception(LOCALIZED("value of table function is not positive")); - if( pos && !isSame ) + if ( pos && !isSame ) { _table = table; NotifySubMeshesHypothesisModification(); @@ -220,11 +273,11 @@ void StdMeshers_NumberOfSegments::SetTableFunction(const std::vector& ta //================================================================================ /*! - * + * */ //================================================================================ -const std::vector& StdMeshers_NumberOfSegments::GetTableFunction() const +const vector& StdMeshers_NumberOfSegments::GetTableFunction() const throw(SALOME_Exception) { if (_distrType != DT_TabFunc) @@ -250,7 +303,7 @@ bool isCorrectArg( const Handle( Expr_GeneralExpression )& expr ) if( !name.IsNull() ) { if( name->GetName()!="t" ) - res = false; + res = false; } else res = isCorrectArg( sub ); @@ -263,21 +316,33 @@ bool isCorrectArg( const Handle( Expr_GeneralExpression )& expr ) * ( result in 'syntax' ) and if only 't' is unknown variable in expression ( result in 'args' ) */ //================================================================================ -bool process( const TCollection_AsciiString& str, - bool& syntax, bool& args, - bool& non_neg, bool& non_zero, - bool& singulars, double& sing_point ) +bool process( const TCollection_AsciiString& str, int convMode, + bool& syntax, bool& args, + bool& non_neg, bool& non_zero, + bool& singulars, double& sing_point ) { - Handle( ExprIntrp_GenExp ) myExpr = ExprIntrp_GenExp::Create(); - myExpr->Process( str.ToCString() ); + Kernel_Utils::Localizer loc; + + bool parsed_ok = true; + Handle( ExprIntrp_GenExp ) myExpr; + try { + OCC_CATCH_SIGNALS; + myExpr = ExprIntrp_GenExp::Create(); + myExpr->Process( str.ToCString() ); + } catch(Standard_Failure) { + Handle(Standard_Failure) aFail = Standard_Failure::Caught(); + parsed_ok = false; + } - if( myExpr->IsDone() ) + syntax = false; + args = false; + if( parsed_ok && myExpr->IsDone() ) { syntax = true; args = isCorrectArg( myExpr->Expression() ); } - bool res = syntax && args; + bool res = parsed_ok && syntax && args; if( !res ) myExpr.Nullify(); @@ -287,42 +352,28 @@ bool process( const TCollection_AsciiString& str, if( res ) { - OSD::SetSignal( true ); - CASCatch_CatchSignals aCatchSignals; - aCatchSignals.Activate(); - double res; - Expr_Array1OfNamedUnknown myVars( 1, 1 ); - TColStd_Array1OfReal myValues( 1, 1 ); - myVars.ChangeValue( 1 ) = new Expr_NamedUnknown( "t" ); - + FunctionExpr f( str.ToCString(), convMode ); const int max = 500; for( int i=0; i<=max; i++ ) { - double t = double(i)/double(max); - myValues.ChangeValue( 1 ) = t; - CASCatch_TRY - { - res = myExpr->Expression()->Evaluate( myVars, myValues ); - } - CASCatch_CATCH(CASCatch_Failure) + double t = double(i)/double(max), val; + if( !f.value( t, val ) ) { - aCatchSignals.Deactivate(); - Handle(CASCatch_Failure) aFail = CASCatch_Failure::Caught(); - sing_point = t; - singulars = true; - break; + sing_point = t; + singulars = true; + break; } - if( res<0 ) + if( val<0 ) { - non_neg = false; - break; + non_neg = false; + break; } - if( res>PRECISION ) - non_zero = true; + if( val>PRECISION ) + non_zero = true; } - aCatchSignals.Deactivate(); } - return res && non_neg && ( !singulars ); + + return res && non_neg && non_zero && ( !singulars ); } //================================================================================ @@ -335,10 +386,29 @@ void StdMeshers_NumberOfSegments::SetExpressionFunction(const char* expr) throw(SALOME_Exception) { if (_distrType != DT_ExprFunc) - throw SALOME_Exception(LOCALIZED("not an expression function distribution")); + _distrType = DT_ExprFunc; + + string func = CheckExpressionFunction( expr, _convMode ); + if( _func != func ) + { + _func = func; + NotifySubMeshesHypothesisModification(); + } +} +//======================================================================= +//function : CheckExpressionFunction +//purpose : Checks validity of the expression of the function f(t), e.g. "sin(t)". +// In case of validity returns a cleaned expression +//======================================================================= + +std::string +StdMeshers_NumberOfSegments::CheckExpressionFunction( const std::string& expr, + const int convMode) + throw (SALOME_Exception) +{ // remove white spaces - TCollection_AsciiString str((Standard_CString)expr); + TCollection_AsciiString str((Standard_CString)expr.c_str()); str.RemoveAll(' '); str.RemoveAll('\t'); str.RemoveAll('\r'); @@ -346,15 +416,15 @@ void StdMeshers_NumberOfSegments::SetExpressionFunction(const char* expr) bool syntax, args, non_neg, singulars, non_zero; double sing_point; - bool res = true;//process( str, syntax, args, non_neg, non_zero, singulars, sing_point ); + bool res = process( str, convMode, syntax, args, non_neg, non_zero, singulars, sing_point ); if( !res ) { if( !syntax ) - throw SALOME_Exception(LOCALIZED("invalid expression syntax")); + throw SALOME_Exception(SMESH_Comment("invalid expression syntax: ") << str ); if( !args ) throw SALOME_Exception(LOCALIZED("only 't' may be used as function argument")); if( !non_neg ) - throw SALOME_Exception(LOCALIZED("only non-negative function can be used as density")); + throw SALOME_Exception(LOCALIZED("only non-negative function can be used")); if( singulars ) { char buf[1024]; @@ -362,17 +432,10 @@ void StdMeshers_NumberOfSegments::SetExpressionFunction(const char* expr) throw SALOME_Exception( buf ); } if( !non_zero ) - throw SALOME_Exception(LOCALIZED("f(t)=0 cannot be used as density")); - - return; - } - - std::string func = expr; - if( _func != func ) - { - _func = func; - NotifySubMeshesHypothesisModification(); + throw SALOME_Exception(LOCALIZED("f(t)=0 cannot be used")); } + + return str.ToCString(); } //================================================================================ @@ -395,15 +458,15 @@ const char* StdMeshers_NumberOfSegments::GetExpressionFunction() const */ //================================================================================ -void StdMeshers_NumberOfSegments::SetExponentMode(bool isExp) +void StdMeshers_NumberOfSegments::SetConversionMode( int conv ) throw(SALOME_Exception) { - if (_distrType != DT_TabFunc && _distrType != DT_ExprFunc) - throw SALOME_Exception(LOCALIZED("not a functional distribution")); +// if (_distrType != DT_TabFunc && _distrType != DT_ExprFunc) +// throw SALOME_Exception(LOCALIZED("not a functional distribution")); - if (isExp != _expMode) + if( conv != _convMode ) { - _expMode = isExp; + _convMode = conv; NotifySubMeshesHypothesisModification(); } } @@ -414,12 +477,12 @@ void StdMeshers_NumberOfSegments::SetExponentMode(bool isExp) */ //================================================================================ -bool StdMeshers_NumberOfSegments::IsExponentMode() const +int StdMeshers_NumberOfSegments::ConversionMode() const throw(SALOME_Exception) { - if (_distrType != DT_TabFunc && _distrType != DT_ExprFunc) - throw SALOME_Exception(LOCALIZED("not a functional distribution")); - return _expMode; +// if (_distrType != DT_TabFunc && _distrType != DT_ExprFunc) +// throw SALOME_Exception(LOCALIZED("not a functional distribution")); + return _convMode; } //============================================================================= @@ -430,6 +493,7 @@ bool StdMeshers_NumberOfSegments::IsExponentMode() const ostream & StdMeshers_NumberOfSegments::SaveTo(ostream & save) { + int listSize = _edgeIDs.size(); save << _numberOfSegments << " " << (int)_distrType; switch (_distrType) { @@ -437,9 +501,8 @@ ostream & StdMeshers_NumberOfSegments::SaveTo(ostream & save) save << " " << _scaleFactor; break; case DT_TabFunc: - int i; save << " " << _table.size(); - for (i=0; i < _table.size(); i++) + for ( size_t i = 0; i < _table.size(); i++ ) save << " " << _table[i]; break; case DT_ExprFunc: @@ -451,7 +514,14 @@ ostream & StdMeshers_NumberOfSegments::SaveTo(ostream & save) } if (_distrType == DT_TabFunc || _distrType == DT_ExprFunc) - save << " " << (int)_expMode; + save << " " << _convMode; + + if ( _distrType != DT_Regular && listSize > 0 ) { + save << " " << listSize; + for ( int i = 0; i < listSize; i++ ) + save << " " << _edgeIDs[i]; + save << " " << _objEntry; + } return save; } @@ -468,14 +538,24 @@ istream & StdMeshers_NumberOfSegments::LoadFrom(istream & load) int a; // read number of segments - isOK = (load >> a); + isOK = static_cast(load >> a); if (isOK) _numberOfSegments = a; else load.clear(ios::badbit | load.rdstate()); - // read ditribution type - isOK = (load >> a); + // read second stored value. It can be two variants here: + // 1. If the hypothesis is stored in old format (nb.segments and scale factor), + // we wait here the scale factor, which is double. + // 2. If the hypothesis is stored in new format + // (nb.segments, distr.type, some other params.), + // we wait here the ditribution type, which is integer + double scale_factor; + isOK = static_cast(load >> scale_factor); + a = (int)scale_factor; + + // try to interprete ditribution type, + // supposing that this hypothesis was written in the new format if (isOK) { if (a < DT_Regular || a > DT_ExprFunc) @@ -492,39 +572,55 @@ istream & StdMeshers_NumberOfSegments::LoadFrom(istream & load) { case DT_Scale: { - isOK = (load >> b); + isOK = static_cast(load >> b); if (isOK) _scaleFactor = b; else + { load.clear(ios::badbit | load.rdstate()); + // this can mean, that the hypothesis is stored in old format + _distrType = DT_Regular; + _scaleFactor = scale_factor; + } } break; case DT_TabFunc: { - isOK = (load >> a); + isOK = static_cast(load >> a); if (isOK) + { _table.resize(a, 0.); + for ( size_t i=0; i < _table.size(); i++ ) + { + isOK = static_cast(load >> b); + if (isOK) + _table[i] = b; + else + load.clear(ios::badbit | load.rdstate()); + } + } 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()); + load.clear(ios::badbit | load.rdstate()); + // this can mean, that the hypothesis is stored in old format + _distrType = DT_Regular; + _scaleFactor = scale_factor; } } break; case DT_ExprFunc: { string str; - isOK = (load >> str); + isOK = static_cast(load >> str); if (isOK) _func = str; else + { load.clear(ios::badbit | load.rdstate()); + // this can mean, that the hypothesis is stored in old format + _distrType = DT_Regular; + _scaleFactor = scale_factor; + } } break; case DT_Regular: @@ -534,19 +630,31 @@ istream & StdMeshers_NumberOfSegments::LoadFrom(istream & load) if (_distrType == DT_TabFunc || _distrType == DT_ExprFunc) { - isOK = (load >> a); + isOK = static_cast(load >> a); if (isOK) - _expMode = (bool) a; + _convMode = a; else load.clear(ios::badbit | load.rdstate()); } + // load reversed edges IDs + int intVal; + isOK = static_cast(load >> intVal); + if ( isOK && _distrType != DT_Regular && intVal > 0 ) { + _edgeIDs.reserve( intVal ); + for ( size_t i = 0; i < _edgeIDs.capacity() && isOK; i++) { + isOK = static_cast(load >> intVal); + if ( isOK ) _edgeIDs.push_back( intVal ); + } + isOK = static_cast(load >> _objEntry); + } + return load; } //============================================================================= /*! - * + * */ //============================================================================= @@ -565,3 +673,70 @@ istream & operator >>(istream & load, StdMeshers_NumberOfSegments & hyp) { return hyp.LoadFrom( load ); } + +//================================================================================ +/*! + * \brief Initialize number of segments by the mesh built on the geometry + * \param theMesh - the built mesh + * \param theShape - the geometry of interest + * \retval bool - true if parameter values have been successfully defined + */ +//================================================================================ + +bool StdMeshers_NumberOfSegments::SetParametersByMesh(const SMESH_Mesh* theMesh, + const TopoDS_Shape& theShape) +{ + if ( !theMesh || theShape.IsNull() ) + return false; + + _numberOfSegments = 0; + _distrType = DT_Regular; + + int nbEdges = 0; + TopTools_IndexedMapOfShape edgeMap; + TopExp::MapShapes( theShape, TopAbs_EDGE, edgeMap ); + SMESHDS_Mesh* aMeshDS = const_cast< SMESH_Mesh* >( theMesh )->GetMeshDS(); + for ( int i = 1; i <= edgeMap.Extent(); ++i ) + { + // get current segment length + SMESHDS_SubMesh * eSubMesh = aMeshDS->MeshElements( edgeMap( i )); + if ( eSubMesh && eSubMesh->NbElements()) + _numberOfSegments += eSubMesh->NbElements(); + + ++nbEdges; + } + if ( nbEdges ) + _numberOfSegments /= nbEdges; + + if (_numberOfSegments == 0) _numberOfSegments = 1; + + return nbEdges; +} +//================================================================================ +/*! + * \brief Initialize my parameter values by default parameters. + * \retval bool - true if parameter values have been successfully defined + */ +//================================================================================ + +bool StdMeshers_NumberOfSegments::SetParametersByDefaults(const TDefaults& dflts, + const SMESH_Mesh* /*theMesh*/) +{ + return (_numberOfSegments = dflts._nbSegments ); +} + +//============================================================================= +/*! + * + */ +//============================================================================= + +void StdMeshers_NumberOfSegments::SetReversedEdges( std::vector& ids ) +{ + if ( ids != _edgeIDs ) { + _edgeIDs = ids; + + NotifySubMeshesHypothesisModification(); + } +} +