From f264dfaecc1f66c2f4a300fe007b818a92a475f8 Mon Sep 17 00:00:00 2001 From: eap Date: Thu, 3 Nov 2016 20:06:08 +0300 Subject: [PATCH] IMP23373: [CEA 1170] Optimization of a 3D mesh using MG-Tetra --- doc/salome/examples/ghs3d_optimization.py | 60 ++ .../images/mgtetra_optim_adv_params.png | Bin 0 -> 25430 bytes .../images/mgtetra_optim_gen_params.png | Bin 0 -> 22098 bytes .../input/ghs3dplugin_python_interface.doc | 6 + doc/salome/gui/GHS3DPLUGIN/input/index.doc | 15 +- .../GHS3DPLUGIN/input/optimization_hypo.doc | 122 +++ idl/GHS3DPlugin_Algorithm.idl | 47 +- resources/GHS3DPlugin.xml | 22 + src/GHS3DPlugin/CMakeLists.txt | 6 + src/GHS3DPlugin/GHS3DPluginBuilder.py | 175 +++- src/GHS3DPlugin/GHS3DPlugin_GHS3D.cxx | 82 +- src/GHS3DPlugin/GHS3DPlugin_GHS3D.hxx | 14 +- src/GHS3DPlugin/GHS3DPlugin_GHS3D_i.cxx | 39 +- src/GHS3DPlugin/GHS3DPlugin_GHS3D_i.hxx | 14 + src/GHS3DPlugin/GHS3DPlugin_Hypothesis.cxx | 8 +- src/GHS3DPlugin/GHS3DPlugin_Hypothesis.hxx | 4 +- src/GHS3DPlugin/GHS3DPlugin_Hypothesis_i.cxx | 251 ++--- src/GHS3DPlugin/GHS3DPlugin_Optimizer.cxx | 444 +++++++++ src/GHS3DPlugin/GHS3DPlugin_Optimizer.hxx | 60 ++ .../GHS3DPlugin_OptimizerHypothesis.cxx | 203 ++++ .../GHS3DPlugin_OptimizerHypothesis.hxx | 86 ++ .../GHS3DPlugin_OptimizerHypothesis_i.cxx | 145 +++ .../GHS3DPlugin_OptimizerHypothesis_i.hxx | 81 ++ src/GHS3DPlugin/GHS3DPlugin_i.cxx | 21 +- src/GHS3DPlugin/MG_Tetra_API.cxx | 141 ++- src/GHS3DPlugin/MG_Tetra_API.hxx | 1 + src/GUI/GHS3DPluginGUI.cxx | 3 +- src/GUI/GHS3DPluginGUI_HypothesisCreator.cxx | 925 ++++++++---------- src/GUI/GHS3DPluginGUI_HypothesisCreator.h | 69 +- src/GUI/GHS3DPlugin_images.ts | 4 + src/GUI/GHS3DPlugin_msg_en.ts | 48 + 31 files changed, 2251 insertions(+), 845 deletions(-) create mode 100644 doc/salome/examples/ghs3d_optimization.py create mode 100644 doc/salome/gui/GHS3DPLUGIN/images/mgtetra_optim_adv_params.png create mode 100644 doc/salome/gui/GHS3DPLUGIN/images/mgtetra_optim_gen_params.png create mode 100644 doc/salome/gui/GHS3DPLUGIN/input/optimization_hypo.doc create mode 100644 src/GHS3DPlugin/GHS3DPlugin_Optimizer.cxx create mode 100644 src/GHS3DPlugin/GHS3DPlugin_Optimizer.hxx create mode 100644 src/GHS3DPlugin/GHS3DPlugin_OptimizerHypothesis.cxx create mode 100644 src/GHS3DPlugin/GHS3DPlugin_OptimizerHypothesis.hxx create mode 100644 src/GHS3DPlugin/GHS3DPlugin_OptimizerHypothesis_i.cxx create mode 100644 src/GHS3DPlugin/GHS3DPlugin_OptimizerHypothesis_i.hxx diff --git a/doc/salome/examples/ghs3d_optimization.py b/doc/salome/examples/ghs3d_optimization.py new file mode 100644 index 0000000..a7ecaf6 --- /dev/null +++ b/doc/salome/examples/ghs3d_optimization.py @@ -0,0 +1,60 @@ +# Copyright (C) 2007-2016 CEA/DEN, EDF R&D, OPEN CASCADE +# +# 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 +# + +import salome +salome.salome_init() + +from salome.geom import geomBuilder +geompy = geomBuilder.New(salome.myStudy) + +from salome.smesh import smeshBuilder +smesh = smeshBuilder.New(salome.myStudy) + +# create a disk +disk = geompy.MakeDiskR(100., 1, theName="disk") + +# triangulate the disk +mesh = smesh.Mesh( disk ) +cadsurf = mesh.Triangle( smeshBuilder.MG_CADSurf ) +cadsurf.SetQuadAllowed( True ) +mesh.Compute() + +# extrude the 2D mesh into a prismatic mesh +mesh.ExtrusionSweepObject( mesh, [0,0,10], 7 ) + +# split prisms into tetrahedra +mesh.SplitVolumesIntoTetra( mesh ) + +# copy the mesh into a new mesh, since only a mesh not based of geometry +# can be optimized using MG-Tetra Optimization +optMesh = smesh.CopyMesh( mesh, "optimization" ) + +# add MG-Tetra Optimization +mg_opt = optMesh.Tetrahedron( smeshBuilder.MG_Tetra_Optimization ) +mg_opt.SetSmoothOffSlivers( True ) +mg_opt.SetOptimizationLevel( smeshBuilder.Strong_Optimization ) + +# run optimization +optMesh.Compute() + +print "Nb tetra before optimization", mesh.NbTetras() +print "Nb tetra after optimization", optMesh.NbTetras() + +# End of script + diff --git a/doc/salome/gui/GHS3DPLUGIN/images/mgtetra_optim_adv_params.png b/doc/salome/gui/GHS3DPLUGIN/images/mgtetra_optim_adv_params.png new file mode 100644 index 0000000000000000000000000000000000000000..4f308c1f6363215199bff2294a185db2a05a3575 GIT binary patch literal 25430 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 literal 0 HcmV?d00001 diff --git a/doc/salome/gui/GHS3DPLUGIN/images/mgtetra_optim_gen_params.png b/doc/salome/gui/GHS3DPLUGIN/images/mgtetra_optim_gen_params.png new file mode 100644 index 0000000000000000000000000000000000000000..35a1a682a4a41585b3c743d52f88a6e4ae51d23d GIT binary patch literal 22098 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 of mesh optimization with MG-Tetra Optimization: +\tui_script{ghs3d_optimization.py} + \ref tui_ghs3d "Back to top" */ diff --git a/doc/salome/gui/GHS3DPLUGIN/input/index.doc b/doc/salome/gui/GHS3DPLUGIN/input/index.doc index bcc3e4a..bf42483 100644 --- a/doc/salome/gui/GHS3DPLUGIN/input/index.doc +++ b/doc/salome/gui/GHS3DPLUGIN/input/index.doc @@ -2,18 +2,23 @@ \mainpage Introduction to MG-Tetra plug-in -\b MG-Tetra plug-in adds MG-Tetra (former GHS3D) meshing -algorithm to the SALOME Mesh module. +MG-Tetra plug-in adds two meshing algorithm to the SALOME Mesh: +\b MG-Tetra (former GHS3D) and MG-Tetra Optimization. \b MG-Tetra meshing algorithm is destined for: -- Meshing 3D geometric entities: solids are split into tetrahedral (pyramidal) elements. -- Generating 3D meshes from 2D meshes (triangles and quadrangles), working without geometrical objects. + - Meshing 3D geometric entities: solids are split into tetrahedral (pyramidal) elements. + - Generating 3D meshes from 2D meshes (triangles and quadrangles), working without geometrical objects. + +MG-Tetra Optimization algorithm optimizes linear tetrahedral +meshes not based on geometry. \note MG-Tetra plug-in uses MG-Tetra commercial mesher and requires a license to be used within the Mesh module. To obtain a license, visit http://www.meshgems.com/meshgems-products.html -To manage parameters of the MG-Tetra mesher use \subpage ghs3d_hypo_page and \subpage additional_hypo_page +To manage parameters of the MG-Tetra mesher use +\subpage ghs3d_hypo_page and \subpage additional_hypo_page. +Parameters of MG-Tetra Optimization can be managed via \subpage optimization_page. Also all MG-Tetra functionalities are accessible via \subpage ghs3dplugin_python_interface_page "MG-Tetra Python interface". diff --git a/doc/salome/gui/GHS3DPLUGIN/input/optimization_hypo.doc b/doc/salome/gui/GHS3DPLUGIN/input/optimization_hypo.doc new file mode 100644 index 0000000..e1868b5 --- /dev/null +++ b/doc/salome/gui/GHS3DPLUGIN/input/optimization_hypo.doc @@ -0,0 +1,122 @@ +/*! + +\page optimization_page MG-Tetra Optimization Parameters hypothesis + +\anchor optimization_top +MG-Tetra Optimization Parameters hypothesis works only +with MG-Tetra Optimization +algorithm. This algorithm is a commercial software. + +To get a license, visit http://www.meshgems.com/meshgems-products.html + +\tableofcontents + +\section mgtetra_optim_gen_params General parameters + +\image html mgtetra_optim_gen_params.png + +- Name - allows to define the name of the hypothesis (MG-Tetra +Parameters by default). + +- Optimization - sets the optimisation type. If Optimization is: + - No : no optimisation is applied + - Yes (default): optimisation is performed upon mesh generation using + the Optimisation level parameter + - Only : only optimisation is performed to an existing mesh. + +- Optimization level - allows choosing the required +optimization level (higher level of optimization provides better mesh, +but can be time-consuming): + - none + - light + - medium (standard) + - standard+ + - strong + +- Split overconstrained elements - sets treatment of element +having all their vertices on the input surface. +If Split overconstrained elements is: + - No (default): no correction is applied + - Yes : correction is applied upon mesh generation + - Only : only correction is applied to an existing mesh. + +- PThreads mode - sets optimization mode when using multithread +capabilities. Valid values are: + - Safe : slower but quality can only get better + - Aggressive : faster but quality may be altered + - None (default): not activated. + +- Max number of threads - sets the maximum number of threads to +be used in parallel. + +- Smooth off sliver elements - activates elimination of sliver +elements as much as possible. + +- Create new nodes - allows insertion of new nodes. + +\ref optimization_top "Back to top" + + +\section ghs3d_advanced_parameters Advanced parameters + +\image html mgtetra_optim_adv_params.png + +\subsection 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 +software will be started with 100 Megabytes of working space. + +- Maximum memory size - launches MG-Tetra software with +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 + +- Working directory - allows defining the folder for input and output +files of MG-Tetra software, which are the files starting with "GHS3D_" prefix. + +- Verbose level - to choose verbosity level in the range from +0 to 10. + + - 0, no standard output, + + - 2, prints the data, quality statistics of the skin and final + meshes and indicates when the final mesh is being saved. In addition + the software gives indication regarding the CPU time. + + - 10, same as 2 plus the main steps in the computation, quality + statistics histogram of the skin mesh, quality statistics histogram + together with the characteristics of the final mesh. + +- Print log in a file - if this option is checked on the log is +printed in a file placed in the working directory, otherwise it is +printed on the standard output. + +- Remove log on success - if this option is checked on the log +file is kept only if an error occurs during the computation. This +option is only available if Print log in a file is enabled +(there must be a log file to delete it) and Keep all working + files is disabled (in this case the log file is always kept). + +- Keep all working files - allows checking input and output +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 + +- A table 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. + +
See Also a sample TUI Script of the +\ref tui_ghs3d "creation of a MG-Tetra Optimization hypothesis". + +\ref optimization_top "Back to top" + +*/ diff --git a/idl/GHS3DPlugin_Algorithm.idl b/idl/GHS3DPlugin_Algorithm.idl index f18b3ac..a697472 100644 --- a/idl/GHS3DPlugin_Algorithm.idl +++ b/idl/GHS3DPlugin_Algorithm.idl @@ -54,7 +54,7 @@ module GHS3DPlugin typedef sequence GHS3DEnforcedMeshList; /*! - * GHS3DPlugin_GHS3D: interface of "Tetrahedron (GHS3D)" algorithm + * GHS3DPlugin_GHS3D: interface of "MG-Tetra" algorithm */ interface GHS3DPlugin_GHS3D : SMESH::SMESH_3D_Algo { @@ -62,7 +62,7 @@ module GHS3DPlugin }; /*! - * Parameters of "Tetrahedron (GHS3D)" algorithm + * Parameters of "MG-Tetra" algorithm */ interface GHS3DPlugin_Hypothesis : SMESH::SMESH_Hypothesis { @@ -202,6 +202,49 @@ module GHS3DPlugin */ boolean p_SetEnforcedMesh(in SMESH::SMESH_IDSource theSource, in SMESH::ElementType elementType, in string name, in string groupName) raises (SALOME::SALOME_Exception); }; + + /*! + * GHS3DPlugin_Optimizer: interface of "MG-Tetra Optimization" algorithm + */ + interface GHS3DPlugin_Optimizer : SMESH::SMESH_3D_Algo + { + }; + + enum PThreadsMode { SAFE, AGGRESSIVE, NONE }; + enum Mode { NO, YES, ONLY }; + + /*! + * Parameters of "MG-Tetra Optimization" algorithm + * + * params inherited from GHS3DPlugin_Hypothesis: + * - create new nodes + * - optimization level + * - init and max memory + * - work dir + * - verbosity + * - log to file + * - keep work files + * - remove log file + * - advanced options + */ + interface GHS3DPlugin_OptimizerHypothesis: GHS3DPlugin_Hypothesis + { + void SetOptimization( in Mode optMode ); + Mode GetOptimization(); + + void SetSplitOverConstrained( in Mode ovcMode ); + Mode GetSplitOverConstrained(); + + void SetSmoothOffSlivers( in boolean toSmooth ); + boolean GetSmoothOffSlivers(); + + void SetPThreadsMode( in PThreadsMode mode ); + PThreadsMode GetPThreadsMode(); + + void SetMaximalNumberOfThreads( in short nb ); + short GetMaximalNumberOfThreads(); + }; + }; #endif diff --git a/resources/GHS3DPlugin.xml b/resources/GHS3DPlugin.xml index 684b313..1989d20 100644 --- a/resources/GHS3DPlugin.xml +++ b/resources/GHS3DPlugin.xml @@ -51,6 +51,13 @@ + + + + @@ -71,6 +78,21 @@ + + + MG-Tetra Optimization=Tetrahedron(algo=smeshBuilder.MG_Tetra_Optimization) + MG-Tetra Optimization Parameters=Parameters() + + + diff --git a/src/GHS3DPlugin/CMakeLists.txt b/src/GHS3DPlugin/CMakeLists.txt index 1f49d54..0747cb8 100644 --- a/src/GHS3DPlugin/CMakeLists.txt +++ b/src/GHS3DPlugin/CMakeLists.txt @@ -71,6 +71,9 @@ SET(GHS3DEngine_HEADERS GHS3DPlugin_GHS3D_i.hxx GHS3DPlugin_Hypothesis.hxx GHS3DPlugin_Hypothesis_i.hxx + GHS3DPlugin_Optimizer.hxx + GHS3DPlugin_OptimizerHypothesis.hxx + GHS3DPlugin_OptimizerHypothesis_i.hxx MG_Tetra_API.hxx ) @@ -83,6 +86,9 @@ SET(GHS3DEngine_SOURCES GHS3DPlugin_i.cxx GHS3DPlugin_Hypothesis.cxx GHS3DPlugin_Hypothesis_i.cxx + GHS3DPlugin_Optimizer.cxx + GHS3DPlugin_OptimizerHypothesis.cxx + GHS3DPlugin_OptimizerHypothesis_i.cxx MG_Tetra_API.cxx ) diff --git a/src/GHS3DPlugin/GHS3DPluginBuilder.py b/src/GHS3DPlugin/GHS3DPluginBuilder.py index 2d1a630..d65efc5 100644 --- a/src/GHS3DPlugin/GHS3DPluginBuilder.py +++ b/src/GHS3DPlugin/GHS3DPluginBuilder.py @@ -38,6 +38,12 @@ None_Optimization, Light_Optimization, Medium_Optimization, Strong_Optimization # V4.1 (partialy redefines V3.1). Issue 0020574 None_Optimization, Light_Optimization, Standard_Optimization, StandardPlus_Optimization, Strong_Optimization = 0,1,2,3,4 +# import items of enums +for e in GHS3DPlugin.Mode._items: exec('%s = GHS3DPlugin.%s'%(e,e)) +for e in GHS3DPlugin.PThreadsMode._items: exec('%s = GHS3DPlugin.%s'%(e,e)) +Mode_NO, Mode_YES, Mode_ONLY = GHS3DPlugin.Mode._items +Mode_SAFE, Mode_AGGRESSIVE, Mode_NONE = GHS3DPlugin.PThreadsMode._items + #---------------------------- # Mesh algo type identifiers #---------------------------- @@ -45,6 +51,7 @@ None_Optimization, Light_Optimization, Standard_Optimization, StandardPlus_Optim ## Algorithm type: MG-Tetra tetrahedron 3D algorithm, see GHS3D_Algorithm MG_Tetra = "MG-Tetra" GHS3D = MG_Tetra +MG_Tetra_Optimization = "MG-Tetra Optimization" ## Tetrahedron MG-Tetra 3D algorithm # @@ -59,7 +66,7 @@ class GHS3D_Algorithm(Mesh_Algorithm): algoType = MG_Tetra ## doc string of the method in smeshBuilder.Mesh class # @internal - docHelper = "Creates tetrahedron 3D algorithm for volumes" + docHelper = "Creates tetrahedron 3D algorithm" ## Private constructor. # @param mesh parent mesh object algorithm is assigned to @@ -270,3 +277,169 @@ class GHS3D_Algorithm(Mesh_Algorithm): pass pass # end of GHS3D_Algorithm class + + +## MG-Tetra Optimization algorithm - optimizer of tetrahedral meshes +# +# It can be created by calling smeshBuilder.Mesh.Tetrahedron( smeshBuilder.MG_Tetra_Optimization ) +class GHS3D_Optimizer(GHS3D_Algorithm): + + ## name of the dynamic method in smeshBuilder.Mesh class + # @internal + meshMethod = "Tetrahedron" + ## type of algorithm used with helper function in smeshBuilder.Mesh class + # @internal + algoType = MG_Tetra_Optimization + ## doc string of the method in smeshBuilder.Mesh class + # @internal + docHelper = "Creates MG-Tetra optimizer of tetrahedral meshes" + + ## Private constructor. + # @param mesh parent mesh object algorithm is assigned to + # @param geom - not used + def __init__(self, mesh, geom=0): + GHS3D_Algorithm.__init__(self, mesh) + + # remove some inherited methods + # del self.SetToMeshHoles + # del self.SetToMakeGroupsOfDomains + # del self.SetToUseBoundaryRecoveryVersion + # del self.SetFEMCorrection + # del self.SetToRemoveCentralPoint + # del self.SetEnforcedVertex + # del self.SetEnforcedVertexGeom + # del self.RemoveEnforcedVertex + # del self.RemoveEnforcedVertexGeom + # del self.SetEnforcedMesh + # del self.SetTextOption + pass + + ## Defines hypothesis having several parameters + # @return hypothesis object + def Parameters(self): + if not self.params: + self.params = self.Hypothesis("MG-Tetra Optimization Parameters", [], + "libGHS3DEngine.so", UseExisting=0) + pass + return self.params + + ## Set Optimization mode + # @param optMode optimization mode, one of the following values: + # smeshBuilder.Mode_NO, + # smeshBuilder.Mode_YES (default), + # smeshBuilder.MODE_ONLY + def SetOptimizationOnly(self, optMode ): + self.Parameters().SetOptimizationOnly(optMode) + pass + + ## Set mode of splitting over-constrained elements + # @param ovcMode, one of the following values + # smeshBuilder.Mode_NO (default), + # smeshBuilder.Mode_YES, + # smeshBuilder.Mode_ONLY + def SetSplitOverConstrained(self, ovcMode ): + self.Parameters().SetSplitOverConstrained(ovcMode) + pass + + ## Activate smoothing sliver elements: + # @param toSmooth - Boolean flag + def SetSmoothOffSlivers(self, toSmooth ): + self.Parameters().SetSmoothOffSlivers(toSmooth) + pass + + ## Set multithread mode + # @param mode - the mode, one of the following values: + # smeshBuilder.Mode_SAFE, + # smeshBuilder.Mode_AGGRESSIVE, + # smeshBuilder.Mode_NONE (default) + def SetPThreadsMode(self, mode ): + self.Parameters().SetPThreadsMode(mode) + pass + + ## Set maximal number of threads + # @param nb - number of threads + def SetMaximalNumberOfThreads(self, nb ): + self.Parameters().SetMaximalNumberOfThreads(nb) + pass + + + ## Set Optimization level: + # @param level optimization level, one of the following values + # - None_Optimization + # - Light_Optimization + # - Standard_Optimization + # - StandardPlus_Optimization + # - Strong_Optimization. + # . + # Default is Standard_Optimization + def SetOptimizationLevel(self, level): + self.Parameters().SetOptimizationLevel(level) + pass + + ## Set maximal size of memory to be used by the algorithm (in Megabytes). + # @param MB maximal size of memory + def SetMaximumMemory(self, MB): + self.Parameters().SetMaximumMemory(MB) + pass + + ## Set initial size of memory to be used by the algorithm (in Megabytes) in + # automatic memory adjustment mode. + # @param MB initial size of memory + def SetInitialMemory(self, MB): + self.Parameters().SetInitialMemory(MB) + pass + + ## Set path to working directory. + # @param path working directory + def SetWorkingDirectory(self, path): + self.Parameters().SetWorkingDirectory(path) + pass + + ## To keep working files or remove them. + # @param toKeep "keep working files" flag value + def SetKeepFiles(self, toKeep): + self.Parameters().SetKeepFiles(toKeep) + pass + + ## Remove or not the log file (if any) in case of successful computation. + # The log file remains in case of errors anyway. If + # the "keep working files" flag is set to true, this option + # has no effect. + # @param toRemove "remove log on success" flag value + def SetRemoveLogOnSuccess(self, toRemove): + self.Parameters().SetRemoveLogOnSuccess(toRemove) + pass + + ## Print the the log in a file. If set to false, the + # log is printed on the standard output + # @param toPrintLogInFile "print log in a file" flag value + def SetPrintLogInFile(self, toPrintLogInFile): + self.Parameters().SetStandardOutputLog(not toPrintLogInFile) + pass + + ## Set verbosity level [0-10]. + # @param level verbosity level + # - 0 - no standard output, + # - 2 - prints the data, quality statistics of the skin and final meshes and + # indicates when the final mesh is being saved. In addition the software + # gives indication regarding the CPU time. + # - 10 - same as 2 plus the main steps in the computation, quality statistics + # histogram of the skin mesh, quality statistics histogram together with + # the characteristics of the final mesh. + def SetVerboseLevel(self, level): + self.Parameters().SetVerboseLevel(level) + pass + + ## To create new nodes. + # @param toCreate "create new nodes" flag value + def SetToCreateNewNodes(self, toCreate): + self.Parameters().SetToCreateNewNodes(toCreate) + pass + + ## Sets command line option as text. + # @param option command line option + def SetAdvancedOption(self, option): + self.Parameters().SetAdvancedOption(option) + pass + + pass # end of GHS3D_Optimizer class diff --git a/src/GHS3DPlugin/GHS3DPlugin_GHS3D.cxx b/src/GHS3DPlugin/GHS3DPlugin_GHS3D.cxx index 0a1091f..55117ae 100644 --- a/src/GHS3DPlugin/GHS3DPlugin_GHS3D.cxx +++ b/src/GHS3DPlugin/GHS3DPlugin_GHS3D.cxx @@ -135,7 +135,6 @@ static void removeFile( const TCollection_AsciiString& fileName ) GHS3DPlugin_GHS3D::GHS3DPlugin_GHS3D(int hypId, int studyId, SMESH_Gen* gen) : SMESH_3D_Algo(hypId, studyId, gen), _isLibUsed( false ) { - MESSAGE("GHS3DPlugin_GHS3D::GHS3DPlugin_GHS3D"); _name = Name(); _shapeType = (1 << TopAbs_SHELL) | (1 << TopAbs_SOLID);// 1 bit /shape type _onlyUnaryInput = false; // Compute() will be called on a compound of solids @@ -143,18 +142,14 @@ GHS3DPlugin_GHS3D::GHS3DPlugin_GHS3D(int hypId, int studyId, SMESH_Gen* gen) _nbShape=0; _compatibleHypothesis.push_back( GHS3DPlugin_Hypothesis::GetHypType()); _compatibleHypothesis.push_back( StdMeshers_ViscousLayers::GetHypType() ); - _requireShape = false; // can work without shape_studyId + _requireShape = false; // can work without shape _smeshGen_i = SMESH_Gen_i::GetSMESHGen(); CORBA::Object_var anObject = _smeshGen_i->GetNS()->Resolve("/myStudyManager"); SALOMEDS::StudyManager_var aStudyMgr = SALOMEDS::StudyManager::_narrow(anObject); - MESSAGE("studyid = " << _studyId); - _study = NULL; _study = aStudyMgr->GetStudyByID(_studyId); - if (!_study->_is_nil()) - MESSAGE("_study->StudyId() = " << _study->StudyId()); _computeCanceled = false; _progressAdvance = 1e-4; @@ -168,7 +163,6 @@ GHS3DPlugin_GHS3D::GHS3DPlugin_GHS3D(int hypId, int studyId, SMESH_Gen* gen) GHS3DPlugin_GHS3D::~GHS3DPlugin_GHS3D() { - MESSAGE("GHS3DPlugin_GHS3D::~GHS3DPlugin_GHS3D"); } //============================================================================= @@ -220,7 +214,6 @@ bool GHS3DPlugin_GHS3D::CheckHypothesis ( SMESH_Mesh& aMesh, TopoDS_Shape GHS3DPlugin_GHS3D::entryToShape(std::string entry) { - MESSAGE("GHS3DPlugin_GHS3D::entryToShape "<_is_nil() ) throw SALOME_Exception("MG-Tetra plugin can't work w/o publishing in the study"); GEOM::GEOM_Object_var aGeomObj; @@ -453,7 +446,6 @@ static void addElemInMeshGroup(SMESH_Mesh* theMesh, SMESHDS_Group* aGroupDS = static_cast( groupDS ); aGroupDS->SMDSGroup().Add(anElem); groupDone = true; -// MESSAGE("Successfully added enforced element to existing group " << groupName); break; } } @@ -465,7 +457,6 @@ static void addElemInMeshGroup(SMESH_Mesh* theMesh, aGroup->SetName( groupName.c_str() ); SMESHDS_Group* aGroupDS = static_cast( aGroup->GetGroupDS() ); aGroupDS->SMDSGroup().Add(anElem); -// MESSAGE("Successfully created enforced vertex group " << groupName); groupDone = true; } if (!groupDone) @@ -489,7 +480,6 @@ static void updateMeshGroups(SMESH_Mesh* theMesh, std::set groupsTo std::string currentGroupName = (string)group->GetName(); if (groupDS->IsEmpty() && groupsToRemove.find(currentGroupName) != groupsToRemove.end()) { // Previous group created by enforced elements - MESSAGE("Delete previous group created by removed enforced elements: " << group->GetName()) theMesh->RemoveGroup(groupDS->GetID()); } } @@ -637,11 +627,9 @@ static bool readGMFFile(MG_Tetra_API* MGOutput, tabRef[GmfHexahedra] = 8; int ver, dim; - MESSAGE("Read " << theFile << " file"); int InpMsh = MGOutput->GmfOpenMesh( theFile, GmfRead, &ver, &dim); if (!InpMsh) return false; - MESSAGE("Done "); // Read ids of domains vector< int > solidIDByDomain; @@ -982,7 +970,6 @@ static bool readGMFFile(MG_Tetra_API* MGOutput, makeDomainGroups( elemsOfDomain, theHelper ); #ifdef _DEBUG_ - MESSAGE("Nb subdomains " << subdomainId2tetraId.size()); std::map >::const_iterator subdomainIt = subdomainId2tetraId.begin(); TCollection_AsciiString aSubdomainFileName = theFile; aSubdomainFileName = aSubdomainFileName + ".subdomain"; @@ -992,7 +979,6 @@ static bool readGMFFile(MG_Tetra_API* MGOutput, for(;subdomainIt != subdomainId2tetraId.end() ; ++subdomainIt) { int subdomainId = subdomainIt->first; std::set tetraIds = subdomainIt->second; - MESSAGE("Subdomain #"<::const_iterator tetraIdsIt = tetraIds.begin(); aSubdomainFile << subdomainId << std::endl; for(;tetraIdsIt != tetraIds.end() ; ++tetraIdsIt) { @@ -1026,7 +1012,6 @@ static bool writeGMFFile(MG_Tetra_API* MGInput GHS3DPlugin_Hypothesis::TGHS3DEnforcedVertexCoordsValues & theEnforcedVertices, int & theInvalidEnforcedFlags) { - MESSAGE("writeGMFFile w/o geometry"); std::string tmpStr; int idx, idxRequired = 0, idxSol = 0; const int dummyint = 0; @@ -1800,10 +1785,15 @@ bool GHS3DPlugin_GHS3D::Compute(SMESH_Mesh& theMesh, } else if ( mgTetra.HasLog() ) { - // get problem description from the log file - _Ghs2smdsConvertor conv( aNodeByGhs3dId, proxyMesh ); - storeErrorDescription( _logInStandardOutput ? 0 : aLogFileName.ToCString(), - mgTetra.GetLog(), conv ); + if( _computeCanceled ) + error( "interruption initiated by user" ); + else + { + // get problem description from the log file + _Ghs2smdsConvertor conv( aNodeByGhs3dId, proxyMesh ); + error( getErrorDescription( _logInStandardOutput ? 0 : aLogFileName.ToCString(), + mgTetra.GetLog(), conv )); + } } else if ( !errStr.empty() ) { @@ -1846,8 +1836,6 @@ bool GHS3DPlugin_GHS3D::Compute(SMESH_Mesh& theMesh, bool GHS3DPlugin_GHS3D::Compute(SMESH_Mesh& theMesh, SMESH_MesherHelper* theHelper) { - MESSAGE("GHS3DPlugin_GHS3D::Compute()"); - theHelper->IsQuadraticSubMesh( theHelper->GetSubShape() ); // a unique working file name @@ -2019,10 +2007,15 @@ bool GHS3DPlugin_GHS3D::Compute(SMESH_Mesh& theMesh, } else if ( mgTetra.HasLog() ) { - // get problem description from the log file - _Ghs2smdsConvertor conv( aNodeByGhs3dId, proxyMesh ); - storeErrorDescription( _logInStandardOutput ? 0 : aLogFileName.ToCString(), - mgTetra.GetLog(), conv ); + if( _computeCanceled ) + error( "interruption initiated by user" ); + else + { + // get problem description from the log file + _Ghs2smdsConvertor conv( aNodeByGhs3dId, proxyMesh ); + error( getErrorDescription( _logInStandardOutput ? 0 : aLogFileName.ToCString(), + mgTetra.GetLog(), conv )); + } } else { // the log file is empty @@ -2378,17 +2371,13 @@ static char* getIds( char* ptr, int nbIds, vector& ids ) */ //================================================================================ -bool GHS3DPlugin_GHS3D::storeErrorDescription(const char* logFile, - const std::string& log, - const _Ghs2smdsConvertor & toSmdsConvertor ) +SMESH_ComputeErrorPtr +GHS3DPlugin_GHS3D::getErrorDescription(const char* logFile, + const std::string& log, + const _Ghs2smdsConvertor & toSmdsConvertor, + const bool isOk/* = false*/ ) { - if(_computeCanceled) - return error(SMESH_Comment("interruption initiated by user")); - - // read file - // SMESH_File file( logFile.ToCString() ); - // if ( file.size() == 0 ) - // return error( SMESH_Comment("See ") << logFile << " for problem description"); + SMESH_ComputeErrorPtr err = SMESH_ComputeError::New( COMPERR_ALGO_FAILED ); char* ptr = const_cast( log.c_str() ); char* buf = ptr, * bufEnd = ptr + log.size(); @@ -2426,7 +2415,7 @@ bool GHS3DPlugin_GHS3D::storeErrorDescription(const char* logFile if ( strncmp( ptr, "ERR ", 4 ) != 0 ) continue; - list badElems; + list& badElems = err->myBadElements; vector nodeIds; ptr += 4; @@ -2600,13 +2589,6 @@ bool GHS3DPlugin_GHS3D::storeErrorDescription(const char* logFile // continue; // not to report different types of errors with bad elements // } - // store bad elements - //if ( allElemsOk ) { - list::iterator elem = badElems.begin(); - for ( ; elem != badElems.end(); ++elem ) - addBadInputElement( *elem ); - //} - // make error text string text = translateError( errNum ); if ( errDescription.find( text ) == text.npos ) { @@ -2631,14 +2613,20 @@ bool GHS3DPlugin_GHS3D::storeErrorDescription(const char* logFile } } - if ( logFile && logFile[0] ) + if ( !isOk && logFile && logFile[0] ) { if ( errDescription.empty() ) errDescription << "See " << logFile << " for problem description"; else errDescription << "\nSee " << logFile << " for more information"; } - return error( errDescription ); + + err->myComment = errDescription; + + if ( err->myComment.empty() && err->myBadElements.empty() ) + err = SMESH_ComputeError::New(); // OK + + return err; } //================================================================================ @@ -2936,7 +2924,7 @@ double GHS3DPlugin_GHS3D::GetProgress() const if ( _isLibUsed ) { // this->_progress is advanced by MG_Tetra_API according to messages from MG library - // but sharply. Advanced it a bit to get smoother advancement. + // but sharply. Advance it a bit to get smoother advancement. GHS3DPlugin_GHS3D* me = const_cast( this ); if ( _progress < 0.1 ) // the first message is at 10% me->_progress = GetProgressByTic(); diff --git a/src/GHS3DPlugin/GHS3DPlugin_GHS3D.hxx b/src/GHS3DPlugin/GHS3DPlugin_GHS3D.hxx index 7d9a359..b5f4c8b 100644 --- a/src/GHS3DPlugin/GHS3DPlugin_GHS3D.hxx +++ b/src/GHS3DPlugin/GHS3DPlugin_GHS3D.hxx @@ -50,6 +50,7 @@ class TopoDS_Shape; class GHS3DPlugin_GHS3D: public SMESH_3D_Algo { public: + GHS3DPlugin_GHS3D(int hypId, int studyId, SMESH_Gen* gen); virtual ~GHS3DPlugin_GHS3D(); @@ -75,20 +76,23 @@ public: bool importGMFMesh(const char* aGMFFileName, SMESH_Mesh& aMesh); + virtual double GetProgress() const; + + static const char* Name() { return "MG-Tetra"; } - virtual double GetProgress() const; + static SMESH_ComputeErrorPtr getErrorDescription(const char* logFile, + const std::string& log, + const _Ghs2smdsConvertor & toSmdsConvertor, + const bool isOK = false); protected: const GHS3DPlugin_Hypothesis* _hyp; const StdMeshers_ViscousLayers* _viscousLayersHyp; std::string _genericName; - + private: - bool storeErrorDescription(const char* logFile, - const std::string& log, - const _Ghs2smdsConvertor & toSmdsConvertor ); TopoDS_Shape entryToShape(std::string entry); int _iShape; diff --git a/src/GHS3DPlugin/GHS3DPlugin_GHS3D_i.cxx b/src/GHS3DPlugin/GHS3DPlugin_GHS3D_i.cxx index 2ab6dc5..4dc8a18 100644 --- a/src/GHS3DPlugin/GHS3DPlugin_GHS3D_i.cxx +++ b/src/GHS3DPlugin/GHS3DPlugin_GHS3D_i.cxx @@ -24,13 +24,16 @@ // $Header$ // #include "GHS3DPlugin_GHS3D_i.hxx" -#include "SMESH_Gen.hxx" -#include "SMESH_Mesh_i.hxx" -#include "SMESH_Gen_i.hxx" + #include "GHS3DPlugin_GHS3D.hxx" -#include "SMESH_PythonDump.hxx" +#include "GHS3DPlugin_Optimizer.hxx" + +#include +#include +#include +#include -#include "utilities.h" +#include #include //============================================================================= @@ -49,7 +52,6 @@ GHS3DPlugin_GHS3D_i::GHS3DPlugin_GHS3D_i (PortableServer::POA_ptr thePOA, SMESH_Algo_i( thePOA ), SMESH_3D_Algo_i( thePOA ) { - MESSAGE( "GHS3DPlugin_GHS3D_i::GHS3DPlugin_GHS3D_i" ); myBaseImpl = new ::GHS3DPlugin_GHS3D (theGenImpl->GetANewId(), theStudyId, theGenImpl ); @@ -65,7 +67,6 @@ GHS3DPlugin_GHS3D_i::GHS3DPlugin_GHS3D_i (PortableServer::POA_ptr thePOA, GHS3DPlugin_GHS3D_i::~GHS3DPlugin_GHS3D_i() { - MESSAGE( "GHS3DPlugin_GHS3D_i::~GHS3DPlugin_GHS3D_i" ); } //============================================================================= @@ -78,7 +79,6 @@ GHS3DPlugin_GHS3D_i::~GHS3DPlugin_GHS3D_i() ::GHS3DPlugin_GHS3D* GHS3DPlugin_GHS3D_i::GetImpl() { - MESSAGE( "GHS3DPlugin_GHS3D_i::GetImpl" ); return ( ::GHS3DPlugin_GHS3D* )myBaseImpl; } @@ -92,7 +92,6 @@ GHS3DPlugin_GHS3D_i::~GHS3DPlugin_GHS3D_i() SMESH::SMESH_Mesh_ptr GHS3DPlugin_GHS3D_i::importGMFMesh(const char* theGMFFileName) { - MESSAGE( "GHS3DPlugin_GHS3D_i::importGMFMesh" ); SMESH_Gen_i* smeshGen = SMESH_Gen_i::GetSMESHGen(); SMESH::SMESH_Mesh_ptr theMesh = smeshGen->CreateEmptyMesh(); smeshGen->RemoveLastFromPythonScript(smeshGen->GetCurrentStudy()->StudyId()); @@ -114,3 +113,25 @@ SMESH::SMESH_Mesh_ptr GHS3DPlugin_GHS3D_i::importGMFMesh(const char* theGMFFileN } return theMesh; } + +//============================================================================= +/*! + * GHS3DPlugin_Optimizer_i::GHS3DPlugin_Optimizer_i + * + * Constructor + */ +//============================================================================= + +GHS3DPlugin_Optimizer_i::GHS3DPlugin_Optimizer_i (PortableServer::POA_ptr thePOA, + int theStudyId, + ::SMESH_Gen* theGenImpl ) + : SALOME::GenericObj_i( thePOA ), + SMESH_Hypothesis_i( thePOA ), + SMESH_Algo_i( thePOA ), + SMESH_3D_Algo_i( thePOA ) +{ + myBaseImpl = new ::GHS3DPlugin_Optimizer (theGenImpl->GetANewId(), + theStudyId, + theGenImpl ); +} + diff --git a/src/GHS3DPlugin/GHS3DPlugin_GHS3D_i.hxx b/src/GHS3DPlugin/GHS3DPlugin_GHS3D_i.hxx index dc27c27..cf77904 100644 --- a/src/GHS3DPlugin/GHS3DPlugin_GHS3D_i.hxx +++ b/src/GHS3DPlugin/GHS3DPlugin_GHS3D_i.hxx @@ -53,4 +53,18 @@ public: virtual SMESH::SMESH_Mesh_ptr importGMFMesh(const char* theGMFFileName); }; +// ====================================================== +// MG-Tetra Optimization 3d algorithm +// ====================================================== +class GHS3DPlugin_Optimizer_i: + public virtual POA_GHS3DPlugin::GHS3DPlugin_Optimizer, + public virtual SMESH_3D_Algo_i +{ +public: + // Constructor + GHS3DPlugin_Optimizer_i (PortableServer::POA_ptr thePOA, + int theStudyId, + ::SMESH_Gen* theGenImpl ); +}; + #endif diff --git a/src/GHS3DPlugin/GHS3DPlugin_Hypothesis.cxx b/src/GHS3DPlugin/GHS3DPlugin_Hypothesis.cxx index 0e480bc..2f2650e 100644 --- a/src/GHS3DPlugin/GHS3DPlugin_Hypothesis.cxx +++ b/src/GHS3DPlugin/GHS3DPlugin_Hypothesis.cxx @@ -1461,7 +1461,7 @@ bool GHS3DPlugin_Hypothesis::SetParametersByDefaults(const TDefaults& dflts, std::string GHS3DPlugin_Hypothesis::CommandToRun(const GHS3DPlugin_Hypothesis* hyp, const bool hasShapeToMesh, - const bool forExucutable) + const bool forExecutable) { std::string cmd = GetExeName(); // check if any option is overridden by hyp->myTextOption @@ -1523,7 +1523,7 @@ std::string GHS3DPlugin_Hypothesis::CommandToRun(const GHS3DPlugin_Hypothesis* h // to create internal nodes if ( no_int_points && !toCreateNewNodes ) { - if ( forExucutable ) + if ( forExecutable ) cmd += " --no_internal_points"; else cmd += " --internalpoints no"; @@ -1546,7 +1546,7 @@ std::string GHS3DPlugin_Hypothesis::CommandToRun(const GHS3DPlugin_Hypothesis* h // to remove initial central point. if ( rem && hyp && hyp->myToRemoveCentralPoint) { - if ( forExucutable ) + if ( forExecutable ) cmd += " --no_initial_central_point"; else cmd += " --centralpoint no"; @@ -1559,7 +1559,7 @@ std::string GHS3DPlugin_Hypothesis::CommandToRun(const GHS3DPlugin_Hypothesis* h // to define volumic gradation. if ( gra && hyp ) { - if ( forExucutable ) + if ( forExecutable ) cmd += " -Dcpropa=" + SMESH_Comment( hyp->myGradation ); else cmd += " --gradation " + SMESH_Comment( hyp->myGradation ); diff --git a/src/GHS3DPlugin/GHS3DPlugin_Hypothesis.hxx b/src/GHS3DPlugin/GHS3DPlugin_Hypothesis.hxx index c6990a3..afcc808 100644 --- a/src/GHS3DPlugin/GHS3DPlugin_Hypothesis.hxx +++ b/src/GHS3DPlugin/GHS3DPlugin_Hypothesis.hxx @@ -323,8 +323,6 @@ public: // Persistence virtual std::ostream & SaveTo(std::ostream & save); virtual std::istream & LoadFrom(std::istream & load); - friend GHS3DPLUGIN_EXPORT std::ostream & operator <<(std::ostream & save, GHS3DPlugin_Hypothesis & hyp); - friend GHS3DPLUGIN_EXPORT std::istream & operator >>(std::istream & load, GHS3DPlugin_Hypothesis & hyp); /*! * \brief Does nothing @@ -336,7 +334,7 @@ public: */ virtual bool SetParametersByDefaults(const TDefaults& dflts, const SMESH_Mesh* theMesh=0); -private: +protected: bool myToMeshHoles; bool myToMakeGroupsOfDomains; diff --git a/src/GHS3DPlugin/GHS3DPlugin_Hypothesis_i.cxx b/src/GHS3DPlugin/GHS3DPlugin_Hypothesis_i.cxx index acc6472..da36903 100644 --- a/src/GHS3DPlugin/GHS3DPlugin_Hypothesis_i.cxx +++ b/src/GHS3DPlugin/GHS3DPlugin_Hypothesis_i.cxx @@ -23,26 +23,20 @@ // #include "GHS3DPlugin_Hypothesis_i.hxx" -#include "SMESH_Gen.hxx" -#include "SMESH_PythonDump.hxx" -//#include "SMESH_Mesh.hxx" -//#include "SMESH_ProxyMesh.hxx" -//#include - -#include "Utils_CorbaException.hxx" -#include "utilities.h" -#include "SMESH_Mesh_i.hxx" -#include "SMESH_Group_i.hxx" -#include "SMESH_Gen_i.hxx" -#include "SMESH_TypeDefs.hxx" -#include "SMESHDS_GroupBase.hxx" +#include +#include + +#include +#include +#include +#include +#include +//#include +#include // SALOME KERNEL includes -#include "SALOMEDSClient.hxx" -#include -// // IDL headers -// #include -// #include CORBA_SERVER_HEADER(SALOMEDS) +// #include +// #include using namespace std; @@ -56,7 +50,6 @@ GHS3DPlugin_Hypothesis_i::GHS3DPlugin_Hypothesis_i (PortableServer::POA_ptr theP : SALOME::GenericObj_i( thePOA ), SMESH_Hypothesis_i( thePOA ) { - MESSAGE( "GHS3DPlugin_Hypothesis_i::GHS3DPlugin_Hypothesis_i" ); myBaseImpl = new ::GHS3DPlugin_Hypothesis (theGenImpl->GetANewId(), theStudyId, theGenImpl); @@ -68,7 +61,6 @@ GHS3DPlugin_Hypothesis_i::GHS3DPlugin_Hypothesis_i (PortableServer::POA_ptr theP GHS3DPlugin_Hypothesis_i::~GHS3DPlugin_Hypothesis_i() { - MESSAGE( "GHS3DPlugin_Hypothesis_i::~GHS3DPlugin_Hypothesis_i" ); } //======================================================================= @@ -118,7 +110,7 @@ CORBA::Boolean GHS3DPlugin_Hypothesis_i::GetToMakeGroupsOfDomains() //======================================================================= void GHS3DPlugin_Hypothesis_i::SetMaximumMemory(CORBA::Long MB) - throw ( SALOME::SALOME_Exception ) + throw ( SALOME::SALOME_Exception ) { if ( MB == 0 ) THROW_SALOME_CORBA_EXCEPTION( "Invalid memory size",SALOME::BAD_PARAM ); @@ -169,7 +161,7 @@ void GHS3DPlugin_Hypothesis_i::SetOptimizationLevel(CORBA::Short level) throw ( SALOME::SALOME_Exception ) { ::GHS3DPlugin_Hypothesis::OptimizationLevel l = - (::GHS3DPlugin_Hypothesis::OptimizationLevel) level; + (::GHS3DPlugin_Hypothesis::OptimizationLevel) level; if ( l < ::GHS3DPlugin_Hypothesis::None || l > ::GHS3DPlugin_Hypothesis::Strong ) THROW_SALOME_CORBA_EXCEPTION( "Invalid optimization level",SALOME::BAD_PARAM ); @@ -465,39 +457,34 @@ CORBA::Boolean GHS3DPlugin_Hypothesis_i::GetRemoveLogOnSuccess() //======================================================================= bool GHS3DPlugin_Hypothesis_i::SetEnforcedVertex(CORBA::Double x, CORBA::Double y, CORBA::Double z, CORBA::Double size) - throw (SALOME::SALOME_Exception) { + throw (SALOME::SALOME_Exception) { ASSERT(myBaseImpl); - MESSAGE("IDL : SetEnforcedVertex( "<< x << ", " << y << ", " << z << ", " << size << ")"); return p_SetEnforcedVertex(size, x, y, z); } bool GHS3DPlugin_Hypothesis_i::SetEnforcedVertexNamed(CORBA::Double x, CORBA::Double y, CORBA::Double z, CORBA::Double size, const char* theVertexName) - throw (SALOME::SALOME_Exception) { + throw (SALOME::SALOME_Exception) { ASSERT(myBaseImpl); - MESSAGE("IDL : SetEnforcedVertexNamed( "<< x << ", " << y << ", " << z << ", " << size << ", " << theVertexName << ")"); return p_SetEnforcedVertex(size, x, y, z, theVertexName, "", ""); } bool GHS3DPlugin_Hypothesis_i::SetEnforcedVertexWithGroup(CORBA::Double x, CORBA::Double y, CORBA::Double z, CORBA::Double size, const char* theGroupName) - throw (SALOME::SALOME_Exception) { + throw (SALOME::SALOME_Exception) { ASSERT(myBaseImpl); - MESSAGE("IDL : SetEnforcedVertexWithGroup( "<< x << ", " << y << ", " << z << ", " << size << ", " << theGroupName << ")"); return p_SetEnforcedVertex(size, x, y, z, "", "", theGroupName); } bool GHS3DPlugin_Hypothesis_i::SetEnforcedVertexNamedWithGroup(CORBA::Double x, CORBA::Double y, CORBA::Double z, CORBA::Double size, const char* theVertexName, const char* theGroupName) - throw (SALOME::SALOME_Exception) { + throw (SALOME::SALOME_Exception) { ASSERT(myBaseImpl); - MESSAGE("IDL : SetEnforcedVertexNamedWithGroup( "<< x << ", " << y << ", " << z << ", " << size << ", " << theVertexName << ", " << theGroupName << ")"); return p_SetEnforcedVertex(size, x, y, z, theVertexName, "", theGroupName); } bool GHS3DPlugin_Hypothesis_i::SetEnforcedVertexGeom(GEOM::GEOM_Object_ptr theVertex, CORBA::Double size) - throw (SALOME::SALOME_Exception) { + throw (SALOME::SALOME_Exception) { ASSERT(myBaseImpl); if ((theVertex->GetShapeType() != GEOM::VERTEX) && (theVertex->GetShapeType() != GEOM::COMPOUND)) { - MESSAGE("theVertex shape type is not VERTEX or COMPOUND"); THROW_SALOME_CORBA_EXCEPTION("theVertex shape type is not VERTEX or COMPOUND", SALOME::BAD_PARAM); } @@ -529,21 +516,18 @@ bool GHS3DPlugin_Hypothesis_i::SetEnforcedVertexGeom(GEOM::GEOM_Object_ptr theVe return false; measureOp->PointCoordinates (theVertex, x, y, z); - MESSAGE("Point coordinates from measureOp: " << x << ", " << y << ", " << z); } string theVertexName = theVertex->GetName(); - MESSAGE("IDL : SetEnforcedVertexGeom( "<< theVertexEntry << ", " << size<< ")"); return p_SetEnforcedVertex(size, x, y, z, theVertexName.c_str(), theVertexEntry.c_str(), "", isCompound); } bool GHS3DPlugin_Hypothesis_i::SetEnforcedVertexGeomWithGroup(GEOM::GEOM_Object_ptr theVertex, CORBA::Double size, const char* theGroupName) - throw (SALOME::SALOME_Exception) { + throw (SALOME::SALOME_Exception) { ASSERT(myBaseImpl); if ((theVertex->GetShapeType() != GEOM::VERTEX) && (theVertex->GetShapeType() != GEOM::COMPOUND)) { - MESSAGE("theVertex shape type is not VERTEX or COMPOUND"); THROW_SALOME_CORBA_EXCEPTION("theVertex shape type is not VERTEX or COMPOUND", SALOME::BAD_PARAM); } @@ -575,21 +559,18 @@ bool GHS3DPlugin_Hypothesis_i::SetEnforcedVertexGeomWithGroup(GEOM::GEOM_Object_ return false; measureOp->PointCoordinates (theVertex, x, y, z); - MESSAGE("Point coordinates from measureOp: " << x << ", " << y << ", " << z); } string theVertexName = theVertex->GetName(); - MESSAGE("IDL : SetEnforcedVertexGeomWithGroup( "<< theVertexEntry << ", " << size<< ", " << theGroupName << ")"); return p_SetEnforcedVertex(size, x, y, z, theVertexName.c_str(), theVertexEntry.c_str(), theGroupName, isCompound); } bool GHS3DPlugin_Hypothesis_i:: p_SetEnforcedVertex(CORBA::Double size, CORBA::Double x, CORBA::Double y, CORBA::Double z, - const char* theVertexName, const char* theVertexEntry, const char* theGroupName, - CORBA::Boolean isCompound) - throw (SALOME::SALOME_Exception) { + const char* theVertexName, const char* theVertexEntry, const char* theGroupName, + CORBA::Boolean isCompound) + throw (SALOME::SALOME_Exception) { ASSERT(myBaseImpl); - MESSAGE("IDL : p_SetEnforcedVertex(" << size << ", " << x << ", " << y << ", " << z << ", \"" << theVertexName << "\", \"" << theVertexEntry << "\", \"" << theGroupName << "\", " << isCompound<< ")"); bool newValue = false; ::GHS3DPlugin_Hypothesis::TCoordsGHS3DEnforcedVertexMap coordsList; @@ -601,20 +582,13 @@ bool GHS3DPlugin_Hypothesis_i:: p_SetEnforcedVertex(CORBA::Double size, CORBA::D coords.push_back(y); coords.push_back(z); if (coordsList.find(coords) == coordsList.end()) { - MESSAGE("Coords not found: add it in coordsList"); newValue = true; } else { - MESSAGE("Coords already found, compare names"); ::GHS3DPlugin_Hypothesis::TGHS3DEnforcedVertex *enfVertex = this->GetImpl()->GetEnforcedVertex(x, y, z); if ((enfVertex->name != theVertexName) || (enfVertex->groupName != theGroupName) || (enfVertex->size != size)) { - MESSAGE("The names or size are different: update"); -// this->GetImpl()->ClearEnforcedVertex(theFaceEntry, x, y, z); newValue = true; } - else { - MESSAGE("The names and size are identical"); - } } if (newValue) { @@ -633,24 +607,15 @@ bool GHS3DPlugin_Hypothesis_i:: p_SetEnforcedVertex(CORBA::Double size, CORBA::D } } else { -// if (isCompound || (!isCompound && !string(theVertexEntry).empty())) { enfVertexEntryList = this->GetImpl()->_GetEnforcedVerticesByEntry(); -// ::BLSURFPlugin_Hypothesis::TGeomEntryGHS3DEnforcedVertexMap::const_iterator it = enfVertexEntryList.find(theVertexEntry); if ( enfVertexEntryList.find(theVertexEntry) == enfVertexEntryList.end()) { - MESSAGE("Geom entry not found: add it in enfVertexEntryList"); newValue = true; } else { - MESSAGE("Geom entry already found, compare names"); ::GHS3DPlugin_Hypothesis::TGHS3DEnforcedVertex *enfVertex = this->GetImpl()->GetEnforcedVertex(theVertexEntry); if ((enfVertex->name != theVertexName) || (enfVertex->groupName != theGroupName) || (enfVertex->size != size)) { - MESSAGE("The names or size are different: update"); -// this->GetImpl()->ClearEnforcedVertex(theFaceEntry, x, y, z); newValue = true; } - else { - MESSAGE("The names and size are identical"); - } } if (newValue) { @@ -664,7 +629,6 @@ bool GHS3DPlugin_Hypothesis_i:: p_SetEnforcedVertex(CORBA::Double size, CORBA::D if (newValue) this->GetImpl()->SetEnforcedVertex(theVertexName, theVertexEntry, theGroupName, size, x, y, z, isCompound); - MESSAGE("IDL : SetEnforcedVertexEntry END"); return newValue; } @@ -682,12 +646,7 @@ CORBA::Double GHS3DPlugin_Hypothesis_i::GetEnforcedVertex(CORBA::Double x, CORBA return isDone; } catch (const std::invalid_argument& ex) { - SALOME::ExceptionStruct ExDescription; - ExDescription.text = ex.what(); - ExDescription.type = SALOME::BAD_PARAM; - ExDescription.sourceFile = "GHS3DPlugin_Hypothesis_i.cxx"; - ExDescription.lineNumber = 513; - throw SALOME::SALOME_Exception(ExDescription); + THROW_SALOME_CORBA_EXCEPTION( ex.what() ,SALOME::BAD_PARAM ); } catch (SALOME_Exception& ex) { THROW_SALOME_CORBA_EXCEPTION( ex.what() ,SALOME::BAD_PARAM ); @@ -704,7 +663,6 @@ CORBA::Double GHS3DPlugin_Hypothesis_i::GetEnforcedVertexGeom(GEOM::GEOM_Object_ ASSERT(myBaseImpl); if ((theVertex->GetShapeType() != GEOM::VERTEX) && (theVertex->GetShapeType() != GEOM::COMPOUND)) { - MESSAGE("theVertex shape type is not VERTEX or COMPOUND"); THROW_SALOME_CORBA_EXCEPTION("theVertex shape type is not VERTEX or COMPOUND", SALOME::BAD_PARAM); } @@ -733,12 +691,7 @@ CORBA::Double GHS3DPlugin_Hypothesis_i::GetEnforcedVertexGeom(GEOM::GEOM_Object_ return isDone; } catch (const std::invalid_argument& ex) { - SALOME::ExceptionStruct ExDescription; - ExDescription.text = ex.what(); - ExDescription.type = SALOME::BAD_PARAM; - ExDescription.sourceFile = "GHS3DPlugin_Hypothesis_i.cxx"; - ExDescription.lineNumber = 538; - throw SALOME::SALOME_Exception(ExDescription); + THROW_SALOME_CORBA_EXCEPTION( ex.what() ,SALOME::BAD_PARAM ); } catch (SALOME_Exception& ex) { THROW_SALOME_CORBA_EXCEPTION( ex.what() ,SALOME::BAD_PARAM ); @@ -780,9 +733,9 @@ GHS3DPlugin::GHS3DEnforcedVertexList* GHS3DPlugin_Hypothesis_i::GetEnforcedVerti enfVertex->isCompound = currentVertex->isCompound; result[i]=enfVertex; - } + } -// SMESH::TPythonDump() << "allEnforcedVertices = " << _this() << ".GetEnforcedVertices()"; + // SMESH::TPythonDump() << "allEnforcedVertices = " << _this() << ".GetEnforcedVertices()"; return result._retn(); } @@ -801,12 +754,7 @@ bool GHS3DPlugin_Hypothesis_i::RemoveEnforcedVertex(CORBA::Double x, CORBA::Doub return res; } catch (const std::invalid_argument& ex) { - SALOME::ExceptionStruct ExDescription; - ExDescription.text = ex.what(); - ExDescription.type = SALOME::BAD_PARAM; - ExDescription.sourceFile = "GHS3DPlugin_Hypothesis_i.cxx"; - ExDescription.lineNumber = 625; - throw SALOME::SALOME_Exception(ExDescription); + THROW_SALOME_CORBA_EXCEPTION( ex.what() ,SALOME::BAD_PARAM ); } catch (SALOME_Exception& ex) { THROW_SALOME_CORBA_EXCEPTION( ex.what() ,SALOME::BAD_PARAM ); @@ -819,7 +767,6 @@ bool GHS3DPlugin_Hypothesis_i::RemoveEnforcedVertexGeom(GEOM::GEOM_Object_ptr th ASSERT(myBaseImpl); if ((theVertex->GetShapeType() != GEOM::VERTEX) && (theVertex->GetShapeType() != GEOM::COMPOUND)) { - MESSAGE("theVertex shape type is not VERTEX or COMPOUND"); THROW_SALOME_CORBA_EXCEPTION("theVertex shape type is not VERTEX or COMPOUND", SALOME::BAD_PARAM); } @@ -846,12 +793,7 @@ bool GHS3DPlugin_Hypothesis_i::RemoveEnforcedVertexGeom(GEOM::GEOM_Object_ptr th return res; } catch (const std::invalid_argument& ex) { - SALOME::ExceptionStruct ExDescription; - ExDescription.text = ex.what(); - ExDescription.type = SALOME::BAD_PARAM; - ExDescription.sourceFile = "GHS3DPlugin_Hypothesis_i.cxx"; - ExDescription.lineNumber = 648; - throw SALOME::SALOME_Exception(ExDescription); + THROW_SALOME_CORBA_EXCEPTION( ex.what() ,SALOME::BAD_PARAM ); } catch (SALOME_Exception& ex) { THROW_SALOME_CORBA_EXCEPTION( ex.what() ,SALOME::BAD_PARAM ); @@ -907,9 +849,9 @@ GHS3DPlugin::GHS3DEnforcedMeshList* GHS3DPlugin_Hypothesis_i::GetEnforcedMeshes( enfMesh->groupName = CORBA::string_dup(currentMesh->groupName.c_str()); result[i]=enfMesh; - } + } -// SMESH::TPythonDump() << "allEnforcedVertices = " << _this() << ".GetEnforcedVertices()"; + // SMESH::TPythonDump() << "allEnforcedVertices = " << _this() << ".GetEnforcedVertices()"; return result._retn(); } @@ -920,16 +862,7 @@ GHS3DPlugin::GHS3DEnforcedMeshList* GHS3DPlugin_Hypothesis_i::GetEnforcedMeshes( bool GHS3DPlugin_Hypothesis_i::SetEnforcedMeshWithGroup(SMESH::SMESH_IDSource_ptr theSource, SMESH::ElementType theType, const char* theGroupName) throw (SALOME::SALOME_Exception) { -// #if GHS3D_VERSION >= 42 return p_SetEnforcedMesh(theSource, theType, "", theGroupName); -// #else -// SALOME::ExceptionStruct ExDescription; -// ExDescription.text = "Bad version of GHS3D. It must >= 4.2."; -// ExDescription.type = SALOME::BAD_PARAM; -// ExDescription.sourceFile = "GHS3DPlugin_Hypothesis_i.cxx"; -// ExDescription.lineNumber = 719; -// throw SALOME::SALOME_Exception(ExDescription); -// #endif } /*! @@ -938,17 +871,7 @@ bool GHS3DPlugin_Hypothesis_i::SetEnforcedMeshWithGroup(SMESH::SMESH_IDSource_pt bool GHS3DPlugin_Hypothesis_i::SetEnforcedMesh(SMESH::SMESH_IDSource_ptr theSource, SMESH::ElementType theType) throw (SALOME::SALOME_Exception) { -// MESSAGE("GHS3DPlugin_Hypothesis_i::SetEnforcedMesh"); -// #if GHS3D_VERSION >= 42 return p_SetEnforcedMesh(theSource, theType); -// #else -// SALOME::ExceptionStruct ExDescription; -// ExDescription.text = "Bad version of GHS3D. It must >= 4.2."; -// ExDescription.type = SALOME::BAD_PARAM; -// ExDescription.sourceFile = "GHS3DPlugin_Hypothesis_i.cxx"; -// ExDescription.lineNumber = 750; -// throw SALOME::SALOME_Exception(ExDescription); -// #endif } /*! @@ -957,16 +880,7 @@ bool GHS3DPlugin_Hypothesis_i::SetEnforcedMesh(SMESH::SMESH_IDSource_ptr theSour bool GHS3DPlugin_Hypothesis_i::SetEnforcedMeshSizeWithGroup(SMESH::SMESH_IDSource_ptr theSource, SMESH::ElementType theType, double theSize, const char* theGroupName) throw (SALOME::SALOME_Exception) { -// #if GHS3D_VERSION >= 42 return p_SetEnforcedMesh(theSource, theType, "", theGroupName); -// #else -// SALOME::ExceptionStruct ExDescription; -// ExDescription.text = "Bad version of GHS3D. It must >= 4.2."; -// ExDescription.type = SALOME::BAD_PARAM; -// ExDescription.sourceFile = "GHS3DPlugin_Hypothesis_i.cxx"; -// ExDescription.lineNumber = 750; -// throw SALOME::SALOME_Exception(ExDescription); -// #endif } /*! @@ -975,64 +889,32 @@ bool GHS3DPlugin_Hypothesis_i::SetEnforcedMeshSizeWithGroup(SMESH::SMESH_IDSourc bool GHS3DPlugin_Hypothesis_i::SetEnforcedMeshSize(SMESH::SMESH_IDSource_ptr theSource, SMESH::ElementType theType, double theSize) throw (SALOME::SALOME_Exception) { -// #if GHS3D_VERSION >= 42 return p_SetEnforcedMesh(theSource, theType); -// #else -// SALOME::ExceptionStruct ExDescription; -// ExDescription.text = "Bad version of GHS3D. It must >= 4.2."; -// ExDescription.type = SALOME::BAD_PARAM; -// ExDescription.sourceFile = "GHS3DPlugin_Hypothesis_i.cxx"; -// ExDescription.lineNumber = 750; -// throw SALOME::SALOME_Exception(ExDescription); -// #endif } -bool GHS3DPlugin_Hypothesis_i::p_SetEnforcedMesh(SMESH::SMESH_IDSource_ptr theSource, SMESH::ElementType theType, const char* theName, const char* theGroupName) +bool GHS3DPlugin_Hypothesis_i::p_SetEnforcedMesh(SMESH::SMESH_IDSource_ptr theSource, + SMESH::ElementType theType, + const char* theName, + const char* theGroupName) throw (SALOME::SALOME_Exception) { - MESSAGE("GHS3DPlugin_Hypothesis_i::p_SetEnforcedMesh"); ASSERT(myBaseImpl); - + if (CORBA::is_nil( theSource )) - { - SALOME::ExceptionStruct ExDescription; - ExDescription.text = "The source mesh CORBA object is NULL"; - ExDescription.type = SALOME::BAD_PARAM; - ExDescription.sourceFile = "GHS3DPlugin_Hypothesis_i.cxx"; - ExDescription.lineNumber = 840; - throw SALOME::SALOME_Exception(ExDescription); - } - + THROW_SALOME_CORBA_EXCEPTION( "The source mesh CORBA object is NULL" ,SALOME::BAD_PARAM ); + switch (theType) { - case SMESH::NODE: - MESSAGE("Required type is NODE"); - break; - case SMESH::EDGE: - MESSAGE("Required type is EDGE"); - break; - case SMESH::FACE: - MESSAGE("Required type is FACE"); - break; - default: - MESSAGE("Incompatible required type: " << theType); - return false; + case SMESH::NODE: + case SMESH::EDGE: + case SMESH::FACE: break; + default: + return false; } -// MESSAGE("Required type is "<GetTypes(); - MESSAGE("Available types:"); - for ( CORBA::ULong i=0;ilength();i++){MESSAGE(types[i]);} if ( types->length() >= 1 && types[types->length()-1] < theType) { - MESSAGE("Required type not available"); return false; -// SALOME::ExceptionStruct ExDescription; -// ExDescription.text = "The source mesh has bad type"; -// ExDescription.type = SALOME::BAD_PARAM; -// ExDescription.sourceFile = "GHS3DPlugin_Hypothesis_i.cxx"; -// ExDescription.lineNumber = 840; -// throw SALOME::SALOME_Exception(ExDescription); } - SMESH_Gen_i *smeshGen = SMESH_Gen_i::GetSMESHGen(); SALOMEDS::SObject_ptr SObj = smeshGen->ObjectToSObject(smeshGen->GetCurrentStudy(),theSource); @@ -1074,21 +956,20 @@ bool GHS3DPlugin_Hypothesis_i::p_SetEnforcedMesh(SMESH::SMESH_IDSource_ptr theSo } else if (theGroup_i)// && types->length() == 1 && types[0] == theType) { - MESSAGE("The source is a group") - try { - bool res = this->GetImpl()->SetEnforcedGroup(theGroup_i->GetGroupDS()->GetMesh(), theGroup_i->GetListOfID(), theType, enfMeshName , SObj->GetID(), theGroupName); - if ( theGroupName && theGroupName[0] ) { - SMESH::TPythonDump () << "isDone = " << _this() << ".SetEnforcedMeshWithGroup( " - << theSource << ", " << theType << ", \"" << theGroupName << "\" )"; - } - else { - SMESH::TPythonDump () << "isDone = " << _this() << ".SetEnforcedMesh( " - << theSource << ", " << theType << " )"; - } - return res; + try { + bool res = this->GetImpl()->SetEnforcedGroup(theGroup_i->GetGroupDS()->GetMesh(), theGroup_i->GetListOfID(), theType, enfMeshName , SObj->GetID(), theGroupName); + if ( theGroupName && theGroupName[0] ) { + SMESH::TPythonDump () << "isDone = " << _this() << ".SetEnforcedMeshWithGroup( " + << theSource << ", " << theType << ", \"" << theGroupName << "\" )"; } - catch (const std::invalid_argument& ex) { - SALOME::ExceptionStruct ExDescription; + else { + SMESH::TPythonDump () << "isDone = " << _this() << ".SetEnforcedMesh( " + << theSource << ", " << theType << " )"; + } + return res; + } + catch (const std::invalid_argument& ex) { + SALOME::ExceptionStruct ExDescription; ExDescription.text = ex.what(); ExDescription.type = SALOME::BAD_PARAM; ExDescription.sourceFile = "GHS3DPlugin_Hypothesis_i.cxx"; @@ -1101,17 +982,16 @@ bool GHS3DPlugin_Hypothesis_i::p_SetEnforcedMesh(SMESH::SMESH_IDSource_ptr theSo } else if (theGroupOnGeom_i)// && types->length() == 1 && types[0] == theType) { - MESSAGE("The source is a group on geom") try { - bool res = this->GetImpl()->SetEnforcedGroup(theGroupOnGeom_i->GetGroupDS()->GetMesh(),theGroupOnGeom_i->GetListOfID(), theType, enfMeshName , SObj->GetID(), theGroupName); - if ( theGroupName && theGroupName[0] ) { - SMESH::TPythonDump () << "isDone = " << _this() << ".SetEnforcedMeshWithGroup( " - << theSource << ", " << theType << ", \"" << theGroupName << "\" )"; - } - else { - SMESH::TPythonDump () << "isDone = " << _this() << ".SetEnforcedMesh( " - << theSource << ", " << theType << " )"; - } + bool res = this->GetImpl()->SetEnforcedGroup(theGroupOnGeom_i->GetGroupDS()->GetMesh(),theGroupOnGeom_i->GetListOfID(), theType, enfMeshName , SObj->GetID(), theGroupName); + if ( theGroupName && theGroupName[0] ) { + SMESH::TPythonDump () << "isDone = " << _this() << ".SetEnforcedMeshWithGroup( " + << theSource << ", " << theType << ", \"" << theGroupName << "\" )"; + } + else { + SMESH::TPythonDump () << "isDone = " << _this() << ".SetEnforcedMesh( " + << theSource << ", " << theType << " )"; + } return res; } catch (const std::invalid_argument& ex) { @@ -1149,4 +1029,3 @@ CORBA::Boolean GHS3DPlugin_Hypothesis_i::IsDimSupported( SMESH::Dimension type ) { return type == SMESH::DIM_3D; } - diff --git a/src/GHS3DPlugin/GHS3DPlugin_Optimizer.cxx b/src/GHS3DPlugin/GHS3DPlugin_Optimizer.cxx new file mode 100644 index 0000000..21cac8e --- /dev/null +++ b/src/GHS3DPlugin/GHS3DPlugin_Optimizer.cxx @@ -0,0 +1,444 @@ +// Copyright (C) 2004-2016 CEA/DEN, EDF R&D +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// +// File : GHS3DPlugin_Optimizer.cxx +// Created : Mon Oct 31 20:05:28 2016 + +#include "GHS3DPlugin_Optimizer.hxx" + +#include "GHS3DPlugin_GHS3D.hxx" +#include "GHS3DPlugin_OptimizerHypothesis.hxx" +#include "MG_Tetra_API.hxx" + +#include +#include +#include +#include +#include + +#include + +//================================================================================ +/*! + * \brief Constructor + */ +//================================================================================ + +GHS3DPlugin_Optimizer::GHS3DPlugin_Optimizer(int hypId, int studyId, SMESH_Gen* gen) + : SMESH_3D_Algo(hypId, studyId, gen) +{ + _name = Name(); + _compatibleHypothesis.push_back( GHS3DPlugin_OptimizerHypothesis::GetHypType()); + _requireShape = false; // work without shape only +} + +//================================================================================ +/*! + * \brief Get a hypothesis + */ +//================================================================================ + +bool GHS3DPlugin_Optimizer::CheckHypothesis(SMESH_Mesh& aMesh, + const TopoDS_Shape& aShape, + Hypothesis_Status& aStatus) +{ + _hyp = NULL; + + const std::list & hyps = GetUsedHypothesis(aMesh, aShape); + if ( !hyps.empty() ) + _hyp = dynamic_cast< const GHS3DPlugin_OptimizerHypothesis* >( hyps.front() ); + + aStatus = HYP_OK; + return true; +} + +//================================================================================ +/*! + * \brief Terminate a process + */ +//================================================================================ + +void GHS3DPlugin_Optimizer::CancelCompute() +{ + _computeCanceled = true; +} + +//================================================================================ +/*! + * \brief Evaluate nb of elements + */ +//================================================================================ + +bool GHS3DPlugin_Optimizer::Evaluate(SMESH_Mesh& aMesh, const TopoDS_Shape& aShape, + MapShapeNbElems& aResMap) +{ + return false; +} +//================================================================================ +/*! + * \brief Does nothing + */ +//================================================================================ + +bool GHS3DPlugin_Optimizer::Compute(SMESH_Mesh & aMesh, const TopoDS_Shape & aShape) +{ + return false; +} + +namespace +{ + //================================================================================ + /*! + * \brief Compute average size of tetrahedra araound a node + */ + //================================================================================ + + double getSizeAtNode( const SMDS_MeshNode* node ) + { + double size = 0; + int nbTet = 0; + + SMDS_VolumeTool vt; + vt.SetExternalNormal(); + + SMDS_ElemIteratorPtr volIt = node->GetInverseElementIterator(SMDSAbs_Volume); + while ( volIt->more() ) + { + const SMDS_MeshElement* vol = volIt->next(); + if ( vol->GetGeomType() != SMDSGeom_TETRA ) + continue; + double volSize = 0.; + int nbLinks = 0; + int dN = vol->IsQuadratic() ? 2 : 1; + vt.Set( vol ); + for ( int iF = 0, nbF = vt.NbFaces(); iF < nbF; ++iF ) + { + const SMDS_MeshNode** nodes = vt. GetFaceNodes( iF ); + for ( int iN = 0, nbN = vt.NbFaceNodes( iF ); iN < nbN; iN += dN ) + if ( nodes[ iN ] < nodes[ iN + dN ]) // use a link once + { + volSize += SMESH_TNodeXYZ( nodes[ iN ]).Distance( nodes[ iN + dN ]); + ++nbLinks; + } + } + size += volSize / nbLinks; + ++nbTet; + } + return nbTet > 0 ? size/nbTet : 0.; + } + + //================================================================================ + /*! + * \brief Write a mesh file and a solution file + */ + //================================================================================ + + bool writeGMFFile( MG_Tetra_API* theMGInput, + SMESH_MesherHelper* theHelper, + const std::string& theMeshFileName, + const std::string& theSolFileName ) + { + const int tag = 0; + + int mfile = theMGInput->GmfOpenMesh( theMeshFileName.c_str(), GmfWrite, GMFVERSION,GMFDIMENSION ); + int sfile = theMGInput->GmfOpenMesh( theSolFileName.c_str(), GmfWrite, GMFVERSION,GMFDIMENSION ); + if ( !mfile || !sfile ) + return false; + + // write all nodes and volume size at them + + SMESHDS_Mesh* meshDS = theHelper->GetMeshDS(); + if ( meshDS->NbNodes() != meshDS->MaxNodeID() ) + meshDS->compactMesh(); + + theMGInput->GmfSetKwd( mfile, GmfVertices, meshDS->NbNodes() ); + int TypTab[] = { GmfSca }; + theMGInput->GmfSetKwd( sfile, GmfSolAtVertices, meshDS->NbNodes(), 1, TypTab); + + SMDS_NodeIteratorPtr nodeIt = theHelper->GetMeshDS()->nodesIterator(); + while ( nodeIt->more() ) + { + const SMDS_MeshNode* node = nodeIt->next(); + theMGInput->GmfSetLin( mfile, GmfVertices, node->X(), node->Y(), node->Z(), tag ); + + double size = getSizeAtNode( node ); + theMGInput->GmfSetLin( sfile, GmfSolAtVertices, &size ); + } + + // write all triangles + + theMGInput->GmfSetKwd( mfile, GmfTriangles, meshDS->GetMeshInfo().NbTriangles() ); + SMDS_ElemIteratorPtr triaIt = meshDS->elementGeomIterator( SMDSGeom_TRIANGLE ); + while ( triaIt->more() ) + { + const SMDS_MeshElement* tria = triaIt->next(); + theMGInput->GmfSetLin( mfile, GmfTriangles, + tria->GetNode(0)->GetID(), + tria->GetNode(1)->GetID(), + tria->GetNode(2)->GetID(), + tag ); + } + + // write all tetra + + theMGInput->GmfSetKwd( mfile, GmfTetrahedra, meshDS->GetMeshInfo().NbTetras() ); + SMDS_ElemIteratorPtr tetIt = meshDS->elementGeomIterator( SMDSGeom_TETRA ); + while ( tetIt->more() ) + { + const SMDS_MeshElement* tet = tetIt->next(); + theMGInput->GmfSetLin( mfile, GmfTetrahedra, + tet->GetNode(0)->GetID(), + tet->GetNode(2)->GetID(), + tet->GetNode(1)->GetID(), + tet->GetNode(3)->GetID(), + tag ); + } + + theMGInput->GmfCloseMesh( mfile ); + theMGInput->GmfCloseMesh( sfile ); + + return true; + } + + //================================================================================ + /*! + * \brief Read optimized tetrahedra + */ + //================================================================================ + + bool readGMFFile( MG_Tetra_API* theMGOutput, + SMESH_MesherHelper* theHelper, + const std::string& theMeshFileName ) + { + int ver, dim, tag; + int inFile = theMGOutput->GmfOpenMesh( theMeshFileName.c_str(), GmfRead, &ver, &dim); + if ( !inFile ) + return false; + + SMESHDS_Mesh* meshDS = theHelper->GetMeshDS(); + + int nbNodes = theMGOutput->GmfStatKwd( inFile, GmfVertices ); + int nbTet = theMGOutput->GmfStatKwd( inFile, GmfTetrahedra ); + int nbNodesOld = meshDS->NbNodes(); + int nbTetOld = meshDS->GetMeshInfo().NbTetras(); + std::cout << "Optimization input: " + << nbNodesOld << " nodes, \t" << nbTetOld << " tetra" << std::endl; + std::cout << "Optimization output: " + << nbNodes << " nodes, \t" << nbTet << " tetra" << std::endl; + + double x,y,z; + int i1, i2, i3, i4; + theMGOutput->GmfGotoKwd( inFile, GmfVertices ); + + if ( nbNodes == nbNodesOld && nbTet == nbTetOld ) + { + // move nodes + SMDS_NodeIteratorPtr nodeIt = theHelper->GetMeshDS()->nodesIterator(); + while ( nodeIt->more() ) + { + const SMDS_MeshNode* node = nodeIt->next(); + theMGOutput->GmfGetLin( inFile, GmfVertices, &x, &y, &z, &tag ); + meshDS->MoveNode( node, x,y,z ); + } + + // update tetra + const SMDS_MeshNode* nodes[ 4 ]; + theMGOutput->GmfGotoKwd( inFile, GmfTetrahedra ); + SMDS_ElemIteratorPtr tetIt = meshDS->elementGeomIterator( SMDSGeom_TETRA ); + for ( int i = 0; i < nbTet; ++i ) + { + const SMDS_MeshElement* tet = tetIt->next(); + theMGOutput->GmfGetLin( inFile, GmfTetrahedra, &i1, &i2, &i3, &i4, &tag); + nodes[ 0 ] = meshDS->FindNode( i1 ); + nodes[ 1 ] = meshDS->FindNode( i3 ); + nodes[ 2 ] = meshDS->FindNode( i2 ); + nodes[ 3 ] = meshDS->FindNode( i4 ); + meshDS->ChangeElementNodes( tet, &nodes[0], 4 ); + } + } + else // tetra added/removed + { + // move or add nodes + for ( int iN = 1; iN <= nbNodes; ++iN ) + { + theMGOutput->GmfGetLin( inFile, GmfVertices, &x, &y, &z, &tag ); + const SMDS_MeshNode* node = meshDS->FindNode( iN ); + if ( !node ) + node = meshDS->AddNode( x,y,z ); + else + meshDS->MoveNode( node, x,y,z ); + } + + // remove tetrahedra + SMDS_ElemIteratorPtr tetIt = meshDS->elementGeomIterator( SMDSGeom_TETRA ); + while ( tetIt->more() ) + meshDS->RemoveFreeElement( tetIt->next(), /*sm=*/0 ); + + // add tetrahedra + theMGOutput->GmfGotoKwd( inFile, GmfTetrahedra ); + for ( int i = 0; i < nbTet; ++i ) + { + theMGOutput->GmfGetLin( inFile, GmfTetrahedra, &i1, &i2, &i3, &i4, &tag); + meshDS->AddVolume( meshDS->FindNode( i1 ), + meshDS->FindNode( i3 ), + meshDS->FindNode( i2 ), + meshDS->FindNode( i4 )); + } + } + + // avoid "No mesh elements assigned to a sub-shape" error + theHelper->GetMesh()->GetSubMesh( theHelper->GetSubShape() )->SetIsAlwaysComputed( true ); + + return true; + } + + void getNodeByGhsId( SMESH_Mesh& mesh, std::vector & nodeByGhsId ) + { + SMESHDS_Mesh* meshDS = mesh.GetMeshDS(); + const int nbNodes = meshDS->NbNodes(); + nodeByGhsId.resize( nbNodes + 1 ); + SMDS_NodeIteratorPtr nodeIt = meshDS->nodesIterator(); + while ( nodeIt->more() ) + { + const SMDS_MeshNode* node = nodeIt->next(); + if ( node->GetID() <= nbNodes ) + nodeByGhsId[ node->GetID() ] = node; +#ifdef _DEBUG_ + else + throw SALOME_Exception(LOCALIZED ("bad ID -- not compacted mesh")); +#endif + } + } + + void removeFile(const std::string& name) + { + SMESH_File( name ).remove(); + } +} + +//================================================================================ +/*! + * \brief Optimize an existing tetrahedral mesh + */ +//================================================================================ + +bool GHS3DPlugin_Optimizer::Compute(SMESH_Mesh& theMesh, + SMESH_MesherHelper* theHelper) +{ + if ( theMesh.NbTetras() == 0 ) + return error( COMPERR_BAD_INPUT_MESH, "No tetrahedra" ); + if ( theMesh.NbTetras( ORDER_QUADRATIC ) > 0 ) + return error( COMPERR_BAD_INPUT_MESH, "Quadratic mesh can't be optimized" ); + if ( theMesh.NbTriangles() == 0 ) + return error( COMPERR_BAD_INPUT_MESH, "2D mesh must exist around tetrahedra" ); + + std::string aGenericName = GHS3DPlugin_Hypothesis::GetFileName(_hyp); + std::string aLogFileName = aGenericName + ".log"; // log + std::string aGMFFileName = aGenericName + ".mesh"; // input GMF mesh file + std::string aSolFileName = aGenericName + ".sol"; // input size map file + std::string aResultFileName = aGenericName + "_Opt.mesh"; // out GMF mesh file + std::string aResSolFileName = aGenericName + "_Opt.sol"; // out size map file + + MG_Tetra_API mgTetra( _computeCanceled, _progress ); + + bool Ok = writeGMFFile( &mgTetra, theHelper, aGMFFileName, aSolFileName ); + + // ----------------- + // run MG-Tetra mesher + // ----------------- + + bool logInStandardOutput = _hyp ? _hyp->GetStandardOutputLog() : false; + bool removeLogOnSuccess = _hyp ? _hyp->GetRemoveLogOnSuccess() : true; + bool keepFiles = _hyp ? _hyp->GetKeepFiles() : false; + + std::string cmd = GHS3DPlugin_OptimizerHypothesis::CommandToRun( _hyp ); + + if ( mgTetra.IsExecutable() ) + { + cmd += " --in " + aGMFFileName; + cmd += " --out " + aResultFileName; + } + if ( !logInStandardOutput ) + { + mgTetra.SetLogFile( aLogFileName.c_str() ); + cmd += " 1>" + aLogFileName; // dump into file + } + std::cout << std::endl; + std::cout << "MG-Tetra execution..." << std::endl; + std::cout << cmd << std::endl; + + _computeCanceled = false; + + std::string errStr; + Ok = mgTetra.Compute( cmd, errStr ); // run + + if ( logInStandardOutput && mgTetra.IsLibrary() ) + std::cout << std::endl << mgTetra.GetLog() << std::endl; + if ( Ok ) + std::cout << std::endl << "End of MG-Tetra execution !" << std::endl; + + // -------------- + // read a result + // -------------- + Ok = Ok && readGMFFile( &mgTetra, theHelper, aResultFileName ); + + // --------------------- + // remove working files + // --------------------- + if ( Ok ) + { + if ( removeLogOnSuccess ) + removeFile( aLogFileName ); + } + if ( mgTetra.HasLog() ) + { + if( _computeCanceled ) + error( "interruption initiated by user" ); + else + { + // get problem description from the log file + std::vector nodeByGhsId; + getNodeByGhsId( theMesh, nodeByGhsId ); + _Ghs2smdsConvertor conv( nodeByGhsId, SMESH_ProxyMesh::Ptr( new SMESH_ProxyMesh( theMesh ))); + error( GHS3DPlugin_GHS3D::getErrorDescription( logInStandardOutput ? 0 : aLogFileName.c_str(), + mgTetra.GetLog(), conv, Ok )); + } + } + else { + // the log file is empty + removeFile( aLogFileName ); + INFOS( "MG-Tetra Error, " << errStr); + error(COMPERR_ALGO_FAILED, errStr); + } + + if ( !keepFiles ) + { + if ( !Ok && _computeCanceled ) + removeFile( aLogFileName ); + removeFile( aGMFFileName ); + removeFile( aSolFileName ); + removeFile( aResultFileName ); + removeFile( aResSolFileName ); + } + return Ok; +} + + +// double GHS3DPlugin_Optimizer::GetProgress() const +// { +// } diff --git a/src/GHS3DPlugin/GHS3DPlugin_Optimizer.hxx b/src/GHS3DPlugin/GHS3DPlugin_Optimizer.hxx new file mode 100644 index 0000000..94e18c5 --- /dev/null +++ b/src/GHS3DPlugin/GHS3DPlugin_Optimizer.hxx @@ -0,0 +1,60 @@ +// Copyright (C) 2004-2016 CEA/DEN, EDF R&D +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// +// File : GHS3DPlugin_Optimizer.hxx +// Created : Mon Oct 31 19:58:02 2016 + + +#ifndef __GHS3DPlugin_Optimizer_HXX__ +#define __GHS3DPlugin_Optimizer_HXX__ + +#include + +class GHS3DPlugin_OptimizerHypothesis; + +class GHS3DPlugin_Optimizer: public SMESH_3D_Algo +{ +public: + GHS3DPlugin_Optimizer(int hypId, int studyId, SMESH_Gen* gen); + + virtual bool CheckHypothesis(SMESH_Mesh& aMesh, + const TopoDS_Shape& aShape, + Hypothesis_Status& aStatus); + + virtual void CancelCompute(); + bool computeCanceled() { return _computeCanceled; } + + virtual bool Evaluate(SMESH_Mesh& aMesh, const TopoDS_Shape& aShape, + MapShapeNbElems& aResMap); + + virtual bool Compute(SMESH_Mesh& theMesh, + SMESH_MesherHelper* theHelper); + virtual bool Compute(SMESH_Mesh & aMesh, + const TopoDS_Shape & aShape); + + static const char* Name() { return "MG-Tetra Optimization"; } + + //virtual double GetProgress() const; + +private: + + const GHS3DPlugin_OptimizerHypothesis* _hyp; +}; + + +#endif diff --git a/src/GHS3DPlugin/GHS3DPlugin_OptimizerHypothesis.cxx b/src/GHS3DPlugin/GHS3DPlugin_OptimizerHypothesis.cxx new file mode 100644 index 0000000..e4e0c65 --- /dev/null +++ b/src/GHS3DPlugin/GHS3DPlugin_OptimizerHypothesis.cxx @@ -0,0 +1,203 @@ +// Copyright (C) 2004-2016 CEA/DEN, EDF R&D +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// +// File : GHS3DPlugin_OptimizerHypothesis.cxx +// Created : Tue Nov 1 17:18:38 2016 + +#include "GHS3DPlugin_OptimizerHypothesis.hxx" + +#include + +GHS3DPlugin_OptimizerHypothesis::GHS3DPlugin_OptimizerHypothesis(int hypId, + int studyId, + SMESH_Gen * gen) + :GHS3DPlugin_Hypothesis( hypId, studyId, gen ), + myOptimization( YES ), + mySplitOverConstrained( NO ), + mySmoothOffSlivers( false ), + myMaximalNumberOfThreads( 4 ), + myPThreadsMode( NONE ) +{ + _name = GetHypType(); + _param_algo_dim = 3; +} + +void GHS3DPlugin_OptimizerHypothesis::SetOptimization( Mode mode ) +{ + if ( myOptimization != mode ) + { + myOptimization = mode; + NotifySubMeshesHypothesisModification(); + } +} + +GHS3DPlugin_OptimizerHypothesis::Mode GHS3DPlugin_OptimizerHypothesis::GetOptimization() const +{ + return myOptimization; +} + +void GHS3DPlugin_OptimizerHypothesis::SetSplitOverConstrained( Mode mode ) +{ + if ( mode != mySplitOverConstrained ) + { + mySplitOverConstrained = mode; + NotifySubMeshesHypothesisModification(); + } +} + +GHS3DPlugin_OptimizerHypothesis::Mode GHS3DPlugin_OptimizerHypothesis::GetSplitOverConstrained() const +{ + return mySplitOverConstrained; +} + +void GHS3DPlugin_OptimizerHypothesis::SetSmoothOffSlivers( bool toSmooth ) +{ + if ( mySmoothOffSlivers != toSmooth ) + { + mySmoothOffSlivers = toSmooth; + NotifySubMeshesHypothesisModification(); + } +} + +bool GHS3DPlugin_OptimizerHypothesis::GetSmoothOffSlivers() const +{ + return mySmoothOffSlivers; +} + +void GHS3DPlugin_OptimizerHypothesis::SetPThreadsMode( PThreadsMode mode ) +{ + if ( myPThreadsMode != mode ) + { + myPThreadsMode = mode; + NotifySubMeshesHypothesisModification(); + } +} + +GHS3DPlugin_OptimizerHypothesis::PThreadsMode GHS3DPlugin_OptimizerHypothesis::GetPThreadsMode() const +{ + return myPThreadsMode; +} + +void GHS3DPlugin_OptimizerHypothesis::SetMaximalNumberOfThreads( int nb ) +{ + if ( myMaximalNumberOfThreads != nb ) + { + myMaximalNumberOfThreads = nb; + NotifySubMeshesHypothesisModification(); + } +} + +int GHS3DPlugin_OptimizerHypothesis::GetMaximalNumberOfThreads() const +{ + return myMaximalNumberOfThreads; +} + + +std::ostream & GHS3DPlugin_OptimizerHypothesis::SaveTo(std::ostream & save) +{ + save << " " << (int)myOptimization + << " " << (int)mySplitOverConstrained + << " " << (int)mySmoothOffSlivers + << " " << (int)myMaximalNumberOfThreads + << " " << (int)myPThreadsMode << " "; + + GHS3DPlugin_Hypothesis::SaveTo( save ); + + return save; +} + +std::istream & GHS3DPlugin_OptimizerHypothesis::LoadFrom(std::istream & load) +{ + int i; + + if ( load >> i ) + myOptimization = (Mode) i; + if ( load >> i ) + mySplitOverConstrained = (Mode) i; + if ( load >> i ) + mySmoothOffSlivers = (bool) i; + if ( load >> i ) + myMaximalNumberOfThreads = i; + if ( load >> i ) + myPThreadsMode = (PThreadsMode) i; + + GHS3DPlugin_Hypothesis::LoadFrom( load ); + return load; +} + +bool GHS3DPlugin_OptimizerHypothesis::SetParametersByMesh(const SMESH_Mesh* theMesh, + const TopoDS_Shape& theShape) +{ + return false; +} + +bool GHS3DPlugin_OptimizerHypothesis::SetParametersByDefaults(const TDefaults& theDflts, + const SMESH_Mesh* theMesh) +{ + return false; +} + +std::string GHS3DPlugin_OptimizerHypothesis::CommandToRun(const GHS3DPlugin_OptimizerHypothesis* hyp) +{ + SMESH_Comment cmd( GetExeName() ); + + if ( hyp ) + { + const char* mode[3] = { "no", "yes", "only" }; + + if ( hyp->GetOptimization() >= 0 && hyp->GetOptimization() < 3 ) + cmd << " --optimisation " << mode[ hyp->GetOptimization() ]; + + if ( hyp->myOptimizationLevel >= 0 && hyp->myOptimizationLevel < 5 ) { + const char* level[] = { "none" , "light" , "standard" , "standard+" , "strong" }; + cmd << " --optimisation_level " << level[ hyp->myOptimizationLevel ]; + } + + if ( hyp->GetSplitOverConstrained() >= 0 && hyp->GetSplitOverConstrained() < 3 ) + cmd << " --split_overconstrained_elements " << mode[ hyp->GetSplitOverConstrained() ]; + + if ( hyp->GetSmoothOffSlivers() ) + cmd << " --smooth_off_slivers yes"; + + switch ( hyp->GetPThreadsMode() ) { + case GHS3DPlugin_OptimizerHypothesis::SAFE: + cmd << " --pthreads_mode safe"; break; + case GHS3DPlugin_OptimizerHypothesis::AGGRESSIVE: + cmd << " --pthreads_mode aggressive"; break; + default:; + } + + if ( hyp->GetMaximalNumberOfThreads() > 0 ) + cmd << " --max_number_of_threads " << hyp->GetMaximalNumberOfThreads(); + + if ( !hyp->myToCreateNewNodes ) + cmd << " --no_internal_points"; + + if ( hyp->myMaximumMemory > 0 ) + cmd << " --max_memory " << hyp->myMaximumMemory; + + if ( hyp->myInitialMemory > 0 ) + cmd << " --automatic_memory " << hyp->myInitialMemory; + + cmd << " --verbose " << hyp->myVerboseLevel; + + cmd << " " << hyp->myTextOption; + } + + return cmd; +} diff --git a/src/GHS3DPlugin/GHS3DPlugin_OptimizerHypothesis.hxx b/src/GHS3DPlugin/GHS3DPlugin_OptimizerHypothesis.hxx new file mode 100644 index 0000000..4717158 --- /dev/null +++ b/src/GHS3DPlugin/GHS3DPlugin_OptimizerHypothesis.hxx @@ -0,0 +1,86 @@ +// Copyright (C) 2004-2016 CEA/DEN, EDF R&D +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// +// File : GHS3DPlugin_OptimizerHypothesis.hxx +// Created : Tue Nov 1 17:03:17 2016 + +#ifndef __GHS3DPlugin_OptimizerHypothesis_HXX__ +#define __GHS3DPlugin_OptimizerHypothesis_HXX__ + +#include "GHS3DPlugin_Hypothesis.hxx" + + +class GHS3DPlugin_OptimizerHypothesis : public GHS3DPlugin_Hypothesis +{ +public: + GHS3DPlugin_OptimizerHypothesis(int hypId, int studyId, SMESH_Gen * gen); + + // inherited params: + // 1 - create new nodes + // 2 - optimization level + // 3 - init and max memory + // 4 - work dir + // 5 - verbosity + // 6 - log to file + // 7 - keep work files + // 8 - remove log file + // 9 - advanced options + + enum PThreadsMode { SAFE, AGGRESSIVE, NONE }; + enum Mode { NO, YES, ONLY }; + + void SetOptimization( Mode isOnly ); + Mode GetOptimization() const; + + void SetSplitOverConstrained( Mode mode ); + Mode GetSplitOverConstrained() const; + + void SetSmoothOffSlivers( bool toSmooth ); + bool GetSmoothOffSlivers() const; + + void SetPThreadsMode( PThreadsMode mode ); + PThreadsMode GetPThreadsMode() const; + + void SetMaximalNumberOfThreads( int nb ); + int GetMaximalNumberOfThreads() const; + + static const char* GetHypType() { return "MG-Tetra Optimization Parameters"; } + + // Persistence + virtual std::ostream & SaveTo(std::ostream & save); + virtual std::istream & LoadFrom(std::istream & load); + + /*! + * \brief Does nothing + */ + virtual bool SetParametersByMesh(const SMESH_Mesh* theMesh, const TopoDS_Shape& theShape); + virtual bool SetParametersByDefaults(const TDefaults& dflts, const SMESH_Mesh* theMesh=0); + + static std::string CommandToRun(const GHS3DPlugin_OptimizerHypothesis* hyp); + +private: + + Mode myOptimization; // no, yes, only + Mode mySplitOverConstrained; // no, yes, only + bool mySmoothOffSlivers; + int myMaximalNumberOfThreads; + PThreadsMode myPThreadsMode; // safe, aggressive, none + +}; + +#endif diff --git a/src/GHS3DPlugin/GHS3DPlugin_OptimizerHypothesis_i.cxx b/src/GHS3DPlugin/GHS3DPlugin_OptimizerHypothesis_i.cxx new file mode 100644 index 0000000..d2b205e --- /dev/null +++ b/src/GHS3DPlugin/GHS3DPlugin_OptimizerHypothesis_i.cxx @@ -0,0 +1,145 @@ +// Copyright (C) 2004-2016 CEA/DEN, EDF R&D +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// +// File : GHS3DPlugin_OptimizerHypothesis_i.cxx +// Created : Tue Nov 1 17:46:39 2016 + +#include "GHS3DPlugin_OptimizerHypothesis_i.hxx" + +#include +#include + +#include + +GHS3DPlugin_OptimizerHypothesis_i:: +GHS3DPlugin_OptimizerHypothesis_i (PortableServer::POA_ptr thePOA, + int theStudyId, + ::SMESH_Gen* theGenImpl) + : SALOME::GenericObj_i( thePOA ), + SMESH_Hypothesis_i( thePOA ), + GHS3DPlugin_Hypothesis_i( thePOA, theStudyId, theGenImpl ) +{ + int id = myBaseImpl ? myBaseImpl->GetID() : theGenImpl->GetANewId(); + if ( myBaseImpl ) + delete myBaseImpl; + + myBaseImpl = new ::GHS3DPlugin_OptimizerHypothesis( id, theStudyId, theGenImpl ); +} + +namespace +{ + const char* dumpMode( GHS3DPlugin::Mode mode ) + { + switch( mode ) { + case GHS3DPlugin::NO: return "GHS3DPlugin.NO"; + case GHS3DPlugin::YES: return "GHS3DPlugin.YES"; + case GHS3DPlugin::ONLY: return "GHS3DPlugin.ONLY"; + default: return "GHS3DPlugin.NO"; + } + return 0; + } +} + +void GHS3DPlugin_OptimizerHypothesis_i::SetOptimization( GHS3DPlugin::Mode mode ) +{ + if ((int) GetImpl()->GetOptimization() != (int) mode ) + { + GetImpl()->SetOptimization( ::GHS3DPlugin_OptimizerHypothesis::Mode( mode )); + SMESH::TPythonDump() << _this() << ".SetOptimization( " << dumpMode( mode ) << " )"; + } +} + +GHS3DPlugin::Mode GHS3DPlugin_OptimizerHypothesis_i::GetOptimization() +{ + return GHS3DPlugin::Mode( GetImpl()->GetOptimization() ); +} + +void GHS3DPlugin_OptimizerHypothesis_i::SetSplitOverConstrained( GHS3DPlugin::Mode mode ) +{ + if ((int) GetImpl()->GetSplitOverConstrained() != (int) mode ) + { + GetImpl()->SetSplitOverConstrained((::GHS3DPlugin_OptimizerHypothesis::Mode) mode ); + SMESH::TPythonDump() << _this() << ".SetSplitOverConstrained( " << dumpMode( mode ) << " )"; + } +} + +GHS3DPlugin::Mode GHS3DPlugin_OptimizerHypothesis_i::GetSplitOverConstrained() +{ + return (GHS3DPlugin::Mode) GetImpl()->GetSplitOverConstrained(); +} + +void GHS3DPlugin_OptimizerHypothesis_i::SetSmoothOffSlivers( CORBA::Boolean toSmooth ) +{ + if ( GetImpl()->GetSmoothOffSlivers() != (bool) toSmooth ) + { + GetImpl()->SetSmoothOffSlivers((bool) toSmooth ); + SMESH::TPythonDump() << _this() << ".SetSmoothOffSlivers( " << toSmooth << " )"; + } +} + +CORBA::Boolean GHS3DPlugin_OptimizerHypothesis_i::GetSmoothOffSlivers() +{ + return GetImpl()->GetSmoothOffSlivers(); +} + +void GHS3DPlugin_OptimizerHypothesis_i::SetPThreadsMode( GHS3DPlugin::PThreadsMode mode ) +{ + if ((int) GetImpl()->GetPThreadsMode() != (int) mode ) + { + GetImpl()->SetPThreadsMode((::GHS3DPlugin_OptimizerHypothesis::PThreadsMode) mode ); + + std::string modeStr; + switch( mode ) { + case ::GHS3DPlugin_OptimizerHypothesis::SAFE: modeStr = "SAFE"; break; + case ::GHS3DPlugin_OptimizerHypothesis::AGGRESSIVE: modeStr = "AGGRESSIVE"; break; + default: modeStr = "NONE"; + } + SMESH::TPythonDump() << _this() << ".SetPThreadsMode( GHS3DPlugin." << modeStr << " )"; + } +} + +GHS3DPlugin::PThreadsMode GHS3DPlugin_OptimizerHypothesis_i::GetPThreadsMode() +{ + return (GHS3DPlugin::PThreadsMode) GetImpl()->GetPThreadsMode(); +} + +void GHS3DPlugin_OptimizerHypothesis_i::SetMaximalNumberOfThreads( CORBA::Short nb ) +{ + if ( GetImpl()->GetMaximalNumberOfThreads() != nb ) + { + GetImpl()->SetMaximalNumberOfThreads( nb ); + SMESH::TPythonDump() << _this() << ".SetMaximalNumberOfThreads( " << nb << " )"; + } +} + +CORBA::Short GHS3DPlugin_OptimizerHypothesis_i::GetMaximalNumberOfThreads() +{ + return (CORBA::Short) GetImpl()->GetMaximalNumberOfThreads(); +} + +::GHS3DPlugin_OptimizerHypothesis* GHS3DPlugin_OptimizerHypothesis_i::GetImpl() +{ + return (::GHS3DPlugin_OptimizerHypothesis*)myBaseImpl; +} + +CORBA::Boolean GHS3DPlugin_OptimizerHypothesis_i::IsDimSupported( SMESH::Dimension type ) +{ + return type == SMESH::DIM_3D; +} + + diff --git a/src/GHS3DPlugin/GHS3DPlugin_OptimizerHypothesis_i.hxx b/src/GHS3DPlugin/GHS3DPlugin_OptimizerHypothesis_i.hxx new file mode 100644 index 0000000..7cffca5 --- /dev/null +++ b/src/GHS3DPlugin/GHS3DPlugin_OptimizerHypothesis_i.hxx @@ -0,0 +1,81 @@ +// Copyright (C) 2004-2016 CEA/DEN, EDF R&D +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// +// File : GHS3DPlugin_OptimizerHypothesis_i.hxx +// Created : Tue Nov 1 17:36:05 2016 + +#ifndef __GHS3DPlugin_OptimizerHypothesis_i_HXX__ +#define __GHS3DPlugin_OptimizerHypothesis_i_HXX__ + +#include "GHS3DPlugin_Defs.hxx" + +#include +#include CORBA_SERVER_HEADER(GHS3DPlugin_Algorithm) + +#include "GHS3DPlugin_OptimizerHypothesis.hxx" +#include "GHS3DPlugin_Hypothesis_i.hxx" +#include "SMESH_Hypothesis_i.hxx" + +class SMESH_Gen; + +// GHS3DPlugin Optimization Parameters hypothesis + +class GHS3DPLUGIN_EXPORT GHS3DPlugin_OptimizerHypothesis_i: + public virtual POA_GHS3DPlugin::GHS3DPlugin_OptimizerHypothesis, + public virtual GHS3DPlugin_Hypothesis_i +{ + public: + GHS3DPlugin_OptimizerHypothesis_i (PortableServer::POA_ptr thePOA, + int theStudyId, + ::SMESH_Gen* theGenImpl); + // inherited params: + // 1 - create new nodes + // 2 - optimization level + // 3 - init and max memory + // 4 - work dir + // 5 - verbosity + // 6 - log to file + // 7 - keep work files + // 8 - remove log file + // 9 - advanced options + + void SetOptimization( GHS3DPlugin::Mode mode ); + GHS3DPlugin::Mode GetOptimization(); + + void SetSplitOverConstrained( GHS3DPlugin::Mode mode ); + GHS3DPlugin::Mode GetSplitOverConstrained(); + + void SetSmoothOffSlivers( CORBA::Boolean toSmooth ); + CORBA::Boolean GetSmoothOffSlivers(); + + void SetPThreadsMode( GHS3DPlugin::PThreadsMode mode ); + GHS3DPlugin::PThreadsMode GetPThreadsMode(); + + void SetMaximalNumberOfThreads( CORBA::Short nb ); + CORBA::Short GetMaximalNumberOfThreads(); + + + // Get implementation + ::GHS3DPlugin_OptimizerHypothesis* GetImpl(); + + // Verify whether hypothesis supports given entity type + CORBA::Boolean IsDimSupported( SMESH::Dimension type ); + +}; + +#endif diff --git a/src/GHS3DPlugin/GHS3DPlugin_i.cxx b/src/GHS3DPlugin/GHS3DPlugin_i.cxx index a81254a..2e71020 100644 --- a/src/GHS3DPlugin/GHS3DPlugin_i.cxx +++ b/src/GHS3DPlugin/GHS3DPlugin_i.cxx @@ -17,18 +17,11 @@ // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // -// SMESH GHS3DPlugin : implementaion of SMESH idl descriptions -// File : GHS3DPlugin.cxx -// Author : Julia DOROVSKIKH -// Module : SMESH -// $Header$ -// #include "SMESH_Hypothesis_i.hxx" -#include "utilities.h" - #include "GHS3DPlugin_GHS3D_i.hxx" #include "GHS3DPlugin_Hypothesis_i.hxx" +#include "GHS3DPlugin_OptimizerHypothesis_i.hxx" template class GHS3DPlugin_Creator_i:public HypothesisCreator_i { @@ -49,21 +42,23 @@ extern "C" GHS3DPLUGIN_EXPORT GenericHypothesisCreator_i* GetHypothesisCreator (const char* aHypName) { - MESSAGE("GetHypothesisCreator " << aHypName); - GenericHypothesisCreator_i* aCreator = 0; - // Hypotheses - // Algorithm if (strcmp(aHypName, "GHS3D_3D") == 0 || strcmp(aHypName, "MG-Tetra") == 0) aCreator = new GHS3DPlugin_Creator_i; + + else if (strcmp(aHypName, "MG-Tetra Optimization") == 0) + aCreator = new GHS3DPlugin_Creator_i; + // Hypothesis else if (strcmp(aHypName, "GHS3D_Parameters") == 0 || strcmp(aHypName, "MG-Tetra Parameters") == 0) aCreator = new GHS3DPlugin_Creator_i; - else ; + + else if (strcmp(aHypName, "MG-Tetra Optimization Parameters") == 0) + aCreator = new GHS3DPlugin_Creator_i; return aCreator; } diff --git a/src/GHS3DPlugin/MG_Tetra_API.cxx b/src/GHS3DPlugin/MG_Tetra_API.cxx index 6467765..5709912 100644 --- a/src/GHS3DPlugin/MG_Tetra_API.cxx +++ b/src/GHS3DPlugin/MG_Tetra_API.cxx @@ -53,16 +53,18 @@ struct MG_Tetra_API::LibData int _nbRequiredEdges; std::vector _triaNodes; int _nbRequiredTria; + std::vector _tetraNodes; int _count; volatile bool& _cancelled_flag; std::string _errorStr; double& _progress; + bool _progressInCallBack; LibData( volatile bool & cancelled_flag, double& progress ) : _context(0), _session(0), _tria_mesh(0), _sizemap(0), _tetra_mesh(0), _nbRequiredEdges(0), _nbRequiredTria(0), - _cancelled_flag( cancelled_flag ), _progress( progress ) + _cancelled_flag( cancelled_flag ), _progress( progress ), _progressInCallBack( false ) { } // methods setting callbacks implemented after callback definitions @@ -329,6 +331,11 @@ struct MG_Tetra_API::LibData _triaNodes.reserve( nb * 3 ); } + void SetNbTetra( int nb ) + { + _tetraNodes.reserve( nb * 4 ); + } + void SetNbReqVertices( int nb ) { _nodeSize.reserve( nb ); @@ -369,6 +376,14 @@ struct MG_Tetra_API::LibData _triaNodes.push_back( node3 ); } + void AddTetraNodes( int node1, int node2, int node3, int node4, int domain ) + { + _tetraNodes.push_back( node1 ); + _tetraNodes.push_back( node2 ); + _tetraNodes.push_back( node3 ); + _tetraNodes.push_back( node4 ); + } + int NbNodes() { return _xyz.size() / 3; @@ -394,11 +409,21 @@ struct MG_Tetra_API::LibData return _triaNodes.size() / 3; } + int NbTetra() + { + return _tetraNodes.size() / 4; + } + int * GetTriaNodes( int iTria ) { return & _triaNodes[ iTria * 3 ]; } + int * GetTetraNodes( int iTet ) + { + return & _tetraNodes[ iTet * 4 ]; + } + int IsVertexRequired( int iNode ) { return ! ( iNode < int( NbNodes() - _nodeSize.size() )); @@ -485,26 +510,25 @@ namespace // functions called by MG library to exchange with the application // return STATUS_OK; // } - // status_t get_tetrahedron_count(integer * nbtetra, void *user_data) - // { - // MG_Tetra_API::LibData* data = (MG_Tetra_API::LibData *) user_data; - - // *nbtetra = 0; /* the number of tetra in your input mesh (0 if you describe a surface mesh) */ - - // return STATUS_OK; - // } + status_t get_tetrahedron_count(integer * nbtetra, void *user_data) + { + MG_Tetra_API::LibData* data = (MG_Tetra_API::LibData *) user_data; + *nbtetra = data->NbTetra(); - // status_t get_tetrahedron_vertices(integer itetra, integer * vtetra, - // void *user_data) - // { - // int j; - // MG_Tetra_API::LibData* data = (MG_Tetra_API::LibData *) user_data; + return STATUS_OK; + } - // for (j = 0; j < 4; j++) - // vtetra[j] = 0; /* the j'th vertex index of the itetra'th tetrahedron */ + status_t get_tetrahedron_vertices(integer itetra, integer * vtetra, + void *user_data) + { + int j; + MG_Tetra_API::LibData* data = (MG_Tetra_API::LibData *) user_data; + int* nodes = data->GetTetraNodes( itetra-1 ); + for (j = 0; j < 4; j++) + vtetra[j] = nodes[j]; - // return STATUS_OK; - // } + return STATUS_OK; + } status_t get_vertex_required_property(integer ivtx, integer * rvtx, void *user_data) { @@ -534,26 +558,37 @@ namespace // functions called by MG library to exchange with the application //std::cout << desc << std::endl; #endif - // Compute progress - // corresponding messages are: - // " -- PHASE 1 COMPLETED" => 10 % - // " -- PHASE 2 COMPLETED" => 25 % - // " ** ITERATION 1" => 25.* % - // " ** ITERATION 2" => 25.* % - // " -- PHASE 3 COMPLETED" => 70 % - // " -- PHASE 4 COMPLETED" => 98 % - - if ( strncmp( "-- PHASE ", desc + 2, 9 ) == 0 && desc[ 13 ] == 'C' ) + if ( strncmp( "MGMESSAGE 1009001 ", desc, 19 ) == 0 ) { - const double progress[] = { 10., 25., 70., 98., 100., 100., 100. }; - int phase = atoi( desc + 11 ); - data->_progress = std::max( data->_progress, progress[ phase - 1 ] / 100. ); + // progress message (10%): "MGMESSAGE 1009001 0 1 1.000000e+01" + data->_progress = atof( desc + 24 ); + + _progressInCallBack = true; } - else if ( strncmp( "** ITERATION ", desc + 5, 13 ) == 0 ) + + if ( !_progressInCallBack ) { - int iter = atoi( desc + 20 ); - double percent = 25. + iter * ( 70 - 25 ) / 20.; - data->_progress = std::max( data->_progress, ( percent / 100. )); + // Compute progress + // corresponding messages are: + // " -- PHASE 1 COMPLETED" => 10 % + // " -- PHASE 2 COMPLETED" => 25 % + // " ** ITERATION 1" => 25.* % + // " ** ITERATION 2" => 25.* % + // " -- PHASE 3 COMPLETED" => 70 % + // " -- PHASE 4 COMPLETED" => 98 % + + if ( strncmp( "-- PHASE ", desc + 2, 9 ) == 0 && desc[ 13 ] == 'C' ) + { + const double progress[] = { 10., 25., 70., 98., 100., 100., 100. }; + int phase = atoi( desc + 11 ); + data->_progress = std::max( data->_progress, progress[ phase - 1 ] / 100. ); + } + else if ( strncmp( "** ITERATION ", desc + 5, 13 ) == 0 ) + { + int iter = atoi( desc + 20 ); + double percent = 25. + iter * ( 70 - 25 ) / 20.; + data->_progress = std::max( data->_progress, ( percent / 100. )); + } } return STATUS_OK; @@ -595,6 +630,8 @@ void MG_Tetra_API::LibData::Init() mesh_set_get_edge_vertices( _tria_mesh, get_edge_vertices, this ); mesh_set_get_triangle_count( _tria_mesh, get_triangle_count, this ); mesh_set_get_triangle_vertices( _tria_mesh, get_triangle_vertices, this ); + mesh_set_get_tetrahedron_count( _tria_mesh, get_tetrahedron_count, this ); + mesh_set_get_tetrahedron_vertices( _tria_mesh, get_tetrahedron_vertices, this ); // Create a tetra session _session = tetra_session_new( _context ); @@ -607,9 +644,19 @@ void MG_Tetra_API::LibData::Init() bool MG_Tetra_API::LibData::Compute() { - // Set surface mesh - status_t ret = tetra_set_surface_mesh( _session, _tria_mesh ); - if ( ret != STATUS_OK ) MG_Error( "unable to set surface mesh"); + status_t ret; + + if ( _tetraNodes.empty() ) + { + // Set surface mesh + ret = tetra_set_surface_mesh( _session, _tria_mesh ); + if ( ret != STATUS_OK ) MG_Error( "unable to set surface mesh"); + } + else + { + ret = tetra_set_volume_mesh( _session, _tria_mesh ); + if ( ret != STATUS_OK ) MG_Error( "unable to set volume mesh"); + } // Set a sizemap if ( !_nodeSize.empty() ) @@ -1136,6 +1183,24 @@ void MG_Tetra_API::GmfSetLin(int iMesh, GmfKwdCod what, int node1, int node2, in ::GmfSetLin(iMesh, what, node1, node2, node3, domain ); } +//================================================================================ +/*! + * \brief Add tetra nodes + */ +//================================================================================ + +void MG_Tetra_API::GmfSetLin(int iMesh, GmfKwdCod what, + int node1, int node2, int node3, int node4, int domain ) +{ + if ( _useLib ) { +#ifdef USE_MG_LIBS + _libData->AddTetraNodes( node1, node2, node3, node4, domain ); + return; +#endif + } + ::GmfSetLin(iMesh, what, node1, node2, node3, node4, domain ); +} + //================================================================================ /*! * \brief Close a file diff --git a/src/GHS3DPlugin/MG_Tetra_API.hxx b/src/GHS3DPlugin/MG_Tetra_API.hxx index ee4ad30..e5f0db4 100644 --- a/src/GHS3DPlugin/MG_Tetra_API.hxx +++ b/src/GHS3DPlugin/MG_Tetra_API.hxx @@ -51,6 +51,7 @@ public: void GmfSetLin(int iMesh, GmfKwdCod what, int node1, int node2, int domain ); // edge void GmfSetLin(int iMesh, GmfKwdCod what, int id ); // required void GmfSetLin(int iMesh, GmfKwdCod what, int node1, int node2, int node3, int domain ); // tria + void GmfSetLin(int iMesh, GmfKwdCod what, int node1, int node2, int node3, int node4, int domain ); // tetra bool Compute( const std::string& cmdLine, std::string& errStr ); diff --git a/src/GUI/GHS3DPluginGUI.cxx b/src/GUI/GHS3DPluginGUI.cxx index dc0b278..86ed21c 100644 --- a/src/GUI/GHS3DPluginGUI.cxx +++ b/src/GUI/GHS3DPluginGUI.cxx @@ -36,7 +36,8 @@ extern "C" { SMESHGUI_GenericHypothesisCreator* aCreator = NULL; if ( aHypType == "GHS3D_Parameters" || - aHypType == "MG-Tetra Parameters" ) + aHypType == "MG-Tetra Parameters" || + aHypType == "MG-Tetra Optimization Parameters" ) aCreator = new GHS3DPluginGUI_HypothesisCreator( aHypType ); return aCreator; } diff --git a/src/GUI/GHS3DPluginGUI_HypothesisCreator.cxx b/src/GUI/GHS3DPluginGUI_HypothesisCreator.cxx index f66769e..a13234c 100644 --- a/src/GUI/GHS3DPluginGUI_HypothesisCreator.cxx +++ b/src/GUI/GHS3DPluginGUI_HypothesisCreator.cxx @@ -25,6 +25,7 @@ #include "GHS3DPluginGUI_HypothesisCreator.h" #include "GHS3DPluginGUI_Enums.h" #include "GHS3DPluginGUI_Dlg.h" +#include "GHS3DPlugin_OptimizerHypothesis.hxx" #include @@ -36,50 +37,67 @@ #include #include -#include +#include #include #include -#include +#include +#include #include #include -#include - +#include #include -#include -#include +#include #include -#include #include +#include +#include +#include #include -#include -#include -#include +#include #include -#include -#include - +#include +#include #include #include -#include +#include #include #include -#include +namespace +{ + QComboBox* getModeCombo( QWidget* parent, bool isPThreadCombo ) + { + QComboBox* combo = new QComboBox( parent ); + if ( isPThreadCombo ) + { + combo->insertItem((int) GHS3DPlugin_OptimizerHypothesis::SAFE, QObject::tr("MODE_SAFE")); + combo->insertItem((int) GHS3DPlugin_OptimizerHypothesis::AGGRESSIVE, QObject::tr("MODE_AGGRESSIVE")); + combo->insertItem((int) GHS3DPlugin_OptimizerHypothesis::NONE, QObject::tr("MODE_NONE")); + } + else + { + combo->insertItem((int) GHS3DPlugin_OptimizerHypothesis::NO, QObject::tr("MODE_NO")); + combo->insertItem((int) GHS3DPlugin_OptimizerHypothesis::YES, QObject::tr("MODE_YES")); + combo->insertItem((int) GHS3DPlugin_OptimizerHypothesis::ONLY, QObject::tr("MODE_ONLY")); + } + return combo; + } +} // // BEGIN EnforcedVertexTableWidgetDelegate // EnforcedVertexTableWidgetDelegate::EnforcedVertexTableWidgetDelegate(QObject *parent) - : QItemDelegate(parent) + : QItemDelegate(parent) { } QWidget *EnforcedVertexTableWidgetDelegate::createEditor(QWidget *parent, - const QStyleOptionViewItem & option , - const QModelIndex & index ) const + const QStyleOptionViewItem & option , + const QModelIndex & index ) const { QModelIndex father = index.parent(); QString entry = father.child(index.row(), ENF_VER_ENTRY_COLUMN).data().toString(); @@ -97,14 +115,9 @@ QWidget *EnforcedVertexTableWidgetDelegate::createEditor(QWidget *parent, editor->setDisabled(!entry.isEmpty()); return editor; } -// else if (index.column() == ENF_VER_COMPOUND_COLUMN) { -// QCheckBox *editor = new QCheckBox(parent); -// editor->setDisabled(!entry.isEmpty()); -// return editor; -// } else if (index.column() == ENF_VER_GROUP_COLUMN || index.column() == ENF_VER_NAME_COLUMN) { -// else { + // else { QLineEdit *editor = new QLineEdit(parent); if (index.column() != ENF_VER_GROUP_COLUMN) { editor->setReadOnly(!entry.isEmpty()); @@ -116,7 +129,7 @@ QWidget *EnforcedVertexTableWidgetDelegate::createEditor(QWidget *parent, } void EnforcedVertexTableWidgetDelegate::setEditorData(QWidget *editor, - const QModelIndex &index) const + const QModelIndex &index) const { if (index.column() == ENF_VER_X_COLUMN || index.column() == ENF_VER_Y_COLUMN || @@ -136,7 +149,7 @@ void EnforcedVertexTableWidgetDelegate::setEditorData(QWidget *editor, } void EnforcedVertexTableWidgetDelegate::setModelData(QWidget *editor, QAbstractItemModel *model, - const QModelIndex &index) const + const QModelIndex &index) const { QModelIndex parent = index.parent(); @@ -179,14 +192,15 @@ void EnforcedVertexTableWidgetDelegate::setModelData(QWidget *editor, QAbstractI } void EnforcedVertexTableWidgetDelegate::updateEditorGeometry(QWidget *editor, - const QStyleOptionViewItem &option, const QModelIndex &/* index */) const + const QStyleOptionViewItem &option, + const QModelIndex &/* index */) const { - editor->setGeometry(option.rect); + editor->setGeometry(option.rect); } bool EnforcedVertexTableWidgetDelegate::vertexExists(QAbstractItemModel *model, - const QModelIndex &index, - QString value) const + const QModelIndex &index, + QString value) const { bool exists = false; QModelIndex parent = index.parent(); @@ -243,61 +257,51 @@ bool EnforcedVertexTableWidgetDelegate::vertexExists(QAbstractItemModel *model, // EnforcedMeshTableWidgetDelegate::EnforcedMeshTableWidgetDelegate(QObject *parent) - : QItemDelegate(parent) + : QItemDelegate(parent) { } QWidget *EnforcedMeshTableWidgetDelegate::createEditor(QWidget *parent, - const QStyleOptionViewItem & option , - const QModelIndex & index ) const + const QStyleOptionViewItem & option , + const QModelIndex & index ) const { return QItemDelegate::createEditor(parent, option, index); } void EnforcedMeshTableWidgetDelegate::setEditorData(QWidget *editor, - const QModelIndex &index) const + const QModelIndex &index) const { - QItemDelegate::setEditorData(editor, index); + QItemDelegate::setEditorData(editor, index); } void EnforcedMeshTableWidgetDelegate::setModelData(QWidget *editor, QAbstractItemModel *model, - const QModelIndex &index) const + const QModelIndex &index) const { QItemDelegate::setModelData(editor, model, index); } void EnforcedMeshTableWidgetDelegate::updateEditorGeometry(QWidget *editor, - const QStyleOptionViewItem &option, const QModelIndex &/* index */) const + const QStyleOptionViewItem &option, + const QModelIndex &/* index */) const { - editor->setGeometry(option.rect); + editor->setGeometry(option.rect); } -// bool EnforcedMeshTableWidgetDelegate::enfMeshExists(QAbstractItemModel *model, -// const QModelIndex &index, -// QString value) const -// { -// bool exists = false; -// QModelIndex parent = index.parent(); -// int row = index.row(); -// int col = index.column(); -// return exists; -// } - // // END EnforcedMeshTableWidgetDelegate // GHS3DPluginGUI_HypothesisCreator::GHS3DPluginGUI_HypothesisCreator( const QString& theHypType ) -: SMESHGUI_GenericHypothesisCreator( theHypType ) + : SMESHGUI_GenericHypothesisCreator( theHypType ) { GeomToolSelected = NULL; GeomToolSelected = getGeomSelectionTool(); iconVertex = QPixmap(SUIT_Session::session()->resourceMgr()->loadPixmap("GEOM", tr("ICON_OBJBROWSER_VERTEX"))); iconCompound = QPixmap(SUIT_Session::session()->resourceMgr()->loadPixmap("GEOM", tr("ICON_OBJBROWSER_COMPOUND"))); -// mySelectionMgr = SMESH::GetSelectionMgr(SMESHGUI::GetSMESHGUI()); + // mySelectionMgr = SMESH::GetSelectionMgr(SMESHGUI::GetSMESHGUI()); myEnfMeshConstraintLabels << tr( "GHS3D_ENF_MESH_CONSTRAINT_NODE" ) << tr( "GHS3D_ENF_MESH_CONSTRAINT_EDGE" ) << tr("GHS3D_ENF_MESH_CONSTRAINT_FACE"); } @@ -326,6 +330,11 @@ GEOM::GEOM_Gen_var GHS3DPluginGUI_HypothesisCreator::getGeomEngine() return GeometryGUI::GetGeomGen(); } +bool GHS3DPluginGUI_HypothesisCreator::isOptimization() const +{ + return ( hypType() == GHS3DPlugin_OptimizerHypothesis::GetHypType() ); +} + QFrame* GHS3DPluginGUI_HypothesisCreator::buildFrame() { QFrame* fr = new QFrame( 0 ); @@ -347,7 +356,7 @@ QFrame* GHS3DPluginGUI_HypothesisCreator::buildFrame() int row = 0; myName = 0; - if( isCreation() ) + if ( isCreation() ) { aStdLayout->addWidget( new QLabel( tr( "SMESH_NAME" ), myStdGroup ), row, 0, 1, 1 ); myName = new QLineEdit( myStdGroup ); @@ -359,16 +368,61 @@ QFrame* GHS3DPluginGUI_HypothesisCreator::buildFrame() myToMakeGroupsOfDomains = new QCheckBox( tr( "GHS3D_TO_MAKE_DOMAIN_GROUPS" ), myStdGroup ); aStdLayout->addWidget( myToMakeGroupsOfDomains, row++, 1, 1, 1 ); - aStdLayout->addWidget( new QLabel( tr( "GHS3D_OPTIMIZATIOL_LEVEL" ), myStdGroup ), row, 0, 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 ); - QStringList types; - types << tr( "LEVEL_NONE" ) << tr( "LEVEL_LIGHT" ) << tr( "LEVEL_MEDIUM" ) << tr( "LEVEL_STANDARDPLUS" ) << tr( "LEVEL_STRONG" ); - myOptimizationLevelCombo->addItems( types ); - + 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(); + } + else + { + optimizationLbl->hide(); + myOptimizationCombo->hide(); + splitOverconstrainedLbl->hide(); + mySplitOverConstrainedCombo->hide(); + pthreadsModeLbl->hide(); + myPThreadsModeCombo->hide(); + nbThreadsLbl->hide(); + myNumberOfThreadsSpin->hide(); + mySmoothOffSliversCheck->hide(); + myCreateNewNodesCheck->hide(); + } + // advanced parameters myAdvGroup = new QWidget(); QGridLayout* anAdvLayout = new QGridLayout( myAdvGroup ); @@ -388,7 +442,7 @@ QFrame* GHS3DPluginGUI_HypothesisCreator::buildFrame() myAdvWidget->initialMemoryLabel ->setText (tr( "MEGABYTE" )); myAdvWidget->maxMemoryLabel ->setText (tr( "MEGABYTE" )); - + myAdvWidget->workingDirectoryLabel ->setText (tr( "WORKING_DIR" )); myAdvWidget->workingDirectoryPushButton ->setText (tr( "SELECT_DIR" )); myAdvWidget->keepWorkingFilesCheck ->setText (tr( "KEEP_WORKING_FILES" )); @@ -407,6 +461,16 @@ QFrame* GHS3DPluginGUI_HypothesisCreator::buildFrame() 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(); QGridLayout* anEnfLayout = new QGridLayout(myEnfGroup); @@ -416,12 +480,12 @@ QFrame* GHS3DPluginGUI_HypothesisCreator::buildFrame() myEnforcedTableWidget->setRowCount( 0 ); myEnforcedTableWidget->setColumnCount( ENF_VER_NB_COLUMNS ); myEnforcedTableWidget->setSortingEnabled(true); - QStringList enforcedHeaders; - enforcedHeaders << tr( "GHS3D_ENF_NAME_COLUMN" ) - << tr( "GHS3D_ENF_VER_X_COLUMN" )<< tr( "GHS3D_ENF_VER_Y_COLUMN" ) << tr( "GHS3D_ENF_VER_Z_COLUMN" ) - << tr( "GHS3D_ENF_SIZE_COLUMN" ) << tr("GHS3D_ENF_ENTRY_COLUMN") << tr("GHS3D_ENF_VER_COMPOUND_COLUMN") << tr( "GHS3D_ENF_GROUP_COLUMN" ); - - myEnforcedTableWidget->setHorizontalHeaderLabels(enforcedHeaders); + myEnforcedTableWidget->setHorizontalHeaderLabels + ( QStringList() + << tr( "GHS3D_ENF_NAME_COLUMN" ) << tr( "GHS3D_ENF_VER_X_COLUMN" ) + << tr( "GHS3D_ENF_VER_Y_COLUMN" ) << tr( "GHS3D_ENF_VER_Z_COLUMN" ) + << tr( "GHS3D_ENF_SIZE_COLUMN" ) << tr("GHS3D_ENF_ENTRY_COLUMN") + << tr("GHS3D_ENF_VER_COMPOUND_COLUMN") << tr( "GHS3D_ENF_GROUP_COLUMN" )); myEnforcedTableWidget->verticalHeader()->hide(); myEnforcedTableWidget->horizontalHeader()->setStretchLastSection(true); myEnforcedTableWidget->setAlternatingRowColors(true); @@ -438,7 +502,7 @@ QFrame* GHS3DPluginGUI_HypothesisCreator::buildFrame() myEnforcedTableWidget->setItemDelegate(new EnforcedVertexTableWidgetDelegate()); -// VERTEX SELECTION + // VERTEX SELECTION TColStd_MapOfInteger shapeTypes; shapeTypes.Add( TopAbs_VERTEX ); shapeTypes.Add( TopAbs_COMPOUND ); @@ -466,20 +530,7 @@ QFrame* GHS3DPluginGUI_HypothesisCreator::buildFrame() addVertexButton = new QPushButton(tr("GHS3D_ENF_ADD"),myEnfGroup); addVertexButton->setEnabled(false); removeVertexButton = new QPushButton(tr("GHS3D_ENF_REMOVE"),myEnfGroup); -// myGlobalGroupName = new QCheckBox(tr("GHS3D_ENF_VER_GROUPS"), myEnfGroup); -// myGlobalGroupName->setChecked(false); - - // QGroupBox* GroupBox = new QGroupBox( myEnfGroup ); - // QLabel* info = new QLabel( GroupBox ); - // info->setText( tr( "GHS3D_ENF_VER_INFO" ) ); - // info->setWordWrap( true ); - // QVBoxLayout* GroupBoxVLayout = new QVBoxLayout( GroupBox ); - // GroupBoxVLayout->setSpacing( 6 ); - // GroupBoxVLayout->setMargin( 11 ); - // GroupBoxVLayout->addWidget( info ); - - //anEnfLayout->addWidget(GroupBox, ENF_VER_WARNING, 0, 1, 2 ); anEnfLayout->addWidget(myEnforcedTableWidget, ENF_VER_VERTEX, 0, ENF_VER_NB_LINES, 1); QGridLayout* anEnfLayout2 = new QGridLayout(myEnfGroup); @@ -531,9 +582,6 @@ QFrame* GHS3DPluginGUI_HypothesisCreator::buildFrame() myEnforcedMeshTableWidget->setItemDelegate(new EnforcedMeshTableWidgetDelegate()); -// myEnfMesh = SMESH::SMESH_Mesh::_nil(); -// myEnfMeshArray = new SMESH::mesh_array(); - myEnfMeshWdg = new StdMeshersGUI_ObjectReferenceParamWdg( SMESH::IDSOURCE, myEnfMeshGroup, /*multiSel=*/true); myEnfMeshWdg->SetDefaultText(tr("GHS3D_ENF_SELECT_MESH"), "QLineEdit { color: grey }"); @@ -549,19 +597,8 @@ QFrame* GHS3DPluginGUI_HypothesisCreator::buildFrame() myMeshGroupName = new QLineEdit(myEnfMeshGroup); addEnfMeshButton = new QPushButton(tr("GHS3D_ENF_ADD"),myEnfMeshGroup); -// addEnfMeshButton->setEnabled(false); removeEnfMeshButton = new QPushButton(tr("GHS3D_ENF_REMOVE"),myEnfMeshGroup); - - // QGroupBox* GroupBox2 = new QGroupBox( myEnfMeshGroup ); - // QLabel* info2 = new QLabel( GroupBox2 ); - // info2->setText( tr( "GHS3D_ENF_MESH_INFO" ) ); - // info2->setWordWrap( true ); - // QVBoxLayout* GroupBox2VLayout = new QVBoxLayout( GroupBox2 ); - // GroupBox2VLayout->setSpacing( 6 ); - // GroupBox2VLayout->setMargin( 11 ); - // GroupBox2VLayout->addWidget( info2 ); - // anEnfMeshLayout->addWidget( GroupBox2, ENF_MESH_WARNING, 0, 1, 2 ); anEnfMeshLayout->addWidget(myEnforcedMeshTableWidget, ENF_MESH_MESH, 0, ENF_MESH_NB_LINES , 1); QGridLayout* anEnfMeshLayout2 = new QGridLayout(myEnfMeshGroup); @@ -580,12 +617,13 @@ QFrame* GHS3DPluginGUI_HypothesisCreator::buildFrame() // add tabs tab->insertTab( STD_TAB, myStdGroup, tr( "SMESH_ARGUMENTS" ) ); tab->insertTab( ADV_TAB, myAdvGroup, tr( "GHS3D_ADV_ARGS" ) ); - tab->insertTab( ENF_VER_TAB, myEnfGroup, tr( "GHS3D_ENFORCED_VERTICES" ) ); - tab->insertTab( ENF_MESH_TAB, myEnfMeshGroup, tr( "GHS3D_ENFORCED_MESHES" ) ); + if ( !isOptimization() ) + { + tab->insertTab( ENF_VER_TAB, myEnfGroup, tr( "GHS3D_ENFORCED_VERTICES" ) ); + tab->insertTab( ENF_MESH_TAB, myEnfMeshGroup, tr( "GHS3D_ENFORCED_MESHES" ) ); + } tab->setCurrentIndex( STD_TAB ); - // connections - //connect( myToMeshHolesCheck, SIGNAL( toggled( bool ) ), this, SLOT( onToMeshHoles(bool))); connect( myAdvWidget->maxMemoryCheck, SIGNAL( toggled( bool ) ), this, SLOT( updateWidgets() ) ); connect( myAdvWidget->initialMemoryCheck, SIGNAL( toggled( bool ) ), this, SLOT( updateWidgets() ) ); connect( myAdvWidget->boundaryRecoveryCheck, SIGNAL( toggled( bool ) ), this, SLOT( updateWidgets() ) ); @@ -612,16 +650,13 @@ QFrame* GHS3DPluginGUI_HypothesisCreator::buildFrame() connect( addEnfMeshButton, SIGNAL( clicked()), this, SLOT( onAddEnforcedMesh() ) ); connect( removeEnfMeshButton, SIGNAL( clicked()), this, SLOT( onRemoveEnforcedMesh() ) ); -// connect( myEnfMeshWdg, SIGNAL( contentModified()), this, SLOT( checkEnfMeshIsDefined() ) ); -// connect( myEnfMeshConstraint, SIGNAL( currentIndexChanged(int) ), this, SLOT( checkEnfMeshIsDefined() ) ); -// connect( this, SIGNAL( enfMeshDefined(bool) ), addEnfMeshButton, SLOT( setEnabled(bool) ) ); return fr; } /** * This method checks if an enforced vertex is defined; -**/ + **/ void GHS3DPluginGUI_HypothesisCreator::clearEnfVertexSelection() { if (myEnfVertexWdg->NbObjects() != 0) { @@ -637,21 +672,21 @@ void GHS3DPluginGUI_HypothesisCreator::clearEnfVertexSelection() /** * This method checks if an enforced vertex is defined; -**/ + **/ void GHS3DPluginGUI_HypothesisCreator::checkVertexIsDefined() { bool enfVertexIsDefined = false; enfVertexIsDefined = (!mySizeValue->GetString().isEmpty() && - (!myEnfVertexWdg->NbObjects() == 0 || - (myEnfVertexWdg->NbObjects() == 0 && !myXCoord->GetString().isEmpty() - && !myYCoord->GetString().isEmpty() - && !myZCoord->GetString().isEmpty()))); + (!myEnfVertexWdg->NbObjects() == 0 || + (myEnfVertexWdg->NbObjects() == 0 && !myXCoord->GetString().isEmpty() + && !myYCoord->GetString().isEmpty() + && !myZCoord->GetString().isEmpty()))); emit vertexDefined(enfVertexIsDefined); } /** * This method checks if an enforced mesh is defined; -**/ + **/ void GHS3DPluginGUI_HypothesisCreator::checkEnfMeshIsDefined() { emit enfMeshDefined( myEnfVertexWdg->NbObjects() != 0); @@ -659,27 +694,24 @@ void GHS3DPluginGUI_HypothesisCreator::checkEnfMeshIsDefined() /** * This method resets the content of the X, Y, Z, size and GroupName widgets; -**/ + **/ void GHS3DPluginGUI_HypothesisCreator::clearEnforcedVertexWidgets() { myXCoord->setCleared(true); myYCoord->setCleared(true); myZCoord->setCleared(true); -// mySizeValue->setCleared(true); myXCoord->setText(""); myYCoord->setText(""); myZCoord->setText(""); -// mySizeValue->setText(""); -// myGroupName->setText(""); addVertexButton->setEnabled(false); } /** GHS3DPluginGUI_HypothesisCreator::updateEnforcedVertexValues(item) -This method updates the tooltip of a modified item. The QLineEdit widgets content -is synchronized with the coordinates of the enforced vertex clicked in the tree widget. + This method updates the tooltip of a modified item. The QLineEdit widgets content + is synchronized with the coordinates of the enforced vertex clicked in the tree widget. */ -void GHS3DPluginGUI_HypothesisCreator::updateEnforcedVertexValues(QTableWidgetItem* item) { -// MESSAGE("GHS3DPluginGUI_HypothesisCreator::updateEnforcedVertexValues"); +void GHS3DPluginGUI_HypothesisCreator::updateEnforcedVertexValues(QTableWidgetItem* item) +{ int row = myEnforcedTableWidget->row(item); QVariant vertexName = myEnforcedTableWidget->item(row,ENF_VER_NAME_COLUMN)->data(Qt::EditRole); @@ -710,7 +742,6 @@ void GHS3DPluginGUI_HypothesisCreator::updateEnforcedVertexValues(QTableWidgetIt if (!groupName.isEmpty()) toolTip += QString(" [") + groupName + QString("]"); -// MESSAGE("Tooltip: " << toolTip.toStdString()); for (int col=0;colitem(row,col)->setToolTip(toolTip); @@ -733,13 +764,14 @@ void GHS3DPluginGUI_HypothesisCreator::updateEnforcedVertexValues(QTableWidgetIt } } -void GHS3DPluginGUI_HypothesisCreator::onSelectEnforcedVertex() { +void GHS3DPluginGUI_HypothesisCreator::onSelectEnforcedVertex() +{ int nbSelEnfVertex = myEnfVertexWdg->NbObjects(); clearEnforcedVertexWidgets(); if (nbSelEnfVertex == 1) { if ( CORBA::is_nil( getGeomEngine() ) && !GeometryGUI::InitGeomGen() ) - return ; + return ; myEnfVertex = myEnfVertexWdg->GetObject< GEOM::GEOM_Object >(nbSelEnfVertex-1); if (myEnfVertex == GEOM::GEOM_Object::_nil()) @@ -769,13 +801,13 @@ void GHS3DPluginGUI_HypothesisCreator::onSelectEnforcedVertex() { } /** GHS3DPluginGUI_HypothesisCreator::synchronizeCoords() -This method synchronizes the QLineEdit/SMESHGUI_SpinBox widgets content with the coordinates -of the enforced vertex clicked in the tree widget. + This method synchronizes the QLineEdit/SMESHGUI_SpinBox widgets content with the coordinates + of the enforced vertex clicked in the tree widget. */ -void GHS3DPluginGUI_HypothesisCreator::synchronizeCoords() { +void GHS3DPluginGUI_HypothesisCreator::synchronizeCoords() +{ clearEnforcedVertexWidgets(); QList items = myEnforcedTableWidget->selectedItems(); -// myEnfVertexWdg->disconnect(SIGNAL(contentModified())); disconnect( myEnfVertexWdg, SIGNAL( contentModified()), this, SLOT( onSelectEnforcedVertex() ) ); if (! items.isEmpty()) { QTableWidgetItem *item; @@ -800,7 +832,7 @@ void GHS3DPluginGUI_HypothesisCreator::synchronizeCoords() { } QVariant group = myEnforcedTableWidget->item(row,ENF_VER_GROUP_COLUMN)->data( Qt::EditRole); if (!x.isNull()/* && entry.isNull()*/) { -// disconnect( myXCoord, SIGNAL( textChanged(const QString &)), this, SLOT( onSelectEnforcedVertex() ) ); + // disconnect( myXCoord, SIGNAL( textChanged(const QString &)), this, SLOT( onSelectEnforcedVertex() ) ); disconnect( myXCoord, SIGNAL( textChanged(const QString&) ), this, SLOT( clearEnfVertexSelection() ) ); disconnect( myYCoord, SIGNAL( textChanged(const QString&) ), this, SLOT( clearEnfVertexSelection() ) ); disconnect( myZCoord, SIGNAL( textChanged(const QString&) ), this, SLOT( clearEnfVertexSelection() ) ); @@ -847,11 +879,13 @@ void GHS3DPluginGUI_HypothesisCreator::synchronizeCoords() { } /** GHS3DPluginGUI_HypothesisCreator::addEnforcedMesh( meshName, geomEntry, elemType, size, groupName) -This method adds in the tree widget an enforced mesh from mesh, submesh or group with optionally size and and groupName. + This method adds in the tree widget an enforced mesh from mesh, submesh or group with optionally size and and groupName. */ -void GHS3DPluginGUI_HypothesisCreator::addEnforcedMesh(std::string name, std::string entry, int elementType, std::string groupName) +void GHS3DPluginGUI_HypothesisCreator::addEnforcedMesh(std::string name, + std::string entry, + int elementType, + std::string groupName) { - MESSAGE("addEnforcedMesh(\"" << name << ", \"" << entry << "\", " << elementType << ", \"" << groupName << "\")"); bool okToCreate = true; QString itemEntry = ""; int itemElementType = 0; @@ -859,23 +893,19 @@ void GHS3DPluginGUI_HypothesisCreator::addEnforcedMesh(std::string name, std::st bool allColumns = true; for (int row = 0;row(myEnforcedMeshTableWidget->cellWidget(row, col)) == 0) { allColumns = false; - MESSAGE("allColumns = false"); break; } } else if (myEnforcedMeshTableWidget->item(row, col) == 0) { allColumns = false; - MESSAGE("allColumns = false"); break; } if (col == ENF_MESH_CONSTRAINT_COLUMN) { QComboBox* itemComboBox = qobject_cast(myEnforcedMeshTableWidget->cellWidget(row, col)); itemElementType = itemComboBox->currentIndex(); - MESSAGE("itemElementType: " << itemElementType); } else if (col == ENF_MESH_ENTRY_COLUMN) itemEntry = myEnforcedMeshTableWidget->item(row, col)->data(Qt::EditRole).toString(); @@ -885,11 +915,6 @@ void GHS3DPluginGUI_HypothesisCreator::addEnforcedMesh(std::string name, std::st break; if (itemEntry == QString(entry.c_str()) && itemElementType == elementType) { -// // update group name -// if (itemGroupName.toStdString() != groupName) { -// MESSAGE("Group is updated from \"" << itemGroupName.toStdString() << "\" to \"" << groupName << "\""); -// myEnforcedMeshTableWidget->item(row, ENF_MESH_GROUP_COLUMN)->setData( Qt::EditRole, QVariant(groupName.c_str())); -// } okToCreate = false; break; } // if @@ -899,13 +924,10 @@ void GHS3DPluginGUI_HypothesisCreator::addEnforcedMesh(std::string name, std::st if (!okToCreate) return; - MESSAGE("Creation of enforced mesh"); - myEnforcedMeshTableWidget->setRowCount(rowCount+1); myEnforcedMeshTableWidget->setSortingEnabled(false); for (int col=0;colpalette(); @@ -914,56 +936,44 @@ void GHS3DPluginGUI_HypothesisCreator::addEnforcedMesh(std::string name, std::st comboBox->insertItems(0,myEnfMeshConstraintLabels); comboBox->setEditable(false); comboBox->setCurrentIndex(elementType); - MESSAGE("Add item in table at (" << rowCount << "," << col << "): " << comboBox->currentText().toStdString()); myEnforcedMeshTableWidget->setCellWidget(rowCount,col,comboBox); } else { QTableWidgetItem* item = new QTableWidgetItem(); item->setFlags( Qt::ItemIsSelectable | Qt::ItemIsEditable | Qt::ItemIsEnabled); switch (col) { - case ENF_MESH_NAME_COLUMN: - item->setData( 0, name.c_str() ); - item->setFlags( Qt::ItemIsSelectable | Qt::ItemIsEnabled); - MESSAGE("Add item in table at (" << rowCount << "," << col << "): " << item->text().toStdString()); - myEnforcedMeshTableWidget->setItem(rowCount,col,item); - break; - case ENF_MESH_ENTRY_COLUMN: - item->setData( 0, entry.c_str() ); - item->setFlags( Qt::ItemIsSelectable | Qt::ItemIsEnabled); - MESSAGE("Add item in table at (" << rowCount << "," << col << "): " << item->text().toStdString()); - myEnforcedMeshTableWidget->setItem(rowCount,col,item); - break; - case ENF_MESH_GROUP_COLUMN: - item->setData( 0, groupName.c_str() ); - MESSAGE("Add item in table at (" << rowCount << "," << col << "): " << item->text().toStdString()); - myEnforcedMeshTableWidget->setItem(rowCount,col,item); - break; - default: - break; + case ENF_MESH_NAME_COLUMN: + item->setData( 0, name.c_str() ); + item->setFlags( Qt::ItemIsSelectable | Qt::ItemIsEnabled); + myEnforcedMeshTableWidget->setItem(rowCount,col,item); + break; + case ENF_MESH_ENTRY_COLUMN: + item->setData( 0, entry.c_str() ); + item->setFlags( Qt::ItemIsSelectable | Qt::ItemIsEnabled); + myEnforcedMeshTableWidget->setItem(rowCount,col,item); + break; + case ENF_MESH_GROUP_COLUMN: + item->setData( 0, groupName.c_str() ); + myEnforcedMeshTableWidget->setItem(rowCount,col,item); + break; + default: + break; } } - MESSAGE("Done"); } - -// connect( myEnforcedMeshTableWidget,SIGNAL( itemChanged(QTableWidgetItem *)), this, SLOT( updateEnforcedVertexValues(QTableWidgetItem *) ) ); - myEnforcedMeshTableWidget->setSortingEnabled(true); -// myEnforcedTableWidget->setCurrentItem(myEnforcedTableWidget->item(rowCount,ENF_VER_NAME_COLUMN)); -// updateEnforcedVertexValues(myEnforcedTableWidget->item(rowCount,ENF_VER_NAME_COLUMN)); - } /** GHS3DPluginGUI_HypothesisCreator::addEnforcedVertex( x, y, z, size, vertexName, geomEntry, groupName) -This method adds in the tree widget an enforced vertex with given size and coords (x,y,z) or GEOM vertex or compound and with optionally groupName. + This method adds in the tree widget an enforced vertex with given size and coords (x,y,z) or GEOM vertex or compound and with optionally groupName. */ void GHS3DPluginGUI_HypothesisCreator::addEnforcedVertex(double x, double y, double z, double size, std::string vertexName, std::string geomEntry, std::string groupName, bool isCompound) { - MESSAGE("addEnforcedVertex(" << x << ", " << y << ", " << z << ", " << size << ", \"" << vertexName << ", \"" << geomEntry << "\", \"" << groupName << "\", " << isCompound << ")"); myEnforcedTableWidget->disconnect(SIGNAL( itemChanged(QTableWidgetItem *))); bool okToCreate = true; double itemX,itemY,itemZ,itemSize = 0; QString itemEntry, itemGroupName = QString(""); -// bool itemIsCompound; + // bool itemIsCompound; int rowCount = myEnforcedTableWidget->rowCount(); QVariant data; bool allColumns; @@ -978,29 +988,26 @@ void GHS3DPluginGUI_HypothesisCreator::addEnforcedVertex(double x, double y, dou data = myEnforcedTableWidget->item(row, col)->data(Qt::EditRole); if (!data.isNull()) { switch (col) { - case ENF_VER_GROUP_COLUMN: - itemGroupName = data.toString(); - break; - case ENF_VER_ENTRY_COLUMN: - itemEntry = data.toString(); - break; -// case ENF_VER_COMPOUND_COLUMN: -// itemIsCompound = data.toBool(); -// break; - case ENF_VER_X_COLUMN: - itemX = data.toDouble(); - break; - case ENF_VER_Y_COLUMN: - itemY = data.toDouble(); - break; - case ENF_VER_Z_COLUMN: - itemZ = data.toDouble(); - break; - case ENF_VER_SIZE_COLUMN: - itemSize = data.toDouble(); - break; - default: - break; + case ENF_VER_GROUP_COLUMN: + itemGroupName = data.toString(); + break; + case ENF_VER_ENTRY_COLUMN: + itemEntry = data.toString(); + break; + case ENF_VER_X_COLUMN: + itemX = data.toDouble(); + break; + case ENF_VER_Y_COLUMN: + itemY = data.toDouble(); + break; + case ENF_VER_Z_COLUMN: + itemZ = data.toDouble(); + break; + case ENF_VER_SIZE_COLUMN: + itemSize = data.toDouble(); + break; + default: + break; } } } @@ -1014,12 +1021,10 @@ void GHS3DPluginGUI_HypothesisCreator::addEnforcedVertex(double x, double y, dou { // update size if (itemSize != size) { - MESSAGE("Size is updated from \"" << itemSize << "\" to \"" << size << "\""); myEnforcedTableWidget->item(row, ENF_VER_SIZE_COLUMN)->setData( Qt::EditRole, QVariant(size)); } // update group name if (itemGroupName.toStdString() != groupName) { - MESSAGE("Group is updated from \"" << itemGroupName.toStdString() << "\" to \"" << groupName << "\""); myEnforcedTableWidget->item(row, ENF_VER_GROUP_COLUMN)->setData( Qt::EditRole, QVariant(groupName.c_str())); } okToCreate = false; @@ -1028,21 +1033,12 @@ void GHS3DPluginGUI_HypothesisCreator::addEnforcedVertex(double x, double y, dou } // for if (!okToCreate) { if (geomEntry.empty()) { - MESSAGE("Vertex with coords " << x << ", " << y << ", " << z << " already exist: dont create again"); } else { - MESSAGE("Vertex with entry " << geomEntry << " already exist: dont create again"); } return; } - if (geomEntry.empty()) { - MESSAGE("Vertex with coords " << x << ", " << y << ", " << z<< " is created"); - } - else { - MESSAGE("Vertex with geom entry " << geomEntry << " is created"); - } - int vertexIndex=0; int indexRef = -1; QString myVertexName; @@ -1062,73 +1058,67 @@ void GHS3DPluginGUI_HypothesisCreator::addEnforcedVertex(double x, double y, dou } } - MESSAGE("myVertexName is \"" << myVertexName.toStdString() << "\""); myEnforcedTableWidget->setRowCount(rowCount+1); myEnforcedTableWidget->setSortingEnabled(false); for (int col=0;colsetFlags( Qt::ItemIsSelectable | Qt::ItemIsEditable | Qt::ItemIsEnabled); switch (col) { - case ENF_VER_NAME_COLUMN: - item->setData( Qt::EditRole, myVertexName ); - if (!geomEntry.empty()) { - if (isCompound) - item->setIcon(QIcon(iconCompound.scaled(iconCompound.size()*0.7,Qt::KeepAspectRatio,Qt::SmoothTransformation))); - else - item->setIcon(QIcon(iconVertex.scaled(iconVertex.size()*0.7,Qt::KeepAspectRatio,Qt::SmoothTransformation))); - } - break; - case ENF_VER_X_COLUMN: - if (!isCompound) - item->setData( 0, QVariant(x) ); - break; - case ENF_VER_Y_COLUMN: - if (!isCompound) - item->setData( 0, QVariant(y) ); - break; - case ENF_VER_Z_COLUMN: - if (!isCompound) - item->setData( 0, QVariant(z) ); - break; - case ENF_VER_SIZE_COLUMN: - item->setData( 0, QVariant(size) ); - break; - case ENF_VER_ENTRY_COLUMN: - if (!geomEntry.empty()) - item->setData( 0, QString(geomEntry.c_str()) ); - break; - case ENF_VER_COMPOUND_COLUMN: - item->setData( Qt::CheckStateRole, isCompound ); - item->setFlags(Qt::ItemIsSelectable | Qt::ItemIsUserCheckable); - break; - case ENF_VER_GROUP_COLUMN: - if (!groupName.empty()) - item->setData( 0, QString(groupName.c_str()) ); - break; - default: - break; + case ENF_VER_NAME_COLUMN: + item->setData( Qt::EditRole, myVertexName ); + if (!geomEntry.empty()) { + if (isCompound) + item->setIcon(QIcon(iconCompound.scaled(iconCompound.size()*0.7,Qt::KeepAspectRatio,Qt::SmoothTransformation))); + else + item->setIcon(QIcon(iconVertex.scaled(iconVertex.size()*0.7,Qt::KeepAspectRatio,Qt::SmoothTransformation))); + } + break; + case ENF_VER_X_COLUMN: + if (!isCompound) + item->setData( 0, QVariant(x) ); + break; + case ENF_VER_Y_COLUMN: + if (!isCompound) + item->setData( 0, QVariant(y) ); + break; + case ENF_VER_Z_COLUMN: + if (!isCompound) + item->setData( 0, QVariant(z) ); + break; + case ENF_VER_SIZE_COLUMN: + item->setData( 0, QVariant(size) ); + break; + case ENF_VER_ENTRY_COLUMN: + if (!geomEntry.empty()) + item->setData( 0, QString(geomEntry.c_str()) ); + break; + case ENF_VER_COMPOUND_COLUMN: + item->setData( Qt::CheckStateRole, isCompound ); + item->setFlags(Qt::ItemIsSelectable | Qt::ItemIsUserCheckable); + break; + case ENF_VER_GROUP_COLUMN: + if (!groupName.empty()) + item->setData( 0, QString(groupName.c_str()) ); + break; + default: + break; } - MESSAGE("Add item in table at (" << rowCount << "," << col << "): " << item->text().toStdString()); myEnforcedTableWidget->setItem(rowCount,col,item); - MESSAGE("Done"); } connect( myEnforcedTableWidget,SIGNAL( itemChanged(QTableWidgetItem *)), this, SLOT( updateEnforcedVertexValues(QTableWidgetItem *) ) ); myEnforcedTableWidget->setSortingEnabled(true); -// myEnforcedTableWidget->setCurrentItem(myEnforcedTableWidget->item(rowCount,ENF_VER_NAME_COLUMN)); + // myEnforcedTableWidget->setCurrentItem(myEnforcedTableWidget->item(rowCount,ENF_VER_NAME_COLUMN)); updateEnforcedVertexValues(myEnforcedTableWidget->item(rowCount,ENF_VER_NAME_COLUMN)); } /** GHS3DPluginGUI_HypothesisCreator::onAddEnforcedMesh() -This method is called when a item is added into the enforced meshes tree widget + This method is called when a item is added into the enforced meshes tree widget */ void GHS3DPluginGUI_HypothesisCreator::onAddEnforcedMesh() { - MESSAGE("GHS3DPluginGUI_HypothesisCreator::onAddEnforcedMesh()"); - GHS3DPluginGUI_HypothesisCreator* that = (GHS3DPluginGUI_HypothesisCreator*)this; that->getGeomSelectionTool()->selectionMgr()->clearFilters(); @@ -1142,44 +1132,30 @@ void GHS3DPluginGUI_HypothesisCreator::onAddEnforcedMesh() if (selEnfMeshes == 0) return; - std::string groupName = myMeshGroupName->text().toStdString(); -// if (myGlobalGroupName->isChecked()) -// groupName = myGlobalGroupName->text().toStdString(); - - if (boost::trim_copy(groupName).empty()) - groupName = ""; - + std::string groupName = myMeshGroupName->text().simplified().toStdString(); int elementType = myEnfMeshConstraint->currentIndex(); _PTR(Study) aStudy = SMESH::GetActiveStudyDocument(); - _PTR(SObject) aSObj; //SMESH::SMESH_IDSource::_nil; + _PTR(SObject) aSObj; QString meshEntry = myEnfMeshWdg->GetValue(); - MESSAGE("myEnfMeshWdg->GetValue()" << meshEntry.toStdString()); if (selEnfMeshes == 1) { - MESSAGE("1 SMESH object selected"); -// myEnfMesh = myEnfMeshWdg->GetObject< SMESH::SMESH_IDSource >(); -// std::string entry = myEnfMeshWdg->GetValue(); aSObj = aStudy->FindObjectID(meshEntry.toStdString().c_str()); CORBA::Object_var anObj = SMESH::SObjectToObject(aSObj,aStudy); - if (!CORBA::is_nil(anObj)) { -// SMESH::SMESH_IDSource_var theSource = SMESH::SObjectToInterface( aSObj ); + if (!CORBA::is_nil(anObj)) addEnforcedMesh( aSObj->GetName(), aSObj->GetID(), elementType, groupName); - } } else { - MESSAGE(selEnfMeshes << " SMESH objects selected"); QStringList meshEntries = meshEntry.split(" ", QString::SkipEmptyParts); QStringListIterator meshEntriesIt (meshEntries); while (meshEntriesIt.hasNext()) { aSObj = aStudy->FindObjectID(meshEntriesIt.next().toStdString().c_str()); CORBA::Object_var anObj = SMESH::SObjectToObject(aSObj,aStudy); if (!CORBA::is_nil(anObj)) { -// SMESH::SMESH_IDSource_var theSource = SMESH::SObjectToInterface( aSObj ); addEnforcedMesh( aSObj->GetName(), aSObj->GetID(), elementType, groupName); } } @@ -1193,12 +1169,10 @@ void GHS3DPluginGUI_HypothesisCreator::onAddEnforcedMesh() /** GHS3DPluginGUI_HypothesisCreator::onAddEnforcedVertex() -This method is called when a item is added into the enforced vertices tree widget + This method is called when a item is added into the enforced vertices tree widget */ void GHS3DPluginGUI_HypothesisCreator::onAddEnforcedVertex() { - MESSAGE("GHS3DPluginGUI_HypothesisCreator::onAddEnforcedVertex()"); - GHS3DPluginGUI_HypothesisCreator* that = (GHS3DPluginGUI_HypothesisCreator*)this; that->getGeomSelectionTool()->selectionMgr()->clearFilters(); @@ -1213,18 +1187,12 @@ void GHS3DPluginGUI_HypothesisCreator::onAddEnforcedVertex() if ((selEnfVertex == 0) && coordsEmpty) return; - std::string groupName = myGroupName->text().toStdString(); -// if (myGlobalGroupName->isChecked()) -// groupName = myGlobalGroupName->text().toStdString(); - - if (boost::trim_copy(groupName).empty()) - groupName = ""; + std::string groupName = myGroupName->text().simplified().toStdString(); double size = mySizeValue->GetValue(); if (selEnfVertex <= 1) { - MESSAGE("0 or 1 GEOM object selected"); double x = 0, y = 0, z=0; if (myXCoord->GetString() != "") { x = myXCoord->GetValue(); @@ -1232,7 +1200,6 @@ void GHS3DPluginGUI_HypothesisCreator::onAddEnforcedVertex() z = myZCoord->GetValue(); } if (selEnfVertex == 1) { - MESSAGE("1 GEOM object selected"); myEnfVertex = myEnfVertexWdg->GetObject< GEOM::GEOM_Object >(); std::string entry = "", name = ""; bool isCompound = false; @@ -1244,8 +1211,6 @@ void GHS3DPluginGUI_HypothesisCreator::onAddEnforcedVertex() addEnforcedVertex(x, y, z, size, name, entry, groupName, isCompound); } else { - MESSAGE("0 GEOM object selected"); - MESSAGE("Coords: ("<IsDone() ) addEnforcedVertex(x, y, z, size, myEnfVertex->GetName(),myEnfVertex->GetStudyEntry(), groupName); } else if (myEnfVertex->GetShapeType() == GEOM::COMPOUND) { - addEnforcedVertex(0., 0., 0., size, myEnfVertex->GetName(),myEnfVertex->GetStudyEntry(), groupName, true); + addEnforcedVertex(0., 0., 0., size, myEnfVertex->GetName(),myEnfVertex->GetStudyEntry(), groupName, true); } } } @@ -1281,7 +1246,7 @@ void GHS3DPluginGUI_HypothesisCreator::onAddEnforcedVertex() } /** GHS3DPluginGUI_HypothesisCreator::onRemoveEnforcedMesh() -This method is called when a item is removed from the enforced meshes tree widget + This method is called when a item is removed from the enforced meshes tree widget */ void GHS3DPluginGUI_HypothesisCreator::onRemoveEnforcedMesh() { @@ -1294,21 +1259,20 @@ void GHS3DPluginGUI_HypothesisCreator::onRemoveEnforcedMesh() if (!selectedRows.contains( row ) ) selectedRows.append(row); } - + qSort( selectedRows ); QListIterator it( selectedRows ); it.toBack(); while ( it.hasPrevious() ) { - row = it.previous(); - MESSAGE("delete row #"<< row); - myEnforcedMeshTableWidget->removeRow(row ); + row = it.previous(); + myEnforcedMeshTableWidget->removeRow(row ); } myEnforcedMeshTableWidget->selectionModel()->clearSelection(); } /** GHS3DPluginGUI_HypothesisCreator::onRemoveEnforcedVertex() -This method is called when a item is removed from the enforced vertices tree widget + This method is called when a item is removed from the enforced vertices tree widget */ void GHS3DPluginGUI_HypothesisCreator::onRemoveEnforcedVertex() { @@ -1326,9 +1290,8 @@ void GHS3DPluginGUI_HypothesisCreator::onRemoveEnforcedVertex() QListIterator it( selectedRows ); it.toBack(); while ( it.hasPrevious() ) { - row = it.previous(); - MESSAGE("delete row #"<< row); - myEnforcedTableWidget->removeRow(row ); + row = it.previous(); + myEnforcedTableWidget->removeRow(row ); } myEnforcedTableWidget->selectionModel()->clearSelection(); @@ -1359,16 +1322,14 @@ void GHS3DPluginGUI_HypothesisCreator::updateWidgets() sender() == myAdvWidget->keepWorkingFilesCheck ) { bool logFileRemovable = myAdvWidget->logInFileCheck->isChecked() && - !myAdvWidget->keepWorkingFilesCheck->isChecked(); - + !myAdvWidget->keepWorkingFilesCheck->isChecked(); + myAdvWidget->removeLogOnSuccessCheck->setEnabled( logFileRemovable ); } } bool GHS3DPluginGUI_HypothesisCreator::checkParams(QString& msg) const { - MESSAGE("GHS3DPluginGUI_HypothesisCreator::checkParams"); - if ( !QFileInfo( myAdvWidget->workingDirectoryLineEdit->text().trimmed() ).isWritable() ) { SUIT_MessageBox::warning( dlg(), tr( "SMESH_WRN_WARNING" ), @@ -1381,17 +1342,28 @@ bool GHS3DPluginGUI_HypothesisCreator::checkParams(QString& msg) const void GHS3DPluginGUI_HypothesisCreator::retrieveParams() const { - MESSAGE("GHS3DPluginGUI_HypothesisCreator::retrieveParams"); GHS3DPluginGUI_HypothesisCreator* that = (GHS3DPluginGUI_HypothesisCreator*)this; GHS3DHypothesisData data; readParamsFromHypo( data ); if ( myName ) + { myName->setText( data.myName ); - + + int width = QFontMetrics( myName->font() ).width( data.myName ); + QGridLayout* aStdLayout = (QGridLayout*) myStdGroup->layout(); + aStdLayout->setColumnMinimumWidth( 1, width + 10 ); + } 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 ); + myAdvWidget->maxMemoryCheck ->setChecked ( data.myMaximumMemory > 0 ); myAdvWidget->maxMemorySpin ->setValue ( qMax( (int)data.myMaximumMemory, myAdvWidget->maxMemorySpin->minimum() )); @@ -1421,63 +1393,52 @@ void GHS3DPluginGUI_HypothesisCreator::retrieveParams() const myEnforcedTableWidget->setRowCount(rowCount+1); for (int col=0;colisCompound: " << enfVertex->isCompound); QTableWidgetItem* item = new QTableWidgetItem(); item->setFlags( Qt::ItemIsSelectable | Qt::ItemIsEditable | Qt::ItemIsEnabled); switch (col) { - case ENF_VER_NAME_COLUMN: - item->setData( 0, enfVertex->name.c_str() ); - if (!enfVertex->geomEntry.empty()) { - if (enfVertex->isCompound) - item->setIcon(QIcon(iconCompound.scaled(iconCompound.size()*0.7,Qt::KeepAspectRatio,Qt::SmoothTransformation))); - else - item->setIcon(QIcon(iconVertex.scaled(iconVertex.size()*0.7,Qt::KeepAspectRatio,Qt::SmoothTransformation))); + case ENF_VER_NAME_COLUMN: + item->setData( 0, enfVertex->name.c_str() ); + if (!enfVertex->geomEntry.empty()) { + if (enfVertex->isCompound) + item->setIcon(QIcon(iconCompound.scaled(iconCompound.size()*0.7,Qt::KeepAspectRatio,Qt::SmoothTransformation))); + else + item->setIcon(QIcon(iconVertex.scaled(iconVertex.size()*0.7,Qt::KeepAspectRatio,Qt::SmoothTransformation))); - MESSAGE("Add item in table at (" << rowCount << "," << col << "): " << item->text().toStdString()); - } - break; - case ENF_VER_X_COLUMN: - if (!enfVertex->isCompound) { - item->setData( 0, enfVertex->coords.at(0) ); - MESSAGE("Add item in table at (" << rowCount << "," << col << "): " << item->text().toStdString()); - } - break; - case ENF_VER_Y_COLUMN: - if (!enfVertex->isCompound) { - item->setData( 0, enfVertex->coords.at(1) ); - MESSAGE("Add item in table at (" << rowCount << "," << col << "): " << item->text().toStdString()); - } - break; - case ENF_VER_Z_COLUMN: - if (!enfVertex->isCompound) { - item->setData( 0, enfVertex->coords.at(2) ); - MESSAGE("Add item in table at (" << rowCount << "," << col << "): " << item->text().toStdString()); - } - break; - case ENF_VER_SIZE_COLUMN: - item->setData( 0, enfVertex->size ); - MESSAGE("Add item in table at (" << rowCount << "," << col << "): " << item->text().toStdString()); - break; - case ENF_VER_ENTRY_COLUMN: - item->setData( 0, enfVertex->geomEntry.c_str() ); - MESSAGE("Add item in table at (" << rowCount << "," << col << "): " << item->text().toStdString()); - break; - case ENF_VER_COMPOUND_COLUMN: - item->setFlags(Qt::ItemIsSelectable | Qt::ItemIsUserCheckable); - item->setData( Qt::CheckStateRole, enfVertex->isCompound ); - MESSAGE("Add item in table at (" << rowCount << "," << col << "): " << enfVertex->isCompound); - break; - case ENF_VER_GROUP_COLUMN: - item->setData( 0, enfVertex->groupName.c_str() ); - MESSAGE("Add item in table at (" << rowCount << "," << col << "): " << item->text().toStdString()); - break; - default: - break; + } + break; + case ENF_VER_X_COLUMN: + if (!enfVertex->isCompound) { + item->setData( 0, enfVertex->coords.at(0) ); + } + break; + case ENF_VER_Y_COLUMN: + if (!enfVertex->isCompound) { + item->setData( 0, enfVertex->coords.at(1) ); + } + break; + case ENF_VER_Z_COLUMN: + if (!enfVertex->isCompound) { + item->setData( 0, enfVertex->coords.at(2) ); + } + break; + case ENF_VER_SIZE_COLUMN: + item->setData( 0, enfVertex->size ); + break; + case ENF_VER_ENTRY_COLUMN: + item->setData( 0, enfVertex->geomEntry.c_str() ); + break; + case ENF_VER_COMPOUND_COLUMN: + item->setFlags(Qt::ItemIsSelectable | Qt::ItemIsUserCheckable); + item->setData( Qt::CheckStateRole, enfVertex->isCompound ); + break; + case ENF_VER_GROUP_COLUMN: + item->setData( 0, enfVertex->groupName.c_str() ); + break; + default: + break; } myEnforcedTableWidget->setItem(rowCount,col,item); - MESSAGE("Done"); } that->updateEnforcedVertexValues(myEnforcedTableWidget->item(rowCount,ENF_VER_NAME_COLUMN)); rowCount++; @@ -1494,14 +1455,13 @@ void GHS3DPluginGUI_HypothesisCreator::retrieveParams() const rowCount = 0; myEnforcedMeshTableWidget->clearContents(); myEnforcedMeshTableWidget->setSortingEnabled(false); -// myEnforcedMeshTableWidget->disconnect(SIGNAL( itemChanged(QTableWidgetItem *))); + // myEnforcedMeshTableWidget->disconnect(SIGNAL( itemChanged(QTableWidgetItem *))); for(itMesh = data.myEnforcedMeshes.begin() ; itMesh != data.myEnforcedMeshes.end(); itMesh++ ) { TEnfMesh* enfMesh = (*itMesh); myEnforcedMeshTableWidget->setRowCount(rowCount+1); for (int col=0;colpalette(); @@ -1510,43 +1470,35 @@ void GHS3DPluginGUI_HypothesisCreator::retrieveParams() const comboBox->insertItems(0,myEnfMeshConstraintLabels); comboBox->setEditable(false); comboBox->setCurrentIndex(enfMesh->elementType); - MESSAGE("Add item in table at (" << rowCount << "," << col << "): " << comboBox->currentText().toStdString()); myEnforcedMeshTableWidget->setCellWidget(rowCount,col,comboBox); } else { QTableWidgetItem* item = new QTableWidgetItem(); item->setFlags( Qt::ItemIsSelectable | Qt::ItemIsEditable | Qt::ItemIsEnabled); switch (col) { - case ENF_MESH_NAME_COLUMN: - item->setData( 0, enfMesh->name.c_str() ); - item->setFlags( Qt::ItemIsSelectable | Qt::ItemIsEnabled); - MESSAGE("Add item in table at (" << rowCount << "," << col << "): " << item->text().toStdString()); - myEnforcedMeshTableWidget->setItem(rowCount,col,item); - break; - case ENF_MESH_ENTRY_COLUMN: - item->setData( 0, enfMesh->entry.c_str() ); - item->setFlags( Qt::ItemIsSelectable | Qt::ItemIsEnabled); - MESSAGE("Add item in table at (" << rowCount << "," << col << "): " << item->text().toStdString()); - myEnforcedMeshTableWidget->setItem(rowCount,col,item); - break; - case ENF_MESH_GROUP_COLUMN: - item->setData( 0, enfMesh->groupName.c_str() ); - MESSAGE("Add item in table at (" << rowCount << "," << col << "): " << item->text().toStdString()); - myEnforcedMeshTableWidget->setItem(rowCount,col,item); - break; - default: - break; + case ENF_MESH_NAME_COLUMN: + item->setData( 0, enfMesh->name.c_str() ); + item->setFlags( Qt::ItemIsSelectable | Qt::ItemIsEnabled); + myEnforcedMeshTableWidget->setItem(rowCount,col,item); + break; + case ENF_MESH_ENTRY_COLUMN: + item->setData( 0, enfMesh->entry.c_str() ); + item->setFlags( Qt::ItemIsSelectable | Qt::ItemIsEnabled); + myEnforcedMeshTableWidget->setItem(rowCount,col,item); + break; + case ENF_MESH_GROUP_COLUMN: + item->setData( 0, enfMesh->groupName.c_str() ); + myEnforcedMeshTableWidget->setItem(rowCount,col,item); + break; + default: + break; } } -// myEnforcedMeshTableWidget->setItem(rowCount,col,item); - MESSAGE("Done"); } -// that->updateEnforcedVertexValues(myEnforcedTableWidget->item(rowCount,ENF_VER_NAME_COLUMN)); rowCount++; } -// connect( myEnforcedMeshTableWidget,SIGNAL( itemChanged(QTableWidgetItem *)), this, SLOT( updateEnforcedVertexValues(QTableWidgetItem *) ) ); myEnforcedMeshTableWidget->setSortingEnabled(true); for (int col=0;col= 0 && data.myOptimizationLevel < 5 && !data.myBoundaryRecovery) { - const char* level[] = { "none" , "light" , "standard" , "standard+" , "strong" }; - valStr += " --optimisation_level "; - valStr += level[ data.myOptimizationLevel ]; - } - if ( data.myMaximumMemory > 0 ) { - valStr += " --max_memory "; - valStr += QString::number( data.myMaximumMemory ); - } - if ( data.myInitialMemory > 0 && !data.myBoundaryRecovery ) { - valStr += " --automatic_memory "; - valStr += QString::number( data.myInitialMemory ); - } - valStr += " --verbose "; - valStr += QString::number( data.myVerboseLevel ); + if ( !data.myBoundaryRecovery ) + valStr = " --components " + data.myToMeshHoles ? "all" : "outside_components" ; - if ( !data.myToCreateNewNodes ) - valStr += " --no_internal_points"; + if ( data.myOptimizationLevel >= 0 && data.myOptimizationLevel < 5 && !data.myBoundaryRecovery) { + const char* level[] = { "none" , "light" , "standard" , "standard+" , "strong" }; + valStr += " --optimisation_level "; + valStr += level[ data.myOptimizationLevel ]; + } + if ( data.myMaximumMemory > 0 ) { + valStr += " --max_memory "; + valStr += QString::number( data.myMaximumMemory ); + } + if ( data.myInitialMemory > 0 && !data.myBoundaryRecovery ) { + valStr += " --automatic_memory "; + valStr += QString::number( data.myInitialMemory ); + } + valStr += " --verbose "; + valStr += QString::number( data.myVerboseLevel ); - if ( data.myRemoveInitialCentralPoint ) - valStr += " --no_initial_central_point"; + if ( !data.myToCreateNewNodes ) + valStr += " --no_internal_points"; - if ( data.myBoundaryRecovery ) - valStr += " -C"; + if ( data.myRemoveInitialCentralPoint ) + valStr += " --no_initial_central_point"; - if ( data.myFEMCorrection ) - valStr += " -FEM"; + if ( data.myBoundaryRecovery ) + valStr += " -C"; - if ( data.myGradation != 1.05 ) { - valStr += " -Dcpropa="; - valStr += QString::number( data.myGradation ); - } + if ( data.myFEMCorrection ) + valStr += " -FEM"; - valStr += " "; - valStr += data.myTextOption; + if ( data.myGradation != 1.05 ) { + valStr += " -Dcpropa="; + valStr += QString::number( data.myGradation ); + } -// valStr += " #BEGIN ENFORCED VERTICES#"; -// // Add size map parameters storage -// for (int i=0 ; irowCount() ; i++) { -// valStr += " ("; -// double x = mySmpModel->data(mySmpModel->index(i,ENF_VER_X_COLUMN)).toDouble(); -// double y = mySmpModel->data(mySmpModel->index(i,ENF_VER_Y_COLUMN)).toDouble(); -// double z = mySmpModel->data(mySmpModel->index(i,ENF_VER_Z_COLUMN)).toDouble(); -// double size = mySmpModel->data(mySmpModel->index(i,ENF_VER_SIZE_COLUMN)).toDouble(); -// valStr += QString::number( x ); -// valStr += ","; -// valStr += QString::number( y ); -// valStr += ","; -// valStr += QString::number( z ); -// valStr += ")="; -// valStr += QString::number( size ); -// if (i!=mySmpModel->rowCount()-1) -// valStr += ";"; -// } -// valStr += " #END ENFORCED VERTICES#"; -// MESSAGE(valStr.toStdString()); + valStr += " "; + valStr += data.myTextOption; + return valStr; } bool GHS3DPluginGUI_HypothesisCreator::readParamsFromHypo( GHS3DHypothesisData& h_data ) const { - MESSAGE("GHS3DPluginGUI_HypothesisCreator::readParamsFromHypo"); GHS3DPlugin::GHS3DPlugin_Hypothesis_var h = GHS3DPlugin::GHS3DPlugin_Hypothesis::_narrow( initParamsHypothesis() ); + GHS3DPlugin::GHS3DPlugin_OptimizerHypothesis_var opt = + GHS3DPlugin::GHS3DPlugin_OptimizerHypothesis::_narrow( initParamsHypothesis() ); HypothesisData* data = SMESH::GetHypothesisData( hypType() ); h_data.myName = isCreation() && data ? hypName() : ""; + if ( !opt->_is_nil() ) + { + h_data.myOptimization = opt->GetOptimization(); + h_data.mySplitOverConstrained = opt->GetSplitOverConstrained(); + h_data.myPThreadsMode = opt->GetPThreadsMode(); + h_data.myNumberOfThreads = opt->GetMaximalNumberOfThreads(); + h_data.mySmoothOffSlivers = opt->GetSmoothOffSlivers(); + } h_data.myToMeshHoles = h->GetToMeshHoles(); - h_data.myToMakeGroupsOfDomains = /*h->GetToMeshHoles() &&*/ h->GetToMakeGroupsOfDomains(); + h_data.myToMakeGroupsOfDomains = h->GetToMakeGroupsOfDomains(); h_data.myMaximumMemory = h->GetMaximumMemory(); h_data.myInitialMemory = h->GetInitialMemory(); h_data.myInitialMemory = h->GetInitialMemory(); @@ -1655,7 +1595,6 @@ bool GHS3DPluginGUI_HypothesisCreator::readParamsFromHypo( GHS3DHypothesisData& h_data.myRemoveLogOnSuccess = h->GetRemoveLogOnSuccess(); GHS3DPlugin::GHS3DEnforcedVertexList_var vertices = h->GetEnforcedVertices(); - MESSAGE("vertices->length(): " << vertices->length()); h_data.myEnforcedVertices.clear(); for (CORBA::ULong i=0 ; ilength() ; i++) { TEnfVertex* myVertex = new TEnfVertex(); @@ -1667,13 +1606,11 @@ bool GHS3DPluginGUI_HypothesisCreator::readParamsFromHypo( GHS3DHypothesisData& if (vertices[i].coords.length()) { for (CORBA::ULong c = 0; c < vertices[i].coords.length() ; c++) myVertex->coords.push_back(vertices[i].coords[c]); - MESSAGE("Add enforced vertex ("<< myVertex->coords.at(0) << ","<< myVertex->coords.at(1) << ","<< myVertex->coords.at(2) << ") ="<< myVertex->size); } h_data.myEnforcedVertices.insert(myVertex); } GHS3DPlugin::GHS3DEnforcedMeshList_var enfMeshes = h->GetEnforcedMeshes(); - MESSAGE("enfMeshes->length(): " << enfMeshes->length()); h_data.myEnforcedMeshes.clear(); for (CORBA::ULong i=0 ; ilength() ; i++) { TEnfMesh* myEnfMesh = new TEnfMesh(); @@ -1681,19 +1618,19 @@ bool GHS3DPluginGUI_HypothesisCreator::readParamsFromHypo( GHS3DHypothesisData& myEnfMesh->entry = CORBA::string_dup(enfMeshes[i].entry.in()); myEnfMesh->groupName = CORBA::string_dup(enfMeshes[i].groupName.in()); switch (enfMeshes[i].elementType) { - case SMESH::NODE: - myEnfMesh->elementType = 0; - break; - case SMESH::EDGE: - myEnfMesh->elementType = 1; - break; - case SMESH::FACE: - myEnfMesh->elementType = 2; - break; - default: - break; + case SMESH::NODE: + myEnfMesh->elementType = 0; + break; + case SMESH::EDGE: + myEnfMesh->elementType = 1; + break; + case SMESH::FACE: + myEnfMesh->elementType = 2; + break; + default: + break; } -// myEnfMesh->elementType = enfMeshes[i].elementType; + // myEnfMesh->elementType = enfMeshes[i].elementType; h_data.myEnforcedMeshes.insert(myEnfMesh); } return true; @@ -1701,9 +1638,10 @@ bool GHS3DPluginGUI_HypothesisCreator::readParamsFromHypo( GHS3DHypothesisData& bool GHS3DPluginGUI_HypothesisCreator::storeParamsToHypo( const GHS3DHypothesisData& h_data ) const { - MESSAGE("GHS3DPluginGUI_HypothesisCreator::storeParamsToHypo"); GHS3DPlugin::GHS3DPlugin_Hypothesis_var h = GHS3DPlugin::GHS3DPlugin_Hypothesis::_narrow( hypothesis() ); + GHS3DPlugin::GHS3DPlugin_OptimizerHypothesis_var opt = + GHS3DPlugin::GHS3DPlugin_OptimizerHypothesis::_narrow( initParamsHypothesis() ); bool ok = true; try @@ -1743,22 +1681,27 @@ bool GHS3DPluginGUI_HypothesisCreator::storeParamsToHypo( const GHS3DHypothesisD h->SetAdvancedOption ( h_data.myTextOption.toLatin1().constData() ); if ( h->GetStandardOutputLog() != h_data.myLogInStandardOutput ) h->SetStandardOutputLog( h_data.myLogInStandardOutput ); - if ( h->GetRemoveLogOnSuccess() != h_data.myRemoveLogOnSuccess ) + if ( h->GetRemoveLogOnSuccess() != h_data.myRemoveLogOnSuccess ) h->SetRemoveLogOnSuccess( h_data.myRemoveLogOnSuccess ); - + + if ( !opt->_is_nil() ) + { + opt->SetOptimization ( (GHS3DPlugin::Mode) h_data.myOptimization ); + opt->SetSplitOverConstrained ( (GHS3DPlugin::Mode) h_data.mySplitOverConstrained ); + opt->SetPThreadsMode ( (GHS3DPlugin::PThreadsMode) h_data.myPThreadsMode ); + opt->SetSmoothOffSlivers ( h_data.mySmoothOffSlivers ); + opt->SetMaximalNumberOfThreads( h_data.myNumberOfThreads ); + } + // Enforced vertices - int nbVertex = (int) h_data.myEnforcedVertices.size(); GHS3DPlugin::GHS3DEnforcedVertexList_var vertexHyp = h->GetEnforcedVertices(); int nbVertexHyp = vertexHyp->length(); - - MESSAGE("Store params for size maps: " << nbVertex << " enforced vertices"); - MESSAGE("h->GetEnforcedVertices()->length(): " << nbVertexHyp); - + // 1. Clear all enforced vertices in hypothesis // 2. Add new enforced vertex according to h_data if ( nbVertexHyp > 0) h->ClearEnforcedVertices(); - + TEnfVertexList::const_iterator it; double x = 0, y = 0, z = 0; for(it = h_data.myEnforcedVertices.begin() ; it != h_data.myEnforcedVertices.end(); it++ ) { @@ -1771,20 +1714,16 @@ bool GHS3DPluginGUI_HypothesisCreator::storeParamsToHypo( const GHS3DHypothesisD } ok = h->p_SetEnforcedVertex( enfVertex->size, x, y, z, enfVertex->name.c_str(), enfVertex->geomEntry.c_str(), enfVertex->groupName.c_str(), enfVertex->isCompound); } // for - + // Enforced Meshes - int nbEnfMeshes = (int) h_data.myEnforcedMeshes.size(); GHS3DPlugin::GHS3DEnforcedMeshList_var enfMeshListHyp = h->GetEnforcedMeshes(); int nbEnfMeshListHyp = enfMeshListHyp->length(); - - MESSAGE("Store params for size maps: " << nbEnfMeshes << " enforced meshes"); - MESSAGE("h->GetEnforcedMeshes()->length(): " << nbEnfMeshListHyp); - + // 1. Clear all enforced vertices in hypothesis // 2. Add new enforced vertex according to h_data if ( nbEnfMeshListHyp > 0) h->ClearEnforcedMeshes(); - + TEnfMeshList::const_iterator itEnfMesh; _PTR(Study) aStudy = SMESH::GetActiveStudyDocument(); @@ -1795,30 +1734,24 @@ bool GHS3DPluginGUI_HypothesisCreator::storeParamsToHypo( const GHS3DHypothesisD _PTR(SObject) aSObj = aStudy->FindObjectID(enfMesh->entry.c_str()); SMESH::SMESH_IDSource_var theSource = SMESH::SObjectToInterface( aSObj ); - MESSAGE("enfMesh->elementType: " << enfMesh->elementType); SMESH::ElementType elementType; switch(enfMesh->elementType) { - case 0: - elementType = SMESH::NODE; - break; - case 1: - elementType = SMESH::EDGE; - break; - case 2: - elementType = SMESH::FACE; - break; - default: - break; + case 0: + elementType = SMESH::NODE; + break; + case 1: + elementType = SMESH::EDGE; + break; + case 2: + elementType = SMESH::FACE; + break; + default: + break; } - std::cout << "h->p_SetEnforcedMesh(theSource, "<< elementType <<", \""<< enfMesh->name << "\", \"" << enfMesh->groupName.c_str() <<"\")"<p_SetEnforcedMesh(theSource, elementType, enfMesh->name.c_str(), enfMesh->groupName.c_str()); } // for } // try -// catch(const std::exception& ex) { -// std::cout << "Exception: " << ex.what() << std::endl; -// throw ex; -// } catch ( const SALOME::SALOME_Exception& ex ) { SalomeApp_Tools::QtCatchCorbaException( ex ); @@ -1829,17 +1762,20 @@ bool GHS3DPluginGUI_HypothesisCreator::storeParamsToHypo( const GHS3DHypothesisD bool GHS3DPluginGUI_HypothesisCreator::readParamsFromWidgets( GHS3DHypothesisData& h_data ) const { - MESSAGE("GHS3DPluginGUI_HypothesisCreator::readParamsFromWidgets"); 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.myOptimizationLevel = myOptimizationLevelCombo->currentIndex(); h_data.myKeepFiles = myAdvWidget->keepWorkingFilesCheck->isChecked(); h_data.myWorkingDir = myAdvWidget->workingDirectoryLineEdit->text().trimmed(); h_data.myVerboseLevel = myAdvWidget->verboseLevelSpin->value(); - h_data.myToCreateNewNodes = myAdvWidget->createNewNodesCheck->isChecked(); h_data.myRemoveInitialCentralPoint = myAdvWidget->removeInitialCentralPointCheck->isChecked(); h_data.myBoundaryRecovery = myAdvWidget->boundaryRecoveryCheck->isChecked(); h_data.myFEMCorrection = myAdvWidget->FEMCorrectionCheck->isChecked(); @@ -1847,21 +1783,20 @@ bool GHS3DPluginGUI_HypothesisCreator::readParamsFromWidgets( GHS3DHypothesisDat 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(); + else + h_data.myToCreateNewNodes = myAdvWidget->createNewNodesCheck->isChecked(); // Enforced vertices h_data.myEnforcedVertices.clear(); QVariant valueX, valueY, valueZ; - for (int row=0 ; rowrowCount() ; row++) { - + for (int row=0 ; rowrowCount() ; row++) + { TEnfVertex *myVertex = new TEnfVertex(); myVertex->name = myEnforcedTableWidget->item(row,ENF_VER_NAME_COLUMN)->data(Qt::EditRole).toString().toStdString(); - MESSAGE("Add new enforced vertex \"" << myVertex->name << "\"" ); myVertex->geomEntry = myEnforcedTableWidget->item(row,ENF_VER_ENTRY_COLUMN)->data(Qt::EditRole).toString().toStdString(); - if (myVertex->geomEntry.size()) - MESSAGE("Geom entry is \"" << myVertex->geomEntry << "\"" ); myVertex->groupName = myEnforcedTableWidget->item(row,ENF_VER_GROUP_COLUMN)->data(Qt::EditRole).toString().toStdString(); - if (myVertex->groupName.size()) - MESSAGE("Group name is \"" << myVertex->groupName << "\"" ); valueX = myEnforcedTableWidget->item(row,ENF_VER_X_COLUMN)->data(Qt::EditRole); valueY = myEnforcedTableWidget->item(row,ENF_VER_Y_COLUMN)->data(Qt::EditRole); valueZ = myEnforcedTableWidget->item(row,ENF_VER_Z_COLUMN)->data(Qt::EditRole); @@ -1869,34 +1804,24 @@ bool GHS3DPluginGUI_HypothesisCreator::readParamsFromWidgets( GHS3DHypothesisDat myVertex->coords.push_back(valueX.toDouble()); myVertex->coords.push_back(valueY.toDouble()); myVertex->coords.push_back(valueZ.toDouble()); - MESSAGE("Coords are (" << myVertex->coords.at(0) << ", " - << myVertex->coords.at(1) << ", " - << myVertex->coords.at(2) << ")"); } myVertex->size = myEnforcedTableWidget->item(row,ENF_VER_SIZE_COLUMN)->data(Qt::EditRole).toDouble(); - MESSAGE("Size is " << myVertex->size); myVertex->isCompound = myEnforcedTableWidget->item(row,ENF_VER_COMPOUND_COLUMN)->data(Qt::CheckStateRole).toBool(); - MESSAGE("Is compound ? " << myVertex->isCompound); h_data.myEnforcedVertices.insert(myVertex); } // Enforced meshes h_data.myEnforcedMeshes.clear(); - for (int row=0 ; rowrowCount() ; row++) { - + for (int row=0 ; rowrowCount() ; row++) + { TEnfMesh *myEnfMesh = new TEnfMesh(); myEnfMesh->name = myEnforcedMeshTableWidget->item(row,ENF_MESH_NAME_COLUMN)->data(Qt::EditRole).toString().toStdString(); - MESSAGE("Add new enforced mesh \"" << myEnfMesh->name << "\"" ); myEnfMesh->entry = myEnforcedMeshTableWidget->item(row,ENF_MESH_ENTRY_COLUMN)->data(Qt::EditRole).toString().toStdString(); - MESSAGE("Entry is \"" << myEnfMesh->entry << "\"" ); myEnfMesh->groupName = myEnforcedMeshTableWidget->item(row,ENF_MESH_GROUP_COLUMN)->data(Qt::EditRole).toString().toStdString(); - MESSAGE("Group name is \"" << myEnfMesh->groupName << "\"" ); QComboBox* combo = qobject_cast(myEnforcedMeshTableWidget->cellWidget(row,ENF_MESH_CONSTRAINT_COLUMN)); myEnfMesh->elementType = combo->currentIndex(); - MESSAGE("Element type: " << myEnfMesh->elementType); h_data.myEnforcedMeshes.insert(myEnfMesh); - std::cout << "h_data.myEnforcedMeshes.size(): " << h_data.myEnforcedMeshes.size() << std::endl; } return true; @@ -1914,10 +1839,10 @@ QPixmap GHS3DPluginGUI_HypothesisCreator::icon() const QString GHS3DPluginGUI_HypothesisCreator::type() const { - return tr( "GHS3D_HYPOTHESIS" ); + return tr( isOptimization() ? "GHS3D_OPTIMIZATIOL_HYPOTHESIS" : "GHS3D_HYPOTHESIS" ); } QString GHS3DPluginGUI_HypothesisCreator::helpPage() const { - return "ghs3d_hypo_page.html"; + return isOptimization() ? "optimization_page.html" : "ghs3d_hypo_page.html"; } diff --git a/src/GUI/GHS3DPluginGUI_HypothesisCreator.h b/src/GUI/GHS3DPluginGUI_HypothesisCreator.h index 1c093ca..4d7ce75 100644 --- a/src/GUI/GHS3DPluginGUI_HypothesisCreator.h +++ b/src/GUI/GHS3DPluginGUI_HypothesisCreator.h @@ -57,11 +57,12 @@ class QTableWidget; class QTableWidgetItem; class QHeaderView; -class SMESHGUI_SpinBox; -class StdMeshersGUI_ObjectReferenceParamWdg; +class GHS3DPluginGUI_AdvWidget; class LightApp_SelectionMgr; +class SMESHGUI_SpinBox; class SUIT_SelectionFilter; -class GHS3DPluginGUI_AdvWidget; +class SalomeApp_IntSpinBox; +class StdMeshersGUI_ObjectReferenceParamWdg; class QTEnfVertex { @@ -151,6 +152,10 @@ typedef struct short myVerboseLevel; TEnfVertexList myEnforcedVertices; TEnfMeshList myEnforcedMeshes; + + int myOptimization, mySplitOverConstrained, myPThreadsMode, myNumberOfThreads; + bool mySmoothOffSlivers; + } GHS3DHypothesisData; /*! @@ -209,46 +214,48 @@ private: bool storeParamsToHypo( const GHS3DHypothesisData& ) const; GeomSelectionTools* getGeomSelectionTool(); GEOM::GEOM_Gen_var getGeomEngine(); + bool isOptimization() const; private: - QWidget* myStdGroup; - QLineEdit* myName; - QCheckBox* myToMeshHolesCheck; - QCheckBox* myToMakeGroupsOfDomains; - QComboBox* myOptimizationLevelCombo; + QWidget* myStdGroup; + QLineEdit* myName; + QCheckBox* myToMeshHolesCheck; + QCheckBox* myToMakeGroupsOfDomains; + QComboBox* myOptimizationLevelCombo; + + QComboBox* myOptimizationCombo; + QComboBox* mySplitOverConstrainedCombo; + QComboBox* myPThreadsModeCombo; + SalomeApp_IntSpinBox* myNumberOfThreadsSpin; + QCheckBox* mySmoothOffSliversCheck; + QCheckBox* myCreateNewNodesCheck; QWidget* myAdvGroup; GHS3DPluginGUI_AdvWidget* myAdvWidget; - QWidget* myEnfGroup; - QPixmap iconVertex, iconCompound; + QWidget* myEnfGroup; + QPixmap iconVertex, iconCompound; StdMeshersGUI_ObjectReferenceParamWdg *myEnfVertexWdg; GEOM::GEOM_Object_var myEnfVertex; - QTableWidget* myEnforcedTableWidget; - SMESHGUI_SpinBox* myXCoord; - SMESHGUI_SpinBox* myYCoord; - SMESHGUI_SpinBox* myZCoord; - SMESHGUI_SpinBox* mySizeValue; - QLineEdit* myGroupName; -// QGroupBox* makeGroupsCheck; -// QCheckBox* myGlobalGroupName; - QPushButton* addVertexButton; - QPushButton* removeVertexButton; + QTableWidget* myEnforcedTableWidget; + SMESHGUI_SpinBox* myXCoord; + SMESHGUI_SpinBox* myYCoord; + SMESHGUI_SpinBox* myZCoord; + SMESHGUI_SpinBox* mySizeValue; + QLineEdit* myGroupName; + QPushButton* addVertexButton; + QPushButton* removeVertexButton; - QWidget* myEnfMeshGroup; + QWidget* myEnfMeshGroup; StdMeshersGUI_ObjectReferenceParamWdg *myEnfMeshWdg; -// SMESH::SMESH_IDSource_var myEnfMesh; - QComboBox* myEnfMeshConstraint; - QStringList myEnfMeshConstraintLabels; -// SMESH::mesh_array_var myEnfMeshArray; - QTableWidget* myEnforcedMeshTableWidget; - QLineEdit* myMeshGroupName; - QPushButton* addEnfMeshButton; - QPushButton* removeEnfMeshButton; + QComboBox* myEnfMeshConstraint; + QStringList myEnfMeshConstraintLabels; + QTableWidget* myEnforcedMeshTableWidget; + QLineEdit* myMeshGroupName; + QPushButton* addEnfMeshButton; + QPushButton* removeEnfMeshButton; GeomSelectionTools* GeomToolSelected; -// SVTK_Selector* mySelector; -// LightApp_SelectionMgr* mySelectionMgr; /* User shape selection */ }; class EnforcedVertexTableWidgetDelegate : public QItemDelegate diff --git a/src/GUI/GHS3DPlugin_images.ts b/src/GUI/GHS3DPlugin_images.ts index 58d83e2..4ea0d95 100644 --- a/src/GUI/GHS3DPlugin_images.ts +++ b/src/GUI/GHS3DPlugin_images.ts @@ -15,5 +15,9 @@ ICON_SMESH_TREE_HYPO_MG-Tetra Parameters mesh_tree_hypo_ghs3d.png + + ICON_SMESH_TREE_HYPO_MG-Tetra Optimization Parameters + mesh_tree_hypo_ghs3d.png + diff --git a/src/GUI/GHS3DPlugin_msg_en.ts b/src/GUI/GHS3DPlugin_msg_en.ts index bca2a59..b90dc6d 100644 --- a/src/GUI/GHS3DPlugin_msg_en.ts +++ b/src/GUI/GHS3DPlugin_msg_en.ts @@ -11,6 +11,10 @@ GHS3D_HYPOTHESIS MG-Tetra + + GHS3D_OPTIMIZATIOL_HYPOTHESIS + MG-Tetra Optimization + GHS3D_OPTIMIZATIOL_LEVEL Optimization level @@ -231,5 +235,49 @@ GHS3D_ENF_MESH_INFO <b>Warning</b>: Enforced meshes are currently only taken into account for meshes w/o associated geometry. + + MODE_SAFE + Safe + + + MODE_AGGRESSIVE + Aggressive + + + MODE_NONE + None + + + MODE_NO + No + + + MODE_YES + Yes + + + MODE_ONLY + Only + + + GHS3D_OPTIMIZATION + Optimization + + + GHS3D_SPLIT_OVERCONSTRAINED + Split overconstrained elements + + + GHS3D_PTHREADS_MODE + PThreads mode + + + GHS3D_NB_THREADS + Max number of threads + + + GHS3D_SMOOTH_OFF_SLIVERS + Smooth off sliver elements + -- 2.39.2