From: eap Date: Wed, 9 Oct 2019 12:49:18 +0000 (+0300) Subject: #17784 [EDF] MESH-GEMS-2.9.6 Meshers options X-Git-Tag: V9_4_0b1~2 X-Git-Url: http://git.salome-platform.org/gitweb/?a=commitdiff_plain;h=90dbc5f10c66da5c69987766aaa141585b4f636f;p=plugins%2Fhybridplugin.git #17784 [EDF] MESH-GEMS-2.9.6 Meshers options --- diff --git a/doc/salome/gui/HYBRIDPLUGIN/images/hybrid_hypothesis_advanced.png b/doc/salome/gui/HYBRIDPLUGIN/images/hybrid_hypothesis_advanced.png index 50b6cf4..bde2d19 100644 Binary files a/doc/salome/gui/HYBRIDPLUGIN/images/hybrid_hypothesis_advanced.png and b/doc/salome/gui/HYBRIDPLUGIN/images/hybrid_hypothesis_advanced.png differ diff --git a/doc/salome/gui/HYBRIDPLUGIN/images/hybrid_hypothesis_arguments.png b/doc/salome/gui/HYBRIDPLUGIN/images/hybrid_hypothesis_arguments.png index d6c2c43..4d3c808 100644 Binary files a/doc/salome/gui/HYBRIDPLUGIN/images/hybrid_hypothesis_arguments.png and b/doc/salome/gui/HYBRIDPLUGIN/images/hybrid_hypothesis_arguments.png differ diff --git a/doc/salome/gui/HYBRIDPLUGIN/input/hybrid_hypo.doc b/doc/salome/gui/HYBRIDPLUGIN/input/hybrid_hypo.doc index 71ada99..e3d8180 100644 --- a/doc/salome/gui/HYBRIDPLUGIN/input/hybrid_hypo.doc +++ b/doc/salome/gui/HYBRIDPLUGIN/input/hybrid_hypo.doc @@ -20,10 +20,9 @@ To get a licence, visit http://www.distene.com and http://www.meshgems.com/ $> mg-hybrid.exe --help - - ============================================== - MG-Hybrid -- MeshGems 2.1-11 (September, 2015) - ============================================== + ========================================== + MG-Hybrid -- MeshGems 2.9-6 (August, 2019) + ========================================== Distene SAS Campus Teratec @@ -33,11 +32,11 @@ $> mg-hybrid.exe --help Phone: +33(0)970-650-219 Fax: +33(0)169-269-033 EMail: - Running MG-Hybrid (Copyright 2014-2015 by Distene SAS) - date of run: 26-Jan-2016 AT 12:24:16 - running on : Linux 3.6.10-4.fc18.x86_64 x86_64 + Running MG-Hybrid (Copyright 2014-2019 by Distene SAS) + date of run: 07-Oct-2019 AT 17:40:47 + running on : Linux 3.16.0-4-amd64 x86_64 using modules: - MeshGems-Core 2.1-11 + MeshGems-Core 2.9-6 MeshGems is a Registered Trademark of Distene SAS @@ -45,20 +44,19 @@ $> mg-hybrid.exe --help MG-HYBRID USAGE mg-hybrid.exe [-h] [-v ] [-i ] [-o ] \ - [--global_physical_size ] \ - [--max_number_of_threads ] \ + [--global_physical_size ] [--max_number_of_threads ] \ [--boundary_layer_size_mode ] \ - [--number_of_boundary_layers ] \ - [--boundary_layer_global_initial_height ] \ + [--boundary_layer_height_relative_to_local_surface_size ] \ + [--number_of_boundary_layers ] [--boundary_layer_global_initial_height ] \ [--boundary_layer_surface_tags ] \ [--boundary_layer_initial_height_on_surface_tags ] \ - [--boundary_layer_imprint_tags ] \ [--boundary_layer_geometric_progression ] \ - [--boundary_layer_max_element_angle ] \ - [--normal_direction ] [--gradation ] \ - [--element_generation ] [--collision_mode ] \ - [--add_multinormals ] [--multinormal_angle_threshold ] \ - [--smooth_normals ] [--optimisation ] + [--boundary_layer_max_element_angle ] [--boundary_layer_imprinting ] \ + [--boundary_layer_imprinting_tags ] [--boundary_layer_snapping ] \ + [--boundary_layer_snapping_tags ] [--normal_direction ] [--gradation ] \ + [--element_generation ] [--collision_mode ] [--add_multinormals ] \ + [--multinormal_angle_threshold ] [--smooth_normals ] \ + [--optimisation ] -h --help prints this help. @@ -91,13 +89,15 @@ MG-HYBRID USAGE --boundary_layer_size_mode Sets the behavior for the boundary layer sizes. If is: - global: the boundary_layer_global_initial_height is used to compute - the layer heights + global: the boundary_layer_global_initial_height is used to compute the layer heights local: the boundary_layer_surface_tags and - boundary_layer_initial_height_on_surface_tags are used to compute - the layer heights + boundary_layer_initial_height_on_surface_tags are used to compute the layer heights Default: global + --boundary_layer_height_relative_to_local_surface_size + If set to yes, the given sizes are relative to the surface size + Default: no + --number_of_boundary_layers Sets the number of boundary layers. Default: 0 @@ -106,64 +106,72 @@ MG-HYBRID USAGE Sets the height of the first layer. --boundary_layer_surface_tags - Comma separated list of surface references to be used to grow - boundary layers. + Comma separated list of surface references to be used to grow boundary layers. --boundary_layer_initial_height_on_surface_tags - Comma separated list of initial heights to be used to grow boundary - layers. - - --boundary_layer_imprint_tags - Comma separated list of surface references that are imprinted by - boundary layers. + Comma separated list of initial heights to be used to grow boundary layers. --boundary_layer_geometric_progression - Sets the geometric progression for all the boundary layer growths - (position of layer number i is h * g^(i-1)). + Sets the geometric progression for all the boundary layer growths (position of layer + number i is h * g^(i-1)). Default: 1.0 --boundary_layer_max_element_angle - Sets the maximum internal angles of elements (in degree). This - setting applies to the boundary layer elements only. + Sets the maximum internal angles of elements (in degree). This setting applies to the + boundary layer elements only. Default: 165. + --boundary_layer_imprinting + Activates the imprinting of the boundary layers. The parts of the surface where the + layers have to be imprinted are defined through the option + --boundary_layer_imprinting_tags + Default: no imprinting + + --boundary_layer_imprinting_tags + Comma separated list of surface references that have to be imprinted by boundary layers. + + --boundary_layer_snapping + Activates the snapping of the generated boundary layers on the surface. The parts of the + surface where the layers have to be snapped into are defined through the option + --boundary_layer_snapping_tags + Default: no snapping + + --boundary_layer_snapping_tags + Comma separated list of surface references that are imprinted by boundary layers. + --normal_direction - Specifies whether mg-hybrid should use the surface normals or the - inverse of the surface normals. + Specifies whether mg-hybrid should use the surface normals or the inverse of the surface + normals. if is: - 1 : means the layers grow in the same direction as the normals to - the surface - -1 : means the layers grow in the opposite direction to the normals - of the surface + 1 : means the layers grow in the same direction as the normals to the surface + -1 : means the layers grow in the opposite direction to the normals of the surface Default: 1 --gradation - Sets the desired maximum ratio between 2 adjacent edges. It applies - only to the edges which belong to the tetrahedra. + Sets the desired maximum ratio between 2 adjacent edges. It applies only to the edges + which belong to the tetrahedra. Default: 2.0 --element_generation Sets the element type for the mesh generation. If is: - tetra_dominant : prismatic or hexahedral elements in the boundary - layers, tetrahedra in the remaining volume - hexa_dominant : prismatic or hexahedral elements in the boundary - layers, mixture of hexahedra and tetrahedra in the remaining + tetra_dominant : prismatic or hexahedral elements in the boundary layers, tetrahedra in + the remaining volume + hexa_dominant : prismatic or hexahedral elements in the boundary layers, mixture of + hexahedra and tetrahedra in the remaining volume + cartesian_core : cartesian hexa core with tetrahedra and pyramids in the remaining volume - cartesian_core : cartesian hexa core with tetrahedra and pyramids - in the remaining volume - extrusion_only : only prismatic or hexahedral elements near the - boundary are generated. The remaining volume is not filled. + extrusion_only : only prismatic or hexahedral elements near the boundary are generated. + The remaining volume is not filled. Default: tetra_dominant --collision_mode Sets the behavior in case of collision between layers. If is: - decrease : keeps the number of desired layer but decreases the - height of the layers to avoid any collision - stop : stops locally the generation of layers to avoid collisions; - the number of generated layers may differ from the specified - desired number + decrease : keeps the number of desired layer but decreases the height of the layers to + avoid any collision + stop : stops locally the generation of layers to avoid collisions; the number of + generated layers may differ from the specified desired number Default: stop --add_multinormals @@ -188,9 +196,9 @@ MG-HYBRID USAGE ================================================================================ - MG-Hybrid -- MeshGems 2.1-11 (September, 2015) - END OF SESSION - MG-Hybrid (Copyright 2014-2015 by Distene SAS) - compiled Sep 3 2015 13:52:38 on Linux_64 + MG-Hybrid -- MeshGems 2.9-6 (August, 2019) + END OF SESSION - MG-Hybrid (Copyright 2014-2019 by Distene SAS) + compiled Sep 2 2019 23:42:41 on Linux_64 MeshGems is a Registered Trademark of Distene SAS ================================================================================ ( Distene SAS @@ -205,6 +213,34 @@ MG-HYBRID USAGE \image html hybrid_hypothesis_advanced.png +\subsection advanced_meshing_options Advanced meshing options + +- A table allows to input in the command line any text + for hybrid argument from "mg-hybrid.exe help", and future advanced options...
+Add option - adds a line to the table where you can type an option and its value as text. +A check box in the first column activates/deactivates the option of the current row. A deactivated option will be erased upon pressing \a Ok. + +- Add multi normals - Add extra normals at opening ridges and +corners. + +- Collision mode - Sets the behavior in case of collision between layers. + + - decrease - keeps the number of desired layer but decreases the height of the layers to + avoid any collision + + - stop - stops locally the generation of layers to avoid collisions; the number of + generated layers may differ from the specified desired number + +- Gradation - Sets the desired maximum ratio between 2 adjacent edges. + It applies only to the edges which belong to the tetrahedra. + +- Maximum number of threads - Sets the maximum number of threads to be used in parallel. + +- Multi normal angle threshold - Set the maximum angle (in + degrees) between the multiple normals at opening ridges. + +- Smooth normals - Smooth normals at closed ridges and corners. + \subsection log Logs and debug - Working directory - allows defining the folder for input and output @@ -235,14 +271,6 @@ is enabled (there must be a log file to delete it) and Keep all working files of hybrid software, while usually these files are removed after the launch of the mesher. The log file (if any) is also kept if this option is checked. -\subsection advanced_meshing_options Advanced meshing options - -- A table allows to input in the command line any text -for hybrid argument from "mg-hybrid.exe help", and future advanced options...
-Add option - adds a line to the table where you can type an option and its value as text. -A check box in the first column activates/deactivates the option of the current row. A deactivated option will be erased upon pressing \a Ok. - - \ref hybrid_top "Back to top" \section hybrid_layers_meshes Layers meshes diff --git a/idl/HYBRIDPlugin_Algorithm.idl b/idl/HYBRIDPlugin_Algorithm.idl index 1147a95..4795e91 100644 --- a/idl/HYBRIDPlugin_Algorithm.idl +++ b/idl/HYBRIDPlugin_Algorithm.idl @@ -34,6 +34,8 @@ */ module HYBRIDPlugin { + typedef sequence string_array; + typedef sequence TCoords; struct HYBRIDEnforcedVertex { string name; @@ -68,6 +70,16 @@ module HYBRIDPlugin */ interface HYBRIDPlugin_Hypothesis : SMESH::SMESH_Hypothesis { + /*! + * Sizes of boundary layers are relative to the surface size. Default no + */ + void SetHeightIsRelative( in boolean isRelative ); + boolean GetHeightIsRelative(); + /*! + * Maximum internal angles of boundary elements (in degree) + */ + void SetBoundaryLayersMaxElemAngle( in double angle ); + double GetBoundaryLayersMaxElemAngle(); /*! * To mesh "holes" in a solid or not. Default is to mesh. */ @@ -227,12 +239,38 @@ module HYBRIDPlugin void SetToRemoveCentralPoint(in boolean toRemove); boolean GetToRemoveCentralPoint(); /*! - * To set hiden/undocumented/advanced options + * Set advanced option value + */ + void SetOptionValue(in string optionName, + in string optionValue) raises (SALOME::SALOME_Exception); + string GetOptionValue(in string optionName) raises (SALOME::SALOME_Exception); + void UnsetOption(in string optionName); + /*! + * Adds custom advanced option and its value */ - void SetAdvancedOption( in string optAndVals ); + void SetAdvancedOption(in string optionsAndValues) // in a form "option_1 v1 option_2 v2'" + raises (SALOME::SALOME_Exception); string GetAdvancedOption(); + void AddOption(in string optionName, in string optionValue); + string GetOption(in string optionName); void SetTextOption(in string option); // obsolete - string GetTextOption(); + string GetTextOption(); // obsolete + /*! + * Return array of strings each of which is option name concatenated + * with option value devided by semicolon - "option_name:option_value:option_type". + * Option value is empty if an option is not set. + * option_type: 1 if user-define, 0 if default + * Note: the method is mostly for interaction with GUI. + */ + string_array GetOptionValues(); + string_array GetAdvancedOptionValues(); + /*! + * Set option values each in the form "option_name[:option_value][:option_type]". + * Note: the method is mostly for interaction with GUI. + */ + void SetOptionValues(in string_array options) raises (SALOME::SALOME_Exception); + void SetAdvancedOptionValues(in string_array options); + /*! * To define the volumic gradation */ diff --git a/src/GUI/CMakeLists.txt b/src/GUI/CMakeLists.txt index 7b9233d..ac0dff3 100644 --- a/src/GUI/CMakeLists.txt +++ b/src/GUI/CMakeLists.txt @@ -34,6 +34,7 @@ INCLUDE_DIRECTORIES( ${CMAKE_CURRENT_BINARY_DIR} ${PROJECT_BINARY_DIR}/idl ${PROJECT_SOURCE_DIR}/src/HYBRIDPlugin + ${PROJECT_SOURCE_DIR}/src/GUI ) # additional preprocessor / compiler flags @@ -64,6 +65,7 @@ SET(_link_LIBRARIES # header files / to be processed by moc SET(_moc_HEADERS + HYBRIDPluginGUI_TreeWidget.h HYBRIDPluginGUI_HypothesisCreator.h HYBRIDPluginGUI_Dlg.h ) @@ -84,7 +86,9 @@ QT_WRAP_MOC(_moc_SOURCES ${_moc_HEADERS}) SET(_other_SOURCES HYBRIDPluginGUI.cxx HYBRIDPluginGUI_HypothesisCreator.cxx + HYBRIDPluginGUI_StdWidget.cxx HYBRIDPluginGUI_AdvWidget.cxx + HYBRIDPluginGUI_TreeWidget.cxx ) # --- resources --- @@ -99,6 +103,7 @@ SET(_ts_RESOURCES # resource files / to be processed by uic SET(_uic_files + HYBRIDPluginGUI_StdWidget_QTD.ui HYBRIDPluginGUI_AdvWidget_QTD.ui ) diff --git a/src/GUI/HYBRIDPluginGUI_AdvWidget.cxx b/src/GUI/HYBRIDPluginGUI_AdvWidget.cxx index e6b967c..50913ba 100644 --- a/src/GUI/HYBRIDPluginGUI_AdvWidget.cxx +++ b/src/GUI/HYBRIDPluginGUI_AdvWidget.cxx @@ -28,7 +28,23 @@ #include #include +#include +namespace +{ + enum { EDITABLE_ROLE = Qt::UserRole + 1, PARAM_NAME, + NAME_COL = 0, VALUE_COL }; + + class ItemDelegate: public QItemDelegate { + public: + ItemDelegate(QObject* parent=0): QItemDelegate(parent) {} + QWidget* createEditor(QWidget *parent, const QStyleOptionViewItem &o, const QModelIndex &index) const + { + bool editable = index.data( EDITABLE_ROLE ).toInt(); + return editable ? QItemDelegate::createEditor( parent, o, index ) : 0; + } + }; +} ////////////////////////////////////////// // HYBRIDPluginGUI_AdvWidget @@ -38,9 +54,84 @@ HYBRIDPluginGUI_AdvWidget::HYBRIDPluginGUI_AdvWidget( QWidget* parent, Qt::Windo : QWidget( parent, f ) { setupUi( this ); - myAdvOptionsTable->layout()->setMargin( 0 ); + //myOptionTable->layout()->setMargin( 0 ); + myOptionTable->header()->setSectionResizeMode( QHeaderView::ResizeToContents ); + myOptionTable->setItemDelegate( new ItemDelegate( myOptionTable ) ); + + connect( myOptionTable, SIGNAL( itemChanged(QTreeWidgetItem *, int)), SLOT( itemChanged(QTreeWidgetItem *, int ))); } HYBRIDPluginGUI_AdvWidget::~HYBRIDPluginGUI_AdvWidget() { } + +void HYBRIDPluginGUI_AdvWidget::AddOption( const char* option, bool isCustom ) +{ + QTreeWidget * table = myOptionTable; + //table->setExpanded( true ); + + QTreeWidgetItem * row = new QTreeWidgetItem( table ); + row->setData( NAME_COL, EDITABLE_ROLE, int( isCustom && !option )); + row->setFlags( row->flags() | Qt::ItemIsEditable ); + + QString name, value; + bool isDefault = false; + if ( option ) + { + QStringList name_value_type = QString(option).split( ":", QString::KeepEmptyParts ); + if ( name_value_type.size() > 0 ) + name = name_value_type[0]; + if ( name_value_type.size() > 1 ) + value = name_value_type[1]; + if ( name_value_type.size() > 2 ) + isDefault = !name_value_type[2].toInt(); + + // if ( value == HYBRIDPlugin_Hypothesis::NoValue() ) + // value.clear(); + } + row->setText( 0, tr( name.toLatin1().constData() )); + row->setText( 1, tr( value.toLatin1().constData() )); + row->setCheckState( 0, isDefault ? Qt::Unchecked : Qt::Checked); + row->setData( NAME_COL, PARAM_NAME, name ); + + if ( isCustom ) + { + myOptionTable->scrollToItem( row ); + myOptionTable->setCurrentItem( row ); + myOptionTable->editItem( row, NAME_COL ); + } +} + +void HYBRIDPluginGUI_AdvWidget::GetOptionAndValue( QTreeWidgetItem * tblRow, + QString& option, + QString& value, + bool& isDefault) +{ + option = tblRow->data( NAME_COL, PARAM_NAME ).toString(); + value = tblRow->text( VALUE_COL ); + isDefault = ! tblRow->checkState( NAME_COL ); + + // if ( value.isEmpty() ) + // value = HYBRIDPlugin_Hypothesis::NoValue(); +} + + +void HYBRIDPluginGUI_AdvWidget::itemChanged(QTreeWidgetItem * tblRow, int column) +{ + if ( tblRow ) + { + myOptionTable->blockSignals( true ); + + tblRow->setData( VALUE_COL, EDITABLE_ROLE, int( tblRow->checkState( NAME_COL ))); + + int c = tblRow->checkState( NAME_COL ) ? 0 : 150; + tblRow->setForeground( VALUE_COL, QBrush( QColor( c, c, c ))); + + if ( column == NAME_COL && tblRow->data( NAME_COL, EDITABLE_ROLE ).toInt() ) // custom table + { + tblRow->setData( NAME_COL, PARAM_NAME, tblRow->text( NAME_COL )); + } + + myOptionTable->blockSignals( false ); + } +} diff --git a/src/GUI/HYBRIDPluginGUI_AdvWidget_QTD.ui b/src/GUI/HYBRIDPluginGUI_AdvWidget_QTD.ui index b5a7350..cdc6bc3 100644 --- a/src/GUI/HYBRIDPluginGUI_AdvWidget_QTD.ui +++ b/src/GUI/HYBRIDPluginGUI_AdvWidget_QTD.ui @@ -6,81 +6,73 @@ 0 0 - 465 - 477 + 337 + 369 Form - - - 0 - - - 0 - - - 0 - - - - - Memory settings + + + + + + 0 + 2 + + + + QAbstractItemView::DoubleClicked|QAbstractItemView::EditKeyPressed + + + true + + + + OPTION_NAME_COLUMN + + + + 50 + false + + + + + + OPTION_VALUE_COLUMN + + + + 50 + false + + + + + + + + + Qt::Horizontal + + + + 188 + 20 + + + + + + + + HYBRID_ADD_OPTION - - - - - MB - - - - - - - Initial memory size - - - - - - - Max memory size - - - - - - - MB - - - - - - - - 1 - 0 - - - - - - - - - 1 - 0 - - - - - - + Logs and debug @@ -154,69 +146,13 @@ - - - - Advanced meshing options - - - - - - Remove initial central point - - - - - - - Volumic gradation - - - - - - - - - - Use FEM correction - - - - - - - Use boundary recovery version - - - - - - - Create new nodes - - - - - - - - - - SMESHGUI_SpinBox - QDoubleSpinBox -
SMESHGUI_SpinBox.h
-
- - SMESH_AdvOptionsWdg - QWidget -
SMESH_AdvOptionsWdg.h
- 1 + HYBRIDPluginGUI_TreeWidget + QTreeWidget +
HYBRIDPluginGUI_TreeWidget.h
diff --git a/src/GUI/HYBRIDPluginGUI_Dlg.h b/src/GUI/HYBRIDPluginGUI_Dlg.h index d6805d6..6ba86fb 100644 --- a/src/GUI/HYBRIDPluginGUI_Dlg.h +++ b/src/GUI/HYBRIDPluginGUI_Dlg.h @@ -23,13 +23,48 @@ #ifndef HYBRIDPLUGINGUI_H #define HYBRIDPLUGINGUI_H -////////////////////////////////////////// -// HYBRIDPluginGUI_AdvWidget -////////////////////////////////////////// +enum { + OPTION_ID_COLUMN = 0, + OPTION_TYPE_COLUMN, + OPTION_NAME_COLUMN = 0, + OPTION_VALUE_COLUMN, + NB_COLUMNS, +}; + +#include "ui_HYBRIDPluginGUI_StdWidget_QTD.h" #include "ui_HYBRIDPluginGUI_AdvWidget_QTD.h" #include "HYBRIDPluginGUI_HypothesisCreator.h" +////////////////////////////////////////// +// HYBRIDPluginGUI_StdWidget +////////////////////////////////////////// + +class HYBRIDPLUGINGUI_EXPORT HYBRIDPluginGUI_StdWidget : public QWidget, + public Ui::HYBRIDPluginGUI_StdWidget_QTD +{ + Q_OBJECT + +public: + HYBRIDPluginGUI_StdWidget( QWidget* = 0, Qt::WindowFlags = 0 ); + ~HYBRIDPluginGUI_StdWidget(); + + bool GetLayersOnAllWrap() const + { + return myBoundaryLayersSizeMode->currentIndex() == 0; // == global + } + void SetLayersOnAllWrap(bool is) + { + myBoundaryLayersSizeMode->setCurrentIndex( !is ); // Global == 0, Local == 1 + } + +public: +}; + +////////////////////////////////////////// +// HYBRIDPluginGUI_AdvWidget +////////////////////////////////////////// + class HYBRIDPLUGINGUI_EXPORT HYBRIDPluginGUI_AdvWidget : public QWidget, public Ui::HYBRIDPluginGUI_AdvWidget_QTD { @@ -38,6 +73,13 @@ class HYBRIDPLUGINGUI_EXPORT HYBRIDPluginGUI_AdvWidget : public QWidget, public: HYBRIDPluginGUI_AdvWidget( QWidget* = 0, Qt::WindowFlags = 0 ); ~HYBRIDPluginGUI_AdvWidget(); + + void AddOption( const char* name_value_type, bool isCustom = false ); + void GetOptionAndValue( QTreeWidgetItem * tblRow, QString& option, QString& value, bool& dflt ); + +public slots: + + void itemChanged(QTreeWidgetItem * tblRow, int column); }; #endif diff --git a/src/GUI/HYBRIDPluginGUI_HypothesisCreator.cxx b/src/GUI/HYBRIDPluginGUI_HypothesisCreator.cxx index 7c0ea49..8d0a163 100644 --- a/src/GUI/HYBRIDPluginGUI_HypothesisCreator.cxx +++ b/src/GUI/HYBRIDPluginGUI_HypothesisCreator.cxx @@ -390,126 +390,12 @@ QFrame* HYBRIDPluginGUI_HypothesisCreator::buildFrame() aStdLayout->addWidget( myName, row++, 1, 1, 1 ); } - myToMeshHolesCheck = new QCheckBox( tr( "HYBRID_TO_MESH_HOLES" ), myStdGroup ); - //aStdLayout->addWidget( myToMeshHolesCheck, row, 0, 1, 1 ); #stay, not view, may be used tomorrow... - myToMeshHolesCheck->hide(); - myToMakeGroupsOfDomains = new QCheckBox( tr( "HYBRID_TO_MAKE_DOMAIN_GROUPS" ), myStdGroup ); - //aStdLayout->addWidget( myToMakeGroupsOfDomains, row++, 1, 1, 1 ); #stay, not view, may be used tomorrow... - myToMakeGroupsOfDomains->hide(); - //aStdLayout->addWidget( new QLabel( tr( "HYBRID_OPTIMIZATIOL_LEVEL" ), myStdGroup ), row, 0, 1, 1 ); - myOptimizationLevelCombo = new QComboBox( myStdGroup ); - //aStdLayout->addWidget( myOptimizationLevelCombo, row++, 1, 1, 1 ); #stay, not view, may be used tomorrow... - myOptimizationLevelCombo->hide(); - - QStringList types; - types << tr( "LEVEL_NONE" ) << tr( "LEVEL_LIGHT" ) << tr( "LEVEL_MEDIUM" ) << tr( "LEVEL_STANDARDPLUS" ) << tr( "LEVEL_STRONG" ); - myOptimizationLevelCombo->addItems( types ); - - QLabel* aLabel = new QLabel( tr( "HYBRID_BOUNDARY_LAYERS_GROWTH" ), myStdGroup ); - aLabel->setToolTip(tr( "HYBRID_BOUNDARY_LAYERS_HELP" )); - aStdLayout->addWidget( aLabel, row, 0, 1, 1 ); - myBoundaryLayersGrowthCombo = new QComboBox( myStdGroup ); - myBoundaryLayersGrowthCombo->setToolTip(tr( "HYBRID_BOUNDARY_LAYERS_HELP" )); - - aStdLayout->addWidget( myBoundaryLayersGrowthCombo, row++, 1, 1, 1 ); - - QStringList typesBoundaryLayersGrowth; - typesBoundaryLayersGrowth << tr( "HYBRID_LAYER_GROWTH_DOWNWARD" ) << tr( "HYBRID_LAYER_GROWTH_UPWARD" ); - myBoundaryLayersGrowthCombo->addItems( typesBoundaryLayersGrowth ); - - aStdLayout->addWidget( new QLabel( tr( "HYBRID_HeightFirstLayer" ), myStdGroup ), row, 0, 1, 1 ); - myHeightFirstLayerSpin = new SMESHGUI_SpinBox( myStdGroup ); - myHeightFirstLayerSpin->RangeStepAndValidator(0., COORD_MAX, .1, "length_precision"); - aStdLayout->addWidget( myHeightFirstLayerSpin, row++, 1, 1, 1 ); - - aStdLayout->addWidget( new QLabel( tr( "HYBRID_NbOfBoundaryLayers" ), myStdGroup ), row, 0, 1, 1 ); - myNbOfBoundaryLayersSpin = new QSpinBox( myStdGroup ); - aStdLayout->addWidget( myNbOfBoundaryLayersSpin, row++, 1, 1, 1 ); - - aStdLayout->addWidget( new QLabel( tr( "HYBRID_BoundaryLayersProgression" ), myStdGroup ), row, 0, 1, 1 ); - myBoundaryLayersProgressionSpin = new SMESHGUI_SpinBox( myStdGroup ); - myBoundaryLayersProgressionSpin->RangeStepAndValidator(0., 10., .1, "length_precision"); - aStdLayout->addWidget( myBoundaryLayersProgressionSpin, row++, 1, 1, 1 ); - - aStdLayout->addWidget( new QLabel( tr( "COLLISION_MODE" ), myStdGroup ), row, 0, 1, 1 ); - myCollisionModeCombo = new QComboBox( myStdGroup ); - aStdLayout->addWidget( myCollisionModeCombo, row++, 1, 1, 1 ); - - QStringList typescoll; - typescoll << tr( "COLLISION_DECREASE" ) << tr( "COLLISION_STOP" ); - myCollisionModeCombo->addItems( typescoll ); - - aStdLayout->addWidget( new QLabel( tr( "HYBRID_GENERATION_ELEMENT" ), myStdGroup ), row, 0, 1, 1 ); - myElementGenerationCombo = new QComboBox( myStdGroup ); - aStdLayout->addWidget( myElementGenerationCombo, row++, 1, 1, 1 ); - - QStringList typesElementGeneration; - typesElementGeneration << tr( "HYBRID_GENERATION_TETRA_DOMINANT" ) << tr( "HYBRID_GENERATION_HEXA_DOMINANT" ) << tr( "HYBRID_GENERATION_CARTESIAN_CORE" ); - myElementGenerationCombo->addItems( typesElementGeneration ); - - aStdLayout->addWidget( new QLabel( tr( "HYBRID_CORE_SIZE" ), myStdGroup ), row, 0, 1, 1 ); - myCoreSizeSpin = new SMESHGUI_SpinBox( myStdGroup ); - myCoreSizeSpin->RangeStepAndValidator(0., COORD_MAX, 10., "length_precision"); - aStdLayout->addWidget( myCoreSizeSpin, row++, 1, 1, 1 ); - - myAddMultinormalsCheck = new QCheckBox( tr( "HYBRID_ADD_MULTINORMALS" ), myStdGroup ); - aStdLayout->addWidget( myAddMultinormalsCheck, row++, 0, 1, 1 ); - - aStdLayout->addWidget( new QLabel( tr( "HYBRID_MULTINORMAL_ANGLE" ), myStdGroup ), row, 0, 1, 1 ); - myMultinormalsAngleSpin = new SMESHGUI_SpinBox( myStdGroup ); - myMultinormalsAngleSpin->RangeStepAndValidator(0., 90., 2., "threshold"); - aStdLayout->addWidget( myMultinormalsAngleSpin, row++, 1, 1, 1 ); - - mySmoothNormalsCheck = new QCheckBox( tr( "HYBRID_SMOOTH_NORMALS" ), myStdGroup ); - aStdLayout->addWidget( mySmoothNormalsCheck, row++, 0, 1, 1 ); - aStdLayout->setRowStretch( row, 10 ); + myStdWidget = new HYBRIDPluginGUI_StdWidget( myStdGroup ); + myStdWidget->verticalLayout->setMargin( 0 ); + aStdLayout->addWidget( myStdWidget, row++, 0, 1, 2 ); // advanced parameters - myAdvGroup = new QWidget(); - QGridLayout* anAdvLayout = new QGridLayout( myAdvGroup ); - anAdvLayout->setSpacing( 6 ); - anAdvLayout->setMargin( 11 ); - myAdvWidget = new HYBRIDPluginGUI_AdvWidget(myAdvGroup); - anAdvLayout->addWidget( myAdvWidget); - - myAdvWidget->maxMemoryCheck->setText(tr( "MAX_MEMORY_SIZE" )); - myAdvWidget->initialMemoryCheck->setText(tr( "INIT_MEMORY_SIZE" )); - - myAdvWidget->maxMemorySpin->RangeStepAndValidator(20.0, 1e6, 10.0); - myAdvWidget->maxMemorySpin->setValue( 128.0 ); - - myAdvWidget->initialMemorySpin->RangeStepAndValidator(0.0, 1e6, 10.0); - myAdvWidget->initialMemorySpin->setValue( 100.0 ); - - myAdvWidget->initialMemoryLabel ->setText (tr( "MEGABYTE" )); - myAdvWidget->maxMemoryLabel ->setText (tr( "MEGABYTE" )); - - myAdvWidget->workingDirectoryPushButton ->setText (tr( "SELECT_DIR" )); - myAdvWidget->keepWorkingFilesCheck ->setText (tr( "KEEP_WORKING_FILES" )); - myAdvWidget->verboseLevelLabel ->setText (tr( "VERBOSE_LEVEL" )); - myAdvWidget->removeLogOnSuccessCheck ->setText (tr( "REMOVE_LOG_ON_SUCCESS" )); - myAdvWidget->logInFileCheck ->setText (tr( "LOG_IN_FILE" )); - - myAdvWidget->memoryGroupBox ->setTitle(tr( "MEMORY_GROUP_TITLE" )); - myAdvWidget->logGroupBox ->setTitle(tr( "LOG_GROUP_TITLE" )); - myAdvWidget->advancedMeshingGroupBox ->setTitle(tr( "ADVANCED_MESHING_GROUP_TITLE" )); - - myAdvWidget->memoryGroupBox->hide(); - - myAdvWidget->createNewNodesCheck->hide(); - //myAdvWidget->createNewNodesLabel->hide(); - myAdvWidget->removeInitialCentralPointCheck->hide(); - myAdvWidget->boundaryRecoveryCheck->hide(); - myAdvWidget->FEMCorrectionCheck->hide(); - myAdvWidget->gradationLabel->hide(); - myAdvWidget->gradationSpinBox->hide(); - - myAdvWidget->createNewNodesCheck ->setText (tr( "TO_ADD_NODES" )); - myAdvWidget->removeInitialCentralPointCheck->setText (tr( "NO_INITIAL_CENTRAL_POINT" )); - myAdvWidget->boundaryRecoveryCheck ->setText (tr( "RECOVERY_VERSION" )); - myAdvWidget->FEMCorrectionCheck ->setText (tr( "FEM_CORRECTION" )); - myAdvWidget->gradationLabel ->setText (tr( "HYBRID_GRADATION" )); - myAdvWidget->gradationSpinBox->RangeStepAndValidator(1.05, 5.0, 0.05, "length_precision"); + myAdvWidget = new HYBRIDPluginGUI_AdvWidget( tab ); // Enforced vertices parameters myEnfGroup = new QWidget(); @@ -684,9 +570,9 @@ QFrame* HYBRIDPluginGUI_HypothesisCreator::buildFrame() // selection of faces for layers QWidget* faceSelLayersGroup = new QWidget( dlg() ); - myLayersOnAllWrapCheck = new QCheckBox( tr( "HYBRID_LAYERS_ON_ALL_WRAP" ), faceSelLayersGroup ); + //myLayersOnAllWrapCheck = new QCheckBox( tr( "HYBRID_LAYERS_ON_ALL_WRAP" ), faceSelLayersGroup ); QGridLayout* faceSelLayersLayout = new QGridLayout( faceSelLayersGroup ); - faceSelLayersLayout->addWidget(myLayersOnAllWrapCheck, 0, 0 ); + //faceSelLayersLayout->addWidget(myLayersOnAllWrapCheck, 0, 0 ); myFacesLbl = new QLabel( tr("HYBRID_FACE_IDS"), faceSelLayersGroup ); faceSelLayersLayout->addWidget( myFacesLbl, 1, 0 ); @@ -726,7 +612,7 @@ QFrame* HYBRIDPluginGUI_HypothesisCreator::buildFrame() // add tabs tab->insertTab( STD_TAB, myStdGroup, tr( "SMESH_ARGUMENTS" ) ); - tab->insertTab( ADV_TAB, myAdvGroup, tr( "HYBRID_ADV_ARGS" ) ); + tab->insertTab( ADV_TAB, myAdvWidget, tr( "HYBRID_ADV_ARGS" ) ); if ( aMainEntry.isEmpty() && aSubEntry.isEmpty() ) // mesh not based of geometry faceSelLayersGroup->hide(); else { @@ -739,18 +625,10 @@ QFrame* HYBRIDPluginGUI_HypothesisCreator::buildFrame() // connections connect( tab, SIGNAL( currentChanged ( int )), this, SLOT( onTabChanged( int ) ) ); - //connect( myLayersOnAllWrapCheck, SIGNAL( toggled( bool ) ), this, SLOT( onLayersOnAllWrap(bool))); - connect( myLayersOnAllWrapCheck, SIGNAL( toggled( bool ) ), this, SLOT( updateWidgets() ) ); - //connect( myToMeshHolesCheck, SIGNAL( toggled( bool ) ), this, SLOT( onToMeshHoles(bool))); - //connect( myAdvWidget->maxMemoryCheck, SIGNAL( toggled( bool ) ), this, SLOT( updateWidgets() ) ); - //connect( myAdvWidget->initialMemoryCheck, SIGNAL( toggled( bool ) ), this, SLOT( updateWidgets() ) ); - //connect( myAdvWidget->boundaryRecoveryCheck, SIGNAL( toggled( bool ) ), this, SLOT( updateWidgets() ) ); - - //connect( myBoundaryLayersGrowthCombo, SIGNAL( toggled( bool ) ), this, SLOT( updateWidgets() ) ); - //connect( myElementGenerationCombo, SIGNAL( toggled( bool ) ), this, SLOT( updateWidgets() ) ); - connect( myAddMultinormalsCheck, SIGNAL( toggled( bool ) ), this, SLOT( updateWidgets() ) ); - connect( mySmoothNormalsCheck, SIGNAL( toggled( bool ) ), this, SLOT( updateWidgets() ) ); - + connect( myAdvWidget->addBtn, SIGNAL( clicked() ), this, SLOT( onAddOption() ) ); + connect( myStdWidget->myBoundaryLayersSizeMode, SIGNAL( currentIndexChanged(int)), SLOT( updateWidgets())); + connect( myStdWidget->myImprinting, SIGNAL( currentIndexChanged(int)), SLOT( updateWidgets())); + connect( myStdWidget->mySnapping, SIGNAL( currentIndexChanged(int)), SLOT( updateWidgets())); connect( myAdvWidget->logInFileCheck, SIGNAL( toggled( bool ) ), this, SLOT( updateWidgets() ) ); connect( myAdvWidget->keepWorkingFilesCheck, SIGNAL( toggled( bool ) ), this, SLOT( updateWidgets() ) ); connect( myAdvWidget->workingDirectoryPushButton, SIGNAL( clicked() ), this, SLOT( onDirBtnClicked() ) ); @@ -904,8 +782,8 @@ void HYBRIDPluginGUI_HypothesisCreator::onSelectEnforcedVertex() { myEnfVertex = myEnfVertexWdg->GetObject< GEOM::GEOM_Object >(nbSelEnfVertex-1); if (myEnfVertex == GEOM::GEOM_Object::_nil()) return; - if (myEnfVertex->GetShapeType() == GEOM::VERTEX) { - HYBRIDPluginGUI_HypothesisCreator* that = (HYBRIDPluginGUI_HypothesisCreator*)this; + if (myEnfVertex->GetShapeType() == GEOM::VERTEX) + { GEOM::GEOM_IMeasureOperations_var measureOp = getGeomEngine()->GetIMeasureOperations(); if (CORBA::is_nil(measureOp)) return; @@ -1452,20 +1330,6 @@ void HYBRIDPluginGUI_HypothesisCreator::onRemoveEnforcedVertex() myEnforcedTableWidget->selectionModel()->clearSelection(); } -void HYBRIDPluginGUI_HypothesisCreator::onLayersOnAllWrap(bool isOn) -{ - // myToMakeGroupsOfDomains->setEnabled( isOn ); - // if ( !isOn ) - // myToMakeGroupsOfDomains->setChecked( false ); -} - -void HYBRIDPluginGUI_HypothesisCreator::onToMeshHoles(bool isOn) -{ - // myToMakeGroupsOfDomains->setEnabled( isOn ); - // if ( !isOn ) - // myToMakeGroupsOfDomains->setChecked( false ); -} - void HYBRIDPluginGUI_HypothesisCreator::onDirBtnClicked() { QString dir = SUIT_FileDlg::getExistingDirectory( dlg(), myAdvWidget->workingDirectoryLineEdit->text(), QString() ); @@ -1487,27 +1351,24 @@ void HYBRIDPluginGUI_HypothesisCreator::onTabChanged( int ) void HYBRIDPluginGUI_HypothesisCreator::updateWidgets() { - //customs automatic set - //myToMakeGroupsOfDomains->setEnabled( myToMeshHolesCheck->isChecked() ); - //myAdvWidget->maxMemorySpin->setEnabled( myAdvWidget->maxMemoryCheck->isChecked() ); - //myAdvWidget->initialMemoryCheck->setEnabled( !myAdvWidget->boundaryRecoveryCheck->isChecked() ); - //myAdvWidget->initialMemorySpin->setEnabled( myAdvWidget->initialMemoryCheck->isChecked() && !myAdvWidget->boundaryRecoveryCheck->isChecked() ); - //myOptimizationLevelCombo->setEnabled( !myAdvWidget->boundaryRecoveryCheck->isChecked() ); - myMultinormalsAngleSpin->setEnabled( myAddMultinormalsCheck->isChecked() ); if ( sender() == myAdvWidget->logInFileCheck || sender() == myAdvWidget->keepWorkingFilesCheck ) { - bool logFileRemovable = myAdvWidget->logInFileCheck->isChecked() && - !myAdvWidget->keepWorkingFilesCheck->isChecked(); - + bool logFileRemovable = ( myAdvWidget->logInFileCheck->isChecked() && + !myAdvWidget->keepWorkingFilesCheck->isChecked() ); myAdvWidget->removeLogOnSuccessCheck->setEnabled( logFileRemovable ); } - bool enabled = !myLayersOnAllWrapCheck->isChecked(); - myFacesLbl->setEnabled(enabled); - myFaceSelectorLayers->setEnabled(enabled); - if ( QTabWidget* tab = qobject_cast( myStdGroup->parentWidget()->parentWidget() )) { - tab->setTabEnabled( FACE_SEL_IMPRINTING_TAB, enabled ); - tab->setTabEnabled( FACE_SEL_SNAPPING_TAB, enabled ); + + myStdWidget->myCoreSize->setEnabled( myStdWidget->myCoreSizeEnabled->isChecked() ); + + if ( QTabWidget* tab = qobject_cast( myStdGroup->parentWidget()->parentWidget() )) + { + bool isGlobal = myStdWidget->GetLayersOnAllWrap(); + bool isImprinting = myStdWidget->myImprinting->currentIndex(); + bool isSnapping = myStdWidget->mySnapping->currentIndex(); + tab->setTabEnabled( FACE_SEL_LAYERS_TAB, !isGlobal ); + tab->setTabEnabled( FACE_SEL_IMPRINTING_TAB, isImprinting ); + tab->setTabEnabled( FACE_SEL_SNAPPING_TAB, isSnapping ); } } @@ -1521,7 +1382,43 @@ bool HYBRIDPluginGUI_HypothesisCreator::checkParams(QString& msg) const return false; } - return true; + HYBRIDPlugin::HYBRIDPlugin_Hypothesis_var h = + HYBRIDPlugin::HYBRIDPlugin_Hypothesis::_narrow( hypothesis() ); + + myAdvWidget->myOptionTable->setFocus(); + QApplication::instance()->processEvents(); + + QString name, value; + bool isDefault, ok = true; + int iRow = 0, nbRows = myAdvWidget->myOptionTable->topLevelItemCount(); + for ( ; iRow < nbRows; ++iRow ) + { + QTreeWidgetItem* row = myAdvWidget->myOptionTable->topLevelItem( iRow ); + myAdvWidget->GetOptionAndValue( row, name, value, isDefault ); + + if ( name.simplified().isEmpty() ) + continue; // invalid custom option + + if ( isDefault ) // not selected option + value.clear(); + + try { + h->SetOptionValue( name.toLatin1().constData(), value.toLatin1().constData() ); + } + catch ( const SALOME::SALOME_Exception& ex ) + { + msg = ex.details.text.in(); + ok = false; + break; + } + } + + if ( !ok ) + { + h->SetOptionValues( myOptions ); // restore values + } + + return ok; } void HYBRIDPluginGUI_HypothesisCreator::retrieveParams() const @@ -1532,30 +1429,24 @@ void HYBRIDPluginGUI_HypothesisCreator::retrieveParams() const if ( myName ) myName->setText( data.myName ); - myLayersOnAllWrapCheck ->setChecked ( data.myLayersOnAllWrap ); - myToMeshHolesCheck ->setChecked ( data.myToMeshHoles ); - myToMakeGroupsOfDomains ->setChecked ( data.myToMakeGroupsOfDomains ); - myOptimizationLevelCombo ->setCurrentIndex( data.myOptimizationLevel ); - myAdvWidget->maxMemoryCheck ->setChecked ( data.myMaximumMemory > 0 ); - myAdvWidget->maxMemorySpin ->setValue ( qMax( data.myMaximumMemory, - myAdvWidget->maxMemorySpin->minimum() )); - myAdvWidget->initialMemoryCheck ->setChecked ( data.myInitialMemory > 0 ); - myAdvWidget->initialMemorySpin ->setValue ( qMax( data.myInitialMemory, - myAdvWidget->initialMemorySpin->minimum() )); - - myCollisionModeCombo ->setCurrentIndex( data.myCollisionMode ); - myBoundaryLayersGrowthCombo ->setCurrentIndex( data.myBoundaryLayersGrowth ); - myElementGenerationCombo ->setCurrentIndex( data.myElementGeneration ); - myAddMultinormalsCheck -> setChecked ( data.myAddMultinormals ); - mySmoothNormalsCheck -> setChecked ( data.mySmoothNormals ); - myHeightFirstLayerSpin -> setValue( data.myHeightFirstLayer ); - myNbOfBoundaryLayersSpin -> setValue( data.myNbOfBoundaryLayers ); - myBoundaryLayersProgressionSpin -> setValue( data.myBoundaryLayersProgression ); + myStdWidget->SetLayersOnAllWrap( data.myLayersOnAllWrap ); + + myStdWidget->myNbOfBoundaryLayers ->setValue( data.myNbOfBoundaryLayers ); + myStdWidget ->SetLayersOnAllWrap( data.myLayersOnAllWrap ); + myStdWidget->myHeightFirstLayer ->setValue( data.myHeightFirstLayer ); + myStdWidget->myHeightIsRelative ->setCurrentIndex( data.myHeightIsRelative ); + myStdWidget->myBoundaryLayersGrowth ->setCurrentIndex( data.myBoundaryLayersGrowth ); + myStdWidget->myBoundaryLayersMaxElemAngle->setValue( data.myBoundaryLayersMaxElemAngle ); + myStdWidget->myBoundaryLayersProgression ->setValue( data.myBoundaryLayersProgression ); + myStdWidget->myImprinting ->setCurrentIndex( data.myImprinting ); + myStdWidget->mySnapping ->setCurrentIndex( data.mySnapping ); + myStdWidget->myElementGeneration ->setCurrentIndex( data.myElementGeneration ); if (data.myCoreSize <= 0) - myCoreSizeSpin->setText(""); + myStdWidget->myCoreSize->setText(""); else - myCoreSizeSpin -> setValue( data.myCoreSize ); - myMultinormalsAngleSpin -> setValue( data.myMultinormalsAngle ); + myStdWidget->myCoreSize->setValue( data.myCoreSize ); + myStdWidget->myCoreSizeEnabled->setChecked( data.myCoreSize > 0 ); + myFaceSelectorLayers ->SetListOfIDs( data.myFaceWLIds ); myFaceSelectorImprinting ->SetListOfIDs( data.myFaceWIIds ); myFaceSelectorSnapping ->SetListOfIDs( data.myFaceWSIds ); @@ -1563,15 +1454,19 @@ void HYBRIDPluginGUI_HypothesisCreator::retrieveParams() const myAdvWidget->workingDirectoryLineEdit ->setText ( data.myWorkingDir ); myAdvWidget->keepWorkingFilesCheck ->setChecked( data.myKeepFiles ); myAdvWidget->verboseLevelSpin ->setValue ( data.myVerboseLevel ); - myAdvWidget->createNewNodesCheck ->setChecked( data.myToCreateNewNodes ); - myAdvWidget->removeInitialCentralPointCheck ->setChecked( data.myRemoveInitialCentralPoint ); - myAdvWidget->boundaryRecoveryCheck ->setChecked( data.myBoundaryRecovery ); - myAdvWidget->FEMCorrectionCheck ->setChecked( data.myFEMCorrection ); - myAdvWidget->gradationSpinBox ->setValue ( data.myGradation ); - myAdvWidget->myAdvOptionsTable ->SetCustomOptions( data.myTextOption ); myAdvWidget->logInFileCheck ->setChecked( !data.myLogInStandardOutput ); myAdvWidget->removeLogOnSuccessCheck ->setChecked( data.myRemoveLogOnSuccess ); + if ( myOptions.operator->() ) { + for ( int i = 0, nb = myOptions->length(); i < nb; ++i ) + myAdvWidget->AddOption( that->myOptions[i].in() ); + } + if ( myCustomOptions.operator->() ) { + for ( int i = 0, nb = myCustomOptions->length(); i < nb; ++i ) + myAdvWidget->AddOption( that->myCustomOptions[i].in() ); + } + myAdvWidget->myOptionTable->resizeColumnToContents( OPTION_NAME_COLUMN ); + TEnfVertexList::const_iterator it; int rowCount = 0; myEnforcedTableWidget->clearContents(); @@ -1708,65 +1603,6 @@ QString HYBRIDPluginGUI_HypothesisCreator::storeParams() const storeParamsToHypo( data ); QString valStr = ""; - - if ( !data.myBoundaryRecovery ) - valStr = "-c " + QString::number( !data.myToMeshHoles ); - - if ( data.myOptimizationLevel >= 0 && data.myOptimizationLevel < 5 && !data.myBoundaryRecovery) { - const char* level[] = { "none" , "light" , "standard" , "standard+" , "strong" }; - valStr += " -o "; - valStr += level[ data.myOptimizationLevel ]; - } - if ( data.myMaximumMemory > 0 ) { - valStr += " -m "; - valStr += QString::number( data.myMaximumMemory ); - } - if ( data.myInitialMemory > 0 && !data.myBoundaryRecovery ) { - valStr += " -M "; - valStr += QString::number( data.myInitialMemory ); - } - valStr += " -v "; - valStr += QString::number( data.myVerboseLevel ); - - if ( !data.myToCreateNewNodes ) - valStr += " -p0"; - - if ( data.myRemoveInitialCentralPoint ) - valStr += " -no_initial_central_point"; - - if ( data.myBoundaryRecovery ) - valStr += " -C"; - - if ( data.myFEMCorrection ) - valStr += " -FEM"; - - if ( data.myGradation != 1.05 ) { - valStr += " -Dcpropa="; - valStr += QString::number( data.myGradation ); - } - - valStr += " "; - valStr += data.myTextOption; - - // valStr += " #BEGIN ENFORCED VERTICES#"; - // // Add size map parameters storage - // for (int i=0 ; irowCount() ; i++) { - // valStr += " ("; - // double x = mySmpModel->data(mySmpModel->index(i,ENF_VER_X_COLUMN)).toDouble(); - // double y = mySmpModel->data(mySmpModel->index(i,ENF_VER_Y_COLUMN)).toDouble(); - // double z = mySmpModel->data(mySmpModel->index(i,ENF_VER_Z_COLUMN)).toDouble(); - // double size = mySmpModel->data(mySmpModel->index(i,ENF_VER_SIZE_COLUMN)).toDouble(); - // valStr += QString::number( x ); - // valStr += ","; - // valStr += QString::number( y ); - // valStr += ","; - // valStr += QString::number( z ); - // valStr += ")="; - // valStr += QString::number( size ); - // if (i!=mySmpModel->rowCount()-1) - // valStr += ";"; - // } - // valStr += " #END ENFORCED VERTICES#"; return valStr; } @@ -1778,40 +1614,36 @@ bool HYBRIDPluginGUI_HypothesisCreator::readParamsFromHypo( HYBRIDHypothesisData HypothesisData* data = SMESH::GetHypothesisData( hypType() ); h_data.myName = isCreation() && data ? hypName() : ""; - h_data.myCollisionMode = h->GetCollisionMode(); - h_data.myBoundaryLayersGrowth = h->GetBoundaryLayersGrowth(); - h_data.myElementGeneration = h->GetElementGeneration(); - h_data.myAddMultinormals = h->GetAddMultinormals(); - h_data.mySmoothNormals = h->GetSmoothNormals(); + h_data.myNbOfBoundaryLayers = h->GetNbOfBoundaryLayers(); + h_data.myLayersOnAllWrap = h->GetLayersOnAllWrap(); h_data.myHeightFirstLayer = h->GetHeightFirstLayer(); + h_data.myHeightIsRelative = h->GetHeightIsRelative(); + h_data.myBoundaryLayersGrowth = h->GetBoundaryLayersGrowth(); + h_data.myBoundaryLayersMaxElemAngle = h->GetBoundaryLayersMaxElemAngle(); h_data.myBoundaryLayersProgression = h->GetBoundaryLayersProgression(); + h_data.myElementGeneration = h->GetElementGeneration(); h_data.myCoreSize = h->GetCoreSize(); - h_data.myMultinormalsAngle = h->GetMultinormalsAngle(); - h_data.myNbOfBoundaryLayers = h->GetNbOfBoundaryLayers(); + h_data.myFaceWLIds = h->GetFacesWithLayers(); h_data.myFaceWIIds = h->GetFacesWithImprinting(); h_data.myFaceWSIds = h->GetFacesWithSnapping(); + h_data.myImprinting = h_data.myFaceWIIds->length();//h->GetImprinting(); + h_data.mySnapping = h_data.myFaceWSIds->length();//h->GetSnapping(); - h_data.myLayersOnAllWrap = h->GetLayersOnAllWrap(); - h_data.myToMeshHoles = h->GetToMeshHoles(); - h_data.myToMakeGroupsOfDomains = /*h->GetToMeshHoles() &&*/ h->GetToMakeGroupsOfDomains(); - h_data.myMaximumMemory = h->GetMaximumMemory(); - h_data.myInitialMemory = h->GetInitialMemory(); - h_data.myInitialMemory = h->GetInitialMemory(); + h_data.myCollisionMode = h->GetCollisionMode(); h_data.myOptimizationLevel = h->GetOptimizationLevel(); - + h_data.myKeepFiles = h->GetKeepFiles(); h_data.myWorkingDir = h->GetWorkingDirectory(); h_data.myVerboseLevel = h->GetVerboseLevel(); - h_data.myToCreateNewNodes = h->GetToCreateNewNodes(); - h_data.myRemoveInitialCentralPoint = h->GetToRemoveCentralPoint(); - h_data.myBoundaryRecovery = h->GetToUseBoundaryRecoveryVersion(); - h_data.myFEMCorrection = h->GetFEMCorrection(); - h_data.myGradation = h->GetGradation(); - h_data.myTextOption = h->GetAdvancedOption(); h_data.myLogInStandardOutput = h->GetStandardOutputLog(); h_data.myRemoveLogOnSuccess = h->GetRemoveLogOnSuccess(); - + + HYBRIDPluginGUI_HypothesisCreator* that = (HYBRIDPluginGUI_HypothesisCreator*)this; + that->myOptions = h->GetOptionValues(); + that->myCustomOptions = h->GetAdvancedOptionValues(); + + HYBRIDPlugin::HYBRIDEnforcedVertexList_var vertices = h->GetEnforcedVertices(); h_data.myEnforcedVertices.clear(); for (CORBA::ULong i=0 ; ilength() ; i++) { @@ -1865,42 +1697,28 @@ bool HYBRIDPluginGUI_HypothesisCreator::storeParamsToHypo( const HYBRIDHypothesi if( isCreation() ) SMESH::SetName( SMESH::FindSObject( h ), h_data.myName.toLatin1().constData() ); + if ( h->GetNbOfBoundaryLayers() != h_data.myNbOfBoundaryLayers ) + h->SetNbOfBoundaryLayers ( h_data.myNbOfBoundaryLayers ); if ( h->GetLayersOnAllWrap() != h_data.myLayersOnAllWrap ) // avoid duplication of DumpPython commands h->SetLayersOnAllWrap ( h_data.myLayersOnAllWrap ); - if ( h->GetToMeshHoles() != h_data.myToMeshHoles ) // avoid duplication of DumpPython commands - h->SetToMeshHoles ( h_data.myToMeshHoles ); - if ( h->GetToMakeGroupsOfDomains() != h_data.myToMakeGroupsOfDomains ) - h->SetToMakeGroupsOfDomains( h_data.myToMakeGroupsOfDomains ); - if ( h->GetMaximumMemory() != h_data.myMaximumMemory ) - h->SetMaximumMemory ( h_data.myMaximumMemory ); - if ( h->GetInitialMemory() != h_data.myInitialMemory ) - h->SetInitialMemory ( h_data.myInitialMemory ); - if ( h->GetInitialMemory() != h_data.myInitialMemory ) - h->SetInitialMemory ( h_data.myInitialMemory ); - if ( h->GetOptimizationLevel() != h_data.myOptimizationLevel ) - h->SetOptimizationLevel( h_data.myOptimizationLevel ); - - if ( h->GetCollisionMode() != h_data.myCollisionMode ) - h->SetCollisionMode( h_data.myCollisionMode ); - if ( h->GetBoundaryLayersGrowth() != h_data.myBoundaryLayersGrowth ) - h->SetBoundaryLayersGrowth( h_data.myBoundaryLayersGrowth ); - if ( h->GetElementGeneration() != h_data.myElementGeneration ) - h->SetElementGeneration( h_data.myElementGeneration ); - - if ( h->GetAddMultinormals() != h_data.myAddMultinormals ) - h->SetAddMultinormals ( h_data.myAddMultinormals ); - if ( h->GetSmoothNormals() != h_data.mySmoothNormals ) - h->SetSmoothNormals ( h_data.mySmoothNormals ); if ( h->GetHeightFirstLayer() != h_data.myHeightFirstLayer ) h->SetHeightFirstLayer ( h_data.myHeightFirstLayer ); + h->SetHeightIsRelative( h_data.myHeightIsRelative ); + if ( h->GetBoundaryLayersGrowth() != h_data.myBoundaryLayersGrowth ) + h->SetBoundaryLayersGrowth( h_data.myBoundaryLayersGrowth ); + h->SetBoundaryLayersMaxElemAngle( h_data.myBoundaryLayersMaxElemAngle ); if ( h->GetBoundaryLayersProgression() != h_data.myBoundaryLayersProgression ) h->SetBoundaryLayersProgression ( h_data.myBoundaryLayersProgression ); + if ( h->GetElementGeneration() != h_data.myElementGeneration ) + h->SetElementGeneration( h_data.myElementGeneration ); if ( h->GetCoreSize() != h_data.myCoreSize ) h->SetCoreSize ( h_data.myCoreSize ); - if ( h->GetMultinormalsAngle() != h_data.myMultinormalsAngle ) - h->SetMultinormalsAngle ( h_data.myMultinormalsAngle ); - if ( h->GetNbOfBoundaryLayers() != h_data.myNbOfBoundaryLayers ) - h->SetNbOfBoundaryLayers ( h_data.myNbOfBoundaryLayers ); + + // if ( h->GetOptimizationLevel() != h_data.myOptimizationLevel ) + // h->SetOptimizationLevel( h_data.myOptimizationLevel ); + // if ( h->GetCollisionMode() != h_data.myCollisionMode ) + // h->SetCollisionMode( h_data.myCollisionMode ); + h->SetFacesWithLayers( h_data.myFaceWLIds ); h->SetFacesWithImprinting( h_data.myFaceWIIds ); h->SetFacesWithSnapping( h_data.myFaceWSIds ); @@ -1911,18 +1729,6 @@ bool HYBRIDPluginGUI_HypothesisCreator::storeParamsToHypo( const HYBRIDHypothesi h->SetWorkingDirectory ( h_data.myWorkingDir.toLatin1().constData() ); if ( h->GetVerboseLevel() != h_data.myVerboseLevel ) h->SetVerboseLevel ( h_data.myVerboseLevel ); - if ( h->GetToCreateNewNodes() != h_data.myToCreateNewNodes ) - h->SetToCreateNewNodes ( h_data.myToCreateNewNodes ); - if ( h->GetToRemoveCentralPoint() != h_data.myRemoveInitialCentralPoint ) - h->SetToRemoveCentralPoint ( h_data.myRemoveInitialCentralPoint ); - if ( h->GetToUseBoundaryRecoveryVersion() != h_data.myBoundaryRecovery ) - h->SetToUseBoundaryRecoveryVersion ( h_data.myBoundaryRecovery ); - if ( h->GetFEMCorrection() != h_data.myFEMCorrection ) - h->SetFEMCorrection ( h_data.myFEMCorrection ); - if ( h->GetGradation() != h_data.myGradation ) - h->SetGradation ( h_data.myGradation ); - if ( h->GetTextOption() != h_data.myTextOption ) - h->SetAdvancedOption ( h_data.myTextOption.toLatin1().constData() ); if ( h->GetStandardOutputLog() != h_data.myLogInStandardOutput ) h->SetStandardOutputLog ( h_data.myLogInStandardOutput ); if ( h->GetRemoveLogOnSuccess() != h_data.myRemoveLogOnSuccess ) @@ -1988,7 +1794,6 @@ bool HYBRIDPluginGUI_HypothesisCreator::storeParamsToHypo( const HYBRIDHypothesi break; } - std::cout << "h->p_SetEnforcedMesh(theSource, "<< elementType <<", \""<< enfMesh->name << "\", \"" << enfMesh->groupName.c_str() <<"\")"<p_SetEnforcedMesh(theSource, elementType, enfMesh->name.c_str(), enfMesh->groupName.c_str()); } // for } // try @@ -2007,24 +1812,16 @@ bool HYBRIDPluginGUI_HypothesisCreator::storeParamsToHypo( const HYBRIDHypothesi bool HYBRIDPluginGUI_HypothesisCreator::readParamsFromWidgets( HYBRIDHypothesisData& h_data ) const { h_data.myName = myName ? myName->text() : ""; - h_data.myLayersOnAllWrap = myLayersOnAllWrapCheck->isChecked(); - h_data.myToMeshHoles = myToMeshHolesCheck->isChecked(); - h_data.myToMakeGroupsOfDomains = myToMakeGroupsOfDomains->isChecked(); - h_data.myMaximumMemory = myAdvWidget->maxMemoryCheck->isChecked() ? myAdvWidget->maxMemorySpin->value() : -1; - h_data.myInitialMemory = myAdvWidget->initialMemoryCheck->isChecked() ? myAdvWidget->initialMemorySpin->value() : -1; - h_data.myOptimizationLevel = myOptimizationLevelCombo->currentIndex(); - - h_data.myCollisionMode = myCollisionModeCombo->currentIndex(); - h_data.myBoundaryLayersGrowth = myBoundaryLayersGrowthCombo->currentIndex(); - h_data.myElementGeneration = myElementGenerationCombo->currentIndex(); - h_data.myAddMultinormals = myAddMultinormalsCheck->isChecked(); - h_data.mySmoothNormals = mySmoothNormalsCheck->isChecked(); - - h_data.myHeightFirstLayer = myHeightFirstLayerSpin -> value(); - h_data.myNbOfBoundaryLayers = myNbOfBoundaryLayersSpin -> value(); - h_data.myBoundaryLayersProgression = myBoundaryLayersProgressionSpin -> value(); - h_data.myCoreSize = myCoreSizeSpin->text().isEmpty() ? 0.0 : myCoreSizeSpin -> value(); - h_data.myMultinormalsAngle = myMultinormalsAngleSpin -> value(); + h_data.myNbOfBoundaryLayers = myStdWidget->myNbOfBoundaryLayers -> value(); + h_data.myLayersOnAllWrap = myStdWidget->GetLayersOnAllWrap(); + h_data.myHeightFirstLayer = myStdWidget->myHeightFirstLayer -> value(); + h_data.myHeightIsRelative = myStdWidget->myHeightIsRelative->currentIndex(); + h_data.myBoundaryLayersGrowth = myStdWidget->myBoundaryLayersGrowth->currentIndex(); + h_data.myBoundaryLayersMaxElemAngle = myStdWidget->myBoundaryLayersMaxElemAngle->value(); + h_data.myBoundaryLayersProgression = myStdWidget->myBoundaryLayersProgression -> value(); + h_data.myElementGeneration = myStdWidget->myElementGeneration->currentIndex(); + h_data.myCoreSize = myStdWidget->myCoreSizeEnabled->isChecked() ? myStdWidget->myCoreSize -> value() : 0; + h_data.myFaceWLIds = myFaceSelectorLayers->GetListOfIDs(); h_data.myFaceWIIds = myFaceSelectorImprinting->GetListOfIDs(); h_data.myFaceWSIds = myFaceSelectorSnapping->GetListOfIDs(); @@ -2032,12 +1829,6 @@ bool HYBRIDPluginGUI_HypothesisCreator::readParamsFromWidgets( HYBRIDHypothesisD h_data.myKeepFiles = myAdvWidget->keepWorkingFilesCheck->isChecked(); h_data.myWorkingDir = myAdvWidget->workingDirectoryLineEdit->text().trimmed(); h_data.myVerboseLevel = myAdvWidget->verboseLevelSpin->value(); - h_data.myToCreateNewNodes = myAdvWidget->createNewNodesCheck->isChecked(); - h_data.myRemoveInitialCentralPoint = myAdvWidget->removeInitialCentralPointCheck->isChecked(); - h_data.myBoundaryRecovery = myAdvWidget->boundaryRecoveryCheck->isChecked(); - h_data.myFEMCorrection = myAdvWidget->FEMCorrectionCheck->isChecked(); - h_data.myGradation = myAdvWidget->gradationSpinBox->value(); - h_data.myTextOption = myAdvWidget->myAdvOptionsTable->GetCustomOptions(); h_data.myLogInStandardOutput = !myAdvWidget->logInFileCheck->isChecked(); h_data.myRemoveLogOnSuccess = myAdvWidget->removeLogOnSuccessCheck->isChecked(); @@ -2077,7 +1868,6 @@ bool HYBRIDPluginGUI_HypothesisCreator::readParamsFromWidgets( HYBRIDHypothesisD QComboBox* combo = qobject_cast(myEnforcedMeshTableWidget->cellWidget(row,ENF_MESH_CONSTRAINT_COLUMN)); myEnfMesh->elementType = combo->currentIndex(); h_data.myEnforcedMeshes.insert(myEnfMesh); - std::cout << "h_data.myEnforcedMeshes.size(): " << h_data.myEnforcedMeshes.size() << std::endl; } return true; @@ -2102,3 +1892,8 @@ QString HYBRIDPluginGUI_HypothesisCreator::helpPage() const { return "hybrid_hypo_page.html"; } + +void HYBRIDPluginGUI_HypothesisCreator::onAddOption() +{ + myAdvWidget->AddOption( NULL, true ); +} diff --git a/src/GUI/HYBRIDPluginGUI_HypothesisCreator.h b/src/GUI/HYBRIDPluginGUI_HypothesisCreator.h index 028aa80..af82f23 100644 --- a/src/GUI/HYBRIDPluginGUI_HypothesisCreator.h +++ b/src/GUI/HYBRIDPluginGUI_HypothesisCreator.h @@ -57,6 +57,7 @@ class QTableWidget; class QTableWidgetItem; class QWidget; +class HYBRIDPluginGUI_StdWidget; class HYBRIDPluginGUI_AdvWidget; class LightApp_SelectionMgr; class SMESHGUI_SpinBox; @@ -142,27 +143,18 @@ typedef std::set< TEnfMesh*, CompareEnfMeshes > TEnfMeshList; typedef struct { - bool myLayersOnAllWrap, myToMeshHoles, myToMakeGroupsOfDomains, - myKeepFiles, myToCreateNewNodes, - myBoundaryRecovery, myFEMCorrection, - myRemoveInitialCentralPoint, - myLogInStandardOutput, myRemoveLogOnSuccess; - double myMaximumMemory,myInitialMemory; - int myOptimizationLevel; - int myCollisionMode; - int myBoundaryLayersGrowth; - int myElementGeneration; - QString myName,myWorkingDir,myTextOption; + bool myHeightIsRelative, myImprinting, mySnapping, myLayersOnAllWrap, + myKeepFiles, myLogInStandardOutput, myRemoveLogOnSuccess; + int myOptimizationLevel, myCollisionMode, myBoundaryLayersGrowth, myElementGeneration; + QString myName,myWorkingDir; double myGradation; short myVerboseLevel; TEnfVertexList myEnforcedVertices; TEnfMeshList myEnforcedMeshes; - bool myAddMultinormals, - mySmoothNormals; double myHeightFirstLayer, myBoundaryLayersProgression, myCoreSize, - myMultinormalsAngle; + myBoundaryLayersMaxElemAngle; short myNbOfBoundaryLayers; // IDs of faces with layers SMESH::long_array_var myFaceWLIds; @@ -197,8 +189,7 @@ protected: virtual QString type() const; protected slots: - void onLayersOnAllWrap(bool); - void onToMeshHoles(bool); + void onAddOption(); void onDirBtnClicked(); void updateWidgets(); @@ -235,18 +226,11 @@ private: private: QWidget* myStdGroup; QLineEdit* myName; - QCheckBox* myLayersOnAllWrapCheck; - QCheckBox* myToMeshHolesCheck; - QCheckBox* myToMakeGroupsOfDomains; - QComboBox* myOptimizationLevelCombo; - QComboBox* myCollisionModeCombo; - QComboBox* myBoundaryLayersGrowthCombo; - QComboBox* myElementGenerationCombo; - QCheckBox* myAddMultinormalsCheck; - QCheckBox* mySmoothNormals; - QWidget* myAdvGroup; + HYBRIDPluginGUI_StdWidget* myStdWidget; HYBRIDPluginGUI_AdvWidget* myAdvWidget; - + + mutable HYBRIDPlugin::string_array_var myOptions, myCustomOptions; + QWidget* myEnfGroup; QPixmap iconVertex, iconCompound; StdMeshersGUI_ObjectReferenceParamWdg *myEnfVertexWdg; diff --git a/src/GUI/HYBRIDPluginGUI_StdWidget.cxx b/src/GUI/HYBRIDPluginGUI_StdWidget.cxx new file mode 100644 index 0000000..f796542 --- /dev/null +++ b/src/GUI/HYBRIDPluginGUI_StdWidget.cxx @@ -0,0 +1,54 @@ +// Copyright (C) 2007-2019 CEA/DEN, EDF R&D +// +// 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, 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 +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// + +// --- +// File : BLSURFPluginGUI_StdWidget.cxx +// Authors : Gilles DAVID (OCC) +// --- +// + +#include "HYBRIDPluginGUI_Dlg.h" + +#include +#include +#include +#include + +//using namespace std; + +////////////////////////////////////////// +// HYBRIDPluginGUI_StdWidget +////////////////////////////////////////// + +HYBRIDPluginGUI_StdWidget::HYBRIDPluginGUI_StdWidget( QWidget* parent, Qt::WindowFlags f ) + : QWidget( parent, f ) +{ + setupUi( this ); + + myHeightFirstLayer->RangeStepAndValidator( 0, 1e+6, 1, "length_precision" ); + myBoundaryLayersMaxElemAngle->RangeStepAndValidator( 90, 360, 5, "angle_precision" ); + myBoundaryLayersProgression->RangeStepAndValidator( -100, 100, 0.1, "length_precision" ); + myCoreSize->RangeStepAndValidator( 0, 1e+6, 1, "length_precision" ); + + connect( myCoreSizeEnabled, SIGNAL( toggled(bool)), myCoreSize, SLOT( setEnabled(bool) )); +} + +HYBRIDPluginGUI_StdWidget::~HYBRIDPluginGUI_StdWidget() +{ +} diff --git a/src/GUI/HYBRIDPluginGUI_StdWidget_QTD.ui b/src/GUI/HYBRIDPluginGUI_StdWidget_QTD.ui new file mode 100644 index 0000000..750a12b --- /dev/null +++ b/src/GUI/HYBRIDPluginGUI_StdWidget_QTD.ui @@ -0,0 +1,250 @@ + + + HYBRIDPluginGUI_StdWidget_QTD + + + + 0 + 0 + 480 + 398 + + + + Form + + + + + + HYBRID_VL_OPTIONS + + + + + + HYBRID_NB_LAYERS + + + + + + + + + + HYBRID_SIZE_MODE + + + + + + + + HYBRID_GLOBAL + + + + + HYBRID_LOCAL + + + + + + + + HYBRID_1ST_LAYER_HEIGHT + + + + + + + HYBRID_HEIGHT_IS_RELATIVE + + + + + + + + HYBRID_NO + + + + + HYBRID_YES + + + + + + + + HYBRID_GROWTH_OF_LAYERS + + + + + + + + HYBRID_LAYER_GROWTH_DOWNWARD + + + + + HYBRID_LAYER_GROWTH_UPWARD + + + + + + + + HYBRID_MAX_ELEM_ANGLE + + + + + + + + + + HYBRID_GEOM_PROGRESSION + + + + + + + + + + HYBRID_IMPRINTING + + + + + + + + HYBRID_NO + + + + + HYBRID_YES + + + + + + + + HYBRID_SNAPPING + + + + + + + + HYBRID_NO + + + + + HYBRID_YES + + + + + + + + + + + + + + HYBRID_OTHER_OPTIONS + + + + + + HYBRID_GENERATION_ELEMENT + + + + + + + + HYBRID_GENERATION_TETRA_DOMINANT + + + + + HYBRID_GENERATION_HEXA_DOMINANT + + + + + HYBRID_GENERATION_CARTESIAN_CORE + + + + + HYBRID_GENERATION_EXTRUSION_ONLY + + + + + + + + HYBRID_CORE_SIZE + + + + + + + + + + + + + Qt::Vertical + + + + 438 + 7 + + + + + + + + + SalomeApp_IntSpinBox + QLineEdit +
SalomeApp_IntSpinBox.h
+
+ + SMESHGUI_SpinBox + QDoubleSpinBox +
SMESHGUI_SpinBox.h
+
+
+ + +
diff --git a/src/GUI/HYBRIDPluginGUI_TreeWidget.cxx b/src/GUI/HYBRIDPluginGUI_TreeWidget.cxx new file mode 100644 index 0000000..0fc743b --- /dev/null +++ b/src/GUI/HYBRIDPluginGUI_TreeWidget.cxx @@ -0,0 +1,91 @@ +// Copyright (C) 2007-2019 CEA/DEN, EDF R&D +// +// 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, 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 +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// + +#include "HYBRIDPluginGUI_TreeWidget.h" +#include + +namespace +{ + bool isEditable( const QModelIndex& index ) + { + return index.isValid() && + index.flags() & Qt::ItemIsEditable && + index.flags() & Qt::ItemIsEnabled && + ( !index.data( Qt::UserRole + 1 ).isValid() || index.data( Qt::UserRole + 1 ).toInt() != 0 ); + } +} + +HYBRIDPluginGUI_TreeWidget::HYBRIDPluginGUI_TreeWidget( QWidget* parent ) + : QTreeWidget( parent ) +{ +} + +QModelIndex HYBRIDPluginGUI_TreeWidget::moveCursor( CursorAction action, Qt::KeyboardModifiers modifiers ) +{ + QModelIndex current = currentIndex(); + int column = current.column(); + if ( action == MoveNext ) { + if ( column < columnCount()-1 ) { + QModelIndex next = current.sibling( current.row(), column+1 ); + if ( isEditable( next ) ) + return next; + } + else { + QModelIndex next = current.sibling( current.row()+1, 0 ); + if ( isEditable( next ) ) + return next; + } + } + else if ( action == MovePrevious ) { + if ( column == 0 ) { + QModelIndex next = current.sibling( current.row()-1, columnCount()-1 ); + if ( isEditable( next ) ) + return next; + } + else { + QModelIndex next = current.sibling( current.row(), column-1 ); + if ( isEditable( next ) ) + return next; + } + } + return QTreeWidget::moveCursor( action, modifiers ); +} + +void HYBRIDPluginGUI_TreeWidget::keyPressEvent( QKeyEvent* e ) +{ + switch ( e->key() ) { + case Qt::Key_F2: + { + QModelIndex index = currentIndex(); + if ( !isEditable( index ) ) { + for ( int i = 0; i < columnCount(); i++ ) { + QModelIndex sibling = index.sibling( index.row(), i ); + if ( isEditable( sibling ) ) { + if ( !edit( sibling, EditKeyPressed, e ) ) + e->ignore(); + } + } + } + } + break; + default: + break; + } + QTreeWidget::keyPressEvent( e ); +} diff --git a/src/GUI/HYBRIDPluginGUI_TreeWidget.h b/src/GUI/HYBRIDPluginGUI_TreeWidget.h new file mode 100644 index 0000000..0b9b297 --- /dev/null +++ b/src/GUI/HYBRIDPluginGUI_TreeWidget.h @@ -0,0 +1,36 @@ +// Copyright (C) 2007-2019 CEA/DEN, EDF R&D +// +// 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, 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 +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// + +#if !defined(HYBRIDPluginGUI_TreeWidget_H) +#define HYBRIDPluginGUI_TreeWidget_H + +#include + +class HYBRIDPluginGUI_TreeWidget : public QTreeWidget +{ + Q_OBJECT +public: + HYBRIDPluginGUI_TreeWidget( QWidget* ); + +protected: + QModelIndex moveCursor( CursorAction, Qt::KeyboardModifiers ); + void keyPressEvent( QKeyEvent* ); +}; + +#endif // HYBRIDPluginGUI_TreeWidget_H diff --git a/src/GUI/HYBRIDPlugin_msg_en.ts b/src/GUI/HYBRIDPlugin_msg_en.ts index 536c322..8b031fa 100644 --- a/src/GUI/HYBRIDPlugin_msg_en.ts +++ b/src/GUI/HYBRIDPlugin_msg_en.ts @@ -28,7 +28,7 @@ Hypothesis Construction - HYBRID_BOUNDARY_LAYERS_GROWTH + HYBRID_GROWTH_OF_LAYERS Growth of boundary layers @@ -56,7 +56,7 @@ downward means inward and upward means outward ... HYBRID_GENERATION_ELEMENT - Element type for mesh in the remaining volume + Element generation HYBRID_GENERATION_TETRA_DOMINANT @@ -70,9 +70,13 @@ downward means inward and upward means outward ... HYBRID_GENERATION_CARTESIAN_CORE Cartesian core + + HYBRID_GENERATION_EXTRUSION_ONLY + Extrusion only + HYBRID_CORE_SIZE - Core elements size (cartesian core only) + Core elements size HYBRID_ADD_MULTINORMALS @@ -87,16 +91,68 @@ downward means inward and upward means outward ... Smooth normals at closed ridges and corners - HYBRID_HeightFirstLayer + HYBRID_1ST_LAYER_HEIGHT Height of first layer - HYBRID_NbOfBoundaryLayers + HYBRID_NB_LAYERS Number of boundary layers - HYBRID_BoundaryLayersProgression - Geometric progression of boundary layers + HYBRID_HEIGHT_IS_RELATIVE + Height relative to local surface + + + HYBRID_SIZE_MODE + Size mode + + + HYBRID_GLOBAL + Global + + + HYBRID_LOCAL + Local + + + HYBRID_MAX_ELEM_ANGLE + Maximal element angle (degrees) + + + HYBRID_IMPRINTING + Imprinting + + + HYBRID_SNAPPING + Snapping + + + HYBRID_NO + No + + + HYBRID_YES + Yes + + + HYBRID_VL_OPTIONS + Options for boundary layers + + + HYBRID_OTHER_OPTIONS + Other options + + + + + + + + + + + HYBRID_GEOM_PROGRESSION + Geometric progression HYBRID_TO_MESH_HOLES @@ -334,5 +390,33 @@ downward means inward and upward means outward ... HYBRID_FACE_IDS Face IDs + + add_multinormals + Add multi normals + + + smooth_normals + Smooth normals + + + max_number_of_threads + Maximum number of threads + + + gradation + Gradation + + + multinormal_angle_threshold + Multi normal angle threshold + + + collision_mode + Collision mode + + + HYBRID_ADD_OPTION + Add option + diff --git a/src/HYBRIDPlugin/HYBRIDPluginBuilder.py b/src/HYBRIDPlugin/HYBRIDPluginBuilder.py index 2ac5ec4..12f1013 100644 --- a/src/HYBRIDPlugin/HYBRIDPluginBuilder.py +++ b/src/HYBRIDPlugin/HYBRIDPluginBuilder.py @@ -163,49 +163,6 @@ class HYBRID_Algorithm(Mesh_Algorithm): self.SetLayersOnAllWrap( False ) pass - """ - obsolete - ## To mesh "holes" in a solid or not. Default is to mesh. - # @param toMesh "mesh holes" flag value - def SetToMeshHoles(self, toMesh): - self.Parameters().SetToMeshHoles(toMesh) - pass - - ## To make groups of volumes of different domains when mesh is generated from skin. - # Default is to make groups. - # This option works only (1) for the mesh w/o shape and (2) if GetToMeshHoles() == true - # @param toMesh "mesh holes" flag value - def SetToMakeGroupsOfDomains(self, toMakeGroups): - self.Parameters().SetToMakeGroupsOfDomains(toMakeGroups) - pass - - ## Set Optimization level: - # @param level optimization level, one of the following values - # - None_Optimization - # - Light_Optimization - # - Standard_Optimization - # - StandardPlus_Optimization - # - Strong_Optimization. - # . - # Default is Standard_Optimization - def SetOptimizationLevel(self, level): - self.Parameters().SetOptimizationLevel(level) - pass - - ## Set maximal size of memory to be used by the algorithm (in Megabytes). - # @param MB maximal size of memory - def SetMaximumMemory(self, MB): - self.Parameters().SetMaximumMemory(MB) - pass - - ## Set initial size of memory to be used by the algorithm (in Megabytes) in - # automatic memory adjustment mode. - # @param MB initial size of memory - def SetInitialMemory(self, MB): - self.Parameters().SetInitialMemory(MB) - pass - """ - ## Set Collision Mode: # @param mode Collision Mode, one of the following values # - Decrease_Collision_Mode @@ -258,6 +215,12 @@ class HYBRID_Algorithm(Mesh_Algorithm): self.Parameters().SetHeightFirstLayer(heightFirstLayer) pass + ## Sizes of boundary layers are relative to the surface size. Default no + # @param isRelative boolean flag + def SetHeightIsRelative(self, isRelative): + self.Parameters().SetHeightIsRelative( isRelative ) + pass + ## To set boundary layers coefficient of geometric progression. # Default is 1.0 # @param boundaryLayersProgression double value @@ -286,6 +249,12 @@ class HYBRID_Algorithm(Mesh_Algorithm): self.Parameters().SetNbOfBoundaryLayers(nbOfBoundaryLayers) pass + ## Set maximum internal angles of boundary elements (in degree) + # @param angle angle in degree + def SetBoundaryLayersMaxElemAngle(self, angle): + self.Parameters().SetBoundaryLayersMaxElemAngle( angle ) + pass + ## Set path to working directory. # @param path working directory def SetWorkingDirectory(self, path): @@ -422,18 +391,25 @@ class HYBRID_Algorithm(Mesh_Algorithm): pass pass + ## Set advanced option value + # @param optionName option name + # @param optionValue option value + def SetOptionValue(self, optionName, optionValue): + self.Parameters().SetOptionValue( optionName, optionValue ) + pass + ## Sets command line option as text. - # - # OBSOLETE. Use SetAdvancedOption() - # @param option command line option - def SetTextOption(self, option): - self.Parameters().SetAdvancedOption(option) + # @param optionAndValue command line option in a form "option value" + def SetAdvancedOption(self, optionAndValue): + self.Parameters().SetAdvancedOption(optionAndValue) pass ## Sets command line option as text. + # + # OBSOLETE. Use SetAdvancedOption() # @param option command line option - def SetAdvancedOption(self, option): + def SetTextOption(self, option): self.Parameters().SetAdvancedOption(option) pass - + pass # end of HYBRID_Algorithm class diff --git a/src/HYBRIDPlugin/HYBRIDPlugin_Hypothesis.cxx b/src/HYBRIDPlugin/HYBRIDPlugin_Hypothesis.cxx index fb18c59..4ef1873 100644 --- a/src/HYBRIDPlugin/HYBRIDPlugin_Hypothesis.cxx +++ b/src/HYBRIDPlugin/HYBRIDPlugin_Hypothesis.cxx @@ -34,54 +34,136 @@ #define getpid _getpid #endif +namespace +{ + struct GET_DEFAULT // struct used to get default value from GetOptionValue() + { + bool isDefault; + operator bool* () { return &isDefault; } + }; +} + //======================================================================= //function : HYBRIDPlugin_Hypothesis //======================================================================= HYBRIDPlugin_Hypothesis::HYBRIDPlugin_Hypothesis(int hypId, SMESH_Gen * gen) : SMESH_Hypothesis(hypId, gen), - myToMeshHoles(DefaultMeshHoles()), - myLayersOnAllWrap(DefaultLayersOnAllWrap()), - myToMakeGroupsOfDomains(DefaultToMakeGroupsOfDomains()), - myMaximumMemory(-1), - myInitialMemory(-1), - myOptimizationLevel(DefaultOptimizationLevel()), - myCollisionMode(DefaultCollisionMode()), - myBoundaryLayersGrowth(DefaultBoundaryLayersGrowth()), - myElementGeneration(DefaultElementGeneration()), - myKeepFiles(DefaultKeepFiles()), - myWorkingDirectory(DefaultWorkingDirectory()), - myVerboseLevel(DefaultVerboseLevel()), - myToCreateNewNodes(DefaultToCreateNewNodes()), - myToUseBoundaryRecoveryVersion(DefaultToUseBoundaryRecoveryVersion()), - myToUseFemCorrection(DefaultToUseFEMCorrection()), - myToRemoveCentralPoint(DefaultToRemoveCentralPoint()), - myLogInStandardOutput(DefaultStandardOutputLog()), - myGradation(DefaultGradation()), - myAddMultinormals(DefaultAddMultinormals()), - mySmoothNormals(DefaultSmoothNormals()), - myHeightFirstLayer(DefaultHeightFirstLayer()), - myBoundaryLayersProgression(DefaultBoundaryLayersProgression()), - myCoreSize(DefaultCoreSize()), - myMultinormalsAngle(DefaultMultinormalsAngle()), - myNbOfBoundaryLayers(DefaultNbOfBoundaryLayers()), - _enfVertexList(DefaultHYBRIDEnforcedVertexList()), - _enfVertexCoordsSizeList(DefaultHYBRIDEnforcedVertexCoordsValues()), - _enfVertexEntrySizeList(DefaultHYBRIDEnforcedVertexEntryValues()), - _coordsEnfVertexMap(DefaultCoordsHYBRIDEnforcedVertexMap()), - _geomEntryEnfVertexMap(DefaultGeomEntryHYBRIDEnforcedVertexMap()), - _enfMeshList(DefaultHYBRIDEnforcedMeshList()), - _entryEnfMeshMap(DefaultEntryHYBRIDEnforcedMeshListMap()), - _enfNodes(TIDSortedNodeGroupMap()), - _enfEdges(TIDSortedElemGroupMap()), - _enfTriangles(TIDSortedElemGroupMap()), - _nodeIDToSizeMap(DefaultID2SizeMap()), - _groupsToRemove(DefaultGroupsToRemove()) + myNbOfBoundaryLayers(DefaultNbOfBoundaryLayers()), + myHeightFirstLayer(DefaultHeightFirstLayer()), + myHeightIsRelative(DefaultHeightIsRelative()), + myBoundaryLayersGrowth(DefaultBoundaryLayersGrowth()), + myBoundaryLayersMaxElemAngle(DefaultBoundaryLayersMaxElemAngle()), + myBoundaryLayersProgression(DefaultBoundaryLayersProgression()), + myElementGeneration(DefaultElementGeneration()), + myCoreSize(DefaultCoreSize()), + myLayersOnAllWrap(DefaultLayersOnAllWrap()), + myCollisionMode(DefaultCollisionMode()), + myAddMultinormals(DefaultAddMultinormals()), + mySmoothNormals(DefaultSmoothNormals()), + myMultinormalsAngle(DefaultMultinormalsAngle()), + myGradation(DefaultGradation()), + myWorkingDirectory(DefaultWorkingDirectory()), + myVerboseLevel(DefaultVerboseLevel()), + myLogInStandardOutput(DefaultStandardOutputLog()), + myRemoveLogOnSuccess(DefaultRemoveLogOnSuccess()), + myKeepFiles(DefaultKeepFiles()), + myOptimizationLevel(DefaultOptimizationLevel()), + myToMakeGroupsOfDomains(DefaultToMakeGroupsOfDomains()), + myToMeshHoles(DefaultMeshHoles()), + myMaximumMemory(-1), + myInitialMemory(-1), + myToCreateNewNodes(DefaultToCreateNewNodes()), + myToUseBoundaryRecoveryVersion(DefaultToUseBoundaryRecoveryVersion()), + myToUseFemCorrection(DefaultToUseFEMCorrection()), + myToRemoveCentralPoint(DefaultToRemoveCentralPoint()) { _name = "HYBRID_Parameters"; _param_algo_dim = 3; + + const char* boolOptionNames[] = { "add_multinormals", // no + "smooth_normals", // no + "" // mark of end + }; + const char* intOptionNames[] = { "max_number_of_threads", // 4 + "" // mark of end + }; + const char* doubleOptionNames[] = { //"global_physical_size", // 0.0 = not set -- myCoreSize + "gradation", // 2.0 + //"boundary_layer_max_element_angle", // 165.0 -- myBoundaryLayersMaxElemAngle + "multinormal_angle_threshold", // 30.0 + "" // mark of end + }; + const char* charOptionNames[] = { "collision_mode", // stop/decrease + "" // mark of end + }; + + int i = 0; + while (boolOptionNames[i][0]) + { + _boolOptions.insert( boolOptionNames[i] ); + _option2value[boolOptionNames[i++]].clear(); + } + i = 0; + while (intOptionNames[i][0]) + _option2value[intOptionNames[i++]].clear(); + + i = 0; + while (doubleOptionNames[i][0]) { + _doubleOptions.insert(doubleOptionNames[i]); + _option2value[doubleOptionNames[i++]].clear(); + } + i = 0; + while (charOptionNames[i][0]) { + _charOptions.insert(charOptionNames[i]); + _option2value[charOptionNames[i++]].clear(); + } + + // default values to be used while MG meshing + + _defaultOptionValues["add_multinormals" ] = "no"; + _defaultOptionValues["smooth_normals" ] = "no"; + _defaultOptionValues["max_number_of_threads" ] = "4"; + //_defaultOptionValues["global_physical_size" ] = "0"; + _defaultOptionValues["gradation" ] = "2"; + //_defaultOptionValues["boundary_layer_max_element_angle"] = "165"; + _defaultOptionValues["multinormal_angle_threshold" ] = "30"; + _defaultOptionValues["collision_mode" ] = "stop"; + +#ifdef _DEBUG_ + // check validity of option names of _defaultOptionValues + TOptionValues::iterator n2v = _defaultOptionValues.begin(); + for ( ; n2v != _defaultOptionValues.end(); ++n2v ) + ASSERT( _option2value.count( n2v->first )); + ASSERT( _option2value.size() == _defaultOptionValues.size() ); +#endif +} + +//======================================================================= +//function : SetHeightIsRelative +//======================================================================= + +void HYBRIDPlugin_Hypothesis::SetHeightIsRelative(bool isRelative) +{ + if ( myHeightIsRelative != isRelative ) { + myHeightIsRelative = isRelative; + NotifySubMeshesHypothesisModification(); + } +} + +//======================================================================= +//function : SetBoundaryLayersMaxElemAngle +//======================================================================= + +void HYBRIDPlugin_Hypothesis::SetBoundaryLayersMaxElemAngle( double angle ) +{ + if ( myBoundaryLayersMaxElemAngle != angle ) { + myBoundaryLayersMaxElemAngle = angle; + NotifySubMeshesHypothesisModification(); + } } + //======================================================================= //function : SetLayersOnAllWrap //======================================================================= @@ -199,12 +281,6 @@ void HYBRIDPlugin_Hypothesis::SetToMeshHoles(bool toMesh) bool HYBRIDPlugin_Hypothesis::GetToMeshHoles(bool checkFreeOption) const { - if (checkFreeOption && !myTextOption.empty()) { - if ( myTextOption.find("-c 0")) - return true; - if ( myTextOption.find("-c 1")) - return false; - } return myToMeshHoles; } @@ -309,10 +385,8 @@ HYBRIDPlugin_Hypothesis::OptimizationLevel HYBRIDPlugin_Hypothesis::GetOptimizat //======================================================================= void HYBRIDPlugin_Hypothesis::SetCollisionMode(CollisionMode mode) { - if ( myCollisionMode != mode ) { - myCollisionMode = mode; - NotifySubMeshesHypothesisModification(); - } + SetOptionValue( "collision_mode", mode == Decrease ? "decrease" : "stop" ); + myCollisionMode = mode; } //======================================================================= @@ -366,10 +440,8 @@ HYBRIDPlugin_Hypothesis::ElementGeneration HYBRIDPlugin_Hypothesis::GetElementGe //======================================================================= void HYBRIDPlugin_Hypothesis::SetAddMultinormals(bool toAddMultinormals) { - if ( myAddMultinormals != toAddMultinormals ) { - myAddMultinormals = toAddMultinormals; - NotifySubMeshesHypothesisModification(); - } + SetOptionValue( "add_multinormals", toAddMultinormals ? "yes" : "no" ); + myAddMultinormals = toAddMultinormals; } //======================================================================= @@ -387,10 +459,8 @@ bool HYBRIDPlugin_Hypothesis::GetAddMultinormals() const void HYBRIDPlugin_Hypothesis::SetSmoothNormals(bool toSmoothNormals) { - if ( mySmoothNormals != toSmoothNormals ) { - mySmoothNormals = toSmoothNormals; - NotifySubMeshesHypothesisModification(); - } + SetOptionValue( "smooth_normals", toSmoothNormals ? "yes" : "no" ); + mySmoothNormals = toSmoothNormals; } //======================================================================= @@ -471,10 +541,8 @@ double HYBRIDPlugin_Hypothesis::GetCoreSize() const void HYBRIDPlugin_Hypothesis::SetMultinormalsAngle(double toMultinormalsAngle) { - if ( myMultinormalsAngle != toMultinormalsAngle ) { - myMultinormalsAngle = toMultinormalsAngle; - NotifySubMeshesHypothesisModification(); - } + SetOptionValue( "multinormal_angle_threshold", SMESH_Comment( toMultinormalsAngle )); + myMultinormalsAngle = toMultinormalsAngle; } //======================================================================= @@ -664,9 +732,16 @@ bool HYBRIDPlugin_Hypothesis::GetToRemoveCentralPoint() const void HYBRIDPlugin_Hypothesis::SetAdvancedOption(const std::string& option) { - if ( myTextOption != option ) { - myTextOption = option; - NotifySubMeshesHypothesisModification(); + size_t wsPos = option.find(' '); + if ( wsPos == std::string::npos ) + { + SetOptionValue( option, "" ); + } + else + { + std::string opt( option, 0, wsPos ); + std::string val( option, wsPos + 1 ); + SetOptionValue( opt, val ); } } @@ -676,7 +751,23 @@ void HYBRIDPlugin_Hypothesis::SetAdvancedOption(const std::string& option) std::string HYBRIDPlugin_Hypothesis::GetAdvancedOption() const { - return myTextOption; + SMESH_Comment txt; + + TOptionValues::const_iterator o2v = _option2value.begin(); + for ( ; o2v != _option2value.end(); ++o2v ) + if ( !o2v->second.empty() ) + { + if ( !txt.empty() ) + txt << " "; + txt << o2v->first << " " << o2v->second; + } + for ( o2v = _customOption2value.begin(); o2v != _customOption2value.end(); ++o2v ) + { + if ( !txt.empty() ) + txt << " "; + txt << o2v->first << " " << o2v->second; + } + return txt; } //======================================================================= @@ -685,10 +776,8 @@ std::string HYBRIDPlugin_Hypothesis::GetAdvancedOption() const void HYBRIDPlugin_Hypothesis::SetGradation(double gradation) { - if ( myGradation != gradation ) { - myGradation = gradation; - NotifySubMeshesHypothesisModification(); - } + SetOptionValue( "gradation", SMESH_Comment( gradation )); + myGradation = gradation; } //======================================================================= @@ -1395,11 +1484,11 @@ std::ostream & HYBRIDPlugin_Hypothesis::SaveTo(std::ostream & save) save << myVerboseLevel << " "; save << myCoreSize << " "; - if (!myTextOption.empty()) { - save << "__OPTIONS_BEGIN__ "; - save << myTextOption << " "; - save << "__OPTIONS_END__ "; - } + // if (!myTextOption.empty()) { + // save << "__OPTIONS_BEGIN__ "; + // save << myTextOption << " "; + // save << "__OPTIONS_END__ "; + // } THYBRIDEnforcedVertexList::iterator it = _enfVertexList.begin(); @@ -1482,6 +1571,23 @@ std::ostream & HYBRIDPlugin_Hypothesis::SaveTo(std::ostream & save) for ( size_t i = 0; i < myFacesWithSnapping.size(); ++i ) save << " " << myFacesWithSnapping[i]; + // New options in 2.9.6 (issue #17784) + + save << " " << myHeightIsRelative; + save << " " << myBoundaryLayersMaxElemAngle; + save << " " << myCollisionMode; + save << " " << myGradation; + save << " " << myOptimizationLevel; + + save << " " << _option2value.size(); + TOptionValues::iterator o2v = _option2value.begin(); + for ( ; o2v != _option2value.end(); ++o2v ) + save << " -" << o2v->first << " -" << o2v->second; + + save << " " << _customOption2value.size(); + for ( o2v = _customOption2value.begin(); o2v != _customOption2value.end(); ++o2v ) + save << " -" << o2v->first << " -" << o2v->second; + return save; } @@ -1587,12 +1693,6 @@ std::istream & HYBRIDPlugin_Hypothesis::LoadFrom(std::istream & load) bool hasEnforcedMeshes = false; isOK = static_cast(load >> separator); - if ( isOK && ( separator == "0" || separator == "1" )) - { - myToMakeGroupsOfDomains = ( separator == "1" ); - isOK = static_cast(load >> separator); - } - if (isOK) { if (separator == "__OPTIONS_BEGIN__") hasOptions = true; @@ -1608,15 +1708,10 @@ std::istream & HYBRIDPlugin_Hypothesis::LoadFrom(std::istream & load) isOK = static_cast(load >> txt); if (isOK) { if (txt == "__OPTIONS_END__") { - if (!myTextOption.empty()) { - // Remove last space - myTextOption.erase(myTextOption.end()-1); - } isOK = false; break; } - myTextOption += txt; - myTextOption += " "; + // myTextOption += txt; } } } @@ -1841,6 +1936,35 @@ std::istream & HYBRIDPlugin_Hypothesis::LoadFrom(std::istream & load) } } + // New options in 2.9.6 (issue #17784) + + if ( static_cast(load >> i)) + { + myHeightIsRelative = (bool) i; + load >> myBoundaryLayersMaxElemAngle; + load >> myCollisionMode; + load >> myGradation; + load >> myOptimizationLevel; + + std::string option, value; + if ( static_cast( load >> i ) && i >= 0 ) + { + for ( int nbRead = 0; nbRead < i; ++nbRead ) + { + load >> option >> value; + _option2value[ std::string( option, 1 )] = std::string( value, 1 ); + } + } + if ( static_cast( load >> i ) && i >= 0 ) + { + for ( int nbRead = 0; nbRead < i; ++nbRead ) + { + load >> option >> value; + _customOption2value[ std::string( option, 1 )] = std::string( value, 1 ); + } + } + } + return load; } @@ -1853,7 +1977,6 @@ bool HYBRIDPlugin_Hypothesis::SetParametersByMesh(const SMESH_Mesh* ,const TopoD return false; } - //================================================================================ /*! * \brief Sets myToMakeGroupsOfDomains depending on whether theMesh is on shape or not @@ -1877,27 +2000,15 @@ std::string HYBRIDPlugin_Hypothesis::CommandToRun(const HYBRIDPlugin_Hypothesis* SMESH_Mesh& mesh) { SMESH_Comment cmd = GetExeName(); - // check if any option is overridden by hyp->myTextOption - bool p_h = ( hyp && hyp->myTextOption.find("-h") != std::string::npos ); - bool p_v = ( hyp && hyp->myTextOption.find("-v") != std::string::npos ); - bool p_i = ( hyp && hyp->myTextOption.find("-i") != std::string::npos ); - bool p_o = ( hyp && hyp->myTextOption.find("-o") != std::string::npos ); - bool p_mnot = ( hyp && hyp->myTextOption.find("--max_number_of_threads ") != std::string::npos ); - bool p_blsi = ( hyp && hyp->myTextOption.find("--boundary_layer_surface_tags ") != std::string::npos ); - bool p_blii = ( hyp && hyp->myTextOption.find("--boundary_layer_imprint_tags ") != std::string::npos ); - bool p_blsd = ( hyp && hyp->myTextOption.find("--normal_direction ") != std::string::npos ); - bool p_hotfl = ( hyp && hyp->myTextOption.find("--boundary_layer_global_initial_height ") != std::string::npos ); - bool p_nobl = ( hyp && hyp->myTextOption.find("--number_of_boundary_layers ") != std::string::npos ); - bool p_blgp = ( hyp && hyp->myTextOption.find("--boundary_layer_geometric_progression ") != std::string::npos ); - bool p_eg = ( hyp && hyp->myTextOption.find("--element_generation ") != std::string::npos ); - bool p_cm = ( hyp && hyp->myTextOption.find("--collision_mode ") != std::string::npos ); - bool p_am = ( hyp && hyp->myTextOption.find("--add_multinormals ") != std::string::npos ); - bool p_cs = ( hyp && hyp->myTextOption.find("--global_physical_size ") != std::string::npos ); - bool p_mat = ( hyp && hyp->myTextOption.find("--multinormal_angle_threshold ") != std::string::npos ); - bool p_sn = ( hyp && hyp->myTextOption.find("--smooth_normals ") != std::string::npos ); - - //missing options : - //- boundary_layer_max_element_angle + // check if any option is overridden by hyp->_option2value + bool p_h = ( hyp && hyp->HasOptionDefined("-h")); + bool p_v = ( hyp && hyp->HasOptionDefined("-v")); + bool p_blsd = ( hyp && hyp->HasOptionDefined("--normal_direction ")); + bool p_hotfl = ( hyp && hyp->HasOptionDefined("--boundary_layer_global_initial_height ")); + bool p_nobl = ( hyp && hyp->HasOptionDefined("--number_of_boundary_layers ")); + bool p_blgp = ( hyp && hyp->HasOptionDefined("--boundary_layer_geometric_progression ")); + bool p_eg = ( hyp && hyp->HasOptionDefined("--element_generation ")); + bool p_cs = ( hyp && hyp->HasOptionDefined("--global_physical_size ")); bool nolayers = false; bool layersOnAllWrap = hyp ? hyp->myLayersOnAllWrap : DefaultLayersOnAllWrap(); @@ -1915,9 +2026,6 @@ std::string HYBRIDPlugin_Hypothesis::CommandToRun(const HYBRIDPlugin_Hypothesis* if ( !p_v && hyp ) cmd << " --verbose " << hyp->myVerboseLevel; - if ( !p_mnot && hyp ) - cmd << " --max_number_of_threads " << 8; //TODO getenv NB CPU - //no layers? if ( !p_nobl && hyp ) { if ( hyp->myNbOfBoundaryLayers < 1 ) nolayers = true; @@ -1925,18 +2033,20 @@ std::string HYBRIDPlugin_Hypothesis::CommandToRun(const HYBRIDPlugin_Hypothesis* if ( !p_hotfl && hyp ) { if ( hyp->myHeightFirstLayer < 1e-50 ) nolayers = true; } - + if ( !p_blsd && hyp ) { if ( hyp->myBoundaryLayersGrowth >= 0 && hyp->myBoundaryLayersGrowth <= 1 ) { const char* value[] = { "-1" , "1" }; // -1 == inside cmd << " --normal_direction " << value[ hyp->myBoundaryLayersGrowth ]; } } - + if ( !p_hotfl && hyp ) { cmd << " --boundary_layer_global_initial_height " << hyp->myHeightFirstLayer; } - + if ( hyp && hyp->GetHeightIsRelative() ) + cmd << " --boundary_layer_height_relative_to_local_surface_size yes"; + if ( !p_nobl && hyp ) { cmd << " --number_of_boundary_layers " << ( nolayers ? 0 : hyp->myNbOfBoundaryLayers ); } @@ -1948,7 +2058,11 @@ std::string HYBRIDPlugin_Hypothesis::CommandToRun(const HYBRIDPlugin_Hypothesis* if ( !nolayers && hyp ) { cmd << " --boundary_layer_size_mode " << ( layersOnAllWrap ? "global" : "local" ); - + + if ( hyp->GetBoundaryLayersMaxElemAngle() != hyp->DefaultBoundaryLayersMaxElemAngle() ) + cmd << " --boundary_layer_max_element_angle " + << SMESH_Comment( hyp->GetBoundaryLayersMaxElemAngle() ); + if ( !layersOnAllWrap ) { // faces with layers @@ -1979,50 +2093,53 @@ std::string HYBRIDPlugin_Hypothesis::CommandToRun(const HYBRIDPlugin_Hypothesis* } if ( !p_eg && hyp ) { - if ( hyp->myElementGeneration >= 0 && hyp->myElementGeneration <= 2 ) { - const char* value[] = { "tetra-dominant" , "hexa-dominant", "cartesian_core" }; + if ( hyp->myElementGeneration >= 0 && hyp->myElementGeneration <= 3 ) { + const char* value[] = { "tetra_dominant" , "hexa_dominant", "cartesian_core", "extrusion_only" }; cmd << " --element_generation " << value[ hyp->myElementGeneration ]; } } if ( !p_cs && hyp ) { - if ( hyp->myCoreSize >= 0 ) { + if ( hyp->myCoreSize > 0 ) { cmd << " --global_physical_size " << hyp->myCoreSize; } } - if ( !p_cm && hyp ) { - if ( hyp->myCollisionMode >= 0 && hyp->myCollisionMode <= 1 ) { - const char* value[] = { "decrease" , "stop" }; - cmd << " --collision_mode " << value[ hyp->myCollisionMode ]; + if ( hyp ) + { + // options as text + std::string option, value; + bool isDefault; + const TOptionValues* options[] = { & hyp->_option2value, & hyp->_customOption2value }; + for ( int iOp = 0; iOp < 2; ++iOp ) + { + TOptionValues::const_iterator o2v = options[iOp]->begin(); + for ( ; o2v != options[iOp]->end(); ++o2v ) + { + option = o2v->first; + value = hyp->GetOptionValue( option, &isDefault ); + + if ( isDefault ) + continue; + if ( value.empty() ) + { + if ( hyp->_defaultOptionValues.count( option )) + continue; // non-custom option with no value + } + if ( option[0] != '-' ) + cmd << " --"; + else + cmd << " "; + cmd << option << " " << value; + } } } - - if ( !p_am && hyp ) { - int res = hyp->myAddMultinormals ? 0 : 1 ; - const char* value[] = { "yes" , "no" }; - cmd << " --add_multinormals " << value[ res ]; - } - - if ( !p_mat && hyp ) { - cmd << " --multinormal_angle_threshold " << hyp->myMultinormalsAngle; - } - - if ( !p_sn && hyp ) { - int res = hyp->mySmoothNormals ? 0 : 1 ; - const char* value[] = { "yes" , "no" }; - cmd << " --smooth_normals " << value[ res ]; - } - // options as text - if ( hyp && !hyp->myTextOption.empty() ) { - cmd += " " + hyp->myTextOption; - } #ifdef WIN32 cmd << " < NUL"; #endif //std::cout << "!!!!!CommandToRun end " << cmd << std::endl; - + return cmd; } @@ -2067,58 +2184,265 @@ std::string HYBRIDPlugin_Hypothesis::GetExeName() #endif } +//============================================================================= +void HYBRIDPlugin_Hypothesis::SetOptionValue(const std::string& optionName, + const std::string& optionValue) + throw (std::invalid_argument) +{ + TOptionValues::iterator op_val = _option2value.find(optionName); + if (op_val == _option2value.end()) + { + op_val = _customOption2value.find( optionName ); + if ( op_val != _customOption2value.end() && op_val->second != optionValue ) + NotifySubMeshesHypothesisModification(); + _customOption2value[ optionName ] = optionValue; + return; + } + + if (op_val->second != optionValue) + { + const char* ptr = optionValue.c_str(); + // strip white spaces + while (ptr[0] == ' ') + ptr++; + int i = strlen(ptr); + while (i != 0 && ptr[i - 1] == ' ') + i--; + // check value type + bool typeOk = true; + std::string typeName; + if (i == 0) { + // empty string + } else if (_charOptions.count(optionName)) { + // do not check strings + } else if (_doubleOptions.count(optionName)) { + // check if value is double + ToDbl(ptr, &typeOk); + typeName = "real"; + } else if (_boolOptions.count(optionName)) { + // check if value is bool + ToBool(ptr, &typeOk); + typeName = "bool"; + } else { + // check if value is int + ToInt(ptr, &typeOk); + typeName = "integer"; + } + if ( typeOk ) // check some specific values ? + { + } + if ( !typeOk ) + { + std::string msg = "Advanced option '" + optionName + "' = '" + optionValue + "' but must be " + typeName; + throw std::invalid_argument(msg); + } + std::string value( ptr, i ); + if ( _defaultOptionValues[ optionName ] == value ) + value.clear(); + + op_val->second = value; + + NotifySubMeshesHypothesisModification(); + } +} + +//============================================================================= +//! Return option value. If isDefault provided, it can be a default value, +// then *isDefault == true. If isDefault is not provided, the value will be +// empty if it equals a default one. +std::string HYBRIDPlugin_Hypothesis::GetOptionValue(const std::string& optionName, + bool* isDefault) const + throw (std::invalid_argument) +{ + TOptionValues::const_iterator op_val = _option2value.find(optionName); + if (op_val == _option2value.end()) + { + op_val = _customOption2value.find(optionName); + if (op_val == _customOption2value.end()) + { + std::string msg = "Unknown MG-Tetra option: <" + optionName + ">"; + throw std::invalid_argument(msg); + } + } + std::string val = op_val->second; + if ( isDefault ) *isDefault = ( val.empty() ); + + if ( val.empty() && isDefault ) + { + op_val = _defaultOptionValues.find( optionName ); + if (op_val != _defaultOptionValues.end()) + val = op_val->second; + } + return val; +} + + +//============================================================================= +bool HYBRIDPlugin_Hypothesis::HasOptionDefined( const std::string& optionName ) const +{ + bool isDefault = false; + try + { + GetOptionValue( optionName, &isDefault ); + } + catch ( std::invalid_argument ) + { + return false; + } + return !isDefault; +} + +//============================================================================= +void HYBRIDPlugin_Hypothesis::ClearOption(const std::string& optionName) +{ + TOptionValues::iterator op_val = _customOption2value.find(optionName); + if (op_val != _customOption2value.end()) + _customOption2value.erase(op_val); + else { + op_val = _option2value.find(optionName); + if (op_val != _option2value.end()) + op_val->second.clear(); + } +} + +//============================================================================= +HYBRIDPlugin_Hypothesis::TOptionValues HYBRIDPlugin_Hypothesis::GetOptionValues() const +{ + TOptionValues vals; + TOptionValues::const_iterator op_val = _option2value.begin(); + for ( ; op_val != _option2value.end(); ++op_val ) + vals.insert( make_pair( op_val->first, GetOptionValue( op_val->first, GET_DEFAULT() ))); + + return vals; +} + +//================================================================================ +/*! + * \brief Converts a string to a bool + */ +//================================================================================ + +bool HYBRIDPlugin_Hypothesis::ToBool(const std::string& str, bool* isOk ) + throw (std::invalid_argument) +{ + std::string s = str; + if ( isOk ) *isOk = true; + + for ( size_t i = 0; i <= s.size(); ++i ) + s[i] = tolower( s[i] ); + + if ( s == "1" || s == "true" || s == "active" || s == "yes" ) + return true; + + if ( s == "0" || s == "false" || s == "inactive" || s == "no" ) + return false; + + if ( isOk ) + *isOk = false; + else { + std::string msg = "Not a Boolean value:'" + str + "'"; + throw std::invalid_argument(msg); + } + return false; +} + +//================================================================================ +/*! + * \brief Converts a string to a real value + */ +//================================================================================ + +double HYBRIDPlugin_Hypothesis::ToDbl(const std::string& str, bool* isOk ) + throw (std::invalid_argument) +{ + if ( str.empty() ) throw std::invalid_argument("Empty value provided"); + + char * endPtr; + double val = strtod(&str[0], &endPtr); + bool ok = (&str[0] != endPtr); + + if ( isOk ) *isOk = ok; + + if ( !ok ) + { + std::string msg = "Not a real value:'" + str + "'"; + throw std::invalid_argument(msg); + } + return val; +} + //================================================================================ /*! -* \brief Return the enforced vertices -*/ + * \brief Converts a string to a integer value + */ //================================================================================ +int HYBRIDPlugin_Hypothesis::ToInt(const std::string& str, bool* isOk ) + throw (std::invalid_argument) +{ + if ( str.empty() ) throw std::invalid_argument("Empty value provided"); + + char * endPtr; + int val = (int)strtol( &str[0], &endPtr, 10); + bool ok = (&str[0] != endPtr); + + if ( isOk ) *isOk = ok; + + if ( !ok ) + { + std::string msg = "Not an integer value:'" + str + "'"; + throw std::invalid_argument(msg); + } + return val; +} + + HYBRIDPlugin_Hypothesis::THYBRIDEnforcedVertexList HYBRIDPlugin_Hypothesis::GetEnforcedVertices(const HYBRIDPlugin_Hypothesis* hyp) { - return hyp ? hyp->_GetEnforcedVertices():DefaultHYBRIDEnforcedVertexList(); + return hyp ? hyp->_GetEnforcedVertices():THYBRIDEnforcedVertexList(); } HYBRIDPlugin_Hypothesis::THYBRIDEnforcedVertexCoordsValues HYBRIDPlugin_Hypothesis::GetEnforcedVerticesCoordsSize (const HYBRIDPlugin_Hypothesis* hyp) { - return hyp ? hyp->_GetEnforcedVerticesCoordsSize(): DefaultHYBRIDEnforcedVertexCoordsValues(); + return hyp ? hyp->_GetEnforcedVerticesCoordsSize(): THYBRIDEnforcedVertexCoordsValues(); } HYBRIDPlugin_Hypothesis::THYBRIDEnforcedVertexEntryValues HYBRIDPlugin_Hypothesis::GetEnforcedVerticesEntrySize (const HYBRIDPlugin_Hypothesis* hyp) { - return hyp ? hyp->_GetEnforcedVerticesEntrySize(): DefaultHYBRIDEnforcedVertexEntryValues(); + return hyp ? hyp->_GetEnforcedVerticesEntrySize():THYBRIDEnforcedVertexEntryValues(); } HYBRIDPlugin_Hypothesis::TCoordsHYBRIDEnforcedVertexMap HYBRIDPlugin_Hypothesis::GetEnforcedVerticesByCoords (const HYBRIDPlugin_Hypothesis* hyp) { - return hyp ? hyp->_GetEnforcedVerticesByCoords(): DefaultCoordsHYBRIDEnforcedVertexMap(); + return hyp ? hyp->_GetEnforcedVerticesByCoords():TCoordsHYBRIDEnforcedVertexMap(); } HYBRIDPlugin_Hypothesis::TGeomEntryHYBRIDEnforcedVertexMap HYBRIDPlugin_Hypothesis::GetEnforcedVerticesByEntry (const HYBRIDPlugin_Hypothesis* hyp) { - return hyp ? hyp->_GetEnforcedVerticesByEntry(): DefaultGeomEntryHYBRIDEnforcedVertexMap(); + return hyp ? hyp->_GetEnforcedVerticesByEntry():TGeomEntryHYBRIDEnforcedVertexMap(); } HYBRIDPlugin_Hypothesis::TIDSortedNodeGroupMap HYBRIDPlugin_Hypothesis::GetEnforcedNodes(const HYBRIDPlugin_Hypothesis* hyp) { - return hyp ? hyp->_GetEnforcedNodes():DefaultIDSortedNodeGroupMap(); + return hyp ? hyp->_GetEnforcedNodes():TIDSortedNodeGroupMap(); } HYBRIDPlugin_Hypothesis::TIDSortedElemGroupMap HYBRIDPlugin_Hypothesis::GetEnforcedEdges(const HYBRIDPlugin_Hypothesis* hyp) { - return hyp ? hyp->_GetEnforcedEdges():DefaultIDSortedElemGroupMap(); + return hyp ? hyp->_GetEnforcedEdges():TIDSortedElemGroupMap(); } HYBRIDPlugin_Hypothesis::TIDSortedElemGroupMap HYBRIDPlugin_Hypothesis::GetEnforcedTriangles(const HYBRIDPlugin_Hypothesis* hyp) { - return hyp ? hyp->_GetEnforcedTriangles():DefaultIDSortedElemGroupMap(); + return hyp ? hyp->_GetEnforcedTriangles():TIDSortedElemGroupMap(); } HYBRIDPlugin_Hypothesis::TID2SizeMap HYBRIDPlugin_Hypothesis::GetNodeIDToSizeMap(const HYBRIDPlugin_Hypothesis* hyp) { - return hyp ? hyp->_GetNodeIDToSizeMap(): DefaultID2SizeMap(); + return hyp ? hyp->_GetNodeIDToSizeMap():TID2SizeMap(); } HYBRIDPlugin_Hypothesis::TSetStrings HYBRIDPlugin_Hypothesis::GetGroupsToRemove(const HYBRIDPlugin_Hypothesis* hyp) { - return hyp ? hyp->_GetGroupsToRemove(): DefaultGroupsToRemove(); + return hyp ? hyp->_GetGroupsToRemove():TSetStrings(); } diff --git a/src/HYBRIDPlugin/HYBRIDPlugin_Hypothesis.hxx b/src/HYBRIDPlugin/HYBRIDPlugin_Hypothesis.hxx index e365af8..93832c6 100644 --- a/src/HYBRIDPlugin/HYBRIDPlugin_Hypothesis.hxx +++ b/src/HYBRIDPlugin/HYBRIDPlugin_Hypothesis.hxx @@ -119,11 +119,18 @@ public: typedef std::set TSetStrings; static const char* GetHypType() { return "HYBRID_Parameters"; } + + /*! - * To mesh "holes" in a solid or not. Default is to mesh. + * Sizes of boundary layers are relative to the surface size. Default no */ - void SetToMeshHoles(bool toMesh); - bool GetToMeshHoles(bool checkFreeOption = false) const; + void SetHeightIsRelative( bool isRelative ); + bool GetHeightIsRelative() const { return myHeightIsRelative; } + /*! + * Maximum internal angles of boundary elements (in degree) + */ + void SetBoundaryLayersMaxElemAngle( double angle ); + double GetBoundaryLayersMaxElemAngle() const { return myBoundaryLayersMaxElemAngle; } /*! * To mesh layers on all wrap. Default is yes. */ @@ -173,7 +180,7 @@ public: * Collision Mode: 0-decrease, 1-stop. Default is decrease */ enum CollisionMode { Decrease = 0, Stop }; - void SetCollisionMode(CollisionMode level); + void SetCollisionMode(CollisionMode mode); CollisionMode GetCollisionMode() const; /*! * BoundaryLayersGrowth: 0-Layer_Growth_Inward, 1-Layer_Growth_Outward. Default is Layer_Growth_Inward @@ -184,7 +191,7 @@ public: /*! * ElementGeneration: 0-Generation_Tetra_Dominant, 1-Generation_Hexa_Dominant, 2-Generation_Cartesian_Core. Default is Generation_Tetra_Dominant */ - enum ElementGeneration { Generation_Tetra_Dominant = 0, Generation_Hexa_Dominant, Generation_Cartesian_Core }; + enum ElementGeneration { Generation_Tetra_Dominant = 0, Generation_Hexa_Dominant, Generation_Cartesian_Core, Generation_Extrusion_Only }; void SetElementGeneration(ElementGeneration level); ElementGeneration GetElementGeneration() const; /*! @@ -282,29 +289,38 @@ public: void SetAdvancedOption(const std::string& option); std::string GetAdvancedOption() const; /*! - * To define the volumic gradation - */ + * To define the volumic gradation + */ void SetGradation(double gradation); double GetGradation() const ; /*! - * Print log in standard output - */ + * Print log in standard output + */ void SetStandardOutputLog(bool logInStandardOutput); bool GetStandardOutputLog() const ; /*! - * Remove log file on success - */ + * Remove log file on success + */ void SetRemoveLogOnSuccess(bool removeLogOnSuccess); bool GetRemoveLogOnSuccess() const ; - - -// struct TEnforcedEdge { -// long ID; -// long node1; -// long node2; -// std::string groupName; -// }; - + + + typedef std::map< std::string, std::string > TOptionValues; + typedef std::set< std::string > TOptionNames; + + void SetOptionValue(const std::string& optionName, + const std::string& optionValue) throw (std::invalid_argument); + std::string GetOptionValue(const std::string& optionName, + bool* isDefault=0) const throw (std::invalid_argument); + bool HasOptionDefined( const std::string& optionName ) const; + void ClearOption(const std::string& optionName); + TOptionValues GetOptionValues() const; + const TOptionValues& GetCustomOptionValues() const { return _customOption2value; } + + static bool ToBool(const std::string& str, bool* isOk=0) throw (std::invalid_argument); + static double ToDbl(const std::string& str, bool* isOk=0) throw (std::invalid_argument); + static int ToInt(const std::string& str, bool* isOk=0) throw (std::invalid_argument); + /*! * \brief Return command to run hybrid mesher excluding file prefix (-f) @@ -372,6 +388,8 @@ public: static bool GetToMakeGroupsOfDomains(const HYBRIDPlugin_Hypothesis* hyp); void ClearGroupsToRemove(); + static bool DefaultHeightIsRelative() { return false; } + static double DefaultBoundaryLayersMaxElemAngle() { return 165.0; } static bool DefaultMeshHoles(); static bool DefaultLayersOnAllWrap(); static bool DefaultToMakeGroupsOfDomains(); @@ -398,28 +416,16 @@ public: static double DefaultBoundaryLayersProgression(); static double DefaultCoreSize(); static double DefaultMultinormalsAngle(); - - static THYBRIDEnforcedVertex DefaultHYBRIDEnforcedVertex() {return THYBRIDEnforcedVertex();} - static THYBRIDEnforcedVertexList DefaultHYBRIDEnforcedVertexList() {return THYBRIDEnforcedVertexList();} - static THYBRIDEnforcedVertexCoordsValues DefaultHYBRIDEnforcedVertexCoordsValues() {return THYBRIDEnforcedVertexCoordsValues();} - static THYBRIDEnforcedVertexEntryValues DefaultHYBRIDEnforcedVertexEntryValues() {return THYBRIDEnforcedVertexEntryValues();} - static TCoordsHYBRIDEnforcedVertexMap DefaultCoordsHYBRIDEnforcedVertexMap() {return TCoordsHYBRIDEnforcedVertexMap();} - static TGeomEntryHYBRIDEnforcedVertexMap DefaultGeomEntryHYBRIDEnforcedVertexMap() {return TGeomEntryHYBRIDEnforcedVertexMap();} - static TGroupNameHYBRIDEnforcedVertexMap DefaultGroupNameHYBRIDEnforcedVertexMap() {return TGroupNameHYBRIDEnforcedVertexMap();} - - static THYBRIDEnforcedMesh DefaultHYBRIDEnforcedMesh() {return THYBRIDEnforcedMesh();} - static THYBRIDEnforcedMeshList DefaultHYBRIDEnforcedMeshList() {return THYBRIDEnforcedMeshList();} - static TEntryHYBRIDEnforcedMeshListMap DefaultEntryHYBRIDEnforcedMeshListMap() {return TEntryHYBRIDEnforcedMeshListMap();} - static TIDSortedNodeGroupMap DefaultIDSortedNodeGroupMap() {return TIDSortedNodeGroupMap();} - static TIDSortedElemGroupMap DefaultIDSortedElemGroupMap() {return TIDSortedElemGroupMap();} - static TID2SizeMap DefaultID2SizeMap() {return TID2SizeMap();} - static TSetStrings DefaultGroupsToRemove() {return TSetStrings();} - + + /*! + * To mesh "holes" in a solid or not. Default is to mesh. + */ + void SetToMeshHoles(bool toMesh); + bool GetToMeshHoles(bool checkFreeOption = false) const; + // Persistence virtual std::ostream & SaveTo(std::ostream & save); virtual std::istream & LoadFrom(std::istream & load); - friend HYBRIDPLUGIN_EXPORT std::ostream & operator <<(std::ostream & save, HYBRIDPlugin_Hypothesis & hyp); - friend HYBRIDPLUGIN_EXPORT std::istream & operator >>(std::istream & load, HYBRIDPlugin_Hypothesis & hyp); /*! * \brief Does nothing @@ -433,38 +439,50 @@ public: private: - bool myToMeshHoles; + short myNbOfBoundaryLayers; + double myHeightFirstLayer; + bool myHeightIsRelative; + short myBoundaryLayersGrowth; + double myBoundaryLayersMaxElemAngle; + double myBoundaryLayersProgression; + + short myElementGeneration; + double myCoreSize; + bool myLayersOnAllWrap; - std::vector myFacesWithLayers; std::vector myFacesWithImprinting; std::vector myFacesWithSnapping; - bool myToMakeGroupsOfDomains; - double myMaximumMemory; - double myInitialMemory; - short myOptimizationLevel; + std::vector myFacesWithLayers; + + // advanced (main params before redesign for 9.6.2) short myCollisionMode; - short myBoundaryLayersGrowth; - short myElementGeneration; - bool myKeepFiles; + bool myAddMultinormals; + bool mySmoothNormals; + double myMultinormalsAngle; + double myGradation; + std::string myWorkingDirectory; short myVerboseLevel; - bool myToCreateNewNodes; - bool myToUseBoundaryRecoveryVersion; - bool myToUseFemCorrection; - bool myToRemoveCentralPoint; bool myLogInStandardOutput; bool myRemoveLogOnSuccess; - std::string myTextOption; - double myGradation; + bool myKeepFiles; + + TOptionValues _option2value, _customOption2value; // user defined values + TOptionValues _defaultOptionValues; // default values + TOptionNames _doubleOptions, _charOptions, _boolOptions; // to find a type of option + + short myOptimizationLevel; // missing from plugin + bool myToMakeGroupsOfDomains; // missing from plugin + + bool myToMeshHoles; // missing from hybrid + double myMaximumMemory; // missing from hybrid + double myInitialMemory; // missing from hybrid + bool myToCreateNewNodes; // missing from hybrid + bool myToUseBoundaryRecoveryVersion; // missing from hybrid + bool myToUseFemCorrection; // missing from hybrid + bool myToRemoveCentralPoint; // missing from hybrid + - bool myAddMultinormals; - bool mySmoothNormals; - double myHeightFirstLayer; - double myBoundaryLayersProgression; - double myCoreSize; - double myMultinormalsAngle; - short myNbOfBoundaryLayers; - THYBRIDEnforcedVertexList _enfVertexList; THYBRIDEnforcedVertexCoordsValues _enfVertexCoordsSizeList; THYBRIDEnforcedVertexEntryValues _enfVertexEntrySizeList; diff --git a/src/HYBRIDPlugin/HYBRIDPlugin_Hypothesis_i.cxx b/src/HYBRIDPlugin/HYBRIDPlugin_Hypothesis_i.cxx index 3643e22..c1755cd 100644 --- a/src/HYBRIDPlugin/HYBRIDPlugin_Hypothesis_i.cxx +++ b/src/HYBRIDPlugin/HYBRIDPlugin_Hypothesis_i.cxx @@ -64,6 +64,47 @@ HYBRIDPlugin_Hypothesis_i::~HYBRIDPlugin_Hypothesis_i() { } +//======================================================================= +/*! + * Sizes of boundary layers are relative to the surface size. Default no + */ +//======================================================================= + +void HYBRIDPlugin_Hypothesis_i::SetHeightIsRelative( CORBA::Boolean isRelative ) +{ + ASSERT(myBaseImpl); + if ( GetImpl()->GetHeightIsRelative() != isRelative ) + { + this->GetImpl()->SetHeightIsRelative( isRelative ); + SMESH::TPythonDump() << _this() << ".SetHeightIsRelative( " << isRelative << " )"; + } +} + +CORBA::Boolean HYBRIDPlugin_Hypothesis_i::GetHeightIsRelative() +{ + return this->GetImpl()->GetHeightIsRelative(); +} + +//======================================================================= +/*! + * Maximum internal angles of boundary elements (in degree) + */ +//======================================================================= + +void HYBRIDPlugin_Hypothesis_i::SetBoundaryLayersMaxElemAngle( CORBA::Double angle ) +{ + if ( GetImpl()->GetBoundaryLayersMaxElemAngle() != angle ) + { + this->GetImpl()->SetBoundaryLayersMaxElemAngle( angle ); + SMESH::TPythonDump() << _this() << ".SetBoundaryLayersMaxElemAngle( " << angle << " )"; + } +} + +CORBA::Double HYBRIDPlugin_Hypothesis_i::GetBoundaryLayersMaxElemAngle() +{ + return this->GetImpl()->GetBoundaryLayersMaxElemAngle(); +} + //======================================================================= //function : SetLayersOnAllWrap //======================================================================= @@ -475,6 +516,289 @@ CORBA::Boolean HYBRIDPlugin_Hypothesis_i::GetToRemoveCentralPoint() return this->GetImpl()->GetToRemoveCentralPoint(); } +//============================================================================= + +void HYBRIDPlugin_Hypothesis_i::SetOptionValue(const char* optionName, const char* optionValue) + throw (SALOME::SALOME_Exception) +{ + ASSERT(myBaseImpl); + try { + std::string name( optionName ); + while ( !name.empty() && name[0] == '-' ) + name = name.substr(1); + + if ( !optionValue || !optionValue[0] ) + UnsetOption( optionName ); + + // basic options (visible in Advanced table) + + else if ( name == "number_of_boundary_layers" ) + SetNbOfBoundaryLayers( GetImpl()->ToInt( optionValue )); + + else if ( name == "boundary_layer_global_initial_height" ) + SetHeightFirstLayer( GetImpl()->ToDbl( optionValue )); + + else if ( name == "boundary_layer_geometric_progression" ) + SetBoundaryLayersProgression( GetImpl()->ToDbl( optionValue )); + + else if ( name == "boundary_layer_max_element_angle" ) + SetBoundaryLayersMaxElemAngle( GetImpl()->ToDbl( optionValue )); + + else if ( name == "gradation" ) + SetGradation( GetImpl()->ToDbl( optionValue )); + + else if ( name == "element_generation" ) + switch ( optionValue[0] ) { + case 't': SetElementGeneration( 0 ); break; + case 'h': SetElementGeneration( 1 ); break; + case 'c': SetElementGeneration( 2 ); break; + case 'e': SetElementGeneration( 3 ); break; + default:; + } + else if ( name == "collision_mode" ) // decrease|stop + SetCollisionMode( optionValue[0] != 'd' ); + + else if ( name == "add_multinormals" ) + SetAddMultinormals( GetImpl()->ToBool( optionValue )); + + else if ( name == "multinormal_angle_threshold" ) + SetMultinormalsAngle( GetImpl()->ToDbl( optionValue )); + + else if ( name == "verbose" ) + SetVerboseLevel( GetImpl()->ToInt( optionValue )); + + else if ( name == "max_memory" ) + SetMaximumMemory( GetImpl()->ToInt( optionValue )); + + else if ( name == "automatic_memory" ) + SetInitialMemory( GetImpl()->ToInt( optionValue )); + + else if ( name == "smooth_normals" ) + SetSmoothNormals( GetImpl()->ToBool( optionValue )); + + else if ( name == "optimisation" ) + switch ( optionValue[0] ) { + case 'n': SetOptimizationLevel( 0 ); break; + case 'y': SetOptimizationLevel( 1 ); break; + case 'o': SetOptimizationLevel( 2 ); break; + default:; + } + + // advanced options (for backward compatibility) + // else if ( name == "create_tag_on_collision" || + // name == "tiny_edge_respect_geometry" ) + // AddOption( optionName, optionValue ); + + else { + bool valueChanged = true; + try { + valueChanged = ( this->GetImpl()->GetOptionValue( name ) != optionValue ); + } + catch ( std::invalid_argument ) { + } + if ( valueChanged ) + { + this->GetImpl()->SetOptionValue(optionName, optionValue); + SMESH::TPythonDump() << _this() << ".SetOptionValue( '" << optionName << "', '" << optionValue << "' )"; + } + } + } catch (const std::invalid_argument& ex) { + THROW_SALOME_CORBA_EXCEPTION( ex.what() ,SALOME::BAD_PARAM ); + } catch (SALOME_Exception& ex) { + THROW_SALOME_CORBA_EXCEPTION( ex.what() ,SALOME::BAD_PARAM ); + } +} + +//============================================================================= + +char* HYBRIDPlugin_Hypothesis_i::GetOptionValue(const char* optionName) + throw (SALOME::SALOME_Exception) +{ + ASSERT(myBaseImpl); + try { + bool isDefault; + return CORBA::string_dup(this->GetImpl()->GetOptionValue(optionName,&isDefault).c_str()); + } catch (const std::invalid_argument& ex) { + THROW_SALOME_CORBA_EXCEPTION( ex.what() ,SALOME::BAD_PARAM ); + } catch (SALOME_Exception& ex) { + THROW_SALOME_CORBA_EXCEPTION( ex.what() ,SALOME::BAD_PARAM ); + } + return 0; +} + +//============================================================================= + +void HYBRIDPlugin_Hypothesis_i::UnsetOption(const char* optionName) { + ASSERT(myBaseImpl); + if ( !GetImpl()->GetOptionValue( optionName ).empty() ) + { + this->GetImpl()->ClearOption(optionName); + SMESH::TPythonDump() << _this() << ".UnsetOption( '" << optionName << "' )"; + } +} + +//============================================================================= + +HYBRIDPlugin::string_array* HYBRIDPlugin_Hypothesis_i::GetOptionValues() +{ + HYBRIDPlugin::string_array_var result = new HYBRIDPlugin::string_array(); + + const ::HYBRIDPlugin_Hypothesis::TOptionValues & opts = this->GetImpl()->GetOptionValues(); + result->length(opts.size()); + int i=0; + + bool isDefault; + ::HYBRIDPlugin_Hypothesis::TOptionValues::const_iterator opIt = opts.begin(); + for (; opIt != opts.end(); ++opIt, ++i) + { + std::string name_value_type = opIt->first; + //if (!opIt->second.empty()) + { + name_value_type += ":"; + name_value_type += GetImpl()->GetOptionValue( opIt->first, &isDefault ); + name_value_type += isDefault ? ":0" : ":1"; + } + result[i] = CORBA::string_dup(name_value_type.c_str()); + } + + return result._retn(); +} + +//============================================================================= + +HYBRIDPlugin::string_array* HYBRIDPlugin_Hypothesis_i::GetAdvancedOptionValues() +{ + HYBRIDPlugin::string_array_var result = new HYBRIDPlugin::string_array(); + + const ::HYBRIDPlugin_Hypothesis::TOptionValues & custom_opts = this->GetImpl()->GetCustomOptionValues(); + result->length(custom_opts.size()); + int i=0; + + ::HYBRIDPlugin_Hypothesis::TOptionValues::const_iterator opIt = custom_opts.begin(); + for (; opIt != custom_opts.end(); ++opIt, ++i) { + std::string name_value_type = opIt->first; + if (!opIt->second.empty()) { + name_value_type += ":"; + name_value_type += opIt->second; + name_value_type += ":1"; // user defined + } + result[i] = CORBA::string_dup(name_value_type.c_str()); + } + return result._retn(); +} + +//============================================================================= + +void HYBRIDPlugin_Hypothesis_i::SetOptionValues(const HYBRIDPlugin::string_array& options) + throw (SALOME::SALOME_Exception) +{ + for (CORBA::ULong i = 0; i < options.length(); ++i) + { + std::string name_value_type = options[i].in(); + if(name_value_type.empty()) + continue; + size_t colonPos = name_value_type.find(':'); + std::string name, value; + if (colonPos == std::string::npos) // ':' not found + name = name_value_type; + else { + name = name_value_type.substr(0, colonPos); + if (colonPos < name_value_type.size() - 1 && name_value_type[colonPos] != ' ') { + std::string value_type = name_value_type.substr(colonPos + 1); + colonPos = value_type.find(':'); + value = value_type.substr(0, colonPos); + if (colonPos < value_type.size() - 1 && value_type[colonPos] != ' ') + if ( value_type.substr(colonPos + 1) == "0" ) // is default + value.clear(); + } + } + SetOptionValue(name.c_str(), value.c_str()); + } +} + +//============================================================================= + +void HYBRIDPlugin_Hypothesis_i::SetAdvancedOptionValues(const HYBRIDPlugin::string_array& options) +{ + SMESH::TPythonDump dump; + + std::string optionsAndValues; + for ( CORBA::ULong i = 0; i < options.length(); ++i) { + std::string name_value_type = options[i].in(); + if(name_value_type.empty()) + continue; + size_t colonPos = name_value_type.find(':'); + std::string name, value; + if (colonPos == std::string::npos) // ':' not found + name = name_value_type; + else { + name = name_value_type.substr(0, colonPos); + if (colonPos < name_value_type.size() - 1 && name_value_type[colonPos] != ' ') { + std::string value_type = name_value_type.substr(colonPos + 1); + colonPos = value_type.find(':'); + value = value_type.substr(0, colonPos); + } + } + AddOption(name.c_str(), value.c_str()); + + optionsAndValues += name + " " + value + " "; + } + + if ( !optionsAndValues.empty() ) + dump << _this() << ".SetAdvancedOptions( '" << optionsAndValues.c_str() << "' )"; +} + +//============================================================================= + +void HYBRIDPlugin_Hypothesis_i::SetAdvancedOption(const char* optionsAndValues) + throw (SALOME::SALOME_Exception) +{ + if ( !optionsAndValues ) return; + + SMESH::TPythonDump dump; + + std::istringstream strm( optionsAndValues ); + std::istream_iterator sIt( strm ), sEnd; + for ( int nbPairs = 0; sIt != sEnd; ++nbPairs ) + { + std::string option = *sIt; + if ( ++sIt != sEnd ) + { + std::string value = *sIt; + ++sIt; + AddOption( option.c_str(), value.c_str() ); + } + else + { + if ( nbPairs > 0 ) + THROW_SALOME_CORBA_EXCEPTION( "Uneven number of options and values" ,SALOME::BAD_PARAM ); + AddOption( option.c_str(), "" ); + } + } + dump << _this() << ".SetAdvancedOption( '" << optionsAndValues << "' )"; +} + +//============================================================================= + +void HYBRIDPlugin_Hypothesis_i::AddOption(const char* optionName, const char* optionValue) +{ + ASSERT(myBaseImpl); + bool valueChanged = ( !this->GetImpl()->HasOptionDefined(optionName) || + this->GetImpl()->GetOptionValue(optionName) != optionValue ); + if (valueChanged) { + this->GetImpl()->SetOptionValue(optionName, optionValue); + SMESH::TPythonDump() << _this() << ".SetOptionValue( '" << optionName << "', '" << optionValue << "' )"; + } +} + +//============================================================================= + +char* HYBRIDPlugin_Hypothesis_i::GetOption(const char* optionName) +{ + ASSERT(myBaseImpl); + return CORBA::string_dup(this->GetImpl()->GetOptionValue(optionName).c_str()); +} + //======================================================================= //function : SetTextOption //======================================================================= @@ -494,18 +818,6 @@ char* HYBRIDPlugin_Hypothesis_i::GetTextOption() return CORBA::string_dup( this->GetImpl()->GetAdvancedOption().c_str() ); } -//======================================================================= -//function : SetAdvancedOption -//======================================================================= -void HYBRIDPlugin_Hypothesis_i::SetAdvancedOption(const char* theOptAndVals ) -{ - if ( theOptAndVals && GetImpl()->GetAdvancedOption() != theOptAndVals ) - { - GetImpl()->SetAdvancedOption( theOptAndVals ); - SMESH::TPythonDump() << _this() << ".SetAdvancedOption( '" << theOptAndVals << "' )"; - } -} - //======================================================================= //function : GetAdvancedOption //======================================================================= @@ -612,7 +924,7 @@ void HYBRIDPlugin_Hypothesis_i::SetElementGeneration(CORBA::Short level) ::HYBRIDPlugin_Hypothesis::ElementGeneration l = (::HYBRIDPlugin_Hypothesis::ElementGeneration) level; if ( l < ::HYBRIDPlugin_Hypothesis::Generation_Tetra_Dominant || - l > ::HYBRIDPlugin_Hypothesis::Generation_Cartesian_Core ) + l > ::HYBRIDPlugin_Hypothesis::Generation_Extrusion_Only ) THROW_SALOME_CORBA_EXCEPTION( "Invalid ElementGeneration mode",SALOME::BAD_PARAM ); ASSERT(myBaseImpl); diff --git a/src/HYBRIDPlugin/HYBRIDPlugin_Hypothesis_i.hxx b/src/HYBRIDPlugin/HYBRIDPlugin_Hypothesis_i.hxx index 9fb85a6..ea4bc7b 100644 --- a/src/HYBRIDPlugin/HYBRIDPlugin_Hypothesis_i.hxx +++ b/src/HYBRIDPlugin/HYBRIDPlugin_Hypothesis_i.hxx @@ -49,12 +49,22 @@ class HYBRIDPLUGIN_EXPORT HYBRIDPlugin_Hypothesis_i: // Destructor virtual ~HYBRIDPlugin_Hypothesis_i(); + /*! + * Sizes of boundary layers are relative to the surface size. Default no + */ + void SetHeightIsRelative( CORBA::Boolean isRelative ); + CORBA::Boolean GetHeightIsRelative(); + /*! + * Maximum internal angles of boundary elements (in degree) + */ + void SetBoundaryLayersMaxElemAngle( CORBA::Double angle ); + CORBA::Double GetBoundaryLayersMaxElemAngle(); /*! * To mesh "holes" in a solid or not. Default is to mesh. */ void SetToMeshHoles(CORBA::Boolean toMesh); CORBA::Boolean GetToMeshHoles(); - /*! + /*! * IDs of faces to grow the layers on */ void SetFacesWithLayers(const SMESH::long_array& faceIDs); @@ -148,10 +158,23 @@ class HYBRIDPLUGIN_EXPORT HYBRIDPlugin_Hypothesis_i: */ void SetToRemoveCentralPoint(CORBA::Boolean toRemove); CORBA::Boolean GetToRemoveCentralPoint(); + + void SetOptionValue(const char* optionName, const char* optionValue) throw (SALOME::SALOME_Exception); + char* GetOptionValue(const char* optionName) throw (SALOME::SALOME_Exception); + void UnsetOption(const char* optionName); + + HYBRIDPlugin::string_array* GetOptionValues(); + HYBRIDPlugin::string_array* GetAdvancedOptionValues(); + + void SetOptionValues(const HYBRIDPlugin::string_array& options) throw (SALOME::SALOME_Exception); + void SetAdvancedOptionValues(const HYBRIDPlugin::string_array& options); + + void AddOption(const char* optionName, const char* optionValue); + char* GetOption(const char* optionName); /*! * To set hiden/undocumented/advanced options */ - void SetAdvancedOption(const char* theOptAndVals ); + void SetAdvancedOption(const char* theOptAndVals ) throw (SALOME::SALOME_Exception); char* GetAdvancedOption(); void SetTextOption(const char* option); char* GetTextOption();