From 59f0e450ae78a157032e4833e06220c8f094b76e Mon Sep 17 00:00:00 2001 From: Markus Lampert Date: Tue, 25 Jul 2017 22:45:17 -0700 Subject: [PATCH] Moved existing holding tag dressup to use the common UI implementation. --- src/Mod/Path/InitGui.py | 4 +- .../PathScripts/PathDressupHoldingTags.py | 589 ++---------------- src/Mod/Path/PathScripts/PathDressupTag.py | 14 +- src/Mod/Path/PathScripts/PathDressupTagGui.py | 58 +- 4 files changed, 81 insertions(+), 584 deletions(-) diff --git a/src/Mod/Path/InitGui.py b/src/Mod/Path/InitGui.py index 7ae7566b18..a2985d7649 100644 --- a/src/Mod/Path/InitGui.py +++ b/src/Mod/Path/InitGui.py @@ -51,7 +51,6 @@ class PathWorkbench (Workbench): from PathScripts import PathDressup from PathScripts import PathDressupDogbone from PathScripts import PathDressupDragknife - from PathScripts import PathDressupHoldingTags from PathScripts import PathDressupRampEntry from PathScripts import PathDressupTagGui from PathScripts import PathDrilling @@ -87,7 +86,7 @@ class PathWorkbench (Workbench): twodopcmdlist = ["Path_Contour", "Path_Profile", "Path_Profile_Edges", "Path_Pocket", "Path_Drilling", "Path_Engrave", "Path_MillFace", "Path_Helix"] threedopcmdlist = ["Path_Surfacing"] modcmdlist = ["Path_Copy", "Path_CompoundExtended", "Path_Array", "Path_SimpleCopy" ] - dressupcmdlist = ["PathDressup_Dogbone", "PathDressup_DragKnife", "PathDressup_HoldingTags", "PathDressup_Tag", "PathDressup_RampEntry"] + dressupcmdlist = ["PathDressup_Dogbone", "PathDressup_DragKnife", "PathDressup_Tag", "PathDressup_RampEntry"] extracmdlist = ["Path_SelectLoop", "Path_Shape", "Path_Area", "Path_Area_Workplane", "Path_Stock"] #modcmdmore = ["Path_Hop",] #remotecmdlist = ["Path_Remote"] @@ -145,7 +144,6 @@ class PathWorkbench (Workbench): if "Job" in selectedName: self.appendContextMenu("", ["Path_ExportTemplate"]) if "Profile" in selectedName or "Contour" in selectedName: - #self.appendContextMenu("", ["Add_Tag"]) #self.appendContextMenu("", ["Set_StartPoint"]) #self.appendContextMenu("", ["Set_EndPoint"]) for cmd in self.dressupcmds: diff --git a/src/Mod/Path/PathScripts/PathDressupHoldingTags.py b/src/Mod/Path/PathScripts/PathDressupHoldingTags.py index 56607ec52d..5e551f3a18 100644 --- a/src/Mod/Path/PathScripts/PathDressupHoldingTags.py +++ b/src/Mod/Path/PathScripts/PathDressupHoldingTags.py @@ -2,7 +2,7 @@ # *************************************************************************** # * * -# * Copyright (c) 2016 sliptonic * +# * Copyright (c) 2017 sliptonic * # * * # * This program is free software; you can redistribute it and/or modify * # * it under the terms of the GNU Lesser General Public License (LGPL) * @@ -22,12 +22,13 @@ # * * # *************************************************************************** import FreeCAD -import FreeCADGui -import Draft import DraftGeomUtils -import Path -import PathScripts.PathLog as PathLog import Part +import Path +import PathScripts +import PathScripts.PathLog as PathLog +import PathScripts.PathPreferencesPathDressup as PathPreferencesPathDressup +import PathScripts.PathUtils as PathUtils import copy import math @@ -40,20 +41,15 @@ from PySide import QtCore """Holding Tags Dressup object and FreeCAD command""" +PathLog.setLevel(PathLog.Level.INFO, PathLog.thisModule()) +#PathLog.trackModule() + # Qt tanslation handling def translate(context, text, disambig=None): return QtCore.QCoreApplication.translate(context, text, disambig) - -LOG_MODULE = PathLog.thisModule() -PathLog.setLevel(PathLog.Level.INFO, LOG_MODULE) - -if FreeCAD.GuiUp: - from pivy import coin - from PySide import QtGui - def debugEdge(edge, prefix, force = False): - if force or PathLog.getLevel(LOG_MODULE) == PathLog.Level.DEBUG: + if force or PathLog.getLevel(PathLog.thisModule()) == PathLog.Level.DEBUG: pf = edge.valueAt(edge.FirstParameter) pl = edge.valueAt(edge.LastParameter) if type(edge.Curve) == Part.Line or type(edge.Curve) == Part.LineSegment: @@ -63,7 +59,7 @@ def debugEdge(edge, prefix, force = False): print("%s %s((%.2f, %.2f, %.2f) - (%.2f, %.2f, %.2f) - (%.2f, %.2f, %.2f))" % (prefix, type(edge.Curve), pf.x, pf.y, pf.z, pm.x, pm.y, pm.z, pl.x, pl.y, pl.z)) def debugMarker(vector, label, color = None, radius = 0.5): - if PathLog.getLevel(LOG_MODULE) == PathLog.Level.DEBUG: + if PathLog.getLevel(PathLog.thisModule()) == PathLog.Level.DEBUG: obj = FreeCAD.ActiveDocument.addObject("Part::Sphere", label) obj.Label = label obj.Radius = radius @@ -72,7 +68,7 @@ def debugMarker(vector, label, color = None, radius = 0.5): obj.ViewObject.ShapeColor = color def debugCylinder(vector, r, height, label, color = None): - if PathLog.getLevel(LOG_MODULE) == PathLog.Level.DEBUG: + if PathLog.getLevel(PathLog.thisModule()) == PathLog.Level.DEBUG: obj = FreeCAD.ActiveDocument.addObject("Part::Cylinder", label) obj.Label = label obj.Radius = r @@ -83,7 +79,7 @@ def debugCylinder(vector, r, height, label, color = None): obj.ViewObject.ShapeColor = color def debugCone(vector, r1, r2, height, label, color = None): - if PathLog.getLevel(LOG_MODULE) == PathLog.Level.DEBUG: + if PathLog.getLevel(PathLog.thisModule()) == PathLog.Level.DEBUG: obj = FreeCAD.ActiveDocument.addObject("Part::Cone", label) obj.Label = label obj.Radius1 = r1 @@ -658,10 +654,10 @@ class PathData: return False -class ObjectDressup: +class ObjectTagDressup: + + def __init__(self, obj, base): - def __init__(self, obj): - self.obj = obj obj.addProperty("App::PropertyLink", "Base","Base", QtCore.QT_TRANSLATE_NOOP("PathDressup_HoldingTags", "The base path to modify")) obj.addProperty("App::PropertyLength", "Width", "Tag", QtCore.QT_TRANSLATE_NOOP("PathDressup_HoldingTags", "Width of tags.")) obj.addProperty("App::PropertyLength", "Height", "Tag", QtCore.QT_TRANSLATE_NOOP("PathDressup_HoldingTags", "Height of tags.")) @@ -670,11 +666,15 @@ class ObjectDressup: obj.addProperty("App::PropertyVectorList", "Positions", "Tag", QtCore.QT_TRANSLATE_NOOP("PathDressup_HoldingTags", "Locations of insterted holding tags")) obj.addProperty("App::PropertyIntegerList", "Disabled", "Tag", QtCore.QT_TRANSLATE_NOOP("PathDressup_HoldingTags", "Ids of disabled holding tags")) obj.addProperty("App::PropertyInteger", "SegmentationFactor", "Tag", QtCore.QT_TRANSLATE_NOOP("PathDressup_HoldingTags", "Factor determining the # segments used to approximate rounded tags.")) + obj.Proxy = self + obj.Base = base + + self.obj = obj + self.solids = [] def __getstate__(self): return None - def __setstate__(self, state): return None @@ -887,16 +887,19 @@ class ObjectDressup: # update disabled in case there are some additional ones disabled = copy.copy(self.obj.Disabled) + solids = [] for tag in self.tags: + solids.append(tag.solid) if not tag.enabled and tag.id not in disabled: disabled.append(tag.id) + self.solids = solids if obj.Disabled != disabled: obj.Disabled = disabled @waiting_effects def processTags(self, obj): tagID = 0 - if PathLog.getLevel(LOG_MODULE) == PathLog.Level.DEBUG: + if PathLog.getLevel(PathLog.thisModule()) == PathLog.Level.DEBUG: for tag in self.tags: tagID += 1 if tag.enabled: @@ -948,539 +951,25 @@ class ObjectDressup: self.setup(obj) return self.pathData.pointIsOnPath(point) -class TaskPanel: - DataX = QtCore.Qt.ItemDataRole.UserRole - DataY = QtCore.Qt.ItemDataRole.UserRole + 1 - DataZ = QtCore.Qt.ItemDataRole.UserRole + 2 - DataID = QtCore.Qt.ItemDataRole.UserRole + 3 - def __init__(self, obj, viewProvider, jvoVisibility=None): - 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.jvo = PathUtils.findParentJob(obj).ViewObject - if jvoVisibility is None: - FreeCAD.ActiveDocument.openTransaction(translate("PathDressup_HoldingTags", "Edit HoldingTags Dress-up")) - self.jvoVisible = self.jvo.isVisible() - if self.jvoVisible: - self.jvo.hide() - else: - 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")) - - 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 - - def abort(self): - FreeCAD.ActiveDocument.abortTransaction() - self.cleanup(False) - - def reject(self): - FreeCAD.ActiveDocument.abortTransaction() - self.cleanup(True) - - def accept(self): - self.getFields() - FreeCAD.ActiveDocument.commitTransaction() - self.cleanup(True) - FreeCAD.ActiveDocument.recompute() - - def cleanup(self, gui): - self.removeGlobalCallbacks() - self.viewProvider.clearTaskPanel() - if gui: - FreeCADGui.ActiveDocument.resetEdit() - FreeCADGui.Control.closeDialog() - FreeCAD.ActiveDocument.recompute() - if self.jvoVisible: - self.jvo.show() - - 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) - enabled = item.checkState() == QtCore.Qt.CheckState.Checked - x = item.data(self.DataX) - y = item.data(self.DataY) - #print("(%.2f, %.2f) i=%d/%s" % (x, y, i, index)) - if includeCurrent or i != index: - tags.append((x, y, enabled)) - return tags - - def getTagParameters(self): - self.obj.Width = FreeCAD.Units.Quantity(self.formTags.ifWidth.text()).Value - self.obj.Height = FreeCAD.Units.Quantity(self.formTags.ifHeight.text()).Value - self.obj.Angle = self.formTags.dsbAngle.value() - self.obj.Radius = FreeCAD.Units.Quantity(self.formTags.ifRadius.text()).Value - - def getFields(self): - self.getTagParameters() - tags = self.getTags(True) - self.obj.Proxy.setXyEnabled(tags) - - def updateTagsView(self): - PathLog.track() - self.formTags.lwTags.blockSignals(True) - self.formTags.lwTags.clear() - for i, pos in enumerate(self.obj.Positions): - lbl = "%d: (%.2f, %.2f)" % (i, pos.x, pos.y) - item = QtGui.QListWidgetItem(lbl) - item.setData(self.DataX, pos.x) - item.setData(self.DataY, pos.y) - item.setData(self.DataZ, pos.z) - item.setData(self.DataID, i) - if i in self.obj.Disabled: - item.setCheckState(QtCore.Qt.CheckState.Unchecked) - else: - item.setCheckState(QtCore.Qt.CheckState.Checked) - flags = QtCore.Qt.ItemFlag.ItemIsSelectable - flags |= QtCore.Qt.ItemFlag.ItemIsEnabled - flags |= QtCore.Qt.ItemFlag.ItemIsUserCheckable - item.setFlags(flags) - self.formTags.lwTags.addItem(item) - self.formTags.lwTags.blockSignals(False) - self.whenTagSelectionChanged() - - def generateNewTags(self): - count = self.formTags.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() - #FreeCAD.ActiveDocument.recompute() - - def whenCountChanged(self): - count = self.formTags.sbCount.value() - self.formTags.pbGenerate.setEnabled(count) - - def selectTagWithId(self, index): - self.formTags.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) - self.viewProvider.selectTag(index) - - def deleteSelectedTag(self): - self.obj.Proxy.setXyEnabled(self.getTags(False)) - self.updateTagsView() - - def addNewTagAt(self, point, obj): - if point and obj and self.obj.Proxy.pointIsOnPath(self.obj, point): - #print("addNewTagAt(%s)" % (point)) - tags = self.tags - tags.append((point.x, point.y, True)) - self.obj.Proxy.setXyEnabled(tags) - self.updateTagsView() - else: - print("ignore new tag at %s" % (point)) - - def addNewTag(self): - self.tags = self.getTags(True) - self.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): - tags = [] - for i, (x, y, enabled) in enumerate(self.tags): - if i == self.editItem: - tags.append((point.x, point.y, enabled)) - else: - tags.append((x, y, enabled)) - self.obj.Proxy.setXyEnabled(tags) - self.updateTagsView() - - def editTag(self, item): - if item: - self.tags = self.getTags(True) - self.editItem = item.data(self.DataID) - x = item.data(self.DataX) - y = item.data(self.DataY) - z = item.data(self.DataZ) - self.getPoint(self.editTagAt, FreeCAD.Vector(x, y, z)) - - def editSelectedTag(self): - self.editTag(self.formTags.lwTags.currentItem()) - - def removeGlobalCallbacks(self): - if hasattr(self, 'view') and self.view: - if self.pointCbClick: - self.view.removeEventCallbackPivy(coin.SoMouseButtonEvent.getClassTypeId(), self.pointCbClick) - self.pointCbClick = None - if self.pointCbMove: - self.view.removeEventCallbackPivy(coin.SoLocation2Event.getClassTypeId(), self.pointCbMove) - 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.pointCancel() - - 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) - widget.setValue(val) - - def setFields(self): - self.updateTagsView() - self.formTags.sbCount.setValue(len(self.obj.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) - - def setupUi(self): - self.setFields() - self.whenCountChanged() - - if self.obj.Proxy.supportsTagGeneration(self.obj): - self.formTags.sbCount.valueChanged.connect(self.whenCountChanged) - self.formTags.pbGenerate.clicked.connect(self.generateNewTags) - else: - self.formTags.cbTagGeneration.setEnabled(False) - - self.formTags.ifHeight.editingFinished.connect(self.updateModel) - self.formTags.ifWidth.editingFinished.connect(self.updateModel) - self.formTags.dsbAngle.editingFinished.connect(self.updateModel) - self.formTags.ifRadius.editingFinished.connect(self.updateModel) - self.formTags.lwTags.itemChanged.connect(self.updateModel) - self.formTags.lwTags.itemSelectionChanged.connect(self.whenTagSelectionChanged) - self.formTags.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.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): - self.point = point - self.color = colors - self.sep = coin.SoSeparator() - self.pos = coin.SoTranslation() - self.pos.translation = (point.x, point.y, point.z) - self.sphere = coin.SoSphere() - self.scale = coin.SoType.fromName('SoShapeScale').createInstance() - self.scale.setPart('shape', self.sphere) - self.scale.scaleFactor.setValue(7) - self.material = coin.SoMaterial() - self.sep.addChild(self.pos) - self.sep.addChild(self.material) - self.sep.addChild(self.scale) - self.enabled = True - self.selected = False - - def setSelected(self, select): - self.selected = select - self.sphere.radius = 1.5 if select else 1.0 - self.setEnabled(self.enabled) - - def setEnabled(self, enabled): - self.enabled = enabled - if enabled: - self.material.diffuseColor = self.color[0] if not self.selected else self.color[2] - self.material.transparency = 0.0 - else: - self.material.diffuseColor = self.color[1] if not self.selected else self.color[2] - self.material.transparency = 0.6 - -class ViewProviderDressup: - - def __init__(self, vobj): - vobj.Proxy = self - self.panel = None - - def setupColors(self): - def colorForColorValue(val): - v = [((val >> n) & 0xff) / 255. for n in [24, 16, 8, 0]] - return coin.SbColor(v[0], v[1], v[2]) - - pref = PathPreferences.preferences() - # R G B A - npc = pref.GetUnsigned("DefaultPathMarkerColor", (( 85*256 + 255)*256 + 0)*256 + 255) - hpc = pref.GetUnsigned("DefaultHighlightPathColor", ((255*256 + 125)*256 + 0)*256 + 255) - dpc = pref.GetUnsigned("DefaultDisabledPathColor", ((205*256 + 205)*256 + 205)*256 + 154) - self.colors = [colorForColorValue(npc), colorForColorValue(dpc), colorForColorValue(hpc)] - - def attach(self, vobj): - self.setupColors() - self.obj = vobj.Object - self.tags = [] - self.switch = coin.SoSwitch() - vobj.RootNode.addChild(self.switch) - self.turnMarkerDisplayOn(False) - - def turnMarkerDisplayOn(self, display): - sw = coin.SO_SWITCH_ALL if display else coin.SO_SWITCH_NONE - self.switch.whichChild = sw - - - def claimChildren(self): - PathLog.notice(self.obj) - if self.obj and self.obj.Base: - for i in self.obj.Base.InList: - if hasattr(i, "Group"): - group = i.Group - for g in group: - if g.Name == self.obj.Base.Name: - group.remove(g) - i.Group = group - #print i.Group - if self.obj.Base: - obj = FreeCADGui.ActiveDocument.getObject(self.obj.Base.Name) - if obj: - obj.Visibility = False - return [self.obj.Base] - return [] - - def setEdit(self, vobj, mode=0): - panel = TaskPanel(vobj.Object, self) - self.setupTaskPanel(panel) - return True - - def unsetEdit(self, vobj, mode): - if hasattr(self, 'panel') and self.panel: - self.panel.abort() - - def setupTaskPanel(self, panel): - self.panel = panel - FreeCADGui.Control.closeDialog() - FreeCADGui.Control.showDialog(panel) - panel.setupUi() - FreeCADGui.Selection.addSelectionGate(self) - FreeCADGui.Selection.addObserver(self) - - def clearTaskPanel(self): - self.panel = None - FreeCADGui.Selection.removeSelectionGate() - FreeCADGui.Selection.removeObserver(self) - self.turnMarkerDisplayOn(False) - - def __getstate__(self): +def Create(baseObject, name = 'DressupTag'): + ''' + Create(basePath, name = 'DressupTag') ... create tag dressup object for the given base path. + ''' + if not baseObject.isDerivedFrom('Path::Feature'): + PathLog.error(translate('PathDressup_Tag', 'The selected object is not a path\n')) return None - def __setstate__(self, state): + if baseObject.isDerivedFrom('Path::FeatureCompoundPython'): + PathLog.error(translate('PathDressup_Tag', 'Please select a Profile object')) return None - def onDelete(self, arg1=None, arg2=None): - '''this makes sure that the base operation is added back to the project and visible''' - if arg1.Object.Base: - obj = FreeCADGui.ActiveDocument.getObject(arg1.Object.Base.Name) - if obj: - obj.Visibility = True - PathUtils.addToJob(arg1.Object.Base) - arg1.Object.Base = None - return True - - def updateData(self, obj, propName): - if 'Disabled' == propName: - for tag in self.tags: - self.switch.removeChild(tag.sep) - tags = [] - for i, p in enumerate(obj.Positions): - tag = HoldingTagMarker(p, self.colors) - tag.setEnabled(not i in obj.Disabled) - tags.append(tag) - self.switch.addChild(tag.sep) - self.tags = tags - - def selectTag(self, index): - PathLog.track(index) - for i, tag in enumerate(self.tags): - tag.setSelected(i == index) - - def tagAtPoint(self, point): - p = FreeCAD.Vector(point[0], point[1], point[2]) - for i, tag in enumerate(self.tags): - if PathGeom.pointsCoincide(p, tag.point, tag.sphere.radius.getValue() * 1.1): - return i - return -1 - - # SelectionObserver interface - def allow(self, doc, obj, sub): - if obj == self.obj: - return True - return False - - def addSelection(self, doc, obj, sub, point): - i = self.tagAtPoint(point) - if self.panel: - self.panel.selectTagWithId(i) - FreeCADGui.updateGui() - -class CommandPathDressupHoldingTags: - - def GetResources(self): - return {'Pixmap': 'Path-Dressup', - 'MenuText': QtCore.QT_TRANSLATE_NOOP("PathDressup_HoldingTags", "HoldingTags Dress-up"), - 'ToolTip': QtCore.QT_TRANSLATE_NOOP("PathDressup_HoldingTags", "Creates a HoldingTags Dress-up object from a selected path")} - - def IsActive(self): - if FreeCAD.ActiveDocument is not None: - for o in FreeCAD.ActiveDocument.Objects: - if o.Name[:3] == "Job": - return True - return False - - def Activated(self): - - # check that the selection contains exactly what we want - selection = FreeCADGui.Selection.getSelection() - if len(selection) != 1: - PathLog.error(translate("PathDressup_HoldingTags", "Please select one path object\n")) - return - baseObject = selection[0] - if not baseObject.isDerivedFrom("Path::Feature"): - PathLog.error(translate("PathDressup_HoldingTags", "The selected object is not a path\n")) - return - if baseObject.isDerivedFrom("Path::FeatureCompoundPython"): - PathLog.error(translate("PathDressup_HoldingTags", "Please select a Profile object")) - return - - # everything ok! - FreeCAD.ActiveDocument.openTransaction(translate("PathDressup_HoldingTags", "Create HoldingTags Dress-up")) - FreeCADGui.addModule("PathScripts.PathDressupHoldingTags") - FreeCADGui.addModule("PathScripts.PathUtils") - FreeCADGui.doCommand('obj = FreeCAD.ActiveDocument.addObject("Path::FeaturePython", "HoldingTagsDressup")') - FreeCADGui.doCommand('dbo = PathScripts.PathDressupHoldingTags.ObjectDressup(obj)') - FreeCADGui.doCommand('obj.Base = FreeCAD.ActiveDocument.' + selection[0].Name) - FreeCADGui.doCommand('PathScripts.PathDressupHoldingTags.ViewProviderDressup(obj.ViewObject)') - FreeCADGui.doCommand('PathScripts.PathUtils.addToJob(obj)') - FreeCADGui.doCommand('Gui.ActiveDocument.getObject(obj.Base.Name).Visibility = False') - FreeCADGui.doCommand('dbo.setup(obj, True)') - FreeCAD.ActiveDocument.commitTransaction() - FreeCAD.ActiveDocument.recompute() - - -if FreeCAD.GuiUp: - # register the FreeCAD command - FreeCADGui.addCommand('PathDressup_HoldingTags', CommandPathDressupHoldingTags()) + obj = FreeCAD.ActiveDocument.addObject("Path::FeaturePython", "TagDressup") + dbo = ObjectTagDressup(obj, baseObject) + job = PathUtils.findParentJob(baseObject) + PathUtils.addObjectToJob(obj, job) + dbo.setup(obj, True) + return obj PathLog.notice("Loading PathDressupHoldingTags... done\n") diff --git a/src/Mod/Path/PathScripts/PathDressupTag.py b/src/Mod/Path/PathScripts/PathDressupTag.py index f17f4faa08..e073645de9 100644 --- a/src/Mod/Path/PathScripts/PathDressupTag.py +++ b/src/Mod/Path/PathScripts/PathDressupTag.py @@ -108,10 +108,10 @@ class TagSolid: return clone -class ObjectDressup(QtCore.QObject): - changed = QtCore.Signal() +class ObjectDressup: def __init__(self, obj, base): + obj.addProperty('App::PropertyLink', 'Base','Base', QtCore.QT_TRANSLATE_NOOP('PathDressup_Tag', 'The base path to modify')) obj.addProperty('App::PropertyLength', 'Width', 'Tag', QtCore.QT_TRANSLATE_NOOP('PathDressup_Tag', 'Width of tags.')) obj.addProperty('App::PropertyLength', 'Height', 'Tag', QtCore.QT_TRANSLATE_NOOP('PathDressup_Tag', 'Height of tags.')) @@ -120,19 +120,12 @@ class ObjectDressup(QtCore.QObject): obj.addProperty('App::PropertyVectorList', 'Positions', 'Tag', QtCore.QT_TRANSLATE_NOOP('PathDressup_Tag', 'Locations of insterted holding tags')) obj.addProperty('App::PropertyIntegerList', 'Disabled', 'Tag', QtCore.QT_TRANSLATE_NOOP('PathDressup_Tag', 'Ids of disabled holding tags')) obj.addProperty('App::PropertyInteger', 'SegmentationFactor', 'Tag', QtCore.QT_TRANSLATE_NOOP('PathDressup_Tag', 'Factor determining the # segments used to approximate rounded tags.')) - obj.addProperty('App::PropertyLink', 'Debug', 'Debug', QtCore.QT_TRANSLATE_NOOP('PathDressup_Tag', 'Some elements for debugging')) obj.Proxy = self obj.Base = base - if PathLog.getLevel(PathLog.thisModule()) != PathLog.Level.DEBUG: - obj.setEditorMode('Debug', 2) # hide - dbg = obj.Document.addObject('App::DocumentObjectGroup', 'TagDebug') - obj.Debug = dbg - self.obj = obj self.solids = [] - super(ObjectDressup, self).__init__() def __getstate__(self): return None @@ -196,7 +189,7 @@ class ObjectDressup(QtCore.QObject): self.wire, rapid = PathGeom.wireForPath(obj.Base.Path) self.edges = self.wire.Edges - maxTagZ = minZ + obj.Height + maxTagZ = minZ + obj.Height.Value lastX = 0 lastY = 0 @@ -214,7 +207,6 @@ class ObjectDressup(QtCore.QObject): commands.append(cmd) obj.Path = obj.Base.Path - self.changed.emit() PathLog.track() diff --git a/src/Mod/Path/PathScripts/PathDressupTagGui.py b/src/Mod/Path/PathScripts/PathDressupTagGui.py index 997c621ad2..e8d8bbbfdb 100644 --- a/src/Mod/Path/PathScripts/PathDressupTagGui.py +++ b/src/Mod/Path/PathScripts/PathDressupTagGui.py @@ -26,7 +26,8 @@ import FreeCAD import FreeCADGui import Path import PathScripts -import PathScripts.PathDressupTag as PathDressupTag +#import PathScripts.PathDressupTag as PathDressupTag +import PathScripts.PathDressupHoldingTags as PathDressupTag import PathScripts.PathLog as PathLog import PathScripts.PathUtils as PathUtils @@ -35,13 +36,16 @@ from PathScripts.PathPreferences import PathPreferences from PySide import QtCore, QtGui from pivy import coin -PathLog.setLevel(PathLog.Level.DEBUG, PathLog.thisModule()) -PathLog.trackModule() +PathLog.setLevel(PathLog.Level.INFO, PathLog.thisModule()) +#PathLog.trackModule() # Qt tanslation handling def translate(context, text, disambig=None): return QtCore.QCoreApplication.translate(context, text, disambig) +def addDebugDisplay(): + return PathLog.getLevel(PathLog.thisModule()) == PathLog.Level.DEBUG + class PathDressupTagTaskPanel: DataX = QtCore.Qt.ItemDataRole.UserRole DataY = QtCore.Qt.ItemDataRole.UserRole + 1 @@ -455,6 +459,17 @@ class PathDressupTagViewProvider: self.vobj = vobj self.panel = None + self.debugDisplay() + + def debugDisplay(self): + #if False and addDebugDisplay(): + # if not hasattr(self.vobj, 'Debug'): + # self.vobj.addProperty('App::PropertyLink', 'Debug', 'Debug', QtCore.QT_TRANSLATE_NOOP('PathDressup_TagGui', 'Some elements for debugging')) + # dbg = self.vobj.Object.Document.addObject('App::DocumentObjectGroup', 'TagDebug') + # self.vobj.Debug = dbg + # return True + return False + def __getstate__(self): return None def __setstate__(self, state): @@ -475,6 +490,7 @@ class PathDressupTagViewProvider: def attach(self, vobj): PathLog.track() self.setupColors() + self.vobj = vobj self.obj = vobj.Object self.tags = [] self.switch = coin.SoSwitch() @@ -487,10 +503,8 @@ class PathDressupTagViewProvider: i.Group = [o for o in i.Group if o.Name != self.obj.Base.Name] if self.obj.Base.ViewObject: self.obj.Base.ViewObject.Visibility = False - if PathLog.getLevel(PathLog.thisModule()) != PathLog.Level.DEBUG and self.obj.Debug.ViewObject: - self.obj.Debug.ViewObject.Visibility = False - - self.obj.Proxy.changed.connect(self.onModelChanged) + #if self.debugDisplay() and self.vobj.Debug.ViewObject: + # self.vobj.Debug.ViewObject.Visibility = False def turnMarkerDisplayOn(self, display): sw = coin.SO_SWITCH_ALL if display else coin.SO_SWITCH_NONE @@ -498,7 +512,9 @@ class PathDressupTagViewProvider: def claimChildren(self): PathLog.track() - return [self.obj.Base, self.obj.Debug] + #if self.debugDisplay(): + # return [self.obj.Base, self.vobj.Debug] + return [self.obj.Base] def onDelete(self, arg1=None, arg2=None): PathLog.track() @@ -506,9 +522,10 @@ class PathDressupTagViewProvider: if self.obj.Base.ViewObject: self.obj.Base.ViewObject.Visibility = True PathUtils.addToJob(arg1.Object.Base) - self.obj.Debug.removeObjectsFromDocument() - self.obj.Debug.Document.removeObject(self.obj.Debug.Name) - self.obj.Debug = None + #if self.debugDisplay(): + # self.vobj.Debug.removeObjectsFromDocument() + # self.vobj.Debug.Document.removeObject(self.vobj.Debug.Name) + # self.vobj.Debug = None return True def updatePositions(self, positions, disabled): @@ -529,15 +546,16 @@ class PathDressupTagViewProvider: def onModelChanged(self): PathLog.track() - self.obj.Debug.removeObjectsFromDocument() - for solid in self.obj.Proxy.solids: - tag = self.obj.Document.addObject('Part::Feature', 'tag') - tag.Shape = solid - if tag.ViewObject and self.obj.Debug.ViewObject: - tag.ViewObject.Visibility = self.obj.Debug.ViewObject.Visibility - tag.ViewObject.Transparency = 80 - self.obj.Debug.addObject(tag) - tag.purgeTouched() + #if self.debugDisplay(): + # self.vobj.Debug.removeObjectsFromDocument() + # for solid in self.obj.Proxy.solids: + # tag = self.obj.Document.addObject('Part::Feature', 'tag') + # tag.Shape = solid + # if tag.ViewObject and self.vobj.Debug.ViewObject: + # tag.ViewObject.Visibility = self.vobj.Debug.ViewObject.Visibility + # tag.ViewObject.Transparency = 80 + # self.vobj.Debug.addObject(tag) + # tag.purgeTouched() def setEdit(self, vobj, mode=0): panel = PathDressupTagTaskPanel(vobj.Object, self)