FEM: improve gmsh binary lookup logic

fixes https://github.com/flathub/org.freecad.FreeCAD/issues/28
also remove unnnecessary/redundant UseStandardGmshLocation preference
This commit is contained in:
Adrian Insaurralde Avalos
2025-08-29 20:51:42 -03:00
committed by Chris Hennes
parent cd0502a155
commit 8a73146311
5 changed files with 60 additions and 176 deletions

View File

@@ -35,48 +35,7 @@
<item>
<layout class="QGridLayout" name="gridLayout">
<item row="0" column="1">
<widget class="Gui::PrefCheckBox" name="cb_gmsh_binary_std">
<property name="text">
<string>Search in known binary directories</string>
</property>
<property name="checked">
<bool>true</bool>
</property>
<property name="prefEntry" stdset="0">
<cstring>UseStandardGmshLocation</cstring>
</property>
<property name="prefPath" stdset="0">
<cstring>Mod/Fem/Gmsh</cstring>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="l_gmsh_binary_path">
<property name="enabled">
<bool>false</bool>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>100</width>
<height>0</height>
</size>
</property>
<property name="text">
<string>Gmsh binary path</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="Gui::PrefFileChooser" name="fc_gmsh_binary_path">
<property name="enabled">
<bool>false</bool>
</property>
<widget class="Gui::PrefFileChooser" name="fc_gmsh_binary_path" native="true">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>0</horstretch>
@@ -112,6 +71,25 @@
</property>
</widget>
</item>
<item row="0" column="0">
<widget class="QLabel" name="l_gmsh_binary_path">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>100</width>
<height>0</height>
</size>
</property>
<property name="text">
<string>Gmsh binary path</string>
</property>
</widget>
</item>
</layout>
</item>
</layout>
@@ -209,11 +187,6 @@
<extends>Gui::FileChooser</extends>
<header>Gui/PrefWidgets.h</header>
</customwidget>
<customwidget>
<class>Gui::PrefCheckBox</class>
<extends>QCheckBox</extends>
<header>Gui/PrefWidgets.h</header>
</customwidget>
<customwidget>
<class>Gui::PrefComboBox</class>
<extends>QComboBox</extends>
@@ -228,70 +201,5 @@
<resources>
<include location="Resources/Fem.qrc"/>
</resources>
<connections>
<connection>
<sender>cb_gmsh_binary_std</sender>
<signal>toggled(bool)</signal>
<receiver>l_gmsh_binary_path</receiver>
<slot>setEnabled(bool)</slot>
<hints>
<hint type="sourcelabel">
<x>406</x>
<y>45</y>
</hint>
<hint type="destinationlabel">
<x>148</x>
<y>68</y>
</hint>
</hints>
</connection>
<connection>
<sender>cb_gmsh_binary_std</sender>
<signal>toggled(bool)</signal>
<receiver>fc_gmsh_binary_path</receiver>
<slot>setEnabled(bool)</slot>
<hints>
<hint type="sourcelabel">
<x>406</x>
<y>45</y>
</hint>
<hint type="destinationlabel">
<x>406</x>
<y>68</y>
</hint>
</hints>
</connection>
<connection>
<sender>cb_gmsh_binary_std</sender>
<signal>toggled(bool)</signal>
<receiver>l_gmsh_binary_path</receiver>
<slot>setDisabled(bool)</slot>
<hints>
<hint type="sourcelabel">
<x>406</x>
<y>45</y>
</hint>
<hint type="destinationlabel">
<x>148</x>
<y>68</y>
</hint>
</hints>
</connection>
<connection>
<sender>cb_gmsh_binary_std</sender>
<signal>toggled(bool)</signal>
<receiver>fc_gmsh_binary_path</receiver>
<slot>setDisabled(bool)</slot>
<hints>
<hint type="sourcelabel">
<x>406</x>
<y>45</y>
</hint>
<hint type="destinationlabel">
<x>406</x>
<y>68</y>
</hint>
</hints>
</connection>
</connections>
<connections/>
</ui>

View File

