Salome HOME
#17784 [EDF] MESH-GEMS-2.9.6 Meshers options
authoreap <eap@opencascade.com>
Wed, 9 Oct 2019 12:49:18 +0000 (15:49 +0300)
committereap <eap@opencascade.com>
Wed, 9 Oct 2019 12:49:18 +0000 (15:49 +0300)
20 files changed:
doc/salome/gui/HYBRIDPLUGIN/images/hybrid_hypothesis_advanced.png
doc/salome/gui/HYBRIDPLUGIN/images/hybrid_hypothesis_arguments.png
doc/salome/gui/HYBRIDPLUGIN/input/hybrid_hypo.doc
idl/HYBRIDPlugin_Algorithm.idl
src/GUI/CMakeLists.txt
src/GUI/HYBRIDPluginGUI_AdvWidget.cxx
src/GUI/HYBRIDPluginGUI_AdvWidget_QTD.ui
src/GUI/HYBRIDPluginGUI_Dlg.h
src/GUI/HYBRIDPluginGUI_HypothesisCreator.cxx
src/GUI/HYBRIDPluginGUI_HypothesisCreator.h
src/GUI/HYBRIDPluginGUI_StdWidget.cxx [new file with mode: 0644]
src/GUI/HYBRIDPluginGUI_StdWidget_QTD.ui [new file with mode: 0644]
src/GUI/HYBRIDPluginGUI_TreeWidget.cxx [new file with mode: 0644]
src/GUI/HYBRIDPluginGUI_TreeWidget.h [new file with mode: 0644]
src/GUI/HYBRIDPlugin_msg_en.ts
src/HYBRIDPlugin/HYBRIDPluginBuilder.py
src/HYBRIDPlugin/HYBRIDPlugin_Hypothesis.cxx
src/HYBRIDPlugin/HYBRIDPlugin_Hypothesis.hxx
src/HYBRIDPlugin/HYBRIDPlugin_Hypothesis_i.cxx
src/HYBRIDPlugin/HYBRIDPlugin_Hypothesis_i.hxx

index 50b6cf4045b4aa262693d4f922aa1cc8ad207beb..bde2d19f9b68af77161f4777c60befe509386b57 100644 (file)
Binary files a/doc/salome/gui/HYBRIDPLUGIN/images/hybrid_hypothesis_advanced.png and b/doc/salome/gui/HYBRIDPLUGIN/images/hybrid_hypothesis_advanced.png differ
index d6c2c431b9a46333b4b08dfa58f342640588a2a3..4d3c808af86c966669783620ca6cd4b246fd5a92 100644 (file)
Binary files a/doc/salome/gui/HYBRIDPLUGIN/images/hybrid_hypothesis_arguments.png and b/doc/salome/gui/HYBRIDPLUGIN/images/hybrid_hypothesis_arguments.png differ
index 71ada995cbd0dd8d303b7c5c46b7234b09a8e64d..e3d8180d87943e77f76bd524e859485aca518a77 100644 (file)
@@ -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: <support@distene.com>
 
-        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 <verbose>] [-i <filein>] [-o <fileout>] \
-        [--global_physical_size <size>] \
-        [--max_number_of_threads <maxthreads>] \
+        [--global_physical_size <size>] [--max_number_of_threads <maxthreads>] \
         [--boundary_layer_size_mode <mode>] \
-        [--number_of_boundary_layers <number>] \
-        [--boundary_layer_global_initial_height <height>] \
+        [--boundary_layer_height_relative_to_local_surface_size <yes|no>] \
+        [--number_of_boundary_layers <number>] [--boundary_layer_global_initial_height <height>] \
         [--boundary_layer_surface_tags <list>] \
         [--boundary_layer_initial_height_on_surface_tags <list>] \
-        [--boundary_layer_imprint_tags <list>] \
         [--boundary_layer_geometric_progression <real>] \
