From 8672ad3e7621ac25fffa8517599afa84ffea509a Mon Sep 17 00:00:00 2001 From: asl Date: Tue, 16 Aug 2005 12:26:35 +0000 Subject: [PATCH] PAL8238 --- idl/SMESH_BasicHypothesis.idl | 51 ++- src/SMESH_SWIG/Makefile.in | 3 +- src/StdMeshers/Makefile.in | 4 +- .../StdMeshers_NumberOfSegments.cxx | 369 ++++++++++++++++-- .../StdMeshers_NumberOfSegments.hxx | 116 +++++- src/StdMeshers/StdMeshers_Regular_1D.cxx | 349 ++++++++++++++++- src/StdMeshers/StdMeshers_Regular_1D.hxx | 20 +- src/StdMeshersGUI/StdMeshersGUI.cxx | 14 +- .../StdMeshersGUI_CreateHypothesisDlg.cxx | 194 ++++++--- .../StdMeshersGUI_CreateHypothesisDlg.h | 35 +- .../StdMeshersGUI_Parameters.cxx | 160 +++++++- src/StdMeshersGUI/StdMeshersGUI_Parameters.h | 4 + src/StdMeshersGUI/StdMeshers_msg_en.po | 24 ++ .../StdMeshers_NumberOfSegments_i.cxx | 169 +++++++- .../StdMeshers_NumberOfSegments_i.hxx | 31 +- 15 files changed, 1406 insertions(+), 137 deletions(-) diff --git a/idl/SMESH_BasicHypothesis.idl b/idl/SMESH_BasicHypothesis.idl index cd23d2431..78ca9b77e 100644 --- a/idl/SMESH_BasicHypothesis.idl +++ b/idl/SMESH_BasicHypothesis.idl @@ -28,6 +28,7 @@ #include "SALOME_Exception.idl" #include "SMESH_Hypothesis.idl" +#include "SMESH_Mesh.idl" /*! @@ -68,6 +69,17 @@ module StdMeshers */ long GetNumberOfSegments(); + /*! + * Sets parameter value + */ + void SetDistrType(in long typ) + raises (SALOME::SALOME_Exception); + + /*! + * Returns parameter value + */ + long GetDistrType(); + /*! * Sets parameter value */ @@ -77,7 +89,44 @@ module StdMeshers /*! * Returns parameter value */ - double GetScaleFactor(); + double GetScaleFactor() + raises (SALOME::SALOME_Exception); + + /*! + * Sets parameter value for distribution DT_TabFunc + */ + void SetTableFunction(in SMESH::double_array table) + raises (SALOME::SALOME_Exception); + + /*! + * Returns
parameter value for distribution DT_TabFunc + */ + SMESH::double_array GetTableFunction() + raises (SALOME::SALOME_Exception); + + /*! + * Sets parameter value for distribution DT_ExprFunc + */ + void SetExpressionFunction(in string expr) + raises (SALOME::SALOME_Exception); + + /*! + * Returns parameter value for distribution DT_ExprFunc + */ + string GetExpressionFunction() + raises (SALOME::SALOME_Exception); + + /*! + * Sets parameter value for functional distributions + */ + void SetExponentMode(in boolean isExponent) + raises (SALOME::SALOME_Exception); + + /*! + * Returns parameter value for functional distributions + */ + boolean IsExponentMode() + raises (SALOME::SALOME_Exception); }; /*! diff --git a/src/SMESH_SWIG/Makefile.in b/src/SMESH_SWIG/Makefile.in index a6c0165aa..df7e19a17 100644 --- a/src/SMESH_SWIG/Makefile.in +++ b/src/SMESH_SWIG/Makefile.in @@ -94,7 +94,8 @@ EXPORT_PYSCRIPTS = libSMESH_Swig.py \ SMESH_GroupLyingOnGeom.py \ PAL_MESH_041_mesh.py \ PAL_MESH_043_2D.py \ - PAL_MESH_043_3D.py + PAL_MESH_043_3D.py \ + SMESH_reg.py LIB_CLIENT_IDL = SALOMEDS.idl \ SALOME_Exception.idl \ diff --git a/src/StdMeshers/Makefile.in b/src/StdMeshers/Makefile.in index caa833378..88661b551 100644 --- a/src/StdMeshers/Makefile.in +++ b/src/StdMeshers/Makefile.in @@ -71,7 +71,7 @@ LIB_SRC = \ StdMeshers_Quadrangle_2D.cxx \ StdMeshers_MEFISTO_2D.cxx \ StdMeshers_Penta_3D.cxx \ - StdMeshers_Hexa_3D.cxx + StdMeshers_Hexa_3D.cxx LIB_SERVER_IDL = @@ -85,6 +85,6 @@ BIN_SRC = CPPFLAGS+= $(OCC_INCLUDES) -I${KERNEL_ROOT_DIR}/include/salome $(BOOST_CPPFLAGS) CXXFLAGS+= $(OCC_CXXFLAGS) -I${KERNEL_ROOT_DIR}/include/salome -I${GEOM_ROOT_DIR}/include/salome -LDFLAGS+= -lSMESHimpl -lMEFISTO2D -L${KERNEL_ROOT_DIR}/lib/salome -L${GEOM_ROOT_DIR}/lib/salome +LDFLAGS+= -lSMESHimpl -lMEFISTO2D -L${CASROOT}/Linux/lib -lTKAdvTools -L${KERNEL_ROOT_DIR}/lib/salome -L${GEOM_ROOT_DIR}/lib/salome @CONCLUDE@ 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; } diff --git a/src/StdMeshers/StdMeshers_NumberOfSegments.hxx b/src/StdMeshers/StdMeshers_NumberOfSegments.hxx index 5ae8dc918..2f559fb04 100644 --- a/src/StdMeshers/StdMeshers_NumberOfSegments.hxx +++ b/src/StdMeshers/StdMeshers_NumberOfSegments.hxx @@ -32,7 +32,14 @@ #include "SMESH_Hypothesis.hxx" #include "Utils_SALOME_Exception.hxx" +#include +/*! + * \brief This class represents hypothesis for 1d algorithm + * + * It provides parameters for subdivision an edge by various + * distribution types, considering the given number of resulting segments + */ class StdMeshers_NumberOfSegments: public SMESH_Hypothesis { @@ -40,15 +47,114 @@ public: StdMeshers_NumberOfSegments(int hypId, int studyId, SMESH_Gen* gen); virtual ~StdMeshers_NumberOfSegments(); + /*! + * \brief Set the number of segments + * \param segmentsNumber - must be greater than zero + */ void SetNumberOfSegments(int segmentsNumber) throw (SALOME_Exception); + /*! + * \brief Get the number of segments + */ int GetNumberOfSegments() const; + /*! + * \brief This enumeration presents available types of distribution + */ + enum DistrType + { + DT_Regular, //!< equidistant distribution + DT_Scale, //!< scale distribution + DT_TabFunc, //!< distribution with density function presented by table + DT_ExprFunc //!< distribution with density function presented by expression + }; + + /*! + * \brief Set distribution type + */ + void SetDistrType(DistrType typ) + throw (SALOME_Exception); + + /*! + * \brief Get distribution type + */ + DistrType GetDistrType() const; + + /*! + * \brief Set scale factor for scale distribution + * \param scaleFactor - positive value different from 1 + * + * Throws SALOME_Exception if distribution type is not DT_Scale, + * or scaleFactor is not a positive value different from 1 + */ virtual void SetScaleFactor(double scaleFactor) throw (SALOME_Exception); - double GetScaleFactor() const; + /*! + * \brief Get scale factor for scale distribution + * + * Throws SALOME_Exception if distribution type is not DT_Scale + */ + double GetScaleFactor() const + throw (SALOME_Exception); + + /*! + * \brief Set table function for distribution DT_TabFunc + * \param table - this vector contains the pairs (parameter, value) + * following each by other, so the number of elements in the vector + * must be even. The parameters must be in range [0,1] and sorted in + * increase order. The values of function must be positive. + * + * Throws SALOME_Exception if distribution type is not DT_TabFunc + */ + void SetTableFunction(const std::vector& table) + throw (SALOME_Exception); + + /*! + * \brief Get table function for distribution DT_TabFunc + * + * Throws SALOME_Exception if distribution type is not DT_TabFunc + */ + const std::vector& GetTableFunction() const + throw (SALOME_Exception); + + /*! + * \brief Set expression function for distribution DT_ExprFunc + * \param expr - string containing the expression of the function + * f(t), e.g. "sin(t)" + * + * Throws SALOME_Exception if distribution type is not DT_ExprFunc + */ + void SetExpressionFunction(const char* expr) + throw (SALOME_Exception); + + /*! + * \brief Get expression function for distribution DT_ExprFunc + * + * Throws SALOME_Exception if distribution type is not DT_ExprFunc + */ + const char* GetExpressionFunction() const + throw (SALOME_Exception); + + /*! + * \brief When exponent mode is set, the function of distribution of density + * is used as an exponent of 10, i,e, 10^f(t). This mode is sensible only when + * function distribution is used (DT_TabFunc or DT_ExprFunc) + * \param isExp - boolean switching on/off the mode + * + * Throws SALOME_Exception if distribution type is not functional + */ + void SetExponentMode(bool isExp) + throw (SALOME_Exception); + + /*! + * \brief Returns true if the exponent mode is set + * + * Throws SALOME_Exception if distribution type is not functional + */ + bool IsExponentMode() const + throw (SALOME_Exception); virtual ostream & SaveTo(ostream & save); virtual istream & LoadFrom(istream & load); @@ -56,8 +162,12 @@ public: friend istream& operator >> (istream & load, StdMeshers_NumberOfSegments & hyp); protected: - int _numberOfSegments; - double _scaleFactor; + int _numberOfSegments; //!< an edge will be split on to this number of segments + DistrType _distrType; //!< the type of distribution of density function + double _scaleFactor; //!< the scale parameter for DT_Scale + std::vector _table; //!< the table for DT_TabFunc, a sequence of pairs of numbers + std::string _func; //!< the expression of the function for DT_ExprFunc + bool _expMode; //!< flag of exponent mode }; #endif diff --git a/src/StdMeshers/StdMeshers_Regular_1D.cxx b/src/StdMeshers/StdMeshers_Regular_1D.cxx index 017af4544..be3e69f1d 100644 --- a/src/StdMeshers/StdMeshers_Regular_1D.cxx +++ b/src/StdMeshers/StdMeshers_Regular_1D.cxx @@ -44,6 +44,7 @@ using namespace std; #include "SMDS_EdgePosition.hxx" #include "SMESH_subMesh.hxx" +#include "Utils_SALOME_Exception.hxx" #include "utilities.h" #include @@ -56,9 +57,14 @@ using namespace std; #include #include #include +#include +#include +#include +#include +#include #include -//#include +#include //============================================================================= /*! @@ -131,9 +137,29 @@ bool StdMeshers_Regular_1D::CheckHypothesis const StdMeshers_NumberOfSegments * hyp = dynamic_cast (theHyp); ASSERT(hyp); - _value[ NB_SEGMENTS_IND ] = hyp->GetNumberOfSegments(); - _value[ SCALE_FACTOR_IND ] = hyp->GetScaleFactor(); - ASSERT( _value[ NB_SEGMENTS_IND ] > 0 ); + _ivalue[ NB_SEGMENTS_IND ] = hyp->GetNumberOfSegments(); + ASSERT( _ivalue[ NB_SEGMENTS_IND ] > 0 ); + _ivalue[ DISTR_TYPE_IND ] = (int) hyp->GetDistrType(); + switch (_ivalue[ DISTR_TYPE_IND ]) + { + case StdMeshers_NumberOfSegments::DT_Scale: + _value[ SCALE_FACTOR_IND ] = hyp->GetScaleFactor(); + break; + case StdMeshers_NumberOfSegments::DT_TabFunc: + _vvalue[ TAB_FUNC_IND ] = hyp->GetTableFunction(); + break; + case StdMeshers_NumberOfSegments::DT_ExprFunc: + _svalue[ EXPR_FUNC_IND ] = hyp->GetExpressionFunction(); + break; + case StdMeshers_NumberOfSegments::DT_Regular: + break; + default: + ASSERT(0); + break; + } + if (_ivalue[ DISTR_TYPE_IND ] == StdMeshers_NumberOfSegments::DT_TabFunc || + _ivalue[ DISTR_TYPE_IND ] == StdMeshers_NumberOfSegments::DT_ExprFunc) + _ivalue[ EXP_MODE_IND ] = (int) hyp->IsExponentMode(); _hypType = NB_SEGMENTS; aStatus = SMESH_Hypothesis::HYP_OK; } @@ -221,6 +247,265 @@ static void compensateError(double a1, double an, } } +/*! + * \brief This class provides interface for a density function + */ +class Function +{ +public: + Function(bool expMode) : _expMode(expMode) {} + double operator() (double t) const; + virtual bool IsReady() const = 0; +protected: + virtual double compute(double t) const = 0; +private: + bool _expMode; +}; + +/*! + * \brief This class provides computation of density function given by a table + */ +class TabFunction: public Function +{ +public: + TabFunction(const vector& table, bool expMode); + virtual bool IsReady() const; +protected: + virtual double compute(double t) const; +private: + const vector& _table; +}; + +/*! + * \brief This class provides computation of density function given by an expression + */ +class ExprFunction: public Function +{ +public: + ExprFunction(const char* expr, bool expMode); + virtual bool IsReady() const; +protected: + virtual double compute(double t) const; +private: + Handle(Expr_GeneralExpression) _expression; + Expr_Array1OfNamedUnknown _var; + mutable TColStd_Array1OfReal _val; +}; + +double Function::operator() (double t) const +{ + double res = compute(t); + if (_expMode) + res = pow(10, res); + return res; +} + +TabFunction::TabFunction(const vector& table, bool expMode) + : Function(expMode), + _table(table) +{ +} + +bool TabFunction::IsReady() const +{ + return true; +} + +double TabFunction::compute (double t) const +{ + //find place of in table + int i; + for (i=0; i < _table.size()/2; i++) + if (_table[i*2] > t) + break; + if (i >= _table.size()/2) + i = _table.size()/2 - 1; + + if (i == 0) + return _table[1]; + + // interpolate function value on found interval + // (t - x[i-1]) / (x[i] - x[i-1]) = (y - f[i-1]) / (f[i] - f[i-1]) + // => y = f[i-1] + (f[i] - f[i-1]) * (t - x[i-1]) / (x[i] - x[i-1]) + double x1 = _table[(i-1)*2]; + double x2 = _table[i*2]; + double y1 = _table[(i-1)*2+1]; + double y2 = _table[i*2+1]; + if (x2 - x1 < Precision::Confusion()) + throw SALOME_Exception("TabFunction::compute : confused points"); + return y1 + (y2 - y1) * ((t - x1) / (x2 - x1)); +} + +ExprFunction::ExprFunction(const char* expr, bool expMode) + : Function(expMode), + _var(1,1), + _val(1,1) +{ + Handle( ExprIntrp_GenExp ) gen = ExprIntrp_GenExp::Create(); + gen->Process(TCollection_AsciiString((char*)expr)); + if (gen->IsDone()) + { + _expression = gen->Expression(); + _var(1) = new Expr_NamedUnknown("t"); + } +} + +bool ExprFunction::IsReady() const +{ + return !_expression.IsNull(); +} + +double ExprFunction::compute (double t) const +{ + ASSERT(!_expression.IsNull()); + _val(1) = t; + return _expression->Evaluate(_var, _val); +} + +//================================================================================ +/*! + * \brief Compute next abscissa when two previous ones are given + * \param sm2 - before previous abscissa + * \param sm1 - previous abscissa + * \param func - function of density + * \param reverse - the direction of next abscissa, increase (0) or decrease (1) + * \retval double - the new abscissa + * + * The abscissa s is given by the formulae + * + * ....|--------|----------------|..... + * sm2 sm1 s + * + * func(sm2) / func(sm1) = (sm1-sm2) / (s-sm1) + * => (s-sm1) * func(sm2) = (sm1-sm2) * func(sm1) + * => s = sm1 + (sm1-sm2) * func(sm1) / func(sm2) + */ +//================================================================================ + +static double nextAbscissa(double sm2, double sm1, const Function& func, int reverse) +{ + if (reverse) + { + sm1 = 1.0 - sm1; + sm2 = 1.0 - sm2; + } + return sm1 + (sm1-sm2) * func(sm1) / func(sm2); +} + +//================================================================================ +/*! + * \brief Compute distribution of points on a curve following the law of a function + * \param C3d - the curve to discretize + * \param first - the first parameter on the curve + * \param last - the last parameter on the curve + * \param theReverse - flag indicating that the curve must be reversed + * \param nbSeg - number of output segments + * \param func - the function f(t) + * \param theParams - output points + * \retval bool - true if success + */ +//================================================================================ + +static bool computeParamByFunc(Adaptor3d_Curve& C3d, double first, double last, + double length, bool theReverse, + int nbSeg, const Function& func, + list& theParams) +{ + if (!func.IsReady()) + return false; + vector xxx[2]; + int nbPnt = 1 + nbSeg; + int rev, i; + for (rev=0; rev < 2; rev++) + { + // curv abscisses initialisation + vector x(nbPnt, 0.); + // the first abscissa is 0.0 + + // The aim of the algorithm is to find a second abscisse x[1] such as the last + // one x[nbSeg] is very close to 1.0 with the epsilon precision + + double x1_too_small = 0.0; + double x1_too_large = RealLast(); + double x1 = 1.0/nbSeg; + while (1) + { + x[1] = x1; + + // Check if the abscissa of the point 2 to N-1 + // are in the segment ... + + bool ok = true; + for (i=2; i <= nbSeg; i++) + { + x[i] = nextAbscissa(x[i-2], x[i-1], func, rev); + if (x[i] - 1.0 > Precision::Confusion()) + { + x[nbSeg] = x[i]; + ok = false; + break; + } + } + if (!ok) + { + // The segments are to large + // Decrease x1 ... + x1_too_large = x1; + x1 = (x1_too_small+x1_too_large)/2; + continue; + } + + // Look at the abscissa of the point N + // which is to be close to 1.0 + + // break condition --> algo converged !! + + if (1.0 - x[nbSeg] < Precision::Confusion()) + break; + + // not ok ... + + x1_too_small = x1; + + // Modify x1 value + + if (x1_too_large > 1e100) + x1 = 2*x1; + else + x1 = (x1_too_small+x1_too_large)/2; + } + xxx[rev] = x; + } + + // average + vector x(nbPnt, 0.); + for (i=0; i < nbPnt; i++) + x[i] = (xxx[0][i] + (1.0 - xxx[1][nbPnt-i])) / 2; + + // apply parameters in range [0,1] to the space of the curve + double prevU = first; + double sign = 1.; + if (theReverse) + { + prevU = last; + sign = -1.; + } + for (i = 1; i < nbSeg; i++) + { + double curvLength = length * (x[i] - x[i-1]) * sign; + GCPnts_AbscissaPoint Discret( C3d, curvLength, prevU ); + if ( !Discret.IsDone() ) + return false; + double U = Discret.Parameter(); + if ( U > first && U < last ) + theParams.push_back( U ); + else + return false; + prevU = U; + } + return false; +} + //============================================================================= /*! * @@ -246,6 +531,7 @@ bool StdMeshers_Regular_1D::computeInternalParameters(const TopoDS_Edge& theEdge double eltSize = 1; if ( _hypType == LOCAL_LENGTH ) { + // Local Length hypothesis double nbseg = ceil(length / _value[ BEG_LENGTH_IND ]); // integer sup if (nbseg <= 0) nbseg = 1; // degenerated edge @@ -253,26 +539,47 @@ bool StdMeshers_Regular_1D::computeInternalParameters(const TopoDS_Edge& theEdge } else { - double epsilon = 0.001; - if (fabs(_value[ SCALE_FACTOR_IND ] - 1.0) > epsilon) + // Number Of Segments hypothesis + switch (_ivalue[ DISTR_TYPE_IND ]) { - double scale = _value[ SCALE_FACTOR_IND ]; - if ( theReverse ) - scale = 1. / scale; - double alpha = pow( scale , 1.0 / (_value[ NB_SEGMENTS_IND ] - 1)); - double factor = (l - f) / (1 - pow( alpha,_value[ NB_SEGMENTS_IND ])); - - int i, NbPoints = 1 + (int) _value[ NB_SEGMENTS_IND ]; - for ( i = 2; i < NbPoints; i++ ) + case StdMeshers_NumberOfSegments::DT_Scale: { - double param = f + factor * (1 - pow(alpha, i - 1)); - theParams.push_back( param ); + double scale = _value[ SCALE_FACTOR_IND ]; + if ( theReverse ) + scale = 1. / scale; + double alpha = pow( scale , 1.0 / (_ivalue[ NB_SEGMENTS_IND ] - 1)); + double factor = (l - f) / (1 - pow( alpha,_ivalue[ NB_SEGMENTS_IND ])); + + int i, NbPoints = 1 + _ivalue[ NB_SEGMENTS_IND ]; + for ( i = 2; i < NbPoints; i++ ) + { + double param = f + factor * (1 - pow(alpha, i - 1)); + theParams.push_back( param ); + } + return true; } - return true; - } - else - { - eltSize = length / _value[ NB_SEGMENTS_IND ]; + break; + case StdMeshers_NumberOfSegments::DT_TabFunc: + { + TabFunction func(_vvalue[ TAB_FUNC_IND ], (bool)_ivalue[ EXP_MODE_IND ]); + return computeParamByFunc(C3d, f, l, length, theReverse, + _ivalue[ NB_SEGMENTS_IND ], func, + theParams); + } + break; + case StdMeshers_NumberOfSegments::DT_ExprFunc: + { + ExprFunction func(_svalue[ EXPR_FUNC_IND ].c_str(), (bool)_ivalue[ EXP_MODE_IND ]); + return computeParamByFunc(C3d, f, l, length, theReverse, + _ivalue[ NB_SEGMENTS_IND ], func, + theParams); + } + break; + case StdMeshers_NumberOfSegments::DT_Regular: + eltSize = length / _ivalue[ NB_SEGMENTS_IND ]; + break; + default: + return false; } } diff --git a/src/StdMeshers/StdMeshers_Regular_1D.hxx b/src/StdMeshers/StdMeshers_Regular_1D.hxx index b9d61432b..b02e21028 100644 --- a/src/StdMeshers/StdMeshers_Regular_1D.hxx +++ b/src/StdMeshers/StdMeshers_Regular_1D.hxx @@ -65,16 +65,32 @@ protected: enum HypothesisType { LOCAL_LENGTH, NB_SEGMENTS, BEG_END_LENGTH, DEFLECTION, ARITHMETIC_1D, NONE }; enum ValueIndex { - NB_SEGMENTS_IND = 0, - SCALE_FACTOR_IND = 1, + SCALE_FACTOR_IND = 0, BEG_LENGTH_IND = 0, END_LENGTH_IND = 1, DEFLECTION_IND = 0 }; + enum IValueIndex { + NB_SEGMENTS_IND = 0, + DISTR_TYPE_IND = 1, + EXP_MODE_IND = 2 + }; + + enum VValueIndex { + TAB_FUNC_IND = 0 + }; + + enum SValueIndex { + EXPR_FUNC_IND = 0 + }; + HypothesisType _hypType; double _value[2]; + int _ivalue[3]; + std::vector _vvalue[1]; + std::string _svalue[1]; // a source of propagated hypothesis, is set by CheckHypothesis() // always called before Compute() diff --git a/src/StdMeshersGUI/StdMeshersGUI.cxx b/src/StdMeshersGUI/StdMeshersGUI.cxx index 93322c3e7..a5acb3b06 100644 --- a/src/StdMeshersGUI/StdMeshersGUI.cxx +++ b/src/StdMeshersGUI/StdMeshersGUI.cxx @@ -40,6 +40,8 @@ #include "SUIT_Desktop.h" #include "SUIT_ResourceMgr.h" +#include + #include #include "utilities.h" @@ -122,7 +124,17 @@ void StdMeshersGUI_HypothesisCreator::EditHypothesis bool modified = false; if ( SMESHGUI_aParameterDlg::Parameters( SMESHGUI::GetSMESHGUI(), paramList, QObject::tr("SMESH_VALUE")) ) - modified = StdMeshersGUI_Parameters::SetParameters( theHyp, paramList ); + { + try + { + modified = StdMeshersGUI_Parameters::SetParameters( theHyp, paramList ); + } + catch (const SALOME::SALOME_Exception& S_ex) + { + SalomeApp_Tools::QtCatchCorbaException(S_ex); + return; + } + } if ( modified ) { //set new Attribute Comment for hypothesis which parameters were modified diff --git a/src/StdMeshersGUI/StdMeshersGUI_CreateHypothesisDlg.cxx b/src/StdMeshersGUI/StdMeshersGUI_CreateHypothesisDlg.cxx index b68b6d24c..d399b595c 100644 --- a/src/StdMeshersGUI/StdMeshersGUI_CreateHypothesisDlg.cxx +++ b/src/StdMeshersGUI/StdMeshersGUI_CreateHypothesisDlg.cxx @@ -55,6 +55,8 @@ #include #include #include +#include +#include using namespace std; @@ -86,19 +88,25 @@ void StdMeshersGUI_CreateHypothesisDlg::CreateDlgLayout(const QString & theCapti setCaption( theCaption ); setSizeGripEnabled( TRUE ); - QGridLayout* StdMeshersGUI_CreateHypothesisDlgLayout = new QGridLayout( this ); + QVBoxLayout* StdMeshersGUI_CreateHypothesisDlgLayout = new QVBoxLayout( this ); StdMeshersGUI_CreateHypothesisDlgLayout->setSpacing( 6 ); StdMeshersGUI_CreateHypothesisDlgLayout->setMargin( 11 ); /***************************************************************/ - iconLabel = new QLabel( this ); + QFrame* titFrame = new QFrame( this ); + QHBoxLayout* titLay = new QHBoxLayout( titFrame, 0, 0 ); + + iconLabel = new QLabel( titFrame ); iconLabel->setPixmap( theHypIcon ); iconLabel->setScaledContents( false ); iconLabel->setSizePolicy( QSizePolicy( QSizePolicy::Fixed, QSizePolicy::Fixed ) ); - typeLabel = new QLabel( this ); + typeLabel = new QLabel( titFrame ); typeLabel->setText( theHypTypeName ); - StdMeshersGUI_CreateHypothesisDlgLayout->addWidget( iconLabel, 0, 0 ); - StdMeshersGUI_CreateHypothesisDlgLayout->addWidget( typeLabel, 0, 1 ); + titLay->addWidget( iconLabel, 0 ); + titLay->addWidget( typeLabel, 0 ); + titLay->addStretch( 1 ); + + StdMeshersGUI_CreateHypothesisDlgLayout->addWidget( titFrame, 0); /***************************************************************/ GroupC1 = new QGroupBox( this, "GroupC1" ); @@ -118,51 +126,42 @@ void StdMeshersGUI_CreateHypothesisDlg::CreateDlgLayout(const QString & theCapti LineEdit_NameHypothesis = new QLineEdit( GroupC1, "LineEdit_NameHypothesis" ); GroupC1Layout->addWidget( LineEdit_NameHypothesis, 0, 1 ); - myParamList.clear(); - GetParameters( myHypType, myParamList ); - ASSERT( !myParamList.empty() ); + myParamMap.clear(); + std::list aParamList; + GetParameters( myHypType, aParamList ); + ASSERT( !aParamList.empty() ); /* Spin boxes with labels */ - list::iterator paramIt = myParamList.begin(); - for ( int row = 1; paramIt != myParamList.end(); paramIt++ , row++ ) + list::iterator paramIt = aParamList.begin(); + for ( int row = 1; paramIt != aParamList.end(); paramIt++ , row++ ) { SMESHGUI_aParameterPtr param = (*paramIt); QLabel * label = new QLabel( GroupC1, "TextLabel" ); GroupC1Layout->addWidget( label, row, 0 ); label->setText( param->Label() ); - QWidget* aSpinWidget = 0; - switch ( param->GetType() ) { - case SMESHGUI_aParameter::DOUBLE: { - SMESHGUI_SpinBox* spin = new SMESHGUI_SpinBox( GroupC1 ); - aSpinWidget = spin; - spin->setPrecision( 12 ); - break; - } - case SMESHGUI_aParameter::INT: { - QSpinBox* spin = new QSpinBox( GroupC1 ); - aSpinWidget = spin; - break; - } - case SMESHGUI_aParameter::TEXT: { - QTextEdit* edit = new QTextEdit( GroupC1 ); - edit->setWordWrap( QTextEdit::NoWrap ); - edit->setTextFormat( Qt::PlainText ); - aSpinWidget = edit; - break; - } - default:; - } - - if ( aSpinWidget ) { - GroupC1Layout->addWidget( aSpinWidget, row, 1 ); - aSpinWidget->setSizePolicy( QSizePolicy( QSizePolicy::Expanding, QSizePolicy::Minimum ) ); - aSpinWidget->setMinimumSize( 150, 0 ); - param->InitializeWidget( aSpinWidget ); - mySpinList.push_back( aSpinWidget ); + QWidget* aWidget = param->CreateWidget( GroupC1 ); + + if ( aWidget ) { + GroupC1Layout->addWidget( aWidget, row, 1 ); + aWidget->setSizePolicy( QSizePolicy( QSizePolicy::Expanding, QSizePolicy::Minimum ) ); + aWidget->setMinimumSize( 150, 0 ); + + QString sig = param->sigValueChanged(); + if( !sig.isEmpty() && param->GetType()!=SMESHGUI_aParameter::TABLE ) + connect( aWidget, sig.latin1(), this, SLOT( onValueChanged() ) ); + + param->InitializeWidget( aWidget ); + + ParamInfo info; + info.editor = aWidget; + info.label = label; + info.order = row-1; + + myParamMap.insert( param, info ); } } - StdMeshersGUI_CreateHypothesisDlgLayout->addMultiCellWidget(GroupC1 , 1, 1, 0, 1 ); + StdMeshersGUI_CreateHypothesisDlgLayout->addWidget( GroupC1, 1 ); /***************************************************************/ GroupButtons = new QGroupBox( this, "GroupButtons" ); @@ -188,7 +187,7 @@ void StdMeshersGUI_CreateHypothesisDlg::CreateDlgLayout(const QString & theCapti buttonCancel->setText( tr( "SMESH_BUT_CLOSE" ) ); buttonCancel->setAutoDefault( TRUE ); GroupButtonsLayout->addWidget( buttonCancel, 0, 3 ); - StdMeshersGUI_CreateHypothesisDlgLayout->addMultiCellWidget( GroupButtons, 2, 2, 0, 1 ); + StdMeshersGUI_CreateHypothesisDlgLayout->addWidget( GroupButtons, 0 ); /***************************************************************/ Init() ; @@ -211,6 +210,11 @@ StdMeshersGUI_CreateHypothesisDlg::~StdMeshersGUI_CreateHypothesisDlg() //================================================================================= void StdMeshersGUI_CreateHypothesisDlg::Init() { + ParameterMap::const_iterator anIt = myParamMap.begin(), + aLast = myParamMap.end(); + for( ; anIt!=aLast; anIt++ ) + UpdateShown( anIt.key() ); + mySMESHGUI = SMESHGUI::GetSMESHGUI() ; char* sHypType = const_cast(myHypType.latin1()); @@ -263,33 +267,49 @@ bool StdMeshersGUI_CreateHypothesisDlg::ClickOnApply() SUIT_OverrideCursor wc; + SMESH::SMESH_Hypothesis_var Hyp = SMESH::SMESH_Hypothesis::_narrow + ( SMESH::CreateHypothesis( myHypType, myHypName, false ) ); // isAlgorithm + try { - SMESH::SMESH_Hypothesis_var Hyp = SMESH::SMESH_Hypothesis::_narrow - ( SMESH::CreateHypothesis (myHypType, - myHypName, - false )); // isAlgorithm - - list::iterator paramIt = myParamList.begin(); - list::iterator widgetIt = mySpinList.begin(); - for ( ; - paramIt != myParamList.end() && widgetIt != mySpinList.end(); - paramIt++ , widgetIt++ ) - (*paramIt)->TakeValue( *widgetIt ); - SetParameters( Hyp, myParamList ); + list aParamList; + ParameterMap::const_iterator anIt = myParamMap.begin(), + aLast = myParamMap.end(); + for( int i=0; iTakeValue( anIt.data().editor ); + aParamList.push_back( anIt.key() ); + break; + } + + SetParameters( Hyp, aParamList ); //set new Attribute Comment for hypothesis which parameters were set QString aParams = ""; - StdMeshersGUI_Parameters::GetParameters( Hyp.in(), myParamList, aParams ); + StdMeshersGUI_Parameters::GetParameters( Hyp.in(), aParamList, aParams ); _PTR(SObject) SHyp = SMESH::FindSObject(Hyp.in()); if (SHyp) - if (!aParams.isEmpty()) { - SMESH::SetValue(SHyp, aParams); - mySMESHGUI->getApp()->objectBrowser()->updateTree(); + if (!aParams.isEmpty()) + { + SMESH::SetValue(SHyp, aParams); + mySMESHGUI->getApp()->objectBrowser()->updateTree(); } } - catch (const SALOME::SALOME_Exception& S_ex) { + catch (const SALOME::SALOME_Exception& S_ex) + { wc.suspend(); + + _PTR(SObject) SHyp = SMESH::FindSObject(Hyp.in()); + _PTR(Study) aStudy = SMESH::GetActiveStudyDocument(); + if( aStudy && !aStudy->GetProperties()->IsLocked() ) + { + _PTR(StudyBuilder) aBuilder = aStudy->NewBuilder(); + aBuilder->RemoveObjectWithChildren( SHyp ); + mySMESHGUI->updateObjBrowser( true, 0 ); + } + SalomeApp_Tools::QtCatchCorbaException(S_ex); return false; } @@ -355,3 +375,61 @@ void StdMeshersGUI_CreateHypothesisDlg::closeEvent( QCloseEvent* e ) mySMESHGUI->ResetState(); QDialog::closeEvent( e ); } + +//================================================================================= +// function : onValueChanged() +// purpose : +//================================================================================= +void StdMeshersGUI_CreateHypothesisDlg::onValueChanged() +{ + if( sender()->inherits( "QWidget" ) ) + { + QWidget* w = ( QWidget* )sender(); + + SMESHGUI_aParameterPtr param; + + ParameterMap::const_iterator anIt = myParamMap.begin(), + aLast = myParamMap.end(); + for( ; anIt!=aLast; anIt++ ) + if( anIt.data().editor == w ) + { + param = anIt.key(); + param->TakeValue( w ); + UpdateShown( param ); + break; + } + } +} + +//================================================================================= +// function : UpdateShown() +// purpose : +//================================================================================= +void StdMeshersGUI_CreateHypothesisDlg::UpdateShown( const SMESHGUI_aParameterPtr param ) +{ + SMESHGUI_dependParameter* depPar = dynamic_cast( param.get() ); + if( !depPar ) + depPar = dynamic_cast( param.get() ); + + if( !depPar ) + return; + + SMESHGUI_dependParameter::ShownMap& map = depPar->shownMap(); + if( map.isEmpty() ) + return; + + int val; + depPar->TakeValue( myParamMap[ param ].editor ); + depPar->GetNewInt( val ); + + bool hasValue = map.contains( val ); + + ParameterMap::const_iterator anIt = myParamMap.begin(), + aLast = myParamMap.end(); + for( ; anIt!=aLast; anIt++ ) + { + bool shown = hasValue && map[ val ].contains( (*anIt).order ); + (*anIt).editor->setShown( shown ); + (*anIt).label->setShown( shown ); + } +} diff --git a/src/StdMeshersGUI/StdMeshersGUI_CreateHypothesisDlg.h b/src/StdMeshersGUI/StdMeshersGUI_CreateHypothesisDlg.h index aa2a3eda9..3230f8eef 100644 --- a/src/StdMeshersGUI/StdMeshersGUI_CreateHypothesisDlg.h +++ b/src/StdMeshersGUI/StdMeshersGUI_CreateHypothesisDlg.h @@ -30,14 +30,14 @@ // QT Includes #include +#include +#include #include #include CORBA_SERVER_HEADER(SMESH_BasicHypothesis) #include "SMESHGUI_aParameter.h" -#include - class QGroupBox; class QLabel; class QLineEdit; @@ -67,23 +67,34 @@ protected: const QPixmap & hypIcon, const QString & hypTypeName); - virtual void GetParameters(const QString & hypType, - std::list & params) = 0; + virtual void GetParameters( const QString& hypType, + std::list& ) = 0; - virtual bool SetParameters(SMESH::SMESH_Hypothesis_ptr theHyp, - const std::list & params) = 0; + virtual bool SetParameters( SMESH::SMESH_Hypothesis_ptr theHyp, + const std::list & params ) = 0; +protected slots: + virtual void onValueChanged(); + private: - + void UpdateShown( const SMESHGUI_aParameterPtr ); void Init() ; void closeEvent( QCloseEvent* e ) ; void enterEvent ( QEvent * ) ; - SMESHGUI* mySMESHGUI ; - QString myHypType ; - - std::list mySpinList; - std::list myParamList; + SMESHGUI* mySMESHGUI; + QString myHypType; + + typedef struct + { + QWidget* editor; + QLabel* label; + int order; + + } ParamInfo; + + typedef QMap< SMESHGUI_aParameterPtr, ParamInfo > ParameterMap; + ParameterMap myParamMap; QLabel* iconLabel; QLabel* typeLabel; diff --git a/src/StdMeshersGUI/StdMeshersGUI_Parameters.cxx b/src/StdMeshersGUI/StdMeshersGUI_Parameters.cxx index b7e447b3e..7d52876d9 100644 --- a/src/StdMeshersGUI/StdMeshersGUI_Parameters.cxx +++ b/src/StdMeshersGUI/StdMeshersGUI_Parameters.cxx @@ -65,7 +65,25 @@ void StdMeshersGUI_Parameters::SetInitValue(SMESHGUI_aParameterPtr param, int initValue) { SMESHGUI_intParameter* p = dynamic_cast(param.get()); - if ( p ) p->InitValue() = initValue; + if ( p ) + { + p->InitValue() = initValue; + return; + } + + SMESHGUI_enumParameter* q = dynamic_cast(param.get()); + if( q ) + { + q->InitValue() = initValue; + return; + } + + SMESHGUI_boolParameter* b = dynamic_cast(param.get()); + if( b ) + { + b->InitValue() = (bool)initValue; + return; + } } //======================================================================= @@ -92,6 +110,21 @@ void StdMeshersGUI_Parameters::SetInitValue(SMESHGUI_aParameterPtr param, if ( p ) p->InitValue() = initValue; } +//======================================================================= +//function : SetInitValue +//purpose : +//======================================================================= +void StdMeshersGUI_Parameters::SetInitValue( SMESHGUI_aParameterPtr param, + SMESH::double_array& initValue) +{ + SMESHGUI_tableParameter* p = dynamic_cast(param.get()); + if( p ) + { + p->setRowCount( initValue.length()/2 ); + p->setData( initValue ); + } +} + //======================================================================= //function : GetParameters //purpose : @@ -100,6 +133,9 @@ void StdMeshersGUI_Parameters::SetInitValue(SMESHGUI_aParameterPtr param, // SMESHGUI_doubleParameter( initValue, label, bottom, top, step, decimals ) #define DOUBLE_PARAM(v,l,b,t,s,d) SMESHGUI_aParameterPtr(new SMESHGUI_doubleParameter(v,l,b,t,s,d)) #define INT_PARAM(v,l,b,t) SMESHGUI_aParameterPtr(new SMESHGUI_intParameter(v,l,b,t)) +#define ENUM_PARAM(v,i,l) SMESHGUI_aParameterPtr(new SMESHGUI_enumParameter(v,i,l)) +#define STR_PARAM(i,l) SMESHGUI_aParameterPtr(new SMESHGUI_strParameter(i,l)) +#define BOOL_PARAM(i,l) SMESHGUI_aParameterPtr(new SMESHGUI_boolParameter(i,l)) void StdMeshersGUI_Parameters::GetParameters (const QString& hypType, list & paramList ) @@ -114,12 +150,58 @@ void StdMeshersGUI_Parameters::GetParameters (const QString& hyp } else if (hypType.compare("NumberOfSegments") == 0) { + //0-th parameter in list paramList.push_back ( INT_PARAM (3, QObject::tr("SMESH_NB_SEGMENTS_PARAM"), 1, 9999 )); + QStringList types; + types.append( QObject::tr( "SMESH_DISTR_REGULAR" ) ); + types.append( QObject::tr( "SMESH_DISTR_SCALE" ) ); + types.append( QObject::tr( "SMESH_DISTR_TAB" ) ); + types.append( QObject::tr( "SMESH_DISTR_EXPR" ) ); + //string description of distribution types + + SMESHGUI_enumParameter* type = new SMESHGUI_enumParameter( types, 0, QObject::tr( "SMESH_DISTR_TYPE" ) ); + SMESHGUI_dependParameter::ShownMap& aMap = type->shownMap(); + aMap[0].append( 0 ); // if DistrType=0 (regular), then number of segments and types are shown (0-th and 1-th) + aMap[0].append( 1 ); + aMap[1].append( 0 ); // if DistrType=1 (scale), then number of segments, types and scale are shown + aMap[1].append( 1 ); + aMap[1].append( 2 ); + aMap[2].append( 0 ); // if DistrType=2 (table), then number of segments, types, table and exponent are shown + aMap[2].append( 1 ); + aMap[2].append( 3 ); + aMap[2].append( 5 ); + aMap[3].append( 0 ); // if DistrType=3 (expression), then number of segments, types, expression and exponent are shown + aMap[3].append( 1 ); + aMap[3].append( 4 ); + aMap[3].append( 5 ); + //1-th parameter in list + paramList.push_back ( SMESHGUI_aParameterPtr( type ) ); + + //2-th parameter in list paramList.push_back ( DOUBLE_PARAM (1.0, QObject::tr("SMESH_NB_SEGMENTS_SCALE_PARAM"), VALUE_SMALL, VALUE_MAX, 0.1, 6 )); + SMESHGUI_tableParameter* tab = new SMESHGUI_tableParameter( 0.0, QObject::tr( "SMESH_TAB_FUNC" ) ); + tab->setRowCount( 5 ); + tab->setColCount( 2 ); + //default size of table: 5x2 + + tab->setColName( 0, "t" ); + tab->setColName( 1, "f(t)" ); + tab->setValidator( 0, 0.0, 1.0, 3 ); + tab->setValidator( 1, 1E-7, 1E+300, 3 ); + tab->setEditRows( true ); + + //3-th parameter in list + paramList.push_back ( SMESHGUI_aParameterPtr( tab ) ); + + //4-th parameter in list + paramList.push_back ( STR_PARAM ( "", QObject::tr( "SMESH_EXPR_FUNC" ) ) ); + + //5-th parameter in list + paramList.push_back ( BOOL_PARAM ( false, QObject::tr( "SMESH_EXP_MODE" ) ) ); } else if (hypType.compare("Arithmetic1D") == 0) { @@ -187,8 +269,34 @@ void StdMeshersGUI_Parameters::GetParameters (SMESH::SMESH_Hypothesis_ptr the { StdMeshers::StdMeshers_NumberOfSegments_var NOS = StdMeshers::StdMeshers_NumberOfSegments::_narrow(theHyp); - SetInitValue( paramList.front(), (int) NOS->GetNumberOfSegments()); - SetInitValue( paramList.back(), NOS->GetScaleFactor()); + + list::iterator anIt = paramList.begin(); + SetInitValue( *anIt, (int) NOS->GetNumberOfSegments()); anIt++; + int DType = (int) NOS->GetDistrType(); + SetInitValue( *anIt, DType ); anIt++; + + if( DType==1 ) + SetInitValue( *anIt, NOS->GetScaleFactor()); + anIt++; + + if( DType==2 ) + { + SMESH::double_array* tab_func = NOS->GetTableFunction(); + SetInitValue( *anIt, *tab_func ); + delete tab_func; + } + anIt++; + + if( DType==3 ) + { + char* expr_func = NOS->GetExpressionFunction(); + SetInitValue( *anIt, expr_func ); + delete expr_func; + } + anIt++; + + if( DType==2 || DType==3 ) + SetInitValue( *anIt, (bool)NOS->IsExponentMode()); } else if (hypType.compare("Arithmetic1D") == 0) { @@ -237,17 +345,25 @@ void StdMeshersGUI_Parameters::GetParameters (SMESH::SMESH_Hypothesis_ptr for ( ; paramIt != paramList.end(); paramIt++) { if (params.compare("")) params += " ; "; - if ((*paramIt)->GetType() == SMESHGUI_aParameter::DOUBLE ) { + SMESHGUI_aParameter::Type t = (*paramIt)->GetType(); + if( t==SMESHGUI_aParameter::DOUBLE ) + { double aDoubleValue = 0.; (*paramIt)->GetNewDouble(aDoubleValue); params += QString::number(aDoubleValue); } - else if ((*paramIt)->GetType() == SMESHGUI_aParameter::TEXT ) { + else if( t==SMESHGUI_aParameter::STRING || t==SMESHGUI_aParameter::ENUM ) + { QString aStrValue( "" ); (*paramIt)->GetNewText(aStrValue); params += aStrValue.simplifyWhiteSpace(); } - else { + else if( t==SMESHGUI_aParameter::TABLE ) + { + params += "TABLE"; + } + else + { int aIntValue = 0; (*paramIt)->GetNewInt(aIntValue); params += QString::number(aIntValue); @@ -281,12 +397,32 @@ bool StdMeshersGUI_Parameters::SetParameters(SMESH::SMESH_Hypothesis_ptr { StdMeshers::StdMeshers_NumberOfSegments_var NOS = StdMeshers::StdMeshers_NumberOfSegments::_narrow(theHyp); - int NbSeg = NOS->GetNumberOfSegments(); - double Scale = NOS->GetScaleFactor() ; - modified = paramList.front()->GetNewInt( NbSeg ); - modified = paramList.back()->GetNewDouble( Scale ) || modified; - NOS->SetNumberOfSegments(NbSeg); - NOS->SetScaleFactor( Scale ); + + list::const_iterator anIt = paramList.begin(); + int NbSeg, DType; + double Scale; + SMESH::double_array TabF; + QString exprF; + int expType; + + modified = (*anIt)->GetNewInt( NbSeg ); anIt++; + modified = (*anIt)->GetNewInt( DType ) || modified; anIt++; + modified = (*anIt)->GetNewDouble( Scale ) || modified; anIt++; + SMESHGUI_aParameterPtr p = *anIt; + ((SMESHGUI_tableParameter*)p.get())->data( TabF ); anIt++; modified = true; + modified = (*anIt)->GetNewText( exprF ) || modified; anIt++; + modified = (*anIt)->GetNewInt( expType ) || modified; + + NOS->SetNumberOfSegments( NbSeg ); + NOS->SetDistrType( DType ); + if( DType==1 ) + NOS->SetScaleFactor( Scale ); + if( DType==2 ) + NOS->SetTableFunction( TabF ); + if( DType==3 ) + NOS->SetExpressionFunction( CORBA::string_dup( exprF.latin1() ) ); + if( DType==2 || DType==3 ) + NOS->SetExponentMode( (bool)expType ); } else if (hypType.compare("Arithmetic1D") == 0) { diff --git a/src/StdMeshersGUI/StdMeshersGUI_Parameters.h b/src/StdMeshersGUI/StdMeshersGUI_Parameters.h index 24fa2f70c..40be46f46 100644 --- a/src/StdMeshersGUI/StdMeshersGUI_Parameters.h +++ b/src/StdMeshersGUI/StdMeshersGUI_Parameters.h @@ -29,10 +29,12 @@ #include #include CORBA_SERVER_HEADER(SMESH_BasicHypothesis) +#include CORBA_SERVER_HEADER(SMESH_Mesh) #include "SMESHGUI_aParameter.h" #include +#include class StdMeshersGUI_Parameters { @@ -57,5 +59,7 @@ class StdMeshersGUI_Parameters double initValue); static void SetInitValue(SMESHGUI_aParameterPtr param, const char* initValue); + static void SetInitValue(SMESHGUI_aParameterPtr param, + SMESH::double_array& initValue); }; #endif diff --git a/src/StdMeshersGUI/StdMeshers_msg_en.po b/src/StdMeshersGUI/StdMeshers_msg_en.po index eef692b3b..177b70189 100644 --- a/src/StdMeshersGUI/StdMeshers_msg_en.po +++ b/src/StdMeshersGUI/StdMeshers_msg_en.po @@ -29,9 +29,33 @@ msgstr "Number of Segments" msgid "SMESH_NB_SEGMENTS_PARAM" msgstr "Number of Segments" +msgid "SMESH_DISTR_TYPE" +msgstr "Type of distribution" + +msgid "SMESH_DISTR_REGULAR" +msgstr "Equidistant distribution" + +msgid "SMESH_DISTR_SCALE" +msgstr "Scale distribution" + +msgid "SMESH_DISTR_TAB" +msgstr "Distribution with table density" + +msgid "SMESH_DISTR_EXPR" +msgstr "Distribution with analitic density" + msgid "SMESH_NB_SEGMENTS_SCALE_PARAM" msgstr "Scale Factor" +msgid "SMESH_TAB_FUNC" +msgstr "Table function" + +msgid "SMESH_EXPR_FUNC" +msgstr "Density function f(t) = " + +msgid "SMESH_EXP_MODE" +msgstr "Exponent mode " + msgid "SMESH_NB_SEGMENTS_TITLE" msgstr "Hypothesis Construction" diff --git a/src/StdMeshers_I/StdMeshers_NumberOfSegments_i.cxx b/src/StdMeshers_I/StdMeshers_NumberOfSegments_i.cxx index 356d19ad3..b4355a2ec 100644 --- a/src/StdMeshers_I/StdMeshers_NumberOfSegments_i.cxx +++ b/src/StdMeshers_I/StdMeshers_NumberOfSegments_i.cxx @@ -114,6 +114,37 @@ CORBA::Long StdMeshers_NumberOfSegments_i::GetNumberOfSegments() return this->GetImpl()->GetNumberOfSegments(); } +//============================================================================= +/*! + */ +//============================================================================= + +void StdMeshers_NumberOfSegments_i::SetDistrType(CORBA::Long typ) + throw ( SALOME::SALOME_Exception ) +{ + MESSAGE( "StdMeshers_NumberOfSegments_i::SetDistrType" ); + ASSERT( myBaseImpl ); + try { + this->GetImpl()->SetDistrType( (::StdMeshers_NumberOfSegments::DistrType) typ ); + } + catch ( SALOME_Exception& S_ex ) { + THROW_SALOME_CORBA_EXCEPTION( S_ex.what(), + SALOME::BAD_PARAM ); + } +} + +//============================================================================= +/*! + */ +//============================================================================= + +CORBA::Long StdMeshers_NumberOfSegments_i::GetDistrType() +{ + MESSAGE( "StdMeshers_NumberOfSegments_i::GetDistrType" ); + ASSERT( myBaseImpl ); + return this->GetImpl()->GetDistrType(); +} + //============================================================================= /*! * StdMeshers_NumberOfSegments_i::SetScaleFactor @@ -145,10 +176,146 @@ void StdMeshers_NumberOfSegments_i::SetScaleFactor( CORBA::Double theScaleFactor //============================================================================= CORBA::Double StdMeshers_NumberOfSegments_i::GetScaleFactor() + throw ( SALOME::SALOME_Exception ) { MESSAGE( "StdMeshers_NumberOfSegments_i::GetScaleFactor" ); ASSERT( myBaseImpl ); - return this->GetImpl()->GetScaleFactor(); + double scale; + try { + scale = this->GetImpl()->GetScaleFactor(); + } + catch ( SALOME_Exception& S_ex ) { + THROW_SALOME_CORBA_EXCEPTION( S_ex.what(), + SALOME::BAD_PARAM ); + } + return scale; +} + +//============================================================================= +/*! + */ +//============================================================================= + +void StdMeshers_NumberOfSegments_i::SetTableFunction(const SMESH::double_array& table) + throw ( SALOME::SALOME_Exception ) +{ + MESSAGE( "StdMeshers_NumberOfSegments_i::SetTableFunction" ); + ASSERT( myBaseImpl ); + std::vector tbl( table.length() ); + for (int i = 0; i < table.length(); i++) + tbl[i] = table[i]; + try { + this->GetImpl()->SetTableFunction( tbl ); + } + catch ( SALOME_Exception& S_ex ) { + THROW_SALOME_CORBA_EXCEPTION( S_ex.what(), + SALOME::BAD_PARAM ); + } +} + +//============================================================================= +/*! + */ +//============================================================================= + +SMESH::double_array* StdMeshers_NumberOfSegments_i::GetTableFunction() + throw ( SALOME::SALOME_Exception ) +{ + MESSAGE( "StdMeshers_NumberOfSegments_i::GetTableFunction" ); + ASSERT( myBaseImpl ); + const std::vector* tbl; + try { + tbl = &this->GetImpl()->GetTableFunction(); + } + catch ( SALOME_Exception& S_ex ) { + THROW_SALOME_CORBA_EXCEPTION( S_ex.what(), + SALOME::BAD_PARAM ); + } + SMESH::double_array_var aRes = new SMESH::double_array(); + aRes->length(tbl->size()); + for (int i = 0; i < tbl->size(); i++) + aRes[i] = (*tbl)[i]; + return aRes._retn(); +} + +//============================================================================= +/*! + */ +//============================================================================= + +void StdMeshers_NumberOfSegments_i::SetExpressionFunction(const char* expr) + throw ( SALOME::SALOME_Exception ) +{ + MESSAGE( "StdMeshers_NumberOfSegments_i::SetExpressionFunction" ); + ASSERT( myBaseImpl ); + try { + this->GetImpl()->SetExpressionFunction( expr ); + } + catch ( SALOME_Exception& S_ex ) { + THROW_SALOME_CORBA_EXCEPTION( S_ex.what(), + SALOME::BAD_PARAM ); + } +} + +//============================================================================= +/*! + */ +//============================================================================= + +char* StdMeshers_NumberOfSegments_i::GetExpressionFunction() + throw ( SALOME::SALOME_Exception ) +{ + MESSAGE( "StdMeshers_NumberOfSegments_i::GetExpressionFunction" ); + ASSERT( myBaseImpl ); + const char* expr; + try { + expr = this->GetImpl()->GetExpressionFunction(); + } + catch ( SALOME_Exception& S_ex ) { + THROW_SALOME_CORBA_EXCEPTION( S_ex.what(), + SALOME::BAD_PARAM ); + } + return CORBA::string_dup(expr); +} + +//============================================================================= +/*! + */ +//============================================================================= + +void StdMeshers_NumberOfSegments_i::SetExponentMode(CORBA::Boolean isExp) + throw ( SALOME::SALOME_Exception ) +{ + MESSAGE( "StdMeshers_NumberOfSegments_i::SetExponentMode" ); + ASSERT( myBaseImpl ); + try { + this->GetImpl()->SetExponentMode( isExp ); + } + catch ( SALOME_Exception& S_ex ) { + THROW_SALOME_CORBA_EXCEPTION( S_ex.what(), + SALOME::BAD_PARAM ); + } +} + +//============================================================================= +/*! + */ +//============================================================================= + +CORBA::Boolean StdMeshers_NumberOfSegments_i::IsExponentMode() + throw ( SALOME::SALOME_Exception ) +{ + MESSAGE( "StdMeshers_NumberOfSegments_i::IsExponentMode" ); + ASSERT( myBaseImpl ); + bool isExp; + try { + isExp = this->GetImpl()->IsExponentMode(); + } + catch ( SALOME_Exception& S_ex ) { + THROW_SALOME_CORBA_EXCEPTION( S_ex.what(), + SALOME::BAD_PARAM ); + } + return isExp; } //============================================================================= diff --git a/src/StdMeshers_I/StdMeshers_NumberOfSegments_i.hxx b/src/StdMeshers_I/StdMeshers_NumberOfSegments_i.hxx index e8a5030b1..22e19d75f 100644 --- a/src/StdMeshers_I/StdMeshers_NumberOfSegments_i.hxx +++ b/src/StdMeshers_I/StdMeshers_NumberOfSegments_i.hxx @@ -31,6 +31,7 @@ #define _SMESH_NUMBEROFSEGMENTS_I_HXX_ #include +#include CORBA_SERVER_HEADER(SMESH_Mesh) #include CORBA_SERVER_HEADER(SMESH_BasicHypothesis) #include "SMESH_Hypothesis_i.hxx" @@ -57,11 +58,39 @@ public: // Get number of segments CORBA::Long GetNumberOfSegments(); + // Set distribution type + void SetDistrType(CORBA::Long typ) + throw ( SALOME::SALOME_Exception ); + // Get distribution type + CORBA::Long GetDistrType(); + // Set scalar factor void SetScaleFactor( CORBA::Double theScaleFactor ) throw ( SALOME::SALOME_Exception ); // Get scalar factor - CORBA::Double GetScaleFactor(); + CORBA::Double GetScaleFactor() + throw ( SALOME::SALOME_Exception ); + + // Set table function for distribution DT_TabFunc + void SetTableFunction(const SMESH::double_array& table) + throw ( SALOME::SALOME_Exception ); + // Get table function for distribution DT_TabFunc + SMESH::double_array* GetTableFunction() + throw ( SALOME::SALOME_Exception ); + + // Set expression function for distribution DT_ExprFunc + void SetExpressionFunction(const char* expr) + throw ( SALOME::SALOME_Exception ); + // Get expression function for distribution DT_ExprFunc + char* GetExpressionFunction() + throw ( SALOME::SALOME_Exception ); + + // Set the exponent mode on/off + void SetExponentMode(CORBA::Boolean isExp) + throw ( SALOME::SALOME_Exception ); + // Returns true if the exponent mode is set + CORBA::Boolean IsExponentMode() + throw ( SALOME::SALOME_Exception ); // Get implementation ::StdMeshers_NumberOfSegments* GetImpl(); -- 2.39.2