PAL8238 - Hypothesis for non-regular 1D meshing

This commit is contained in:
asl 2005-11-23 09:07:44 +00:00
parent 82ea47a7c9
commit 2ad752b10c
15 changed files with 1115 additions and 351 deletions

View File

@ -44,7 +44,8 @@ EXPORT_HEADERS= SMESHGUI_Swig.hxx \
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 = \
@ -111,7 +112,8 @@ LIB_SRC = SMESHGUI.cxx \
SMESHGUI_Dialog.cxx \
SMESHGUI_MeshDlg.cxx \
SMESHGUI_MeshOp.cxx \
SMESHGUI_Displayer.cxx
SMESHGUI_Displayer.cxx \
SMESHGUI_FunctionPreview.cxx
LIB_MOC = \
SMESHGUI.h \
@ -159,7 +161,8 @@ LIB_MOC = \
SMESHGUI_SelectionOp.h \
SMESHGUI_Dialog.h \
SMESHGUI_MeshDlg.h \
SMESHGUI_MeshOp.h
SMESHGUI_MeshOp.h \
SMESHGUI_FunctionPreview.h
LIB_CLIENT_IDL = SALOME_Exception.idl \
@ -186,13 +189,17 @@ LIB_SERVER_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)

View File

@ -0,0 +1,252 @@
#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;
}

View File

@ -0,0 +1,54 @@
#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

View File

@ -40,7 +40,25 @@
#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
{
@ -54,8 +72,9 @@ 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 )
{
@ -113,8 +132,9 @@ SMESHGUI_doubleParameter::SMESHGUI_doubleParameter (const double 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)
{
@ -172,8 +192,9 @@ QString SMESHGUI_doubleParameter::sigValueChanged() const
// 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)
{
}
@ -181,6 +202,7 @@ SMESHGUI_aParameter::Type SMESHGUI_strParameter::GetType() const
{
return SMESHGUI_aParameter::STRING;
}
bool SMESHGUI_strParameter::GetNewInt (int & theValue) const
{
return false;
@ -225,8 +247,8 @@ QString SMESHGUI_strParameter::sigValueChanged() const
// 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 )
{
}
@ -250,8 +272,9 @@ SMESHGUI_dependParameter::ShownMap& SMESHGUI_dependParameter::shownMap()
//=================================================================================
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 )
@ -329,8 +352,9 @@ QString SMESHGUI_enumParameter::sigValueChanged() const
// 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 )
{
@ -453,8 +477,10 @@ QWidget* SMESHGUI_doubleItem::createEditor() const
// 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 )
{
}
@ -509,18 +535,99 @@ void SMESHGUI_Table::setValidator( const double minV, const double maxV, const i
}
}
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 );
@ -616,8 +723,9 @@ void SMESHGUI_TableFrame::onButtonClicked()
// 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 ),
@ -630,6 +738,54 @@ SMESHGUI_tableParameter::~SMESHGUI_tableParameter()
{
}
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;
@ -652,7 +808,7 @@ bool SMESHGUI_tableParameter::GetNewText( QString& ) const
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 ) ) );
@ -705,7 +861,7 @@ void SMESHGUI_tableParameter::InitializeWidget( QWidget* w ) const
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] ) );
}
}
@ -728,11 +884,13 @@ void SMESHGUI_tableParameter::TakeValue( QWidget* w )
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
@ -874,68 +1032,77 @@ void SMESHGUI_tableParameter::onEdit( SMESHGUI_TableFrame::Button b, int n )
{
SMESHGUI_TableFrame* fr = ( SMESHGUI_TableFrame* )sender();
SMESHGUI_Table* tab = fr->table();
onEdit( tab, b, n );
}
}
switch( b )
void SMESHGUI_tableParameter::onEdit( SMESHGUI_Table* tab, SMESHGUI_TableFrame::Button b, int n )
{
if( !tab )
return;
SMESHGUI_TableFrame* fr = dynamic_cast<SMESHGUI_TableFrame*>( tab->parent() );
switch( b )
{
case SMESHGUI_TableFrame::ADD_COLUMN:
{
case SMESHGUI_TableFrame::ADD_COLUMN:
{
if( !myEditCols || myCols.get() )
return;
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;
}
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::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 );
break;
}
break;
}
case SMESHGUI_TableFrame::ADD_ROW:
{
if( !myEditRows || myRows.get() )
return;
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;
}
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;
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;
}
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;
}
}
}