-        [--boundary_layer_max_element_angle <size>] \
-        [--normal_direction <dir>] [--gradation <real>] \
-        [--element_generation <type>] [--collision_mode <mode>] \
-        [--add_multinormals <yes|no>] [--multinormal_angle_threshold <angle>] \
-        [--smooth_normals <yes|no>] [--optimisation <type>]
+        [--boundary_layer_max_element_angle <size>] [--boundary_layer_imprinting <boolean>] \
+        [--boundary_layer_imprinting_tags <list>] [--boundary_layer_snapping <boolean>] \
+        [--boundary_layer_snapping_tags <list>] [--normal_direction <dir>] [--gradation <real>] \
+        [--element_generation <type>] [--collision_mode <mode>] [--add_multinormals <yes|no>] \
+        [--multinormal_angle_threshold <angle>] [--smooth_normals <yes|no>] \
+        [--optimisation <type>]
 
   -h --help
           prints this help.
@@ -91,13 +89,15 @@ MG-HYBRID USAGE
      --boundary_layer_size_mode <mode>
           Sets the behavior for the boundary layer sizes.
           If <mode> 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 <yes|no>
+          If set to yes, the given sizes are relative to the surface size
+          Default: no
+
      --number_of_boundary_layers <number>
           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 <list>
-          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 <list>
-          Comma separated list of initial heights to be used to grow boundary
-          layers.
-
-     --boundary_layer_imprint_tags <list>
-          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 <real>
-          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 <size>
-          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 <boolean>
+          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 <list>
+          Comma separated list of surface references that have to be imprinted by boundary layers.
+
+     --boundary_layer_snapping <boolean>
+          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 <list>
+          Comma separated list of surface references that are imprinted by boundary layers.
+
      --normal_direction <dir>
-          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 <dir> 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 <real>
-          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 <type>
           Sets the element type for the mesh generation.
           If <type> 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 <mode>
           Sets the behavior in case of collision between layers.
           If <mode> 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 <yes|no>
@@ -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... <br> 
+<b>Add option</b> - 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.
+
+- <b>Add multi normals</b> - Add extra normals at opening ridges and
+corners.
+
+- <b>Collision mode</b> - Sets the behavior in case of collision between layers.
+
+  - <b>decrease</b> - keeps the number of desired layer but decreases the height of the layers to
+             avoid any collision
+
+  - <b>stop</b> - stops locally the generation of layers to avoid collisions; the number of
+             generated layers may differ from the specified desired number
+
+- <b>Gradation</b> - Sets the desired maximum ratio between 2 adjacent edges. 
+  It applies only to the edges which belong to the tetrahedra.
+
+- <b>Maximum number of threads</b> - Sets the maximum number of threads to be used in parallel.
+
+- <b>Multi normal angle threshold</b> - Set the maximum angle (in
+  degrees) between the multiple normals at opening ridges.
+
+- <b>Smooth normals</b> - Smooth normals at closed ridges and corners.
+
 \subsection log Logs and debug
 
 - <b>Working directory</b> - allows defining the folder for input and output
@@ -235,14 +271,6 @@ is enabled (there must be a log file to delete it) and <b>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... <br> 
-<b>Add option</b> - 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
index 1147a95467d65304b64c2a572d1b402612ec12bf..4795e913f01bc5934d534f5d1893322a6354cee8 100644 (file)
@@ -34,6 +34,8 @@
  */
 module HYBRIDPlugin
 {
+  typedef sequence<string> string_array;
+
   typedef sequence<double,3> 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
      */
index 7b9233d6bdf07f4412bb812a62a4ffad91f640ee..ac0dff371f84a9b2ce12c879b0b274ee1d5a1325 100644 (file)
@@ -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
 )
 
index e6b967c709b01e1ed42a26aac572e3674e2fb78f..50913bae2b4cc8221ad87fc5696d5dcadb06644f 100644 (file)
 #include <QFileDialog>
 
 #include <iostream>
+#include <HYBRIDPlugin_Hypothesis.hxx>
 
