SMESHGUI_SpinBox.h \
SMESHGUI_aParameter.h \
SMESHGUI_aParameterDlg.h \
- SMESHGUI_Selection.h
+ SMESHGUI_Selection.h \
+ SMESHGUI_FunctionPreview.h
# .po files to transform in .qm
PO_FILES = \
SMESHGUI_Dialog.cxx \
SMESHGUI_MeshDlg.cxx \
SMESHGUI_MeshOp.cxx \
- SMESHGUI_Displayer.cxx
+ SMESHGUI_Displayer.cxx \
+ SMESHGUI_FunctionPreview.cxx
LIB_MOC = \
SMESHGUI.h \
SMESHGUI_SelectionOp.h \
SMESHGUI_Dialog.h \
SMESHGUI_MeshDlg.h \
- SMESHGUI_MeshOp.h
+ SMESHGUI_MeshOp.h \
+ SMESHGUI_FunctionPreview.h
LIB_CLIENT_IDL = SALOME_Exception.idl \
CPPFLAGS += $(QT_INCLUDES) $(VTK_INCLUDES) $(OGL_INCLUDES) $(OCC_INCLUDES) $(PYTHON_INCLUDES) \
-I${KERNEL_ROOT_DIR}/include/salome -I${GUI_ROOT_DIR}/include/salome \
- -I${GEOM_ROOT_DIR}/include/salome $(BOOST_CPPFLAGS)
+ -I${GEOM_ROOT_DIR}/include/salome $(BOOST_CPPFLAGS) -I${QWTHOME}/include
CXXFLAGS += -I${KERNEL_ROOT_DIR}/include/salome -I${GUI_ROOT_DIR}/include/salome \
- -I${GEOM_ROOT_DIR}/include/salome
+ -I${GEOM_ROOT_DIR}/include/salome -I${QWTHOME}/include
-LDFLAGS += -lSMESHObject -lSMESHFiltersSelection -lSMDS -lSMESHControls -lDlgRef $(OCC_KERNEL_LIBS) -lTKBO -L${KERNEL_ROOT_DIR}/lib/salome -L${GUI_ROOT_DIR}/lib/salome -lVTKViewer -lSalomeApp -lSalomePrs -lSalomeNS -lSalomeLifeCycleCORBA -lOpUtil -lSalomeObject -lEvent -lSALOMELocalTrace -lSVTK -lOCCViewer -L${GEOM_ROOT_DIR}/lib/salome -lGEOM -lGEOMClient -lGEOMBase -lGEOMObject -lGEOMFiltersSelection
+LDFLAGS += -lSMESHObject -lSMESHFiltersSelection -lSMDS -lSMESHControls -lDlgRef \
+ $(OCC_KERNEL_LIBS) -lTKBO -lTKAdvTools -L${KERNEL_ROOT_DIR}/lib/salome -L${GUI_ROOT_DIR}/lib/salome \
+ -lVTKViewer -lSalomeApp -lSalomePrs -lSalomeNS -lSalomeLifeCycleCORBA -lOpUtil -lSalomeObject \
+ -lEvent -lSALOMELocalTrace -lSVTK -lOCCViewer -L${GEOM_ROOT_DIR}/lib/salome -lGEOM -lGEOMClient \
+ -lGEOMBase -lGEOMObject -lGEOMFiltersSelection
LDFLAGSFORBIN += $(LDFLAGS)
--- /dev/null
+
+#include "SMESHGUI_FunctionPreview.h"
+#include <Expr_NamedUnknown.hxx>
+#include <Expr_GeneralExpression.hxx>
+#include <CASCatch_CatchSignals.hxx>
+#include <CASCatch_Failure.hxx>
+#include <CASCatch_ErrorHandler.hxx>
+#include <OSD.hxx>
+
+SMESHGUI_FunctionPreview::SMESHGUI_FunctionPreview( QWidget* p )
+: QwtPlot( p ),
+ myXmin( 0.0 ),
+ myXmax( 1.0 ),
+ myPoints( 50 ),
+ myIsTable( false ),
+ myVars( 1, 1 ),
+ myValues( 1, 1 ),
+ myIsExp( false ),
+ myIsDone( true )
+{
+ myVars.ChangeValue( 1 ) = new Expr_NamedUnknown( "t" );
+ myCurve = insertCurve( QString() );
+ setCurvePen( myCurve, QPen( Qt::red, 1 ) );
+}
+
+SMESHGUI_FunctionPreview::~SMESHGUI_FunctionPreview()
+{
+}
+
+bool SMESHGUI_FunctionPreview::isTableFunc() const
+{
+ return myIsTable;
+}
+
+void SMESHGUI_FunctionPreview::tableFunc( SMESH::double_array& f ) const
+{
+ f = myTableFunc;
+}
+
+QString SMESHGUI_FunctionPreview::function() const
+{
+ return myFunction;
+}
+
+void SMESHGUI_FunctionPreview::interval( double& xmin, double& xmax ) const
+{
+ xmin = myXmin;
+ xmax = myXmax;
+}
+
+int SMESHGUI_FunctionPreview::pointsCount() const
+{
+ return myPoints;
+}
+
+void SMESHGUI_FunctionPreview::setIsExp( const bool exp, const bool update )
+{
+ myIsExp = exp;
+ if( update )
+ repaint();
+}
+
+bool SMESHGUI_FunctionPreview::setParams( const QString& func,
+ const double xmin, const double xmax,
+ const int points, const bool update )
+{
+ myIsTable = false;
+ myTableFunc = SMESH::double_array();
+ myFunction = func.isEmpty() ? "0" : func;
+ myXmin = xmin;
+ myXmax = xmax<myXmin ? myXmax : xmax;
+ myPoints = points>0 ? points : 2;
+ bool res = init( func );
+ if( update )
+ repaint();
+ return res;
+}
+
+bool SMESHGUI_FunctionPreview::setParams( const SMESH::double_array& f, const double xmin, const double xmax,
+ const bool update )
+{
+ myIsTable = true;
+ myTableFunc = f;
+ if( myTableFunc.length()%2==1 )
+ myTableFunc.length( myTableFunc.length()-1 );
+
+ myFunction = "0";
+ myXmin = xmin;
+ myXmax = xmax<myXmin ? myXmax : xmax;
+ myPoints = myTableFunc.length()/2;
+
+ if( update )
+ repaint();
+
+ return myTableFunc.length()>0;
+}
+
+bool SMESHGUI_FunctionPreview::createTable( SMESH::double_array& func )
+{
+ if( myExpr.IsNull() )
+ {
+ func.length( 0 );
+ return false;
+ }
+
+ double d = (myXmax-myXmin)/double(myPoints-1);
+ func.length( 2*myPoints );
+ int err = 0;
+ for( int i=0, j=0; i<myPoints; j++ )
+ {
+ bool ok;
+ double t = myXmin + d*j, f = funcValue( t, ok );
+ if( ok )
+ {
+ func[2*i] = t;
+ func[2*i+1] = f;
+ i++;
+ }
+ else
+ err++;
+ }
+ func.length( func.length()-2*err );
+ return err==0;
+}
+
+void SMESHGUI_FunctionPreview::drawContents( QPainter* p )
+{
+ SMESH::double_array f;
+ if( isTableFunc() )
+ {
+ myIsDone = true;
+ f = myTableFunc;
+ }
+ else
+ myIsDone = createTable( f );
+
+ int size = f.length()/2;
+ if( size==0 )
+ {
+ setAxisScale( curveXAxis( myCurve ), 0.0, 0.0 );
+ setAxisScale( curveYAxis( myCurve ), 0.0, 0.0 );
+ setCurveData( myCurve, 0, 0, 0 );
+ replot();
+ QwtPlot::drawContents( p );
+ return;
+ }
+
+ double* x = new double[size], *y = new double[size];
+ double min_x, max_x, min_y, max_y;
+ for( int i=0; i<size; i++ )
+ {
+ x[i] = f[2*i];
+ y[i] = myIsExp ? pow( 10.0, f[2*i+1] ) : f[2*i+1];
+ if( i==0 || y[i]<min_y )
+ min_y = y[i];
+ if( i==0 || y[i]>max_y )
+ max_y = y[i];
+ if( i==0 || x[i]<min_x )
+ min_x = x[i];
+ if( i==0 || x[i]>max_x )
+ max_x = x[i];
+ }
+
+ setAxisScale( curveXAxis( myCurve ), min_x, max_x );
+ setAxisScale( curveYAxis( myCurve ), min_y, max_y );
+ setCurveData( myCurve, x, y, size );
+ delete[] x;
+ delete[] y;
+
+ replot();
+ QwtPlot::drawContents( p );
+}
+
+bool isCorrectArg( const Handle( Expr_GeneralExpression )& expr )
+{
+ Handle( Expr_NamedUnknown ) sub = Handle( Expr_NamedUnknown )::DownCast( expr );
+ if( !sub.IsNull() )
+ return sub->GetName()=="t";
+
+ bool res = true;
+ for( int i=1, n=expr->NbSubExpressions(); i<=n && res; i++ )
+ {
+ Handle( Expr_GeneralExpression ) sub = expr->SubExpression( i );
+ Handle( Expr_NamedUnknown ) name = Handle( Expr_NamedUnknown )::DownCast( sub );
+ if( !name.IsNull() )
+ {
+ if( name->GetName()!="t" )
+ res = false;
+ }
+ else
+ res = isCorrectArg( sub );
+ }
+ return res;
+}
+
+bool SMESHGUI_FunctionPreview::init( const QString& str )
+{
+ myExpr = ExprIntrp_GenExp::Create();
+ myExpr->Process( ( Standard_CString ) str.latin1() );
+
+ bool syntax = false, args = false;
+ if( myExpr->IsDone() )
+ {
+ syntax = true;
+ args = isCorrectArg( myExpr->Expression() );
+ }
+
+ bool res = syntax && args;
+ if( !res )
+ myExpr.Nullify();
+ return res;
+}
+
+double SMESHGUI_FunctionPreview::funcValue( const double t, bool& ok )
+{
+ if( myExpr.IsNull() )
+ return 0;
+
+ myValues.ChangeValue( 1 ) = t;
+
+ ok = true;
+ double res = calc( ok );
+
+ return res;
+}
+
+double SMESHGUI_FunctionPreview::calc( bool& ok )
+{
+ OSD::SetSignal( true );
+ double res = 0.0;
+
+ CASCatch_CatchSignals aCatchSignals;
+ aCatchSignals.Activate();
+
+ ok = true;
+ CASCatch_TRY {
+ res = myExpr->Expression()->Evaluate( myVars, myValues );
+ }
+ CASCatch_CATCH(CASCatch_Failure) {
+ aCatchSignals.Deactivate();
+ Handle(CASCatch_Failure) aFail = CASCatch_Failure::Caught();
+ ok = false;
+ res = 0.0;
+ }
+ aCatchSignals.Deactivate();
+ return res;
+}
+
+bool SMESHGUI_FunctionPreview::isDone() const
+{
+ return myIsDone;
+}
--- /dev/null
+
+#ifndef SMESHGUI_FUNCTION_PREVIEW_HEADER
+#define SMESHGUI_FUNCTION_PREVIEW_HEADER
+
+#include "qwt_plot.h"
+#include <SALOMEconfig.h>
+#include CORBA_SERVER_HEADER(SMESH_Mesh)
+#include <ExprIntrp_GenExp.hxx>
+#include <Expr_Array1OfNamedUnknown.hxx>
+#include <TColStd_Array1OfReal.hxx>
+
+class SMESHGUI_FunctionPreview : public QwtPlot
+{
+ Q_OBJECT
+
+public:
+ SMESHGUI_FunctionPreview( QWidget* );
+ virtual ~SMESHGUI_FunctionPreview();
+
+ QString function() const;
+ bool isTableFunc() const;
+ void tableFunc( SMESH::double_array& ) const;
+ void interval( double&, double& ) const;
+ int pointsCount() const;
+ bool isDone() const;
+
+ bool setParams( const QString&, const double = 0.0, const double = 1.0, const int = 50, const bool = true );
+ bool setParams( const SMESH::double_array&, const double = 0.0, const double = 1.0, const bool = true );
+ void setIsExp( const bool, const bool = true );
+
+protected:
+ virtual bool init( const QString& );
+ virtual double funcValue( const double, bool& );
+ virtual bool createTable( SMESH::double_array& );
+ virtual void drawContents( QPainter* );
+
+private:
+ double calc( bool& );
+
+private:
+ QString myFunction;
+ double myXmin, myXmax;
+ int myPoints;
+ bool myIsTable;
+ bool myIsExp;
+ SMESH::double_array myTableFunc;
+ long myCurve;
+ Handle(ExprIntrp_GenExp) myExpr;
+ Expr_Array1OfNamedUnknown myVars;
+ TColStd_Array1OfReal myValues;
+ bool myIsDone;
+};
+
+#endif
#include <QtxDblSpinBox.h>
-SMESHGUI_aParameter::~SMESHGUI_aParameter() {}
+SMESHGUI_aParameter::SMESHGUI_aParameter( const QString& label, const bool preview )
+: _needPreview( preview ),
+ _label(label)
+{
+}
+
+SMESHGUI_aParameter::~SMESHGUI_aParameter()
+{
+}
+
+bool SMESHGUI_aParameter::needPreview() const
+{
+ return _needPreview;
+}
+
+QString& SMESHGUI_aParameter::Label()
+{
+ return _label;
+}
QString SMESHGUI_aParameter::sigValueChanged() const
{
SMESHGUI_intParameter::SMESHGUI_intParameter (const int theInitValue,
const QString& theLabel,
const int theBottom,
- const int theTop)
- :SMESHGUI_aParameter(theLabel),
+ const int theTop,
+ const bool preview )
+ :SMESHGUI_aParameter(theLabel, preview),
_top(theTop), _bottom(theBottom), _initValue(theInitValue),
_newValue( theInitValue )
{
const double theBottom,
const double theTop,
const double theStep,
- const int theDecimals)
- :SMESHGUI_aParameter(theLabel),
+ const int theDecimals,
+ const bool preview )
+ :SMESHGUI_aParameter(theLabel, preview),
_top(theTop), _bottom(theBottom), _step(theStep),
_initValue(theInitValue), _decimals(theDecimals)
{
// purpose :
//=================================================================================
SMESHGUI_strParameter::SMESHGUI_strParameter (const QString& theInitValue,
- const QString& theLabel)
- :SMESHGUI_aParameter(theLabel),
+ const QString& theLabel,
+ const bool preview )
+ :SMESHGUI_aParameter(theLabel, preview),
_initValue(theInitValue)
{
}
{
return SMESHGUI_aParameter::STRING;
}
+
bool SMESHGUI_strParameter::GetNewInt (int & theValue) const
{
return false;
// class : SMESHGUI_dependParameter
// purpose :
//=================================================================================
-SMESHGUI_dependParameter::SMESHGUI_dependParameter( const QString& label )
-: SMESHGUI_aParameter( label )
+SMESHGUI_dependParameter::SMESHGUI_dependParameter( const QString& label, const bool preview )
+: SMESHGUI_aParameter( label, preview )
{
}
//=================================================================================
SMESHGUI_enumParameter::SMESHGUI_enumParameter( const QStringList& values,
const int initValue,
- const QString& label )
-: SMESHGUI_dependParameter( label ),
+ const QString& label,
+ const bool preview )
+: SMESHGUI_dependParameter( label, preview ),
myInitValue( initValue ),
myValue( initValue ),
myValues( values )
// purpose :
//=================================================================================
SMESHGUI_boolParameter::SMESHGUI_boolParameter( const bool initValue,
- const QString& label )
-: SMESHGUI_dependParameter( label ),
+ const QString& label,
+ const bool preview )
+: SMESHGUI_dependParameter( label, preview ),
myInitValue( initValue ),
myValue( myInitValue )
{
// class : SMESHGUI_Table
// purpose :
//=================================================================================
-SMESHGUI_Table::SMESHGUI_Table( int numRows, int numCols, QWidget* parent, const char* name )
-: QTable( numRows, numCols, parent, name )
+SMESHGUI_Table::SMESHGUI_Table( const SMESHGUI_tableParameter* tab, int numRows, int numCols,
+ QWidget* parent, const char* name )
+: QTable( numRows, numCols, parent, name ),
+ myParam( ( SMESHGUI_tableParameter* )tab )
{
}
}
}
+bool SMESHGUI_Table::eventFilter( QObject* o, QEvent* e )
+{
+ if( o && e && e->type()==QEvent::KeyPress )
+ {
+ QKeyEvent* ke = ( QKeyEvent* )e;
+ if( ke->key()==Qt::Key_Tab || ke->key()==Qt::Key_Backtab || ke->key()==Qt::Key_Return )
+ {
+ keyPressEvent( ke );
+ return true;
+ }
+ }
+
+ return QTable::eventFilter( o, e );
+}
+
+void SMESHGUI_Table::keyPressEvent( QKeyEvent* e )
+{
+ if( e )
+ {
+ bool shift = ( e->state() & Qt::ShiftButton );
+ int col = currentColumn(), row = currentRow();
+ if( e->key()==Qt::Key_Tab || e->key()==Qt::Key_Backtab )
+ {
+ if( e->key()==Qt::Key_Tab )
+ col++;
+ else
+ col--;
+ if( col<0 )
+ {
+ col = numCols()-1;
+ row--;
+ if( row<0 )
+ {
+ col = 0;
+ row = 0;
+ }
+ }
+ if( col>=numCols() )
+ {
+ col = 0;
+ row++;
+ if( row>=numRows() )
+ row = numRows()-1;
+ }
+ e->accept();
+ }
+ else if( e->key()==Qt::Key_Return )
+ {
+ col = 0;
+ if( shift )
+ row--;
+ else
+ row++;
+ if( row<0 )
+ row = 0;
+ else if( row>=numRows() )
+ {
+ //add row
+ myParam->onEdit( this, SMESHGUI_TableFrame::ADD_ROW, 1 );
+ }
+ e->accept();
+ }
+ if( e->isAccepted() )
+ {
+ clearSelection();
+ setCurrentCell( row, col );
+ }
+ else
+ QTable::keyPressEvent( e );
+ }
+}
+
+QWidget* SMESHGUI_Table::createEditor( int r, int c, bool init ) const
+{
+ QWidget* w = QTable::createEditor( r, c, init );
+ if( w )
+ w->installEventFilter( this );
+ return w;
+}
+
//=================================================================================
// class : SMESHGUI_TableFrame
// purpose :
//=================================================================================
-SMESHGUI_TableFrame::SMESHGUI_TableFrame( QWidget* parent )
+SMESHGUI_TableFrame::SMESHGUI_TableFrame( const SMESHGUI_tableParameter* param, QWidget* parent )
: QFrame( parent )
{
QVBoxLayout* main = new QVBoxLayout( this, 0, 0 );
- myTable = new SMESHGUI_Table( 1, 1, this );
+ myTable = new SMESHGUI_Table( param, 1, 1, this );
+ connect( myTable, SIGNAL( valueChanged( int, int ) ), this, SIGNAL( valueChanged( int, int ) ) );
QFrame* aButFrame = new QFrame( this );
QHBoxLayout* butLay = new QHBoxLayout( aButFrame, 5, 5 );
// purpose :
//=================================================================================
SMESHGUI_tableParameter::SMESHGUI_tableParameter( const double init,
- const QString& label )
-: SMESHGUI_aParameter( label ),
+ const QString& label,
+ const bool preview )
+: SMESHGUI_aParameter( label, preview ),
myInitValue( init ),
myColsInt( 1 ),
myRowsInt( 1 ),
{
}
+bool operator<( const QPair<double,double>& p1, const QPair<double,double>& p2 )
+{
+ return p1.first < p2.first;
+}
+
+void SMESHGUI_tableParameter::sortData( SMESH::double_array& arr )
+{
+ QValueList< QPair<double,double> > aData;
+ if( arr.length()%2==1 )
+ arr.length( arr.length()-1 );
+
+ int aLen = arr.length();
+ for( int i=0; i<aLen/2; i++ )
+ aData.append( QPair<double,double>( arr[2*i], arr[2*i+1] ) );
+
+ qHeapSort( aData );
+
+ QValueList< QPair<double,double> >::const_iterator anIt = aData.begin(), aLast = aData.end();
+ QValueList<double> unique_values;
+ double prev; int i=0;
+ if( (*anIt).first>0.0 )
+ {
+ unique_values.append( 0.0 );
+ unique_values.append( 0.0 );
+ i++; prev = 0.0;
+ }
+ for( ; anIt!=aLast; anIt++ )
+ {
+ if( i==0 || (*anIt).first>prev )
+ {
+ unique_values.append( (*anIt).first );
+ unique_values.append( (*anIt).second );
+ i++;
+ }
+ prev = (*anIt).first;
+ }
+ if( prev<1.0 )
+ {
+ unique_values.append( 1.0 );
+ unique_values.append( 0.0 );
+ }
+
+ arr.length( unique_values.count() );
+ QValueList<double>::const_iterator anIt1 = unique_values.begin(), aLast1 = unique_values.end();
+ for( int j=0; anIt1!=aLast1; anIt1++, j++ )
+ arr[j] = *anIt1;
+}
+
SMESHGUI_aParameter::Type SMESHGUI_tableParameter::GetType() const
{
return TABLE;
QWidget* SMESHGUI_tableParameter::CreateWidget( QWidget* par ) const
{
- SMESHGUI_TableFrame* t = new SMESHGUI_TableFrame( par );
+ SMESHGUI_TableFrame* t = new SMESHGUI_TableFrame( this, par );
connect( t, SIGNAL( toEdit( SMESHGUI_TableFrame::Button, int ) ),
this, SLOT ( onEdit( SMESHGUI_TableFrame::Button, int ) ) );
for( int i=0, m=row; i<m; i++ )
for( int j=0, n=col; j<n; j++ )
if( row*j+i<myData.length() )
- tab->item( i, j )->setText( QString( "%1" ).arg( myData[row*j+i] ) );
+ tab->item( i, j )->setText( QString( "%1" ).arg( myData[col*i+j] ) );
}
}
void SMESHGUI_tableParameter::data( SMESH::double_array& v ) const
{
v = myData;
+ sortData( v );
}
void SMESHGUI_tableParameter::setData( const SMESH::double_array& d )
{
myData = d;
+ sortData( myData );
}
void SMESHGUI_tableParameter::update( QWidget* w ) const
{
SMESHGUI_TableFrame* fr = ( SMESHGUI_TableFrame* )sender();
SMESHGUI_Table* tab = fr->table();
+ onEdit( tab, b, n );
+ }
+}
- switch( b )
- {
- case SMESHGUI_TableFrame::ADD_COLUMN:
- {
- if( !myEditCols || myCols.get() )
- return;
-
- myColsInt++; update( fr );
- if( n>=0 )
- for( int i=0; i<myRowsInt; i++ )
- for( int j=myColsInt-1; j>=n; j-- )
- if( j==n )
- tab->setText( i, j, QString( "%1" ).arg( myInitValue ) );
- else
- tab->setText( i, j, tab->text( i, j-1 ) );
- break;
- }
-
- case SMESHGUI_TableFrame::REMOVE_COLUMN:
- {
- if( !myEditCols || myCols.get() || myColsInt<=1 )
- return;
+void SMESHGUI_tableParameter::onEdit( SMESHGUI_Table* tab, SMESHGUI_TableFrame::Button b, int n )
+{
+ if( !tab )
+ return;
- if( n>=0 )
- for( int i=0; i<myRowsInt; i++ )
- for( int j=n; j<myColsInt-1; j++ )
- tab->setText( i, j, tab->text( i, j+1 ) );
- myColsInt--; update( fr );
+ SMESHGUI_TableFrame* fr = dynamic_cast<SMESHGUI_TableFrame*>( tab->parent() );
- break;
- }
+ switch( b )
+ {
+ case SMESHGUI_TableFrame::ADD_COLUMN:
+ {
+ if( !myEditCols || myCols.get() )
+ return;
+
+ myColsInt++; update( fr );
+ if( n>=0 )
+ for( int i=0; i<myRowsInt; i++ )
+ for( int j=myColsInt-1; j>=n; j-- )
+ if( j==n )
+ tab->setText( i, j, QString( "%1" ).arg( myInitValue ) );
+ else
+ tab->setText( i, j, tab->text( i, j-1 ) );
+ break;
+ }
+
+ case SMESHGUI_TableFrame::REMOVE_COLUMN:
+ {
+ if( !myEditCols || myCols.get() || myColsInt<=1 )
+ return;
+
+ if( n>=0 )
+ for( int i=0; i<myRowsInt; i++ )
+ for( int j=n; j<myColsInt-1; j++ )
+ tab->setText( i, j, tab->text( i, j+1 ) );
+ myColsInt--; update( fr );
- case SMESHGUI_TableFrame::ADD_ROW:
- {
- if( !myEditRows || myRows.get() )
- return;
-
- myRowsInt++; update( fr );
- if( n>=0 )
- for( int i=myRowsInt-1; i>=n; i-- )
- for( int j=0; j<myColsInt; j++ )
- if( i==n )
- tab->setText( i, j, QString( "%1" ).arg( myInitValue ) );
- else
- tab->setText( i, j, tab->text( i-1, j ) );
- break;
- }
+ break;
+ }
- case SMESHGUI_TableFrame::REMOVE_ROW:
- {
- if( !myEditRows || myRows.get() || myRowsInt<=1 )
- return;
-
- if( n>=0 )
- for( int i=n; i<myRowsInt-1; i++ )
- for( int j=0; j<myColsInt; j++ )
- tab->setText( i, j, tab->text( i+1, j ) );
- myRowsInt--; update( fr );
-
- break;
- }
+ case SMESHGUI_TableFrame::ADD_ROW:
+ {
+ if( !myEditRows || myRows.get() )
+ return;
+
+ myRowsInt++; update( fr );
+ if( n>=0 )
+ for( int i=myRowsInt-1; i>=n; i-- )
+ for( int j=0; j<myColsInt; j++ )
+ if( i==n )
+ tab->setText( i, j, QString( "%1" ).arg( myInitValue ) );
+ else
+ tab->setText( i, j, tab->text( i-1, j ) );
+ break;
+ }
+
+ case SMESHGUI_TableFrame::REMOVE_ROW:
+ {
+ if( !myEditRows || myRows.get() || myRowsInt<=1 )
+ return;
+
+ if( n>=0 )
+ for( int i=n; i<myRowsInt-1; i++ )
+ for( int j=0; j<myColsInt; j++ )
+ tab->setText( i, j, tab->text( i+1, j ) );
+ myRowsInt--; update( fr );
+
+ break;
}
}
}
class SMESHGUI_aParameter
{
public:
- SMESHGUI_aParameter(const QString& label):_label(label) {}
+ typedef bool (*VALIDATION_FUNC)( SMESHGUI_aParameter* );
+
+ SMESHGUI_aParameter(const QString& label, const bool = false );
virtual ~SMESHGUI_aParameter();
enum Type { INT, DOUBLE, STRING, ENUM, BOOL, TABLE };
virtual QWidget* CreateWidget( QWidget* ) const = 0;
virtual void InitializeWidget( QWidget* ) const = 0;
+ bool needPreview() const;
+
/*!
* \brief Returns string representation of signal emitted when value in corrsponding widget is changed
*/
virtual QString sigValueChanged() const;
- QString & Label() { return _label; }
+ QString & Label();
private:
QString _label;
+ bool _needPreview;
};
/*!
SMESHGUI_intParameter(const int initValue = 0,
const QString& label = QString::null,
const int bottom = 0,
- const int top = 1000);
+ const int top = 1000,
+ const bool = false );
int & InitValue() { return _initValue; }
int & Top() { return _top; }
int & Bottom() { return _bottom; }
const double bottom = -1E6,
const double top = +1E6,
const double step = 1.0,
- const int decimals = 3);
+ const int decimals = 3,
+ const bool = false);
double & InitValue() { return _initValue; }
double & Top() { return _top; }
double & Bottom() { return _bottom; }
{
public:
SMESHGUI_strParameter( const QString& initValue = "",
- const QString& label = QString::null);
+ const QString& label = QString::null,
+ const bool = false );
QString& InitValue() { return _initValue; }
virtual Type GetType() const;
virtual bool GetNewInt( int & Value ) const;
typedef QMap< int, IntList > ShownMap;
public:
- SMESHGUI_dependParameter( const QString& = QString::null );
+ SMESHGUI_dependParameter( const QString& = QString::null, const bool = false );
const ShownMap& shownMap() const;
ShownMap& shownMap();
*/
SMESHGUI_enumParameter( const QStringList& values,
const int init = 0,
- const QString& label = QString::null );
+ const QString& label = QString::null,
+ const bool = false );
virtual ~SMESHGUI_enumParameter();
/*!
{
public:
SMESHGUI_boolParameter( const bool = false,
- const QString& = QString::null );
+ const QString& = QString::null,
+ const bool = false );
virtual ~SMESHGUI_boolParameter();
bool& InitValue() { return myInitValue; }
class QButton;
+class SMESHGUI_tableParameter;
+
/*!
* \brief This class represents custom table. It has only double values and
Q_OBJECT
public:
- SMESHGUI_Table( int numRows, int numCols, QWidget* = 0, const char* = 0 );
+ SMESHGUI_Table( const SMESHGUI_tableParameter*, int numRows, int numCols, QWidget* = 0, const char* = 0 );
virtual ~SMESHGUI_Table();
/*!
void setValidator( const double, const double, const int,
const int rmin = -1, const int rmax = -1,
const int cmin = -1, const int cmax = -1 );
+
+protected:
+ virtual void keyPressEvent( QKeyEvent* );
+ virtual bool eventFilter( QObject*, QEvent* );
+ virtual QWidget* createEditor( int, int, bool ) const;
+
+private:
+ SMESHGUI_tableParameter* myParam;
};
typedef enum { ADD_COLUMN, REMOVE_COLUMN, ADD_ROW, REMOVE_ROW } Button;
public:
- SMESHGUI_TableFrame( QWidget* );
+ SMESHGUI_TableFrame( const SMESHGUI_tableParameter*, QWidget* );
~SMESHGUI_TableFrame();
SMESHGUI_Table* table() const;
* this object resize table ( returned by table() ) automatically
*/
void toEdit( SMESHGUI_TableFrame::Button, int );
+ void valueChanged( int, int );
private:
QButton *myAddColumn, *myRemoveColumn, *myAddRow, *myRemoveRow;
* and if new column or row is added then it is filled with default value
*/
SMESHGUI_tableParameter( const double init = 0.0,
- const QString& label = QString::null );
+ const QString& label = QString::null,
+ const bool preview = false );
virtual ~SMESHGUI_tableParameter();
virtual Type GetType() const;
virtual void InitializeWidget( QWidget* ) const;
virtual void TakeValue( QWidget* );
+ static void sortData( SMESH::double_array& );
+
/*!
* \brief Updates look of widget in accordance with all parameters of this object
*/
private slots:
void onEdit( SMESHGUI_TableFrame::Button, int );
+ void onEdit( SMESHGUI_Table*, SMESHGUI_TableFrame::Button, int );
private:
void setItems( QWidget*, int = -1, int = -1, int = -1, int = -1 ) const;
ValidatorsMap myValidators;
bool myEditCols, myEditRows;
QMap< int, QString > myColNames;
+
+ friend class SMESHGUI_Table;
};
#endif // SMESHGUI_aParameter.h
+
#include "SMESHGUI.h"
#include "SMESHGUI_SpinBox.h"
#include "SMESHGUI_Utils.h"
+#include "SMESHGUI_FunctionPreview.h"
#include "SUIT_Tools.h"
#include "SUIT_Desktop.h"
GroupC1Layout->setMargin(11);
/* Spin boxes with labels */
list<SMESHGUI_aParameterPtr>::iterator paramIt = myParamList.begin();
- for (int row = 0; paramIt != myParamList.end(); paramIt++ , row++)
+ int row;
+ for( row = 0; paramIt != myParamList.end(); paramIt++ , row++)
{
SMESHGUI_aParameterPtr param = (*paramIt);
QLabel * label = new QLabel(GroupC1, "TextLabel");
aSpinWidget->setMinimumSize(150, 0);
QString sig = param->sigValueChanged();
- if( !sig.isEmpty() && param->GetType()!=SMESHGUI_aParameter::TABLE )
+ if( !sig.isEmpty() /*&& param->GetType()!=SMESHGUI_aParameter::TABLE*/ )
connect( aSpinWidget, sig.latin1(), this, SLOT( onValueChanged() ) );
param->InitializeWidget(aSpinWidget);
}
}
+ myPreview = new SMESHGUI_FunctionPreview( GroupC1 );
+ GroupC1Layout->addWidget( myPreview, row, 1 );
+
paramIt = myParamList.begin();
std::list<QWidget*>::const_iterator anIt = mySpinList.begin();
for( ; paramIt!=myParamList.end(); paramIt++, anIt++ )
+ {
+ (*paramIt)->TakeValue( *anIt );
UpdateShown( *paramIt, *anIt );
-
+ FunctionPreview( *paramIt, *anIt );
+ }
/***************************************************************/
QGroupBox* GroupButtons = new QGroupBox(this, "GroupButtons");
return false;
}
+//=======================================================================
+// function : FunctionPreview
+// purpose :
+//=======================================================================
+void SMESHGUI_aParameterDlg::FunctionPreview( const SMESHGUI_aParameterPtr p, QWidget* w )
+{
+ if( !w || !w->isShown() )
+ return;
+
+ SMESHGUI_strParameter* str_param = dynamic_cast<SMESHGUI_strParameter*>( p.operator->() );
+ SMESHGUI_tableParameter* tab_param = dynamic_cast<SMESHGUI_tableParameter*>( p.operator->() );
+ SMESHGUI_boolParameter* bool_param = dynamic_cast<SMESHGUI_boolParameter*>( p.operator->() );
+ if( str_param && str_param->needPreview() )
+ {
+ QString val; str_param->GetNewText( val );
+ if( !val.isNull() )
+ myPreview->setParams( val );
+ }
+ else if( tab_param && tab_param->needPreview() )
+ {
+ SMESH::double_array d;
+ tab_param->data( d );
+ myPreview->setParams( d );
+ }
+ else if( bool_param && bool_param->needPreview() )
+ {
+ int exp=0;
+ bool_param->GetNewInt( exp );
+ myPreview->setIsExp( exp );
+ }
+}
+
//=======================================================================
// function : onValueChanged
// purpose :
{
QWidget* w = ( QWidget* )sender();
- SMESHGUI_aParameterPtr param;
std::list<QWidget*>::const_iterator anIt = mySpinList.begin(),
aLast = mySpinList.end();
{
(*aPIt)->TakeValue( w );
UpdateShown( *aPIt, w );
+ FunctionPreview( *aPIt, w );
break;
}
}
std::list<QWidget*>::const_iterator anIt = mySpinList.begin(),
aLast = mySpinList.end(),
aLIt = myLabelList.begin();
- for( int i=0; anIt!=aLast; anIt++, aLIt++, i++ )
+ std::list<SMESHGUI_aParameterPtr>::iterator aPIt = myParamList.begin();
+ bool preview = false;
+ for( int i=0; anIt!=aLast; anIt++, aLIt++, i++, aPIt++ )
{
bool shown = hasValue && map[ val ].contains( i );
(*anIt)->setShown( shown );
(*aLIt)->setShown( shown );
+ if( shown )
+ {
+ SMESHGUI_strParameter* str_param = dynamic_cast<SMESHGUI_strParameter*>( (*aPIt).operator->() );
+ SMESHGUI_tableParameter* tab_param = dynamic_cast<SMESHGUI_tableParameter*>( (*aPIt).operator->() );
+ preview = preview || ( str_param && str_param->needPreview() ) || ( tab_param && tab_param->needPreview() );
+ }
}
+ myPreview->setShown( preview );
}
class QPushButton;
class SMESHGUI;
class QWidget;
+class SMESHGUI_FunctionPreview;
//=================================================================================
// class : SMESHGUI_aParameterDlg
void ClickOnOk();
void UpdateShown( const SMESHGUI_aParameterPtr, QWidget* );
+private:
+ void FunctionPreview( const SMESHGUI_aParameterPtr, QWidget* );
+
private:
SMESHGUI* mySMESHGUI;
std::list<QWidget*> mySpinList, myLabelList;
std::list<SMESHGUI_aParameterPtr> myParamList;
+ SMESHGUI_FunctionPreview* myPreview;
};
#endif // SMESHGUI_aParameterDlg.h
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 $(OCC_LDPATH) -lTKAdvTools -L${KERNEL_ROOT_DIR}/lib/salome -L${GEOM_ROOT_DIR}/lib/salome
+LDFLAGS+= -lSMESHimpl -lMEFISTO2D $(OCC_LDPATH) -lTKAdvTools -L${KERNEL_ROOT_DIR}/lib/salome -L${GEOM_ROOT_DIR}/lib/salome \
+ -lCASCatch
@CONCLUDE@
#include <TCollection_AsciiString.hxx>
#include <ExprIntrp_GenExp.hxx>
#include <Expr_NamedUnknown.hxx>
+#include <CASCatch_CatchSignals.hxx>
+#include <CASCatch_Failure.hxx>
+#include <CASCatch_ErrorHandler.hxx>
+#include <OSD.hxx>
+#include <Expr_Array1OfNamedUnknown.hxx>
+#include <TColStd_Array1OfReal.hxx>
+
const double PRECISION = 1e-7;
_expMode(false)
{
_name = "NumberOfSegments";
- _param_algo_dim = 1;
+ _param_algo_dim = 1;
}
//=============================================================================
double prev = -PRECISION;
bool isSame = table.size() == _table.size();
+ bool pos = false;
for (i=0; i < table.size()/2; i++) {
double par = table[i*2];
double val = table[i*2+1];
throw SALOME_Exception(LOCALIZED("parameter of table function is out of range [0,1]"));
if ( fabs(par-prev)<PRECISION )
throw SALOME_Exception(LOCALIZED("two parameters are the same"));
- if (val < PRECISION)
+ if ( val < 0 )
throw SALOME_Exception(LOCALIZED("value of table function is not positive"));
+ if( val>PRECISION )
+ pos = true;
if (isSame)
{
double oldpar = _table[i*2];
prev = par;
}
- if (!isSame)
+ if( !pos )
+ throw SALOME_Exception(LOCALIZED("value of table function is not positive"));
+
+ if( pos && !isSame )
{
_table = table;
NotifySubMeshesHypothesisModification();
/*! check if only 't' is unknown variable in expression
*/
//================================================================================
-bool isCorrect( const Handle( Expr_GeneralExpression )& expr )
+bool isCorrectArg( const Handle( Expr_GeneralExpression )& expr )
{
- if( expr.IsNull() )
- return true;
-
+ Handle( Expr_NamedUnknown ) sub = Handle( Expr_NamedUnknown )::DownCast( expr );
+ if( !sub.IsNull() )
+ return sub->GetName()=="t";
+
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 );
+ Handle( Expr_GeneralExpression ) sub = expr->SubExpression( i );
+ Handle( Expr_NamedUnknown ) name = Handle( Expr_NamedUnknown )::DownCast( sub );
if( !name.IsNull() )
{
if( name->GetName()!="t" )
- res = false;
+ res = false;
}
else
- res = isCorrect( subexpr );
+ res = isCorrectArg( sub );
}
return res;
}
* ( 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 )
+bool process( const TCollection_AsciiString& str,
+ bool& syntax, bool& args,
+ bool& non_neg, bool& non_zero,
+ bool& singulars, double& sing_point )
{
- // check validity of expression
- syntax = false;
- args = false;
- try
+ Handle( ExprIntrp_GenExp ) myExpr = ExprIntrp_GenExp::Create();
+ myExpr->Process( str.ToCString() );
+
+ if( myExpr->IsDone() )
{
- Handle( ExprIntrp_GenExp ) gen = ExprIntrp_GenExp::Create();
- gen->Process( str );
-
- if( gen->IsDone() )
- {
- syntax = true;
- args = isCorrect( gen->Expression() );
- }
+ syntax = true;
+ args = isCorrectArg( myExpr->Expression() );
}
- catch (Standard_Failure)
+
+ bool res = syntax && args;
+ if( !res )
+ myExpr.Nullify();
+
+ non_neg = true;
+ singulars = false;
+ non_zero = false;
+
+ 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" );
+
+ 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)
+ {
+ aCatchSignals.Deactivate();
+ Handle(CASCatch_Failure) aFail = CASCatch_Failure::Caught();
+ sing_point = t;
+ singulars = true;
+ break;
+ }
+ if( res<0 )
+ {
+ non_neg = false;
+ break;
+ }
+ if( res>PRECISION )
+ non_zero = true;
+ }
+ aCatchSignals.Deactivate();
}
+ return res && non_neg && ( !singulars );
}
//================================================================================
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"));
+ 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 );
+ if( !res )
+ {
+ if( !syntax )
+ throw SALOME_Exception(LOCALIZED("invalid expression syntax"));
+ 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"));
+ if( singulars )
+ {
+ char buf[1024];
+ sprintf( buf, "Function has singular point in %.3f", sing_point );
+ throw SALOME_Exception( buf );
+ }
+ if( !non_zero )
+ throw SALOME_Exception(LOCALIZED("f(t)=0 cannot be used as density"));
- string func(str.ToCString());
- if (_func != func)
+ return;
+ }
+
+ std::string func = expr;
+ if( _func != func )
{
_func = func;
NotifySubMeshesHypothesisModification();
*
* Throws SALOME_Exception if distribution type is not DT_ExprFunc
*/
- void SetExpressionFunction(const char* expr)
+ void SetExpressionFunction( const char* expr)
throw (SALOME_Exception);
/*!
#include <TColStd_Array1OfReal.hxx>
#include <ExprIntrp_GenExp.hxx>
+#include <CASCatch_CatchSignals.hxx>
+#include <CASCatch_Failure.hxx>
+#include <CASCatch_ErrorHandler.hxx>
+#include <OSD.hxx>
+#include <math_GaussSingleIntegration.hxx>
+
#include <string>
#include <math.h>
}
}
-/*!
- * \brief This class provides interface for a density function
- */
-class 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;
+ Function( const bool exp )
+ : myExp( exp )
+ {
+ }
+
+ virtual ~Function()
+ {
+ }
+
+ virtual bool value( const double, double& f )
+ {
+ if( myExp )
+ f = pow( 10, f );
+ return true;
+ }
+ virtual double integral( const double, const double ) = 0;
+
private:
- bool _expMode;
+ bool myExp;
};
-/*!
- * \brief This class provides computation of density function given by a table
- */
-class TabFunction: public Function
+class FunctionIntegral : public Function
{
public:
- TabFunction(const vector<double>& table, bool expMode);
- virtual bool IsReady() const;
-protected:
- virtual double compute(double t) const;
+ FunctionIntegral( Function*, const double );
+ virtual ~FunctionIntegral();
+ virtual bool value( const double, double& );
+ virtual double integral( const double, const double );
+
private:
- const vector<double>& _table;
+ Function* myFunc;
+ double myStart;
};
-/*!
- * \brief This class provides computation of density function given by an expression
- */
-class ExprFunction: public Function
+FunctionIntegral::FunctionIntegral( Function* f, const double st )
+: Function( false )
+{
+ myFunc = f;
+ myStart = st;
+}
+
+FunctionIntegral::~FunctionIntegral()
+{
+}
+
+bool FunctionIntegral::value( const double t, double& f )
+{
+ f = myFunc ? myFunc->integral( myStart, t ) : 0;
+ return myFunc!=0 && Function::value( t, f );
+}
+
+double FunctionIntegral::integral( const double, const double )
+{
+ return 0;
+}
+
+class FunctionTable : public Function
{
public:
- ExprFunction(const char* expr, bool expMode);
- virtual bool IsReady() const;
-protected:
- virtual double compute(double t) const;
+ FunctionTable( const std::vector<double>&, const bool );
+ virtual ~FunctionTable();
+ virtual bool value( const double, double& );
+ virtual double integral( const double, const double );
+
private:
- Handle(Expr_GeneralExpression) _expression;
- Expr_Array1OfNamedUnknown _var;
- mutable TColStd_Array1OfReal _val;
+ bool findBounds( const double, int&, int& ) const;
+
+ //integral from x[i] to x[i+1]
+ double integral( const int i );
+
+ //integral from x[i] to x[i]+d
+ //warning: function is presented as linear on interaval from x[i] to x[i]+d,
+ // for correct result d must be >=0 and <=x[i+1]-x[i]
+ double integral( const int i, const double d );
+
+private:
+ std::vector<double> myData;
};
-double Function::operator() (double t) const
+FunctionTable::FunctionTable( const std::vector<double>& data, const bool exp )
+: Function( exp )
{
- double res = compute(t);
- if (_expMode)
- res = pow(10, res);
- return res;
+ myData = data;
}
-TabFunction::TabFunction(const vector<double>& table, bool expMode)
- : Function(expMode),
- _table(table)
+FunctionTable::~FunctionTable()
{
}
-bool TabFunction::IsReady() const
+bool FunctionTable::value( const double t, double& f )
{
+ int i1, i2;
+ if( !findBounds( t, i1, i2 ) )
+ return false;
+
+ double
+ x1 = myData[2*i1], y1 = myData[2*i1+1],
+ x2 = myData[2*i2], y2 = myData[2*i2+1];
+
+ Function::value( x1, y1 );
+ Function::value( x2, y2 );
+
+ f = y1 + ( y2-y1 ) * ( t-x1 ) / ( x2-x1 );
return true;
}
-double TabFunction::compute (double t) const
+double FunctionTable::integral( const int i )
{
- //find place of <t> 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));
+ if( i>=0 && i<myData.size()-1 )
+ return integral( i, myData[2*(i+1)]-myData[2*i] );
+ else
+ return 0;
}
-ExprFunction::ExprFunction(const char* expr, bool expMode)
- : Function(expMode),
- _var(1,1),
- _val(1,1)
+double FunctionTable::integral( const int i, const double d )
{
- 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");
- }
+ double f, res = 0.0;
+ if( value( myData[2*i]+d, f ) )
+ res = ( myData[2*i] + f ) / 2.0 * d;
+
+ return res;
}
-bool ExprFunction::IsReady() const
+double FunctionTable::integral( const double a, const double b )
{
- return !_expression.IsNull();
+ int x1s, x1f, x2s, x2f;
+ findBounds( a, x1s, x1f );
+ findBounds( b, x2s, x2f );
+ double J = 0;
+ for( int i=x1s; i<x2s; i++ )
+ J+=integral( i );
+ J-=integral( x1s, a-myData[2*x1s] );
+ J+=integral( x2s, b-myData[2*x2s] );
+ return J;
}
-double ExprFunction::compute (double t) const
+bool FunctionTable::findBounds( const double x, int& x_ind_1, int& x_ind_2 ) const
{
- ASSERT(!_expression.IsNull());
- _val(1) = t;
- return _expression->Evaluate(_var, _val);
+ int n = myData.size();
+ if( n==0 || x<myData[0] )
+ {
+ x_ind_1 = x_ind_2 = 0;
+ return false;
+ }
+
+ for( int i=0; i<n-1; i++ )
+ if( myData[2*i]<=x && x<=myData[2*(i+1)] )
+ {
+ x_ind_1 = i;
+ x_ind_2 = i+1;
+ return true;
+ }
+ x_ind_1 = n-1;
+ x_ind_2 = n-1;
+ return false;
}
-//================================================================================
-/*!
- * \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)
+
+class FunctionExpr : public Function, public math_Function
{
- if (reverse)
- {
- sm1 = 1.0 - sm1;
- sm2 = 1.0 - sm2;
- }
- return sm1 + (sm1-sm2) * func(sm1) / func(sm2);
+public:
+ FunctionExpr( const char*, const bool );
+ virtual ~FunctionExpr();
+ virtual Standard_Boolean Value( Standard_Real, Standard_Real& );
+ virtual bool value( const double, double& ); //inherited from Function
+ virtual double integral( const double, const double );
+
+private:
+ Handle(ExprIntrp_GenExp) myExpr;
+ Expr_Array1OfNamedUnknown myVars;
+ TColStd_Array1OfReal myValues;
+};
+
+FunctionExpr::FunctionExpr( const char* str, const bool exp )
+: Function( exp ),
+ myVars( 1, 1 ),
+ myValues( 1, 1 )
+{
+ myExpr = ExprIntrp_GenExp::Create();
+ myExpr->Process( ( Standard_CString )str );
+ if( !myExpr->IsDone() )
+ myExpr.Nullify();
+
+ myVars.ChangeValue( 1 ) = new Expr_NamedUnknown( "t" );
}
-//================================================================================
-/*!
- * \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
- */
-//================================================================================
+FunctionExpr::~FunctionExpr()
+{
+}
-static bool computeParamByFunc(Adaptor3d_Curve& C3d, double first, double last,
- double length, bool theReverse,
- int nbSeg, const Function& func,
- list<double>& theParams)
+Standard_Boolean FunctionExpr::Value( Standard_Real T, Standard_Real& F )
+{
+ double f;
+ Standard_Boolean res = value( T, f );
+ F = f;
+ return res;
+}
+
+bool FunctionExpr::value( const double t, double& f )
{
- if (!func.IsReady())
+ if( myExpr.IsNull() )
return false;
- // ########## TMP until pb division by zero when func(0.0)==0 is fixed #########
- if (::Abs(func(0.0)) <= ::RealSmall() ) return false;
- // ########## TMP until pb division by zero when func(0.0)==0 is fixed #########
+ CASCatch_CatchSignals aCatchSignals;
+ aCatchSignals.Activate();
- vector<double> xxx[2];
- int nbPnt = 1 + nbSeg;
- int rev, i;
- for (rev=0; rev < 2; rev++)
+ myValues.ChangeValue( 1 ) = t;
+ bool ok = true;
+ CASCatch_TRY {
+ f = myExpr->Expression()->Evaluate( myVars, myValues );
+ }
+ CASCatch_CATCH(CASCatch_Failure) {
+ aCatchSignals.Deactivate();
+ Handle(CASCatch_Failure) aFail = CASCatch_Failure::Caught();
+ f = 0.0;
+ }
+
+ aCatchSignals.Deactivate();
+ ok = Function::value( t, f ) && ok;
+ return ok;
+}
+
+double FunctionExpr::integral( const double a, const double b )
+{
+ double res = 0.0;
+ CASCatch_TRY
{
- // curv abscisses initialisation
- vector<double> x(nbPnt, 0.);
- // the first abscissa is 0.0
+ math_GaussSingleIntegration _int( *this, a, b, 20 );
+ if( _int.IsDone() )
+ res = _int.Value();
+ }
+ CASCatch_CATCH(CASCatch_Failure)
+ {
+ res = 0.0;
+ MESSAGE( "Exception in integral calculating" );
+ }
+ return res;
+}
- // 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;
- if ( x1 <= ::RealSmall() )
- return false; // break infinite loop
- 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;
+double dihotomySolve( Function& f, const double val, const double _start, const double _fin, const double eps, bool& ok )
+{
+ double start = _start, fin = _fin, start_val, fin_val; bool ok1, ok2;
+ ok1 = f.value( start, start_val );
+ ok2 = f.value( fin, fin_val );
- // not ok ...
+ if( !ok1 || !ok2 )
+ {
+ ok = false;
+ return 0.0;
+ }
- x1_too_small = x1;
+ bool start_pos = start_val>=val, fin_pos = fin_val>=val;
+ ok = true;
+
+ while( fin-start>eps )
+ {
+ double mid = ( start+fin )/2.0, mid_val;
+ ok = f.value( mid, mid_val );
+ if( !ok )
+ return 0.0;
- // Modify x1 value
+// char buf[1024];
+// sprintf( buf, "start=%f\nfin=%f\nmid_val=%f\n", float( start ), float( fin ), float( mid_val ) );
+// MESSAGE( buf );
- if (x1_too_large > 1e100)
- x1 = 2*x1;
- else
- x1 = (x1_too_small+x1_too_large)/2;
+ bool mid_pos = mid_val>=val;
+ if( start_pos!=mid_pos )
+ {
+ fin_pos = mid_pos;
+ fin = mid;
}
- xxx[rev] = x;
+ else if( fin_pos!=mid_pos )
+ {
+ start_pos = mid_pos;
+ start = mid;
+ }
+ else
+ break;
}
+ return (start+fin)/2.0;
+}
+
+static bool computeParamByFunc(Adaptor3d_Curve& C3d, double first, double last,
+ double length, bool theReverse,
+ int nbSeg, Function& func,
+ list<double>& theParams)
+{
+ OSD::SetSignal( true );
+ if( nbSeg<=0 )
+ return false;
- // average
+ MESSAGE( "computeParamByFunc" );
+
+ int nbPnt = 1 + nbSeg;
vector<double> x(nbPnt, 0.);
- for (i=0; i < nbPnt; i++)
- x[i] = (xxx[0][i] + (1.0 - xxx[1][nbPnt-i])) / 2;
+
+ x[0] = 0.0;
+ double J = func.integral( 0.0, 1.0 ) / nbSeg;
+ bool ok;
+ for( int i=1; i<nbSeg; i++ )
+ {
+ FunctionIntegral f_int( &func, x[i-1] );
+ x[i] = dihotomySolve( f_int, J, x[i-1], 1.0, 1E-4, ok );
+ if( !ok )
+ return false;
+ }
+
+ x[nbSeg] = 1.0;
+ MESSAGE( "Points:\n" );
+ char buf[1024];
+ for( int i=0; i<=nbSeg; i++ )
+ {
+ sprintf( buf, "%f\n", float(x[i] ) );
+ MESSAGE( buf );
+ }
+
+
// apply parameters in range [0,1] to the space of the curve
double prevU = first;
prevU = last;
sign = -1.;
}
- for (i = 1; i < nbSeg; i++)
+ for( int i = 1; i < nbSeg; i++ )
{
double curvLength = length * (x[i] - x[i-1]) * sign;
GCPnts_AbscissaPoint Discret( C3d, curvLength, prevU );
break;
case StdMeshers_NumberOfSegments::DT_TabFunc:
{
- TabFunction func(_vvalue[ TAB_FUNC_IND ], (bool)_ivalue[ EXP_MODE_IND ]);
+ FunctionTable 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 ]);
+ FunctionExpr 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);
CPPFLAGS += $(QT_INCLUDES) $(VTK_INCLUDES) $(OGL_INCLUDES) $(OCC_INCLUDES) $(PYTHON_INCLUDES) \
-I${KERNEL_ROOT_DIR}/include/salome -I${GUI_ROOT_DIR}/include/salome -I${GEOM_ROOT_DIR}/include/salome \
$(BOOST_CPPFLAGS)
-CXXFLAGS += -I${KERNEL_ROOT_DIR}/include/salome -I${GUI_ROOT_DIR}/include/salome -I${GEOM_ROOT_DIR}/include/salome
+CXXFLAGS += -I${KERNEL_ROOT_DIR}/include/salome -I${GUI_ROOT_DIR}/include/salome -I${GEOM_ROOT_DIR}/include/salome \
+ -I${QWTHOME}/include
#$(OCC_CXXFLAGS)
LDFLAGS += -lSMESH -lVTKViewer -lSalomeApp -lSMESHObject -lSMESHFiltersSelection $(OCC_KERNEL_LIBS) -lTKBO -L${KERNEL_ROOT_DIR}/lib/salome -L${GEOM_ROOT_DIR}/lib/salome -L${GUI_ROOT_DIR}/lib/salome
#include "SMESHGUI_Hypotheses.h"
#include "SMESHGUI_HypothesesUtils.h"
#include "SMESHGUI_Utils.h"
+#include "SMESHGUI_FunctionPreview.h"
#include "SUIT_Application.h"
#include "SUIT_Desktop.h"
/* Spin boxes with labels */
list<SMESHGUI_aParameterPtr>::iterator paramIt = aParamList.begin();
- for ( int row = 1; paramIt != aParamList.end(); paramIt++ , row++ )
+ int row;
+ for ( row = 1; paramIt != aParamList.end(); paramIt++ , row++ )
{
SMESHGUI_aParameterPtr param = (*paramIt);
QLabel * label = new QLabel( GroupC1, "TextLabel" );
aWidget->setMinimumSize( 150, 0 );
QString sig = param->sigValueChanged();
- if( !sig.isEmpty() && param->GetType()!=SMESHGUI_aParameter::TABLE )
+ if( !sig.isEmpty() /* && param->GetType()!=SMESHGUI_aParameter::TABLE*/ )
connect( aWidget, sig.latin1(), this, SLOT( onValueChanged() ) );
param->InitializeWidget( aWidget );
myParamMap.insert( param, info );
}
}
+ myPreview = new SMESHGUI_FunctionPreview( GroupC1 );
+ GroupC1Layout->addWidget( myPreview, row, 1 );
StdMeshersGUI_CreateHypothesisDlgLayout->addWidget( GroupC1, 1 );
break;
}
- SetParameters( Hyp, aParamList );
+ if( !SetParameters( Hyp, aParamList ) )
+ return false;
//set new Attribute Comment for hypothesis which parameters were set
QString aParams = "";
if( anIt.data().editor == w )
{
param = anIt.key();
- param->TakeValue( w );
+ param->TakeValue( w );
+
+ SMESHGUI_strParameter* str_param = dynamic_cast<SMESHGUI_strParameter*>( param.operator->() );
+ SMESHGUI_tableParameter* tab_param = dynamic_cast<SMESHGUI_tableParameter*>( param.operator->() );
+ SMESHGUI_boolParameter* bool_param = dynamic_cast<SMESHGUI_boolParameter*>( param.operator->() );
+
+ if( str_param && str_param->needPreview() )
+ {
+ QString val; str_param->GetNewText( val );
+ myPreview->setParams( val );
+ }
+ else if( tab_param && tab_param->needPreview() )
+ {
+ SMESH::double_array d;
+ tab_param->data( d );
+ myPreview->setParams( d );
+ }
+ else if( bool_param && bool_param->needPreview() )
+ {
+ int exp=0;
+ bool_param->GetNewInt( exp );
+ myPreview->setIsExp( exp );
+ }
UpdateShown( param );
break;
}
ParameterMap::const_iterator anIt = myParamMap.begin(),
aLast = myParamMap.end();
+ bool preview = false;
for( ; anIt!=aLast; anIt++ )
{
bool shown = hasValue && map[ val ].contains( (*anIt).order );
(*anIt).editor->setShown( shown );
(*anIt).label->setShown( shown );
+ if( shown )
+ {
+ SMESHGUI_strParameter* str_param = dynamic_cast<SMESHGUI_strParameter*>( anIt.key().operator->() );
+ SMESHGUI_tableParameter* tab_param = dynamic_cast<SMESHGUI_tableParameter*>( anIt.key().operator->() );
+ preview = preview || ( str_param && str_param->needPreview() ) || ( tab_param && tab_param->needPreview() );
+ }
}
+ myPreview->setShown( preview );
}
class QPushButton;
class SMESHGUI;
class SMESHGUI_SpinBox;
+class SMESHGUI_FunctionPreview;
//=================================================================================
// class : StdMeshersGUI_CreateHypothesisDlg
QPushButton* buttonOk;
QPushButton* buttonApply;
QPushButton* buttonCancel;
+ SMESHGUI_FunctionPreview* myPreview;
private slots:
#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))
+#define STR_PARAM(i,l,preview) SMESHGUI_aParameterPtr(new SMESHGUI_strParameter(i,l,preview))
+#define BOOL_PARAM(i,l,preview) SMESHGUI_aParameterPtr(new SMESHGUI_boolParameter(i,l,preview))
void StdMeshersGUI_Parameters::GetParameters (const QString& hypType,
list<SMESHGUI_aParameterPtr> & paramList )
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" ) );
+ SMESHGUI_tableParameter* tab = new SMESHGUI_tableParameter( 0.0, QObject::tr( "SMESH_TAB_FUNC" ), true );
tab->setRowCount( 5 );
tab->setColCount( 2 );
//default size of table: 5x2
paramList.push_back ( SMESHGUI_aParameterPtr( tab ) );
//4-th parameter in list
- paramList.push_back ( STR_PARAM ( "", QObject::tr( "SMESH_EXPR_FUNC" ) ) );
+ paramList.push_back ( STR_PARAM ( "", QObject::tr( "SMESH_EXPR_FUNC" ), true ) );
//5-th parameter in list
- paramList.push_back ( BOOL_PARAM ( false, QObject::tr( "SMESH_EXP_MODE" ) ) );
+ paramList.push_back ( BOOL_PARAM ( false, QObject::tr( "SMESH_EXP_MODE" ), true ) );
}
else if (hypType.compare("Arithmetic1D") == 0)
{
{
char* expr_func = NOS->GetExpressionFunction();
SetInitValue( *anIt, expr_func );
- delete expr_func;
+ //delete expr_func;
}
anIt++;