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())