From: eap Date: Wed, 9 Oct 2019 12:45:33 +0000 (+0300) Subject: #17784 [EDF] MESH-GEMS-2.9.6 Meshers options X-Git-Tag: V9_4_0b1~1 X-Git-Url: http://git.salome-platform.org/gitweb/?a=commitdiff_plain;h=f899b6e4b56e76e17e2d9341298341e9680e8eec;p=plugins%2Fghs3dplugin.git #17784 [EDF] MESH-GEMS-2.9.6 Meshers options --- diff --git a/doc/salome/gui/GHS3DPLUGIN/images/ghs3d_parameters_advanced.png b/doc/salome/gui/GHS3DPLUGIN/images/ghs3d_parameters_advanced.png index 4372e3c..a0bca6a 100644 Binary files a/doc/salome/gui/GHS3DPLUGIN/images/ghs3d_parameters_advanced.png and b/doc/salome/gui/GHS3DPLUGIN/images/ghs3d_parameters_advanced.png differ diff --git a/doc/salome/gui/GHS3DPLUGIN/images/ghs3d_parameters_basic.png b/doc/salome/gui/GHS3DPLUGIN/images/ghs3d_parameters_basic.png index 8963bd0..3ecb4f2 100644 Binary files a/doc/salome/gui/GHS3DPLUGIN/images/ghs3d_parameters_basic.png and b/doc/salome/gui/GHS3DPLUGIN/images/ghs3d_parameters_basic.png differ diff --git a/doc/salome/gui/GHS3DPLUGIN/input/ghs3d_hypo.doc b/doc/salome/gui/GHS3DPLUGIN/input/ghs3d_hypo.doc index 9e29026..af2ab19 100644 --- a/doc/salome/gui/GHS3DPLUGIN/input/ghs3d_hypo.doc +++ b/doc/salome/gui/GHS3DPLUGIN/input/ghs3d_hypo.doc @@ -17,15 +17,6 @@ To get a license, visit http://www.meshgems.com/meshgems-products.html - Name - allows to define the name of the hypothesis (MG-Tetra Parameters by default). -- Mesh holes - if checked, the algorithm will -create mesh in the holes inside a solid shape, else only the outermost -shape will be meshed. Volumic elements created within holes are bound -to the solid. - -- Make groups of domains - if checked, the algorithm will -create groups of just generated elements corresponding to each mesh -domain.
- - Optimization level - allows choosing the required optimization level (higher level of optimization provides better mesh, but can be time-consuming): @@ -40,12 +31,168 @@ but can be time-consuming): - strong +- Minimal size - sets the minimum edge size in the generated mesh. + +- Maximal size - sets the maximum edge size in the generated mesh. + +- Volumic gradation - Defines the volumic ratio between 2 consecutive elements. +WARNING: Changing the default value of this parameter may dramatically +decrease the quality of the resulting mesh. + +- Use volume proximity - activates consideration of distance between opposite surfaces. + + - Number of layers - asks for at least given number of layers of tets between opposite surfaces. + +- Mesh holes - if checked, the algorithm will +create mesh in the holes inside a solid shape, else only the outermost +shape will be meshed. Volumic elements created within holes are bound +to the solid. + +- Make groups of domains - if checked, the algorithm will +create groups of just generated elements corresponding to each mesh +domain.
+ \ref ghs3d_top "Back to top" \section ghs3d_advanced_parameters Advanced parameters \image html ghs3d_parameters_advanced.png +\subsection advanced_meshing_options Advanced meshing options + +Advanced page tab expose mostly useful advanced options. Initially, +default values of the options are displayed and they are not +modifiable. If an option is activated using a check-box, its value +becomes modifiable. + +Add option button 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. + +- Gradation on skin - This option set or not the gradation + value on the initial size of the skin vertices. + + - no the gradation is not applied on the skin vertices. + In this case the initial size of a vertex is the average edges + lenght which belong the vertex. + + - yes the gradation is applied on the skin vertices. In + this case the initial size of a vertex is the average edges + lenght which belong the vertex multiplied by the gradation. + + +- Boundary regeneration - defines the boundary regeneration mode. + MeshGems-Tetra uses alternative strategies for boundary regeneration. + + - standard means that the standard boundary regeneration algorithm is used. + + - safe means that various methods are tried as long as + the regeneration phase fails (including the alternate boundary + recovery mode), can be time consuming and can fail in very + difficult cases. + + - recovery means that the alternate boundary recovery + version is activated. Check Using MeshGems-Tetra with the + boundary recovery module chapter of MG-Tetra User Manual. + +- Force maximum edge size - This option can be used to force + the desired maximum edge size in the generated mesh given by + the Max Size parameter. The default value is no, meaning that + the maximum edge length can be greater than the given value of + the Max Size parameter. + +- Force quadratic mesh - This option permits to write or not an + output mesh file in case of negative Jacobians when generating a + quadratic mesh. Refer to section 4.6.3 for more details. + + - no means that no output is written (this is the default); + + - yes means that an output is written even in case of negative Jacobians. + +- Respect surface mesh - This option forbids or not the + correction of input triangles and enforced edges mid-nodes to make + the element Jacobian strictly positive when generating a quadratic + mesh. + + - yes means that the input triangles and edges mid-nodes + are unchanged, the correction of nodes is only applied in the volume. + + - no means that the input triangles and edges mid-nodes + can be moved. The correction of nodes is applied in the volume + and the mid-nodes correction can be applied on the input + triangles and edges mid-nodes. The corrected surface mid-nodes + are approximated on the surface first, or put on the linear + edges; The corrected edges mid-nodes can be put on the linear + edges. + +- Max number of errors - the error messages will be printed up + to a given maximum number of errors. At least 1 error is printed and + at most 100 errors are printed to prevent infinite loops. + +- Maximal number of threads - This allows to set the maximal + number of threads the software can use in parallel for the + multi-threading optimization mode. + +- No central point - yes prevents adding an internal point at the + centre of gravity of the bounding box that MeshGems-Tetra uses by + default in order to speed up and to simplify the meshing + process. This option can be particularly useful to: + + - generate a volume mesh without internal points at all; + + - in some rare cases, help the boundary regeneration phase when + it failed with the standard options (for example when one + dimension of the domain is large compared to the other two with + a ratio of 20 or more). Use this option when the boundary + regeneration failed with the standard parameters and before + using the recovery version. + +- Optimise worst elements - Applies an optimization processing + to improve the worst quality elements whenever possible. + +- Mode of pthreads - This option sets the optimization mode + when using multithread capabilities. By default, this option is not + activated which means that only a sequential optimization is + performed. + + - safe is slower than the sequential mode, but the + quality of the mesh can only improve; + + - aggressive - is faster than the sequential mode, but + the quality of the resulting mesh may altered compared to the sequential mode. + +- Rectify jacobian - This option activates correction of some + nodes so as to make the Jacobian of element strictly positive when + generating a quadratic mesh. + +- Sliver angle - This options can be used to specify to + MeshGems-Tetra what is considered as a sliver and what is not. The + user has the possibility to specify an angle (in degrees), which + caracterizes a sliver : any tetrahedron which has at least an angle + below this value will be considered as a sliver. + +- Remove overconstrained tetrahedra - This option can be used + to only split the tetrahadra which have at least two facets that + belong to the surface mesh. It will not split the overconstrained + edges in the mesh. The overconstrained tetrahedra are splitting, + whenever possible, which ensures that no tetrahedron has no more + than one boundary facet. + + - no means that no correction is applied; + + - yes means that the correction is applied after mesh generation; + + - only means only correction is applied to an existing mesh. + +- Target quality - Sets the desired maximum target of worst + quality acceptable for the volume mesh used during optimisation + phase. When defined, an optimization processing is applied to + improve the quality until the given target is reached whenever + possible. By default, this option is not activated which means that + only the standard optimisations are performed (the quality target is + the target quality computed by the program). + \subsection memory_settings Memory settings - Maximum memory size - launches MG-Tetra software with @@ -86,54 +233,6 @@ is enabled (there must be a log file to delete it) and Keep all working files of MG-Tetra 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 - -- Create new nodes - if this option is checked off, MG-Tetra -tries to create tetrahedrons using only the nodes of the 2D mesh. - -- Remove the initial central point MG-Tetra adds an internal point -at the gravity center of the bounding box to speed up and to simplify -the meshing process. However, it is possible to refrain from creating -this point by using the command line option -no initial central point. This can be -particularly useful to generate a volume mesh without internal points at all and in some rare cases -at the boundary regeneration phase when it is impossible to proceed -with the standard options -(for example, when one dimension of the domain is more than 20 times greater than the other two). -Use this option if the boundary regeneration has failed with the standard parameters and before using -the recovery version (command line option -C). -Note: when using this option, the speed of the meshing process may -decrease, and the quality may change. -Note: the boundary regeneration may fail with this option, in some rare cases. - -- Use boundary recovery version - enables using a -boundary recovery module which tries to -create volume meshes starting from very poor quality surface meshes -(almost flat triangles on the surface, high density propagation, -extreme aspect ratios, etc.) which fails with the standard version. The -resulting volume mesh will however most likely have a very poor -quality (poor aspect ratio of elements, tetrahedra with a very small -positive volume). - -- Use FEM correction - Applies finite-element correction by -replacing overconstrained elements where it is possible. At first the process -slices the overconstrained edges and at second the overconstrained -facets. This ensures that there are no edges with two boundary -vertices and that there are no facets with three boundary vertices. MG-Tetra gives the initial -and final overconstrained edges and facets. It also gives the facets -which have three edges on the boundary. -Note: when using this option, the speed of the meshing process may -decrease, quality may change, and the smallest volume may be smaller. -By default, the FEM correction is not used. - -- Volumic gradation - Defines the volumic ratio between 2 consecutive elements. -WARNING: Changing the default value of this parameter may dramatically decrease the quality of the resulting mesh. - -- A table at the page bottom allows to input in the command line any text -for MG-Tetra, for example, advanced options.
-Add option - adds a line to the table where you can type an option and its value as text. -A check box in the first column activates/deactivates the option of the current row. A deactivated option will be erased upon pressing \a Ok. - - \ref ghs3d_top "Back to top" \section ghs3d_enforced_vertices Enforced vertices diff --git a/doc/salome/gui/GHS3DPLUGIN/input/optimization_hypo.doc b/doc/salome/gui/GHS3DPLUGIN/input/optimization_hypo.doc index e1868b5..a87bc55 100644 --- a/doc/salome/gui/GHS3DPLUGIN/input/optimization_hypo.doc +++ b/doc/salome/gui/GHS3DPLUGIN/input/optimization_hypo.doc @@ -57,11 +57,11 @@ elements as much as possible. \ref optimization_top "Back to top" -\section ghs3d_advanced_parameters Advanced parameters +\section mgtetra_optim_advanced_parameters Advanced parameters \image html mgtetra_optim_adv_params.png -\subsection memory_settings Memory settings +\subsection mgtetra_optim_memory_settings Memory settings - Initial memory size - starts MG-Tetra software with the specified amount of work space, in Mbytes. If this option is checked off, the @@ -71,7 +71,7 @@ software will be started with 100 Megabytes of working space. work space limited to the specified amount of RAM, in Mbytes. If this option is checked off, the software will be launched with 7O% of the total RAM space. -\subsection log Logs and debug +\subsection mgtetra_optim_log Logs and debug - Working directory - allows defining the folder for input and output files of MG-Tetra software, which are the files starting with "GHS3D_" prefix. @@ -104,7 +104,7 @@ files of MG-Tetra 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 +\subsection mgtetra_optim_advanced_meshing_options Advanced meshing options - A table allows to input in the command line any text for MG-Tetra, for example, advanced options.
diff --git a/idl/GHS3DPlugin_Algorithm.idl b/idl/GHS3DPlugin_Algorithm.idl index bae1d03..752f9e6 100644 --- a/idl/GHS3DPlugin_Algorithm.idl +++ b/idl/GHS3DPlugin_Algorithm.idl @@ -32,6 +32,8 @@ */ module GHS3DPlugin { + typedef sequence string_array; + typedef sequence TCoords; struct GHS3DEnforcedVertex { string name; @@ -71,6 +73,26 @@ module GHS3DPlugin */ void SetToMeshHoles(in boolean toMesh); boolean GetToMeshHoles(); + /*! + *Set lower boundary of mesh element size + */ + void SetMinSize(in double theMinSize); + double GetMinSize(); + /*! + *Set upper boundary of mesh element size + */ + void SetMaxSize(in double theMaxSize); + double GetMaxSize(); + /*! + * Activate/deactivate volume proximity computation + */ + void SetVolumeProximity( in boolean toUse ); + boolean GetVolumeProximity(); + /*! + * Set number of surface element layers to be generated due to volume proximity + */ + void SetNbVolumeProximityLayers( in short nbLayers ); + short GetNbVolumeProximityLayers(); /*! * To make groups of volumes of different domains when mesh is generated from skin. * Default is to make groups. @@ -142,13 +164,6 @@ module GHS3DPlugin */ void SetToRemoveCentralPoint(in boolean toRemove); boolean GetToRemoveCentralPoint(); - /*! - * To set hiden/undocumented/advanced options - */ - void SetAdvancedOption(in string option); - string GetAdvancedOption(); - void SetTextOption(in string option); // obsolete - string GetTextOption(); /*! * To define the volumic gradation */ @@ -164,6 +179,39 @@ module GHS3DPlugin */ void SetRemoveLogOnSuccess(in boolean removeLogOnSuccess); boolean GetRemoveLogOnSuccess(); + /*! + * 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 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(); // 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 set an enforced vertex */ @@ -201,6 +249,11 @@ module GHS3DPlugin * Set/get/unset an enforced vertex (private method for GUI) */ boolean p_SetEnforcedMesh(in SMESH::SMESH_IDSource theSource, in SMESH::ElementType elementType, in string name, in string groupName) raises (SALOME::SALOME_Exception); + + // GUI methods + double GetMaxSizeDefault(); + double GetMinSizeDefault(); + void SetMinMaxSizeDefault( in double theMinSize, in double theMaxSize ); }; /*! diff --git a/src/GHS3DPlugin/GHS3DPluginBuilder.py b/src/GHS3DPlugin/GHS3DPluginBuilder.py index c1b710f..1c58b89 100644 --- a/src/GHS3DPlugin/GHS3DPluginBuilder.py +++ b/src/GHS3DPlugin/GHS3DPluginBuilder.py @@ -88,6 +88,30 @@ class GHS3D_Algorithm(Mesh_Algorithm): pass return self.params + ## Set lower boundary of mesh element size + # Set it to zero to deactivate this option + def SetMinSize(self, theMinSize): + self.Parameters().SetMinSize(theMinSize) + return + + ## Set upper boundary of mesh element size + # Set it to zero to deactivate this option + def SetMaxSize(self, theMaxSize): + self.Parameters().SetMaxSize(theMaxSize) + return + + ## Activate/deactivate volume proximity computation + # + def SetVolumeProximity(self, toUse ): + self.Parameters().SetVolumeProximity(toUse) + return + + ## Set number of surface element layers to be generated due to volume proximity + # + def SetNbVolumeProximityLayers(self, nbLayers ): + self.Parameters().SetNbVolumeProximityLayers(nbLayers) + return + ## To mesh "holes" in a solid or not. Default is to mesh. # @param toMesh "mesh holes" flag value def SetToMeshHoles(self, toMesh): @@ -264,15 +288,22 @@ class GHS3D_Algorithm(Mesh_Algorithm): pass pass - ## Sets command line option as text. - # @param option command line option - def SetTextOption(self, option): - self.Parameters().SetAdvancedOption(option) + ## 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. + # @param optionAndValue command line option in a form "option value" + def SetAdvancedOption(self, optionAndValue): + self.Parameters().SetAdvancedOption(optionAndValue) + pass + + ## OBSOLETE Sets command line option as text. # @param option command line option - def SetAdvancedOption(self, option): + def SetTextOption(self, option): self.Parameters().SetAdvancedOption(option) pass diff --git a/src/GHS3DPlugin/GHS3DPlugin_Hypothesis.cxx b/src/GHS3DPlugin/GHS3DPlugin_Hypothesis.cxx index 892aa70..705c3e4 100644 --- a/src/GHS3DPlugin/GHS3DPlugin_Hypothesis.cxx +++ b/src/GHS3DPlugin/GHS3DPlugin_Hypothesis.cxx @@ -36,6 +36,15 @@ using namespace std; +namespace +{ + struct GET_DEFAULT // struct used to get default value from GetOptionValue() + { + bool isDefault; + operator bool* () { return &isDefault; } + }; +} + //======================================================================= //function : GHS3DPlugin_Hypothesis //======================================================================= @@ -57,21 +66,84 @@ GHS3DPlugin_Hypothesis::GHS3DPlugin_Hypothesis(int hypId, SMESH_Gen * gen) myLogInStandardOutput(DefaultStandardOutputLog()), myRemoveLogOnSuccess( DefaultRemoveLogOnSuccess() ), myGradation(DefaultGradation()), - _enfVertexList(DefaultGHS3DEnforcedVertexList()), - _enfVertexCoordsSizeList(DefaultGHS3DEnforcedVertexCoordsValues()), - _enfVertexEntrySizeList(DefaultGHS3DEnforcedVertexEntryValues()), - _coordsEnfVertexMap(DefaultCoordsGHS3DEnforcedVertexMap()), - _geomEntryEnfVertexMap(DefaultGeomEntryGHS3DEnforcedVertexMap()), - _enfMeshList(DefaultGHS3DEnforcedMeshList()), - _entryEnfMeshMap(DefaultEntryGHS3DEnforcedMeshListMap()), - _enfNodes(TIDSortedNodeGroupMap()), - _enfEdges(TIDSortedElemGroupMap()), - _enfTriangles(TIDSortedElemGroupMap()), - _nodeIDToSizeMap(DefaultID2SizeMap()), - _groupsToRemove(DefaultGroupsToRemove()) + myUseVolumeProximity(DefaultUseVolumeProximity()), + myNbVolumeProximityLayers(DefaultNbVolumeProximityLayers()), + myMinSize(0), + myMinSizeDefault(0), + myMaxSize(0), + myMaxSizeDefault(0) { _name = GetHypType(); _param_algo_dim = 3; + + const char* boolOptionNames[] = { "no_initial_central_point", // no + "force_max_size", // no + "apply_gradation_on_skin_vertex_sizes", // yes + "optimise_worst_elements", // no + "force_output_quadratic_mesh", // no + "rectify_jacobian", // yes + "jacobian_rectification_respect_input_surface_mesh", // yes + "" // mark of end + }; + const char* intOptionNames[] = { "max_number_of_errors_printed", // 1 + "max_number_of_threads", // 4 + "" // mark of end + }; + const char* doubleOptionNames[] = { "target_quality", // 0 + "sliver_angle", // 5 + "" // mark of end + }; + const char* charOptionNames[] = { "pthreads_mode", // "" + "boundary_regeneration", // standard + "split_overconstrained_tetrahedra", // no + "" // 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["no_initial_central_point" ] = "no"; + _defaultOptionValues["force_max_size" ] = "no"; + _defaultOptionValues["apply_gradation_on_skin_vertex_sizes" ] = "yes"; + _defaultOptionValues["optimise_worst_elements" ] = "no"; + _defaultOptionValues["force_output_quadratic_mesh" ] = "no"; + _defaultOptionValues["rectify_jacobian" ] = "yes"; + _defaultOptionValues["jacobian_rectification_respect_input_surface_mesh"] = "yes"; + _defaultOptionValues["max_number_of_errors_printed" ] = "1"; + _defaultOptionValues["max_number_of_threads" ] = "4"; + _defaultOptionValues["target_quality" ] = "";//NoValue(); + _defaultOptionValues["sliver_angle" ] = "5"; + _defaultOptionValues["pthreads_mode" ] = "";//NoValue(); + _defaultOptionValues["boundary_regeneration" ] = "standard"; + _defaultOptionValues["split_overconstrained_tetrahedra" ] = "no"; + +#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 } //======================================================================= @@ -92,11 +164,17 @@ void GHS3DPlugin_Hypothesis::SetToMeshHoles(bool toMesh) bool GHS3DPlugin_Hypothesis::GetToMeshHoles(bool checkFreeOption) const { - if (checkFreeOption && !myTextOption.empty()) { - if ( myTextOption.find("--components all")) - return true; - if ( myTextOption.find("--components outside_components")) - return false; + if ( checkFreeOption ) + { + std::string optionName = "components"; + TOptionValues::const_iterator op_val = _customOption2value.find(optionName); + if ( op_val != _customOption2value.end()) + { + if ( op_val->second.find("all")) + return true; + if ( op_val->second.find("outside_components")) + return false; + } } return myToMeshHoles; } @@ -330,10 +408,8 @@ bool GHS3DPlugin_Hypothesis::GetFEMCorrection() const void GHS3DPlugin_Hypothesis::SetToRemoveCentralPoint(bool toRemove) { - if ( myToRemoveCentralPoint != toRemove ) { - myToRemoveCentralPoint = toRemove; - NotifySubMeshesHypothesisModification(); - } + SetOptionValue( "no_initial_central_point", toRemove ? "yes" : "no" ); + myToRemoveCentralPoint = toRemove; } //======================================================================= @@ -351,9 +427,16 @@ bool GHS3DPlugin_Hypothesis::GetToRemoveCentralPoint() const void GHS3DPlugin_Hypothesis::SetAdvancedOption(const std::string& option) { - if ( myTextOption != option ) { - myTextOption = option; - NotifySubMeshesHypothesisModification(); + size_t wsPos = option.find(' '); + if ( wsPos == string::npos ) + { + SetOptionValue( option, "" ); + } + else + { + std::string opt( option, 0, wsPos ); + std::string val( option, wsPos + 1 ); + SetOptionValue( opt, val ); } } @@ -363,7 +446,23 @@ void GHS3DPlugin_Hypothesis::SetAdvancedOption(const std::string& option) std::string GHS3DPlugin_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; } //======================================================================= @@ -387,6 +486,46 @@ double GHS3DPlugin_Hypothesis::GetGradation() const return myGradation; } +//============================================================================= +void GHS3DPlugin_Hypothesis::SetMinSize(double theMinSize) +{ + if ( theMinSize != myMinSize ) + { + myMinSize = theMinSize; + NotifySubMeshesHypothesisModification(); + } +} + +//============================================================================= +void GHS3DPlugin_Hypothesis::SetMaxSize(double theMaxSize) +{ + if ( theMaxSize != myMaxSize ) + { + myMaxSize = theMaxSize; + NotifySubMeshesHypothesisModification(); + } +} + +//============================================================================= +void GHS3DPlugin_Hypothesis::SetUseVolumeProximity( bool toUse ) +{ + if ( myUseVolumeProximity != toUse ) + { + myUseVolumeProximity = toUse; + NotifySubMeshesHypothesisModification(); + } +} + +//============================================================================= +void GHS3DPlugin_Hypothesis::SetNbVolumeProximityLayers( int nbLayers ) +{ + if ( myNbVolumeProximityLayers != nbLayers ) + { + myNbVolumeProximityLayers = nbLayers; + NotifySubMeshesHypothesisModification(); + } +} + //======================================================================= //function : SetStandardOutputLog //======================================================================= @@ -983,15 +1122,6 @@ bool GHS3DPlugin_Hypothesis::DefaultToRemoveCentralPoint() return false; } -//======================================================================= -//function : DefaultGradation -//======================================================================= - -double GHS3DPlugin_Hypothesis::DefaultGradation() -{ - return 1.05; -} - //======================================================================= //function : DefaultStandardOutputLog //======================================================================= @@ -1030,11 +1160,11 @@ std::ostream & GHS3DPlugin_Hypothesis::SaveTo(std::ostream & save) save << (int)myToRemoveCentralPoint << " "; save << myGradation << " "; save << myToMakeGroupsOfDomains << " "; - if (!myTextOption.empty()) { - save << "__OPTIONS_BEGIN__ "; - save << myTextOption << " "; - save << "__OPTIONS_END__ "; - } + // if (!myTextOption.empty()) { + // save << "__OPTIONS_BEGIN__ "; + // save << myTextOption << " "; + // save << "__OPTIONS_END__ "; + // } TGHS3DEnforcedVertexList::iterator it = _enfVertexList.begin(); @@ -1104,6 +1234,25 @@ std::ostream & GHS3DPlugin_Hypothesis::SaveTo(std::ostream & save) } save << " " << "__ENFORCED_MESHES_END__ "; } + + // New options in 2.9.6 (issue #17784) + + save << " " << myUseVolumeProximity; + save << " " << myNbVolumeProximityLayers; + save << " " << myMinSize; + save << " " << myMaxSize; + save << " " << myMinSizeDefault; + save << " " << myMaxSizeDefault; + + 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; } @@ -1226,15 +1375,15 @@ std::istream & GHS3DPlugin_Hypothesis::LoadFrom(std::istream & load) isOK = static_cast(load >> txt); if (isOK) { if (txt == "__OPTIONS_END__") { - if (!myTextOption.empty()) { - // Remove last space - myTextOption.erase(myTextOption.end()-1); - } + // if (!myTextOption.empty()) { + // // Remove last space + // myTextOption.erase(myTextOption.end()-1); + // } isOK = false; break; } - myTextOption += txt; - myTextOption += " "; + // myTextOption += txt; + // myTextOption += " "; } } } @@ -1427,6 +1576,39 @@ std::istream & GHS3DPlugin_Hypothesis::LoadFrom(std::istream & load) } // while } // if + // New options in 2.9.6 (issue #17784) + + if ( ! hasOptions && ! hasEnforcedVertices && ! hasEnforcedMeshes ) + myUseVolumeProximity = ( separator == "1" ); + else if ( static_cast( load >> i )) + myUseVolumeProximity = (bool) i; + + if ( static_cast( load >> myNbVolumeProximityLayers )) + { + load >> myMinSize; + load >> myMaxSize; + load >> myMinSizeDefault; + load >> myMaxSizeDefault; + + std::string option, value; + if ( static_cast( load >> i ) && i >= 0 ) + { + for ( int nbRead = 0; nbRead < i; ++nbRead ) + { + load >> option >> value; + _option2value[ std::string( option, 1 )] = std::string( value, 1 ); + } + } + if ( static_cast( load >> i ) && i >= 0 ) + { + for ( int nbRead = 0; nbRead < i; ++nbRead ) + { + load >> option >> value; + _customOption2value[ std::string( option, 1 )] = std::string( value, 1 ); + } + } + } + return load; } @@ -1450,6 +1632,11 @@ bool GHS3DPlugin_Hypothesis::SetParametersByDefaults(const TDefaults& dflts, const SMESH_Mesh* /*theMesh*/) { myToMakeGroupsOfDomains = ( !dflts._shape || dflts._shape->IsNull() ); + + double diagonal = dflts._elemLength * _gen->GetBoundaryBoxSegmentation(); + myMinSizeDefault = 1e-3 * diagonal; + myMaxSizeDefault = diagonal / 5.; + return true; } @@ -1465,16 +1652,16 @@ std::string GHS3DPlugin_Hypothesis::CommandToRun(const GHS3DPlugin_Hypothesis* h { std::string cmd = GetExeName(); // check if any option is overridden by hyp->myTextOption - bool max_memory = hyp ? ( hyp->myTextOption.find("--max_memory") == std::string::npos ) : true; - bool auto_memory = hyp ? ( hyp->myTextOption.find("--automatic_memory") == std::string::npos ) : true; - bool comp = hyp ? ( hyp->myTextOption.find("--components") == std::string::npos ) : true; - bool optim_level = hyp ? ( hyp->myTextOption.find("--optimisation_level") == std::string::npos ) : true; - bool no_int_points = hyp ? ( hyp->myTextOption.find("--no_internal_points") == std::string::npos ) : true; - bool C = hyp ? ( hyp->myTextOption.find("-C") == std::string::npos ) : true; - bool verbose = hyp ? ( hyp->myTextOption.find("--verbose") == std::string::npos ) : true; - bool fem = hyp ? ( hyp->myTextOption.find("-FEM")== std::string::npos ) : true; - bool rem = hyp ? ( hyp->myTextOption.find("--no_initial_central_point")== std::string::npos ) : true; - bool gra = hyp ? ( hyp->myTextOption.find("-Dcpropa")== std::string::npos ) : true; + bool max_memory = hyp ? !hyp->HasOptionDefined("max_memory") : true; + bool auto_memory = hyp ? !hyp->HasOptionDefined("automatic_memory") : true; + bool comp = hyp ? !hyp->HasOptionDefined("components") : true; + bool optim_level = hyp ? !hyp->HasOptionDefined("optimisation_level") : true; + bool no_int_points = hyp ? !hyp->HasOptionDefined("no_internal_points") : true; + bool C = hyp ? !hyp->HasOptionDefined("-C") : true; + bool verbose = hyp ? !hyp->HasOptionDefined("verbose") : true; + bool gra = hyp ? !hyp->HasOptionDefined("-Dcpropa") : true; + bool rem = hyp ? !hyp->HasOptionDefined("no_initial_central_point") : true; + //bool fem = hyp ? !hyp->HasOptionDefined("-FEM") : true; // if use boundary recovery version, few options are allowed bool useBndRecovery = !C; @@ -1535,17 +1722,17 @@ std::string GHS3DPlugin_Hypothesis::CommandToRun(const GHS3DPlugin_Hypothesis* h } // boundary recovery version - if ( useBndRecovery ) { - cmd += " -C"; - } + // if ( useBndRecovery ) { + // cmd += " -C"; + // } // to use FEM correction - if ( fem && hyp && hyp->myToUseFemCorrection) { - cmd += " -FEM"; - } + // if ( fem && hyp && hyp->myToUseFemCorrection) { + // cmd += " -FEM"; + // } // to remove initial central point. - if ( rem && hyp && hyp->myToRemoveCentralPoint) { + if ( rem && hyp && hyp->myToRemoveCentralPoint ) { if ( forExecutable ) cmd += " --no_initial_central_point"; else @@ -1553,16 +1740,65 @@ std::string GHS3DPlugin_Hypothesis::CommandToRun(const GHS3DPlugin_Hypothesis* h } // options as text - if ( hyp && !hyp->myTextOption.empty() ) { - cmd += " " + hyp->myTextOption; + // if ( hyp && !hyp->myTextOption.empty() ) { + // cmd += " " + hyp->myTextOption; + // } + + // min/max size + if ( hyp ) + { + if ( hyp->GetMinSize() > 0 ) + cmd += " --min_size " + SMESH_Comment( hyp->GetMinSize() ); + if ( hyp->GetMaxSize() > 0 ) + cmd += " --max_size " + SMESH_Comment( hyp->GetMaxSize() ); } // to define volumic gradation. - if ( gra && hyp ) { - if ( forExecutable ) - cmd += " -Dcpropa=" + SMESH_Comment( hyp->myGradation ); - else - cmd += " --gradation " + SMESH_Comment( hyp->myGradation ); + if ( gra && hyp ) + { + cmd += " --gradation " + SMESH_Comment( hyp->myGradation ); + } + + if ( hyp ) + { + // proximity + if ( hyp->GetUseVolumeProximity() ) + { + cmd += " --volume_proximity_layers " + SMESH_Comment( hyp->GetNbVolumeProximityLayers() ); + } + + 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() )//value == NoValue() ) + { + if ( hyp->_defaultOptionValues.count( option )) + continue; // non-custom option with no value + //value.clear(); + } + if ( strncmp( "no", option.c_str(), 2 ) == 0 ) // options w/o values: --no_* + { + if ( !value.empty() && ToBool( value ) == false ) + continue; + value.clear(); + } + if ( option[0] != '-' ) + cmd += " --"; + else + cmd += " "; + cmd += option + " " + value; + } + } } #ifdef WIN32 @@ -1616,50 +1852,264 @@ std::string GHS3DPlugin_Hypothesis::GetExeName() GHS3DPlugin_Hypothesis::TGHS3DEnforcedVertexList GHS3DPlugin_Hypothesis::GetEnforcedVertices(const GHS3DPlugin_Hypothesis* hyp) { - return hyp ? hyp->_GetEnforcedVertices():DefaultGHS3DEnforcedVertexList(); + return hyp ? hyp->_GetEnforcedVertices(): TGHS3DEnforcedVertexList(); } GHS3DPlugin_Hypothesis::TGHS3DEnforcedVertexCoordsValues GHS3DPlugin_Hypothesis::GetEnforcedVerticesCoordsSize (const GHS3DPlugin_Hypothesis* hyp) { - return hyp ? hyp->_GetEnforcedVerticesCoordsSize(): DefaultGHS3DEnforcedVertexCoordsValues(); + return hyp ? hyp->_GetEnforcedVerticesCoordsSize(): TGHS3DEnforcedVertexCoordsValues(); } GHS3DPlugin_Hypothesis::TGHS3DEnforcedVertexEntryValues GHS3DPlugin_Hypothesis::GetEnforcedVerticesEntrySize (const GHS3DPlugin_Hypothesis* hyp) { - return hyp ? hyp->_GetEnforcedVerticesEntrySize(): DefaultGHS3DEnforcedVertexEntryValues(); + return hyp ? hyp->_GetEnforcedVerticesEntrySize(): TGHS3DEnforcedVertexEntryValues(); } GHS3DPlugin_Hypothesis::TCoordsGHS3DEnforcedVertexMap GHS3DPlugin_Hypothesis::GetEnforcedVerticesByCoords (const GHS3DPlugin_Hypothesis* hyp) { - return hyp ? hyp->_GetEnforcedVerticesByCoords(): DefaultCoordsGHS3DEnforcedVertexMap(); + return hyp ? hyp->_GetEnforcedVerticesByCoords(): TCoordsGHS3DEnforcedVertexMap(); } GHS3DPlugin_Hypothesis::TGeomEntryGHS3DEnforcedVertexMap GHS3DPlugin_Hypothesis::GetEnforcedVerticesByEntry (const GHS3DPlugin_Hypothesis* hyp) { - return hyp ? hyp->_GetEnforcedVerticesByEntry(): DefaultGeomEntryGHS3DEnforcedVertexMap(); + return hyp ? hyp->_GetEnforcedVerticesByEntry(): TGeomEntryGHS3DEnforcedVertexMap(); } GHS3DPlugin_Hypothesis::TIDSortedNodeGroupMap GHS3DPlugin_Hypothesis::GetEnforcedNodes(const GHS3DPlugin_Hypothesis* hyp) { - return hyp ? hyp->_GetEnforcedNodes():DefaultIDSortedNodeGroupMap(); + return hyp ? hyp->_GetEnforcedNodes():TIDSortedNodeGroupMap(); } GHS3DPlugin_Hypothesis::TIDSortedElemGroupMap GHS3DPlugin_Hypothesis::GetEnforcedEdges(const GHS3DPlugin_Hypothesis* hyp) { - return hyp ? hyp->_GetEnforcedEdges():DefaultIDSortedElemGroupMap(); + return hyp ? hyp->_GetEnforcedEdges():TIDSortedElemGroupMap(); } GHS3DPlugin_Hypothesis::TIDSortedElemGroupMap GHS3DPlugin_Hypothesis::GetEnforcedTriangles(const GHS3DPlugin_Hypothesis* hyp) { - return hyp ? hyp->_GetEnforcedTriangles():DefaultIDSortedElemGroupMap(); + return hyp ? hyp->_GetEnforcedTriangles():TIDSortedElemGroupMap(); } GHS3DPlugin_Hypothesis::TID2SizeMap GHS3DPlugin_Hypothesis::GetNodeIDToSizeMap(const GHS3DPlugin_Hypothesis* hyp) { - return hyp ? hyp->_GetNodeIDToSizeMap(): DefaultID2SizeMap(); + return hyp ? hyp->_GetNodeIDToSizeMap(): TID2SizeMap(); } GHS3DPlugin_Hypothesis::TSetStrings GHS3DPlugin_Hypothesis::GetGroupsToRemove(const GHS3DPlugin_Hypothesis* hyp) { - return hyp ? hyp->_GetGroupsToRemove(): DefaultGroupsToRemove(); + return hyp ? hyp->_GetGroupsToRemove(): TSetStrings(); } + + +//============================================================================= +void GHS3DPlugin_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 GHS3DPlugin_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 GHS3DPlugin_Hypothesis::HasOptionDefined( const std::string& optionName ) const +{ + bool isDefault = false; + try + { + GetOptionValue( optionName, &isDefault ); + } + catch ( std::invalid_argument ) + { + return false; + } + return !isDefault; +} + +//============================================================================= +void GHS3DPlugin_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(); + } +} + +//============================================================================= +GHS3DPlugin_Hypothesis::TOptionValues GHS3DPlugin_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 GHS3DPlugin_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 GHS3DPlugin_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 Converts a string to a integer value + */ +//================================================================================ + +int GHS3DPlugin_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; +} + diff --git a/src/GHS3DPlugin/GHS3DPlugin_Hypothesis.hxx b/src/GHS3DPlugin/GHS3DPlugin_Hypothesis.hxx index 77cde27..667c8eb 100644 --- a/src/GHS3DPlugin/GHS3DPlugin_Hypothesis.hxx +++ b/src/GHS3DPlugin/GHS3DPlugin_Hypothesis.hxx @@ -119,6 +119,19 @@ public: typedef std::set TSetStrings; static const char* GetHypType() { return "MG-Tetra Parameters"; } + + void SetMinSize(double theMinSize); + double GetMinSize() const { return myMinSize; } + + void SetMaxSize(double theMaxSize); + double GetMaxSize() const { return myMaxSize; } + + void SetUseVolumeProximity( bool toUse ); + bool GetUseVolumeProximity() const { return myUseVolumeProximity; } + + void SetNbVolumeProximityLayers( int nbLayers ); + int GetNbVolumeProximityLayers() const { return myNbVolumeProximityLayers; } + /*! * To mesh "holes" in a solid or not. Default is to mesh. */ @@ -215,6 +228,19 @@ public: void SetRemoveLogOnSuccess(bool removeLogOnSuccess); bool GetRemoveLogOnSuccess() const ; + + 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 inline const char* NoValue() { return "_"; } // struct TEnforcedEdge { // long ID; @@ -302,24 +328,15 @@ public: static bool DefaultToRemoveCentralPoint(); static bool DefaultStandardOutputLog(); static bool DefaultRemoveLogOnSuccess(); - static double DefaultGradation(); - - static TGHS3DEnforcedVertex DefaultGHS3DEnforcedVertex() {return TGHS3DEnforcedVertex();} - static TGHS3DEnforcedVertexList DefaultGHS3DEnforcedVertexList() {return TGHS3DEnforcedVertexList();} - static TGHS3DEnforcedVertexCoordsValues DefaultGHS3DEnforcedVertexCoordsValues() {return TGHS3DEnforcedVertexCoordsValues();} - static TGHS3DEnforcedVertexEntryValues DefaultGHS3DEnforcedVertexEntryValues() {return TGHS3DEnforcedVertexEntryValues();} - static TCoordsGHS3DEnforcedVertexMap DefaultCoordsGHS3DEnforcedVertexMap() {return TCoordsGHS3DEnforcedVertexMap();} - static TGeomEntryGHS3DEnforcedVertexMap DefaultGeomEntryGHS3DEnforcedVertexMap() {return TGeomEntryGHS3DEnforcedVertexMap();} - static TGroupNameGHS3DEnforcedVertexMap DefaultGroupNameGHS3DEnforcedVertexMap() {return TGroupNameGHS3DEnforcedVertexMap();} - - static TGHS3DEnforcedMesh DefaultGHS3DEnforcedMesh() {return TGHS3DEnforcedMesh();} - static TGHS3DEnforcedMeshList DefaultGHS3DEnforcedMeshList() {return TGHS3DEnforcedMeshList();} - static TEntryGHS3DEnforcedMeshListMap DefaultEntryGHS3DEnforcedMeshListMap() {return TEntryGHS3DEnforcedMeshListMap();} - static TIDSortedNodeGroupMap DefaultIDSortedNodeGroupMap() {return TIDSortedNodeGroupMap();} - static TIDSortedElemGroupMap DefaultIDSortedElemGroupMap() {return TIDSortedElemGroupMap();} - static TID2SizeMap DefaultID2SizeMap() {return TID2SizeMap();} - static TSetStrings DefaultGroupsToRemove() {return TSetStrings();} - + static inline double DefaultGradation() { return 1.05; } + static bool DefaultUseVolumeProximity() { return false; } + static int DefaultNbVolumeProximityLayers() { return 2; } + + void SetMinMaxSizeDefault( double theMinSize, double theMaxSize ) + { myMinSizeDefault = theMinSize; myMaxSizeDefault = theMaxSize; } + double GetMinSizeDefault() const { return myMinSizeDefault; } + double GetMaxSizeDefault() const { return myMaxSizeDefault; } + // Persistence virtual std::ostream & SaveTo(std::ostream & save); virtual std::istream & LoadFrom(std::istream & load); @@ -334,6 +351,10 @@ public: */ virtual bool SetParametersByDefaults(const TDefaults& dflts, const SMESH_Mesh* theMesh=0); + 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); + protected: bool myToMeshHoles; @@ -350,9 +371,17 @@ protected: bool myToRemoveCentralPoint; bool myLogInStandardOutput; bool myRemoveLogOnSuccess; - std::string myTextOption; double myGradation; + bool myUseVolumeProximity; + int myNbVolumeProximityLayers; + double myMinSize, myMinSizeDefault; + double myMaxSize, myMaxSizeDefault; + //std::string myTextOption; + TOptionValues _option2value, _customOption2value; // user defined values + TOptionValues _defaultOptionValues; // default values + TOptionNames _doubleOptions, _charOptions, _boolOptions; // to find a type of option + TGHS3DEnforcedVertexList _enfVertexList; TGHS3DEnforcedVertexCoordsValues _enfVertexCoordsSizeList; TGHS3DEnforcedVertexEntryValues _enfVertexEntrySizeList; diff --git a/src/GHS3DPlugin/GHS3DPlugin_Hypothesis_i.cxx b/src/GHS3DPlugin/GHS3DPlugin_Hypothesis_i.cxx index b686ff5..38babcd 100644 --- a/src/GHS3DPlugin/GHS3DPlugin_Hypothesis_i.cxx +++ b/src/GHS3DPlugin/GHS3DPlugin_Hypothesis_i.cxx @@ -31,12 +31,8 @@ #include #include #include -//#include #include -// SALOME KERNEL includes -// #include -// #include using namespace std; @@ -82,6 +78,92 @@ CORBA::Boolean GHS3DPlugin_Hypothesis_i::GetToMeshHoles() return this->GetImpl()->GetToMeshHoles(); } +//============================================================================= +void GHS3DPlugin_Hypothesis_i::SetMinSize(CORBA::Double theMinSize) +{ + if ( GetMinSize() != theMinSize ) { + this->GetImpl()->SetMinSize( theMinSize ); + SMESH::TPythonDump() << _this() << ".SetMinSize( " << theMinSize << " )"; + } +} + +//============================================================================= +CORBA::Double GHS3DPlugin_Hypothesis_i::GetMinSize() +{ + return this->GetImpl()->GetMinSize(); +} + +//============================================================================= +CORBA::Double GHS3DPlugin_Hypothesis_i::GetMinSizeDefault() +{ + return this->GetImpl()->GetMinSizeDefault(); +} + +//============================================================================= +void GHS3DPlugin_Hypothesis_i::SetMaxSize(CORBA::Double theMaxSize) +{ + if ( GetMaxSize() != theMaxSize ) { + this->GetImpl()->SetMaxSize( theMaxSize ); + SMESH::TPythonDump() << _this() << ".SetMaxSize( " << theMaxSize << " )"; + } +} + +//============================================================================= +CORBA::Double GHS3DPlugin_Hypothesis_i::GetMaxSize() +{ + return this->GetImpl()->GetMaxSize(); +} + +//============================================================================= +CORBA::Double GHS3DPlugin_Hypothesis_i::GetMaxSizeDefault() +{ + return this->GetImpl()->GetMaxSizeDefault(); +} + +//============================================================================= +void GHS3DPlugin_Hypothesis_i::SetMinMaxSizeDefault( CORBA::Double theMinSize, + CORBA::Double theMaxSize ) +{ + this->GetImpl()->SetMinMaxSizeDefault( theMinSize, theMaxSize ); +} + +//============================================================================= +/*! + * Activate/deactivate volume proximity computation + */ +void GHS3DPlugin_Hypothesis_i::SetVolumeProximity( CORBA::Boolean toUse ) +{ + if ( GetVolumeProximity() != toUse ) + { + this->GetImpl()->SetUseVolumeProximity( toUse ); + SMESH::TPythonDump() << _this() << ".SetVolumeProximity( " << toUse << " )"; + } +} + +CORBA::Boolean GHS3DPlugin_Hypothesis_i::GetVolumeProximity() +{ + return this->GetImpl()->GetUseVolumeProximity(); +} + + +//============================================================================= +/*! + * Set number of surface element layers to be generated due to volume proximity + */ +void GHS3DPlugin_Hypothesis_i::SetNbVolumeProximityLayers( CORBA::Short nbLayers ) +{ + if ( GetNbVolumeProximityLayers() != nbLayers ) + { + this->GetImpl()->SetNbVolumeProximityLayers( nbLayers ); + SMESH::TPythonDump() << _this() << ".SetNbVolumeProximityLayers( " << nbLayers << " )"; + } +} + +CORBA::Short GHS3DPlugin_Hypothesis_i::GetNbVolumeProximityLayers() +{ + return this->GetImpl()->GetNbVolumeProximityLayers(); +} + //======================================================================= //function : SetToMakeGroupsOfDomains //======================================================================= @@ -349,9 +431,7 @@ CORBA::Boolean GHS3DPlugin_Hypothesis_i::GetToRemoveCentralPoint() void GHS3DPlugin_Hypothesis_i::SetTextOption(const char* option) { - ASSERT(myBaseImpl); - this->GetImpl()->SetAdvancedOption(option); - SMESH::TPythonDump() << _this() << ".SetAdvancedOption( '" << option << "' )"; + SetAdvancedOption(option); } //======================================================================= @@ -360,20 +440,19 @@ void GHS3DPlugin_Hypothesis_i::SetTextOption(const char* option) char* GHS3DPlugin_Hypothesis_i::GetTextOption() { - ASSERT(myBaseImpl); - return CORBA::string_dup( this->GetImpl()->GetAdvancedOption().c_str() ); + return GetAdvancedOption(); } //======================================================================= //function : SetAdvancedOption //======================================================================= -void GHS3DPlugin_Hypothesis_i::SetAdvancedOption(const char* option) -{ - ASSERT(myBaseImpl); - this->GetImpl()->SetAdvancedOption(option); - SMESH::TPythonDump() << _this() << ".SetAdvancedOption( '" << option << "' )"; -} +// void GHS3DPlugin_Hypothesis_i::SetAdvancedOption(const char* option) +// { +// ASSERT(myBaseImpl); +// this->GetImpl()->SetAdvancedOption(option); +// SMESH::TPythonDump() << _this() << ".SetAdvancedOption( '" << option << "' )"; +// } //======================================================================= //function : GetAdvancedOption @@ -385,8 +464,278 @@ char* GHS3DPlugin_Hypothesis_i::GetAdvancedOption() return CORBA::string_dup( this->GetImpl()->GetAdvancedOption().c_str() ); } +//============================================================================= + +void GHS3DPlugin_Hypothesis_i::SetOptionValue(const char* optionName, const char* optionValue) + throw (SALOME::SALOME_Exception) +{ + ASSERT(myBaseImpl); + try { + std::string name( optionName ); + if ( !optionValue || !optionValue[0] ) + UnsetOption( optionName ); + + // basic options (visible in Advanced table) + + 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 == "no_initial_central_point" && // optimizer + strcmp( GetImpl()->GetName(), ::GHS3DPlugin_Hypothesis::GetHypType() ) != 0 ) + { + //if ( strcmp( optionValue, ::GHS3DPlugin_Hypothesis::NoValue() ) == 0 ) + if ( !optionValue[0] ) + SetToRemoveCentralPoint( true ); + else + SetToRemoveCentralPoint( GetImpl()->ToBool( optionValue )); + } + else if ( name == "no_internal_points" && // optimizer + strcmp( GetImpl()->GetName(), ::GHS3DPlugin_Hypothesis::GetHypType() ) != 0) + { + //if ( strcmp( optionValue, ::GHS3DPlugin_Hypothesis::NoValue() ) == 0 ) + if ( !optionValue[0] ) + SetToRemoveCentralPoint( true ); + else + SetToCreateNewNodes( GetImpl()->ToBool( optionValue )); + } + else if ( name == "min_size" ) + SetMinSize( GetImpl()->ToDbl( optionValue )); + + else if ( name == "max_size" ) + SetMaxSize( GetImpl()->ToDbl( optionValue )); + + else if ( name == "gradation" ) + SetGradation( GetImpl()->ToDbl( optionValue )); + + else if ( name == "volume_proximity_layers" ) + SetNbVolumeProximityLayers( GetImpl()->ToInt( optionValue )); + + else if ( name == "components" ) + SetToMeshHoles( strncmp( "all", optionValue, 3 ) == 0 ); + + // 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* GHS3DPlugin_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 GHS3DPlugin_Hypothesis_i::UnsetOption(const char* optionName) { + ASSERT(myBaseImpl); + if ( !GetImpl()->GetOptionValue( optionName ).empty() ) + { + this->GetImpl()->ClearOption(optionName); + SMESH::TPythonDump() << _this() << ".UnsetOption( '" << optionName << "' )"; + } +} + +//============================================================================= + +GHS3DPlugin::string_array* GHS3DPlugin_Hypothesis_i::GetOptionValues() +{ + GHS3DPlugin::string_array_var result = new GHS3DPlugin::string_array(); + + const ::GHS3DPlugin_Hypothesis::TOptionValues & opts = this->GetImpl()->GetOptionValues(); + result->length(opts.size()); + int i=0; + + bool isDefault; + ::GHS3DPlugin_Hypothesis::TOptionValues::const_iterator opIt = opts.begin(); + for (; opIt != opts.end(); ++opIt, ++i) + { + 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(); +} + +//============================================================================= + +GHS3DPlugin::string_array* GHS3DPlugin_Hypothesis_i::GetAdvancedOptionValues() +{ + GHS3DPlugin::string_array_var result = new GHS3DPlugin::string_array(); + + const ::GHS3DPlugin_Hypothesis::TOptionValues & custom_opts = this->GetImpl()->GetCustomOptionValues(); + result->length(custom_opts.size()); + int i=0; + + ::GHS3DPlugin_Hypothesis::TOptionValues::const_iterator opIt = custom_opts.begin(); + for (; opIt != custom_opts.end(); ++opIt, ++i) { + 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 GHS3DPlugin_Hypothesis_i::SetOptionValues(const GHS3DPlugin::string_array& options) + throw (SALOME::SALOME_Exception) +{ + for (CORBA::ULong i = 0; i < options.length(); ++i) + { + string name_value_type = options[i].in(); + if(name_value_type.empty()) + continue; + size_t colonPos = name_value_type.find(':'); + string name, value; + if (colonPos == 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] != ' ') { + 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 GHS3DPlugin_Hypothesis_i::SetAdvancedOptionValues(const GHS3DPlugin::string_array& options) +{ + SMESH::TPythonDump dump; + + string optionsAndValues; + for ( CORBA::ULong i = 0; i < options.length(); ++i) { + string name_value_type = options[i].in(); + if(name_value_type.empty()) + continue; + size_t colonPos = name_value_type.find(':'); + string name, value; + if (colonPos == 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] != ' ') { + 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 GHS3DPlugin_Hypothesis_i::SetAdvancedOption(const char* optionsAndValues) + throw (SALOME::SALOME_Exception) +{ + if ( !optionsAndValues ) return; + + SMESH::TPythonDump dump; + + std::istringstream strm( optionsAndValues ); + std::istream_iterator sIt( strm ), sEnd; + for ( int nbPairs = 0; sIt != sEnd; ++nbPairs ) + { + std::string option = *sIt; + if ( ++sIt != sEnd ) + { + std::string value = *sIt; + ++sIt; + AddOption( option.c_str(), value.c_str() ); + } + else + { + if ( nbPairs > 0 ) + THROW_SALOME_CORBA_EXCEPTION( "Uneven number of options and values" ,SALOME::BAD_PARAM ); + AddOption( option.c_str(), "" ); + } + } + dump << _this() << ".SetAdvancedOption( '" << optionsAndValues << "' )"; +} + +//============================================================================= + +void GHS3DPlugin_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* GHS3DPlugin_Hypothesis_i::GetOption(const char* optionName) +{ + ASSERT(myBaseImpl); + return CORBA::string_dup(this->GetImpl()->GetOptionValue(optionName).c_str()); +} + //======================================================================= -//function : SetToRemoveCentralPoint +//function : SetGradation //======================================================================= void GHS3DPlugin_Hypothesis_i::SetGradation(CORBA::Double gradation) @@ -399,7 +748,7 @@ void GHS3DPlugin_Hypothesis_i::SetGradation(CORBA::Double gradation) } //======================================================================= -//function : GetToRemoveCentralPoint +//function : GetGradation //======================================================================= CORBA::Double GHS3DPlugin_Hypothesis_i::GetGradation() diff --git a/src/GHS3DPlugin/GHS3DPlugin_Hypothesis_i.hxx b/src/GHS3DPlugin/GHS3DPlugin_Hypothesis_i.hxx index 2860543..37f1a86 100644 --- a/src/GHS3DPlugin/GHS3DPlugin_Hypothesis_i.hxx +++ b/src/GHS3DPlugin/GHS3DPlugin_Hypothesis_i.hxx @@ -54,6 +54,22 @@ class GHS3DPLUGIN_EXPORT GHS3DPlugin_Hypothesis_i: */ void SetToMeshHoles(CORBA::Boolean toMesh); CORBA::Boolean GetToMeshHoles(); + /*! + * Activate/deactivate volume proximity computation + */ + void SetVolumeProximity( CORBA::Boolean toUse ); + CORBA::Boolean GetVolumeProximity(); + /*! + * Set number of surface element layers to be generated due to volume proximity + */ + void SetNbVolumeProximityLayers( CORBA::Short nbLayers ); + CORBA::Short GetNbVolumeProximityLayers(); + + void SetMaxSize(CORBA::Double theMaxSize); + CORBA::Double GetMaxSize(); + + void SetMinSize(CORBA::Double theMinSize); + CORBA::Double GetMinSize(); /*! * To make groups of volumes of different domains when mesh is generated from skin. * Default is to make groups. @@ -126,10 +142,23 @@ class GHS3DPLUGIN_EXPORT GHS3DPlugin_Hypothesis_i: /*! * To set hiden/undocumented/advanced options */ - void SetAdvancedOption(const char* option); + void SetAdvancedOption(const char* option) throw (SALOME::SALOME_Exception); char* GetAdvancedOption(); void SetTextOption(const char* option); // obsolete char* GetTextOption(); + + 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); + + GHS3DPlugin::string_array* GetOptionValues(); + GHS3DPlugin::string_array* GetAdvancedOptionValues(); + + void SetOptionValues(const GHS3DPlugin::string_array& options) throw (SALOME::SALOME_Exception); + void SetAdvancedOptionValues(const GHS3DPlugin::string_array& options); + + void AddOption(const char* optionName, const char* optionValue); + char* GetOption(const char* optionName); /*! * To define the volumic gradation */ @@ -179,6 +208,11 @@ class GHS3DPLUGIN_EXPORT GHS3DPlugin_Hypothesis_i: GHS3DPlugin::GHS3DEnforcedMeshList* GetEnforcedMeshes(); void ClearEnforcedMeshes(); + // 3 GUI methods + CORBA::Double GetMaxSizeDefault(); + CORBA::Double GetMinSizeDefault(); + void SetMinMaxSizeDefault( CORBA::Double theMinSize, CORBA::Double theMaxSize ); + // Get implementation ::GHS3DPlugin_Hypothesis* GetImpl(); diff --git a/src/GHS3DPlugin/GHS3DPlugin_OptimizerHypothesis.cxx b/src/GHS3DPlugin/GHS3DPlugin_OptimizerHypothesis.cxx index 1ad894f..d4b2961 100644 --- a/src/GHS3DPlugin/GHS3DPlugin_OptimizerHypothesis.cxx +++ b/src/GHS3DPlugin/GHS3DPlugin_OptimizerHypothesis.cxx @@ -195,7 +195,7 @@ std::string GHS3DPlugin_OptimizerHypothesis::CommandToRun(const GHS3DPlugin_Opti cmd << " --verbose " << hyp->myVerboseLevel; - cmd << " " << hyp->myTextOption; + //cmd << " " << hyp->myTextOption; } return cmd; diff --git a/src/GUI/CMakeLists.txt b/src/GUI/CMakeLists.txt index 1665d35..e381f5f 100644 --- a/src/GUI/CMakeLists.txt +++ b/src/GUI/CMakeLists.txt @@ -33,6 +33,7 @@ INCLUDE_DIRECTORIES( ${CMAKE_CURRENT_BINARY_DIR} ${PROJECT_BINARY_DIR}/idl ${PROJECT_SOURCE_DIR}/src/GHS3DPlugin + ${PROJECT_SOURCE_DIR}/src/GUI ) # additional preprocessor / compiler flags @@ -65,6 +66,7 @@ SET(_link_LIBRARIES SET(_moc_HEADERS GHS3DPluginGUI_HypothesisCreator.h GHS3DPluginGUI_Dlg.h + GHS3DPluginGUI_TreeWidget.h ) # header files / no moc processed @@ -84,6 +86,7 @@ SET(_other_SOURCES GHS3DPluginGUI.cxx GHS3DPluginGUI_HypothesisCreator.cxx GHS3DPluginGUI_AdvWidget.cxx + GHS3DPluginGUI_TreeWidget.cxx ) # --- resources --- diff --git a/src/GUI/GHS3DPluginGUI_AdvWidget.cxx b/src/GUI/GHS3DPluginGUI_AdvWidget.cxx index 18a79bf..a29f5eb 100644 --- a/src/GUI/GHS3DPluginGUI_AdvWidget.cxx +++ b/src/GUI/GHS3DPluginGUI_AdvWidget.cxx @@ -28,7 +28,23 @@ #include #include +#include +namespace +{ + enum { EDITABLE_ROLE = Qt::UserRole + 1, PARAM_NAME, + NAME_COL = 0, VALUE_COL }; + + class ItemDelegate: public QItemDelegate { + public: + ItemDelegate(QObject* parent=0): QItemDelegate(parent) {} + QWidget* createEditor(QWidget *parent, const QStyleOptionViewItem &o, const QModelIndex &index) const + { + bool editable = index.data( EDITABLE_ROLE ).toInt(); + return editable ? QItemDelegate::createEditor( parent, o, index ) : 0; + } + }; +} ////////////////////////////////////////// // GHS3DPluginGUI_AdvWidget @@ -38,9 +54,84 @@ GHS3DPluginGUI_AdvWidget::GHS3DPluginGUI_AdvWidget( QWidget* parent, Qt::WindowF : QWidget( parent, f ) { setupUi( this ); - advOptionTable->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 ))); } GHS3DPluginGUI_AdvWidget::~GHS3DPluginGUI_AdvWidget() { } + +void GHS3DPluginGUI_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 == GHS3DPlugin_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 GHS3DPluginGUI_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 = GHS3DPlugin_Hypothesis::NoValue(); +} + + +void GHS3DPluginGUI_AdvWidget::itemChanged(QTreeWidgetItem * tblRow, int column) +{ + if ( tblRow ) + { + myOptionTable->blockSignals( true ); + + tblRow->setData( VALUE_COL, EDITABLE_ROLE, int( tblRow->checkState( NAME_COL ))); + + int c = tblRow->checkState( NAME_COL ) ? 0 : 150; + tblRow->setForeground( VALUE_COL, QBrush( QColor( c, c, c ))); + + if ( column == NAME_COL && tblRow->data( NAME_COL, EDITABLE_ROLE ).toInt() ) // custom table + { + tblRow->setData( NAME_COL, PARAM_NAME, tblRow->text( NAME_COL )); + } + + myOptionTable->blockSignals( false ); + } +} diff --git a/src/GUI/GHS3DPluginGUI_AdvWidget_QTD.ui b/src/GUI/GHS3DPluginGUI_AdvWidget_QTD.ui index e589dc5..dea16fe 100644 --- a/src/GUI/GHS3DPluginGUI_AdvWidget_QTD.ui +++ b/src/GUI/GHS3DPluginGUI_AdvWidget_QTD.ui @@ -6,24 +6,67 @@ 0 0 - 485 - 477 + 337 + 369 Form - - - 0 - - - 0 - - - 0 - - + + + + + QAbstractItemView::DoubleClicked|QAbstractItemView::EditKeyPressed + + + true + + + + OPTION_NAME_COLUMN + + + + 50 + false + + + + + + OPTION_VALUE_COLUMN + + + + 50 + false + + + + + + + + + GHS3D_ADD_OPTION + + + + + + + Qt::Horizontal + + + + 188 + 20 + + + + + Memory settings @@ -104,7 +147,7 @@ - + Logs and debug @@ -178,56 +221,6 @@ - - - - Advanced meshing options - - - - - - Use FEM correction - - - - - - - Remove initial central point - - - - - - - - - - Volumic gradation - - - - - - - Create new nodes - - - - - - - Use boundary recovery version - - - - - - - - - @@ -237,10 +230,9 @@
SMESHGUI_SpinBox.h
- SMESH_AdvOptionsWdg - QWidget -
SMESH_AdvOptionsWdg.h
- 1 + GHS3DPluginGUI_TreeWidget + QTreeWidget +
GHS3DPluginGUI_TreeWidget.h
diff --git a/src/GUI/GHS3DPluginGUI_Dlg.h b/src/GUI/GHS3DPluginGUI_Dlg.h index a647e3d..dbd491d 100644 --- a/src/GUI/GHS3DPluginGUI_Dlg.h +++ b/src/GUI/GHS3DPluginGUI_Dlg.h @@ -23,6 +23,14 @@ #ifndef GHS3DPLUGINGUI_H #define GHS3DPLUGINGUI_H +enum { + OPTION_ID_COLUMN = 0, + OPTION_TYPE_COLUMN, + OPTION_NAME_COLUMN = 0, + OPTION_VALUE_COLUMN, + NB_COLUMNS, +}; + ////////////////////////////////////////// // GHS3DPluginGUI_AdvWidget ////////////////////////////////////////// @@ -38,6 +46,13 @@ class GHS3DPLUGINGUI_EXPORT GHS3DPluginGUI_AdvWidget : public QWidget, public: GHS3DPluginGUI_AdvWidget( QWidget* = 0, Qt::WindowFlags = 0 ); ~GHS3DPluginGUI_AdvWidget(); + + void AddOption( const char* name_value_type, bool isCustom = false ); + void GetOptionAndValue( QTreeWidgetItem * tblRow, QString& option, QString& value, bool& dflt ); + +public slots: + + void itemChanged(QTreeWidgetItem * tblRow, int column); }; #endif diff --git a/src/GUI/GHS3DPluginGUI_HypothesisCreator.cxx b/src/GUI/GHS3DPluginGUI_HypothesisCreator.cxx index 452397b..2183f96 100644 --- a/src/GUI/GHS3DPluginGUI_HypothesisCreator.cxx +++ b/src/GUI/GHS3DPluginGUI_HypothesisCreator.cxx @@ -294,7 +294,25 @@ void EnforcedMeshTableWidgetDelegate::updateEditorGeometry(QWidget *editor, GHS3DPluginGUI_HypothesisCreator::GHS3DPluginGUI_HypothesisCreator( const QString& theHypType ) - : SMESHGUI_GenericHypothesisCreator( theHypType ) + : SMESHGUI_GenericHypothesisCreator( theHypType ), + myName(0), + myOptimizationLevelCombo(0), + myMinSizeCheck(0), + myMaxSizeCheck(0), + myMinSizeSpin(0), + myMaxSizeSpin(0), + myGradationCheck(0), + myGradationSpin(0), + myUseProximityGroup(0), + myNbProximityLayers(0), + myToMakeGroupsOfDomains(0), + myToMeshHolesCheck(0), + myOptimizationCombo(0), + mySplitOverConstrainedCombo(0), + myPThreadsModeCombo(0), + myNumberOfThreadsSpin(0), + mySmoothOffSliversCheck(0), + myCreateNewNodesCheck(0) { GeomToolSelected = NULL; GeomToolSelected = getGeomSelectionTool(); @@ -354,73 +372,127 @@ QFrame* GHS3DPluginGUI_HypothesisCreator::buildFrame() aStdLayout->setMargin( 11 ); int row = 0; - myName = 0; if ( isCreation() ) { aStdLayout->addWidget( new QLabel( tr( "SMESH_NAME" ), myStdGroup ), row, 0, 1, 1 ); myName = new QLineEdit( myStdGroup ); aStdLayout->addWidget( myName, row++, 1, 1, 1 ); } - - myToMeshHolesCheck = new QCheckBox( tr( "GHS3D_TO_MESH_HOLES" ), myStdGroup ); - aStdLayout->addWidget( myToMeshHolesCheck, row, 0, 1, 1 ); - myToMakeGroupsOfDomains = new QCheckBox( tr( "GHS3D_TO_MAKE_DOMAIN_GROUPS" ), myStdGroup ); - aStdLayout->addWidget( myToMakeGroupsOfDomains, row++, 1, 1, 1 ); - - QLabel* optimizationLbl = new QLabel( tr( "GHS3D_OPTIMIZATION" ), myStdGroup ); - aStdLayout->addWidget( optimizationLbl, row, 0, 1, 1 ); - myOptimizationCombo = getModeCombo( myStdGroup, false ); - aStdLayout->addWidget( myOptimizationCombo, row++, 1, 1, 1 ); - - QLabel* optimizatiolLevelLbl = new QLabel( tr( "GHS3D_OPTIMIZATIOL_LEVEL" ), myStdGroup ); - aStdLayout->addWidget( optimizatiolLevelLbl, row, 0, 1, 1 ); - myOptimizationLevelCombo = new QComboBox( myStdGroup ); - aStdLayout->addWidget( myOptimizationLevelCombo, row++, 1, 1, 1 ); - - QLabel* splitOverconstrainedLbl = new QLabel( tr("GHS3D_SPLIT_OVERCONSTRAINED"), myStdGroup ); - aStdLayout->addWidget( splitOverconstrainedLbl, row, 0, 1, 1 ); - mySplitOverConstrainedCombo = getModeCombo( myStdGroup, false ); - aStdLayout->addWidget( mySplitOverConstrainedCombo, row++, 1, 1, 1 ); - - QLabel* pthreadsModeLbl = new QLabel( tr( "GHS3D_PTHREADS_MODE" ), myStdGroup); - aStdLayout->addWidget( pthreadsModeLbl, row, 0, 1, 1 ); - myPThreadsModeCombo = getModeCombo( myStdGroup, true ); - aStdLayout->addWidget( myPThreadsModeCombo, row++, 1, 1, 1 ); - - QLabel* nbThreadsLbl = new QLabel( tr( "GHS3D_NB_THREADS" ), myStdGroup); - aStdLayout->addWidget( nbThreadsLbl, row, 0, 1, 1 ); - myNumberOfThreadsSpin = new SalomeApp_IntSpinBox( 0, 1000, 1, myStdGroup ); - aStdLayout->addWidget( myNumberOfThreadsSpin, row++, 1, 1, 1 ); - - mySmoothOffSliversCheck = new QCheckBox( tr( "GHS3D_SMOOTH_OFF_SLIVERS" ), myStdGroup ); - aStdLayout->addWidget( mySmoothOffSliversCheck, row, 0, 1, 1 ); - myCreateNewNodesCheck = new QCheckBox( tr( "TO_ADD_NODES" ), myStdGroup ); - aStdLayout->addWidget( myCreateNewNodesCheck, row++, 1, 1, 1 ); - - myOptimizationLevelCombo->addItems( QStringList() - << tr( "LEVEL_NONE" ) << tr( "LEVEL_LIGHT" ) - << tr( "LEVEL_MEDIUM" ) << tr( "LEVEL_STANDARDPLUS" ) - << tr( "LEVEL_STRONG" )); - aStdLayout->setRowStretch( row, 10 ); - if ( isOptimization() ) { - myToMeshHolesCheck->hide(); - myToMakeGroupsOfDomains->hide(); + myToMeshHolesCheck = new QCheckBox( tr( "GHS3D_TO_MESH_HOLES" ), myStdGroup ); + aStdLayout->addWidget( myToMeshHolesCheck, row, 0, 1, 1 ); + myToMakeGroupsOfDomains = new QCheckBox( tr( "GHS3D_TO_MAKE_DOMAIN_GROUPS" ), myStdGroup ); + aStdLayout->addWidget( myToMakeGroupsOfDomains, row++, 1, 1, 1 ); + + QLabel* optimizationLbl = new QLabel( tr( "GHS3D_OPTIMIZATION" ), myStdGroup ); + aStdLayout->addWidget( optimizationLbl, row, 0, 1, 1 ); + myOptimizationCombo = getModeCombo( myStdGroup, false ); + aStdLayout->addWidget( myOptimizationCombo, row++, 1, 1, 1 ); + + QLabel* optimizatiolLevelLbl = new QLabel( tr( "GHS3D_OPTIMIZATIOL_LEVEL" ), myStdGroup ); + aStdLayout->addWidget( optimizatiolLevelLbl, row, 0, 1, 1 ); + myOptimizationLevelCombo = new QComboBox( myStdGroup ); + aStdLayout->addWidget( myOptimizationLevelCombo, row++, 1, 1, 1 ); + + QLabel* splitOverconstrainedLbl = new QLabel( tr("GHS3D_SPLIT_OVERCONSTRAINED"), myStdGroup ); + aStdLayout->addWidget( splitOverconstrainedLbl, row, 0, 1, 1 ); + mySplitOverConstrainedCombo = getModeCombo( myStdGroup, false ); + aStdLayout->addWidget( mySplitOverConstrainedCombo, row++, 1, 1, 1 ); + + QLabel* pthreadsModeLbl = new QLabel( tr( "GHS3D_PTHREADS_MODE" ), myStdGroup); + aStdLayout->addWidget( pthreadsModeLbl, row, 0, 1, 1 ); + myPThreadsModeCombo = getModeCombo( myStdGroup, true ); + aStdLayout->addWidget( myPThreadsModeCombo, row++, 1, 1, 1 ); + + QLabel* nbThreadsLbl = new QLabel( tr( "GHS3D_NB_THREADS" ), myStdGroup); + aStdLayout->addWidget( nbThreadsLbl, row, 0, 1, 1 ); + myNumberOfThreadsSpin = new SalomeApp_IntSpinBox( 0, 1000, 1, myStdGroup ); + aStdLayout->addWidget( myNumberOfThreadsSpin, row++, 1, 1, 1 ); + + mySmoothOffSliversCheck = new QCheckBox( tr( "GHS3D_SMOOTH_OFF_SLIVERS" ), myStdGroup ); + aStdLayout->addWidget( mySmoothOffSliversCheck, row, 0, 1, 1 ); + myCreateNewNodesCheck = new QCheckBox( tr( "TO_ADD_NODES" ), myStdGroup ); + aStdLayout->addWidget( myCreateNewNodesCheck, row++, 1, 1, 1 ); } else { - optimizationLbl->hide(); - myOptimizationCombo->hide(); - splitOverconstrainedLbl->hide(); - mySplitOverConstrainedCombo->hide(); - pthreadsModeLbl->hide(); - myPThreadsModeCombo->hide(); - nbThreadsLbl->hide(); - myNumberOfThreadsSpin->hide(); - mySmoothOffSliversCheck->hide(); - myCreateNewNodesCheck->hide(); + // Main parameters + + QGroupBox* mainGroup = new QGroupBox( tr("GHS3D_MAIN_PARAMS"), myStdGroup ); + QLabel* optimizatiolLevelLbl = new QLabel( tr( "GHS3D_OPTIMIZATIOL_LEVEL" ), mainGroup ); + myOptimizationLevelCombo = new QComboBox( mainGroup ); + myMinSizeCheck = new QCheckBox( tr("GHS3D_MIN_SIZE"), mainGroup ); + myMaxSizeCheck = new QCheckBox( tr("GHS3D_MAX_SIZE"), mainGroup ); + myMinSizeSpin = new SMESHGUI_SpinBox( mainGroup ); + myMaxSizeSpin = new SMESHGUI_SpinBox( mainGroup ); + myMinSizeCheck->setChecked( false ); + myMaxSizeCheck->setChecked( false ); + myMinSizeSpin->RangeStepAndValidator(0, COORD_MAX, 10.0, "length_precision"); + myMaxSizeSpin->RangeStepAndValidator(0, COORD_MAX, 10.0, "length_precision"); + myMinSizeSpin->setEnabled( false ); + myMaxSizeSpin->setEnabled( false ); + connect( myMinSizeCheck, SIGNAL( toggled(bool)), myMinSizeSpin, SLOT( setEnabled(bool))); + connect( myMaxSizeCheck, SIGNAL( toggled(bool)), myMaxSizeSpin, SLOT( setEnabled(bool))); + + QGridLayout* mainLayout = new QGridLayout( mainGroup ); + mainLayout->setSpacing( 6 ); + mainLayout->setMargin( 11 ); + mainLayout->addWidget( optimizatiolLevelLbl, 0, 0, 1, 1 ); + mainLayout->addWidget( myOptimizationLevelCombo, 0, 1, 1, 1 ); + mainLayout->addWidget( myMinSizeCheck, 1, 0, 1, 1 ); + mainLayout->addWidget( myMinSizeSpin, 1, 1, 1, 1 ); + mainLayout->addWidget( myMaxSizeCheck, 2, 0, 1, 1 ); + mainLayout->addWidget( myMaxSizeSpin, 2, 1, 1, 1 ); + + // Volume proximity + + QGroupBox* proxyGroup = new QGroupBox( tr("GHS3D_VOLUME_PROXIMITY"), myStdGroup ); + myGradationCheck = new QCheckBox( tr("GHS3D_GRADATION"), proxyGroup ); + myGradationSpin = new SMESHGUI_SpinBox( proxyGroup ); + myGradationSpin->RangeStepAndValidator(1, COORD_MAX, 0.1, "length_precision"); + myGradationSpin->setEnabled( false ); + connect( myGradationCheck, SIGNAL( toggled(bool)), myGradationSpin, SLOT( setEnabled(bool))); + myUseProximityGroup = new QGroupBox( tr("GHS3D_USE_VOLUME_PROXIMITY"), proxyGroup ); + myUseProximityGroup->setCheckable( true ); + //myUseProximityGroup->setChecked( false ); + QLabel* nbProximityLayersLabel = new QLabel( tr("GHS3D_NB_LAYERS")); + myNbProximityLayers = new SalomeApp_IntSpinBox( 2, 1e6, 1, proxyGroup ); + + QHBoxLayout* useProxyLayout = new QHBoxLayout( myUseProximityGroup ); + useProxyLayout->addWidget( nbProximityLayersLabel ); + useProxyLayout->addWidget( myNbProximityLayers ); + + QGridLayout* proxyLayout = new QGridLayout( proxyGroup ); + proxyLayout->setSpacing( 6 ); + proxyLayout->setMargin( 11 ); + proxyLayout->addWidget( myGradationCheck, 0, 0, 1, 1 ); + proxyLayout->addWidget( myGradationSpin, 0, 1, 1, 1 ); + proxyLayout->addWidget( myUseProximityGroup, 1, 0, 1, 2 ); + + // Other parameters + + QGroupBox* otherGroup = new QGroupBox( tr("GHS3D_OTHER_PARAMETERS"), myStdGroup ); + myToMeshHolesCheck = new QCheckBox( tr( "GHS3D_TO_MESH_HOLES" ), otherGroup ); + myToMakeGroupsOfDomains = new QCheckBox( tr( "GHS3D_TO_MAKE_DOMAIN_GROUPS" ), otherGroup ); + + QGridLayout* otherLayout = new QGridLayout( otherGroup ); + otherLayout->setSpacing( 6 ); + otherLayout->setMargin( 11 ); + otherLayout->addWidget( myToMeshHolesCheck, 0, 0 ); + otherLayout->addWidget( myToMakeGroupsOfDomains, 1, 0 ); + + + aStdLayout->addWidget( mainGroup, row++, 0, 1, 2 ); + aStdLayout->addWidget( proxyGroup, row++, 0, 1, 2 ); + aStdLayout->addWidget( otherGroup, row++, 0, 1, 2 ); } + aStdLayout->setRowStretch( row, 10 ); + + myOptimizationLevelCombo->addItems( QStringList() + << tr( "LEVEL_NONE" ) << tr( "LEVEL_LIGHT" ) + << tr( "LEVEL_MEDIUM" ) << tr( "LEVEL_STANDARDPLUS" ) + << tr( "LEVEL_STRONG" )); // advanced parameters myAdvGroup = new QWidget(); @@ -451,24 +523,24 @@ QFrame* GHS3DPluginGUI_HypothesisCreator::buildFrame() myAdvWidget->memoryGroupBox ->setTitle(tr( "MEMORY_GROUP_TITLE" )); myAdvWidget->logGroupBox ->setTitle(tr( "LOG_GROUP_TITLE" )); - myAdvWidget->advancedMeshingGroupBox ->setTitle(tr( "ADVANCED_MESHING_GROUP_TITLE" )); + //myAdvWidget->advancedMeshingGroupBox ->setTitle(tr( "ADVANCED_MESHING_GROUP_TITLE" )); - 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( "GHS3D_GRADATION" )); - myAdvWidget->gradationSpinBox->RangeStepAndValidator(0.0, 5.0, 0.05, "length_precision"); - - if ( isOptimization() ) - { - myAdvWidget->createNewNodesCheck->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( "GHS3D_GRADATION" )); + // myAdvWidget->gradationSpinBox->RangeStepAndValidator(0.0, 5.0, 0.05, "length_precision"); + + // if ( isOptimization() ) + // { + // myAdvWidget->createNewNodesCheck->hide(); + // myAdvWidget->removeInitialCentralPointCheck->hide(); + // myAdvWidget->boundaryRecoveryCheck->hide(); + // myAdvWidget->FEMCorrectionCheck->hide(); + // myAdvWidget->gradationLabel->hide(); + // myAdvWidget->gradationSpinBox->hide(); + // } // Enforced vertices parameters myEnfGroup = new QWidget(); @@ -619,10 +691,10 @@ QFrame* GHS3DPluginGUI_HypothesisCreator::buildFrame() 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( 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() ) ); + connect( myAdvWidget->addBtn, SIGNAL( clicked() ), this, SLOT( onAddOption() ) ); connect( myEnforcedTableWidget, SIGNAL( itemClicked(QTableWidgetItem *)), this, SLOT( synchronizeCoords() ) ); connect( myEnforcedTableWidget, SIGNAL( itemChanged(QTableWidgetItem *)), this, SLOT( updateEnforcedVertexValues(QTableWidgetItem *) ) ); @@ -769,12 +841,12 @@ void GHS3DPluginGUI_HypothesisCreator::onSelectEnforcedVertex() myEnfVertex = myEnfVertexWdg->GetObject< GEOM::GEOM_Object >(nbSelEnfVertex-1); if (myEnfVertex == GEOM::GEOM_Object::_nil()) return; - if (myEnfVertex->GetShapeType() == GEOM::VERTEX) { - GHS3DPluginGUI_HypothesisCreator* that = (GHS3DPluginGUI_HypothesisCreator*)this; + if (myEnfVertex->GetShapeType() == GEOM::VERTEX) + { GEOM::GEOM_IMeasureOperations_var measureOp = getGeomEngine()->GetIMeasureOperations( ); if (CORBA::is_nil(measureOp)) return; - + CORBA::Double x,y,z; measureOp->PointCoordinates (myEnfVertex, x, y, z); if ( measureOp->IsDone() ) @@ -1309,15 +1381,14 @@ void GHS3DPluginGUI_HypothesisCreator::updateWidgets() { //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() ); + //myAdvWidget->initialMemoryCheck->setEnabled( !myAdvWidget->boundaryRecoveryCheck->isChecked() ); + myAdvWidget->initialMemorySpin->setEnabled( myAdvWidget->initialMemoryCheck->isChecked() /*&& !myAdvWidget->boundaryRecoveryCheck->isChecked()*/ ); + //myOptimizationLevelCombo->setEnabled( !myAdvWidget->boundaryRecoveryCheck->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 ); } } @@ -1331,7 +1402,43 @@ bool GHS3DPluginGUI_HypothesisCreator::checkParams(QString& msg) const return false; } - return true; + GHS3DPlugin::GHS3DPlugin_Hypothesis_var h = + GHS3DPlugin::GHS3DPlugin_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 GHS3DPluginGUI_HypothesisCreator::retrieveParams() const @@ -1351,31 +1458,49 @@ void GHS3DPluginGUI_HypothesisCreator::retrieveParams() const myToMeshHolesCheck ->setChecked ( data.myToMeshHoles ); myToMakeGroupsOfDomains ->setChecked ( data.myToMakeGroupsOfDomains ); myOptimizationLevelCombo ->setCurrentIndex( data.myOptimizationLevel ); - myOptimizationCombo ->setCurrentIndex( data.myOptimization ); - mySplitOverConstrainedCombo ->setCurrentIndex( data.mySplitOverConstrained ); - myPThreadsModeCombo ->setCurrentIndex( data.myPThreadsMode ); - myNumberOfThreadsSpin ->setValue ( data.myNumberOfThreads ); - mySmoothOffSliversCheck ->setChecked ( data.mySmoothOffSlivers ); - myCreateNewNodesCheck ->setChecked ( data.myToCreateNewNodes ); - + if ( myOptimizationCombo ) // optimizer + { + myOptimizationCombo ->setCurrentIndex( data.myOptimization ); + mySplitOverConstrainedCombo ->setCurrentIndex( data.mySplitOverConstrained ); + myPThreadsModeCombo ->setCurrentIndex( data.myPThreadsMode ); + myNumberOfThreadsSpin ->setValue ( data.myNumberOfThreads ); + mySmoothOffSliversCheck ->setChecked ( data.mySmoothOffSlivers ); + myCreateNewNodesCheck ->setChecked ( data.myToCreateNewNodes ); + } + else + { + myMinSizeSpin->setValue( data.myMinSize ); + myMinSizeCheck->setChecked( data.myUseMinSize ); + myMaxSizeSpin->setValue( data.myMaxSize ); + myMaxSizeCheck->setChecked( data.myUseMaxSize ); + myGradationCheck->setChecked( data.myUseGradation ); + myGradationSpin->setValue( data.myUseGradation ? data.myGradation : GHS3DPlugin_Hypothesis::DefaultGradation() ); + myUseProximityGroup->setChecked( data.myUseProximity ); + myNbProximityLayers->setValue( data.myNbProximityLayers ); + } myAdvWidget->maxMemoryCheck ->setChecked ( data.myMaximumMemory > 0 ); - myAdvWidget->maxMemorySpin ->setValue ( qMax( data.myMaximumMemory, - (float)myAdvWidget->maxMemorySpin->minimum() )); + myAdvWidget->maxMemorySpin ->setValue + ( qMax( data.myMaximumMemory, (float)myAdvWidget->maxMemorySpin->minimum() )); myAdvWidget->initialMemoryCheck ->setChecked ( data.myInitialMemory > 0 ); - myAdvWidget->initialMemorySpin ->setValue ( qMax( data.myInitialMemory, - (float)myAdvWidget->initialMemorySpin->minimum() )); + myAdvWidget->initialMemorySpin ->setValue + ( qMax( data.myInitialMemory, (float)myAdvWidget->initialMemorySpin->minimum() )); 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->advOptionTable ->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(); @@ -1535,20 +1660,17 @@ QString GHS3DPluginGUI_HypothesisCreator::storeParams() const if ( data.myRemoveInitialCentralPoint ) valStr += " --no_initial_central_point"; - if ( data.myBoundaryRecovery ) - valStr += " -C"; + // if ( data.myBoundaryRecovery ) + // valStr += " -C"; - if ( data.myFEMCorrection ) - valStr += " -FEM"; + // if ( data.myFEMCorrection ) + // valStr += " -FEM"; if ( data.myGradation != 1.05 ) { valStr += " -Dcpropa="; valStr += QString::number( data.myGradation ); } - valStr += " "; - valStr += data.myTextOption; - return valStr; } @@ -1570,31 +1692,47 @@ bool GHS3DPluginGUI_HypothesisCreator::readParamsFromHypo( GHS3DHypothesisData& h_data.myNumberOfThreads = opt->GetMaximalNumberOfThreads(); h_data.mySmoothOffSlivers = opt->GetSmoothOffSlivers(); } - else // avoid "Conditional jump or move depends on uninitialised value" error + else { + // avoid "Conditional jump or move depends on uninitialised value" error h_data.myOptimization = 1; h_data.mySplitOverConstrained = 1; h_data.myPThreadsMode = 1; h_data.myNumberOfThreads = 1; h_data.mySmoothOffSlivers = 1; } + h_data.myOptimizationLevel = h->GetOptimizationLevel(); + h_data.myMinSize = h->GetMinSize(); + h_data.myMaxSize = h->GetMaxSize(); + this->myMinSizeDefault = h->GetMinSizeDefault(); + this->myMaxSizeDefault = h->GetMaxSizeDefault(); + if ( ! ( h_data.myUseMinSize = h_data.myMinSize > 0 )) + h_data.myMinSize = this->myMinSizeDefault; + if ( ! ( h_data.myUseMaxSize = h_data.myMaxSize > 0 )) + h_data.myMaxSize = this->myMaxSizeDefault; + h_data.myNbProximityLayers = h->GetNbVolumeProximityLayers(); + h_data.myUseGradation = h->GetGradation() != GHS3DPlugin_Hypothesis::DefaultGradation(); + h_data.myUseProximity = h->GetVolumeProximity(); h_data.myToMeshHoles = h->GetToMeshHoles(); h_data.myToMakeGroupsOfDomains = h->GetToMakeGroupsOfDomains(); h_data.myMaximumMemory = h->GetMaximumMemory(); h_data.myInitialMemory = h->GetInitialMemory(); h_data.myInitialMemory = h->GetInitialMemory(); - 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.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.myTextOption = h->GetAdvancedOption(); h_data.myLogInStandardOutput = h->GetStandardOutputLog(); h_data.myRemoveLogOnSuccess = h->GetRemoveLogOnSuccess(); + + GHS3DPluginGUI_HypothesisCreator* that = (GHS3DPluginGUI_HypothesisCreator*)this; + that->myOptions = h->GetOptionValues(); + that->myCustomOptions = h->GetAdvancedOptionValues(); GHS3DPlugin::GHS3DEnforcedVertexList_var vertices = h->GetEnforcedVertices(); h_data.myEnforcedVertices.clear(); @@ -1651,43 +1789,31 @@ bool GHS3DPluginGUI_HypothesisCreator::storeParamsToHypo( const GHS3DHypothesisD if( isCreation() ) SMESH::SetName( SMESH::FindSObject( h ), h_data.myName.toLatin1().constData() ); - 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->GetKeepFiles() != h_data.myKeepFiles ) - h->SetKeepFiles ( h_data.myKeepFiles ); - if ( h->GetWorkingDirectory() != h_data.myWorkingDir ) - 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->GetAdvancedOption() != 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 ) - h->SetRemoveLogOnSuccess( h_data.myRemoveLogOnSuccess ); + h->SetOptimizationLevel ( h_data.myOptimizationLevel ); + h->SetMinSize ( h_data.myUseMinSize ? h_data.myMinSize : 0 ); + h->SetMaxSize ( h_data.myUseMaxSize ? h_data.myMaxSize : 0 ); + h->SetMinMaxSizeDefault ( this->myMinSizeDefault, this->myMaxSizeDefault ); + h->SetGradation ( h_data.myGradation ); + h->SetVolumeProximity ( h_data.myUseProximity ); + h->SetNbVolumeProximityLayers ( h_data.myNbProximityLayers ); + h->SetToMeshHoles ( h_data.myToMeshHoles ); + h->SetToMakeGroupsOfDomains ( h_data.myToMakeGroupsOfDomains ); + + h->SetMaximumMemory ( h_data.myMaximumMemory ); + h->SetInitialMemory ( h_data.myInitialMemory ); + h->SetInitialMemory ( h_data.myInitialMemory ); + h->SetKeepFiles ( h_data.myKeepFiles ); + h->SetWorkingDirectory ( h_data.myWorkingDir.toLatin1().constData() ); + h->SetVerboseLevel ( h_data.myVerboseLevel ); + //h->SetToRemoveCentralPoint ( h_data.myRemoveInitialCentralPoint ); + //h->SetToUseBoundaryRecoveryVersion( h_data.myBoundaryRecovery ); + //h->SetFEMCorrection ( h_data.myFEMCorrection ); + h->SetStandardOutputLog ( h_data.myLogInStandardOutput ); + h->SetRemoveLogOnSuccess ( h_data.myRemoveLogOnSuccess ); if ( !opt->_is_nil() ) { + opt->SetToCreateNewNodes ( h_data.myToCreateNewNodes ); opt->SetOptimization ( (GHS3DPlugin::Mode) h_data.myOptimization ); opt->SetSplitOverConstrained ( (GHS3DPlugin::Mode) h_data.mySplitOverConstrained ); opt->SetPThreadsMode ( (GHS3DPlugin::PThreadsMode) h_data.myPThreadsMode ); @@ -1750,7 +1876,7 @@ bool GHS3DPluginGUI_HypothesisCreator::storeParamsToHypo( const GHS3DHypothesisD default: break; } - + ok = h->p_SetEnforcedMesh(theSource, elementType, enfMesh->name.c_str(), enfMesh->groupName.c_str()); } // for } // try @@ -1764,32 +1890,38 @@ bool GHS3DPluginGUI_HypothesisCreator::storeParamsToHypo( const GHS3DHypothesisD bool GHS3DPluginGUI_HypothesisCreator::readParamsFromWidgets( GHS3DHypothesisData& h_data ) const { - h_data.myName = myName ? myName->text() : ""; - h_data.myToMeshHoles = myToMeshHolesCheck->isChecked(); - h_data.myToMakeGroupsOfDomains = myToMakeGroupsOfDomains->isChecked(); - h_data.myOptimization = myOptimizationCombo->currentIndex(); - h_data.myOptimizationLevel = myOptimizationLevelCombo->currentIndex(); - h_data.mySplitOverConstrained = mySplitOverConstrainedCombo->currentIndex(); - h_data.myPThreadsMode = myPThreadsModeCombo->currentIndex(); - h_data.myNumberOfThreads = myNumberOfThreadsSpin->value(); - h_data.mySmoothOffSlivers = mySmoothOffSliversCheck->isChecked(); - h_data.myMaximumMemory = myAdvWidget->maxMemoryCheck->isChecked() ? myAdvWidget->maxMemorySpin->value() : -1; - h_data.myInitialMemory = myAdvWidget->initialMemoryCheck->isChecked() ? myAdvWidget->initialMemorySpin->value() : -1; - h_data.myKeepFiles = myAdvWidget->keepWorkingFilesCheck->isChecked(); - h_data.myWorkingDir = myAdvWidget->workingDirectoryLineEdit->text().trimmed(); - h_data.myVerboseLevel = myAdvWidget->verboseLevelSpin->value(); - 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->advOptionTable->GetCustomOptions(); - h_data.myLogInStandardOutput = !myAdvWidget->logInFileCheck->isChecked(); - h_data.myRemoveLogOnSuccess = myAdvWidget->removeLogOnSuccessCheck->isChecked(); - if ( isOptimization() ) - h_data.myToCreateNewNodes = myCreateNewNodesCheck->isChecked(); + h_data.myName = myName ? myName->text() : ""; + h_data.myOptimizationLevel = myOptimizationLevelCombo->currentIndex(); + if ( mySplitOverConstrainedCombo ) // optimizer + { + h_data.myToCreateNewNodes = myCreateNewNodesCheck->isChecked(); + h_data.myOptimization = myOptimizationCombo->currentIndex(); + h_data.mySplitOverConstrained = mySplitOverConstrainedCombo->currentIndex(); + h_data.myPThreadsMode = myPThreadsModeCombo->currentIndex(); + h_data.myNumberOfThreads = myNumberOfThreadsSpin->value(); + h_data.mySmoothOffSlivers = mySmoothOffSliversCheck->isChecked(); + } else - h_data.myToCreateNewNodes = myAdvWidget->createNewNodesCheck->isChecked(); - + { + h_data.myMinSize = myMinSizeSpin->value(); + h_data.myMaxSize = myMaxSizeSpin->value(); + h_data.myUseMinSize = myMinSizeCheck->isChecked(); + h_data.myUseMaxSize = myMaxSizeCheck->isChecked(); + h_data.myGradation = myGradationSpin->value(); + h_data.myUseGradation = myGradationCheck->isChecked(); + h_data.myUseProximity = myUseProximityGroup->isChecked(); + h_data.myNbProximityLayers = myNbProximityLayers->value(); + 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.myKeepFiles = myAdvWidget->keepWorkingFilesCheck->isChecked(); + h_data.myWorkingDir = myAdvWidget->workingDirectoryLineEdit->text().trimmed(); + h_data.myVerboseLevel = myAdvWidget->verboseLevelSpin->value(); + h_data.myLogInStandardOutput = !myAdvWidget->logInFileCheck->isChecked(); + h_data.myRemoveLogOnSuccess = myAdvWidget->removeLogOnSuccessCheck->isChecked(); + // Enforced vertices h_data.myEnforcedVertices.clear(); QVariant valueX, valueY, valueZ; @@ -1848,3 +1980,8 @@ QString GHS3DPluginGUI_HypothesisCreator::helpPage() const { return isOptimization() ? "optimization_page.html" : "ghs3d_hypo_page.html"; } + +void GHS3DPluginGUI_HypothesisCreator::onAddOption() +{ + myAdvWidget->AddOption( NULL, true ); +} diff --git a/src/GUI/GHS3DPluginGUI_HypothesisCreator.h b/src/GUI/GHS3DPluginGUI_HypothesisCreator.h index 4f979dc..6437f41 100644 --- a/src/GUI/GHS3DPluginGUI_HypothesisCreator.h +++ b/src/GUI/GHS3DPluginGUI_HypothesisCreator.h @@ -56,6 +56,7 @@ class QSpinBox; class QTableWidget; class QTableWidgetItem; class QHeaderView; +class QGroupBox; class GHS3DPluginGUI_AdvWidget; class LightApp_SelectionMgr; @@ -142,13 +143,16 @@ typedef std::set< TEnfMesh*, CompareEnfMeshes > TEnfMeshList; typedef struct { - bool myToMeshHoles,myToMakeGroupsOfDomains,myKeepFiles,myToCreateNewNodes,myBoundaryRecovery,myFEMCorrection,myRemoveInitialCentralPoint, - myLogInStandardOutput, myRemoveLogOnSuccess; - float myMaximumMemory; - float myInitialMemory; int myOptimizationLevel; - QString myName,myWorkingDir,myTextOption; + double myMinSize, myMaxSize, myMinSizeDefault, myMaxSizeDefault; double myGradation; + int myNbProximityLayers; + bool myUseMinSize, myUseMaxSize, myUseGradation, myUseProximity; + bool myToMeshHoles, myToMakeGroupsOfDomains; + bool myToCreateNewNodes,myBoundaryRecovery,myFEMCorrection,myRemoveInitialCentralPoint, + myKeepFiles,myLogInStandardOutput, myRemoveLogOnSuccess; + float myInitialMemory, myMaximumMemory; + QString myName,myWorkingDir; short myVerboseLevel; TEnfVertexList myEnforcedVertices; TEnfMeshList myEnforcedMeshes; @@ -182,6 +186,7 @@ protected: virtual QString type() const; protected slots: + void onAddOption(); void onToMeshHoles(bool); void onDirBtnClicked(); void updateWidgets(); @@ -219,9 +224,21 @@ private: private: QWidget* myStdGroup; QLineEdit* myName; - QCheckBox* myToMeshHolesCheck; - QCheckBox* myToMakeGroupsOfDomains; + // main QComboBox* myOptimizationLevelCombo; + QCheckBox* myMinSizeCheck; + QCheckBox* myMaxSizeCheck; + SMESHGUI_SpinBox* myMinSizeSpin; + SMESHGUI_SpinBox* myMaxSizeSpin; + mutable double myMinSizeDefault, myMaxSizeDefault; + // proximity + QCheckBox* myGradationCheck; + SMESHGUI_SpinBox* myGradationSpin; + QGroupBox* myUseProximityGroup; + SalomeApp_IntSpinBox* myNbProximityLayers; + // other + QCheckBox* myToMakeGroupsOfDomains; + QCheckBox* myToMeshHolesCheck; QComboBox* myOptimizationCombo; QComboBox* mySplitOverConstrainedCombo; @@ -232,6 +249,8 @@ private: QWidget* myAdvGroup; GHS3DPluginGUI_AdvWidget* myAdvWidget; + mutable GHS3DPlugin::string_array_var myOptions, myCustomOptions; + QWidget* myEnfGroup; QPixmap iconVertex, iconCompound; diff --git a/src/GUI/GHS3DPluginGUI_TreeWidget.cxx b/src/GUI/GHS3DPluginGUI_TreeWidget.cxx new file mode 100644 index 0000000..8511275 --- /dev/null +++ b/src/GUI/GHS3DPluginGUI_TreeWidget.cxx @@ -0,0 +1,91 @@ +// Copyright (C) 2007-2019 CEA/DEN, EDF R&D +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// + +#include "GHS3DPluginGUI_TreeWidget.h" +#include + +namespace +{ + bool isEditable( const QModelIndex& index ) + { + return index.isValid() && + index.flags() & Qt::ItemIsEditable && + index.flags() & Qt::ItemIsEnabled && + ( !index.data( Qt::UserRole + 1 ).isValid() || index.data( Qt::UserRole + 1 ).toInt() != 0 ); + } +} + +GHS3DPluginGUI_TreeWidget::GHS3DPluginGUI_TreeWidget( QWidget* parent ) + : QTreeWidget( parent ) +{ +} + +QModelIndex GHS3DPluginGUI_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 GHS3DPluginGUI_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/GHS3DPluginGUI_TreeWidget.h b/src/GUI/GHS3DPluginGUI_TreeWidget.h new file mode 100644 index 0000000..e80b3e2 --- /dev/null +++ b/src/GUI/GHS3DPluginGUI_TreeWidget.h @@ -0,0 +1,36 @@ +// Copyright (C) 2007-2019 CEA/DEN, EDF R&D +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// + +#if !defined(GHS3DPluginGUI_TreeWidget_H) +#define GHS3DPluginGUI_TreeWidget_H + +#include + +class GHS3DPluginGUI_TreeWidget : public QTreeWidget +{ + Q_OBJECT +public: + GHS3DPluginGUI_TreeWidget( QWidget* ); + +protected: + QModelIndex moveCursor( CursorAction, Qt::KeyboardModifiers ); + void keyPressEvent( QKeyEvent* ); +}; + +#endif // GHS3DPluginGUI_TreeWidget_H diff --git a/src/GUI/GHS3DPlugin_msg_en.ts b/src/GUI/GHS3DPlugin_msg_en.ts index b90dc6d..5271493 100644 --- a/src/GUI/GHS3DPlugin_msg_en.ts +++ b/src/GUI/GHS3DPlugin_msg_en.ts @@ -279,5 +279,109 @@ GHS3D_SMOOTH_OFF_SLIVERS Smooth off sliver elements + + OPTION_TYPE_COLUMN + Type + + + OPTION_NAME_COLUMN + Option + + + OPTION_VALUE_COLUMN + Value + + + GHS3D_ADD_OPTION + Add option + + + GHS3D_MAIN_PARAMS + Main parameters + + + GHS3D_MIN_SIZE + Minimal size + + + GHS3D_MAX_SIZE + Maximal size + + + GHS3D_VOLUME_PROXIMITY + Volume proximity + + + GHS3D_USE_VOLUME_PROXIMITY + Use volume proximity + + + GHS3D_NB_LAYERS + Number of layers + + + GHS3D_OTHER_PARAMETERS + Other parameters + + + no_initial_central_point + No central point + + + force_max_size + Force maximum edge size + + + apply_gradation_on_skin_vertex_sizes + Gradation on skin + + + optimise_worst_elements + Optimise worst elements + + + force_output_quadratic_mesh + Force quadratic mesh + + + rectify_jacobian + Rectify jacobian + + + jacobian_rectification_respect_input_surface_mesh + Respect surface mesh + + + max_number_of_errors_printed + Max number of errors + + + max_number_of_threads + Maximal number of threads + + + target_quality + Target quality + + + sliver_angle + Sliver angle + + + pthreads_mode + Mode of pthreads + + + boundary_regeneration + Boundary regeneration + + + split_overconstrained_tetrahedra + Remove overconstrained tetrahedra + + + _ + +