View File

@ -47,7 +47,9 @@ typedef boost::shared_ptr<SMESHGUI_aParameter> SMESHGUI_aParameterPtr;
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 };
@ -59,15 +61,18 @@ public:
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;
};
/*!
@ -79,7 +84,8 @@ public:
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; }
@ -109,7 +115,8 @@ public:
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; }
@ -138,7 +145,8 @@ class SMESHGUI_strParameter: public SMESHGUI_aParameter
{
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;
@ -171,7 +179,7 @@ public:
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();
@ -192,7 +200,8 @@ public:
*/
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();
/*!
@ -224,7 +233,8 @@ class SMESHGUI_boolParameter: public SMESHGUI_dependParameter
{
public:
SMESHGUI_boolParameter( const bool = false,
const QString& = QString::null );
const QString& = QString::null,
const bool = false );
virtual ~SMESHGUI_boolParameter();
bool& InitValue() { return myInitValue; }
@ -244,6 +254,8 @@ private:
class QButton;
class SMESHGUI_tableParameter;
/*!
* \brief This class represents custom table. It has only double values and
@ -254,7 +266,7 @@ class SMESHGUI_Table : public QTable
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();
/*!
@ -278,6 +290,14 @@ public:
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;
};
@ -295,7 +315,7 @@ public:
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;
@ -324,6 +344,7 @@ signals:
* this object resize table ( returned by table() ) automatically
*/
void toEdit( SMESHGUI_TableFrame::Button, int );
void valueChanged( int, int );
private:
QButton *myAddColumn, *myRemoveColumn, *myAddRow, *myRemoveRow;
@ -345,7 +366,8 @@ public:
* 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;
@ -356,6 +378,8 @@ public:
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
*/
@ -416,6 +440,7 @@ public:
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;
@ -437,6 +462,9 @@ private:
ValidatorsMap myValidators;
bool myEditCols, myEditRows;
QMap< int, QString > myColNames;
friend class SMESHGUI_Table;
};
#endif // SMESHGUI_aParameter.h

View File

@ -31,6 +31,7 @@
#include "SMESHGUI.h"
#include "SMESHGUI_SpinBox.h"
#include "SMESHGUI_Utils.h"
#include "SMESHGUI_FunctionPreview.h"
#include "SUIT_Tools.h"
#include "SUIT_Desktop.h"
@ -94,7 +95,8 @@ void SMESHGUI_aParameterDlg::init()
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");
@ -107,7 +109,7 @@ void SMESHGUI_aParameterDlg::init()
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);
@ -116,11 +118,17 @@ void SMESHGUI_aParameterDlg::init()
}
}
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");
@ -196,6 +204,38 @@ bool SMESHGUI_aParameterDlg::Parameters( SMESHGUI* theModule,
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 :
@ -206,7 +246,6 @@ void SMESHGUI_aParameterDlg::onValueChanged()
{
QWidget* w = ( QWidget* )sender();
SMESHGUI_aParameterPtr param;
std::list<QWidget*>::const_iterator anIt = mySpinList.begin(),
aLast = mySpinList.end();
@ -216,6 +255,7 @@ void SMESHGUI_aParameterDlg::onValueChanged()
{
(*aPIt)->TakeValue( w );
UpdateShown( *aPIt, w );
FunctionPreview( *aPIt, w );
break;
}
}
@ -246,10 +286,19 @@ void SMESHGUI_aParameterDlg::UpdateShown( const SMESHGUI_aParameterPtr param, QW
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 );
}

View File

@ -39,6 +39,7 @@ class QLabel;
class QPushButton;
class SMESHGUI;
class QWidget;
class SMESHGUI_FunctionPreview;
//=================================================================================
// class : SMESHGUI_aParameterDlg
@ -69,6 +70,9 @@ private slots:
void ClickOnOk();
void UpdateShown( const SMESHGUI_aParameterPtr, QWidget* );
private:
void FunctionPreview( const SMESHGUI_aParameterPtr, QWidget* );
private:
SMESHGUI* mySMESHGUI;
@ -77,6 +81,7 @@ private:
std::list<QWidget*> mySpinList, myLabelList;
std::list<SMESHGUI_aParameterPtr> myParamList;
SMESHGUI_FunctionPreview* myPreview;
};
#endif // SMESHGUI_aParameterDlg.h