+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 );
+  }
+}
index b5a735055dd3c023a7cb66aa4ec0985e373ea003..cdc6bc3e7445896432f987809ec70e20e3c4209d 100644 (file)
@@ -6,81 +6,73 @@
    <rect>
     <x>0</x>
     <y>0</y>
-    <width>465</width>
-    <height>477</height>
+    <width>337</width>
+    <height>369</height>
    </rect>
   </property>
   <property name="windowTitle">
    <string>Form</string>
   </property>
-  <layout class="QVBoxLayout" name="verticalLayout_2">
-   <property name="leftMargin">
-    <number>0</number>
-   </property>
-   <property name="topMargin">
-    <number>0</number>
-   </property>
-   <property name="rightMargin">
-    <number>0</number>
-   </property>
-   <item>
-    <widget class="QGroupBox" name="memoryGroupBox">
-     <property name="title">
-      <string>Memory settings</string>
+  <layout class="QGridLayout" name="gridLayout_4">
+   <item row="0" column="0" colspan="2">
+    <widget class="HYBRIDPluginGUI_TreeWidget" name="myOptionTable">
+     <property name="sizePolicy">
+      <sizepolicy hsizetype="Preferred" vsizetype="Preferred">
+       <horstretch>0</horstretch>
+       <verstretch>2</verstretch>
+      </sizepolicy>
+     </property>
+     <property name="editTriggers">
+      <set>QAbstractItemView::DoubleClicked|QAbstractItemView::EditKeyPressed</set>
+     </property>
+     <property name="tabKeyNavigation">
+      <bool>true</bool>
+     </property>
+     <column>
+      <property name="text">
+       <string>OPTION_NAME_COLUMN</string>
+      </property>
+      <property name="font">
+       <font>
+        <weight>50</weight>
+        <bold>false</bold>
+       </font>
+      </property>
+     </column>
+     <column>
+      <property name="text">
+       <string>OPTION_VALUE_COLUMN</string>
+      </property>
+      <property name="font">
+       <font>
+        <weight>50</weight>
+        <bold>false</bold>
+       </font>
+      </property>
+     </column>
+    </widget>
+   </item>
+   <item row="1" column="1">
+    <spacer name="horizontalSpacer">
+     <property name="orientation">
+      <enum>Qt::Horizontal</enum>
+     </property>
+     <property name="sizeHint" stdset="0">
+      <size>
+       <width>188</width>
+       <height>20</height>
+      </size>
+     </property>
+    </spacer>
+   </item>
+   <item row="1" column="0">
+    <widget class="QPushButton" name="addBtn">
+     <property name="text">
+      <string>HYBRID_ADD_OPTION</string>
      </property>
-     <layout class="QGridLayout" name="gridLayout_3">
-      <item row="3" column="4">
-       <widget class="QLabel" name="maxMemoryLabel">
-        <property name="text">
-         <string>MB</string>
-        </property>
-       </widget>
-      </item>
-      <item row="0" column="0">
-       <widget class="QCheckBox" name="initialMemoryCheck">
-        <property name="text">
-         <string>Initial memory size</string>
-        </property>
-       </widget>
-      </item>
-      <item row="3" column="0">
-       <widget class="QCheckBox" name="maxMemoryCheck">
-        <property name="text">
-         <string>Max memory size</string>
-        </property>
-       </widget>
-      </item>
-      <item row="0" column="4">
-       <widget class="QLabel" name="initialMemoryLabel">
-        <property name="text">
-         <string>MB</string>
-        </property>
-       </widget>
-      </item>
-      <item row="0" column="2" colspan="2">
-       <widget class="SMESHGUI_SpinBox" name="initialMemorySpin">
-        <property name="sizePolicy">
-         <sizepolicy hsizetype="Minimum" vsizetype="Fixed">
-          <horstretch>1</horstretch>
-          <verstretch>0</verstretch>
-         </sizepolicy>
-        </property>
-       </widget>
-      </item>
-      <item row="3" column="2" colspan="2">
-       <widget class="SMESHGUI_SpinBox" name="maxMemorySpin">
-        <property name="sizePolicy">
-         <sizepolicy hsizetype="Minimum" vsizetype="Fixed">
-          <horstretch>1</horstretch>
-          <verstretch>0</verstretch>
-         </sizepolicy>
-        </property>
-       </widget>
-      </item>
-     </layout>
     </widget>
    </item>