@@ -25,6 +25,7 @@
#include "PreCompiled.h"
#ifndef _PreComp_
#include <QMessageBox>
#include <QStandardPaths>
#include <QThread>
#endif
@@ -42,16 +43,15 @@ DlgSettingsFemGmshImp::DlgSettingsFemGmshImp(QWidget* parent)
ui->setupUi(this);
connect(ui->fc_gmsh_binary_path,
&Gui::PrefFileChooser::fileNameChanged,
&Gui::PrefFileChooser::fileNameSelected,
this,
&DlgSettingsFemGmshImp::onfileNameChanged);
&DlgSettingsFemGmshImp::onfileNameSelected);
}
DlgSettingsFemGmshImp::~DlgSettingsFemGmshImp() = default;
void DlgSettingsFemGmshImp::saveSettings()
{
ui->cb_gmsh_binary_std->onSave();
ui->fc_gmsh_binary_path->onSave();
ui->cb_log_verbosity->onSave();
ui->sb_threads->onSave();
@@ -59,7 +59,6 @@ void DlgSettingsFemGmshImp::saveSettings()
void DlgSettingsFemGmshImp::loadSettings()
{
ui->cb_gmsh_binary_std->onRestore();
ui->fc_gmsh_binary_path->onRestore();
ParameterGrp::handle hGrp = App::GetApplication().GetParameterGroupByPath(
@@ -84,14 +83,15 @@ void DlgSettingsFemGmshImp::changeEvent(QEvent* e)
}
}
void DlgSettingsFemGmshImp::onfileNameChanged(QString FileName)
void DlgSettingsFemGmshImp::onfileNameSelected(QString FileName)
{
if (!QFileInfo::exists(FileName)) {
QMessageBox::critical(this,
tr("File does not exist"),
tr("The specified executable\n'%1'\n does not exist!\n"
"Specify another file.")
.arg(FileName));
if (!FileName.isEmpty() && QStandardPaths::findExecutable(FileName).isEmpty()) {
QMessageBox::critical(
this,
tr("Not an executable binary"),
tr("The specified file \n'%1'\n does not exist or is not executable.\n"
"Specify another file.")
.arg(FileName));
}
}

View File

@@ -41,7 +41,7 @@ public:
~DlgSettingsFemGmshImp() override;
protected Q_SLOTS:
void onfileNameChanged(QString FileName);
void onfileNameSelected(QString FileName);
protected:
void saveSettings() override;

View File

@@ -81,6 +81,7 @@
#include <QPushButton>
#include <QSlider>
#include <QStackedWidget>
#include <QStandardPaths>
#include <QString>
#include <QStringList>
#include <QTextCharFormat>

View File

@@ -29,6 +29,7 @@ __url__ = "https://www.freecad.org"
import os
import re
import shutil
import subprocess
from PySide.QtCore import QProcess, QThread
@@ -337,59 +338,33 @@ class GmshTools:
Console.PrintMessage(" " + self.temp_file_geo + "\n")
def get_gmsh_command(self):
from platform import system
gmsh_std_location = FreeCAD.ParamGet(
self.gmsh_bin = FreeCAD.ParamGet(
"User parameter:BaseApp/Preferences/Mod/Fem/Gmsh"
).GetBool("UseStandardGmshLocation")
if gmsh_std_location:
if system() == "Windows":
gmsh_path = FreeCAD.getHomePath() + "bin/gmsh.exe"
FreeCAD.ParamGet("User parameter:BaseApp/Preferences/Mod/Fem/Gmsh").SetString(
"gmshBinaryPath", gmsh_path
)
self.gmsh_bin = gmsh_path
elif system() == "Linux":
p1 = subprocess.Popen(["which", "gmsh"], stdout=subprocess.PIPE)
if p1.wait() == 0:
output = p1.stdout.read()
output = output.decode("utf-8")
gmsh_path = output.split("\n")[0]
elif p1.wait() == 1:
error_message = (
"Gmsh binary gmsh not found in standard system binary path. "
"Please install Gmsh or set path to binary "
"in FEM preferences tab Gmsh.\n"
)
Console.PrintError(error_message)
raise GmshError(error_message)
self.gmsh_bin = gmsh_path
elif system() == "Darwin":
# https://forum.freecad.org/viewtopic.php?f=13&t=73041&p=642026#p642022
gmsh_path = "/Applications/Gmsh.app/Contents/MacOS/gmsh"
FreeCAD.ParamGet("User parameter:BaseApp/Preferences/Mod/Fem/Gmsh").SetString(
"gmshBinaryPath", gmsh_path
)
self.gmsh_bin = gmsh_path
else:
).GetString("gmshBinaryPath", "")
if self.gmsh_bin and not shutil.which(self.gmsh_bin):
error_message = (
f"Configured Gmsh binary '${self.gmsh_bin}' not found. Please set path to "
"binary in FEM's Gmsh preferences page or leave blank to use default binary.\n"
)
Console.PrintError(error_message)
raise GmshError(error_message)
if not self.gmsh_bin:
from platform import system
gmsh_path = shutil.which("gmsh")
if system() == "Darwin" and not gmsh_path:
gmsh_path = shutil.which("/Applications/Gmsh.app/Contents/MacOS/gmsh")
if not gmsh_path:
error_message = (
"No standard location implemented for your operating system. "
"Set GMHS binary path in FEM preferences.\n"
"Gmsh binary not found. Please install Gmsh or set path to binary "
"in FEM's Gmsh preferences page.\n"
)
Console.PrintError(error_message)
raise GmshError(error_message)
else:
if not self.gmsh_bin:
self.gmsh_bin = FreeCAD.ParamGet(
"User parameter:BaseApp/Preferences/Mod/Fem/Gmsh"
).GetString("gmshBinaryPath", "")
if not self.gmsh_bin: # in prefs not set, we will try to use something reasonable
if system() == "Linux":
self.gmsh_bin = "gmsh"
elif system() == "Windows":
self.gmsh_bin = FreeCAD.getHomePath() + "bin/gmsh.exe"
else:
self.gmsh_bin = "gmsh"
self.gmsh_bin = gmsh_path
Console.PrintMessage(" " + self.gmsh_bin + "\n")
def get_group_data(self):
@@ -433,7 +408,7 @@ class GmshTools:
def version(self):
self.get_gmsh_command()
if os.path.exists(self.gmsh_bin):
if shutil.which(self.gmsh_bin):
found_message = "file found: " + self.gmsh_bin
Console.PrintMessage(found_message + "\n")
else:
@@ -949,10 +924,10 @@ class GmshTools:
# print(output)
# print(error)
except Exception:
if os.path.exists(self.gmsh_bin):
if shutil.which(self.gmsh_bin):
error = "Error executing: {}\n".format(" ".join(command_list))
else:
error = f"Gmsh executable not found: {self.gmsh_bin}\n"
error = f"Gmsh executable not found: '{self.gmsh_bin}'\n"
Console.PrintError(error)
self.error = True