View File

@ -87,6 +87,7 @@ 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 $(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@

View File

@ -33,6 +33,13 @@ using namespace std;
#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;
@ -51,7 +58,7 @@ StdMeshers_NumberOfSegments::StdMeshers_NumberOfSegments(int hypId, int studyId,
_expMode(false)
{
_name = "NumberOfSegments";
_param_algo_dim = 1;
_param_algo_dim = 1;
}
//=============================================================================
@ -179,6 +186,7 @@ void StdMeshers_NumberOfSegments::SetTableFunction(const std::vector<double>& ta
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];
@ -186,8 +194,10 @@ void StdMeshers_NumberOfSegments::SetTableFunction(const std::vector<double>& ta
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];
@ -198,7 +208,10 @@ void StdMeshers_NumberOfSegments::SetTableFunction(const std::vector<double>& ta
prev = par;
}
if (!isSame)
if( !pos )
throw SALOME_Exception(LOCALIZED("value of table function is not positive"));
if( pos && !isSame )
{
_table = table;
NotifySubMeshesHypothesisModification();
@ -223,23 +236,24 @@ const std::vector<double>& StdMeshers_NumberOfSegments::GetTableFunction() const
/*! 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;
}
@ -249,25 +263,66 @@ bool isCorrect( const Handle( Expr_GeneralExpression )& expr )
* ( 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 = isCorrectArg( myExpr->Expression() );
}
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++ )
{
syntax = true;
args = isCorrect( gen->Expression() );
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();
}
catch (Standard_Failure)
{
}
return res && non_neg && ( !singulars );
}
//================================================================================
@ -289,15 +344,31 @@ void StdMeshers_NumberOfSegments::SetExpressionFunction(const char* expr)
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();

View File

@ -126,7 +126,7 @@ public:
*
* Throws SALOME_Exception if distribution type is not DT_ExprFunc
*/
void SetExpressionFunction(const char* expr)
void SetExpressionFunction( const char* expr)
throw (SALOME_Exception);
/*!

View File

@ -64,6 +64,12 @@ using namespace std;
#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>
@ -260,247 +266,333 @@ static void compensateError(double a1, double an,
}
}
/*!
* \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 )
{
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;
myFunc = f;
myStart = st;
}
TabFunction::TabFunction(const vector<double>& table, bool expMode)
: Function(expMode),
_table(table)
FunctionIntegral::~FunctionIntegral()
{
}
bool TabFunction::IsReady() const
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:
FunctionTable( const std::vector<double>&, const bool );
virtual ~FunctionTable();
virtual bool value( const double, double& );
virtual double integral( const double, const double );
private:
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;
};
FunctionTable::FunctionTable( const std::vector<double>& data, const bool exp )
: Function( exp )
{
myData = data;
}
FunctionTable::~FunctionTable()
{
}
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)
if( i>=0 && i<myData.size()-1 )
return integral( i, myData[2*(i+1)]-myData[2*i] );
else
return 0;
}
double FunctionTable::integral( const int i, const double d )
{
double f, res = 0.0;
if( value( myData[2*i]+d, f ) )
res = ( myData[2*i] + f ) / 2.0 * d;
return res;
}
double FunctionTable::integral( const double a, const double b )
{
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;
}
bool FunctionTable::findBounds( const double x, int& x_ind_1, int& x_ind_2 ) const
{
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;
}
class FunctionExpr : public Function, public math_Function
{
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" );
}
FunctionExpr::~FunctionExpr()
{
}
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( myExpr.IsNull() )
return false;
CASCatch_CatchSignals aCatchSignals;
aCatchSignals.Activate();
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
{
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;
}
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 );
if( !ok1 || !ok2 )
{
ok = false;
return 0.0;
}
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;
// char buf[1024];
// sprintf( buf, "start=%f\nfin=%f\nmid_val=%f\n", float( start ), float( fin ), float( mid_val ) );
// MESSAGE( buf );
bool mid_pos = mid_val>=val;
if( start_pos!=mid_pos )
{
fin_pos = mid_pos;
fin = mid;
}
else if( fin_pos!=mid_pos )
{
start_pos = mid_pos;
start = mid;
}
else
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");
}
return (start+fin)/2.0;
}
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,
int nbSeg, Function& func,
list<double>& theParams)
{
if (!func.IsReady())
OSD::SetSignal( true );
if( nbSeg<=0 )
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 #########
MESSAGE( "computeParamByFunc" );
vector<double> xxx[2];
int nbPnt = 1 + nbSeg;
int rev, i;
for (rev=0; rev < 2; rev++)
vector<double> x(nbPnt, 0.);
x[0] = 0.0;
double J = func.integral( 0.0, 1.0 ) / nbSeg;
bool ok;
for( int i=1; i<nbSeg; i++ )
{
// curv abscisses initialisation
vector<double> 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;
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;
// 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;
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;
}
// average
vector<double> x(nbPnt, 0.);
for (i=0; i < nbPnt; i++)
x[i] = (xxx[0][i] + (1.0 - xxx[1][nbPnt-i])) / 2;
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;
@ -510,7 +602,7 @@ static bool computeParamByFunc(Adaptor3d_Curve& C3d, double first, double last,
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 );
@ -581,7 +673,7 @@ bool StdMeshers_Regular_1D::computeInternalParameters(const TopoDS_Edge& theEdge
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);
@ -589,7 +681,7 @@ bool StdMeshers_Regular_1D::computeInternalParameters(const TopoDS_Edge& theEdge
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);

View File

@ -71,7 +71,8 @@ LIB_SERVER_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)
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

View File

@ -34,6 +34,7 @@
#include "SMESHGUI_Hypotheses.h"
#include "SMESHGUI_HypothesesUtils.h"
#include "SMESHGUI_Utils.h"
#include "SMESHGUI_FunctionPreview.h"
#include "SUIT_Application.h"
#include "SUIT_Desktop.h"
@ -133,7 +134,8 @@ void StdMeshersGUI_CreateHypothesisDlg::CreateDlgLayout(const QString & theCapti
/* 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" );
@ -147,7 +149,7 @@ void StdMeshersGUI_CreateHypothesisDlg::CreateDlgLayout(const QString & theCapti
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 );
@ -160,6 +162,8 @@ void StdMeshersGUI_CreateHypothesisDlg::CreateDlgLayout(const QString & theCapti
myParamMap.insert( param, info );
}
}
myPreview = new SMESHGUI_FunctionPreview( GroupC1 );
GroupC1Layout->addWidget( myPreview, row, 1 );
StdMeshersGUI_CreateHypothesisDlgLayout->addWidget( GroupC1, 1 );
@ -284,7 +288,8 @@ bool StdMeshersGUI_CreateHypothesisDlg::ClickOnApply()
break;
}
SetParameters( Hyp, aParamList );
if( !SetParameters( Hyp, aParamList ) )
return false;
//set new Attribute Comment for hypothesis which parameters were set
QString aParams = "";
@ -394,7 +399,29 @@ void StdMeshersGUI_CreateHypothesisDlg::onValueChanged()
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;
}
@ -426,10 +453,18 @@ void StdMeshersGUI_CreateHypothesisDlg::UpdateShown( const SMESHGUI_aParameterPt
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 );
}

View File

@ -46,6 +46,7 @@ class QLineEdit;
class QPushButton;
class SMESHGUI;
class SMESHGUI_SpinBox;
class SMESHGUI_FunctionPreview;
//=================================================================================
// class : StdMeshersGUI_CreateHypothesisDlg
@ -108,6 +109,7 @@ private:
QPushButton* buttonOk;
QPushButton* buttonApply;
QPushButton* buttonCancel;
SMESHGUI_FunctionPreview* myPreview;
private slots:

View File

@ -134,8 +134,8 @@ void StdMeshersGUI_Parameters::SetInitValue( SMESHGUI_aParameterPtr param,
#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 )
@ -183,7 +183,7 @@ void StdMeshersGUI_Parameters::GetParameters (const QString& hyp
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
@ -198,10 +198,10 @@ void StdMeshersGUI_Parameters::GetParameters (const QString& hyp
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)
{
@ -291,7 +291,7 @@ void StdMeshersGUI_Parameters::GetParameters (SMESH::SMESH_Hypothesis_ptr the
{
char* expr_func = NOS->GetExpressionFunction();
SetInitValue( *anIt, expr_func );
delete expr_func;
//delete expr_func;
}
anIt++;