From 05d675364cc7331e9bfb3e18de6ac500041a810a Mon Sep 17 00:00:00 2001 From: Uwe Date: Fri, 24 Mar 2023 19:29:25 +0100 Subject: [PATCH] [FEM] improve new default solver setting - fix bug if no solver should be default - only provide solvers that are available to be the default - also add commit opened transactions - also remove unused include and correct an include --- src/Mod/Fem/Gui/DlgSettingsFemCcxImp.cpp | 2 +- src/Mod/Fem/Gui/DlgSettingsFemGeneral.ui | 30 +++--------------- src/Mod/Fem/Gui/DlgSettingsFemGeneralImp.cpp | 33 ++++++++++++++++++++ src/Mod/Fem/femcommands/commands.py | 24 +++++++++++--- src/Mod/Fem/femcommands/manager.py | 1 - src/Mod/Fem/femsolver/settings.py | 30 ++++++++++++------ 6 files changed, 77 insertions(+), 43 deletions(-) diff --git a/src/Mod/Fem/Gui/DlgSettingsFemCcxImp.cpp b/src/Mod/Fem/Gui/DlgSettingsFemCcxImp.cpp index 74e7a443ec..993e973bb0 100644 --- a/src/Mod/Fem/Gui/DlgSettingsFemCcxImp.cpp +++ b/src/Mod/Fem/Gui/DlgSettingsFemCcxImp.cpp @@ -29,7 +29,7 @@ # include #endif -#include +#include #include "DlgSettingsFemCcxImp.h" #include "ui_DlgSettingsFemCcx.h" diff --git a/src/Mod/Fem/Gui/DlgSettingsFemGeneral.ui b/src/Mod/Fem/Gui/DlgSettingsFemGeneral.ui index c501f868d5..4e15a7732e 100644 --- a/src/Mod/Fem/Gui/DlgSettingsFemGeneral.ui +++ b/src/Mod/Fem/Gui/DlgSettingsFemGeneral.ui @@ -6,8 +6,8 @@ 0 0 - 425 - 447 + 411 + 450 @@ -387,11 +387,9 @@ true - - false - - Default solver used by the analysis container + Default solver to be added when +adding an analysis container DefaultSolver @@ -404,26 +402,6 @@ None - - - CalculiX - - - - - Elmer - - - - - Mystran - - - - - Z88 - - diff --git a/src/Mod/Fem/Gui/DlgSettingsFemGeneralImp.cpp b/src/Mod/Fem/Gui/DlgSettingsFemGeneralImp.cpp index 5a5bc62444..e2c44e9d8e 100644 --- a/src/Mod/Fem/Gui/DlgSettingsFemGeneralImp.cpp +++ b/src/Mod/Fem/Gui/DlgSettingsFemGeneralImp.cpp @@ -24,6 +24,8 @@ #include "PreCompiled.h" +#include + #include "DlgSettingsFemGeneralImp.h" #include "ui_DlgSettingsFemGeneral.h" @@ -35,6 +37,37 @@ DlgSettingsFemGeneralImp::DlgSettingsFemGeneralImp(QWidget* parent) , ui(new Ui_DlgSettingsFemGeneralImp) { ui->setupUi(this); + + // fill solvers combo with available solvers + ui->cmb_def_solver->clear(); + std::vector Solvers = {"None"}; + + ParameterGrp::handle hGrp = App::GetApplication().GetParameterGroupByPath( + "User parameter:BaseApp/Preferences/Mod/Fem/Ccx"); + auto ccxBinaryPath = hGrp->GetASCII("ccxBinaryPath", ""); + if (!ccxBinaryPath.empty()) + Solvers.push_back("CalculiX"); + hGrp = App::GetApplication().GetParameterGroupByPath( + "User parameter:BaseApp/Preferences/Mod/Fem/Elmer"); + auto elmerBinaryPath = hGrp->GetASCII("elmerBinaryPath", ""); + if (!elmerBinaryPath.empty()) + Solvers.push_back("Elmer"); + hGrp = App::GetApplication().GetParameterGroupByPath( + "User parameter:BaseApp/Preferences/Mod/Fem/mystran"); + auto MystranBinaryPath = hGrp->GetASCII("MystranBinaryPath", ""); + if (!MystranBinaryPath.empty()) + Solvers.push_back("Mystran"); + hGrp = App::GetApplication().GetParameterGroupByPath( + "User parameter:BaseApp/Preferences/Mod/Fem/Z88"); + auto z88BinaryPath = hGrp->GetASCII("z88BinaryPath", ""); + if (!z88BinaryPath.empty()) + Solvers.push_back("Z88"); + + QStringList solversList; + for (auto item : Solvers) { + solversList << QLatin1String(item.c_str()); + } + ui->cmb_def_solver->addItems(solversList); } DlgSettingsFemGeneralImp::~DlgSettingsFemGeneralImp() diff --git a/src/Mod/Fem/femcommands/commands.py b/src/Mod/Fem/femcommands/commands.py index 2055459c9b..9fc2da335d 100644 --- a/src/Mod/Fem/femcommands/commands.py +++ b/src/Mod/Fem/femcommands/commands.py @@ -69,12 +69,20 @@ class _Analysis(CommandManager): FreeCADGui.addModule("ObjectsFem") FreeCADGui.doCommand("ObjectsFem.makeAnalysis(FreeCAD.ActiveDocument, 'Analysis')") FreeCADGui.doCommand("FemGui.setActiveAnalysis(FreeCAD.ActiveDocument.ActiveObject)") - if get_default_solver(): + FreeCAD.ActiveDocument.commitTransaction() + if get_default_solver() != "None": + FreeCAD.ActiveDocument.openTransaction("Create default solver") FreeCADGui.doCommand("ObjectsFem.makeSolver{}(FreeCAD.ActiveDocument)" - .format(get_default_solver())) + .format(get_default_solver()) + ) FreeCADGui.doCommand( - "FemGui.getActiveAnalysis().addObject(FreeCAD.ActiveDocument.ActiveObject)") - + "FemGui.getActiveAnalysis().addObject(FreeCAD.ActiveDocument.ActiveObject)" + ) + FreeCAD.ActiveDocument.commitTransaction() + self.do_activated = "add_obj_on_gui_expand_noset_edit" + # Fixme: expand analysis object in tree view to make added solver visible + # expandParentObject() does not work because the Analysis is not yet a tree + # in the tree view FreeCAD.ActiveDocument.recompute() @@ -711,6 +719,7 @@ class _MaterialMechanicalNonlinear(CommandManager): ) solver_object.MaterialNonlinearity = "nonlinear" solver_object.GeometricalNonlinearity = "nonlinear" + FreeCAD.ActiveDocument.commitTransaction() FreeCADGui.Selection.clearSelection() FreeCAD.ActiveDocument.recompute() @@ -793,6 +802,7 @@ class _FEMMesh2Mesh(CommandManager): FreeCADGui.doCommand( "FreeCAD.ActiveDocument." + femmesh.Name + ".ViewObject.hide()" ) + FreeCAD.ActiveDocument.commitTransaction() FreeCADGui.Selection.clearSelection() FreeCAD.ActiveDocument.recompute() @@ -835,6 +845,7 @@ class _MeshClear(CommandManager): FreeCADGui.doCommand( "FreeCAD.ActiveDocument." + self.selobj.Name + ".FemMesh = Fem.FemMesh()" ) + FreeCAD.ActiveDocument.commitTransaction() FreeCADGui.Selection.clearSelection() FreeCAD.ActiveDocument.recompute() @@ -864,6 +875,7 @@ class _MeshDisplayInfo(CommandManager): FreeCADGui.doCommand( "PySide.QtGui.QMessageBox.information(None, 'FEM Mesh Info', mesh_info)" ) + FreeCAD.ActiveDocument.commitTransaction() FreeCADGui.Selection.clearSelection() FreeCAD.ActiveDocument.recompute() @@ -909,6 +921,7 @@ class _MeshGmshFromShape(CommandManager): FreeCADGui.doCommand( "FreeCADGui.ActiveDocument.setEdit(FreeCAD.ActiveDocument.ActiveObject.Name)" ) + FreeCAD.ActiveDocument.commitTransaction() FreeCADGui.Selection.clearSelection() FreeCAD.ActiveDocument.recompute() @@ -971,6 +984,7 @@ class _MeshNetgenFromShape(CommandManager): FreeCADGui.doCommand( "FreeCADGui.ActiveDocument.setEdit(FreeCAD.ActiveDocument.ActiveObject.Name)" ) + FreeCAD.ActiveDocument.commitTransaction() FreeCADGui.Selection.clearSelection() # a recompute immediately starts meshing when task panel is opened, this is not intended @@ -1071,7 +1085,7 @@ class _SolverCxxtools(CommandManager): "makeSolverCalculixCcxTools(FreeCAD.ActiveDocument))" ) FreeCAD.ActiveDocument.commitTransaction() - # expand analysis object in tree view + # expand analysis object in tree view expandParentObject() FreeCAD.ActiveDocument.recompute() diff --git a/src/Mod/Fem/femcommands/manager.py b/src/Mod/Fem/femcommands/manager.py index 58890677a1..31c411280e 100644 --- a/src/Mod/Fem/femcommands/manager.py +++ b/src/Mod/Fem/femcommands/manager.py @@ -37,7 +37,6 @@ from femtools.femutils import is_of_type if FreeCAD.GuiUp: from PySide import QtCore - from PySide import QtGui import FreeCADGui import FemGui diff --git a/src/Mod/Fem/femsolver/settings.py b/src/Mod/Fem/femsolver/settings.py index ff89ea5bf3..a620a3d53f 100644 --- a/src/Mod/Fem/femsolver/settings.py +++ b/src/Mod/Fem/femsolver/settings.py @@ -81,7 +81,7 @@ _PARAM_PATH = "User parameter:BaseApp/Preferences/Mod/Fem/" _GENERAL_PARAM = _PARAM_PATH + "General" -def get_binary(name): +def get_binary(name, silent=False): """ Find binary of solver *name* honoring user settings. Return the specific path set by the user in FreeCADs settings/parameter @@ -92,16 +92,18 @@ def get_binary(name): That check is done in DlgSettingsFem_Solver_Imp.cpp :param name: solver id as a ``str`` (see :mod:`femsolver.settings`) + :param silent: whether to output error if binary not found """ if name in _SOLVER_PARAM: - binary = _SOLVER_PARAM[name].get_binary() + binary = _SOLVER_PARAM[name].get_binary(silent) return binary else: - FreeCAD.Console.PrintError( - "Settings solver name: {} not found in " - "solver settings modules _SOLVER_PARAM dirctionary.\n" - .format(name) - ) + if not silent: + FreeCAD.Console.PrintError( + "Settings solver name: {} not found in " + "solver settings modules _SOLVER_PARAM dirctionary.\n" + .format(name) + ) return None @@ -168,7 +170,15 @@ def get_dir_setting(): def get_default_solver(): """ Return default solver name. """ - solver_map = {0: None, 1: "CalculixCcxTools", 2: "Elmer", 3: "Mystran", 4: "Z88"} + solver_map = {0: "None"} + if get_binary("Calculix", True): + solver_map[1] = "CalculixCcxTools" + if get_binary("ElmerSolver", True): + solver_map[len(solver_map)] = "Elmer" + if get_binary("Mystran", True): + solver_map[len(solver_map)] = "Mystran" + if get_binary("Z88", True): + solver_map[len(solver_map)] = "Z88" param_group = FreeCAD.ParamGet(_GENERAL_PARAM) return solver_map[param_group.GetInt("DefaultSolver", 0)] @@ -213,7 +223,7 @@ class _SolverDlg(object): self.param_group = FreeCAD.ParamGet(self.param_path) - def get_binary(self): + def get_binary(self, silent=False): # set the binary path to the FreeCAD defaults # ATM pure unix shell commands without path names are used as standard @@ -234,7 +244,7 @@ class _SolverDlg(object): # The user does not know what exactly has going wrong. from distutils.spawn import find_executable as find_bin the_found_binary = find_bin(binary) - if the_found_binary is None: + if (the_found_binary is None) and (not silent): FreeCAD.Console.PrintError( "The binary has not been found. Full binary search path: {}\n" .format(binary)