-   <item>
+   <item row="2" column="0" colspan="2">
     <widget class="QGroupBox" name="logGroupBox">
      <property name="title">
       <string>Logs and debug</string>
      </layout>
     </widget>
    </item>
-   <item>
-    <widget class="QGroupBox" name="advancedMeshingGroupBox">
-     <property name="title">
-      <string>Advanced meshing options</string>
-     </property>
-     <layout class="QGridLayout" name="gridLayout_4">
-      <item row="1" column="0">
-       <widget class="QCheckBox" name="removeInitialCentralPointCheck">
-        <property name="text">
-         <string>Remove initial central point</string>
-        </property>
-       </widget>
-      </item>
-      <item row="6" column="0">
-       <widget class="QLabel" name="gradationLabel">
-        <property name="text">
-         <string>Volumic gradation</string>
-        </property>
-       </widget>
-      </item>
-      <item row="6" column="1">
-       <widget class="SMESHGUI_SpinBox" name="gradationSpinBox"/>
-      </item>
-      <item row="1" column="1">
-       <widget class="QCheckBox" name="FEMCorrectionCheck">
-        <property name="text">
-         <string>Use FEM correction</string>
-        </property>
-       </widget>
-      </item>
-      <item row="0" column="1">
-       <widget class="QCheckBox" name="boundaryRecoveryCheck">
-        <property name="text">
-         <string>Use boundary recovery version</string>
-        </property>
-       </widget>
-      </item>
-      <item row="0" column="0">
-       <widget class="QCheckBox" name="createNewNodesCheck">
-        <property name="text">
-         <string>Create new nodes</string>
-        </property>
-       </widget>
-      </item>
-      <item row="7" column="0" colspan="2">
-       <widget class="SMESH_AdvOptionsWdg" name="myAdvOptionsTable" native="true"/>
-      </item>
-     </layout>
-    </widget>
-   </item>
   </layout>
  </widget>
  <customwidgets>
   <customwidget>
-   <class>SMESHGUI_SpinBox</class>
-   <extends>QDoubleSpinBox</extends>
-   <header location="global">SMESHGUI_SpinBox.h</header>
-  </customwidget>
-  <customwidget>
-   <class>SMESH_AdvOptionsWdg</class>
-   <extends>QWidget</extends>
-   <header location="global">SMESH_AdvOptionsWdg.h</header>
-   <container>1</container>
+   <class>HYBRIDPluginGUI_TreeWidget</class>
+   <extends>QTreeWidget</extends>
+   <header location="global">HYBRIDPluginGUI_TreeWidget.h</header>
   </customwidget>
  </customwidgets>
  <resources/>
index d6805d6fdf885db6d8929d4c28ae3e83b8d36334..6ba86fbb17c4d4a50492f115cac6ae30f48f0b99 100644 (file)
 #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
