Merge branch 'main' into cam-postprocessor-errors

This commit is contained in:
Samuel
2025-04-19 00:29:33 +02:00
committed by GitHub
16 changed files with 2492 additions and 2197 deletions

View File

@@ -46,7 +46,7 @@ jobs:
persist-credentials: false
- name: "Run analysis"
uses: ossf/scorecard-action@62b2cac7ed8198b15735ed49ab1e5cf35480ba46 # v2.4.0
uses: ossf/scorecard-action@f49aabe0b5af0936a0987cfb85d86b75731b0186 # v2.4.1
with:
results_file: results.sarif
results_format: sarif

View File

@@ -64,6 +64,15 @@ jobs:
runs-on: ${{ matrix.os }}
environment: weekly-build
steps:
# prevent running out of disk space on Ubuntu runners.
- name: Maximize build space
if: runner.os == 'Linux'
uses: AdityaGarg8/remove-unwanted-software@v5
with:
verbose: 'true'
remove-android: 'true' # (frees ~9 GB)
remove-cached-tools: 'true' # (frees ~8.3 GB)
- name: Harden the runner (Audit all outbound calls)
uses: step-security/harden-runner@c6295a65d1254861815972266d5933fd6e532bdf # v2.11.1
with:

View File

@@ -49,9 +49,8 @@ rm -rf ${conda_env}/lib/cmake/
find . -name "*.h" -type f -delete
find . -name "*.cmake" -type f -delete
build_tag=$(git describe --tags)
python_version=$(python -c 'import platform; print("py" + platform.python_version_tuple()[0] + platform.python_version_tuple()[1])')
version_name="FreeCAD_${build_tag}-Linux-$(uname -m)-${python_version}"
version_name="FreeCAD_${BUILD_TAG}-Linux-$(uname -m)-${python_version}"
echo -e "\################"
echo -e "version_name: ${version_name}"

File diff suppressed because it is too large Load Diff

View File

@@ -20,7 +20,7 @@ backend = { name = "pixi-build-rattler-build", version = "*" }
freecad = { path = "." }
[feature.package.dependencies]
python = "==3.12.9"
python = ">=3.11,<3.12"
## Linux (x86-64)
[feature.package.target.linux-64.dependencies]

View File

@@ -15,13 +15,13 @@ build:
requirements:
build:
- ccache
- cmake>=3.31.6,<4.0.0
- cmake
- compilers
- doxygen
- ninja
- noqt5
- python==3.12.9
- qt6-main==6.8.2
- python>=3.11,<3.12
- qt6-main<6.9
- swig
- if: linux and x86_64
@@ -108,8 +108,8 @@ requirements:
- ply
- pybind11
- pyside6
- python==3.12.9
- qt6-main==6.8.2
- python>=3.11,<3.12
- qt6-main<6.9
- six
- smesh
- vtk
@@ -117,8 +117,9 @@ requirements:
- yaml-cpp
- zlib
- if: windows
- if: win
then:
- winpthreads-devel
- tbb-devel
- if: unix
@@ -142,7 +143,7 @@ requirements:
- docutils
- gmsh
- graphviz
# - ifcopenshell
- ifcopenshell
- jinja2
- lark
- lxml
@@ -160,10 +161,10 @@ requirements:
- ply
- pycollada
- pyside6
- python==3.12.9
- python>=3.11,<3.12
- pythonocc-core
- pyyaml
- qt6-main==6.8.2
- qt6-main<6.9
- requests
- scipy
- sympy

View File

@@ -55,10 +55,8 @@ cp ssl-patch.py ${copy_dir}/bin/Lib/ssl.py
echo '[Paths]' >> ${copy_dir}/bin/qt6.conf
echo 'Prefix = ../lib/qt6' >> ${copy_dir}/bin/qt6.conf
build_tag=$(git describe --tags)
python_version=$(python -c 'import platform; print("py" + platform.python_version_tuple()[0] + platform.python_version_tuple()[1])')
version_name="FreeCAD_${build_tag}-Windows-$(uname -m)-${python_version}"
application_menu_name="FreeCAD_${build_tag}"
version_name="FreeCAD_${BUILD_TAG}-Windows-$(uname -m)-${python_version}"
echo -e "################"
echo -e "version_name: ${version_name}"

View File

