1 // SMESH SMESH : implementaion of SMESH idl descriptions
3 // Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
6 // This library is free software; you can redistribute it and/or
7 // modify it under the terms of the GNU Lesser General Public
8 // License as published by the Free Software Foundation; either
9 // version 2.1 of the License.
11 // This library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 // Lesser General Public License for more details.
16 // You should have received a copy of the GNU Lesser General Public
17 // License along with this library; if not, write to the Free Software
18 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 // See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org
24 // File : StdMeshers_NumberOfSegments.cxx
25 // Moved here from SMESH_NumberOfSegments.cxx
26 // Author : Paul RASCLE, EDF
31 #include "StdMeshers_NumberOfSegments.hxx"
32 #include <Standard_ErrorHandler.hxx>
33 #include <TCollection_AsciiString.hxx>
34 #include <ExprIntrp_GenExp.hxx>
35 #include <Expr_NamedUnknown.hxx>
37 const double PRECISION = 1e-7;
39 //=============================================================================
43 //=============================================================================
45 StdMeshers_NumberOfSegments::StdMeshers_NumberOfSegments(int hypId, int studyId,
47 : SMESH_Hypothesis(hypId, studyId, gen),
49 _distrType(DT_Regular),
53 _name = "NumberOfSegments";
57 //=============================================================================
61 //=============================================================================
63 StdMeshers_NumberOfSegments::~StdMeshers_NumberOfSegments()
67 //=============================================================================
71 //=============================================================================
73 void StdMeshers_NumberOfSegments::SetNumberOfSegments(int segmentsNumber)
74 throw(SALOME_Exception)
76 int oldNumberOfSegments = _numberOfSegments;
77 if (segmentsNumber <= 0)
79 SALOME_Exception(LOCALIZED("number of segments must be positive"));
80 _numberOfSegments = segmentsNumber;
82 if (oldNumberOfSegments != _numberOfSegments)
83 NotifySubMeshesHypothesisModification();
86 //=============================================================================
90 //=============================================================================
92 int StdMeshers_NumberOfSegments::GetNumberOfSegments() const
94 return _numberOfSegments;
97 //================================================================================
101 //================================================================================
103 void StdMeshers_NumberOfSegments::SetDistrType(DistrType typ)
104 throw(SALOME_Exception)
106 if (typ < DT_Regular || typ > DT_ExprFunc)
107 throw SALOME_Exception(LOCALIZED("distribution type is out of range"));
109 if (typ != _distrType)
112 NotifySubMeshesHypothesisModification();
116 //================================================================================
120 //================================================================================
122 StdMeshers_NumberOfSegments::DistrType StdMeshers_NumberOfSegments::GetDistrType() const
127 //================================================================================
131 //================================================================================
133 void StdMeshers_NumberOfSegments::SetScaleFactor(double scaleFactor)
134 throw(SALOME_Exception)
136 if (_distrType != DT_Scale)
137 throw SALOME_Exception(LOCALIZED("not a scale distribution"));
138 if (scaleFactor < PRECISION)
139 throw SALOME_Exception(LOCALIZED("scale factor must be positive"));
140 if (fabs(scaleFactor - 1.0) < PRECISION)
141 throw SALOME_Exception(LOCALIZED("scale factor must not be equal to 1"));
143 if (fabs(_scaleFactor - scaleFactor) > PRECISION)
145 _scaleFactor = scaleFactor;
146 NotifySubMeshesHypothesisModification();
150 //================================================================================
154 //================================================================================
156 double StdMeshers_NumberOfSegments::GetScaleFactor() const
157 throw(SALOME_Exception)
159 if (_distrType != DT_Scale)
160 throw SALOME_Exception(LOCALIZED("not a scale distribution"));
164 //================================================================================
168 //================================================================================
170 void StdMeshers_NumberOfSegments::SetTableFunction(const std::vector<double>& table)
171 throw(SALOME_Exception)
173 if (_distrType != DT_TabFunc)
174 throw SALOME_Exception(LOCALIZED("not a table function distribution"));
175 if ( (table.size() % 2) != 0 )
176 throw SALOME_Exception(LOCALIZED("odd size of vector of table function"));
179 double prev = -PRECISION;
180 bool isSame = table.size() == _table.size();
182 for (i=0; i < table.size()/2; i++) {
183 double par = table[i*2];
184 double val = table[i*2+1];
185 if ( par<0 || par > 1)
186 throw SALOME_Exception(LOCALIZED("parameter of table function is out of range [0,1]"));
187 if ( fabs(par-prev)<PRECISION )
188 throw SALOME_Exception(LOCALIZED("two parameters are the same"));
190 throw SALOME_Exception(LOCALIZED("value of table function is not positive"));
193 double oldpar = _table[i*2];
194 double oldval = _table[i*2+1];
195 if (fabs(par - oldpar) > PRECISION || fabs(val - oldval) > PRECISION)
204 NotifySubMeshesHypothesisModification();
208 //================================================================================
212 //================================================================================
214 const std::vector<double>& StdMeshers_NumberOfSegments::GetTableFunction() const
215 throw(SALOME_Exception)
217 if (_distrType != DT_TabFunc)
218 throw SALOME_Exception(LOCALIZED("not a table function distribution"));
222 //================================================================================
223 /*! check if only 't' is unknown variable in expression
225 //================================================================================
226 bool isCorrect( const Handle( Expr_GeneralExpression )& expr )
232 for( int i=1, n=expr->NbSubExpressions(); i<=n && res; i++ )
234 Handle( Expr_GeneralExpression ) subexpr = expr->SubExpression( i );
235 Handle( Expr_NamedUnknown ) name = Handle( Expr_NamedUnknown )::DownCast( subexpr );
238 if( name->GetName()!="t" )
242 res = isCorrect( subexpr );
247 //================================================================================
248 /*! this function parses the expression 'str' in order to check if syntax is correct
249 * ( result in 'syntax' ) and if only 't' is unknown variable in expression ( result in 'args' )
251 //================================================================================
252 void casProcess( const TCollection_AsciiString& str, bool& syntax, bool& args )
254 // check validity of expression
259 Handle( ExprIntrp_GenExp ) gen = ExprIntrp_GenExp::Create();
265 args = isCorrect( gen->Expression() );
268 catch (Standard_Failure)
273 //================================================================================
277 //================================================================================
279 void StdMeshers_NumberOfSegments::SetExpressionFunction(const char* expr)
280 throw(SALOME_Exception)
282 if (_distrType != DT_ExprFunc)
283 throw SALOME_Exception(LOCALIZED("not an expression function distribution"));
285 // remove white spaces
286 TCollection_AsciiString str((Standard_CString)expr);
293 casProcess( str, syntax, args );
295 throw SALOME_Exception(LOCALIZED("invalid expression syntax"));
297 throw SALOME_Exception(LOCALIZED("only 't' may be used as function argument"));
299 string func(str.ToCString());
303 NotifySubMeshesHypothesisModification();
307 //================================================================================
311 //================================================================================
313 const char* StdMeshers_NumberOfSegments::GetExpressionFunction() const
314 throw(SALOME_Exception)
316 if (_distrType != DT_ExprFunc)
317 throw SALOME_Exception(LOCALIZED("not an expression function distribution"));
318 return _func.c_str();
321 //================================================================================
325 //================================================================================
327 void StdMeshers_NumberOfSegments::SetExponentMode(bool isExp)
328 throw(SALOME_Exception)
330 if (_distrType != DT_TabFunc && _distrType != DT_ExprFunc)
331 throw SALOME_Exception(LOCALIZED("not a functional distribution"));
333 if (isExp != _expMode)
336 NotifySubMeshesHypothesisModification();
340 //================================================================================
344 //================================================================================
346 bool StdMeshers_NumberOfSegments::IsExponentMode() const
347 throw(SALOME_Exception)
349 if (_distrType != DT_TabFunc && _distrType != DT_ExprFunc)
350 throw SALOME_Exception(LOCALIZED("not a functional distribution"));
354 //=============================================================================
358 //=============================================================================
360 ostream & StdMeshers_NumberOfSegments::SaveTo(ostream & save)
362 save << _numberOfSegments << " " << (int)_distrType;
366 save << " " << _scaleFactor;
370 save << " " << _table.size();
371 for (i=0; i < _table.size(); i++)
372 save << " " << _table[i];
375 save << " " << _func;
382 if (_distrType == DT_TabFunc || _distrType == DT_ExprFunc)
383 save << " " << (int)_expMode;
388 //=============================================================================
392 //=============================================================================
394 istream & StdMeshers_NumberOfSegments::LoadFrom(istream & load)
399 // read number of segments
402 _numberOfSegments = a;
404 load.clear(ios::badbit | load.rdstate());
406 // read ditribution type
410 if (a < DT_Regular || a > DT_ExprFunc)
411 _distrType = DT_Regular;
413 _distrType = (DistrType) a;
416 load.clear(ios::badbit | load.rdstate());
418 // parameters of distribution
428 load.clear(ios::badbit | load.rdstate());
435 _table.resize(a, 0.);
437 load.clear(ios::badbit | load.rdstate());
439 for (i=0; i < _table.size(); i++)
445 load.clear(ios::badbit | load.rdstate());
452 isOK = (load >> str);
456 load.clear(ios::badbit | load.rdstate());
464 if (_distrType == DT_TabFunc || _distrType == DT_ExprFunc)
470 load.clear(ios::badbit | load.rdstate());
476 //=============================================================================
480 //=============================================================================
482 ostream & operator <<(ostream & save, StdMeshers_NumberOfSegments & hyp)
484 return hyp.SaveTo( save );
487 //=============================================================================
491 //=============================================================================
493 istream & operator >>(istream & load, StdMeshers_NumberOfSegments & hyp)
495 return hyp.LoadFrom( load );