index 7c0ea49df162ca131a03d4e86c9d2578a38f6b75..8d0a16383ca2094afca0a35b917ef1c302fd0cd8 100644 (file)
@@ -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<QTabWidget*>( 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<QTabWidget*>( 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 ; i<mySmpModel->rowCount() ; 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 ; i<vertices->length() ; 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() <<"\")"<<std::endl;
       ok = h->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<QComboBox*>(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 );
+}
index 028aa80b1524abf58db02fb5bfac271963e34d7e..af82f23c415b4d31300da2ac08de3bb02898b48d 100644 (file)
@@ -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 (file)
index 0000000..f796542
--- /dev/null
@@ -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 <SUIT_Session.h>
+#include <SUIT_ResourceMgr.h>
+#include <SUIT_FileDlg.h>
+#include <SalomeApp_Tools.h>
+
+//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 (file)
index 0000000..750a12b
--- /dev/null
@@ -0,0 +1,250 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>HYBRIDPluginGUI_StdWidget_QTD</class>
+ <widget class="QWidget" name="HYBRIDPluginGUI_StdWidget_QTD">
+  <property name="geometry">
+   <rect>
+    <x>0</x>
+    <y>0</y>
+    <width>480</width>
+    <height>398</height>
+   </rect>
+  </property>
+  <property name="windowTitle">
+   <string>Form</string>
+  </property>
+  <layout class="QVBoxLayout" name="verticalLayout">
+   <item>
+    <widget class="QGroupBox" name="groupBox">
+     <property name="title">
+      <string>HYBRID_VL_OPTIONS</string>
+     </property>
+     <layout class="QGridLayout" name="gridLayout">
+      <item row="0" column="0">
+       <widget class="QLabel" name="label">
+        <property name="text">
+         <string>HYBRID_NB_LAYERS</string>
+        </property>
+       </widget>
+      </item>
+      <item row="0" column="1">
+       <widget class="SalomeApp_IntSpinBox" name="myNbOfBoundaryLayers"/>
+      </item>
+      <item row="1" column="0">
+       <widget class="QLabel" name="label_2">
+        <property name="text">
+         <string>HYBRID_SIZE_MODE</string>
+        </property>
+       </widget>
+      </item>
+      <item row="1" column="1">
+       <widget class="QComboBox" name="myBoundaryLayersSizeMode">
+        <item>
+         <property name="text">
+          <string>HYBRID_GLOBAL</string>
+         </property>
+        </item>
+        <item>
+         <property name="text">
+          <string>HYBRID_LOCAL</string>
+         </property>
+        </item>
+       </widget>
+      </item>
+      <item row="2" column="0">
+       <widget class="QLabel" name="label_3">
+        <property name="text">
+         <string>HYBRID_1ST_LAYER_HEIGHT</string>
+        </property>
+       </widget>
+      </item>
+      <item row="3" column="0">
+       <widget class="QLabel" name="label_4">
+        <property name="text">
+         <string>HYBRID_HEIGHT_IS_RELATIVE</string>
+        </property>
+       </widget>
+      </item>
+      <item row="3" column="1">
+       <widget class="QComboBox" name="myHeightIsRelative">
+        <item>
+         <property name="text">
+          <string>HYBRID_NO</string>
+         </property>
+        </item>
+        <item>
+         <property name="text">
+          <string>HYBRID_YES</string>
+         </property>
+        </item>
+       </widget>
+      </item>
+      <item row="4" column="0">
+       <widget class="QLabel" name="label_5">
+        <property name="text">
+         <string>HYBRID_GROWTH_OF_LAYERS</string>
+        </property>
+       </widget>
+      </item>
+      <item row="4" column="1">
+       <widget class="QComboBox" name="myBoundaryLayersGrowth">
+        <item>
+         <property name="text">
+          <string>HYBRID_LAYER_GROWTH_DOWNWARD</string>
+         </property>
+        </item>
+        <item>
+         <property name="text">
+          <string>HYBRID_LAYER_GROWTH_UPWARD</string>
+         </property>
+        </item>
+       </widget>
+      </item>
+      <item row="5" column="0">
+       <widget class="QLabel" name="label_6">
+        <property name="text">
+         <string>HYBRID_MAX_ELEM_ANGLE</string>
+        </property>
+       </widget>
+      </item>
+      <item row="5" column="1">
+       <widget class="SMESHGUI_SpinBox" name="myBoundaryLayersMaxElemAngle"/>
+      </item>
+      <item row="6" column="0">
+       <widget class="QLabel" name="label_7">
+        <property name="text">
+         <string>HYBRID_GEOM_PROGRESSION</string>
+        </property>
+       </widget>
+      </item>
+      <item row="6" column="1">
+       <widget class="SMESHGUI_SpinBox" name="myBoundaryLayersProgression"/>
+      </item>
+      <item row="7" column="0">
+       <widget class="QLabel" name="label_8">
+        <property name="text">
+         <string>HYBRID_IMPRINTING</string>
+        </property>
+       </widget>
+      </item>
+      <item row="7" column="1">
+       <widget class="QComboBox" name="myImprinting">
+        <item>
+         <property name="text">
+          <string>HYBRID_NO</string>
+         </property>
+        </item>
+        <item>
+         <property name="text">
+          <string>HYBRID_YES</string>
+         </property>
+        </item>
+       </widget>
+      </item>
+      <item row="8" column="0">
+       <widget class="QLabel" name="label_9">
+        <property name="text">
+         <string>HYBRID_SNAPPING</string>
+        </property>
+       </widget>
+      </item>
+      <item row="8" column="1">
+       <widget class="QComboBox" name="mySnapping">
+        <item>
+         <property name="text">
+          <string>HYBRID_NO</string>
+         </property>
+        </item>
+        <item>
+         <property name="text">
+          <string>HYBRID_YES</string>
+         </property>
+        </item>
+       </widget>
+      </item>
+      <item row="2" column="1">
+       <widget class="SMESHGUI_SpinBox" name="myHeightFirstLayer"/>
+      </item>
+     </layout>
+    </widget>
+   </item>
+   <item>
+    <widget class="QGroupBox" name="groupBox_2">
+     <property name="title">
+      <string>HYBRID_OTHER_OPTIONS</string>
+     </property>
+     <layout class="QGridLayout" name="gridLayout_2">
+      <item row="0" column="0">
+       <widget class="QLabel" name="label_10">
+        <property name="text">
+         <string>HYBRID_GENERATION_ELEMENT</string>
+        </property>
+       </widget>
+      </item>
+      <item row="0" column="1">
+       <widget class="QComboBox" name="myElementGeneration">
+        <item>
+         <property name="text">
+          <string>HYBRID_GENERATION_TETRA_DOMINANT</string>
+         </property>
+        </item>
+        <item>
+         <property name="text">
+          <string>HYBRID_GENERATION_HEXA_DOMINANT</string>
+         </property>
+        </item>
+        <item>
+         <property name="text">
+          <string>HYBRID_GENERATION_CARTESIAN_CORE</string>
+         </property>
+        </item>
+        <item>
+         <property name="text">
+          <string>HYBRID_GENERATION_EXTRUSION_ONLY</string>
+         </property>
+        </item>
+       </widget>
+      </item>
+      <item row="1" column="0">
+       <widget class="QCheckBox" name="myCoreSizeEnabled">
+        <property name="text">
+         <string>HYBRID_CORE_SIZE</string>
+        </property>
+       </widget>
+      </item>
+      <item row="1" column="1">
+       <widget class="SMESHGUI_SpinBox" name="myCoreSize"/>
+      </item>
+     </layout>
+    </widget>
+   </item>
+   <item>
+    <spacer name="verticalSpacer">
+     <property name="orientation">
+      <enum>Qt::Vertical</enum>
+     </property>
+     <property name="sizeHint" stdset="0">
+      <size>
+       <width>438</width>
+       <height>7</height>
+      </size>
+     </property>
+    </spacer>
+   </item>
+  </layout>
+ </widget>
+ <customwidgets>
+  <customwidget>
+   <class>SalomeApp_IntSpinBox</class>
+   <extends>QLineEdit</extends>
+   <header location="global">SalomeApp_IntSpinBox.h</header>
+  </customwidget>
+  <customwidget>
+   <class>SMESHGUI_SpinBox</class>
+   <extends>QDoubleSpinBox</extends>
+   <header location="global">SMESHGUI_SpinBox.h</header>
+  </customwidget>
+ </customwidgets>
+ <resources/>
+ <connections/>
+</ui>
diff --git a/src/GUI/HYBRIDPluginGUI_TreeWidget.cxx b/src/GUI/HYBRIDPluginGUI_TreeWidget.cxx
new file mode 100644 (file)
index 0000000..0fc743b
--- /dev/null
@@ -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 <QKeyEvent>
+
+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 (file)
index 0000000..0b9b297
--- /dev/null
@@ -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 <QTreeWidget>
+
+class HYBRIDPluginGUI_TreeWidget : public QTreeWidget
+{
+  Q_OBJECT
+public:
+  HYBRIDPluginGUI_TreeWidget( QWidget* );
+
+protected:
+  QModelIndex moveCursor( CursorAction, Qt::KeyboardModifiers );
+  void keyPressEvent( QKeyEvent* );
+};
+
+#endif // HYBRIDPluginGUI_TreeWidget_H
index 536c322db5b7190b7b8bd0725c260dcb89e6a6a2..8b031fa3808e9027b6a1369f83716c5df81b6c33 100644 (file)
@@ -28,7 +28,7 @@
         <translation>Hypothesis Construction</translation>
     </message>
     <message>
-        <source>HYBRID_BOUNDARY_LAYERS_GROWTH</source>
+        <source>HYBRID_GROWTH_OF_LAYERS</source>
         <translation>Growth of boundary layers</translation>
     </message>
     <message>
@@ -56,7 +56,7 @@ downward means inward and upward means outward ...
     </message>
     <message>
         <source>HYBRID_GENERATION_ELEMENT</source>
-        <translation>Element type for mesh in the remaining volume</translation>
+        <translation>Element generation</translation>
     </message>
     <message>
         <source>HYBRID_GENERATION_TETRA_DOMINANT</source>
@@ -70,9 +70,13 @@ downward means inward and upward means outward ...
         <source>HYBRID_GENERATION_CARTESIAN_CORE</source>
         <translation>Cartesian core</translation>
     </message>
+    <message>
+        <source>HYBRID_GENERATION_EXTRUSION_ONLY</source>
+        <translation>Extrusion only</translation>
+    </message>
     <message>
         <source>HYBRID_CORE_SIZE</source>
-        <translation>Core elements size (cartesian core only)</translation>
+        <translation>Core elements size</translation>
     </message>
     <message>
         <source>HYBRID_ADD_MULTINORMALS</source>
@@ -87,16 +91,68 @@ downward means inward and upward means outward ...
         <translation>Smooth normals at closed ridges and corners</translation>
     </message>
     <message>
-        <source>HYBRID_HeightFirstLayer</source>
+        <source>HYBRID_1ST_LAYER_HEIGHT</source>
         <translation>Height of first layer</translation>
     </message>
     <message>
-        <source>HYBRID_NbOfBoundaryLayers</source>
+        <source>HYBRID_NB_LAYERS</source>
         <translation>Number of boundary layers</translation>
     </message>
     <message>
-        <source>HYBRID_BoundaryLayersProgression</source>
-        <translation>Geometric progression of boundary layers</translation>
+        <source>HYBRID_HEIGHT_IS_RELATIVE</source>
+        <translation>Height relative to local surface</translation>
+    </message>
+    <message>
+        <source>HYBRID_SIZE_MODE</source>
+        <translation>Size mode</translation>
+    </message>
+    <message>
+        <source>HYBRID_GLOBAL</source>
+        <translation>Global</translation>
+    </message>
+    <message>
+        <source>HYBRID_LOCAL</source>
+        <translation>Local</translation>
+    </message>
+    <message>
+        <source>HYBRID_MAX_ELEM_ANGLE</source>
+        <translation>Maximal element angle (degrees)</translation>
+    </message>
+    <message>
+        <source>HYBRID_IMPRINTING</source>
+        <translation>Imprinting</translation>
+    </message>
+    <message>
+        <source>HYBRID_SNAPPING</source>
+        <translation>Snapping</translation>
+    </message>
+    <message>
+        <source>HYBRID_NO</source>
+        <translation>No</translation>
+    </message>
+    <message>
+        <source>HYBRID_YES</source>
+        <translation>Yes</translation>
+    </message>
+    <message>
+        <source>HYBRID_VL_OPTIONS</source>
+        <translation>Options for boundary layers</translation>
+    </message>
+    <message>
+        <source>HYBRID_OTHER_OPTIONS</source>
+        <translation>Other options</translation>
+    </message>
+    <message>
+        <source></source>
+        <translation></translation>
+    </message>
+    <message>
+        <source></source>
+        <translation></translation>
+    </message>
+    <message>
+        <source>HYBRID_GEOM_PROGRESSION</source>
+        <translation>Geometric progression</translation>
     </message>
     <message>
         <source>HYBRID_TO_MESH_HOLES</source>
@@ -334,5 +390,33 @@ downward means inward and upward means outward ...
         <source>HYBRID_FACE_IDS</source>
         <translation>Face IDs</translation>
     </message>
+    <message>
+        <source>add_multinormals</source>
+        <translation>Add multi normals</translation>
+    </message>
+    <message>
+        <source>smooth_normals</source>
+        <translation>Smooth normals</translation>
+    </message>
+    <message>
+        <source>max_number_of_threads</source>
+        <translation>Maximum number of threads</translation>
+    </message>
+    <message>
+        <source>gradation</source>
+        <translation>Gradation</translation>
+    </message>
+    <message>
+        <source>multinormal_angle_threshold</source>
+        <translation>Multi normal angle threshold</translation>
+    </message>
+    <message>
+        <source>collision_mode</source>
+        <translation>Collision mode</translation>
+    </message>
+    <message>
+        <source>HYBRID_ADD_OPTION</source>
+        <translation>Add option</translation>
+    </message>
 </context>
 </TS>
index 2ac5ec4644272b1cf2d48db1e459472020be7036..12f1013682291c6bbdd8517ec57929c8e4751421 100644 (file)
@@ -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
index fb18c5958dd3c3e15b98ce24448c8a6f99a3f5b5..4ef187351b18cf98af348d5ed90b58ec7891a2c1 100644 (file)
 #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<bool>(load >> separator);
 
-  if ( isOK && ( separator == "0" || separator == "1" ))
-  {
-    myToMakeGroupsOfDomains = ( separator == "1" );
-    isOK = static_cast<bool>(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<bool>(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<bool>(load >> i))
+  {
+    myHeightIsRelative = (bool) i;
+    load >> myBoundaryLayersMaxElemAngle;
+    load >> myCollisionMode;
+    load >> myGradation;
+    load >> myOptimizationLevel;
+
+    std::string option, value;
+    if ( static_cast<bool>( 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<bool>( 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();
 }
index e365af80747134a596160ce6641f101f5cb8bd92..93832c63e98b6507c85f241fc5447cea33b6adbc 100644 (file)
@@ -119,11 +119,18 @@ public:
   typedef std::set<std::string> 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<int> myFacesWithLayers;
   std::vector<int> myFacesWithImprinting;
   std::vector<int> myFacesWithSnapping;
-  bool             myToMakeGroupsOfDomains;
-  double           myMaximumMemory;
-  double           myInitialMemory;
-  short            myOptimizationLevel;
+  std::vector<int> 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;
index 3643e221f94f15525377152ce2bc16f537b6ee29..c1755cd25a621f50567a24523925a021bc8e822b 100644 (file)
@@ -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<std::string> 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);
index 9fb85a650c1a42e1448355b83d4ecc40ec4b1d2a..ea4bc7b0caff8a527e0cc21f8c9da638411719e1 100644 (file)
@@ -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();