@@ -25,7 +25,6 @@
#define GUI_VIEWPROVIDER_DRAGGER_H
#include "ViewProviderDocumentObject.h"
#include "Inventor/Draggers/SoTransformDragger.h"
#include <Base/Placement.h>
#include <App/PropertyGeo.h>
@@ -38,6 +37,7 @@ namespace TaskView {
class TaskDialog;
}
class SoTransformDragger;
class View3DInventorViewer;
/**
@@ -113,7 +113,7 @@ protected:
*/
virtual TaskView::TaskDialog* getTransformDialog();
CoinPtr<SoTransformDragger> transformDragger = nullptr;
CoinPtr<SoTransformDragger> transformDragger;
ViewProvider *forwardedViewProvider = nullptr;
CoinPtr<SoSwitch> pcPlacement;

View File

@@ -295,7 +295,6 @@ class _CommandStructure:
self.Length = params.get_param_arch("StructureLength")
self.Height = params.get_param_arch("StructureHeight")
self.Profile = None
self.continueCmd = False
self.bpoint = None
self.bmode = False
self.precastvalues = None
@@ -338,6 +337,7 @@ class _CommandStructure:
title=translate("Arch","Base point of column")+":"
FreeCAD.activeDraftCommand = self # register as a Draft command for auto grid on/off
FreeCADGui.Snapper.getPoint(callback=self.getPoint,movecallback=self.update,extradlg=[self.taskbox(),self.precast.form,self.dents.form],title=title)
FreeCADGui.draftToolBar.continueCmd.show()
def getPoint(self,point=None,obj=None):
@@ -423,7 +423,7 @@ class _CommandStructure:
FreeCAD.ActiveDocument.recompute()
# gui_utils.end_all_events() # Causes a crash on Linux.
self.tracker.finalize()
if self.continueCmd:
if FreeCADGui.draftToolBar.continueCmd.isChecked():
self.Activated()
def _createItemlist(self, baselist):
@@ -505,21 +505,10 @@ class _CommandStructure:
grid.addWidget(self.vHeight,6,1,1,1)
# horizontal button
value5 = QtGui.QPushButton(translate("Arch","Switch Length/Height"))
grid.addWidget(value5,7,0,1,1)
value6 = QtGui.QPushButton(translate("Arch","Switch Length/Width"))
grid.addWidget(value6,7,1,1,1)
# continue button
label4 = QtGui.QLabel(translate("Arch","Con&tinue"))
value4 = QtGui.QCheckBox()
value4.setObjectName("ContinueCmd")
value4.setLayoutDirection(QtCore.Qt.RightToLeft)
label4.setBuddy(value4)
self.continueCmd = params.get_param("ContinueMode")
value4.setChecked(self.continueCmd)
grid.addWidget(label4,8,0,1,1)
grid.addWidget(value4,8,1,1,1)
value4 = QtGui.QPushButton(translate("Arch","Switch Length/Height"))
grid.addWidget(value4,7,0,1,1)
value5 = QtGui.QPushButton(translate("Arch","Switch Length/Width"))
grid.addWidget(value5,7,1,1,1)
# connect slots
QtCore.QObject.connect(self.valuec,QtCore.SIGNAL("currentIndexChanged(int)"),self.setCategory)
@@ -527,9 +516,8 @@ class _CommandStructure:
QtCore.QObject.connect(self.vLength,QtCore.SIGNAL("valueChanged(double)"),self.setLength)
QtCore.QObject.connect(self.vWidth,QtCore.SIGNAL("valueChanged(double)"),self.setWidth)
QtCore.QObject.connect(self.vHeight,QtCore.SIGNAL("valueChanged(double)"),self.setHeight)
QtCore.QObject.connect(value4,QtCore.SIGNAL("stateChanged(int)"),self.setContinue)
QtCore.QObject.connect(value5,QtCore.SIGNAL("pressed()"),self.rotateLH)
QtCore.QObject.connect(value6,QtCore.SIGNAL("pressed()"),self.rotateLW)
QtCore.QObject.connect(value4,QtCore.SIGNAL("pressed()"),self.rotateLH)
QtCore.QObject.connect(value5,QtCore.SIGNAL("pressed()"),self.rotateLW)
QtCore.QObject.connect(self.modeb,QtCore.SIGNAL("toggled(bool)"),self.switchLH)
# restore preset
@@ -602,11 +590,6 @@ class _CommandStructure:
else:
params.set_param_arch("StructureLength",d)
def setContinue(self,i):
self.continueCmd = bool(i)
params.set_param("ContinueMode", bool(i))
def setCategory(self,i):
self.vPresets.clear()

