diff --git a/src/Mod/Draft/DraftSnap.py b/src/Mod/Draft/DraftSnap.py
index 204afde016..63a7425dfd 100644
--- a/src/Mod/Draft/DraftSnap.py
+++ b/src/Mod/Draft/DraftSnap.py
@@ -987,7 +987,8 @@ class Snapper:
self.radius = 0
self.setCursor()
if hideSnapBar or Draft.getParam("hideSnapBar",False):
- self.toolbar.hide()
+ if hasattr(self,"toolbar") and self.toolbar:
+ self.toolbar.hide()
self.mask = None
self.lastArchPoint = None
self.selectMode = False
diff --git a/src/Mod/Fem/Gui/DlgSettingsFemGeneral.ui b/src/Mod/Fem/Gui/DlgSettingsFemGeneral.ui
index 39cae5e047..679ff4f126 100644
--- a/src/Mod/Fem/Gui/DlgSettingsFemGeneral.ui
+++ b/src/Mod/Fem/Gui/DlgSettingsFemGeneral.ui
@@ -67,6 +67,9 @@
WorkingDir
+
+ Gui::FileChooser::Directory
+
Mod/Fem/General
diff --git a/src/Mod/Fem/PyGui/_TaskPanelFemMaterial.py b/src/Mod/Fem/PyGui/_TaskPanelFemMaterial.py
index d1447d5577..667a3ab984 100644
--- a/src/Mod/Fem/PyGui/_TaskPanelFemMaterial.py
+++ b/src/Mod/Fem/PyGui/_TaskPanelFemMaterial.py
@@ -345,7 +345,8 @@ class _TaskPanelFemMaterial:
ym_new_unit = "MPa"
ym = FreeCAD.Units.Quantity(matmap['YoungsModulus'])
ym_with_new_unit = ym.getValueAs(ym_new_unit)
- self.form.input_fd_young_modulus.setText("{} {}".format(ym_with_new_unit, ym_new_unit))
+ q = FreeCAD.Units.Quantity("{} {}".format(ym_with_new_unit, ym_new_unit))
+ self.form.input_fd_young_modulus.setText(q.UserString)
if 'PoissonRatio' in matmap:
self.form.spinBox_poisson_ratio.setValue(float(matmap['PoissonRatio']))
# Fluidic properties
@@ -353,35 +354,41 @@ class _TaskPanelFemMaterial:
nu_new_unit = "m^2/s"
nu = FreeCAD.Units.Quantity(matmap['KinematicViscosity'])
nu_with_new_unit = nu.getValueAs(nu_new_unit)
- self.form.input_fd_kinematic_viscosity.setText("{} {}".format(nu_with_new_unit, nu_new_unit))
+ q = FreeCAD.Units.Quantity("{} {}".format(nu_with_new_unit, nu_new_unit))
+ self.form.input_fd_kinematic_viscosity.setText(q.UserString)
# For isotropic materials the volumetric thermal expansion coefficient is three times the linear coefficient:
if 'VolumetricThermalExpansionCoefficient' in matmap: # linear, only for solid
vtec_new_unit = "m/m/K"
vtec = FreeCAD.Units.Quantity(matmap['VolumetricThermalExpansionCoefficient'])
vtec_with_new_unit = vtec.getValueAs(vtec_new_unit)
- self.form.input_fd_vol_expansion_coefficient.setText("{} {}".format(vtec_with_new_unit, vtec_new_unit))
-
+ q = FreeCAD.Units.Quantity("{} {}".format(vtec_with_new_unit, vtec_new_unit))
+ self.form.input_fd_vol_expansion_coefficient.setText(q.UserString)
if 'Density' in matmap:
density_new_unit = "kg/m^3"
density = FreeCAD.Units.Quantity(matmap['Density'])
density_with_new_unit = density.getValueAs(density_new_unit)
- self.form.input_fd_density.setText("{} {}".format(density_with_new_unit, density_new_unit))
+ #self.form.input_fd_density.setText("{} {}".format(density_with_new_unit, density_new_unit))
+ q = FreeCAD.Units.Quantity("{} {}".format(density_with_new_unit, density_new_unit))
+ self.form.input_fd_density.setText(q.UserString)
# thermal properties
if 'ThermalConductivity' in matmap:
tc_new_unit = "W/m/K"
tc = FreeCAD.Units.Quantity(matmap['ThermalConductivity'])
tc_with_new_unit = tc.getValueAs(tc_new_unit)
- self.form.input_fd_thermal_conductivity.setText("{} {}".format(tc_with_new_unit, tc_new_unit))
+ q = FreeCAD.Units.Quantity("{} {}".format(tc_with_new_unit, tc_new_unit))
+ self.form.input_fd_thermal_conductivity.setText(q.UserString)
if 'ThermalExpansionCoefficient' in matmap: # linear, only for solid
tec_new_unit = "um/m/K"
tec = FreeCAD.Units.Quantity(matmap['ThermalExpansionCoefficient'])
tec_with_new_unit = tec.getValueAs(tec_new_unit)
- self.form.input_fd_expansion_coefficient.setText("{} {}".format(tec_with_new_unit, tec_new_unit))
+ q = FreeCAD.Units.Quantity("{} {}".format(tec_with_new_unit, tec_new_unit))
+ self.form.input_fd_expansion_coefficient.setText(q.UserString)
if 'SpecificHeat' in matmap:
sh_new_unit = "J/kg/K"
sh = FreeCAD.Units.Quantity(matmap['SpecificHeat'])
sh_with_new_unit = sh.getValueAs(sh_new_unit)
- self.form.input_fd_specific_heat.setText("{} {}".format(sh_with_new_unit, sh_new_unit))
+ q = FreeCAD.Units.Quantity("{} {}".format(sh_with_new_unit, sh_new_unit))
+ self.form.input_fd_specific_heat.setText(q.UserString)
def add_transient_material(self, material):
material_name = self.get_material_name(material)
diff --git a/src/Mod/Path/Gui/Resources/panels/HoldingTagsEdit.ui b/src/Mod/Path/Gui/Resources/panels/HoldingTagsEdit.ui
index d713114a74..b73529606d 100644
--- a/src/Mod/Path/Gui/Resources/panels/HoldingTagsEdit.ui
+++ b/src/Mod/Path/Gui/Resources/panels/HoldingTagsEdit.ui
@@ -15,187 +15,156 @@
-
-
-
-
- 0
- 0
-
+
+
+
-
+
+
+ Add...
+
+
+
+ -
+
+
+ false
+
+
+ Delete
+
+
+
+ -
+
+
+ false
+
+
+ Edit...
+
+
+
+ -
+
+
+ Auto Generate
+
+
+
-
+
+
+ 2
+
+
+
+ -
+
+
+ false
+
+
+ Replace All
+
+
+
+ -
+
+
+ Number of Tags
+
+
+ Qt::AlignCenter
+
+
+
+
+
+
+
+
+
+ -
+
+
+ <html><head/><body><p>List of current tags. Edit coordinates by double click or Edit button.</p><p>Tags are automatically disabled if they overlap with the previous tag, or don't lie on the base wire.</p></body></html>
-
- QFrame::NoFrame
-
-
- 0
-
-
-
-
- 0
- 0
- 381
- 528
-
+
+
+ -
+
+
+
+ QFormLayout::AllNonFixedFieldsGrow
-
- Tags
-
-
-
-
-
-
-
- QFormLayout::AllNonFixedFieldsGrow
-
-
-
-
-
- Width
-
-
-
- -
-
-
- Height
-
-
-
- -
-
-
- Angle
-
-
-
- -
-
-
- <html><head/><body><p>Width of the resulting holding tag.</p></body></html>
-
-
-
- -
-
-
- <html><head/><body><p>Height of holding tag.</p><p>Note that resulting tag might be smaller if the tag's width and angle result in a triangular shape.</p></body></html>
-
-
-
- -
-
-
- <html><head/><body><p>Plunge angle for ascent and descent of holding tag.</p></body></html>
-
-
- 5.000000000000000
-
-
- 90.000000000000000
-
-
- 15.000000000000000
-
-
- 45.000000000000000
-
-
-
- -
-
-
- Radius
-
-
-
- -
-
-
- <html><head/><body><p>Radius of the fillet at the top.</p><p>If the radius is too big for the tag shape it gets reduced to the maximum possible radius - resulting in a spherical shape.</p></body></html>
-
-
-
-
-
-
- -
-
-
- <html><head/><body><p>List of current tags. Edit coordinates by double click or Edit button.</p><p>Tags are automatically disabled if they overlap with the previous tag, or don't lie on the base wire.</p></body></html>
-
-
-
- -
-
-
-
-
-
-
- false
-
-
- Delete
-
-
-
- -
-
-
- Add...
-
-
-
- -
-
-
- false
-
-
- Edit...
-
-
-
-
-
-
- -
-
-
- Auto Generate
-
-
-
-
-
-
- 2
-
-
-
- -
-
-
- false
-
-
- Replace All
-
-
-
- -
-
-
- Number of Tags
-
-
- Qt::AlignCenter
-
-
-
-
-
-
-
-
+ -
+
+
+ Width
+
+
+
+ -
+
+
+ Height
+
+
+
+ -
+
+
+ Angle
+
+
+
+ -
+
+
+ <html><head/><body><p>Width of the resulting holding tag.</p></body></html>
+
+
+
+ -
+
+
+ <html><head/><body><p>Height of holding tag.</p><p>Note that resulting tag might be smaller if the tag's width and angle result in a triangular shape.</p></body></html>
+
+
+
+ -
+
+
+ <html><head/><body><p>Plunge angle for ascent and descent of holding tag.</p></body></html>
+
+
+ 5.000000000000000
+
+
+ 90.000000000000000
+
+
+ 15.000000000000000
+
+
+ 45.000000000000000
+
+
+
+ -
+
+
+ Radius
+
+
+
+ -
+
+
+ <html><head/><body><p>Radius of the fillet at the top.</p><p>If the radius is too big for the tag shape it gets reduced to the maximum possible radius - resulting in a spherical shape.</p></body></html>
+
+
+
+
diff --git a/src/Mod/Path/PathScripts/PathDressupHoldingTags.py b/src/Mod/Path/PathScripts/PathDressupHoldingTags.py
index 1ffc6fddc0..c5b49c403e 100644
--- a/src/Mod/Path/PathScripts/PathDressupHoldingTags.py
+++ b/src/Mod/Path/PathScripts/PathDressupHoldingTags.py
@@ -42,8 +42,11 @@ from PySide import QtCore
"""Holding Tags Dressup object and FreeCAD command"""
-PathLog.setLevel(PathLog.Level.INFO, PathLog.thisModule())
-#PathLog.trackModule()
+if False:
+ PathLog.setLevel(PathLog.Level.DEBUG, PathLog.thisModule())
+ PathLog.trackModule()
+else:
+ PathLog.setLevel(PathLog.Level.INFO, PathLog.thisModule())
# Qt tanslation handling
def translate(context, text, disambig=None):
@@ -643,14 +646,18 @@ class PathData:
ordered.append(t)
# disable all tags that are not on the base wire.
for tag in tags:
- PathLog.notice("Tag #%d not on base wire - disabling\n" % len(ordered))
+ PathLog.info("Tag #%d (%.2f, %.2f) not on base wire - disabling\n" % (len(ordered), tag.x, tag.y))
tag.enabled = False
ordered.append(tag)
return ordered
def pointIsOnPath(self, p):
- for e in self.edges:
- if DraftGeomUtils.isPtOnEdge(p, e):
+ v = Part.Vertex(FreeCAD.Vector(p.x, p.y, self.minZ))
+ PathLog.debug("pt = (%f, %f, %f)" % (v.X, v.Y, v.Z))
+ for e in self.bottomEdges:
+ indent = "{} ".format(e.distToShape(v)[0])
+ debugEdge(e, indent, True)
+ if PathGeom.isRoughly(v.distToShape(e)[0], 0.0, 1.0):
return True
return False
@@ -788,7 +795,7 @@ class ObjectTagDressup:
zVal2 = zVal2 and round(zVal2, 8)
if cmd.Name in ['G1', 'G2', 'G3', 'G01', 'G02', 'G03']:
- if zVal is not None and zVal2 != zVal:
+ if False and zVal is not None and zVal2 != zVal:
params['F'] = vertFeed
else:
params['F'] = horizFeed
@@ -823,7 +830,7 @@ class ObjectTagDressup:
if tag.enabled:
if prev:
if prev.solid.common(tag.solid).Faces:
- PathLog.notice("Tag #%d intersects with previous tag - disabling\n" % i)
+ PathLog.info("Tag #%d intersects with previous tag - disabling\n" % i)
PathLog.debug("this tag = %d [%s]" % (i, tag.solid.BoundBox))
tag.enabled = False
elif self.pathData.edges:
@@ -831,7 +838,7 @@ class ObjectTagDressup:
p0 = e.valueAt(e.FirstParameter)
p1 = e.valueAt(e.LastParameter)
if tag.solid.isInside(p0, PathGeom.Tolerance, True) or tag.solid.isInside(p1, PathGeom.Tolerance, True):
- PathLog.notice("Tag #%d intersects with starting point - disabling\n" % i)
+ PathLog.info("Tag #%d intersects with starting point - disabling\n" % i)
tag.enabled = False
if tag.enabled:
diff --git a/src/Mod/Path/PathScripts/PathDressupTagGui.py b/src/Mod/Path/PathScripts/PathDressupTagGui.py
index 1fdfcd9e3d..6b6a7410a8 100644
--- a/src/Mod/Path/PathScripts/PathDressupTagGui.py
+++ b/src/Mod/Path/PathScripts/PathDressupTagGui.py
@@ -27,6 +27,7 @@ import FreeCADGui
import Path
import PathScripts
#import PathScripts.PathDressupTag as PathDressupTag
+import PathScripts.PathGetPoint as PathGetPoint
import PathScripts.PathDressupHoldingTags as PathDressupTag
import PathScripts.PathLog as PathLog
import PathScripts.PathUtils as PathUtils
@@ -56,18 +57,8 @@ class PathDressupTagTaskPanel:
self.obj = obj
self.obj.Proxy.obj = obj
self.viewProvider = viewProvider
- self.form = QtGui.QWidget()
- self.formTags = FreeCADGui.PySideUic.loadUi(":/panels/HoldingTagsEdit.ui")
- self.formPoint = FreeCADGui.PySideUic.loadUi(":/panels/PointEdit.ui")
- self.layout = QtGui.QVBoxLayout(self.form)
- #self.form.setGeometry(self.formTags.geometry())
- self.form.setWindowTitle(self.formTags.windowTitle())
- self.form.setSizePolicy(self.formTags.sizePolicy())
- self.formTags.setParent(self.form)
- self.formPoint.setParent(self.form)
- self.layout.addWidget(self.formTags)
- self.layout.addWidget(self.formPoint)
- self.formPoint.hide()
+ self.form = FreeCADGui.PySideUic.loadUi(":/panels/HoldingTagsEdit.ui")
+ self.getPoint = PathGetPoint.TaskPanel(self.form.removeEditAddGroup, True)
self.jvo = PathUtils.findParentJob(obj).ViewObject
if jvoVisibility is None:
FreeCAD.ActiveDocument.openTransaction(translate("PathDressup_HoldingTags", "Edit HoldingTags Dress-up"))
@@ -78,9 +69,6 @@ class PathDressupTagTaskPanel:
self.jvoVisible = jvoVisibility
self.pt = FreeCAD.Vector(0, 0, 0)
- closeButton = self.formPoint.buttonBox.button(QtGui.QDialogButtonBox.StandardButton.Close)
- closeButton.setText(translate("PathDressup_HoldingTags", "Done"))
-
self.isDirty = True
def getStandardButtons(self):
@@ -92,22 +80,9 @@ class PathDressupTagTaskPanel:
self.obj.Proxy.execute(self.obj)
self.isDirty = False
- def addEscapeShortcut(self):
- # The only way I could get to intercept the escape key, or really any key was
- # by creating an action with a shortcut .....
- self.escape = QtGui.QAction(self.formPoint)
- self.escape.setText('Done')
- self.escape.setShortcut(QtGui.QKeySequence.fromString('Esc'))
- QtCore.QObject.connect(self.escape, QtCore.SIGNAL('triggered()'), self.pointDone)
- self.formPoint.addAction(self.escape)
-
- def removeEscapeShortcut(self):
- if self.escape:
- self.formPoint.removeAction(self.escape)
- self.escape = None
-
def modifyStandardButtons(self, buttonBox):
self.buttonBox = buttonBox
+ self.getPoint.buttonBox = buttonBox
def abort(self):
FreeCAD.ActiveDocument.abortTransaction()
@@ -136,9 +111,9 @@ class PathDressupTagTaskPanel:
def getTags(self, includeCurrent):
tags = []
- index = self.formTags.lwTags.currentRow()
- for i in range(0, self.formTags.lwTags.count()):
- item = self.formTags.lwTags.item(i)
+ index = self.form.lwTags.currentRow()
+ for i in range(0, self.form.lwTags.count()):
+ item = self.form.lwTags.item(i)
enabled = item.checkState() == QtCore.Qt.CheckState.Checked
x = item.data(self.DataX)
y = item.data(self.DataY)
@@ -148,10 +123,10 @@ class PathDressupTagTaskPanel:
return tags
def getFields(self):
- width = FreeCAD.Units.Quantity(self.formTags.ifWidth.text()).Value
- height = FreeCAD.Units.Quantity(self.formTags.ifHeight.text()).Value
- angle = self.formTags.dsbAngle.value()
- radius = FreeCAD.Units.Quantity(self.formTags.ifRadius.text()).Value
+ width = FreeCAD.Units.Quantity(self.form.ifWidth.text()).Value
+ height = FreeCAD.Units.Quantity(self.form.ifHeight.text()).Value
+ angle = self.form.dsbAngle.value()
+ radius = FreeCAD.Units.Quantity(self.form.ifRadius.text()).Value
tags = self.getTags(True)
positions = []
@@ -183,8 +158,8 @@ class PathDressupTagTaskPanel:
def updateTagsView(self):
PathLog.track()
- self.formTags.lwTags.blockSignals(True)
- self.formTags.lwTags.clear()
+ self.form.lwTags.blockSignals(True)
+ self.form.lwTags.clear()
for i, pos in enumerate(self.Positions):
lbl = "%d: (%.2f, %.2f)" % (i, pos.x, pos.y)
item = QtGui.QListWidgetItem(lbl)
@@ -200,41 +175,36 @@ class PathDressupTagTaskPanel:
flags |= QtCore.Qt.ItemFlag.ItemIsEnabled
flags |= QtCore.Qt.ItemFlag.ItemIsUserCheckable
item.setFlags(flags)
- self.formTags.lwTags.addItem(item)
- self.formTags.lwTags.blockSignals(False)
+ self.form.lwTags.addItem(item)
+ self.form.lwTags.blockSignals(False)
self.whenTagSelectionChanged()
self.viewProvider.updatePositions(self.Positions, self.Disabled)
def generateNewTags(self):
- count = self.formTags.sbCount.value()
+ count = self.form.sbCount.value()
if not self.obj.Proxy.generateTags(self.obj, count):
self.obj.Proxy.execute(self.obj)
self.updateTagsView()
- #if PathLog.getLevel(LOG_MODULE) == PathLog.Level.DEBUG:
- # # this causes a big of an echo and a double click on the spin buttons, don't know why though
- # FreeCAD.ActiveDocument.recompute()
-
def updateModel(self):
self.getFields()
self.updateTagsView()
self.isDirty = True
- #FreeCAD.ActiveDocument.recompute()
def whenCountChanged(self):
- count = self.formTags.sbCount.value()
- self.formTags.pbGenerate.setEnabled(count)
+ count = self.form.sbCount.value()
+ self.form.pbGenerate.setEnabled(count)
def selectTagWithId(self, index):
PathLog.track(index)
- self.formTags.lwTags.setCurrentRow(index)
+ self.form.lwTags.setCurrentRow(index)
def whenTagSelectionChanged(self):
- index = self.formTags.lwTags.currentRow()
- count = self.formTags.lwTags.count()
- self.formTags.pbDelete.setEnabled(index != -1 and count > 2)
- self.formTags.pbEdit.setEnabled(index != -1)
+ index = self.form.lwTags.currentRow()
+ count = self.form.lwTags.count()
+ self.form.pbDelete.setEnabled(index != -1 and count > 2)
+ self.form.pbEdit.setEnabled(index != -1)
self.viewProvider.selectTag(index)
def whenTagsViewChanged(self):
@@ -255,11 +225,11 @@ class PathDressupTagTaskPanel:
self.Positions.append(FreeCAD.Vector(point.x, point.y, 0))
self.updateTagsView()
else:
- print("ignore new tag at %s" % (point))
+ print("ignore new tag at %s (obj=%s, on-path=%d" % (point, obj, 0))
def addNewTag(self):
self.tags = self.getTags(True)
- self.getPoint(self.addNewTagAt)
+ self.getPoint.getPoint(self.addNewTagAt)
def editTagAt(self, point, obj):
if point and obj and (obj or point != FreeCAD.Vector()) and self.obj.Proxy.pointIsOnPath(self.obj, point):
@@ -278,10 +248,10 @@ class PathDressupTagTaskPanel:
x = item.data(self.DataX)
y = item.data(self.DataY)
z = item.data(self.DataZ)
- self.getPoint(self.editTagAt, FreeCAD.Vector(x, y, z))
+ self.getPoint.getPoint(self.editTagAt, FreeCAD.Vector(x, y, z))
def editSelectedTag(self):
- self.editTag(self.formTags.lwTags.currentItem())
+ self.editTag(self.form.lwTags.currentItem())
def removeGlobalCallbacks(self):
if hasattr(self, 'view') and self.view:
@@ -293,54 +263,6 @@ class PathDressupTagTaskPanel:
self.pointCbMove = None
self.view = None
- def getPoint(self, whenDone, start=None):
-
- def displayPoint(p):
- self.formPoint.ifValueX.setText(FreeCAD.Units.Quantity(p.x, FreeCAD.Units.Length).UserString)
- self.formPoint.ifValueY.setText(FreeCAD.Units.Quantity(p.y, FreeCAD.Units.Length).UserString)
- self.formPoint.ifValueZ.setText(FreeCAD.Units.Quantity(p.z, FreeCAD.Units.Length).UserString)
- self.formPoint.ifValueX.setFocus()
- self.formPoint.ifValueX.selectAll()
-
- def mouseMove(cb):
- event = cb.getEvent()
- pos = event.getPosition()
- cntrl = event.wasCtrlDown()
- shift = event.wasShiftDown()
- self.pt = FreeCADGui.Snapper.snap(pos, lastpoint=start, active=cntrl, constrain=shift)
- plane = FreeCAD.DraftWorkingPlane
- p = plane.getLocalCoords(self.pt)
- displayPoint(p)
-
- def click(cb):
- event = cb.getEvent()
- if event.getButton() == 1 and event.getState() == coin.SoMouseButtonEvent.DOWN:
- accept()
-
- def accept():
- if start:
- self.pointAccept()
- else:
- self.pointAcceptAndContinue()
-
- def cancel():
- self.pointReject()
-
- self.pointWhenDone = whenDone
- self.formTags.hide()
- self.formPoint.show()
- self.addEscapeShortcut()
- if start:
- displayPoint(start)
- else:
- displayPoint(FreeCAD.Vector(0,0,0))
-
- self.view = Draft.get3DView()
- self.pointCbClick = self.view.addEventCallbackPivy(coin.SoMouseButtonEvent.getClassTypeId(), click)
- self.pointCbMove = self.view.addEventCallbackPivy(coin.SoLocation2Event.getClassTypeId(), mouseMove)
-
- self.buttonBox.setEnabled(False)
-
def setupSpinBox(self, widget, val, decimals = 2):
if decimals:
widget.setDecimals(decimals)
@@ -348,11 +270,11 @@ class PathDressupTagTaskPanel:
def setFields(self):
self.updateTagsView()
- self.formTags.sbCount.setValue(len(self.Positions))
- self.formTags.ifHeight.setText(FreeCAD.Units.Quantity(self.obj.Height, FreeCAD.Units.Length).UserString)
- self.formTags.ifWidth.setText(FreeCAD.Units.Quantity(self.obj.Width, FreeCAD.Units.Length).UserString)
- self.formTags.dsbAngle.setValue(self.obj.Angle)
- self.formTags.ifRadius.setText(FreeCAD.Units.Quantity(self.obj.Radius, FreeCAD.Units.Length).UserString)
+ self.form.sbCount.setValue(len(self.Positions))
+ self.form.ifHeight.setText(FreeCAD.Units.Quantity(self.obj.Height, FreeCAD.Units.Length).UserString)
+ self.form.ifWidth.setText(FreeCAD.Units.Quantity(self.obj.Width, FreeCAD.Units.Length).UserString)
+ self.form.dsbAngle.setValue(self.obj.Angle)
+ self.form.ifRadius.setText(FreeCAD.Units.Quantity(self.obj.Radius, FreeCAD.Units.Length).UserString)
def setupUi(self):
self.Positions = self.obj.Positions
@@ -362,62 +284,22 @@ class PathDressupTagTaskPanel:
self.whenCountChanged()
if self.obj.Proxy.supportsTagGeneration(self.obj):
- self.formTags.sbCount.valueChanged.connect(self.whenCountChanged)
- self.formTags.pbGenerate.clicked.connect(self.generateNewTags)
+ self.form.sbCount.valueChanged.connect(self.whenCountChanged)
+ self.form.pbGenerate.clicked.connect(self.generateNewTags)
else:
- self.formTags.cbTagGeneration.setEnabled(False)
+ self.form.cbTagGeneration.setEnabled(False)
- self.formTags.lwTags.itemChanged.connect(self.whenTagsViewChanged)
- self.formTags.lwTags.itemSelectionChanged.connect(self.whenTagSelectionChanged)
- self.formTags.lwTags.itemActivated.connect(self.editTag)
+ self.form.lwTags.itemChanged.connect(self.whenTagsViewChanged)
+ self.form.lwTags.itemSelectionChanged.connect(self.whenTagSelectionChanged)
+ self.form.lwTags.itemActivated.connect(self.editTag)
- self.formTags.pbDelete.clicked.connect(self.deleteSelectedTag)
- self.formTags.pbEdit.clicked.connect(self.editSelectedTag)
- self.formTags.pbAdd.clicked.connect(self.addNewTag)
-
- self.formPoint.buttonBox.accepted.connect(self.pointAccept)
- self.formPoint.buttonBox.rejected.connect(self.pointReject)
-
- self.formPoint.ifValueX.editingFinished.connect(self.updatePoint)
- self.formPoint.ifValueY.editingFinished.connect(self.updatePoint)
- self.formPoint.ifValueZ.editingFinished.connect(self.updatePoint)
+ self.form.pbDelete.clicked.connect(self.deleteSelectedTag)
+ self.form.pbEdit.clicked.connect(self.editSelectedTag)
+ self.form.pbAdd.clicked.connect(self.addNewTag)
self.viewProvider.turnMarkerDisplayOn(True)
- def pointFinish(self, ok, cleanup = True):
- obj = FreeCADGui.Snapper.lastSnappedObject
- if cleanup:
- self.removeGlobalCallbacks();
- FreeCADGui.Snapper.off()
- self.buttonBox.setEnabled(True)
- self.removeEscapeShortcut()
- self.formPoint.hide()
- self.formTags.show()
- self.formTags.setFocus()
-
- if ok:
- self.pointWhenDone(self.pt, obj)
- else:
- self.pointWhenDone(None, None)
-
- def pointDone(self):
- self.pointFinish(False)
-
- def pointReject(self):
- self.pointFinish(False)
-
- def pointAccept(self):
- self.pointFinish(True)
-
- def pointAcceptAndContinue(self):
- self.pointFinish(True, False)
-
- def updatePoint(self):
- x = FreeCAD.Units.Quantity(self.formPoint.ifValueX.text()).Value
- y = FreeCAD.Units.Quantity(self.formPoint.ifValueY.text()).Value
- z = FreeCAD.Units.Quantity(self.formPoint.ifValueZ.text()).Value
- self.pt = FreeCAD.Vector(x, y, z)
class HoldingTagMarker:
def __init__(self, point, colors):
diff --git a/src/Mod/Path/PathScripts/PathGetPoint.py b/src/Mod/Path/PathScripts/PathGetPoint.py
index b4793fc654..bfe4d19dfb 100644
--- a/src/Mod/Path/PathScripts/PathGetPoint.py
+++ b/src/Mod/Path/PathScripts/PathGetPoint.py
@@ -25,6 +25,7 @@
import Draft
import FreeCAD
import FreeCADGui
+import PathScripts.PathLog as PathLog
from PySide import QtCore, QtGui
from pivy import coin
@@ -34,6 +35,8 @@ __author__ = "sliptonic (Brad Collette)"
__url__ = "http://www.freecadweb.org"
__doc__ = "Helper class to use FreeCADGUi.Snapper to let the user enter arbitray points while the task panel is active."
+PathLog.setLevel(PathLog.Level.INFO, PathLog.thisModule())
+
class TaskPanel:
'''Use an instance of this class in another TaskPanel to invoke the snapper.
Create the instance in the TaskPanel's constructors and invoke getPoint(whenDone, start) whenever a new point is
@@ -41,7 +44,7 @@ class TaskPanel:
provided in the constructor.
The (only) public API function other than the constructor is getPoint(whenDone, start).
'''
- def __init__(self, form):
+ def __init__(self, form, onPath=False):
'''__init___(form) ... form will be replaced by PointEdit.ui while the Snapper is active.'''
self.formOrig = form
self.formPoint = FreeCADGui.PySideUic.loadUi(":/panels/PointEdit.ui")
@@ -52,6 +55,8 @@ class TaskPanel:
self.setupUi()
self.buttonBox = None
+ self.onPath = onPath
+ self.obj = None
def setupUi(self):
'''setupUi() ... internal function - do not call.'''
@@ -95,19 +100,38 @@ class TaskPanel:
self.formPoint.ifValueX.selectAll()
def mouseMove(cb):
+ p = None
event = cb.getEvent()
pos = event.getPosition()
- cntrl = event.wasCtrlDown()
- shift = event.wasShiftDown()
- self.pt = FreeCADGui.Snapper.snap(pos, lastpoint=start, active=cntrl, constrain=shift)
- plane = FreeCAD.DraftWorkingPlane
- p = plane.getLocalCoords(self.pt)
- displayPoint(p)
+ if self.onPath:
+ # There should not be a dependency from Draft->Path, so handle Path "snapping"
+ # directly, at least for now. Simple enough because there isn't really any
+ # "snapping" going on other than what getObjectInfo() provides.
+ screenpos = tuple(pos.getValue())
+ snapInfo = Draft.get3DView().getObjectInfo(screenpos)
+ if snapInfo:
+ obj = FreeCAD.ActiveDocument.getObject(snapInfo['Object'])
+ if hasattr(obj, 'Path'):
+ self.obj = obj
+ p = FreeCAD.Vector(snapInfo['x'], snapInfo['y'], snapInfo['z'])
+ else:
+ self.obj = None
+ else:
+ # Snapper handles regular objects just fine
+ cntrl = event.wasCtrlDown()
+ shift = event.wasShiftDown()
+ self.pt = FreeCADGui.Snapper.snap(pos, lastpoint=start, active=cntrl, constrain=shift)
+ plane = FreeCAD.DraftWorkingPlane
+ p = plane.getLocalCoords(self.pt)
+ self.obj = FreeCADGui.Snapper.lastSnappedObject
+ if p:
+ displayPoint(p)
def click(cb):
event = cb.getEvent()
if event.getButton() == 1 and event.getState() == coin.SoMouseButtonEvent.DOWN:
- accept()
+ if self.obj:
+ accept()
def accept():
if start:
@@ -137,7 +161,6 @@ class TaskPanel:
def pointFinish(self, ok, cleanup = True):
'''pointFinish(ok, cleanup=True) ... internal function - do not call.'''
- obj = FreeCADGui.Snapper.lastSnappedObject
if cleanup:
self.removeGlobalCallbacks()
@@ -150,7 +173,7 @@ class TaskPanel:
self.formOrig.setFocus()
if ok:
- self.pointWhenDone(self.pt, obj)
+ self.pointWhenDone(self.pt, self.obj)
else:
self.pointWhenDone(None, None)
diff --git a/src/Mod/Path/PathScripts/PathSanity.py b/src/Mod/Path/PathScripts/PathSanity.py
index 0c3fb4fce7..14403d0bf3 100644
--- a/src/Mod/Path/PathScripts/PathSanity.py
+++ b/src/Mod/Path/PathScripts/PathSanity.py
@@ -52,98 +52,11 @@ class CommandPathSanity:
def IsActive(self):
obj = FreeCADGui.Selection.getSelectionEx()[0].Object
- if (obj.TypeId == "Path::FeatureCompoundPython"):
+ if hasattr(obj, 'Operations') and hasattr(obj, 'ToolController'):
return True
return False
- def __review(self, obj):
- "checks the selected job for common errors"
- toolcontrolcount = 0
- operationcount = 0
- #global baseobj
-
- # if obj.X_Max == obj.X_Min or obj.Y_Max == obj.Y_Min:
- # FreeCAD.Console.PrintWarning(translate("Path_Sanity", "It appears the machine limits haven't been set. Not able to check path extents.\n"))
-
- if obj.PostProcessor == '':
- FreeCAD.Console.PrintWarning(translate("Path_Sanity", "A Postprocessor has not been selected.\n"))
-
- if obj.PostProcessorOutputFile == '':
- FreeCAD.Console.PrintWarning(translate("Path_Sanity", "No output file is named. You'll be prompted during postprocessing.\n"))
-
- for item in obj.Group:
- print("Checking: " + item.Label)
- if isinstance(item.Proxy, PathScripts.PathToolController.ToolController):
- toolcontrolcount += 1
- self.__checkTC(item)
-
- if isinstance(item.Proxy, PathScripts.PathProfileContour.ObjectContour):
- if item.Active:
- operationcount +=1
- # simobj = item.Proxy.execute(item, getsim=True)
- # if simobj is not None:
- # print ('collision detected')
- # PC.getCollisionObject(self.baseobj, simobj)
-
- if isinstance(item.Proxy, PathScripts.PathProfileFaces.ObjectProfile):
- if item.Active:
- operationcount +=1
- # simobj = item.Proxy.execute(item, getsim=True)
- # if simobj is not None:
- # print ('collision detected')
- # PC.getCollisionObject(self.baseobj, simobj)
-
- if isinstance(item.Proxy, PathScripts.PathProfileEdges.ObjectProfile):
- if item.Active:
- operationcount +=1
- # simobj = item.Proxy.execute(item, getsim=True)
- # if simobj is not None:
- # print ('collision detected')
- # PC.getCollisionObject(self.baseobj, simobj)
-
- if isinstance(item.Proxy, PathScripts.PathPocket.ObjectPocket):
- if item.Active:
- operationcount +=1
- # simobj = item.Proxy.execute(item, getsim=True)
- # if simobj is not None:
- # print ('collision detected')
- # PC.getCollisionObject(self.baseobj, simobj)
-
- if isinstance(item.Proxy, PathScripts.PathDrilling.ObjectDrilling):
- if item.Active:
- operationcount +=1
-
- if isinstance(item.Proxy, PathScripts.PathMillFace.ObjectFace):
- if item.Active:
- operationcount +=1
-
- if isinstance(item.Proxy, PathScripts.PathHelix.ObjectHelix):
- if item.Active:
- operationcount +=1
-
- if isinstance(item.Proxy, PathScripts.PathSurface.ObjectSurface):
- if item.Active:
- operationcount +=1
-
- if operationcount == 0: #no active operations
- FreeCAD.Console.PrintWarning(translate("Path_Sanity", "A Tool Controller was not found. Default values are used which is dangerous. Please add a Tool Controller.\n"))
-
- if toolcontrolcount == 0: #need at least one active TC
- FreeCAD.Console.PrintWarning(translate("Path_Sanity", "A Tool Controller was not found. Default values are used which is dangerous. Please add a Tool Controller.\n"))
-
- def __checkTC(self, item):
- if item.ToolNumber == 0:
- FreeCAD.Console.PrintWarning(translate("Path_Sanity", "Tool Controller: " + str(item.Label) + " is using ID 0 which the undefined default. Please set a real tool.\n"))
- if item.HorizFeed == 0:
- FreeCAD.Console.PrintWarning(translate("Path_Sanity", "Tool Controller: " + str(item.Label) + " has a 0 value for the Horizontal feed rate\n"))
- if item.VertFeed == 0:
- FreeCAD.Console.PrintWarning(translate("Path_Sanity", "Tool Controller: " + str(item.Label) + " has a 0 value for the Vertical feed rate\n"))
- if item.SpindleSpeed == 0:
- FreeCAD.Console.PrintWarning(translate("Path_Sanity", "Tool Controller: " + str(item.Label) + " has a 0 value for the spindle speed\n"))
-
-
def Activated(self):
- #global baseobj
# if everything is ok, execute
obj = FreeCADGui.Selection.getSelectionEx()[0].Object
self.baseobj = obj.Base
@@ -152,6 +65,100 @@ class CommandPathSanity:
return
self.__review(obj)
+ def __review(self, obj):
+ "checks the selected job for common errors"
+ clean = True
+
+ # if obj.X_Max == obj.X_Min or obj.Y_Max == obj.Y_Min:
+ # FreeCAD.Console.PrintWarning(translate("Path_Sanity", "It appears the machine limits haven't been set. Not able to check path extents.\n"))
+
+ if obj.PostProcessor == '':
+ FreeCAD.Console.PrintWarning(translate("Path_Sanity", "A Postprocessor has not been selected.\n"))
+ clean = False
+
+ if obj.PostProcessorOutputFile == '':
+ FreeCAD.Console.PrintWarning(translate("Path_Sanity", "No output file is named. You'll be prompted during postprocessing.\n"))
+ clean = False
+
+ for tc in obj.ToolController:
+ PathLog.info("Checking: {}.{}".format(obj.Label, tc.Label))
+ clean &= self.__checkTC(tc)
+
+ for op in obj.Operations.Group:
+ PathLog.info("Checking: {}.{}".format(obj.Label, op.Label))
+
+ if isinstance(op.Proxy, PathScripts.PathProfileContour.ObjectContour):
+ if op.Active:
+ # simobj = op.Proxy.execute(op, getsim=True)
+ # if simobj is not None:
+ # print ('collision detected')
+ # PC.getCollisionObject(self.baseobj, simobj)
+ # clean = False
+ pass
+
+ if isinstance(op.Proxy, PathScripts.PathProfileFaces.ObjectProfile):
+ if op.Active:
+ # simobj = op.Proxy.execute(op, getsim=True)
+ # if simobj is not None:
+ # print ('collision detected')
+ # PC.getCollisionObject(self.baseobj, simobj)
+ # clean = False
+ pass
+
+ if isinstance(op.Proxy, PathScripts.PathProfileEdges.ObjectProfile):
+ if op.Active:
+ # simobj = op.Proxy.execute(op, getsim=True)
+ # if simobj is not None:
+ # print ('collision detected')
+ # PC.getCollisionObject(self.baseobj, simobj)
+ # clean = False
+ pass
+
+ if isinstance(op.Proxy, PathScripts.PathPocket.ObjectPocket):
+ if op.Active:
+ # simobj = op.Proxy.execute(op, getsim=True)
+ # if simobj is not None:
+ # print ('collision detected')
+ # PC.getCollisionObject(self.baseobj, simobj)
+ # clean = False
+ pass
+
+ if isinstance(op.Proxy, PathScripts.PathPocketShape.ObjectPocket):
+ if op.Active:
+ # simobj = op.Proxy.execute(op, getsim=True)
+ # if simobj is not None:
+ # print ('collision detected')
+ # PC.getCollisionObject(self.baseobj, simobj)
+ # clean = False
+ pass
+
+ if not any(op.Active for op in obj.Operations.Group): #no active operations
+ FreeCAD.Console.PrintWarning(translate("Path_Sanity", "No active operations was found. Post processing will not result in any tooling."))
+ clean = False
+
+ if len(obj.ToolController) == 0: #need at least one active TC
+ FreeCAD.Console.PrintWarning(translate("Path_Sanity", "A Tool Controller was not found. Default values are used which is dangerous. Please add a Tool Controller.\n"))
+ clean = False
+
+ if clean:
+ FreeCAD.Console.PrintMessage(translate("Path_Sanity", "No issues detected, {} has passed basic sanity check.").format(obj.Label))
+
+ def __checkTC(self, tc):
+ clean = True
+ if tc.ToolNumber == 0:
+ FreeCAD.Console.PrintWarning(translate("Path_Sanity", "Tool Controller: " + str(tc.Label) + " is using ID 0 which the undefined default. Please set a real tool.\n"))
+ clean = False
+ if tc.HorizFeed == 0:
+ FreeCAD.Console.PrintWarning(translate("Path_Sanity", "Tool Controller: " + str(tc.Label) + " has a 0 value for the Horizontal feed rate\n"))
+ clean = False
+ if tc.VertFeed == 0:
+ FreeCAD.Console.PrintWarning(translate("Path_Sanity", "Tool Controller: " + str(tc.Label) + " has a 0 value for the Vertical feed rate\n"))
+ clean = False
+ if tc.SpindleSpeed == 0:
+ FreeCAD.Console.PrintWarning(translate("Path_Sanity", "Tool Controller: " + str(tc.Label) + " has a 0 value for the spindle speed\n"))
+ clean = False
+ return clean
+
if FreeCAD.GuiUp:
# register the FreeCAD command
FreeCADGui.addCommand('Path_Sanity',CommandPathSanity())