diff --git a/src/Mod/Path/PathScripts/PathCircularHoleBase.py b/src/Mod/Path/PathScripts/PathCircularHoleBase.py index 8310e9dcbf..7983b5efb3 100644 --- a/src/Mod/Path/PathScripts/PathCircularHoleBase.py +++ b/src/Mod/Path/PathScripts/PathCircularHoleBase.py @@ -384,7 +384,7 @@ class ObjectOp(PathOp.ObjectOp): if 1 == len(self.model) and self.baseIsArchPanel(obj, self.model[0]): panel = self.model[0] holeshapes = panel.Proxy.getHoles(panel, transform=True) - tooldiameter = obj.ToolController.Proxy.getTool(obj.ToolController).Diameter + tooldiameter = float(obj.ToolController.Proxy.getTool(obj.ToolController).Diameter) for holeNr, hole in enumerate(holeshapes): PathLog.debug('Entering new HoleShape') for wireNr, wire in enumerate(hole.Wires): @@ -405,7 +405,7 @@ class ObjectOp(PathOp.ObjectOp): PathLog.track('obj: {} shape: {}'.format(obj, shape)) holelist = [] features = [] - # tooldiameter = obj.ToolController.Proxy.getTool(obj.ToolController).Diameter + # tooldiameter = float(obj.ToolController.Proxy.getTool(obj.ToolController).Diameter) tooldiameter = None PathLog.debug('search for holes larger than tooldiameter: {}: '.format(tooldiameter)) if DraftGeomUtils.isPlanar(shape): diff --git a/src/Mod/Path/PathScripts/PathDeburr.py b/src/Mod/Path/PathScripts/PathDeburr.py index 347e5c5bf7..c112eb496a 100644 --- a/src/Mod/Path/PathScripts/PathDeburr.py +++ b/src/Mod/Path/PathScripts/PathDeburr.py @@ -56,7 +56,7 @@ def toolDepthAndOffset(width, extraDepth, tool): toolDepth = 0 if 0 == tan else width / tan depth = toolDepth + extraDepth toolOffset = tool.FlatRadius - extraOffset = tool.Diameter / 2 - width if 180 == angle else extraDepth / tan + extraOffset = float(tool.Diameter) / 2 - width if 180 == angle else extraDepth / tan offset = toolOffset + extraOffset return (depth, offset) diff --git a/src/Mod/Path/PathScripts/PathDressupDogbone.py b/src/Mod/Path/PathScripts/PathDressupDogbone.py index 9866cf8fc5..66f9930cdd 100644 --- a/src/Mod/Path/PathScripts/PathDressupDogbone.py +++ b/src/Mod/Path/PathScripts/PathDressupDogbone.py @@ -860,10 +860,10 @@ class ObjectDressup: self.toolRadius = 5 else: tool = tc.Proxy.getTool(tc) # PathUtils.getTool(obj, tc.ToolNumber) - if not tool or tool.Diameter == 0: + if not tool or float(tool.Diameter) == 0: self.toolRadius = 5 else: - self.toolRadius = tool.Diameter / 2 + self.toolRadius = float(tool.Diameter) / 2 self.shapes = {} self.dbg = [] diff --git a/src/Mod/Path/PathScripts/PathDressupHoldingTags.py b/src/Mod/Path/PathScripts/PathDressupHoldingTags.py index 6c454e4415..1a0b30e920 100644 --- a/src/Mod/Path/PathScripts/PathDressupHoldingTags.py +++ b/src/Mod/Path/PathScripts/PathDressupHoldingTags.py @@ -1021,7 +1021,7 @@ class ObjectTagDressup: # traceback.print_exc() return None - self.toolRadius = PathDressup.toolController(obj.Base).Tool.Diameter / 2 + self.toolRadius = float(PathDressup.toolController(obj.Base).Tool.Diameter) / 2 self.pathData = pathData if generate: obj.Height = self.pathData.defaultTagHeight() diff --git a/src/Mod/Path/PathScripts/PathDressupTag.py b/src/Mod/Path/PathScripts/PathDressupTag.py index 9dab62d975..263ea19336 100644 --- a/src/Mod/Path/PathScripts/PathDressupTag.py +++ b/src/Mod/Path/PathScripts/PathDressupTag.py @@ -220,7 +220,7 @@ class ObjectDressup: PathLog.track() def toolRadius(self): - return PathDressup.toolController(self.obj.Base).Tool.Diameter / 2.0 + return float(PathDressup.toolController(self.obj.Base).Tool.Diameter) / 2.0 def addTagsToDocuemnt(self): for i, solid in enumerate(self.solids): diff --git a/src/Mod/Path/PathScripts/PathOp.py b/src/Mod/Path/PathScripts/PathOp.py index ae84503f46..d90202a3b9 100644 --- a/src/Mod/Path/PathScripts/PathOp.py +++ b/src/Mod/Path/PathScripts/PathOp.py @@ -498,10 +498,10 @@ class ObjectOp(object): self.vertRapid = tc.VertRapid.Value self.horizRapid = tc.HorizRapid.Value tool = tc.Proxy.getTool(tc) - if not tool or tool.Diameter == 0: + if not tool or float(tool.Diameter) == 0: FreeCAD.Console.PrintError("No Tool found or diameter is zero. We need a tool to build a Path.") return - self.radius = tool.Diameter/2 + self.radius = float(tool.Diameter) /2 self.tool = tool obj.OpToolDiameter = tool.Diameter diff --git a/src/Mod/Path/PathScripts/PathSimulatorGui.py b/src/Mod/Path/PathScripts/PathSimulatorGui.py index 7f3c3e2f05..2260d9ccc8 100644 --- a/src/Mod/Path/PathScripts/PathSimulatorGui.py +++ b/src/Mod/Path/PathScripts/PathSimulatorGui.py @@ -125,7 +125,7 @@ class PathSimulation: # if hasattr(self.operation, "ToolController"): # self.tool = self.operation.ToolController.Tool if (self.tool is not None): - toolProf = self.CreateToolProfile(self.tool, Vector(0, 1, 0), Vector(0, 0, 0), self.tool.Diameter / 2.0) + toolProf = self.CreateToolProfile(self.tool, Vector(0, 1, 0), Vector(0, 0, 0), float(self.tool.Diameter) / 2.0) self.cutTool.Shape = Part.makeSolid(toolProf.revolve(Vector(0, 0, 0), Vector(0, 0, 1))) self.cutTool.ViewObject.show() self.voxSim.SetCurrentTool(self.tool) @@ -298,7 +298,7 @@ class PathSimulation: # except: # return (None, e1.valueAt(e1.LastParameter)) # height = self.height - # rad = tool.Diameter / 2.0 - 0.001 * curpos[2] # hack to overcome occ bug + # rad = float(tool.Diameter) / 2.0 - 0.001 * curpos[2] # hack to overcome occ bug # if type(e1.Curve) is Part.Circle and e1.Curve.Radius <= rad: # hack to overcome occ bug # rad = e1.Curve.Radius - 0.001 # # return (None, e1.valueAt(e1.LastParameter)) @@ -350,7 +350,7 @@ class PathSimulation: # height = self.height # hack to overcome occ bugs - rad = tool.Diameter / 2.0 - 0.001 * pos[2] + rad = float(tool.Diameter) / 2.0 - 0.001 * pos[2] # rad = rad + 0.001 * self.icmd if type(toolPath.Curve) is Part.Circle and toolPath.Curve.Radius <= rad: rad = toolPath.Curve.Radius - 0.01 * (pos[2] + 1) @@ -386,7 +386,7 @@ class PathSimulation: # create radial profile of the tool (90 degrees to the direction of the path) def CreateToolProfile(self, tool, dir, pos, rad): type = tool.ToolType - # rad = tool.Diameter / 2.0 - 0.001 * pos[2] # hack to overcome occ bug + # rad = float(tool.Diameter) / 2.0 - 0.001 * pos[2] # hack to overcome occ bug xf = dir[0] * rad yf = dir[1] * rad xp = pos[0] diff --git a/src/Mod/Path/PathScripts/PathSurface.py b/src/Mod/Path/PathScripts/PathSurface.py index 6dfcf5206c..c32dedcd9b 100644 --- a/src/Mod/Path/PathScripts/PathSurface.py +++ b/src/Mod/Path/PathScripts/PathSurface.py @@ -1792,10 +1792,10 @@ class ObjectSurface(PathOp.ObjectOp): def setOclCutter(self, obj): # Set cutter details # https://www.freecadweb.org/api/dd/dfe/classPath_1_1Tool.html#details - diam_1 = obj.ToolController.Tool.Diameter - lenOfst = obj.ToolController.Tool.LengthOffset - FR = obj.ToolController.Tool.FlatRadius - CEH = obj.ToolController.Tool.CuttingEdgeHeight + diam_1 = float(obj.ToolController.Tool.Diameter) + lenOfst = obj.ToolController.Tool.LengthOffset if hasattr(obj.ToolController.Tool, 'LengthOffset') else 0 + FR = obj.ToolController.Tool.FlatRadius if hasattr(obj.ToolController.Tool, 'FlatRadius') else 0 + CEH = obj.ToolController.Tool.CuttingEdgeHeight if hasattr(obj.ToolController.Tool, 'CuttingEdgeHeight') else 0 if obj.ToolController.Tool.ToolType == 'EndMill': # Standard End Mill diff --git a/src/Mod/Path/PathScripts/PathToolBitCmd.py b/src/Mod/Path/PathScripts/PathToolBitCmd.py index 7a45d2b50f..b87569f879 100644 --- a/src/Mod/Path/PathScripts/PathToolBitCmd.py +++ b/src/Mod/Path/PathScripts/PathToolBitCmd.py @@ -126,10 +126,8 @@ class CommandToolBitLoad: return FreeCAD.ActiveDocument is not None def Activated(self): - from PySide import QtGui - foo = QtGui.QFileDialog.getOpenFileName(QtGui.QApplication.activeWindow(), "Tool", PathScripts.PathPreferences.lastPathToolBit(), "*.fctb") - if foo: - PathScripts.PathToolBitGui.CreateFrom(foo[0]) + if PathScripts.PathToolBitGui.LoadTool(): + FreeCAD.ActiveDocument.recompute() if FreeCAD.GuiUp: FreeCADGui.addCommand('Path_ToolBitCreate', CommandToolBitCreate()) diff --git a/src/Mod/Path/PathScripts/PathToolBitEdit.py b/src/Mod/Path/PathScripts/PathToolBitEdit.py index 4c546477cb..f7ca4f2ab8 100644 --- a/src/Mod/Path/PathScripts/PathToolBitEdit.py +++ b/src/Mod/Path/PathScripts/PathToolBitEdit.py @@ -124,12 +124,12 @@ class ToolBitEditor: path = self.tool.BitTemplate if not path: path = LastPath - foo = QtGui.QFileDialog.getOpenFileName(QtGui.QApplication.activeWindow(), + foo = QtGui.QFileDialog.getOpenFileName(self.form, "Path - Tool Template", path, - "*.fcstd")[0] - if foo: - self.form.templatePath.setText(foo) + "*.fcstd") + if foo and foo[0]: + self.form.templatePath.setText(foo[0]) self.updateTemplate() def setupUI(self): diff --git a/src/Mod/Path/PathScripts/PathToolBitGui.py b/src/Mod/Path/PathScripts/PathToolBitGui.py index af128ea83a..d6d6c2b7a6 100644 --- a/src/Mod/Path/PathScripts/PathToolBitGui.py +++ b/src/Mod/Path/PathScripts/PathToolBitGui.py @@ -27,6 +27,7 @@ import FreeCADGui import PathScripts.PathGui as PathGui import PathScripts.PathIconViewProvider as PathIconViewProvider import PathScripts.PathLog as PathLog +import PathScripts.PathPreferences as PathPreferences import PathScripts.PathToolBit as PathToolBit import PathScripts.PathToolBitEdit as PathToolBitEdit import PathScripts.PathUtil as PathUtil @@ -165,18 +166,18 @@ class ToolBitSelector(object): self.form = FreeCADGui.PySideUic.loadUi(":/panels/ToolBitSelector.ui") self.setupUI() - def getTool(self): - selected = None + def updateTools(self, selected=None): + PathLog.track() selItem = None self.form.tools.setUpdatesEnabled(False) - if self.form.tools.currentItem(): + if selected is None and self.form.tools.currentItem(): selected = self.form.tools.currentItem().text() self.form.tools.clear() for tool in sorted(self.loadedTools(), key=lambda t: t.Label): icon = None if tool.ViewObject and tool.ViewObject.Proxy: icon = tool.ViewObject.Proxy.getIcon() - if icon: + if icon and isinstance(icon, QtGui.QIcon): item = QtGui.QListWidgetItem(icon, tool.Label) else: item = QtGui.QListWidgetItem(tool.Label) @@ -188,32 +189,68 @@ class ToolBitSelector(object): self.form.tools.setCurrentItem(selItem) self.updateSelection() self.form.tools.setUpdatesEnabled(True) + + def getTool(self): + PathLog.track() + self.updateTools() res = self.form.exec_() if 1 == res and self.form.tools.currentItem(): return self.form.tools.currentItem().data(self.ToolRole) return None def loadedTools(self): + PathLog.track() if FreeCAD.ActiveDocument: return [o for o in FreeCAD.ActiveDocument.Objects if hasattr(o, 'Proxy') and isinstance(o.Proxy, PathToolBit.ToolBit)] return [] def loadTool(self): - pass + PathLog.track() + tool = LoadTool(self.form) + if tool: + self.updateTools(tool.Label) def createTool(self): - pass + PathLog.track() + tool = Create() + + def accept(): + self.editor.accept() + self.dialog.done(1) + self.updateTools(tool.Label) + + def reject(): + FreeCAD.ActiveDocument.openTransaction(translate("PathToolBit", "Uncreate ToolBit")) + self.editor.reject() + self.dialog.done(0) + FreeCAD.ActiveDocument.removeObject(tool.Name) + FreeCAD.ActiveDocument.commitTransaction() + + self.dialog = QtGui.QDialog(self.form) + layout = QtGui.QVBoxLayout(self.dialog) + self.editor = PathToolBitEdit.ToolBitEditor(tool, self.dialog) + self.editor.setupUI() + self.buttons = QtGui.QDialogButtonBox( + QtGui.QDialogButtonBox.Ok | QtGui.QDialogButtonBox.Cancel, + QtCore.Qt.Horizontal, self.dialog) + layout.addWidget(self.buttons) + self.buttons.accepted.connect(accept) + self.buttons.rejected.connect(reject) + print(self.dialog.exec_()) def updateSelection(self): + PathLog.track() if self.form.tools.selectedItems(): self.form.buttonBox.button(QtGui.QDialogButtonBox.Ok).setEnabled(True) else: self.form.buttonBox.button(QtGui.QDialogButtonBox.Ok).setEnabled(False) def setupUI(self): + PathLog.track() self.form.toolCreate.clicked.connect(self.createTool) self.form.toolLoad.clicked.connect(self.loadTool) self.form.tools.itemSelectionChanged.connect(self.updateSelection) + self.form.tools.doubleClicked.connect(self.form.accept) def Create(name = 'ToolBit'): '''Create(name = 'ToolBit') ... creates a new tool bit. @@ -232,4 +269,13 @@ def CreateFrom(path, name = 'ToolBit'): FreeCAD.ActiveDocument.commitTransaction() return tool +def LoadTool(parent = None): + '''LoadTool(parent=None) ... Open a file dialog to load a tool from a file.''' + if parent is None: + parent = QtGui.QApplication.activeWindow() + foo = QtGui.QFileDialog.getOpenFileName(parent, "Tool", PathPreferences.lastPathToolBit(), "*.fctb") + if foo and foo[0]: + return CreateFrom(foo[0]) + return None + PathIconViewProvider.RegisterViewProvider('ToolBit', ViewProvider) diff --git a/src/Mod/Path/PathScripts/PathToolControllerGui.py b/src/Mod/Path/PathScripts/PathToolControllerGui.py index a18cd423c9..19e4c72272 100644 --- a/src/Mod/Path/PathScripts/PathToolControllerGui.py +++ b/src/Mod/Path/PathScripts/PathToolControllerGui.py @@ -142,6 +142,9 @@ class CommandPathToolController(object): sel = FreeCADGui.Selection.getSelectionEx() if sel and sel[0].Object.Name[:3] == 'Job': return sel[0].Object + jobs = [o for o in FreeCAD.ActiveDocument.Objects if o.Name[:3] == 'Job'] + if 1 == len(jobs): + return jobs[0] return None def IsActive(self): @@ -153,8 +156,9 @@ class CommandPathToolController(object): if job: tool = PathToolBitGui.ToolBitSelector().getTool() if tool: - tc = Create(tool) - job.addToolController(tc) + tc = Create("TC: {}".format(tool.Label), tool) + job.Proxy.addToolController(tc) + FreeCAD.ActiveDocument.recompute() class ToolControllerEditor(object): @@ -262,7 +266,7 @@ class TaskPanel: if self.toolrep: tool = self.obj.Tool - radius = tool.Diameter / 2 + radius = float(tool.Diameter) / 2 length = tool.CuttingEdgeHeight t = Part.makeCylinder(radius, length) self.toolrep.Shape = t diff --git a/src/Mod/Path/PathScripts/PathUtils.py b/src/Mod/Path/PathScripts/PathUtils.py index 4c47649177..945dac2159 100644 --- a/src/Mod/Path/PathScripts/PathUtils.py +++ b/src/Mod/Path/PathScripts/PathUtils.py @@ -703,14 +703,14 @@ def guessDepths(objshape, subs=None): def drillTipLength(tool): """returns the length of the drillbit tip.""" - if tool.CuttingEdgeAngle == 180 or tool.CuttingEdgeAngle == 0.0 or tool.Diameter == 0.0: + if tool.CuttingEdgeAngle == 180 or tool.CuttingEdgeAngle == 0.0 or float(tool.Diameter) == 0.0: return 0.0 else: if tool.CuttingEdgeAngle <= 0 or tool.CuttingEdgeAngle >= 180: PathLog.error(translate("Path", "Invalid Cutting Edge Angle %.2f, must be >0° and <=180°") % tool.CuttingEdgeAngle) return 0.0 theta = math.radians(tool.CuttingEdgeAngle) - length = (tool.Diameter / 2) / math.tan(theta / 2) + length = (float(tool.Diameter) / 2) / math.tan(theta / 2) if length < 0: PathLog.error(translate("Path", "Cutting Edge Angle (%.2f) results in negative tool tip length") % tool.CuttingEdgeAngle) return 0.0