View File

@@ -38,6 +38,7 @@ class BIM_Beam(ArchStructure._CommandStructure):
def __init__(self):
super().__init__()
self.beammode = True
self.featureName = "Beam"
def IsActive(self):
v = hasattr(FreeCADGui.getMainWindow().getActiveWindow(), "getSceneGraph")

View File

@@ -38,6 +38,7 @@ class BIM_Column(ArchStructure._CommandStructure):
def __init__(self):
super().__init__()
self.beammode = False
self.featureName = "Column"
def IsActive(self):
v = hasattr(FreeCADGui.getMainWindow().getActiveWindow(), "getSceneGraph")

View File

@@ -70,7 +70,7 @@ class Arch_Panel:
self.Width = params.get_param_arch("PanelWidth")
self.Thickness = params.get_param_arch("PanelThickness")
self.Profile = None
self.continueCmd = False
self.featureName = "Panel"
self.rotated = False
sel = FreeCADGui.Selection.getSelection()
if sel:
@@ -96,7 +96,9 @@ class Arch_Panel:
self.tracker.height(self.Thickness)
self.tracker.length(self.Length)
self.tracker.on()
FreeCAD.activeDraftCommand = self
FreeCADGui.Snapper.getPoint(callback=self.getPoint,movecallback=self.update,extradlg=self.taskbox())
FreeCADGui.draftToolBar.continueCmd.show()
def getPoint(self,point=None,obj=None):
@@ -105,6 +107,7 @@ class Arch_Panel:
import DraftVecUtils
self.tracker.finalize()
if point is None:
FreeCAD.activeDraftCommand = None
return
FreeCAD.ActiveDocument.openTransaction(translate("Arch","Create Panel"))
FreeCADGui.addModule("Arch")
@@ -120,7 +123,8 @@ class Arch_Panel:
FreeCADGui.doCommand('s.Placement.Rotation = FreeCAD.Rotation(FreeCAD.Vector(1.00,0.00,0.00),90.00)')
FreeCAD.ActiveDocument.commitTransaction()
FreeCAD.ActiveDocument.recompute()
if self.continueCmd:
FreeCAD.activeDraftCommand = None
if FreeCADGui.draftToolBar.continueCmd.isChecked():
self.Activated()
def taskbox(self):
@@ -166,26 +170,14 @@ class Arch_Panel:
grid.addWidget(self.vHeight,3,1,1,1)
# horizontal button
value5 = QtGui.QPushButton(translate("Arch","Rotate"))
grid.addWidget(value5,4,0,1,2)
# continue button
label4 = QtGui.QLabel(translate("Arch","Con&tinue"))
value4 = QtGui.QCheckBox()
value4.setObjectName("ContinueCmd")
value4.setLayoutDirection(QtCore.Qt.RightToLeft)
label4.setBuddy(value4)
self.continueCmd = params.get_param("ContinueMode")
value4.setChecked(self.continueCmd)
grid.addWidget(label4,5,0,1,1)
grid.addWidget(value4,5,1,1,1)
value4= QtGui.QPushButton(translate("Arch","Rotate"))
grid.addWidget(value4,4,0,1,2)
valuep.currentIndexChanged.connect(self.setPreset)
self.vLength.valueChanged.connect(self.setLength)
self.vWidth.valueChanged.connect(self.setWidth)
self.vHeight.valueChanged.connect(self.setThickness)
value4.stateChanged.connect(self.setContinue)
value5.pressed.connect(self.rotate)
value4.pressed.connect(self.rotate)
return w
def update(self,point,info):
@@ -221,12 +213,6 @@ class Arch_Panel:
self.Length = d.Value
params.set_param_arch("PanelLength",d)
def setContinue(self,i):
from draftutils import params
self.continueCmd = bool(i)
params.set_param("ContinueMode", bool(i))
def setPreset(self,i):
if i > 0:

View File

