-// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2014 CEA/DEN, EDF R&D, OPEN CASCADE
//
// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
-// version 2.1 of the License.
+// version 2.1 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// SMESH includes
#include "StdMeshersGUI_CartesianParamCreator.h"
-#include <SMESHGUI.h>
-#include <SMESHGUI_Utils.h>
-#include <SMESHGUI_HypothesesUtils.h>
-#include <SMESHGUI_SpinBox.h>
+#include "SMESHGUI.h"
+#include "SMESHGUI_Utils.h"
+#include "SMESHGUI_VTKUtils.h"
+#include "SMESHGUI_HypothesesUtils.h"
+#include "SMESHGUI_SpinBox.h"
+#include "SMESHGUI_MeshEditPreview.h"
// IDL includes
#include CORBA_SERVER_HEADER(SMESH_BasicHypothesis)
// SALOME GUI includes
-#include <SalomeApp_Tools.h>
-#include <SalomeApp_IntSpinBox.h>
+#include <LightApp_SelectionMgr.h>
#include <QtxComboBox.h>
+#include <SALOME_InteractiveObject.hxx>
+#include <SALOME_ListIO.hxx>
+#include <SALOME_ListIteratorOfListIO.hxx>
+#include <SUIT_ResourceMgr.h>
+#include <SalomeApp_IntSpinBox.h>
+#include <SalomeApp_Tools.h>
+
+#include <GEOMBase.h>
+
+#include <BRepBndLib.hxx>
+#include <Bnd_Box.hxx>
+#include <TopoDS_Iterator.hxx>
+#include <TopoDS_Shape.hxx>
+#include <gp_Pnt.hxx>
// Qt includes
#include <QAbstractItemModel>
#include <QApplication>
#include <QButtonGroup>
+#include <QCheckBox>
#include <QGridLayout>
#include <QGroupBox>
#include <QHBoxLayout>
#include <QLineEdit>
#include <QListWidget>
#include <QModelIndex>
+#include <QPushButton>
#include <QRadioButton>
#include <QString>
#include <QStyleOptionViewItem>
+#include <QTabWidget>
#include <QTreeWidget>
#include <QTreeWidgetItem>
#include <QVBoxLayout>
-#include <QPushButton>
-#include <QTabWidget>
#define SPACING 6
#define MARGIN 11
myStepSpin->SetValue( myStep = 1. );
// 3) Coodrinates/Spacing group
- QFrame* csFrame = new QFrame( this );
+ QFrame* csFrame = new QFrame( this );
QVBoxLayout* scLay = new QVBoxLayout( csFrame );
scLay->setMargin( 0 );
scLay->setSpacing( SPACING );
connect( myInsertBtn, SIGNAL( clicked() ), SLOT( onInsert() ));
connect( myDeleteBtn, SIGNAL( clicked() ), SLOT( onDelete() ));
connect( myModeGroup, SIGNAL( buttonClicked ( int )), SLOT( onMode(int)));
+ connect( myModeGroup, SIGNAL( buttonClicked ( int )), SIGNAL( gridModeChanged(int)));
connect( mySpacingTreeWdg, SIGNAL( itemSelectionChanged()), SLOT( updateButtons() ));
connect( myCoordList, SIGNAL( itemSelectionChanged()), SLOT( updateButtons() ));
connect( myStepSpin, SIGNAL( valueChanged(double)), SLOT( onStepChange() ));
}
+ //================================================================================
+ /*!
+ * \brief SLOT onInsert
+ */
+ //================================================================================
+
void GridAxisTab::onInsert()
{
if ( isGridBySpacing() )
updateButtons();
}
+ //================================================================================
+ /*!
+ * \brief SLOT onDelete
+ */
+ //================================================================================
+
void GridAxisTab::onDelete()
{
if ( isGridBySpacing() )
updateButtons();
}
+ //================================================================================
+ /*!
+ * \brief SLOT onMode
+ */
+ //================================================================================
+
void GridAxisTab::onMode(int isSpacing)
{
mySpacingTreeWdg->setShown( isSpacing );
updateButtons();
}
+ //================================================================================
+ /*!
+ * \brief SLOT onStepChange
+ */
+ //================================================================================
+
void GridAxisTab::onStepChange()
{
if ( fabs( myStepSpin->GetValue() ) < 1e-100 )
myStep = myStepSpin->GetValue();
}
+ //================================================================================
+ /*!
+ * \brief Enables/disables buttons
+ */
+ //================================================================================
+
void GridAxisTab::updateButtons()
{
bool insertEnable = false, deleteEnable = false;
myDeleteBtn->setEnabled( deleteEnable );
}
+ //================================================================================
+ /*!
+ * \brief Inserts coordinates into myCoordList
+ */
+ //================================================================================
+
void GridAxisTab::setCoordinates( SMESH::double_array_var coords )
{
myCoordList->clear();
onMode( COORD_BUT );
}
+ //================================================================================
+ /*!
+ * \brief Sets spacing got from hypothesis
+ */
+ //================================================================================
+
void GridAxisTab::setSpacing( SMESH::string_array_var funs, SMESH::double_array_var points )
{
mySpacingTreeWdg->clear();
onMode( SPACING_BUT );
}
+ //================================================================================
+ /*!
+ * \brief Checks grid definintion mode
+ */
+ //================================================================================
+
bool GridAxisTab::isGridBySpacing() const
{
return ( myModeGroup->checkedId() == SPACING_BUT );
}
+ //================================================================================
+ /*!
+ * \brief Returns coordinates to set to a hypothesis
+ */
+ //================================================================================
+
SMESH::double_array* GridAxisTab::getCoordinates()
{
SMESH::double_array_var coords = new SMESH::double_array;
return coords._retn();
}
+ //================================================================================
+ /*!
+ * \brief Returms spacing to set to a hypothesis
+ */
+ //================================================================================
+
void GridAxisTab::getSpacing(SMESH::string_array_out funs,
SMESH::double_array_out points) const
{
}
+ //================================================================================
+ /*!
+ * \brief Verifies parameters
+ */
+ //================================================================================
+
bool GridAxisTab::checkParams(QString& msg, SMESH::SMESH_Hypothesis_var& hyp) const
{
if ( isGridBySpacing() )
return true;
}
+ //================================================================================
+ /*!
+ * \brief LineDelegate constructor
+ */
+ //================================================================================
+
LineDelegate::LineDelegate( QWidget* parent ):
QItemDelegate( parent ),
mySpacingTreeWdg( qobject_cast<QTreeWidget*>( parent )),
{
}
+ //================================================================================
+ /*!
+ * \brief Creates an editor depending on a current item
+ */
+ //================================================================================
+
QWidget* LineDelegate::createEditor( QWidget* parent,
const QStyleOptionViewItem& opt,
const QModelIndex& index) const
return w;
}
+ //================================================================================
+ /*!
+ * \brief Limit value range in the spin of a neighbor range
+ */
+ //================================================================================
+
void LineDelegate::setEditorData ( QWidget * editor, const QModelIndex & index ) const
{
if ( mySpacingTreeWdg && index.column() == 0 )
QItemDelegate::setEditorData( editor, index );
}
}
+
+ //================================================================================
+ /*!
+ * \brief
+ */
+ //================================================================================
+
void LineDelegate::setModelData( QWidget* editor,
QAbstractItemModel* model,
const QModelIndex& index ) const
} // namespace StdMeshersGUI
+namespace
+{
+ const double theAngTol = M_PI / 180.;
+
+ //================================================================================
+ /*!
+ * \brief Set variables to groups of spin boxes
+ */
+ //================================================================================
+
+ void setText( const QString& vars, SMESHGUI_SpinBox** spins )
+ {
+ QStringList varList = vars.split( ':' );
+ for ( int i = 0; i < 3 && i < varList.count(); ++i )
+ if ( !varList[i].isEmpty() )
+ spins[i]->setText( varList[i] );
+ }
+
+ //================================================================================
+ /*!
+ * \brief Computes more 2 axes by one
+ * \param [in] iOk - index of a given axis
+ * \param [in,out] dirs - directions of 3 axes
+ */
+ //================================================================================
+
+ void get3Dirs( int iOk, gp_XYZ dirs[3] )
+ {
+ dirs[ ( iOk+1 ) % 3 ] = dirs[ iOk ];
+
+ if ( Abs( dirs[ iOk ].Y() ) < 1e-100 &&
+ Abs( dirs[ iOk ].Z() ) < 1e-100 )
+ // dirs[ iOk ] || OX
+ dirs[ ( iOk+1 ) % 3 ].SetY( dirs[ iOk ].Y() + 1. );
+ else
+ dirs[ ( iOk+1 ) % 3 ].SetX( dirs[ iOk ].X() + 1. );
+
+ dirs[( iOk+2 ) % 3] = dirs[ iOk ] ^ dirs[ ( iOk+1 ) % 3 ];
+ dirs[( iOk+1 ) % 3] = dirs[ ( iOk+2 ) % 3 ] ^ dirs[ iOk ];
+ }
+}
+
+//================================================================================
+/*!
+ * \brief StdMeshersGUI_CartesianParamCreator constructor
+ */
+//================================================================================
StdMeshersGUI_CartesianParamCreator::StdMeshersGUI_CartesianParamCreator(const QString& aHypType)
: StdMeshersGUI_StdHypothesisCreator( aHypType ),
myAxisTabs[0] = 0;
myAxisTabs[1] = 0;
myAxisTabs[2] = 0;
+
+ myAxesPreview = new SMESHGUI_MeshEditPreview( SMESH::GetViewWindow( SMESHGUI::GetSMESHGUI() ));
+ myAxesPreview->SetArrowShapeAndNb( /*nbArrows=*/3,
+ /*headLength=*/0.1,
+ /*headRadius=*/0.01,
+ /*start=*/0.,
+ /*labels=*/"XYZ");
+
+ myDirTic[0] = myDirTic[1] = myDirTic[2] = 0;
}
+//================================================================================
+/*!
+ * \brief StdMeshersGUI_CartesianParamCreator destructor
+ */
+//================================================================================
+
StdMeshersGUI_CartesianParamCreator::~StdMeshersGUI_CartesianParamCreator()
{
if ( myAxisTabs[0] ) delete myAxisTabs[0];
myAxisTabs[0] = 0;
myAxisTabs[1] = 0;
myAxisTabs[2] = 0;
+
+ delete myAxesPreview;
}
+//================================================================================
+/*!
+ * \brief Validate parameters
+ */
+//================================================================================
+
bool StdMeshersGUI_CartesianParamCreator::checkParams( QString& msg ) const
{
if( !SMESHGUI_GenericHypothesisCreator::checkParams( msg ) )
if ( !myAxisTabs[1]->checkParams( msg, hyp )) return false;
if ( !myAxisTabs[2]->checkParams( msg, hyp )) return false;
+ StdMeshersGUI_CartesianParamCreator* me = (StdMeshersGUI_CartesianParamCreator*) this;
+ if ( !me->updateAxesPreview() )
+ {
+ msg = tr("INVALID_AXES_DIR");
+ return false;
+ }
+
return true;
}
+//================================================================================
+/*!
+ * \brief Create widgets
+ */
+//================================================================================
+
QFrame* StdMeshersGUI_CartesianParamCreator::buildFrame()
{
QFrame* fr = new QFrame();
argGroupLayout->addWidget( new QLabel( tr( "THRESHOLD" ), GroupC1 ), row, 0 );
myThreshold = new SMESHGUI_SpinBox( GroupC1 );
myThreshold->setAcceptNames( false ); // No Notebook variables allowed
- myThreshold->RangeStepAndValidator( 1.1, 1e+10, 1., "length_precision" );
+ myThreshold->RangeStepAndValidator( 1.00001, 1e+10, 1., "length_precision" );
argGroupLayout->addWidget( myThreshold, row, 1 );
row++;
- // 2) Grid definition
+ // 2) "Implement edges"
+ myAddEdges = new QCheckBox( tr("ADD_EDGES"), GroupC1 );
+ argGroupLayout->addWidget( myAddEdges, row, 0, 1, 2 );
+ row++;
+
+ // 3) Grid definition
QTabWidget* tabWdg = new QTabWidget( fr );
myAxisTabs[ 0 ] = new StdMeshersGUI::GridAxisTab( tabWdg, 0 );
myAxisTabs[ 1 ] = new StdMeshersGUI::GridAxisTab( tabWdg, 1 );
tabWdg->addTab( myAxisTabs[ 1 ], tr( "AXIS_Y" ) );
tabWdg->addTab( myAxisTabs[ 2 ], tr( "AXIS_Z" ) );
argGroupLayout->addWidget( tabWdg, row, 0, 1, 2 );
+ row++;
+
+ QPixmap aPix = SMESHGUI::resourceMgr()->loadPixmap("SMESH", tr("ICON_SELECT"));
+
+ // 4) Fixed point
+ myFixedPointGrp = new QGroupBox( tr("FIXED_POINT"), fr );
+ myFixedPointGrp->setCheckable( true );
+ //QPushButton* pointBtn = new QPushButton( QIcon(aPix), "", myFixedPointGrp );
+ QLabel* pXLbl = new QLabel( tr("SMESH_X"), myFixedPointGrp );
+ QLabel* pYLbl = new QLabel( tr("SMESH_Y"), myFixedPointGrp );
+ QLabel* pZLbl = new QLabel( tr("SMESH_Z"), myFixedPointGrp );
+ for ( int i = 0; i < 3; ++i )
+ {
+ myPointSpin[i] = new SMESHGUI_SpinBox( myFixedPointGrp );
+ myPointSpin[i]->RangeStepAndValidator( -1e20, 1e20, 10 );
+ myPointSpin[i]->SetValue( 0. );
+ }
+ QHBoxLayout* aFixedPointLay = new QHBoxLayout( myFixedPointGrp );
+ aFixedPointLay->addWidget( pXLbl, 0, Qt::AlignRight );
+ aFixedPointLay->addWidget( myPointSpin[0], 1 );
+ aFixedPointLay->addWidget( pYLbl, 0, Qt::AlignRight );
+ aFixedPointLay->addWidget( myPointSpin[1], 1 );
+ aFixedPointLay->addWidget( pZLbl, 0, Qt::AlignRight );
+ aFixedPointLay->addWidget( myPointSpin[2], 1 );
+ argGroupLayout->addWidget( myFixedPointGrp, row, 0, 1, 2 );
+ row++;
+
+ // 5) Axes direction
+ QGroupBox* axesDirGrp = new QGroupBox( tr("AXES_DIRECTION"), fr );
+ QGridLayout* axisDirLay = new QGridLayout( axesDirGrp );
+ axisDirLay->setSpacing( SPACING );
+ axisDirLay->setMargin( MARGIN );
+ axisDirLay->setColumnStretch( 0, 2 );
+ // is orthogonal
+ myOrthogonalChk = new QCheckBox( tr("ORTHOGONAL_AXES"), axesDirGrp );
+ axisDirLay->addWidget( myOrthogonalChk, 0, 0, 1, 7 );
+ // axes
+ QLabel* axisLbl[3];
+ axisLbl[0] = new QLabel( tr( "AXIS_X"), axesDirGrp );
+ axisLbl[1] = new QLabel( tr( "AXIS_Y"), axesDirGrp );
+ axisLbl[2] = new QLabel( tr( "AXIS_Z"), axesDirGrp );
+ QLabel* dLbl[3];
+ myAxisBtnGrp = new QButtonGroup( axesDirGrp );
+ SMESHGUI_SpinBox** spins[3] = { &myXDirSpin[0], &myYDirSpin[0], &myZDirSpin[0] };
+ for ( int i = 0; i < 3; ++i )
+ {
+ QPushButton* axisBtn = new QPushButton( QIcon(aPix), "", axesDirGrp );
+ axisBtn->setCheckable( true );
+ myAxisBtnGrp->addButton( axisBtn, i );
+ myXDirSpin[i] = new SMESHGUI_SpinBox( axesDirGrp );
+ myYDirSpin[i] = new SMESHGUI_SpinBox( axesDirGrp );
+ myZDirSpin[i] = new SMESHGUI_SpinBox( axesDirGrp );
+ myXDirSpin[i]->RangeStepAndValidator( -1, 1, 0.1, "len_tol_precision" );
+ myYDirSpin[i]->RangeStepAndValidator( -1, 1, 0.1, "len_tol_precision" );
+ myZDirSpin[i]->RangeStepAndValidator( -1, 1, 0.1, "len_tol_precision" );
+ dLbl[0] = new QLabel( tr("SMESH_DX"), axesDirGrp );
+ dLbl[1] = new QLabel( tr("SMESH_DY"), axesDirGrp );
+ dLbl[2] = new QLabel( tr("SMESH_DZ"), axesDirGrp );
+ axisDirLay->addWidget( axisLbl[i], i+1, 0 );
+ axisDirLay->addWidget( axisBtn, i+1, 1 );
+ axisDirLay->addWidget( dLbl[0], i+1, 2 );
+ axisDirLay->addWidget( dLbl[1], i+1, 4 );
+ axisDirLay->addWidget( dLbl[2], i+1, 6 );
+ axisDirLay->addWidget( myXDirSpin[i], 1, 3+i*2 );
+ axisDirLay->addWidget( myYDirSpin[i], 2, 3+i*2 );
+ axisDirLay->addWidget( myZDirSpin[i], 3, 3+i*2 );
+ }
+ axisDirLay->setColumnStretch( 3, 10 );
+ axisDirLay->setColumnStretch( 5, 10 );
+ axisDirLay->setColumnStretch( 7, 10 );
+
+ // set optimal axes
+ QPushButton* optimBtn = new QPushButton( tr("OPTIMAL_AXES"), axesDirGrp );
+ QPushButton* resetBtn = new QPushButton( tr("RESET_AXES"), axesDirGrp );
+ axisDirLay->addWidget( optimBtn, 4, 0, 1, 4 );
+ axisDirLay->addWidget( resetBtn, 4, 4, 1, 4 );
+
+ argGroupLayout->addWidget( axesDirGrp, row, 0, 1, 2 );
+ row++;
+
+ // Signals
+
+ LightApp_SelectionMgr* selMgr = SMESH::GetSelectionMgr( SMESHGUI::GetSMESHGUI() );
+
+ connect( selMgr, SIGNAL( currentSelectionChanged()), SLOT( onSelectionChange()));
+ connect( myOrthogonalChk, SIGNAL( toggled(bool)), SLOT( onOrthogonalAxes(bool)));
+ connect( optimBtn, SIGNAL( clicked(bool)), SLOT( onOptimalAxes(bool)));
+ connect( resetBtn, SIGNAL( clicked(bool)), SLOT( onResetAxes(bool)));
+ for ( int i = 0; i < 3; ++i )
+ {
+ connect( myXDirSpin[i], SIGNAL(valueChanged (const QString&)),
+ this, SLOT (onAxisDirChange(const QString&)) );
+ connect( myYDirSpin[i], SIGNAL(valueChanged (const QString&)),
+ this, SLOT (onAxisDirChange(const QString&)) );
+ connect( myZDirSpin[i], SIGNAL(valueChanged (const QString&)),
+ this, SLOT (onAxisDirChange(const QString&)) );
+ connect( myAxisTabs[i], SIGNAL(gridModeChanged(int)),
+ this, SLOT (onGridModeChanged(int)));
+ }
+
+ // Show axes
+ myAxesLen = 120; // default trihedron size is 100
+ myOrigin[0] = myOrigin[1] = myOrigin[2] = 0.;
+ TopoDS_Shape shape;
+ QString shapeEntry = getMainShapeEntry();
+ if ( !shapeEntry.isEmpty() )
+ {
+ // find origin
+ Handle(SALOME_InteractiveObject) io =
+ new SALOME_InteractiveObject( shapeEntry.toStdString().c_str(), "GEOM" );
+ GEOM::GEOM_Object_var geomObj = SMESH::IObjectToInterface<GEOM::GEOM_Object>( io );
+ if ( GEOMBase::GetShape( geomObj, shape ) && !shape.IsNull())
+ {
+ Bnd_Box box;
+ BRepBndLib::Add( shape, box );
+ double max[3];
+ if ( !box.IsVoid() )
+ {
+ box.Get( myOrigin[0], myOrigin[1], myOrigin[2], max[0], max[1], max[2] );
+ gp_Pnt o( myOrigin[0], myOrigin[1], myOrigin[2] );
+ gp_Pnt x( max[0], max[1], max[2] );
+ myAxesLen = o.Distance( x );
+
+ double step = 1e20;
+ while ( step > myAxesLen / 5 )
+ step /= 10;
+ myPointSpin[0]->SetStep( step );
+ myPointSpin[1]->SetStep( step );
+ myPointSpin[2]->SetStep( step );
+ }
+ }
+ }
+ myAxisBtnGrp->button(0)->setEnabled( !shape.IsNull() );
+ myAxisBtnGrp->button(1)->setEnabled( !shape.IsNull() );
+ myAxisBtnGrp->button(2)->setEnabled( !shape.IsNull() );
+ optimBtn->setEnabled( !shape.IsNull() );
+
+ updateAxesPreview();
return fr;
}
+//================================================================================
+/*!
+ * \brief Tranfer parameters from hypothesis to widgets
+ */
+//================================================================================
+
void StdMeshersGUI_CartesianParamCreator::retrieveParams() const
{
StdMeshers::StdMeshers_CartesianParameters3D_var h =
else
myThreshold->setText( varName );
+ myAddEdges->setChecked( h->GetToAddEdges() );
+
+ // grid definition
for ( int ax = 0; ax < 3; ++ax )
{
if ( h->IsGridBySpacing( ax ))
myAxisTabs[ax]->setCoordinates( coords );
}
}
+
+ // fixed point
+ SMESH::PointStruct fp;
+ StdMeshersGUI_CartesianParamCreator* me = (StdMeshersGUI_CartesianParamCreator*) this;
+ if ( h->GetFixedPoint( fp ))
+ {
+ me->myPointSpin[0]->SetValue( fp.x );
+ me->myPointSpin[1]->SetValue( fp.y );
+ me->myPointSpin[2]->SetValue( fp.z );
+ setText( getVariableName("GetFixedPoint"), &me->myPointSpin[0] );
+ myFixedPointGrp->setChecked( true );
+ }
+ else
+ {
+ myFixedPointGrp->setChecked( false );
+ }
+
+ // axes directions
+ SMESHGUI_SpinBox** spins[3] = { &me->myXDirSpin[0], &me->myYDirSpin[0], &me->myZDirSpin[0] };
+ SMESH::DirStruct axisDir[3];
+ h->GetAxesDirs( axisDir[0],
+ axisDir[1],
+ axisDir[2]);
+ QString vars = getVariableName("GetAxesDirs");
+ for ( int i = 0; i < 3; ++i )
+ {
+ spins[i][0]->SetValue( axisDir[i].PS.x );
+ spins[i][1]->SetValue( axisDir[i].PS.y );
+ spins[i][2]->SetValue( axisDir[i].PS.z );
+ setText( vars, spins[i] );
+
+ // cut off 3 used vars
+ if ( !vars.isEmpty() )
+ {
+ int ind = -1;
+ for ( int j = 0; j < 3; ++j )
+ if (( ind = vars.indexOf(':', ind+1 )) < 0 )
+ break;
+ if ( ind < 0 )
+ vars.clear();
+ else
+ vars.remove( 0, ind+1 );
+ }
+ }
+
if ( dlg() )
- dlg()->setMinimumSize( dlg()->minimumSizeHint().width(), dlg()->minimumSizeHint().height() );
+ dlg()->setMinimumSize( dlg()->minimumSizeHint().width(),
+ dlg()->minimumSizeHint().height() );
}
+//================================================================================
+/*!
+ * \brief Tranfer parameters from widgets to hypothesis
+ */
+//================================================================================
+
QString StdMeshersGUI_CartesianParamCreator::storeParams() const
{
StdMeshers::StdMeshers_CartesianParameters3D_var h =
if( isCreation() )
SMESH::SetName( SMESH::FindSObject( h ), myName->text().toLatin1().constData() );
+ // threshold
h->SetVarParameter( myThreshold->text().toLatin1().constData(), "SetSizeThreshold" );
h->SetSizeThreshold( myThreshold->text().toDouble() );
+ h->SetToAddEdges( myAddEdges->isChecked() );
+ // grid
for ( int ax = 0; ax < 3; ++ax )
{
if ( myAxisTabs[ax]->isGridBySpacing())
h->SetGrid( coords, ax );
}
}
+
+ // fixed point
+ QStringList params;
+ params << myPointSpin[0]->text();
+ params << myPointSpin[1]->text();
+ params << myPointSpin[2]->text();
+ h->SetVarParameter( params.join(":").toLatin1().constData(), "SetFixedPoint" );
+ params.clear();
+
+ SMESH::PointStruct ps;
+ ps.x = myPointSpin[0]->GetValue();
+ ps.y = myPointSpin[1]->GetValue();
+ ps.z = myPointSpin[2]->GetValue();
+ h->SetFixedPoint( ps, !myFixedPointGrp->isEnabled() || !myFixedPointGrp->isChecked() );
+
+ // axes directions
+ SMESHGUI_SpinBox* const * spins[3] = { &myXDirSpin[0], &myYDirSpin[0], &myZDirSpin[0] };
+ for ( int ax = 0; ax < 3; ++ax )
+ {
+ params << spins[ax][0]->text();
+ params << spins[ax][1]->text();
+ params << spins[ax][2]->text();
+ }
+ h->SetVarParameter( params.join(":").toLatin1().constData(), "SetAxesDirs" );
+
+ SMESH::DirStruct axDir[3];
+ for ( int ax = 0; ax < 3; ++ax )
+ {
+ axDir[ax].PS.x = spins[ax][0]->GetValue();
+ axDir[ax].PS.y = spins[ax][1]->GetValue();
+ axDir[ax].PS.z = spins[ax][2]->GetValue();
+ }
+ h->SetAxesDirs( axDir[0], axDir[1], axDir[2] );
+
}
catch(const SALOME::SALOME_Exception& ex)
{
return "";
}
+//================================================================================
+/*!
+ * \brief Returns a name of help page
+ */
+//================================================================================
+
QString StdMeshersGUI_CartesianParamCreator::helpPage() const
{
return "cartesian_algo_page.html#cartesian_hyp_anchor";
}
+
+//================================================================================
+/*!
+ * \brief Show axes if they are OK
+ */
+//================================================================================
+
+bool StdMeshersGUI_CartesianParamCreator::updateAxesPreview()
+{
+ bool isOk = true;
+ gp_Ax1 axes[3];
+ SMESHGUI_SpinBox** spins[3] = { &myXDirSpin[0], &myYDirSpin[0], &myZDirSpin[0] };
+ for ( int i = 0; i < 3 && isOk; ++i )
+ {
+ gp_XYZ dir( spins[i][0]->GetValue(),
+ spins[i][1]->GetValue(),
+ spins[i][2]->GetValue());
+ if (( isOk = ( dir.Modulus() > 1e-100 )))
+ axes[i].SetDirection( gp_Dir( dir ));
+
+ axes[i].SetLocation ( gp_Pnt( myOrigin[0],
+ myOrigin[1],
+ myOrigin[2]));
+ }
+ gp_Vec norm01 = axes[0].Direction().XYZ() ^ axes[1].Direction().XYZ();
+ gp_Vec norm12 = axes[1].Direction().XYZ() ^ axes[2].Direction().XYZ();
+ if ( isOk )
+ isOk = ( !axes[0].Direction().IsParallel( axes[1].Direction(), theAngTol ) &&
+ !axes[1].Direction().IsParallel( axes[2].Direction(), theAngTol ) &&
+ !axes[2].Direction().IsParallel( axes[0].Direction(), theAngTol ) &&
+ !norm01.IsParallel( norm12, theAngTol ) );
+ if ( isOk )
+ myAxesPreview->SetArrows( axes, myAxesLen );
+
+ myAxesPreview->SetVisibility( isOk );
+
+ return isOk;
+}
+
+//================================================================================
+/*!
+ * \brief Makes axes orthogonal if necessary
+ */
+//================================================================================
+
+void StdMeshersGUI_CartesianParamCreator::onOrthogonalAxes(bool isOrtho)
+{
+ if ( !isOrtho )
+ {
+ updateAxesPreview();
+ return;
+ }
+
+ std::multimap< int, int > ageOfAxis;
+ gp_XYZ dirs[3];
+ SMESHGUI_SpinBox** spins[3] = { &myXDirSpin[0], &myYDirSpin[0], &myZDirSpin[0] };
+ int nbOk = 0, isOk;
+ for ( int iAx = 0; iAx < 3; ++iAx )
+ {
+ dirs[iAx].SetCoord( spins[iAx][0]->GetValue(),
+ spins[iAx][1]->GetValue(),
+ spins[iAx][2]->GetValue());
+ if (( isOk = ( dirs[iAx].Modulus() > 1e-100 )))
+ ageOfAxis.insert( std::make_pair( myDirTic[iAx], iAx ));
+ else
+ ageOfAxis.insert( std::make_pair( -1, iAx ));
+ nbOk += isOk;
+ }
+ switch ( nbOk )
+ {
+ case 0:
+ {
+ dirs[0].SetCoord( 1, 0, 0 );
+ dirs[1].SetCoord( 0, 1, 0 );
+ dirs[2].SetCoord( 0, 0, 1 );
+ break;
+ }
+ case 1:
+ {
+ int iOk = ageOfAxis.rbegin()->second;
+ get3Dirs( iOk, dirs );
+ break;
+ }
+ default:
+ std::multimap< int, int >::reverse_iterator ag2ax = ageOfAxis.rbegin();
+ int iOk1 = ag2ax->second;
+ int iOk2 = (++ag2ax)->second;
+ int iKo = (++ag2ax)->second;
+ if ( gp_Vec( dirs[ iOk1 ]).IsParallel( gp_Vec( dirs[ iOk2 ]), theAngTol ))
+ std::swap( iOk2, iKo );
+ if ( gp_Vec( dirs[ iOk1 ]).IsParallel( gp_Vec( dirs[ iOk2 ]), theAngTol ))
+ {
+ get3Dirs( iOk1, dirs );
+ }
+ else
+ {
+ dirs[ iKo ] = dirs[ iOk1 ] ^ dirs[ iOk2 ];
+ dirs[ iOk2 ] = dirs[ iKo ] ^ dirs[ iOk1 ];
+ if ( ( iOk1+1 ) % 3 != iOk2 )
+ dirs[ iKo ].Reverse();
+ }
+ }
+
+ for ( int iAx = 0; iAx < 3; ++iAx )
+ {
+ double size = dirs[iAx].Modulus();
+ if ( size > 1e-100 )
+ dirs[iAx] /= size;
+ for (int i = 0; i < 3; ++i )
+ {
+ bool isBlocked = spins[iAx][i]->blockSignals( true );
+ spins[iAx][i]->SetValue( dirs[iAx].Coord( i+1 ));
+ spins[iAx][i]->blockSignals( isBlocked );
+ }
+ }
+
+ updateAxesPreview();
+}
+
+//================================================================================
+/*!
+ * \brief Increment myDirTic and update the preview of axes
+ */
+//================================================================================
+
+void StdMeshersGUI_CartesianParamCreator::onAxisDirChange(const QString&)
+{
+ QObject* changedSpin = sender();
+ SMESHGUI_SpinBox** spins[3] = { &myXDirSpin[0], &myYDirSpin[0], &myZDirSpin[0] };
+ for ( int iAx = 0; iAx < 3; ++iAx )
+ if ( spins[iAx][0] == changedSpin ||
+ spins[iAx][1] == changedSpin ||
+ spins[iAx][2] == changedSpin )
+ {
+ myDirTic[ iAx ] = 1 + Max( Max( myDirTic[0], myDirTic[1] ), myDirTic[2] );
+ break;
+ }
+
+ onOrthogonalAxes( myOrthogonalChk->isChecked() );
+}
+
+//================================================================================
+/*!
+ * \brief Sets axis direction by a selected EDGE
+ */
+//================================================================================
+
+void StdMeshersGUI_CartesianParamCreator::onSelectionChange()
+{
+ int iAxis = myAxisBtnGrp->checkedId();
+ if ( iAxis < 0 )
+ return;
+
+ SALOME_ListIO aList;
+ SMESHGUI::GetSMESHGUI()->selectionMgr()->selectedObjects(aList);
+
+ TopoDS_Shape edge, shape;
+ for( SALOME_ListIteratorOfListIO anIt( aList ); anIt.More(); anIt.Next() )
+ {
+ GEOM::GEOM_Object_var go = SMESH::IObjectToInterface<GEOM::GEOM_Object>( anIt.Value() );
+ if ( GEOMBase::GetShape( go, shape ) && shape.ShapeType() == TopAbs_EDGE )
+ {
+ if ( !edge.IsNull() )
+ return; // several EDGEs selected
+ edge = shape;
+ }
+ }
+ if ( edge.IsNull() )
+ return;
+
+ TopoDS_Shape vv[2];
+ TopoDS_Iterator vIt( edge );
+ for ( ; vIt.More() && vv[1].IsNull(); vIt.Next() )
+ vv[ !vv[0].IsNull() ] = vIt.Value();
+
+ gp_Pnt pp[2];
+ if ( !GEOMBase::VertexToPoint( vv[0], pp[0] ) ||
+ !GEOMBase::VertexToPoint( vv[1], pp[1] ))
+ return;
+
+ SMESHGUI_SpinBox** spins[3] = { &myXDirSpin[0], &myYDirSpin[0], &myZDirSpin[0] };
+
+ gp_Vec newDir( pp[0], pp[1] );
+ gp_Vec curDir( spins[iAxis][0]->GetValue(),
+ spins[iAxis][1]->GetValue(),
+ spins[iAxis][2]->GetValue());
+ if ( newDir * curDir < 0 )
+ newDir.Reverse();
+
+ double size = newDir.Magnitude();
+ if ( size < 1e-100 )
+ return;
+ newDir /= size;
+
+ for (int i = 0; i < 3; ++i )
+ {
+ bool isBlocked = spins[iAxis][i]->blockSignals( true );
+ spins[iAxis][i]->SetValue( newDir.Coord( i+1 ));
+ spins[iAxis][i]->blockSignals( isBlocked );
+ }
+ myDirTic[ iAxis ] = 1 + Max( Max( myDirTic[0], myDirTic[1] ), myDirTic[2] );
+
+ onOrthogonalAxes( myOrthogonalChk->isChecked() );
+}
+
+//================================================================================
+/*!
+ * \brief Sets axes at which number of hexahedra is maximal
+ */
+//================================================================================
+
+void StdMeshersGUI_CartesianParamCreator::onOptimalAxes(bool)
+{
+ StdMeshers::StdMeshers_CartesianParameters3D_var h =
+ StdMeshers::StdMeshers_CartesianParameters3D::_narrow( hypothesis() );
+ if ( h->_is_nil() )
+ return;
+
+ QString shapeEntry = getMainShapeEntry();
+ if ( shapeEntry.isEmpty() )
+ return;
+
+ Handle(SALOME_InteractiveObject) io =
+ new SALOME_InteractiveObject( shapeEntry.toStdString().c_str(), "GEOM" );
+ GEOM::GEOM_Object_var geomObj = SMESH::IObjectToInterface<GEOM::GEOM_Object>( io );
+ if ( geomObj->_is_nil() )
+ return;
+
+ SMESH::DirStruct axDirs[3];
+ h->ComputeOptimalAxesDirs( geomObj,
+ myOrthogonalChk->isChecked(),
+ axDirs[0],
+ axDirs[1],
+ axDirs[2]);
+
+ SMESHGUI_SpinBox** spins[3] = { &myXDirSpin[0], &myYDirSpin[0], &myZDirSpin[0] };
+ for ( int iAx = 0; iAx < 3; ++iAx )
+ {
+ double coords[3] = { axDirs[iAx].PS.x, axDirs[iAx].PS.y, axDirs[iAx].PS.z };
+ for (int i = 0; i < 3; ++i )
+ {
+ bool isBlocked = spins[iAx][i]->blockSignals( true );
+ spins[iAx][i]->SetValue( coords[ i ]);
+ spins[iAx][i]->blockSignals( isBlocked );
+ }
+ }
+ updateAxesPreview();
+}
+
+//================================================================================
+/*!
+ * \brief Sets axes || to the axes of global CS
+ */
+//================================================================================
+
+void StdMeshersGUI_CartesianParamCreator::onResetAxes(bool)
+{
+ SMESHGUI_SpinBox** spins[3] = { &myXDirSpin[0], &myYDirSpin[0], &myZDirSpin[0] };
+ for ( int iAx = 0; iAx < 3; ++iAx )
+ {
+ for (int i = 0; i < 3; ++i )
+ {
+ bool isBlocked = spins[iAx][i]->blockSignals( true );
+ spins[iAx][i]->SetValue( iAx == i ? 1. : 0. );
+ spins[iAx][i]->blockSignals( isBlocked );
+ }
+ myDirTic[iAx] = 0;
+ }
+ updateAxesPreview();
+}
+
+//================================================================================
+/*!
+ * \brief SLOT called when the grid definintion mode changes
+ */
+//================================================================================
+
+void StdMeshersGUI_CartesianParamCreator::onGridModeChanged(int)
+{
+ bool haveSpacing = ( myAxisTabs[0]->isGridBySpacing() ||
+ myAxisTabs[1]->isGridBySpacing() ||
+ myAxisTabs[2]->isGridBySpacing() );
+
+ myFixedPointGrp->setEnabled( haveSpacing );
+}