@@ -75,7 +75,7 @@ class Arch_Wall:
self.MultiMat = None
self.Length = None
self.lengthValue = 0
self.continueCmd = False
self.featureName = "Wall"
self.Width = params.get_param_arch("WallWidth")
self.Height = params.get_param_arch("WallHeight")
self.JOIN_WALLS_SKETCHES = params.get_param_arch("joinWallSketches")
@@ -118,6 +118,7 @@ class Arch_Wall:
FreeCADGui.Snapper.getPoint(callback=self.getPoint,
extradlg=self.taskbox(),
title=translate("Arch","First point of wall")+":")
FreeCADGui.draftToolBar.continueCmd.show()
def getPoint(self,point=None,obj=None):
"""Callback for clicks during interactive mode.
@@ -194,7 +195,7 @@ class Arch_Wall:
FreeCAD.ActiveDocument.recompute()
# gui_utils.end_all_events() # Causes a crash on Linux.
self.tracker.finalize()
if self.continueCmd:
if FreeCADGui.draftToolBar.continueCmd.isChecked():
self.Activated()
def addDefault(self):
@@ -319,31 +320,20 @@ class Arch_Wall:
grid.addWidget(label3,4,0,1,1)
grid.addWidget(value3,4,1,1,1)
label4 = QtGui.QLabel(translate("Arch","Con&tinue"))
label4 = QtGui.QLabel(translate("Arch","Use sketches"))
value4 = QtGui.QCheckBox()
value4.setObjectName("ContinueCmd")
value4.setObjectName("UseSketches")
value4.setLayoutDirection(QtCore.Qt.RightToLeft)
label4.setBuddy(value4)
self.continueCmd = params.get_param("ContinueMode")
value4.setChecked(self.continueCmd)
value4.setChecked(params.get_param_arch("WallSketches"))
grid.addWidget(label4,5,0,1,1)
grid.addWidget(value4,5,1,1,1)
label5 = QtGui.QLabel(translate("Arch","Use sketches"))
value5 = QtGui.QCheckBox()
value5.setObjectName("UseSketches")
value5.setLayoutDirection(QtCore.Qt.RightToLeft)
label5.setBuddy(value5)
value5.setChecked(params.get_param_arch("WallSketches"))
grid.addWidget(label5,6,0,1,1)
grid.addWidget(value5,6,1,1,1)
self.Length.valueChanged.connect(self.setLength)
value1.valueChanged.connect(self.setWidth)
value2.valueChanged.connect(self.setHeight)
value3.currentIndexChanged.connect(self.setAlign)
value4.stateChanged.connect(self.setContinue)
value5.stateChanged.connect(self.setUseSketch)
value4.stateChanged.connect(self.setUseSketch)
self.Length.returnPressed.connect(value1.setFocus)
self.Length.returnPressed.connect(value1.selectAll)
value1.returnPressed.connect(value2.setFocus)
@@ -397,16 +387,6 @@ class Arch_Wall:
self.Align = ["Center","Left","Right"][i]
params.set_param_arch("WallAlignment",i)
def setContinue(self,i):
"""Simple callback to set if the interactive mode will restart when finished.
This allows for several walls to be placed one after another.
"""
from draftutils import params
self.continueCmd = bool(i)
params.set_param("ContinueMode", bool(i))
def setUseSketch(self,i):
"""Simple callback to set if walls should based on sketches."""

View File

@@ -156,6 +156,7 @@ class DraftToolBar:
self.paramconstr = utils.rgba_to_argb(params.get_param("constructioncolor"))
self.constrMode = False
self.continueMode = False
self.chainedMode = False
self.relativeMode = True
self.globalMode = False
self.state = None
@@ -390,7 +391,11 @@ class DraftToolBar:
self.relativeMode = params.get_param("RelativeMode")
self.globalMode = params.get_param("GlobalMode")
self.makeFaceMode = params.get_param("MakeFaceMode")
self.continueMode = params.get_param("ContinueMode")
feature_name = getattr(FreeCAD.activeDraftCommand, "featureName", None)
self.continueMode = params.get_param(feature_name, "Mod/Draft/ContinueMode", silent=True)
self.chainedMode = params.get_param("ChainedMode")
# Note: The order of the calls to self._checkbox() below controls
# the position of the checkboxes in the task panel.
@@ -399,7 +404,11 @@ class DraftToolBar:
self.isRelative = self._checkbox("isRelative", self.layout, checked=self.relativeMode)
self.isGlobal = self._checkbox("isGlobal", self.layout, checked=self.globalMode)
self.makeFace = self._checkbox("makeFace", self.layout, checked=self.makeFaceMode)
self.continueCmd = self._checkbox("continueCmd", self.layout, checked=self.continueMode)
self.continueCmd = self._checkbox("continueCmd", self.layout, checked=bool(self.continueMode))
self.chainedModeCmd = self._checkbox("chainedModeCmd", self.layout, checked=self.chainedMode)
self.chainedModeCmd.setEnabled(not (hasattr(self.sourceCmd, "contMode") and self.continueMode))
self.continueCmd.setEnabled(not (hasattr(self.sourceCmd, "chain") and self.chainedMode))
# update checkboxes without parameters and without internal modes:
self.occOffset = self._checkbox("occOffset", self.layout, checked=False)
@@ -449,6 +458,7 @@ class DraftToolBar:
QtCore.QObject.connect(self.undoButton,QtCore.SIGNAL("pressed()"),self.undoSegment)
QtCore.QObject.connect(self.selectButton,QtCore.SIGNAL("pressed()"),self.selectEdge)
QtCore.QObject.connect(self.continueCmd,QtCore.SIGNAL("stateChanged(int)"),self.setContinue)
QtCore.QObject.connect(self.chainedModeCmd,QtCore.SIGNAL("stateChanged(int)"),self.setChainedMode)
QtCore.QObject.connect(self.isCopy,QtCore.SIGNAL("stateChanged(int)"),self.setCopymode)
QtCore.QObject.connect(self.isSubelementMode, QtCore.SIGNAL("stateChanged(int)"), self.setSubelementMode)
@@ -549,6 +559,9 @@ class DraftToolBar:
+ "the command button again"))
self.continueCmd.setText(translate(
"draft", "Continue") + " (" + _get_incmd_shortcut("Continue") + ")")
self.chainedModeCmd.setText(translate("draft", "Chained Mode"))
self.chainedModeCmd.setToolTip(translate("draft", "If checked, next Dimension will be placed in a chain" \
" with the previously placed Dimension"))
self.occOffset.setToolTip(translate(
"draft", "If checked, an OCC-style offset will be performed"
+ " instead of the classic offset"))
@@ -920,8 +933,14 @@ class DraftToolBar:
#---------------------------------------------------------------------------
def setContinue(self, val):
params.set_param("ContinueMode", bool(val))
params.set_param(FreeCAD.activeDraftCommand.featureName, bool(val), "Mod/Draft/ContinueMode")
self.continueMode = bool(val)
self.chainedModeCmd.setEnabled(not val)
def setChainedMode(self, val):
params.set_param("ChainedMode", bool(val))
self.chainedMode = bool(val)
self.continueCmd.setEnabled(not val)
# val=-1 is used to temporarily switch to relativeMode and disable the checkbox.
# val=-2 is used to switch back.

View File

@@ -74,8 +74,10 @@ class Dimension(gui_base_original.Creator):
def __init__(self):
super().__init__()
self.max = 2
self.cont = None
self.chain = None
self.contMode = None
self.dir = None
self.featureName = "Dimension"
def GetResources(self):
"""Set icon, menu and tooltip."""
@@ -87,13 +89,14 @@ class Dimension(gui_base_original.Creator):
def Activated(self):
"""Execute when the command is called."""
if self.cont:
if self.chain and not self.contMode:
self.finish()
else:
super().Activated(name="Dimension")
super().Activated(name=self.featureName)
if self.ui:
self.ui.pointUi(title=translate("draft", "Dimension"), icon="Draft_Dimension")
self.ui.pointUi(title=translate("draft", self.featureName), icon="Draft_Dimension")
self.ui.continueCmd.show()
self.ui.chainedModeCmd.show()
self.ui.selectButton.show()
self.altdown = False
self.call = self.view.addEventCallback("SoEvent", self.action)
@@ -159,7 +162,8 @@ class Dimension(gui_base_original.Creator):
def finish(self, cont=False):
"""Terminate the operation."""
self.end_callbacks(self.call)
self.cont = None
self.chain = None
self.contMode = None
self.dir = None
if self.ui:
self.dimtrack.finalize()
@@ -283,8 +287,9 @@ class Dimension(gui_base_original.Creator):
# Linear dimension, not linked to any edge
self.create_linear_dimension()
if self.ui.continueMode:
self.cont = self.node[2]
if self.ui.chainedMode or self.ui.continueMode:
if self.ui.chainedMode:
self.chain = self.node[2]
if not self.dir:
if self.link:
v1 = self.link[0].Shape.Vertexes[self.link[1]].Point
@@ -339,7 +344,7 @@ class Dimension(gui_base_original.Creator):
ed = ob.Shape.Edges[num]
v1 = ed.Vertexes[0].Point
v2 = ed.Vertexes[-1].Point
self.dimtrack.update([v1, v2, self.cont])
self.dimtrack.update([v1, v2, self.chain])
else:
if self.node and (len(self.edges) < 2):
self.dimtrack.on()
@@ -413,7 +418,7 @@ class Dimension(gui_base_original.Creator):
# update the dimline
if self.node and not self.arcmode:
self.dimtrack.update(self.node
+ [self.point] + [self.cont])
+ [self.point] + [self.chain])
gui_tool_utils.redraw3DView()
elif arg["Type"] == "SoMouseButtonEvent":
if (arg["State"] == "DOWN") and (arg["Button"] == "BUTTON1"):
@@ -493,10 +498,10 @@ class Dimension(gui_base_original.Creator):
self.dimtrack.on()
if self.planetrack:
self.planetrack.set(self.node[0])
elif len(self.node) == 2 and self.cont:
self.node.append(self.cont)
elif len(self.node) == 2 and self.chain:
self.node.append(self.chain)
self.createObject()
if not self.cont:
if not self.chain:
self.finish()
elif len(self.node) == 3:
# for unlinked arc mode:
@@ -506,7 +511,10 @@ class Dimension(gui_base_original.Creator):
# cen = self.node[0].add(v)
# self.node = [self.node[0], self.node[1], cen]
self.createObject()
if not self.cont:
if self.ui.continueMode:
self.contMode = True
self.Activated()
elif not self.chain:
self.finish()
elif self.angledata:
self.node.append(self.point)
@@ -526,7 +534,7 @@ class Dimension(gui_base_original.Creator):
self.dimtrack.on()
elif len(self.node) == 3:
self.createObject()
if not self.cont:
if not self.chain:
self.finish()
def set_constraint_node(self):

View File

@@ -404,8 +404,8 @@ def _get_param_dictionary():
param_dict["Mod/Draft"] = {
"AnnotationStyleEditorHeight": ("int", 450),
"AnnotationStyleEditorWidth": ("int", 450),
"ChainedMode": ("bool", False),
"CenterPlaneOnView": ("bool", False),
"ContinueMode": ("bool", False),
"CopyMode": ("bool", False),
"DefaultAnnoDisplayMode": ("int", 0),
"DefaultDisplayMode": ("int", 0),
@@ -443,6 +443,35 @@ def _get_param_dictionary():
"useSupport": ("bool", False),
}
param_dict["Mod/Draft/ContinueMode"] = {
# Draft
"Line": ("bool", False),
"Polyline": ("bool", False),
"Arc": ("bool", False),
"Arc_3Points": ("bool", False),
"Circle": ("bool", False),
"Ellipse": ("bool", False),
"Rectangle": ("bool", False),
"Polygon": ("bool", False),
"Bspline": ("bool", False),
"CubicBezCurve": ("bool", False),
"BezCurve": ("bool", False),
"Point": ("bool", False),
"Text": ("bool", False),
"Dimension": ("bool", False),
# Standard operations (Draft)
"Move": ("bool", False),
"Copy": ("bool", False),
"Rotate": ("bool", False),
# Arch/BIM
"Wall": ("bool", False),
"Column": ("bool", False),
"Beam": ("bool", False),
"Panel": ("bool", False),
}
# Arch parameters that are not in the preferences:
param_dict["Mod/Arch"] = {
"applyConstructionStyle": ("bool", True),
@@ -634,7 +663,7 @@ def _get_param_dictionary():
PARAM_DICT = _get_param_dictionary()
def get_param(entry, path="Mod/Draft", ret_default=False):
def get_param(entry, path="Mod/Draft", ret_default=False, silent=False):
"""Return a stored parameter value or its default.
Parameters
@@ -648,13 +677,17 @@ def get_param(entry, path="Mod/Draft", ret_default=False):
ret_default: bool, optional
Defaults to `False`.
If `True`, always return the default value even if a stored value is available.
silent: bool, optional
Defaults to `False`.
If `True`, do not log anything if entry wasn't found.
Returns
-------
bool, float, int or str (if successful) or `None`.
"""
if path not in PARAM_DICT or entry not in PARAM_DICT[path]:
print(f"draftutils.params.get_param: Unable to find '{entry}' in '{path}'")
if not silent:
print(f"draftutils.params.get_param: Unable to find '{entry}' in '{path}'")
return None
param_grp = App.ParamGet("User parameter:BaseApp/Preferences/" + path)
typ, default = PARAM_DICT[path][entry]