diff --git a/src/Mod/Path/CMakeLists.txt b/src/Mod/Path/CMakeLists.txt index 29ff0c5b10a8..10bb00414eb7 100644 --- a/src/Mod/Path/CMakeLists.txt +++ b/src/Mod/Path/CMakeLists.txt @@ -37,8 +37,7 @@ SET(PathScripts_SRCS PathScripts/PathFixture.py PathScripts/PathCopy.py PathScripts/PathCompoundExtended.py - PathScripts/PathProject.py - PathScripts/PathToolTableEdit.py + PathScripts/PathJob.py PathScripts/PathStock.py PathScripts/PathPlane.py PathScripts/PathPost.py @@ -46,7 +45,6 @@ SET(PathScripts_SRCS PathScripts/PathToolLenOffset.py PathScripts/PathComment.py PathScripts/PathStop.py - PathScripts/PathMachine.py PathScripts/PathFromShape.py PathScripts/DlgSettingsPath.ui PathScripts/PathKurveUtils.py @@ -62,7 +60,7 @@ SET(PathScripts_SRCS PathScripts/PathSurface.py PathScripts/PathRemote.py PathScripts/PathSanity.py - + PathScripts/PathToolLibraryManager.py ) SET(PathScripts_NC_SRCS diff --git a/src/Mod/Path/Gui/DlgJobChooser.ui b/src/Mod/Path/Gui/DlgJobChooser.ui new file mode 100644 index 000000000000..d6d460130a7b --- /dev/null +++ b/src/Mod/Path/Gui/DlgJobChooser.ui @@ -0,0 +1,70 @@ + + + DlgJobChooser + + + Qt::WindowModal + + + + 0 + 0 + 264 + 92 + + + + Choose a Path Job + + + + + + + + + Qt::Horizontal + + + QDialogButtonBox::Cancel|QDialogButtonBox::Ok + + + + + + + + + buttonBox + accepted() + DlgJobChooser + accept() + + + 248 + 254 + + + 157 + 274 + + + + + buttonBox + rejected() + DlgJobChooser + reject() + + + 316 + 260 + + + 286 + 274 + + + + + diff --git a/src/Mod/Path/Gui/Resources/Path.qrc b/src/Mod/Path/Gui/Resources/Path.qrc index 424b448b0e20..fefb56ccca0f 100644 --- a/src/Mod/Path/Gui/Resources/Path.qrc +++ b/src/Mod/Path/Gui/Resources/Path.qrc @@ -7,7 +7,7 @@ icons/Path-Profile.svg icons/Path-Pocket.svg icons/Path-Drilling.svg - icons/Path-Project.svg + icons/Path-Job.svg icons/Path-Dressup.svg icons/Path-Hop.svg icons/Path-Datums.svg @@ -74,5 +74,10 @@ panels/SurfaceEdit.ui panels/RemoteEdit.ui panels/ToolControl.ui + panels/ToolLibraryEditor.ui + panels/JobEdit.ui + panels/DlgToolCopy.ui + panels/ToolEdit.ui + panels/DlgJobChooser.ui diff --git a/src/Mod/Path/Gui/Resources/icons/Path-Project.svg b/src/Mod/Path/Gui/Resources/icons/Path-Job.svg similarity index 100% rename from src/Mod/Path/Gui/Resources/icons/Path-Project.svg rename to src/Mod/Path/Gui/Resources/icons/Path-Job.svg diff --git a/src/Mod/Path/Gui/Resources/panels/DlgJobChooser.ui b/src/Mod/Path/Gui/Resources/panels/DlgJobChooser.ui new file mode 100644 index 000000000000..d6d460130a7b --- /dev/null +++ b/src/Mod/Path/Gui/Resources/panels/DlgJobChooser.ui @@ -0,0 +1,70 @@ + + + DlgJobChooser + + + Qt::WindowModal + + + + 0 + 0 + 264 + 92 + + + + Choose a Path Job + + + + + + + + + Qt::Horizontal + + + QDialogButtonBox::Cancel|QDialogButtonBox::Ok + + + + + + + + + buttonBox + accepted() + DlgJobChooser + accept() + + + 248 + 254 + + + 157 + 274 + + + + + buttonBox + rejected() + DlgJobChooser + reject() + + + 316 + 260 + + + 286 + 274 + + + + + diff --git a/src/Mod/Path/Gui/Resources/panels/DlgToolCopy.ui b/src/Mod/Path/Gui/Resources/panels/DlgToolCopy.ui new file mode 100644 index 000000000000..0f05cdc7ae85 --- /dev/null +++ b/src/Mod/Path/Gui/Resources/panels/DlgToolCopy.ui @@ -0,0 +1,93 @@ + + + DlgJobChooser + + + Qt::WindowModal + + + + 0 + 0 + 367 + 119 + + + + + 0 + 0 + + + + Copy Selected Tools + + + + + + Destination + + + + + + + + + + Create Tool Controllers + + + true + + + + + + + Qt::Horizontal + + + QDialogButtonBox::Cancel|QDialogButtonBox::Ok + + + + + + + + + buttonBox + accepted() + DlgJobChooser + accept() + + + 248 + 254 + + + 157 + 274 + + + + + buttonBox + rejected() + DlgJobChooser + reject() + + + 316 + 260 + + + 286 + 274 + + + + + diff --git a/src/Mod/Path/Gui/Resources/panels/EngraveEdit.ui b/src/Mod/Path/Gui/Resources/panels/EngraveEdit.ui index 024577e345e0..d0055a4b6fad 100644 --- a/src/Mod/Path/Gui/Resources/panels/EngraveEdit.ui +++ b/src/Mod/Path/Gui/Resources/panels/EngraveEdit.ui @@ -106,6 +106,30 @@ + + + + :/icons/Path-LoadTool.svg:/icons/Path-LoadTool.svg + + + Tool Settings + + + + + 0 + 10 + 301 + 41 + + + + + + + + + diff --git a/src/Mod/Path/Gui/Resources/panels/JobEdit.ui b/src/Mod/Path/Gui/Resources/panels/JobEdit.ui new file mode 100644 index 000000000000..54cd85effd12 --- /dev/null +++ b/src/Mod/Path/Gui/Resources/panels/JobEdit.ui @@ -0,0 +1,298 @@ + + + frmCNCJob + + + + 0 + 0 + 398 + 534 + + + + + 0 + 0 + + + + + 0 + 533 + + + + CNC Job + + + + + + + 0 + 0 + + + + 0 + + + + + 0 + 0 + 380 + 426 + + + + + :/icons/Path-OperationB.svg:/icons/Path-OperationB.svg + + + General + + + + + + + + + Job Type + + + + + + + label + + + + + + + + Milling + + + + + + + + + + + Base Object + + + + + + + Create Linked Clone + + + + + + + Reorder operations by dragging them to their correct location + + + true + + + + + + + + 0 + 0 + + + + true + + + QAbstractItemView::InternalMove + + + Qt::MoveAction + + + + + + + + + + + + + + + + + + + + 0 + 0 + 380 + 426 + + + + + :/icons/Path-Stock.svg:/icons/Path-Stock.svg + + + Stock + + + + + + + + + Use Part Bounding Box + + + true + + + + + + + false + + + + Create from Part Bounding Box + + + + + + + + Material + + + + + + + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + + 0 + 0 + 380 + 426 + + + + + :/icons/Path-Post.svg:/icons/Path-Post.svg + + + Post Processing + + + + + + + + + Output File + + + + + + + + 0 + 0 + + + + + + + + + 0 + 0 + + + + ... + + + + + + + + + + Post Processor + + + + + + + + + + Qt::Vertical + + + + 13 + 290 + + + + + + + + + + + + + + + diff --git a/src/Mod/Path/Gui/Resources/panels/ToolControl.ui b/src/Mod/Path/Gui/Resources/panels/ToolControl.ui index b974ea5c266c..ba0208eb0e75 100644 --- a/src/Mod/Path/Gui/Resources/panels/ToolControl.ui +++ b/src/Mod/Path/Gui/Resources/panels/ToolControl.ui @@ -15,7 +15,11 @@ - + + + true + + @@ -26,37 +30,30 @@ QFrame::Raised - - + + Unknown + + + - + Unknown - + Unknown - - - - - - - Unknown - - - @@ -109,7 +106,11 @@ - + + + 99999 + + diff --git a/src/Mod/Path/Gui/Resources/panels/ToolEdit.ui b/src/Mod/Path/Gui/Resources/panels/ToolEdit.ui new file mode 100644 index 000000000000..ce7ec3c3df57 --- /dev/null +++ b/src/Mod/Path/Gui/Resources/panels/ToolEdit.ui @@ -0,0 +1,287 @@ + + + Dialog + + + + 0 + 0 + 423 + 435 + + + + Dialog + + + + + + Tool Properties + + + + QFormLayout::AllNonFixedFieldsGrow + + + + + Name + + + + + + + + + + Type + + + + + + + + Drill + + + + + CenterDrill + + + + + CounterSink + + + + + CounterBore + + + + + Reamer + + + + + Tap + + + + + EndMill + + + + + SlotCutter + + + + + BallEndMill + + + + + ChamferMill + + + + + CornerRound + + + + + Engraver + + + + + + + + Material + + + + + + + + HighSpeedSteel + + + + + HighCarbonSteel + + + + + CastAlloy + + + + + Carbide + + + + + Ceramics + + + + + Diamond + + + + + Sialon + + + + + + + + Diameter + + + + + + + mm + + + + + + + Length Offset + + + + + + + mm + + + + + + + Flat Radius + + + + + + + mm + + + + + + + Corner Radius + + + + + + + mm + + + + + + + Cutting Edge Angle + + + + + + + ° + + + + + + + Cutting Edge Height + + + + + + + mm + + + + + + + + + + Qt::Horizontal + + + QDialogButtonBox::Cancel|QDialogButtonBox::Ok + + + + + + + + + buttonBox + accepted() + Dialog + accept() + + + 248 + 254 + + + 157 + 274 + + + + + buttonBox + rejected() + Dialog + reject() + + + 316 + 260 + + + 286 + 274 + + + + + diff --git a/src/Mod/Path/Gui/Resources/panels/ToolLibraryEditor.ui b/src/Mod/Path/Gui/Resources/panels/ToolLibraryEditor.ui new file mode 100644 index 000000000000..18822962dd5f --- /dev/null +++ b/src/Mod/Path/Gui/Resources/panels/ToolLibraryEditor.ui @@ -0,0 +1,207 @@ + + + Dialog + + + + 0 + 0 + 946 + 614 + + + + Dialog + + + + + + Qt::Horizontal + + + QDialogButtonBox::Cancel|QDialogButtonBox::Ok + + + + + + + Tool Library + + + + + + Import... + + + + + + + Move down + + + + :/icons/button_down.svg:/icons/button_down.svg + + + + + + + Move up + + + + :/icons/button_up.svg:/icons/button_up.svg + + + false + + + false + + + false + + + + + + + true + + + QAbstractItemView::DragOnly + + + true + + + QAbstractItemView::SingleSelection + + + QAbstractItemView::SelectRows + + + false + + + false + + + + + + + Export... + + + + + + + Delete + + + + :/icons/delete.svg:/icons/delete.svg + + + + + + + + 0 + 0 + + + + true + + + true + + + QAbstractItemView::DropOnly + + + + + + + New Tool + + + + :/icons/Path-LoadTool.svg:/icons/Path-LoadTool.svg + + + + + + + + 0 + 0 + + + + Copy checked tools to another library + + + + + + + :/icons/button_left.svg:/icons/button_left.svg + + + + + + + + + + + + + + + buttonBox + accepted() + Dialog + accept() + + + 248 + 254 + + + 157 + 274 + + + + + buttonBox + rejected() + Dialog + reject() + + + 316 + 260 + + + 286 + 274 + + + + + diff --git a/src/Mod/Path/Gui/TaskDlgPathCompound.ui b/src/Mod/Path/Gui/TaskDlgPathCompound.ui index 2c801e7528f2..fb738f73749c 100644 --- a/src/Mod/Path/Gui/TaskDlgPathCompound.ui +++ b/src/Mod/Path/Gui/TaskDlgPathCompound.ui @@ -6,8 +6,8 @@ 0 0 - 285 - 385 + 315 + 404 diff --git a/src/Mod/Path/InitGui.py b/src/Mod/Path/InitGui.py index 5c5350ee9f9b..cff99b995f49 100644 --- a/src/Mod/Path/InitGui.py +++ b/src/Mod/Path/InitGui.py @@ -46,8 +46,8 @@ def Initialize(self): from PathScripts import PathCopy from PathScripts import PathFixture from PathScripts import PathCompoundExtended - from PathScripts import PathProject - from PathScripts import PathToolTableEdit + from PathScripts import PathJob + from PathScripts import PathToolLibraryManager from PathScripts import PathStock from PathScripts import PathPlane from PathScripts import PathPost @@ -55,7 +55,6 @@ def Initialize(self): from PathScripts import PathLoadTool from PathScripts import PathComment from PathScripts import PathStop - from PathScripts import PathMachine from PathScripts import PathFromShape from PathScripts import PathArray from PathScripts import PathFaceProfile @@ -70,15 +69,15 @@ def Initialize(self): from PathScripts import DragknifeDressup # build commands list - projcmdlist = ["Path_Project", "Path_Post", "Path_Inspect", "Path_Sanity"] - #toolcmdlist = ["Path_ToolTableEdit", "Path_ToolLibraryEdit", "Path_LoadTool"] - toolcmdlist = ["Path_ToolTableEdit", "Path_LoadTool"] + projcmdlist = ["Path_Job", "Path_Post", "Path_Inspect", "Path_Sanity"] + toolcmdlist = ["Path_ToolLibraryEdit", "Path_LoadTool"] prepcmdlist = ["Path_Plane", "Path_Fixture", "Path_ToolLenOffset", "Path_Comment", "Path_Stop", "Path_FaceProfile", "Path_FacePocket", "Path_Custom", "Path_FromShape"] opcmdlist = ["Path_Profile", "Path_Pocket", "Path_Drilling", "Path_Engrave", "Path_Surfacing"] - modcmdlist = ["Path_Copy", "Path_CompoundExtended", - "Path_Dressup", "Path_Hop", "Path_Array", "Path_SimpleCopy", "DragKnife_Dressup"] + modcmdlist = ["Path_Copy", "Path_CompoundExtended", "Path_Array", + "Path_SimpleCopy" ] + modcmdmore = ["Path_Dressup", "Path_Hop", "DragKnife_Dressup"] remotecmdlist = ["Path_Remote"] # Add commands to menu and toolbar @@ -96,13 +95,15 @@ def translate(context, text): self.appendMenu([translate("Path", "Path"), translate( "Path", "Project Tools")], projcmdlist) self.appendMenu([translate("Path", "Path"), translate( - "Path", "Tools")], projcmdlist) + "Path", "Tools")], toolcmdlist) self.appendMenu([translate("Path", "Path"), translate( "Path", "Partial Commands")], prepcmdlist) self.appendMenu([translate("Path", "Path"), translate( "Path", "New Operations")], opcmdlist) self.appendMenu([translate("Path", "Path"), translate( "Path", "Path Modification")], modcmdlist) + self.appendMenu([translate("Path", "Path"), translate( + "Path", "Path Modification")], modcmdmore) self.appendMenu([translate("Path", "Path"), translate( "Path", "Remote Operations")], remotecmdlist) diff --git a/src/Mod/Path/PathScripts/DlgToolLibrary.ui b/src/Mod/Path/PathScripts/DlgToolLibrary.ui new file mode 100644 index 000000000000..e26daff49088 --- /dev/null +++ b/src/Mod/Path/PathScripts/DlgToolLibrary.ui @@ -0,0 +1,145 @@ + + + Dialog + + + + 0 + 0 + 946 + 614 + + + + Dialog + + + + + + Qt::Horizontal + + + QDialogButtonBox::Cancel|QDialogButtonBox::Ok + + + + + + + Add Selected Tools to Project + + + + + + + Tool Library + + + + + + Delete + + + + + + + Import... + + + + + + + Move up + + + + + + + Add new List + + + + + + + Move down + + + + + + + New Tool + + + + + + + + 0 + 0 + + + + true + + + + + + + Export... + + + + + + + + + + + + + + + buttonBox + accepted() + Dialog + accept() + + + 248 + 254 + + + 157 + 274 + + + + + buttonBox + rejected() + Dialog + reject() + + + 316 + 260 + + + 286 + 274 + + + + + diff --git a/src/Mod/Path/PathScripts/DlgToolTableEditor.ui b/src/Mod/Path/PathScripts/DlgToolTableEditor.ui new file mode 100644 index 000000000000..9bae38f3f55c --- /dev/null +++ b/src/Mod/Path/PathScripts/DlgToolTableEditor.ui @@ -0,0 +1,244 @@ + + + Dialog + + + + 0 + 0 + 807 + 555 + + + + Dialog + + + + + + Tool Properties + + + + QFormLayout::AllNonFixedFieldsGrow + + + + + Name + + + + + + + + + + Type + + + + + + + + + + Material + + + + + + + + + + Diameter + + + + + + + mm + + + + + + + Length Offset + + + + + + + mm + + + + + + + Flat Radius + + + + + + + mm + + + + + + + Corner Radius + + + + + + + mm + + + + + + + Cutting Edge Angle + + + + + + + ° + + + + + + + Cutting Edge Height + + + + + + + mm + + + + + + + + + + Qt::Horizontal + + + QDialogButtonBox::Cancel|QDialogButtonBox::Ok + + + + + + + Tool List + + + + + + Delete + + + + + + + Move up + + + + + + + Import... + + + + + + + Export... + + + + + + + Add new + + + + + + + + + + Move down + + + + + + + + + + + + buttonBox + accepted() + Dialog + accept() + + + 248 + 254 + + + 157 + 274 + + + + + buttonBox + rejected() + Dialog + reject() + + + 316 + 260 + + + 286 + 274 + + + + + diff --git a/src/Mod/Path/PathScripts/DragknifeDressup.py b/src/Mod/Path/PathScripts/DragknifeDressup.py index 07612d0daba8..5109ea835c7e 100644 --- a/src/Mod/Path/PathScripts/DragknifeDressup.py +++ b/src/Mod/Path/PathScripts/DragknifeDressup.py @@ -476,7 +476,11 @@ def GetResources(self): 'ToolTip': QtCore.QT_TRANSLATE_NOOP("DragKnife_Dressup", "Modifies a path to add dragknife corner actions")} def IsActive(self): - return FreeCAD.ActiveDocument is not None + if FreeCAD.ActiveDocument is not None: + for o in FreeCAD.ActiveDocument.Objects: + if o.Name[:3] == "Job": + return True + return False def Activated(self): diff --git a/src/Mod/Path/PathScripts/PathArray.py b/src/Mod/Path/PathScripts/PathArray.py index b209c4658c6a..05913d8dda8b 100644 --- a/src/Mod/Path/PathScripts/PathArray.py +++ b/src/Mod/Path/PathScripts/PathArray.py @@ -1,29 +1,31 @@ # -*- coding: utf-8 -*- -#*************************************************************************** -#* * -#* Copyright (c) 2015 Yorik van Havre * -#* * -#* This program is free software; you can redistribute it and/or modify * -#* it under the terms of the GNU Lesser General Public License (LGPL) * -#* as published by the Free Software Foundation; either version 2 of * -#* the License, or (at your option) any later version. * -#* for detail see the LICENCE text file. * -#* * -#* This program is distributed in the hope that it will be useful, * -#* but WITHOUT ANY WARRANTY; without even the implied warranty of * -#* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * -#* GNU Library General Public License for more details. * -#* * -#* You should have received a copy of the GNU Library General Public * -#* License along with this program; if not, write to the Free Software * -#* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * -#* USA * -#* * -#*************************************************************************** - -import FreeCAD,FreeCADGui,Path,PathGui -from PySide import QtCore,QtGui +# *************************************************************************** +# * * +# * Copyright (c) 2015 Yorik van Havre * +# * * +# * This program is free software; you can redistribute it and/or modify * +# * it under the terms of the GNU Lesser General Public License (LGPL) * +# * as published by the Free Software Foundation; either version 2 of * +# * the License, or (at your option) any later version. * +# * for detail see the LICENCE text file. * +# * * +# * This program is distributed in the hope that it will be useful, * +# * but WITHOUT ANY WARRANTY; without even the implied warranty of * +# * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * +# * GNU Library General Public License for more details. * +# * * +# * You should have received a copy of the GNU Library General Public * +# * License along with this program; if not, write to the Free Software * +# * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * +# * USA * +# * * +# *************************************************************************** + +import FreeCAD +import FreeCADGui +import Path +from PySide import QtCore, QtGui """Path Array object and FreeCAD command""" @@ -38,27 +40,29 @@ def translate(context, text, disambig=None): class ObjectArray: - - def __init__(self,obj): - obj.addProperty("App::PropertyLink","Base","Path",QtCore.QT_TRANSLATE_NOOP("App::Property","The path to array")) - obj.addProperty("App::PropertyVectorDistance","Offset","Path",QtCore.QT_TRANSLATE_NOOP("App::Property","The spacing between the array copies")) - obj.addProperty("App::PropertyInteger","Copies","Path",QtCore.QT_TRANSLATE_NOOP("App::Property","The number of copies")) + def __init__(self, obj): + obj.addProperty("App::PropertyLink", "Base", + "Path", "The path to array") + obj.addProperty("App::PropertyVectorDistance", "Offset", + "Path", "The spacing between the array copies") + obj.addProperty("App::PropertyInteger", "Copies", + "Path", "The number of copies") obj.Proxy = self def __getstate__(self): return None - def __setstate__(self,state): + def __setstate__(self, state): return None - - def execute(self,obj): + + def execute(self, obj): if obj.Base: if not obj.Base.isDerivedFrom("Path::Feature"): return if not obj.Base.Path: return - + # build copies basepath = obj.Base.Path output = basepath.toGCode() @@ -66,33 +70,33 @@ def execute(self,obj): if obj.Offset != FreeCAD.Vector(): for i in range(obj.Copies): pl.move(obj.Offset) - np = Path.Path([cm.transform(pl) for cm in basepath.Commands]) + np = Path.Path([cm.transform(pl) + for cm in basepath.Commands]) output += np.toGCode() - #print output + # print output path = Path.Path(output) obj.Path = path class ViewProviderArray: - - def __init__(self,vobj): + def __init__(self, vobj): vobj.Proxy = self - - def attach(self,vobj): + + def attach(self, vobj): self.Object = vobj.Object return def __getstate__(self): return None - def __setstate__(self,state): + def __setstate__(self, state): return None - + def claimChildren(self): - if hasattr(self,"Object"): - if hasattr(self.Object,"Base"): + if hasattr(self, "Object"): + if hasattr(self.Object, "Base"): if self.Object.Base: return self.Object.Base return [] @@ -100,40 +104,48 @@ def claimChildren(self): class CommandPathArray: - def GetResources(self): - return {'Pixmap' : 'Path-Array', - 'MenuText': QtCore.QT_TRANSLATE_NOOP("Path_Array","Array"), - 'ToolTip': QtCore.QT_TRANSLATE_NOOP("Path_Array","Creates an array from a selected path")} + return {'Pixmap': 'Path-Array', + 'MenuText': QtCore.QT_TRANSLATE_NOOP("Path_Array", "Array"), + 'ToolTip': QtCore.QT_TRANSLATE_NOOP("Path_Array", "Creates an array from a selected path")} def IsActive(self): - return not FreeCAD.ActiveDocument is None - + 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: - FreeCAD.Console.PrintError(translate("Path_Array","Please select exactly one path object\n")) + FreeCAD.Console.PrintError( + translate("Path_Array", "Please select exactly one path object\n")) return if not(selection[0].isDerivedFrom("Path::Feature")): - FreeCAD.Console.PrintError(translate("Path_Array","Please select exactly one path object\n")) + FreeCAD.Console.PrintError( + translate("Path_Array", "Please select exactly one path object\n")) return - - # if everything is ok, execute and register the transaction in the undo/redo stack + + # if everything is ok, execute and register the transaction in the + # undo/redo stack FreeCAD.ActiveDocument.openTransaction("Create Array") FreeCADGui.addModule("PathScripts.PathArray") FreeCADGui.addModule("PathScripts.PathUtils") - FreeCADGui.doCommand('obj = FreeCAD.ActiveDocument.addObject("Path::FeaturePython","Array")') + FreeCADGui.doCommand( + 'obj = FreeCAD.ActiveDocument.addObject("Path::FeaturePython","Array")') FreeCADGui.doCommand('PathScripts.PathArray.ObjectArray(obj)') - FreeCADGui.doCommand('obj.Base = (FreeCAD.ActiveDocument.' + selection[0].Name + ')') - #FreeCADGui.doCommand('PathScripts.PathArray.ViewProviderArray(obj.ViewObject)') + FreeCADGui.doCommand( + 'obj.Base = (FreeCAD.ActiveDocument.' + selection[0].Name + ')') + # FreeCADGui.doCommand('PathScripts.PathArray.ViewProviderArray(obj.ViewObject)') FreeCADGui.doCommand('obj.ViewObject.Proxy = 0') - FreeCADGui.doCommand('PathScripts.PathUtils.addToProject(obj)') + FreeCADGui.doCommand('PathScripts.PathUtils.addToJob(obj)') FreeCAD.ActiveDocument.commitTransaction() FreeCAD.ActiveDocument.recompute() -if FreeCAD.GuiUp: +if FreeCAD.GuiUp: # register the FreeCAD command - FreeCADGui.addCommand('Path_Array',CommandPathArray()) + FreeCADGui.addCommand('Path_Array', CommandPathArray()) diff --git a/src/Mod/Path/PathScripts/PathComment.py b/src/Mod/Path/PathScripts/PathComment.py index b3d6cb833cf5..de048667321e 100644 --- a/src/Mod/Path/PathScripts/PathComment.py +++ b/src/Mod/Path/PathScripts/PathComment.py @@ -1,119 +1,126 @@ # -*- coding: utf-8 -*- -#*************************************************************************** -#* * -#* Copyright (c) 2015 Dan Falck * -#* * -#* This program is free software; you can redistribute it and/or modify * -#* it under the terms of the GNU Lesser General Public License (LGPL) * -#* as published by the Free Software Foundation; either version 2 of * -#* the License, or (at your option) any later version. * -#* for detail see the LICENCE text file. * -#* * -#* This program is distributed in the hope that it will be useful, * -#* but WITHOUT ANY WARRANTY; without even the implied warranty of * -#* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * -#* GNU Library General Public License for more details. * -#* * -#* You should have received a copy of the GNU Library General Public * -#* License along with this program; if not, write to the Free Software * -#* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * -#* USA * -#* * -#*************************************************************************** +# *************************************************************************** +# * * +# * Copyright (c) 2015 Dan Falck * +# * * +# * This program is free software; you can redistribute it and/or modify * +# * it under the terms of the GNU Lesser General Public License (LGPL) * +# * as published by the Free Software Foundation; either version 2 of * +# * the License, or (at your option) any later version. * +# * for detail see the LICENCE text file. * +# * * +# * This program is distributed in the hope that it will be useful, * +# * but WITHOUT ANY WARRANTY; without even the implied warranty of * +# * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * +# * GNU Library General Public License for more details. * +# * * +# * You should have received a copy of the GNU Library General Public * +# * License along with this program; if not, write to the Free Software * +# * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * +# * USA * +# * * +# *************************************************************************** ''' Used for CNC machine comments for Path module. Create a comment and place it in the Document tree.''' -import FreeCAD,FreeCADGui,Path,PathGui -from PathScripts import PathProject -from PySide import QtCore,QtGui +import FreeCAD +import FreeCADGui +import Path +from PySide import QtCore, QtGui # Qt tanslation handling try: _encoding = QtGui.QApplication.UnicodeUTF8 + def translate(context, text, disambig=None): return QtGui.QApplication.translate(context, text, disambig, _encoding) except AttributeError: def translate(context, text, disambig=None): return QtGui.QApplication.translate(context, text, disambig) + class Comment: - def __init__(self,obj): - obj.addProperty("App::PropertyString","Comment","Path",QtCore.QT_TRANSLATE_NOOP("App::Property","Comment or note for CNC program")) + + def __init__(self, obj): + obj.addProperty("App::PropertyString", "Comment", + "Path", "Comment or note for CNC program") obj.Proxy = self mode = 2 - obj.setEditorMode('Placement',mode) - + obj.setEditorMode('Placement', mode) def __getstate__(self): return None - def __setstate__(self,state): + def __setstate__(self, state): return None - def onChanged(self,obj,prop): + def onChanged(self, obj, prop): pass - def execute(self,obj): - output ="" - output += '('+ str(obj.Comment)+')\n' - path = Path.Path(output) - obj.Path = path + def execute(self, obj): + output = "" + output += '(' + str(obj.Comment) + ')\n' + path = Path.Path(output) + obj.Path = path + class _ViewProviderComment: - def __init__(self,vobj): #mandatory -# obj.addProperty("App::PropertyFloat","SomePropertyName","PropertyGroup","Description of this property") + + def __init__(self, vobj): # mandatory vobj.Proxy = self mode = 2 - vobj.setEditorMode('LineWidth',mode) - vobj.setEditorMode('MarkerColor',mode) - vobj.setEditorMode('NormalColor',mode) - vobj.setEditorMode('ShowFirstRapid',mode) - vobj.setEditorMode('DisplayMode',mode) - vobj.setEditorMode('BoundingBox',mode) - vobj.setEditorMode('Selectable',mode) - vobj.setEditorMode('ShapeColor',mode) - vobj.setEditorMode('Transparency',mode) - vobj.setEditorMode('Visibility',mode) - - - def __getstate__(self): #mandatory + vobj.setEditorMode('LineWidth', mode) + vobj.setEditorMode('MarkerColor', mode) + vobj.setEditorMode('NormalColor', mode) + vobj.setEditorMode('ShowFirstRapid', mode) + vobj.setEditorMode('DisplayMode', mode) + vobj.setEditorMode('BoundingBox', mode) + vobj.setEditorMode('Selectable', mode) + vobj.setEditorMode('ShapeColor', mode) + vobj.setEditorMode('Transparency', mode) + vobj.setEditorMode('Visibility', mode) + + def __getstate__(self): # mandatory return None - def __setstate__(self,state): #mandatory + def __setstate__(self, state): # mandatory return None - def getIcon(self): #optional + def getIcon(self): # optional return ":/icons/Path-Comment.svg" - def onChanged(self,vobj,prop): #optional + def onChanged(self, vobj, prop): # optional mode = 2 - vobj.setEditorMode('LineWidth',mode) - vobj.setEditorMode('MarkerColor',mode) - vobj.setEditorMode('NormalColor',mode) - vobj.setEditorMode('ShowFirstRapid',mode) - vobj.setEditorMode('DisplayMode',mode) - vobj.setEditorMode('BoundingBox',mode) - vobj.setEditorMode('Selectable',mode) - vobj.setEditorMode('ShapeColor',mode) - vobj.setEditorMode('Transparency',mode) - vobj.setEditorMode('Visibility',mode) - - def getIcon(self): - return ":/icons/Path-Comment.svg" + vobj.setEditorMode('LineWidth', mode) + vobj.setEditorMode('MarkerColor', mode) + vobj.setEditorMode('NormalColor', mode) + vobj.setEditorMode('ShowFirstRapid', mode) + vobj.setEditorMode('DisplayMode', mode) + vobj.setEditorMode('BoundingBox', mode) + vobj.setEditorMode('Selectable', mode) + vobj.setEditorMode('ShapeColor', mode) + vobj.setEditorMode('Transparency', mode) + vobj.setEditorMode('Visibility', mode) class CommandPathComment: + def GetResources(self): - return {'Pixmap' : 'Path-Comment', - 'MenuText': QtCore.QT_TRANSLATE_NOOP("Path_Comment","Comment"), + return {'Pixmap': 'Path-Comment', + 'MenuText': QtCore.QT_TRANSLATE_NOOP("Path_Comment", "Comment"), 'Accel': "P, C", - 'ToolTip': QtCore.QT_TRANSLATE_NOOP("Path_Comment","Add a Comment to your CNC program")} + 'ToolTip': QtCore.QT_TRANSLATE_NOOP("Path_Comment", "Add a Comment to your CNC program")} def IsActive(self): - return not FreeCAD.ActiveDocument is None + if FreeCAD.ActiveDocument is not None: + for o in FreeCAD.ActiveDocument.Objects: + if o.Name[:3] == "Job": + return True + return False def Activated(self): - FreeCAD.ActiveDocument.openTransaction(translate("Path_Comment","Create a Comment in your CNC program")) + FreeCAD.ActiveDocument.openTransaction( + translate("Path_Comment", "Create a Comment in your CNC program")) FreeCADGui.addModule("PathScripts.PathComment") snippet = ''' import Path @@ -123,15 +130,15 @@ def Activated(self): PathScripts.PathComment.Comment(obj) PathScripts.PathComment._ViewProviderComment(obj.ViewObject) -PathUtils.addToProject(obj) +PathUtils.addToJob(obj) ''' FreeCADGui.doCommand(snippet) FreeCAD.ActiveDocument.commitTransaction() FreeCAD.ActiveDocument.recompute() -if FreeCAD.GuiUp: +if FreeCAD.GuiUp: # register the FreeCAD command - FreeCADGui.addCommand('Path_Comment',CommandPathComment()) + FreeCADGui.addCommand('Path_Comment', CommandPathComment()) FreeCAD.Console.PrintLog("Loading PathComment... done\n") diff --git a/src/Mod/Path/PathScripts/PathCompoundExtended.py b/src/Mod/Path/PathScripts/PathCompoundExtended.py index cdcc48ebb226..08e9b20808bf 100644 --- a/src/Mod/Path/PathScripts/PathCompoundExtended.py +++ b/src/Mod/Path/PathScripts/PathCompoundExtended.py @@ -1,35 +1,37 @@ # -*- coding: utf-8 -*- - -#*************************************************************************** -#* * -#* Copyright (c) 2014 Yorik van Havre * -#* * -#* This program is free software; you can redistribute it and/or modify * -#* it under the terms of the GNU Lesser General Public License (LGPL) * -#* as published by the Free Software Foundation; either version 2 of * -#* the License, or (at your option) any later version. * -#* for detail see the LICENCE text file. * -#* * -#* This program is distributed in the hope that it will be useful, * -#* but WITHOUT ANY WARRANTY; without even the implied warranty of * -#* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * -#* GNU Library General Public License for more details. * -#* * -#* You should have received a copy of the GNU Library General Public * -#* License along with this program; if not, write to the Free Software * -#* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * -#* USA * -#* * -#*************************************************************************** - -import FreeCAD,FreeCADGui,Path,PathGui, PathUtils -from PySide import QtCore,QtGui +# *************************************************************************** +# * * +# * Copyright (c) 2014 Yorik van Havre * +# * * +# * This program is free software; you can redistribute it and/or modify * +# * it under the terms of the GNU Lesser General Public License (LGPL) * +# * as published by the Free Software Foundation; either version 2 of * +# * the License, or (at your option) any later version. * +# * for detail see the LICENCE text file. * +# * * +# * This program is distributed in the hope that it will be useful, * +# * but WITHOUT ANY WARRANTY; without even the implied warranty of * +# * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * +# * GNU Library General Public License for more details. * +# * * +# * You should have received a copy of the GNU Library General Public * +# * License along with this program; if not, write to the Free Software * +# * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * +# * USA * +# * * +# *************************************************************************** + +import FreeCAD +import FreeCADGui +import Path +from PySide import QtCore, QtGui """Path Compound Extended object and FreeCAD command""" # Qt tanslation handling try: _encoding = QtGui.QApplication.UnicodeUTF8 + def translate(context, text, disambig=None): return QtGui.QApplication.translate(context, text, disambig, _encoding) except AttributeError: @@ -38,7 +40,6 @@ def translate(context, text, disambig=None): class ObjectCompoundExtended: - def __init__(self,obj): obj.addProperty("App::PropertyString","Description", "Path",QtCore.QT_TRANSLATE_NOOP("App::Property","An ptional description of this compounded operation")) @@ -51,17 +52,17 @@ def __init__(self,obj): def __getstate__(self): return None - def __setstate__(self,state): + def __setstate__(self, state): return None - def onChanged(self,obj,prop): + def onChanged(self, obj, prop): if prop == "Group": print 'check order' for child in obj.Group: if child.isDerivedFrom("Path::Feature"): - child.touch() + child.touch() - def execute(self,obj): + def execute(self, obj): cmds = [] for child in obj.Group: if child.isDerivedFrom("Path::Feature"): @@ -77,10 +78,10 @@ def execute(self,obj): class ViewProviderCompoundExtended: - def __init__(self,vobj): + def __init__(self, vobj): vobj.Proxy = self - def attach(self,vobj): + def attach(self, vobj): self.Object = vobj.Object return @@ -90,25 +91,29 @@ def getIcon(self): def __getstate__(self): return None - def __setstate__(self,state): + def __setstate__(self, state): return None class CommandCompoundExtended: - def GetResources(self): - return {'Pixmap' : 'Path-Compound', - 'MenuText': QtCore.QT_TRANSLATE_NOOP("Path_CompoundExtended","Compound"), + return {'Pixmap': 'Path-Compound', + 'MenuText': QtCore.QT_TRANSLATE_NOOP("Path_CompoundExtended", "Compound"), 'Accel': "P, C", - 'ToolTip': QtCore.QT_TRANSLATE_NOOP("Path_CompoundExtended","Creates a Path Compound object")} + 'ToolTip': QtCore.QT_TRANSLATE_NOOP("Path_CompoundExtended", "Creates a Path Compound object")} def IsActive(self): - return not FreeCAD.ActiveDocument is None - + if FreeCAD.ActiveDocument is not None: + for o in FreeCAD.ActiveDocument.Objects: + if o.Name[:3] == "Job": + return True + return False + def Activated(self): - FreeCAD.ActiveDocument.openTransaction(translate("Path_CompoundExtended","Create Compound")) + FreeCAD.ActiveDocument.openTransaction( + translate("Path_CompoundExtended", "Create Compound")) FreeCADGui.addModule("PathScripts.PathCompoundExtended") snippet = ''' import Path @@ -124,12 +129,11 @@ def Activated(self): obj = FreeCAD.ActiveDocument.addObject("Path::FeatureCompoundPython","Compound") PathScripts.PathCompoundExtended.ObjectCompoundExtended(obj) PathScripts.PathCompoundExtended.ViewProviderCompoundExtended(obj.ViewObject) -project = PathUtils.addToProject(obj) +project = PathUtils.addToJob(obj) if incl: children = [] p = project.Group - g = obj.Group for child in incl: p.remove(child) @@ -143,8 +147,8 @@ def Activated(self): FreeCAD.ActiveDocument.recompute() -if FreeCAD.GuiUp: +if FreeCAD.GuiUp: # register the FreeCAD command - FreeCADGui.addCommand('Path_CompoundExtended',CommandCompoundExtended()) + FreeCADGui.addCommand('Path_CompoundExtended', CommandCompoundExtended()) FreeCAD.Console.PrintLog("Loading PathCompoundExtended... done\n") diff --git a/src/Mod/Path/PathScripts/PathCopy.py b/src/Mod/Path/PathScripts/PathCopy.py index d2c25dd01164..2dd346772175 100644 --- a/src/Mod/Path/PathScripts/PathCopy.py +++ b/src/Mod/Path/PathScripts/PathCopy.py @@ -1,35 +1,37 @@ # -*- coding: utf-8 -*- -#*************************************************************************** -#* * -#* Copyright (c) 2014 Yorik van Havre * -#* * -#* This program is free software; you can redistribute it and/or modify * -#* it under the terms of the GNU Lesser General Public License (LGPL) * -#* as published by the Free Software Foundation; either version 2 of * -#* the License, or (at your option) any later version. * -#* for detail see the LICENCE text file. * -#* * -#* This program is distributed in the hope that it will be useful, * -#* but WITHOUT ANY WARRANTY; without even the implied warranty of * -#* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * -#* GNU Library General Public License for more details. * -#* * -#* You should have received a copy of the GNU Library General Public * -#* License along with this program; if not, write to the Free Software * -#* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * -#* USA * -#* * -#*************************************************************************** - -import FreeCAD,FreeCADGui,Path,PathGui -from PySide import QtCore,QtGui +# *************************************************************************** +# * * +# * Copyright (c) 2014 Yorik van Havre * +# * * +# * This program is free software; you can redistribute it and/or modify * +# * it under the terms of the GNU Lesser General Public License (LGPL) * +# * as published by the Free Software Foundation; either version 2 of * +# * the License, or (at your option) any later version. * +# * for detail see the LICENCE text file. * +# * * +# * This program is distributed in the hope that it will be useful, * +# * but WITHOUT ANY WARRANTY; without even the implied warranty of * +# * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * +# * GNU Library General Public License for more details. * +# * * +# * You should have received a copy of the GNU Library General Public * +# * License along with this program; if not, write to the Free Software * +# * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * +# * USA * +# * * +# *************************************************************************** + +import FreeCAD +import FreeCADGui +from PySide import QtCore, QtGui """Path Copy object and FreeCAD command""" # Qt tanslation handling try: _encoding = QtGui.QApplication.UnicodeUTF8 + def translate(context, text, disambig=None): return QtGui.QApplication.translate(context, text, disambig, _encoding) except AttributeError: @@ -38,7 +40,6 @@ def translate(context, text, disambig=None): class ObjectPathCopy: - def __init__(self,obj): obj.addProperty("App::PropertyLink","Base","Path",QtCore.QT_TRANSLATE_NOOP("App::Property","The path to be copied")) @@ -47,10 +48,10 @@ def __init__(self,obj): def __getstate__(self): return None - def __setstate__(self,state): + def __setstate__(self, state): return None - - def execute(self,obj): + + def execute(self, obj): if obj.Base: if obj.Base.Path: obj.Path = obj.Base.Path.copy() @@ -58,10 +59,10 @@ def execute(self,obj): class ViewProviderPathCopy: - def __init__(self,vobj): + def __init__(self, vobj): vobj.Proxy = self - def attach(self,vobj): + def attach(self, vobj): self.Object = vobj.Object return @@ -71,25 +72,29 @@ def getIcon(self): def __getstate__(self): return None - def __setstate__(self,state): + def __setstate__(self, state): return None class CommandPathCopy: - def GetResources(self): - return {'Pixmap' : 'Path-Copy', - 'MenuText': QtCore.QT_TRANSLATE_NOOP("Path_Copy","Copy"), + return {'Pixmap': 'Path-Copy', + 'MenuText': QtCore.QT_TRANSLATE_NOOP("Path_Copy", "Copy"), 'Accel': "P, Y", - 'ToolTip': QtCore.QT_TRANSLATE_NOOP("Path_Copy","Creates a linked copy of another path")} + 'ToolTip': QtCore.QT_TRANSLATE_NOOP("Path_Copy", "Creates a linked copy of another path")} def IsActive(self): - return not FreeCAD.ActiveDocument is None - + if FreeCAD.ActiveDocument is not None: + for o in FreeCAD.ActiveDocument.Objects: + if o.Name[:3] == "Job": + return True + return False + def Activated(self): - FreeCAD.ActiveDocument.openTransaction(translate("Path_Copy","Create Copy")) + FreeCAD.ActiveDocument.openTransaction( + translate("Path_Copy", "Create Copy")) FreeCADGui.addModule("PathScripts.PathCopy") consolecode = ''' @@ -128,8 +133,8 @@ def Activated(self): FreeCAD.ActiveDocument.recompute() -if FreeCAD.GuiUp: +if FreeCAD.GuiUp: # register the FreeCAD command - FreeCADGui.addCommand('Path_Copy',CommandPathCopy()) + FreeCADGui.addCommand('Path_Copy', CommandPathCopy()) FreeCAD.Console.PrintLog("Loading PathCopy... done\n") diff --git a/src/Mod/Path/PathScripts/PathCustom.py b/src/Mod/Path/PathScripts/PathCustom.py index 9ba1c3b255ef..eeb393fc5386 100644 --- a/src/Mod/Path/PathScripts/PathCustom.py +++ b/src/Mod/Path/PathScripts/PathCustom.py @@ -1,35 +1,37 @@ # -*- coding: utf-8 -*- - -#*************************************************************************** -#* * -#* Copyright (c) 2014 Yorik van Havre * -#* * -#* This program is free software; you can redistribute it and/or modify * -#* it under the terms of the GNU Lesser General Public License (LGPL) * -#* as published by the Free Software Foundation; either version 2 of * -#* the License, or (at your option) any later version. * -#* for detail see the LICENCE text file. * -#* * -#* This program is distributed in the hope that it will be useful, * -#* but WITHOUT ANY WARRANTY; without even the implied warranty of * -#* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * -#* GNU Library General Public License for more details. * -#* * -#* You should have received a copy of the GNU Library General Public * -#* License along with this program; if not, write to the Free Software * -#* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * -#* USA * -#* * -#*************************************************************************** - -import FreeCAD,FreeCADGui,Path,PathGui -from PySide import QtCore,QtGui +# *************************************************************************** +# * * +# * Copyright (c) 2014 Yorik van Havre * +# * * +# * This program is free software; you can redistribute it and/or modify * +# * it under the terms of the GNU Lesser General Public License (LGPL) * +# * as published by the Free Software Foundation; either version 2 of * +# * the License, or (at your option) any later version. * +# * for detail see the LICENCE text file. * +# * * +# * This program is distributed in the hope that it will be useful, * +# * but WITHOUT ANY WARRANTY; without even the implied warranty of * +# * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * +# * GNU Library General Public License for more details. * +# * * +# * You should have received a copy of the GNU Library General Public * +# * License along with this program; if not, write to the Free Software * +# * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * +# * USA * +# * * +# *************************************************************************** + +import FreeCAD +import FreeCADGui +import Path +from PySide import QtCore, QtGui """Path Custom object and FreeCAD command""" # Qt tanslation handling try: _encoding = QtGui.QApplication.UnicodeUTF8 + def translate(context, text, disambig=None): return QtGui.QApplication.translate(context, text, disambig, _encoding) except AttributeError: @@ -47,11 +49,11 @@ def __init__(self,obj): def __getstate__(self): return None - def __setstate__(self,state): + def __setstate__(self, state): return None - - def execute(self,obj): - if obj.Gcode: + + def execute(self, obj): + if obj.Gcode: s = "" for l in obj.Gcode: s += str(l) @@ -62,27 +64,31 @@ def execute(self,obj): class CommandPathCustom: - def GetResources(self): - return {'Pixmap' : 'Path-Custom', - 'MenuText': QtCore.QT_TRANSLATE_NOOP("Path_Custom","Custom"), - 'ToolTip': QtCore.QT_TRANSLATE_NOOP("Path_Custom","Creates a path object based on custom G-code")} + return {'Pixmap': 'Path-Custom', + 'MenuText': QtCore.QT_TRANSLATE_NOOP("Path_Custom", "Custom"), + 'ToolTip': QtCore.QT_TRANSLATE_NOOP("Path_Custom", "Creates a path object based on custom G-code")} def IsActive(self): - return not FreeCAD.ActiveDocument is None - + if FreeCAD.ActiveDocument is not None: + for o in FreeCAD.ActiveDocument.Objects: + if o.Name[:3] == "Job": + return True + return False + def Activated(self): FreeCAD.ActiveDocument.openTransaction("Create Custom Path") FreeCADGui.addModule("PathScripts.PathCustom") FreeCADGui.addModule("PathScripts.PathUtils") - FreeCADGui.doCommand('obj = FreeCAD.ActiveDocument.addObject("Path::FeaturePython","Custom")') + FreeCADGui.doCommand( + 'obj = FreeCAD.ActiveDocument.addObject("Path::FeaturePython","Custom")') FreeCADGui.doCommand('PathScripts.PathCustom.ObjectCustom(obj)') FreeCADGui.doCommand('obj.ViewObject.Proxy = 0') - FreeCADGui.doCommand('PathScripts.PathUtils.addToProject(obj)') + FreeCADGui.doCommand('PathScripts.PathUtils.addToJob(obj)') FreeCAD.ActiveDocument.commitTransaction() FreeCAD.ActiveDocument.recompute() -if FreeCAD.GuiUp: +if FreeCAD.GuiUp: # register the FreeCAD command - FreeCADGui.addCommand('Path_Custom',CommandPathCustom()) + FreeCADGui.addCommand('Path_Custom', CommandPathCustom()) diff --git a/src/Mod/Path/PathScripts/PathDressup.py b/src/Mod/Path/PathScripts/PathDressup.py index d87fbed8204e..395474719422 100644 --- a/src/Mod/Path/PathScripts/PathDressup.py +++ b/src/Mod/Path/PathScripts/PathDressup.py @@ -114,7 +114,11 @@ def GetResources(self): 'ToolTip': QtCore.QT_TRANSLATE_NOOP("Path_Dressup", "Creates a Path Dress-up object from a selected path")} def IsActive(self): - return FreeCAD.ActiveDocument is not None + if FreeCAD.ActiveDocument is not None: + for o in FreeCAD.ActiveDocument.Objects: + if o.Name[:3] == "Job": + return True + return False def Activated(self): diff --git a/src/Mod/Path/PathScripts/PathDrilling.py b/src/Mod/Path/PathScripts/PathDrilling.py index ffe5d9957fa3..2fe3b8c51fe6 100644 --- a/src/Mod/Path/PathScripts/PathDrilling.py +++ b/src/Mod/Path/PathScripts/PathDrilling.py @@ -266,7 +266,11 @@ def GetResources(self): 'ToolTip': QtCore.QT_TRANSLATE_NOOP("Path_Drilling", "Creates a Path Drilling object")} def IsActive(self): - return FreeCAD.ActiveDocument is not None + if FreeCAD.ActiveDocument is not None: + for o in FreeCAD.ActiveDocument.Objects: + if o.Name[:3] == "Job": + return True + return False def Activated(self): @@ -283,7 +287,7 @@ def Activated(self): FreeCADGui.doCommand('obj.ClearanceHeight = ' + str(ztop)) FreeCADGui.doCommand('obj.RetractHeight= ' + str(ztop)) FreeCADGui.doCommand('obj.FinalDepth=' + str(zbottom)) - FreeCADGui.doCommand('PathScripts.PathUtils.addToProject(obj)') + FreeCADGui.doCommand('PathScripts.PathUtils.addToJob(obj)') FreeCAD.ActiveDocument.commitTransaction() FreeCAD.ActiveDocument.recompute() diff --git a/src/Mod/Path/PathScripts/PathEngrave.py b/src/Mod/Path/PathScripts/PathEngrave.py index de6683cf7de3..3519fbf4c023 100644 --- a/src/Mod/Path/PathScripts/PathEngrave.py +++ b/src/Mod/Path/PathScripts/PathEngrave.py @@ -56,6 +56,9 @@ def __init__(self, obj): obj.Algorithm = ['OCC Native'] # Tool Properties + obj.addProperty("App::PropertyEnumeration", "ToolController", "Tool", QtCore.QT_TRANSLATE_NOOP("App::Property","The tool controller to use")) + obj.ToolController = ["None"] + obj.addProperty("App::PropertyIntegerConstraint", "ToolNumber", "Tool", QtCore.QT_TRANSLATE_NOOP("App::Property","The tool number in use")) obj.ToolNumber = (0, 0, 1000, 1) obj.setEditorMode('ToolNumber', 1) # make this read only @@ -88,6 +91,17 @@ def execute(self, obj): if obj.Comment != "": output += '(' + str(obj.Comment)+')\n' + myJob = PathUtils.findMyJob(obj) + if myJob is not None: + controllers = myJob.Proxy.getToolControllers(myJob) + if len(controllers) >= 1: + mlist = [] + for c in controllers: + mlist.append(c.Name) + else: + mlist = ["None"] + obj.ToolController = mlist + toolLoad = PathUtils.getLastToolLoad(obj) if toolLoad is None or toolLoad.ToolNumber == 0: self.vertFeed = 100 @@ -238,6 +252,9 @@ def __getstate__(self): def __setstate__(self, state): return None + def onDelete(self): + return None + class CommandPathEngrave: @@ -247,7 +264,11 @@ def GetResources(self): 'ToolTip': QtCore.QT_TRANSLATE_NOOP("Path_Engrave", "Creates an Engraving Path around a Draft ShapeString")} def IsActive(self): - return FreeCAD.ActiveDocument is not None + if FreeCAD.ActiveDocument is not None: + for o in FreeCAD.ActiveDocument.Objects: + if o.Name[:3] == "Job": + return True + return False def Activated(self): @@ -263,7 +284,7 @@ def Activated(self): FreeCADGui.doCommand('obj.SafeHeight= 5.0') FreeCADGui.doCommand('obj.Active = True') - FreeCADGui.doCommand('PathScripts.PathUtils.addToProject(obj)') + FreeCADGui.doCommand('PathScripts.PathUtils.addToJob(obj)') FreeCAD.ActiveDocument.commitTransaction() FreeCAD.ActiveDocument.recompute() FreeCADGui.doCommand('obj.ViewObject.startEditing()') diff --git a/src/Mod/Path/PathScripts/PathFacePocket.py b/src/Mod/Path/PathScripts/PathFacePocket.py index 75007cac2918..aacadb3fd5bf 100644 --- a/src/Mod/Path/PathScripts/PathFacePocket.py +++ b/src/Mod/Path/PathScripts/PathFacePocket.py @@ -1,35 +1,37 @@ # -*- coding: utf-8 -*- - -#*************************************************************************** -#* * -#* Copyright (c) 2014 Yorik van Havre * -#* * -#* This program is free software; you can redistribute it and/or modify * -#* it under the terms of the GNU Lesser General Public License (LGPL) * -#* as published by the Free Software Foundation; either version 2 of * -#* the License, or (at your option) any later version. * -#* for detail see the LICENCE text file. * -#* * -#* This program is distributed in the hope that it will be useful, * -#* but WITHOUT ANY WARRANTY; without even the implied warranty of * -#* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * -#* GNU Library General Public License for more details. * -#* * -#* You should have received a copy of the GNU Library General Public * -#* License along with this program; if not, write to the Free Software * -#* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * -#* USA * -#* * -#*************************************************************************** - -import FreeCAD,FreeCADGui,Path,PathGui -from PySide import QtCore,QtGui +# *************************************************************************** +# * * +# * Copyright (c) 2014 Yorik van Havre * +# * * +# * This program is free software; you can redistribute it and/or modify * +# * it under the terms of the GNU Lesser General Public License (LGPL) * +# * as published by the Free Software Foundation; either version 2 of * +# * the License, or (at your option) any later version. * +# * for detail see the LICENCE text file. * +# * * +# * This program is distributed in the hope that it will be useful, * +# * but WITHOUT ANY WARRANTY; without even the implied warranty of * +# * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * +# * GNU Library General Public License for more details. * +# * * +# * You should have received a copy of the GNU Library General Public * +# * License along with this program; if not, write to the Free Software * +# * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * +# * USA * +# * * +# *************************************************************************** + +import FreeCAD +import FreeCADGui +import Path +from PySide import QtCore, QtGui """Path Pocket object and FreeCAD command""" # Qt tanslation handling try: _encoding = QtGui.QApplication.UnicodeUTF8 + def translate(context, text, disambig=None): return QtGui.QApplication.translate(context, text, disambig, _encoding) except AttributeError: @@ -38,7 +40,6 @@ def translate(context, text, disambig=None): class ObjectFacePocket: - def __init__(self,obj): obj.addProperty("App::PropertyLinkSub","Base","Path",QtCore.QT_TRANSLATE_NOOP("App::Property","The base geometry of this object")) @@ -53,44 +54,47 @@ def __init__(self,obj): def __getstate__(self): return None - def __setstate__(self,state): + def __setstate__(self, state): return None - - def execute(self,obj): + + def execute(self, obj): if obj.Base and obj.Offset.Value: - import Part, DraftGeomUtils + import Part + import DraftGeomUtils if "Face" in obj.Base[1][0]: - shape = getattr(obj.Base[0].Shape,obj.Base[1][0]) + shape = getattr(obj.Base[0].Shape, obj.Base[1][0]) else: - edges = [getattr(obj.Base[0].Shape,sub) for sub in obj.Base[1]] + edges = [getattr(obj.Base[0].Shape, sub) + for sub in obj.Base[1]] shape = Part.Wire(edges) - + # absolute coords, millimeters, cancel offsets output = "G90\nG21\nG40\n" - + # build offsets offsets = [] nextradius = obj.Offset.Value - result = DraftGeomUtils.pocket2d(shape,nextradius) + result = DraftGeomUtils.pocket2d(shape, nextradius) while result: offsets.extend(result) if obj.Fill: nextradius += obj.Offset.Value - result = DraftGeomUtils.pocket2d(shape,nextradius) + result = DraftGeomUtils.pocket2d(shape, nextradius) else: result = [] - + first = True point = None - + # revert the list so we start with the outer wires offsets.reverse() - + # loop over successive wires while offsets: currentWire = offsets.pop() if first: - currentWire = DraftGeomUtils.rebaseWire(currentWire,obj.StartVertex) + currentWire = DraftGeomUtils.rebaseWire( + currentWire, obj.StartVertex) last = None for edge in currentWire.Edges: if not last: @@ -100,91 +104,107 @@ def execute(self,obj): first = False else: if obj.RetractHeight.Value and point: - output += "G0 X" + str("%f" % point.x) + " Y" + str("%f" % point.y) + " Z" + str("%f" % obj.RetractHeight.Value) + "\n" + output += "G0 X" + str("%f" % point.x) + " Y" + str( + "%f" % point.y) + " Z" + str("%f" % obj.RetractHeight.Value) + "\n" last = edge.Vertexes[0].Point - output += "G0 X" + str("%f" % last.x) + " Y" + str("%f" % last.y) + " Z" + str("%f" % obj.RetractHeight.Value) + "\n" + output += "G0 X" + str("%f" % last.x) + " Y" + str( + "%f" % last.y) + " Z" + str("%f" % obj.RetractHeight.Value) + "\n" output += "G1" last = edge.Vertexes[0].Point - output += " X" + str("%f" % last.x) + " Y" + str("%f" % last.y) + " Z" + str("%f" % last.z) + "\n" - if isinstance(edge.Curve,Part.Circle): + output += " X" + \ + str("%f" % last.x) + " Y" + str("%f" % + last.y) + " Z" + str("%f" % last.z) + "\n" + if isinstance(edge.Curve, Part.Circle): point = edge.Vertexes[-1].Point - if point == last: # edges can come flipped + if point == last: # edges can come flipped point = edge.Vertexes[0].Point center = edge.Curve.Center relcenter = center.sub(last) - v1 = last.sub(center) - v2 = point.sub(center) + # v1 = last.sub(center) + # v2 = point.sub(center) if edge.Curve.Axis.z < 0: output += "G2" else: output += "G3" - output += " X" + str("%f" % point.x) + " Y" + str("%f" % point.y) + " Z" + str("%f" % point.z) - output += " I" + str("%f" % relcenter.x) + " J" + str("%f" % relcenter.y) + " K" + str("%f" % relcenter.z) + output += " X" + \ + str("%f" % point.x) + " Y" + str("%f" % + point.y) + " Z" + str("%f" % point.z) + output += " I" + str("%f" % relcenter.x) + " J" + str( + "%f" % relcenter.y) + " K" + str("%f" % relcenter.z) output += "\n" last = point else: point = edge.Vertexes[-1].Point - if point == last: # edges can come flipped + if point == last: # edges can come flipped point = edge.Vertexes[0].Point - output += "G1 X" + str("%f" % point.x) + " Y" + str("%f" % point.y) + " Z" + str("%f" % point.z) + "\n" + output += "G1 X" + \ + str("%f" % point.x) + " Y" + str("%f" % + point.y) + " Z" + str("%f" % point.z) + "\n" last = point - - #print output + + # print output path = Path.Path(output) obj.Path = path class CommandPathFacePocket: - def GetResources(self): - return {'Pixmap' : 'Path-FacePocket', - 'MenuText': QtCore.QT_TRANSLATE_NOOP("Path_FacePocket","Face Pocket"), - 'ToolTip': QtCore.QT_TRANSLATE_NOOP("Path_FacePocket","Creates a pocket inside a loop of edges or a face")} + return {'Pixmap': 'Path-FacePocket', + 'MenuText': QtCore.QT_TRANSLATE_NOOP("Path_FacePocket", "Face Pocket"), + 'ToolTip': QtCore.QT_TRANSLATE_NOOP("Path_FacePocket", "Creates a pocket inside a loop of edges or a face")} def IsActive(self): return not FreeCAD.ActiveDocument is None - + def Activated(self): - + # check that the selection contains exactly what we want selection = FreeCADGui.Selection.getSelectionEx() if len(selection) != 1: - FreeCAD.Console.PrintError(translate("Path_FacePocket","Please select an edges loop from one object, or a single face\n")) + FreeCAD.Console.PrintError(translate( + "Path_FacePocket", "Please select an edges loop from one object, or a single face\n")) return if len(selection[0].SubObjects) == 0: - FreeCAD.Console.PrintError(translate("Path_FacePocket","Please select an edges loop from one object, or a single face\n")) + FreeCAD.Console.PrintError(translate( + "Path_FacePocket", "Please select an edges loop from one object, or a single face\n")) return for s in selection[0].SubObjects: if s.ShapeType != "Edge": if (s.ShapeType != "Face") or (len(selection[0].SubObjects) != 1): - FreeCAD.Console.PrintError(translate("Path_FacePocket","Please select only edges or a single face\n")) + FreeCAD.Console.PrintError( + translate("Path_FacePocket", "Please select only edges or a single face\n")) return if selection[0].SubObjects[0].ShapeType == "Edge": try: import Part - w = Part.Wire(selection[0].SubObjects) + # w = Part.Wire(selection[0].SubObjects) except: - FreeCAD.Console.PrintError(translate("Path_FacePocket","The selected edges don't form a loop\n")) + FreeCAD.Console.PrintError( + translate("Path_FacePocket", "The selected edges don't form a loop\n")) return - - # if everything is ok, execute and register the transaction in the undo/redo stack + + # if everything is ok, execute and register the transaction in the + # undo/redo stack FreeCAD.ActiveDocument.openTransaction("Create Pocket") FreeCADGui.addModule("PathScripts.PathFacePocket") FreeCADGui.addModule("PathScripts.PathUtils") - FreeCADGui.doCommand('obj = FreeCAD.ActiveDocument.addObject("Path::FeaturePython","FacePocket")') - FreeCADGui.doCommand('PathScripts.PathFacePocket.ObjectFacePocket(obj)') + FreeCADGui.doCommand( + 'obj = FreeCAD.ActiveDocument.addObject("Path::FeaturePython","FacePocket")') + FreeCADGui.doCommand( + 'PathScripts.PathFacePocket.ObjectFacePocket(obj)') subs = "[" for s in selection[0].SubElementNames: subs += '"' + s + '",' subs += "]" - FreeCADGui.doCommand('obj.Base = (FreeCAD.ActiveDocument.' + selection[0].ObjectName + ',' + subs + ')') + FreeCADGui.doCommand( + 'obj.Base = (FreeCAD.ActiveDocument.' + selection[0].ObjectName + ',' + subs + ')') FreeCADGui.doCommand('obj.ViewObject.Proxy = 0') - FreeCADGui.doCommand('PathScripts.PathUtils.addToProject(obj)') + FreeCADGui.doCommand('PathScripts.PathUtils.addToJob(obj)') FreeCAD.ActiveDocument.commitTransaction() FreeCAD.ActiveDocument.recompute() -if FreeCAD.GuiUp: +if FreeCAD.GuiUp: # register the FreeCAD command - FreeCADGui.addCommand('Path_FacePocket',CommandPathFacePocket()) + FreeCADGui.addCommand('Path_FacePocket', CommandPathFacePocket()) diff --git a/src/Mod/Path/PathScripts/PathFaceProfile.py b/src/Mod/Path/PathScripts/PathFaceProfile.py index 4349b70120cd..fd2c2f31a958 100644 --- a/src/Mod/Path/PathScripts/PathFaceProfile.py +++ b/src/Mod/Path/PathScripts/PathFaceProfile.py @@ -1,35 +1,37 @@ # -*- coding: utf-8 -*- - -#*************************************************************************** -#* * -#* Copyright (c) 2014 Yorik van Havre * -#* * -#* This program is free software; you can redistribute it and/or modify * -#* it under the terms of the GNU Lesser General Public License (LGPL) * -#* as published by the Free Software Foundation; either version 2 of * -#* the License, or (at your option) any later version. * -#* for detail see the LICENCE text file. * -#* * -#* This program is distributed in the hope that it will be useful, * -#* but WITHOUT ANY WARRANTY; without even the implied warranty of * -#* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * -#* GNU Library General Public License for more details. * -#* * -#* You should have received a copy of the GNU Library General Public * -#* License along with this program; if not, write to the Free Software * -#* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * -#* USA * -#* * -#*************************************************************************** - -import FreeCAD,FreeCADGui,Path,PathGui -from PySide import QtCore,QtGui +# *************************************************************************** +# * * +# * Copyright (c) 2014 Yorik van Havre * +# * * +# * This program is free software; you can redistribute it and/or modify * +# * it under the terms of the GNU Lesser General Public License (LGPL) * +# * as published by the Free Software Foundation; either version 2 of * +# * the License, or (at your option) any later version. * +# * for detail see the LICENCE text file. * +# * * +# * This program is distributed in the hope that it will be useful, * +# * but WITHOUT ANY WARRANTY; without even the implied warranty of * +# * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * +# * GNU Library General Public License for more details. * +# * * +# * You should have received a copy of the GNU Library General Public * +# * License along with this program; if not, write to the Free Software * +# * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * +# * USA * +# * * +# *************************************************************************** + +import FreeCAD +import FreeCADGui +import Path +from PySide import QtCore, QtGui """Path Profile object and FreeCAD command""" # Qt tanslation handling try: _encoding = QtGui.QApplication.UnicodeUTF8 + def translate(context, text, disambig=None): return QtGui.QApplication.translate(context, text, disambig, _encoding) except AttributeError: @@ -38,7 +40,6 @@ def translate(context, text, disambig=None): class ObjectFaceProfile: - def __init__(self,obj): obj.addProperty("App::PropertyLinkSub","Base","Path",QtCore.QT_TRANSLATE_NOOP("App::Property","The base geometry of this object")) @@ -51,14 +52,15 @@ def __init__(self,obj): def __getstate__(self): return None - def __setstate__(self,state): + def __setstate__(self, state): return None - - def execute(self,obj): - if obj.Base: - import Part,DraftGeomUtils + + def execute(self, obj): + if obj.Base: + import Part + import DraftGeomUtils # we only consider the outer wire if this is a Face - shape = getattr(obj.Base[0].Shape,obj.Base[1][0]) + shape = getattr(obj.Base[0].Shape, obj.Base[1][0]) if shape.ShapeType == "Wire": wire = shape else: @@ -71,17 +73,19 @@ def execute(self,obj): # absolute coords, millimeters, cancel offsets output = "G90\nG21\nG40\n" # reorder the wire - offset = DraftGeomUtils.rebaseWire(offset,obj.StartVertex) + offset = DraftGeomUtils.rebaseWire(offset, obj.StartVertex) # we create the path from the offset shape last = None for edge in offset.Edges: if not last: # we set the first move to our first point last = edge.Vertexes[0].Point - output += obj.FirstMove + " X" + str("%f" % last.x) + " Y" + str("%f" % last.y) + " Z" + str("%f" % last.z) + "\n" - if isinstance(edge.Curve,Part.Circle): + output += obj.FirstMove + " X" + \ + str("%f" % last.x) + " Y" + str("%f" % + last.y) + " Z" + str("%f" % last.z) + "\n" + if isinstance(edge.Curve, Part.Circle): point = edge.Vertexes[-1].Point - if point == last: # edges can come flipped + if point == last: # edges can come flipped point = edge.Vertexes[0].Point center = edge.Curve.Center relcenter = center.sub(last) @@ -91,59 +95,69 @@ def execute(self,obj): output += "G2" else: output += "G3" - output += " X" + str("%f" % point.x) + " Y" + str("%f" % point.y) + " Z" + str("%f" % point.z) - output += " I" + str("%f" % relcenter.x) + " J" + str("%f" % relcenter.y) + " K" + str("%f" % relcenter.z) + output += " X" + str("%f" % point.x) + " Y" + \ + str("%f" % point.y) + " Z" + str("%f" % point.z) + output += " I" + str("%f" % relcenter.x) + " J" + str("%f" % + relcenter.y) + " K" + str("%f" % relcenter.z) output += "\n" last = point else: point = edge.Vertexes[-1].Point - if point == last: # edges can come flipped + if point == last: # edges can come flipped point = edge.Vertexes[0].Point - output += "G1 X" + str("%f" % point.x) + " Y" + str("%f" % point.y) + " Z" + str("%f" % point.z) + "\n" + output += "G1 X" + \ + str("%f" % point.x) + " Y" + str("%f" % + point.y) + " Z" + str("%f" % point.z) + "\n" last = point - #print output + # print output path = Path.Path(output) obj.Path = path class CommandPathFaceProfile: - def GetResources(self): - return {'Pixmap' : 'Path-FaceProfile', - 'MenuText': QtCore.QT_TRANSLATE_NOOP("Path_FaceProfile","Face Profile"), - 'ToolTip': QtCore.QT_TRANSLATE_NOOP("Path_FaceProfile","Creates a profile object around a selected face")} + return {'Pixmap': 'Path-FaceProfile', + 'MenuText': QtCore.QT_TRANSLATE_NOOP("Path_FaceProfile", "Face Profile"), + 'ToolTip': QtCore.QT_TRANSLATE_NOOP("Path_FaceProfile", "Creates a profile object around a selected face")} def IsActive(self): - return not FreeCAD.ActiveDocument is None - + return FreeCAD.ActiveDocument is not None + def Activated(self): - + # check that the selection contains exactly what we want selection = FreeCADGui.Selection.getSelectionEx() if len(selection) != 1: - FreeCAD.Console.PrintError(translate("Path_FaceProfile","Please select one face or wire\n")) + FreeCAD.Console.PrintError( + translate("Path_FaceProfile", "Please select one face or wire\n")) return if len(selection[0].SubObjects) != 1: - FreeCAD.Console.PrintError(translate("Path_FaceProfile","Please select only one face or wire\n")) + FreeCAD.Console.PrintError( + translate("Path_FaceProfile", "Please select only one face or wire\n")) return - if not selection[0].SubObjects[0].ShapeType in ["Face","Wire"]: - FreeCAD.Console.PrintError(translate("Path_FaceProfile","Please select only a face or a wire\n")) + if not selection[0].SubObjects[0].ShapeType in ["Face", "Wire"]: + FreeCAD.Console.PrintError( + translate("Path_FaceProfile", "Please select only a face or a wire\n")) return - - # if everything is ok, execute and register the transaction in the undo/redo stack + + # if everything is ok, execute and register the transaction in the + # undo/redo stack FreeCAD.ActiveDocument.openTransaction("Create Profile") FreeCADGui.addModule("PathScripts.PathFaceProfile") FreeCADGui.addModule("PathScripts.PathUtils") - FreeCADGui.doCommand('obj = FreeCAD.ActiveDocument.addObject("Path::FeaturePython","FaceProfile")') - FreeCADGui.doCommand('PathScripts.PathFaceProfile.ObjectFaceProfile(obj)') - FreeCADGui.doCommand('obj.Base = (FreeCAD.ActiveDocument.'+selection[0].ObjectName+',"'+selection[0].SubElementNames[0]+'")') + FreeCADGui.doCommand( + 'obj = FreeCAD.ActiveDocument.addObject("Path::FeaturePython","FaceProfile")') + FreeCADGui.doCommand( + 'PathScripts.PathFaceProfile.ObjectFaceProfile(obj)') + FreeCADGui.doCommand('obj.Base = (FreeCAD.ActiveDocument.' + selection[ + 0].ObjectName + ',"' + selection[0].SubElementNames[0] + '")') FreeCADGui.doCommand('obj.ViewObject.Proxy = 0') - FreeCADGui.doCommand('PathScripts.PathUtils.addToProject(obj)') + FreeCADGui.doCommand('PathScripts.PathUtils.addToJob(obj)') FreeCAD.ActiveDocument.commitTransaction() FreeCAD.ActiveDocument.recompute() -if FreeCAD.GuiUp: +if FreeCAD.GuiUp: # register the FreeCAD command - FreeCADGui.addCommand('Path_FaceProfile',CommandPathFaceProfile()) + FreeCADGui.addCommand('Path_FaceProfile', CommandPathFaceProfile()) diff --git a/src/Mod/Path/PathScripts/PathFixture.py b/src/Mod/Path/PathScripts/PathFixture.py index 50e191181245..92364d56ee04 100644 --- a/src/Mod/Path/PathScripts/PathFixture.py +++ b/src/Mod/Path/PathScripts/PathFixture.py @@ -1,41 +1,43 @@ # -*- coding: utf-8 -*- - -#*************************************************************************** -#* * -#* Copyright (c) 2015 Dan Falck * -#* * -#* This program is free software; you can redistribute it and/or modify * -#* it under the terms of the GNU Lesser General Public License (LGPL) * -#* as published by the Free Software Foundation; either version 2 of * -#* the License, or (at your option) any later version. * -#* for detail see the LICENCE text file. * -#* * -#* This program is distributed in the hope that it will be useful, * -#* but WITHOUT ANY WARRANTY; without even the implied warranty of * -#* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * -#* GNU Library General Public License for more details. * -#* * -#* You should have received a copy of the GNU Library General Public * -#* License along with this program; if not, write to the Free Software * -#* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * -#* USA * -#* * -#*************************************************************************** +# *************************************************************************** +# * * +# * Copyright (c) 2015 Dan Falck * +# * * +# * This program is free software; you can redistribute it and/or modify * +# * it under the terms of the GNU Lesser General Public License (LGPL) * +# * as published by the Free Software Foundation; either version 2 of * +# * the License, or (at your option) any later version. * +# * for detail see the LICENCE text file. * +# * * +# * This program is distributed in the hope that it will be useful, * +# * but WITHOUT ANY WARRANTY; without even the implied warranty of * +# * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * +# * GNU Library General Public License for more details. * +# * * +# * You should have received a copy of the GNU Library General Public * +# * License along with this program; if not, write to the Free Software * +# * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * +# * USA * +# * * +# *************************************************************************** ''' Used to create CNC machine fixture offsets such as G54,G55, etc...''' -import FreeCAD,FreeCADGui,Path,PathGui -from PathScripts import PathProject -from PySide import QtCore,QtGui +import FreeCAD +import FreeCADGui +import Path +from PySide import QtCore, QtGui # Qt tanslation handling try: _encoding = QtGui.QApplication.UnicodeUTF8 + def translate(context, text, disambig=None): return QtGui.QApplication.translate(context, text, disambig, _encoding) except AttributeError: def translate(context, text, disambig=None): return QtGui.QApplication.translate(context, text, disambig) + class Fixture: def __init__(self,obj): obj.addProperty("App::PropertyEnumeration", "Fixture", "Path",QtCore.QT_TRANSLATE_NOOP("App::Property","Fixture Offset Number")) @@ -44,11 +46,12 @@ def __init__(self,obj): obj.Proxy = self - def execute(self,obj): - fixlist = ['G53','G54','G55','G56','G57','G58','G59','G59.1', 'G59.2', 'G59.3', 'G59.4', 'G59.5','G59.6','G59.7', 'G59.8', 'G59.9'] - fixture=fixlist.index(obj.Fixture) + def execute(self, obj): + fixlist = ['G53', 'G54', 'G55', 'G56', 'G57', 'G58', 'G59', 'G59.1', + 'G59.2', 'G59.3', 'G59.4', 'G59.5', 'G59.6', 'G59.7', 'G59.8', 'G59.9'] + fixture = fixlist.index(obj.Fixture) obj.Path = Path.Path(str(obj.Fixture)) - obj.Label = "Fixture"+str(fixture) + obj.Label = "Fixture" + str(fixture) if obj.Active: obj.Path = Path.Path(str(obj.Fixture)) obj.ViewObject.Visibility = True @@ -59,72 +62,78 @@ def execute(self,obj): class _ViewProviderFixture: - def __init__(self,vobj): #mandatory -# obj.addProperty("App::PropertyFloat","SomePropertyName","PropertyGroup","Description of this property") + def __init__(self, vobj): # mandatory + # obj.addProperty("App::PropertyFloat","SomePropertyName","PropertyGroup","Description of this property") vobj.Proxy = self mode = 2 - vobj.setEditorMode('LineWidth',mode) - vobj.setEditorMode('MarkerColor',mode) - vobj.setEditorMode('NormalColor',mode) - vobj.setEditorMode('ShowFirstRapid',mode) - vobj.setEditorMode('DisplayMode',mode) - vobj.setEditorMode('BoundingBox',mode) - vobj.setEditorMode('Selectable',mode) - vobj.setEditorMode('ShapeColor',mode) - vobj.setEditorMode('Transparency',mode) - vobj.setEditorMode('Visibility',mode) - - def __getstate__(self): #mandatory + vobj.setEditorMode('LineWidth', mode) + vobj.setEditorMode('MarkerColor', mode) + vobj.setEditorMode('NormalColor', mode) + vobj.setEditorMode('ShowFirstRapid', mode) + vobj.setEditorMode('DisplayMode', mode) + vobj.setEditorMode('BoundingBox', mode) + vobj.setEditorMode('Selectable', mode) + vobj.setEditorMode('ShapeColor', mode) + vobj.setEditorMode('Transparency', mode) + vobj.setEditorMode('Visibility', mode) + + def __getstate__(self): # mandatory return None - def __setstate__(self,state): #mandatory + def __setstate__(self, state): # mandatory return None - def getIcon(self): #optional + def getIcon(self): # optional return ":/icons/Path-Datums.svg" # def attach(self): #optional # # this is executed on object creation and object load from file # pass - def onChanged(self,vobj,prop): #optional + def onChanged(self, vobj, prop): # optional mode = 2 - vobj.setEditorMode('LineWidth',mode) - vobj.setEditorMode('MarkerColor',mode) - vobj.setEditorMode('NormalColor',mode) - vobj.setEditorMode('ShowFirstRapid',mode) - vobj.setEditorMode('DisplayMode',mode) - vobj.setEditorMode('BoundingBox',mode) - vobj.setEditorMode('Selectable',mode) - vobj.setEditorMode('ShapeColor',mode) - vobj.setEditorMode('Transparency',mode) - vobj.setEditorMode('Visibility',mode) - - def updateData(self,vobj,prop): #optional + vobj.setEditorMode('LineWidth', mode) + vobj.setEditorMode('MarkerColor', mode) + vobj.setEditorMode('NormalColor', mode) + vobj.setEditorMode('ShowFirstRapid', mode) + vobj.setEditorMode('DisplayMode', mode) + vobj.setEditorMode('BoundingBox', mode) + vobj.setEditorMode('Selectable', mode) + vobj.setEditorMode('ShapeColor', mode) + vobj.setEditorMode('Transparency', mode) + vobj.setEditorMode('Visibility', mode) + + def updateData(self, vobj, prop): # optional # this is executed when a property of the APP OBJECT changes pass - def setEdit(self,vobj,mode): #optional + def setEdit(self, vobj, mode): # optional # this is executed when the object is double-clicked in the tree pass - def unsetEdit(self,vobj,mode): #optional + def unsetEdit(self, vobj, mode): # optional # this is executed when the user cancels or terminates edit mode pass class CommandPathFixture: + def GetResources(self): - return {'Pixmap' : 'Path-Datums', - 'MenuText': QtCore.QT_TRANSLATE_NOOP("Path_Fixture","Fixture"), + return {'Pixmap': 'Path-Datums', + 'MenuText': QtCore.QT_TRANSLATE_NOOP("Path_Fixture", "Fixture"), 'Accel': "P, F", - 'ToolTip': QtCore.QT_TRANSLATE_NOOP("Path_Fixture","Creates a Fixture Offset object")} + 'ToolTip': QtCore.QT_TRANSLATE_NOOP("Path_Fixture", "Creates a Fixture Offset object")} def IsActive(self): - return not FreeCAD.ActiveDocument is None + if FreeCAD.ActiveDocument is not None: + for o in FreeCAD.ActiveDocument.Objects: + if o.Name[:3] == "Job": + return True + return False def Activated(self): - FreeCAD.ActiveDocument.openTransaction(translate("Path_Fixture","Create a Fixture Offset")) + FreeCAD.ActiveDocument.openTransaction( + translate("Path_Fixture", "Create a Fixture Offset")) FreeCADGui.addModule("PathScripts.PathFixture") snippet = ''' import Path @@ -136,16 +145,16 @@ def Activated(self): obj.Active = True PathScripts.PathFixture._ViewProviderFixture(obj.ViewObject) -PathUtils.addToProject(obj) +PathUtils.addToJob(obj) ''' FreeCADGui.doCommand(snippet) FreeCAD.ActiveDocument.commitTransaction() FreeCAD.ActiveDocument.recompute() -if FreeCAD.GuiUp: +if FreeCAD.GuiUp: # register the FreeCAD command - FreeCADGui.addCommand('Path_Fixture',CommandPathFixture()) + FreeCADGui.addCommand('Path_Fixture', CommandPathFixture()) FreeCAD.Console.PrintLog("Loading PathFixture... done\n") diff --git a/src/Mod/Path/PathScripts/PathFromShape.py b/src/Mod/Path/PathScripts/PathFromShape.py index 98812e3dec05..46edda23be9d 100644 --- a/src/Mod/Path/PathScripts/PathFromShape.py +++ b/src/Mod/Path/PathScripts/PathFromShape.py @@ -1,42 +1,44 @@ # -*- coding: utf-8 -*- - -#*************************************************************************** -#* * -#* Copyright (c) 2015 Dan Falck * -#* * -#* This program is free software; you can redistribute it and/or modify * -#* it under the terms of the GNU Lesser General Public License (LGPL) * -#* as published by the Free Software Foundation; either version 2 of * -#* the License, or (at your option) any later version. * -#* for detail see the LICENCE text file. * -#* * -#* This program is distributed in the hope that it will be useful, * -#* but WITHOUT ANY WARRANTY; without even the implied warranty of * -#* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * -#* GNU Library General Public License for more details. * -#* * -#* You should have received a copy of the GNU Library General Public * -#* License along with this program; if not, write to the Free Software * -#* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * -#* USA * -#* * -#*************************************************************************** +# *************************************************************************** +# * * +# * Copyright (c) 2015 Dan Falck * +# * * +# * This program is free software; you can redistribute it and/or modify * +# * it under the terms of the GNU Lesser General Public License (LGPL) * +# * as published by the Free Software Foundation; either version 2 of * +# * the License, or (at your option) any later version. * +# * for detail see the LICENCE text file. * +# * * +# * This program is distributed in the hope that it will be useful, * +# * but WITHOUT ANY WARRANTY; without even the implied warranty of * +# * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * +# * GNU Library General Public License for more details. * +# * * +# * You should have received a copy of the GNU Library General Public * +# * License along with this program; if not, write to the Free Software * +# * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * +# * USA * +# * * +# *************************************************************************** ''' Used to make GCode from FreeCAD shapes - Wires and Edges/Curves ''' -import FreeCAD,FreeCADGui,Path,PathGui -from PathScripts import PathProject -from PySide import QtCore,QtGui +import FreeCAD +import FreeCADGui +from PySide import QtCore, QtGui # Qt tanslation handling try: _encoding = QtGui.QApplication.UnicodeUTF8 + def translate(context, text, disambig=None): return QtGui.QApplication.translate(context, text, disambig, _encoding) except AttributeError: def translate(context, text, disambig=None): return QtGui.QApplication.translate(context, text, disambig) -#TODO make the shape parametric +# TODO make the shape parametric + + class FromShape: @@ -47,61 +49,66 @@ def __init__(self,obj): def __getstate__(self): return None - def __setstate__(self,state): + def __setstate__(self, state): return None - def execute(self,obj): + def execute(self, obj): pass class _ViewProviderFromShape: - - def __init__(self,vobj): #mandatory + def __init__(self, vobj): # mandatory vobj.Proxy = self def attach(self, vobj): self.Object = vobj.Object - def __getstate__(self): #mandatory + def __getstate__(self): # mandatory return None - def __setstate__(self,state): #mandatory + def __setstate__(self, state): # mandatory return None - def getIcon(self): #optional + def getIcon(self): # optional return ":/icons/Path-Shape.svg" class CommandFromShape: + def GetResources(self): - return {'Pixmap' : 'Path-Shape', - 'MenuText': QtCore.QT_TRANSLATE_NOOP("Path_FromShape","Path from a Shape"), + return {'Pixmap': 'Path-Shape', + 'MenuText': QtCore.QT_TRANSLATE_NOOP("Path_FromShape", "Path from a Shape"), 'Accel': "P, S", - 'ToolTip': QtCore.QT_TRANSLATE_NOOP("Path_FromShape","Creates a Path from a wire/curve")} + 'ToolTip': QtCore.QT_TRANSLATE_NOOP("Path_FromShape", "Creates a Path from a wire/curve")} def IsActive(self): - return not FreeCAD.ActiveDocument is None - + return FreeCAD.ActiveDocument is not None + def Activated(self): - + # check that the selection contains exactly what we want selection = FreeCADGui.Selection.getSelection() if len(selection) != 1: - FreeCAD.Console.PrintError(translate("Path_FromShape","Please select exactly one Part-based object\n")) + FreeCAD.Console.PrintError( + translate("Path_FromShape", "Please select exactly one Part-based object\n")) return if not(selection[0].isDerivedFrom("Part::Feature")): - FreeCAD.Console.PrintError(translate("Path_FromShape","Please select exactly one Part-based object\n")) + FreeCAD.Console.PrintError( + translate("Path_FromShape", "Please select exactly one Part-based object\n")) return - - FreeCAD.ActiveDocument.openTransaction(translate("Path_FromShape","Create path from shape")) + + FreeCAD.ActiveDocument.openTransaction( + translate("Path_FromShape", "Create path from shape")) FreeCADGui.addModule("PathScripts.PathUtils") - FreeCADGui.doCommand("obj = FreeCAD.activeDocument().addObject('Path::FeatureShape','PathShape')") - FreeCADGui.doCommand("obj.Shape = FreeCAD.activeDocument()."+selection[0].Name+".Shape") - FreeCADGui.doCommand('PathScripts.PathUtils.addToProject(obj)') + FreeCADGui.doCommand( + "obj = FreeCAD.activeDocument().addObject('Path::FeatureShape','PathShape')") + FreeCADGui.doCommand( + "obj.Shape = FreeCAD.activeDocument()." + selection[0].Name + ".Shape") + FreeCADGui.doCommand('PathScripts.PathUtils.addToJob(obj)') FreeCAD.ActiveDocument.commitTransaction() FreeCAD.ActiveDocument.recompute() -if FreeCAD.GuiUp: +if FreeCAD.GuiUp: # register the FreeCAD command - FreeCADGui.addCommand('Path_FromShape',CommandFromShape()) + FreeCADGui.addCommand('Path_FromShape', CommandFromShape()) diff --git a/src/Mod/Path/PathScripts/PathHop.py b/src/Mod/Path/PathScripts/PathHop.py index 94311065ad29..7509d0061809 100644 --- a/src/Mod/Path/PathScripts/PathHop.py +++ b/src/Mod/Path/PathScripts/PathHop.py @@ -105,7 +105,11 @@ def GetResources(self): 'ToolTip': QtCore.QT_TRANSLATE_NOOP("Path_Hop", "Creates a Path Hop object")} def IsActive(self): - return FreeCAD.ActiveDocument is not None + if FreeCAD.ActiveDocument is not None: + for o in FreeCAD.ActiveDocument.Objects: + if o.Name[:3] == "Job": + return True + return False def Activated(self): @@ -131,7 +135,7 @@ def Activated(self): 'PathScripts.PathHop.ViewProviderPathHop(obj.ViewObject)') FreeCADGui.doCommand( 'obj.NextObject = FreeCAD.ActiveDocument.' + selection[0].Name) - FreeCADGui.doCommand('PathScripts.PathUtils.addToProject(obj)') + FreeCADGui.doCommand('PathScripts.PathUtils.addToJob(obj)') FreeCAD.ActiveDocument.commitTransaction() FreeCAD.ActiveDocument.recompute() diff --git a/src/Mod/Path/PathScripts/PathInspect.py b/src/Mod/Path/PathScripts/PathInspect.py index 4b17c94b70fa..4312a12088c4 100644 --- a/src/Mod/Path/PathScripts/PathInspect.py +++ b/src/Mod/Path/PathScripts/PathInspect.py @@ -1,34 +1,35 @@ -#*************************************************************************** -#* (c) Yorik van Havre (yorik@uncreated.net) 2015 * -#* * -#* This file is part of the FreeCAD CAx development system. * -#* * -#* This program is free software; you can redistribute it and/or modify * -#* it under the terms of the GNU Lesser General Public License (LGPL) * -#* as published by the Free Software Foundation; either version 2 of * -#* the License, or (at your option) any later version. * -#* for detail see the LICENCE text file. * -#* * -#* FreeCAD is distributed in the hope that it will be useful, * -#* but WITHOUT ANY WARRANTY; without even the implied warranty of * -#* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * -#* GNU Lesser General Public License for more details. * -#* * -#* You should have received a copy of the GNU Library General Public * -#* License along with FreeCAD; if not, write to the Free Software * -#* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * -#* USA * -#* * -#***************************************************************************/ +# *************************************************************************** +# * (c) Yorik van Havre (yorik@uncreated.net) 2015 * +# * * +# * This file is part of the FreeCAD CAx development system. * +# * * +# * This program is free software; you can redistribute it and/or modify * +# * it under the terms of the GNU Lesser General Public License (LGPL) * +# * as published by the Free Software Foundation; either version 2 of * +# * the License, or (at your option) any later version. * +# * for detail see the LICENCE text file. * +# * * +# * FreeCAD is distributed in the hope that it will be useful, * +# * but WITHOUT ANY WARRANTY; without even the implied warranty of * +# * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * +# * GNU Lesser General Public License for more details. * +# * * +# * You should have received a copy of the GNU Library General Public * +# * License along with FreeCAD; if not, write to the Free Software * +# * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * +# * USA * +# * * +# ***************************************************************************/ from PySide import QtCore, QtGui -import FreeCAD,FreeCADGui - +import FreeCAD +import FreeCADGui # Qt tanslation handling try: _encoding = QtGui.QApplication.UnicodeUTF8 + def translate(context, text, disambig=None): return QtGui.QApplication.translate(context, text, disambig, _encoding) except AttributeError: @@ -38,7 +39,6 @@ def translate(context, text, disambig=None): class OldHighlighter(QtGui.QSyntaxHighlighter): - def highlightBlock(self, text): myClassFormat = QtGui.QTextCharFormat() @@ -56,11 +56,10 @@ def highlightBlock(self, text): class GCodeHighlighter(QtGui.QSyntaxHighlighter): - def __init__(self, parent=None): - + def convertcolor(c): - return QtGui.QColor(int((c>>24)&0xFF),int((c>>16)&0xFF),int((c>>8)&0xFF)) + return QtGui.QColor(int((c >> 24) & 0xFF), int((c >> 16) & 0xFF), int((c >> 8) & 0xFF)) super(GCodeHighlighter, self).__init__(parent) p = FreeCAD.ParamGet("User parameter:BaseApp/Preferences/Editor") @@ -74,26 +73,29 @@ def convertcolor(c): if c: colors.append(convertcolor(c)) else: - colors.append(QtGui.QColor(0,170,0)) + colors.append(QtGui.QColor(0, 170, 0)) c = p.GetUnsigned("Define name") if c: colors.append(convertcolor(c)) else: - colors.append(QtGui.QColor(160,160,164)) - + colors.append(QtGui.QColor(160, 160, 164)) + self.highlightingRules = [] numberFormat = QtGui.QTextCharFormat() numberFormat.setForeground(colors[0]) - self.highlightingRules.append((QtCore.QRegExp("[\\-0-9\\.]"),numberFormat)) + self.highlightingRules.append( + (QtCore.QRegExp("[\\-0-9\\.]"), numberFormat)) keywordFormat = QtGui.QTextCharFormat() keywordFormat.setForeground(colors[1]) keywordFormat.setFontWeight(QtGui.QFont.Bold) keywordPatterns = ["\\bG[0-9]+\\b", "\\bM[0-9]+\\b"] - self.highlightingRules.extend([(QtCore.QRegExp(pattern), keywordFormat) for pattern in keywordPatterns]) + self.highlightingRules.extend( + [(QtCore.QRegExp(pattern), keywordFormat) for pattern in keywordPatterns]) speedFormat = QtGui.QTextCharFormat() speedFormat.setFontWeight(QtGui.QFont.Bold) speedFormat.setForeground(colors[2]) - self.highlightingRules.append((QtCore.QRegExp("\\bF[0-9\\.]+\\b"),speedFormat)) + self.highlightingRules.append( + (QtCore.QRegExp("\\bF[0-9\\.]+\\b"), speedFormat)) def highlightBlock(self, text): @@ -108,30 +110,29 @@ def highlightBlock(self, text): class GCodeEditorDialog(QtGui.QDialog): + def __init__(self, parent=FreeCADGui.getMainWindow()): - def __init__(self, parent = FreeCADGui.getMainWindow()): - - QtGui.QDialog.__init__(self,parent) + QtGui.QDialog.__init__(self, parent) layout = QtGui.QVBoxLayout(self) # nice text editor widget for editing the gcode self.editor = QtGui.QTextEdit() font = QtGui.QFont() p = FreeCAD.ParamGet("User parameter:BaseApp/Preferences/Editor") - font.setFamily(p.GetString("Font","Courier")) + font.setFamily(p.GetString("Font", "Courier")) font.setFixedPitch(True) - font.setPointSize(p.GetInt("FontSize",10)) + font.setPointSize(p.GetInt("FontSize", 10)) self.editor.setFont(font) self.editor.setText("G01 X55 Y4.5 F300.0") self.highlighter = GCodeHighlighter(self.editor.document()) layout.addWidget(self.editor) - + # Note lab = QtGui.QLabel() - lab.setText(translate("PathInspect","Note: Pressing OK will commit any change you make above to the object, but if the object is parametric, these changes will be overridden on recompute.")) + lab.setText(translate("PathInspect", "Note: Pressing OK will commit any change you make above to the object, but if the object is parametric, these changes will be overridden on recompute.")) lab.setWordWrap(True) layout.addWidget(lab) - + # OK and Cancel buttons self.buttons = QtGui.QDialogButtonBox( QtGui.QDialogButtonBox.Ok | QtGui.QDialogButtonBox.Cancel, @@ -142,15 +143,15 @@ def __init__(self, parent = FreeCADGui.getMainWindow()): def show(obj): - "show(obj): shows the G-code data of the given Path object in a dialog" - if hasattr(obj,"Path"): - if obj.Path: + if hasattr(obj, "Path"): + if obj.Path: dia = GCodeEditorDialog() dia.editor.setText(obj.Path.toGCode()) result = dia.exec_() - # exec_() returns 0 or 1 depending on the button pressed (Ok or Cancel) + # exec_() returns 0 or 1 depending on the button pressed (Ok or + # Cancel) if result: import Path p = Path.Path(dia.editor.toPlainText()) @@ -162,31 +163,36 @@ def show(obj): class CommandPathInspect: - def GetResources(self): - return {'Pixmap' : 'Path-Inspect', - 'MenuText': QtCore.QT_TRANSLATE_NOOP("Path_Inspect","Inspect G-code"), - 'ToolTip': QtCore.QT_TRANSLATE_NOOP("Path_Inspect","Inspects the G-code contents of a path")} + return {'Pixmap': 'Path-Inspect', + 'MenuText': QtCore.QT_TRANSLATE_NOOP("Path_Inspect", "Inspect G-code"), + 'ToolTip': QtCore.QT_TRANSLATE_NOOP("Path_Inspect", "Inspects the G-code contents of a path")} def IsActive(self): - return not FreeCAD.ActiveDocument is None - + 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: - FreeCAD.Console.PrintError(translate("Path_Inspect","Please select exactly one path object\n")) + FreeCAD.Console.PrintError( + translate("Path_Inspect", "Please select exactly one path object\n")) return if not(selection[0].isDerivedFrom("Path::Feature")): - FreeCAD.Console.PrintError(translate("Path_Inspect","Please select exactly one path object\n")) + FreeCAD.Console.PrintError( + translate("Path_Inspect", "Please select exactly one path object\n")) return - + # if everything is ok, execute FreeCADGui.addModule("PathScripts.PathInspect") - FreeCADGui.doCommand('PathScripts.PathInspect.show(FreeCAD.ActiveDocument.' + selection[0].Name + ')') + FreeCADGui.doCommand( + 'PathScripts.PathInspect.show(FreeCAD.ActiveDocument.' + selection[0].Name + ')') -if FreeCAD.GuiUp: +if FreeCAD.GuiUp: # register the FreeCAD command - FreeCADGui.addCommand('Path_Inspect',CommandPathInspect()) - + FreeCADGui.addCommand('Path_Inspect', CommandPathInspect()) diff --git a/src/Mod/Path/PathScripts/PathJob.py b/src/Mod/Path/PathScripts/PathJob.py new file mode 100644 index 000000000000..a352d5a93783 --- /dev/null +++ b/src/Mod/Path/PathScripts/PathJob.py @@ -0,0 +1,314 @@ +# -*- coding: utf-8 -*- + +# *************************************************************************** +# * * +# * Copyright (c) 2014 Yorik van Havre * +# * * +# * This program is free software; you can redistribute it and/or modify * +# * it under the terms of the GNU Lesser General Public License (LGPL) * +# * as published by the Free Software Foundation; either version 2 of * +# * the License, or (at your option) any later version. * +# * for detail see the LICENCE text file. * +# * * +# * This program is distributed in the hope that it will be useful, * +# * but WITHOUT ANY WARRANTY; without even the implied warranty of * +# * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * +# * GNU Library General Public License for more details. * +# * * +# * You should have received a copy of the GNU Library General Public * +# * License along with this program; if not, write to the Free Software * +# * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * +# * USA * +# * * +# *************************************************************************** + +import FreeCAD +import Path +from PySide import QtCore, QtGui +import os +import sys +import glob +import PathLoadTool + + +FreeCADGui = None +if FreeCAD.GuiUp: + import FreeCADGui + +"""Path Job object and FreeCAD command""" + +# Qt tanslation handling +try: + _encoding = QtGui.QApplication.UnicodeUTF8 + + def translate(context, text, disambig=None): + return QtGui.QApplication.translate(context, text, disambig, _encoding) +except AttributeError: + def translate(context, text, disambig=None): + return QtGui.QApplication.translate(context, text, disambig) + + +class ObjectPathJob: + + def __init__(self, obj): + path = FreeCAD.getHomePath() + ("Mod/Path/PathScripts/") + posts = glob.glob(path + '/*_post.py') + allposts = [ str(os.path.split(os.path.splitext(p)[0])[1][:-5]) for p in posts] + + grp = FreeCAD.ParamGet("User parameter:BaseApp/Preferences/Macro") + path = grp.GetString("MacroPath", FreeCAD.getUserAppDataDir()) + posts = glob.glob(path + '/*_post.py') + + allposts.extend([ str(os.path.split(os.path.splitext(p)[0])[1][:-5]) for p in posts]) + + # obj.addProperty("App::PropertyFile", "PostProcessor", "CodeOutput", "Select the Post Processor file for this project") + obj.addProperty("App::PropertyFile", "OutputFile", "CodeOutput", QtCore.QT_TRANSLATE_NOOP("App::Property","The NC output file for this project")) + obj.setEditorMode("OutputFile", 0) # set to default mode + + obj.addProperty("App::PropertyString", "Description", "Path", QtCore.QT_TRANSLATE_NOOP("App::Property","An optional description for this job")) + obj.addProperty("App::PropertyEnumeration", "PostProcessor", "Output", QtCore.QT_TRANSLATE_NOOP("App::Property","Select the Post Processor")) + obj.PostProcessor = allposts + obj.addProperty("App::PropertyString", "MachineName", "Output", QtCore.QT_TRANSLATE_NOOP("App::Property","Name of the Machine that will use the CNC program")) + + obj.addProperty("Path::PropertyTooltable", "Tooltable", "Base", QtCore.QT_TRANSLATE_NOOP("App::Property","The tooltable used for this CNC program")) + + obj.addProperty("App::PropertyEnumeration", "MachineUnits", "Output", QtCore.QT_TRANSLATE_NOOP("App::Property","Units that the machine works in, ie Metric or Inch")) + obj.MachineUnits = ['Metric', 'Inch'] + + obj.addProperty("App::PropertyDistance", "X_Max", "Limits", QtCore.QT_TRANSLATE_NOOP("App::Property","The Maximum distance in X the machine can travel")) + obj.addProperty("App::PropertyDistance", "Y_Max", "Limits", QtCore.QT_TRANSLATE_NOOP("App::Property","The Maximum distance in X the machine can travel")) + obj.addProperty("App::PropertyDistance", "Z_Max", "Limits", QtCore.QT_TRANSLATE_NOOP("App::Property","The Maximum distance in X the machine can travel")) + + obj.addProperty("App::PropertyDistance", "X_Min", "Limits", QtCore.QT_TRANSLATE_NOOP("App::Property","The Minimum distance in X the machine can travel")) + obj.addProperty("App::PropertyDistance", "Y_Min", "Limits", QtCore.QT_TRANSLATE_NOOP("App::Property","The Minimum distance in X the machine can travel")) + obj.addProperty("App::PropertyDistance", "Z_Min", "Limits", QtCore.QT_TRANSLATE_NOOP("App::Property","The Minimum distance in X the machine can travel")) + + obj.Proxy = self + + if FreeCAD.GuiUp: + ViewProviderJob(obj.ViewObject) + + + def __getstate__(self): + return None + + def __setstate__(self, state): + return None + + def onChanged(self, obj, prop): + mode = 2 + obj.setEditorMode('Placement', mode) + + if prop == "PostProcessor": + postname = obj.PostProcessor + "_post" + + exec "import %s as current_post" % postname + if hasattr(current_post, "UNITS"): + if current_post.UNITS == "G21": + obj.MachineUnits = "Metric" + else: + obj.MachineUnits = "Inch" + if hasattr(current_post, "MACHINE_NAME"): + obj.MachineName = current_post.MACHINE_NAME + + if hasattr(current_post, "CORNER_MAX"): + obj.X_Max = current_post.CORNER_MAX['x'] + obj.Y_Max = current_post.CORNER_MAX['y'] + obj.Z_Max = current_post.CORNER_MAX['z'] + + if hasattr(current_post, "CORNER_MIN"): + obj.X_Min = current_post.CORNER_MIN['x'] + obj.Y_Min = current_post.CORNER_MIN['y'] + obj.Z_Min = current_post.CORNER_MIN['z'] + + def getToolControllers(self, obj): + '''returns a list of ToolControllers for the current job''' + controllers = [] + for o in obj.Group: + if "Proxy" in o.PropertiesList: + if isinstance(o.Proxy, PathLoadTool.LoadTool): + controllers.append (o.Name) + return controllers + + + def execute(self, obj): + cmds = [] + for child in obj.Group: + if child.isDerivedFrom("Path::Feature"): + if obj.UsePlacements: + for c in child.Path.Commands: + cmds.append(c.transform(child.Placement)) + else: + cmds.extend(child.Path.Commands) + if cmds: + path = Path.Path(cmds) + obj.Path = path + + +class ViewProviderJob: + + def __init__(self, vobj): + vobj.Proxy = self + mode = 2 + vobj.setEditorMode('BoundingBox', mode) + vobj.setEditorMode('DisplayMode', mode) + vobj.setEditorMode('Selectable', mode) + vobj.setEditorMode('ShapeColor', mode) + vobj.setEditorMode('Transparency', mode) + + def __getstate__(self): # mandatory + return None + + def __setstate__(self, state): # mandatory + return None + + def setEdit(self, vobj, mode=0): + FreeCADGui.Control.closeDialog() + taskd = TaskPanel() + taskd.obj = vobj.Object + FreeCADGui.Control.showDialog(taskd) + taskd.setupUi() + return True + + def getIcon(self): + return ":/icons/Path-Job.svg" + + def onChanged(self, vobj, prop): + mode = 2 + vobj.setEditorMode('BoundingBox', mode) + vobj.setEditorMode('DisplayMode', mode) + vobj.setEditorMode('Selectable', mode) + vobj.setEditorMode('ShapeColor', mode) + vobj.setEditorMode('Transparency', mode) + + +class CommandJob: + + def GetResources(self): + return {'Pixmap': 'Path-Job', + 'MenuText': QtCore.QT_TRANSLATE_NOOP("Path_Job", "Job"), + 'Accel': "P, P", + 'ToolTip': QtCore.QT_TRANSLATE_NOOP("Path_Job", "Creates a Path Job object")} + + def IsActive(self): + return FreeCAD.ActiveDocument is not None + + def Activated(self): + CommandJob.Create() + FreeCAD.ActiveDocument.recompute() + + @staticmethod + def Create(): + FreeCAD.ActiveDocument.openTransaction(translate("Path_Job", "Create Job")) + FreeCADGui.addModule('PathScripts.PathUtils') + FreeCADGui.addModule('PathScripts.PathLoadTool') + FreeCADGui.doCommand('obj = FreeCAD.ActiveDocument.addObject("Path::FeatureCompoundPython", "Job")') + FreeCADGui.doCommand('PathScripts.PathJob.ObjectPathJob(obj)') + FreeCADGui.doCommand('PathScripts.PathLoadTool.CommandPathLoadTool.Create(obj.Name)') + FreeCADGui.doCommand('obj.ViewObject.startEditing()') + # FreeCADGui.doCommand('tool = Path.Tool()') + # FreeCADGui.doCommand('tool') + # FreeCADGui.doCommand('tool.Diameter = 5.0') + # FreeCADGui.doCommand('tool.Name = "Default Tool"') + # FreeCADGui.doCommand('tool.cuttingEdgeHeight = 15.0') + # FreeCADGui.doCommand('tool.ToolType = "EndMill"') + # FreeCADGui.doCommand('tool.Material = "HighSpeedSteel"') + # FreeCADGui.doCommand('obj.ToolTable.addTools(tool)') + + FreeCAD.ActiveDocument.commitTransaction() + + +class TaskPanel: + def __init__(self): + #self.form = FreeCADGui.PySideUic.loadUi(":/panels/JobEdit.ui") + self.form = FreeCADGui.PySideUic.loadUi(FreeCAD.getHomePath() + "Mod/Path/JobEdit.ui") + path = FreeCAD.getHomePath() + ("Mod/Path/PathScripts/") + posts = glob.glob(path + '/*_post.py') + allposts = [ str(os.path.split(os.path.splitext(p)[0])[1][:-5]) for p in posts] + + grp = FreeCAD.ParamGet("User parameter:BaseApp/Preferences/Macro") + path = grp.GetString("MacroPath", FreeCAD.getUserAppDataDir()) + posts = glob.glob(path + '/*_post.py') + + allposts.extend([ str(os.path.split(os.path.splitext(p)[0])[1][:-5]) for p in posts]) + + for post in allposts: + self.form.cboPostProcessor.addItem(post) + self.updating = False + + + def accept(self): + self.getFields() + FreeCADGui.ActiveDocument.resetEdit() + FreeCADGui.Control.closeDialog() + FreeCAD.ActiveDocument.recompute() + + def reject(self): + FreeCADGui.Control.closeDialog() + FreeCAD.ActiveDocument.recompute() + + def getFields(self): + if self.obj: + if hasattr(self.obj, "PostProcessor"): + self.obj.PostProcessor = str(self.form.cboPostProcessor.currentText()) + if hasattr(self.obj, "Label"): + self.obj.Label = str(self.form.leLabel.text()) + if hasattr(self.obj, "OutputFile"): + self.obj.OutputFile = str(self.form.leOutputFile.text()) + + oldlist = self.obj.Group + newlist = [] + + for index in xrange(self.form.PathsList.count()): + item = self.form.PathsList.item(index) + for olditem in oldlist: + if olditem.Name == item.text(): + newlist.append(olditem) + self.obj.Group = newlist + + + self.obj.Proxy.execute(self.obj) + + def setFields(self): + + self.form.leLabel.setText(self.obj.Label) + self.form.leOutputFile.setText(self.obj.OutputFile) + + index = self.form.cboPostProcessor.findText( + self.obj.PostProcessor, QtCore.Qt.MatchFixedString) + if index >= 0: + self.form.cboPostProcessor.setCurrentIndex(index) + + for child in self.obj.Group: + self.form.PathsList.addItem(child.Name) + + + + def open(self): + pass + + def setFile(self): + filename = QtGui.QFileDialog.getSaveFileName(self.form, translate("PathJob", "Select Output File", None), None, translate("Path Job", "All Files (*.*)", None)) + if filename: + self.obj.OutputFile = str(filename[0]) + self.setFields() + + def getStandardButtons(self): + return int(QtGui.QDialogButtonBox.Ok) + + def setupUi(self): + # Connect Signals and Slots + self.form.cboPostProcessor.currentIndexChanged.connect(self.getFields) + self.form.leOutputFile.editingFinished.connect(self.getFields) + self.form.leLabel.editingFinished.connect(self.getFields) + self.form.btnSelectFile.clicked.connect(self.setFile) + self.form.PathsList.indexesMoved.connect(self.getFields) + + self.setFields() + + +if FreeCAD.GuiUp: + # register the FreeCAD command + FreeCADGui.addCommand('Path_Job', CommandJob()) + +FreeCAD.Console.PrintLog("Loading PathJob... done\n") diff --git a/src/Mod/Path/PathScripts/PathLoadTool.py b/src/Mod/Path/PathScripts/PathLoadTool.py index 71562f41cdf9..c6eb5591ab1c 100644 --- a/src/Mod/Path/PathScripts/PathLoadTool.py +++ b/src/Mod/Path/PathScripts/PathLoadTool.py @@ -25,12 +25,9 @@ import FreeCAD import FreeCADGui -import Path -# import PathGui -import PathScripts import PathUtils import Part -# from PathScripts import PathProject +import PathScripts from PySide import QtCore, QtGui # Qt tanslation handling @@ -76,16 +73,15 @@ def execute(self, obj): else: commands += 'M4S' + str(obj.SpindleSpeed) + '\n' - obj.Path = Path.Path(commands) - def onChanged(self, obj, prop): mode = 2 obj.setEditorMode('Placement', mode) # if prop == "ToolNumber": - proj = PathUtils.findProj() - for g in proj.Group: - if not(isinstance(g.Proxy, PathScripts.PathLoadTool.LoadTool)): - g.touch() + job = PathUtils.findParentJob(obj) + if job is not None: + for g in job.Group: + if not(isinstance(g.Proxy, PathScripts.PathLoadTool.LoadTool)): + g.touch() class _ViewProviderLoadTool: @@ -147,12 +143,16 @@ def unsetEdit(self, vobj, mode): class CommandPathLoadTool: def GetResources(self): return {'Pixmap': 'Path-LoadTool', - 'MenuText': QtCore.QT_TRANSLATE_NOOP("Path_LoadTool", "Add Tool Controller to the Project"), + 'MenuText': QtCore.QT_TRANSLATE_NOOP("Path_LoadTool", "Add Tool Controller to the Job"), 'Accel': "P, T", 'ToolTip': QtCore.QT_TRANSLATE_NOOP("Path_LoadTool", "Add Tool Controller")} def IsActive(self): - return FreeCAD.ActiveDocument is not None + if FreeCAD.ActiveDocument is not None: + for o in FreeCAD.ActiveDocument.Objects: + if o.Name[:3] == "Job": + return True + return False def Activated(self): FreeCAD.ActiveDocument.openTransaction(translate("Path_LoadTool", "Create Tool Controller Object")) @@ -164,16 +164,14 @@ def Activated(self): PathScripts.PathLoadTool.LoadTool(obj) PathScripts.PathLoadTool._ViewProviderLoadTool(obj.ViewObject) -PathUtils.addToProject(obj) +PathUtils.addToJob(obj) ''' FreeCADGui.doCommand(snippet) FreeCAD.ActiveDocument.commitTransaction() FreeCAD.ActiveDocument.recompute() @staticmethod - def Create(): - # FreeCADGui.addModule("PathScripts.PathLoadTool") - # import Path + def Create(jobname = None): import PathScripts import PathUtils @@ -181,7 +179,7 @@ def Create(): PathScripts.PathLoadTool.LoadTool(obj) PathScripts.PathLoadTool._ViewProviderLoadTool(obj.ViewObject) - PathUtils.addToProject(obj) + PathUtils.addToJob(obj, jobname) class TaskPanel: @@ -205,6 +203,8 @@ def accept(self): def reject(self): FreeCADGui.Control.closeDialog() + if self.toolrep is not None: + FreeCAD.ActiveDocument.removeObject(self.toolrep.Name) FreeCAD.ActiveDocument.recompute() FreeCADGui.Selection.removeObserver(self.s) @@ -221,11 +221,12 @@ def getFields(self): self.obj.SpindleSpeed = self.form.spindleSpeed.value() if hasattr(self.obj, "SpindleDir"): self.obj.SpindleDir = str(self.form.cboSpindleDirection.currentText()) - #if hasattr(self.obj, "ToolNumber"): - # self.obj.ToolNumber = self.form.ToolNumber.value() + self.obj.Proxy.execute(self.obj) def setFields(self): + self.form.cboToolSelect.blockSignals(True) + self.form.vertFeed.setText(str(self.obj.VertFeed.Value)) self.form.horizFeed.setText(str(self.obj.HorizFeed.Value)) self.form.spindleSpeed.setValue(self.obj.SpindleSpeed) @@ -234,20 +235,45 @@ def setFields(self): index = self.form.cboSpindleDirection.findText(self.obj.SpindleDir, QtCore.Qt.MatchFixedString) if index >= 0: self.form.cboSpindleDirection.setCurrentIndex(index) - # Populate the tool list - mach = PathUtils.findMachine() + myJob = PathUtils.findParentJob(self.obj) + + #populate the toolselector and select correct tool + self.form.cboToolSelect.clear() + tooltable = myJob.Tooltable + for number, tool in tooltable.Tools.iteritems(): + self.form.cboToolSelect.addItem(tool.Name) + try: - tool = mach.Tooltable.Tools[self.obj.ToolNumber] - self.form.txtToolName.setText(tool.Name) + tool = myJob.Tooltable.Tools[self.obj.ToolNumber] self.form.txtToolType.setText(tool.ToolType) self.form.txtToolMaterial.setText(tool.Material) self.form.txtToolDiameter.setText(str(tool.Diameter)) + + index = self.form.cboToolSelect.findText(tool.Name, QtCore.Qt.MatchFixedString) + if index >= 0: + self.form.cboToolSelect.setCurrentIndex(index) + except: - self.form.txtToolName.setText("UNDEFINED") + self.form.cboToolSelect.setCurrentIndex(-1) self.form.txtToolType.setText("UNDEFINED") self.form.txtToolMaterial.setText("UNDEFINED") self.form.txtToolDiameter.setText("UNDEFINED") + self.form.cboToolSelect.blockSignals(False) + + radius = tool.Diameter / 2 + length = tool.CuttingEdgeHeight + t = Part.makeCylinder(radius, length) + self.toolrep.Shape = t + def changeTool(self): + myJob = PathUtils.findParentJob(self.obj) + newtool = self.form.cboToolSelect.currentText() + + tooltable = myJob.Tooltable + for number, tool in tooltable.Tools.iteritems(): + if tool.Name == newtool: + self.obj.ToolNumber = number + self.setFields() def open(self): self.s = SelObserver() @@ -267,17 +293,19 @@ def resetObject(self, remove=None): FreeCAD.ActiveDocument.recompute() def setupUi(self): - # setup the form fields - self.setFields() + + self.form.cboToolSelect.currentIndexChanged.connect(self.changeTool) + self.form.tcoName.editingFinished.connect(self.getFields) # build the tool representation - if self.form.txtToolDiameter.text() != "UNDEFINED": - radius = float(self.form.txtToolDiameter.text()) / 2 - length = radius * 8 - t = Part.makeCylinder(radius, length) + if self.obj.ToolNumber != 0: + t = Part.makeCylinder(1, 1) self.toolrep = FreeCAD.ActiveDocument.addObject("Part::Feature", "tool") self.toolrep.Shape = t + # setup the form fields + self.setFields() + class SelObserver: def __init__(self): pass diff --git a/src/Mod/Path/PathScripts/PathMachine.py b/src/Mod/Path/PathScripts/PathMachine.py deleted file mode 100644 index 29d8a942e9b8..000000000000 --- a/src/Mod/Path/PathScripts/PathMachine.py +++ /dev/null @@ -1,254 +0,0 @@ -# -*- coding: utf-8 -*- - -# *************************************************************************** -# * * -# * Copyright (c) 2015 Dan Falck * -# * * -# * This program is free software; you can redistribute it and/or modify * -# * it under the terms of the GNU Lesser General Public License (LGPL) * -# * as published by the Free Software Foundation; either version 2 of * -# * the License, or (at your option) any later version. * -# * for detail see the LICENCE text file. * -# * * -# * This program is distributed in the hope that it will be useful, * -# * but WITHOUT ANY WARRANTY; without even the implied warranty of * -# * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * -# * GNU Library General Public License for more details. * -# * * -# * You should have received a copy of the GNU Library General Public * -# * License along with this program; if not, write to the Free Software * -# * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * -# * USA * -# * * -# *************************************************************************** -''' A CNC machine object to define how code is posted ''' - -import FreeCAD -import Path -import PathScripts -from PathScripts import PathUtils -from PySide import QtCore, QtGui -import os -import sys - -# Qt tanslation handling -try: - _encoding = QtGui.QApplication.UnicodeUTF8 - - def translate(context, text, disambig=None): - return QtGui.QApplication.translate(context, text, disambig, _encoding) -except AttributeError: - def translate(context, text, disambig=None): - return QtGui.QApplication.translate(context, text, disambig) - - -class Machine: - - def __init__(self, obj): - - obj.addProperty("App::PropertyString", "MachineName", "Base", QtCore.QT_TRANSLATE_NOOP("App::Property","Name of the Machine that will use the CNC program")) - - obj.addProperty("App::PropertyFile", "PostProcessor", "CodeOutput", QtCore.QT_TRANSLATE_NOOP("App::Property","Select the Post Processor file for this machine")) - obj.addProperty("App::PropertyEnumeration", "MachineUnits", "CodeOutput", QtCore.QT_TRANSLATE_NOOP("App::Property","Units that the machine works in, ie Metric or Inch")) - obj.MachineUnits = ['Metric', 'Inch'] - - obj.addProperty("Path::PropertyTooltable", "Tooltable", "Base", QtCore.QT_TRANSLATE_NOOP("App::Property","The tooltable used for this CNC program")) - - obj.addProperty("App::PropertyDistance", "X_Max", "Limits", QtCore.QT_TRANSLATE_NOOP("App::Property","The Maximum distance in X the machine can travel")) - obj.addProperty("App::PropertyDistance", "Y_Max", "Limits", QtCore.QT_TRANSLATE_NOOP("App::Property","The Maximum distance in Y the machine can travel")) - obj.addProperty("App::PropertyDistance", "Z_Max", "Limits", QtCore.QT_TRANSLATE_NOOP("App::Property","The Maximum distance in Z the machine can travel")) - - obj.addProperty("App::PropertyDistance", "X_Min", "Limits", QtCore.QT_TRANSLATE_NOOP("App::Property","The Minimum distance in X the machine can travel")) - obj.addProperty("App::PropertyDistance", "Y_Min", "Limits", QtCore.QT_TRANSLATE_NOOP("App::Property","The Minimum distance in Y the machine can travel")) - obj.addProperty("App::PropertyDistance", "Z_Min", "Limits", QtCore.QT_TRANSLATE_NOOP("App::Property","The Minimum distance in Z the machine can travel")) - - obj.addProperty("App::PropertyDistance", "X", "HomePosition", QtCore.QT_TRANSLATE_NOOP("App::Property","Home position of machine, in X (mainly for visualization)")) - obj.addProperty("App::PropertyDistance", "Y", "HomePosition", QtCore.QT_TRANSLATE_NOOP("App::Property","Home position of machine, in Y (mainly for visualization)")) - obj.addProperty("App::PropertyDistance", "Z", "HomePosition", QtCore.QT_TRANSLATE_NOOP("App::Property","Home position of machine, in Z (mainly for visualization)")) - - obj.Proxy = self - mode = 2 - obj.setEditorMode('Placement', mode) - - def execute(self, obj): - obj.Label = "Machine_" + str(obj.MachineName) - # need to filter this path out in post- only for visualization - #gcode = 'G0 X' + str(obj.X.Value) + ' Y' + \ - # str(obj.Y.Value) + ' Z' + str(obj.Z.Value) - gcode = "" - gcode += '(' + str(obj.Label) + ')' - obj.Path = Path.Path(gcode) - - def onChanged(self, obj, prop): - mode = 2 - obj.setEditorMode('Placement', mode) - - if prop == "PostProcessor": - sys.path.append(os.path.split(obj.PostProcessor)[0]) - lessextn = os.path.splitext(obj.PostProcessor)[0] - postname = os.path.split(lessextn)[1] - - exec "import %s as current_post" % postname - if hasattr(current_post, "UNITS"): - if current_post.UNITS == "G21": - obj.MachineUnits = "Metric" - else: - obj.MachineUnits = "Inch" - if hasattr(current_post, "MACHINE_NAME"): - obj.MachineName = current_post.MACHINE_NAME - - if hasattr(current_post, "CORNER_MAX"): - obj.X_Max = current_post.CORNER_MAX['x'] - obj.Y_Max = current_post.CORNER_MAX['y'] - obj.Z_Max = current_post.CORNER_MAX['z'] - - if hasattr(current_post, "CORNER_MIN"): - obj.X_Min = current_post.CORNER_MIN['x'] - obj.Y_Min = current_post.CORNER_MIN['y'] - obj.Z_Min = current_post.CORNER_MIN['z'] - - if prop == "Tooltable": - proj = PathUtils.findProj() - for g in proj.Group: - if not(isinstance(g.Proxy, PathScripts.PathMachine.Machine)): - g.touch() - - -class _ViewProviderMachine: - - def __init__(self, vobj): - vobj.Proxy = self - vobj.addProperty("App::PropertyBool", "ShowLimits", "Path", - QtCore.QT_TRANSLATE_NOOP("App::Property", "Switch the machine max and minimum travel bounding box on/off")) - mode = 2 - vobj.setEditorMode('LineWidth', mode) - vobj.setEditorMode('MarkerColor', mode) - vobj.setEditorMode('NormalColor', mode) - vobj.setEditorMode('ShowFirstRapid', 0) - vobj.setEditorMode('DisplayMode', mode) - vobj.setEditorMode('BoundingBox', mode) - vobj.setEditorMode('Selectable', mode) - - def __getstate__(self): # mandatory - return None - - def __setstate__(self, state): # mandatory - return None - - def getIcon(self): # optional - return ":/icons/Path-Machine.svg" - - def attach(self, vobj): - from pivy import coin - self.extentsBox = coin.SoSeparator() - vobj.RootNode.addChild(self.extentsBox) - - def onChanged(self, vobj, prop): - - if prop == "ShowLimits": - self.extentsBox.removeAllChildren() - if vobj.ShowLimits and hasattr(vobj, "Object"): - from pivy import coin - parent = coin.SoType.fromName( - "SoSkipBoundingGroup").createInstance() - self.extentsBox.addChild(parent) - # set pattern - pattern = FreeCAD.ParamGet( - "User parameter:BaseApp/Preferences/Mod/Part").GetInt("GridLinePattern", 0x0f0f) - defStyle = coin.SoDrawStyle() - defStyle.lineWidth = 1 - defStyle.linePattern = pattern - parent.addChild(defStyle) - # set color - c = FreeCAD.ParamGet( - "User parameter:BaseApp/Preferences/Mod/Path").GetUnsigned("DefaultExtentsColor", 3418866943) - r = float((c >> 24) & 0xFF) / 255.0 - g = float((c >> 16) & 0xFF) / 255.0 - b = float((c >> 8) & 0xFF) / 255.0 - color = coin.SoBaseColor() - parent.addChild(color) - # set boundbox - extents = coin.SoType.fromName( - "SoFCBoundingBox").createInstance() - extents.coordsOn.setValue(False) - extents.dimensionsOn.setValue(False) - - XMax, YMax, ZMax = vobj.Object.X_Max.Value, vobj.Object.Y_Max.Value, vobj.Object.Z_Max.Value - XMin, YMin, ZMin = vobj.Object.X_Min.Value, vobj.Object.Y_Min.Value, vobj.Object.Z_Min.Value - # UnitParams = FreeCAD.ParamGet( - # "User parameter:BaseApp/Preferences/Units") - - extents.minBounds.setValue(XMax, YMax, ZMax) - extents.maxBounds.setValue(XMin, YMin, ZMin) - - parent.addChild(extents) - mode = 2 - vobj.setEditorMode('LineWidth', mode) - vobj.setEditorMode('MarkerColor', mode) - vobj.setEditorMode('NormalColor', mode) - vobj.setEditorMode('ShowFirstRapid', 0) - vobj.setEditorMode('DisplayMode', mode) - vobj.setEditorMode('BoundingBox', mode) - vobj.setEditorMode('Selectable', mode) - - def updateData(self, vobj, prop): # optional - # this is executed when a property of the APP OBJECT changes - pass - - def setEdit(self, vobj, mode=0): # optional - return True - - def unsetEdit(self, vobj, mode=0): # optional - # this is executed when the user cancels or terminates edit mode - pass - - def doubleClicked(self, vobj): - from PathScripts import TooltableEditor - TooltableEditor.edit(vobj.Object.Name) - - -class CommandPathMachine: - - def GetResources(self): - return {'Pixmap': 'Path-Machine', - 'MenuText': QtCore.QT_TRANSLATE_NOOP("PathMachine", "Machine Object"), - 'Accel': "P, M", - 'ToolTip': QtCore.QT_TRANSLATE_NOOP("PathMachine", "Create a Machine object")} - - def IsActive(self): - return FreeCAD.ActiveDocument is not None - - def Activated(self): - FreeCAD.ActiveDocument.openTransaction( - translate("PathMachine", "Create a Machine object")) - CommandPathMachine.Create() - FreeCAD.ActiveDocument.commitTransaction() - FreeCAD.ActiveDocument.recompute() - - @staticmethod - def Create(): - obj = FreeCAD.ActiveDocument.addObject( - "Path::FeaturePython", "Machine") - Machine(obj) - _ViewProviderMachine(obj.ViewObject) - - PathUtils.addToProject(obj) - - UnitParams = FreeCAD.ParamGet( - "User parameter:BaseApp/Preferences/Units") - if UnitParams.GetInt('UserSchema') == 0: - obj.MachineUnits = 'Metric' - # metric mode - else: - obj.MachineUnits = 'Inch' - - obj.ViewObject.ShowFirstRapid = False - return obj - -if FreeCAD.GuiUp: - # register the FreeCAD command - import FreeCADGui - FreeCADGui.addCommand('Path_Machine', CommandPathMachine()) - - -FreeCAD.Console.PrintLog("Loading PathMachine... done\n") diff --git a/src/Mod/Path/PathScripts/PathPlane.py b/src/Mod/Path/PathScripts/PathPlane.py index 94c26c0b497c..8b5e7d100a10 100644 --- a/src/Mod/Path/PathScripts/PathPlane.py +++ b/src/Mod/Path/PathScripts/PathPlane.py @@ -1,41 +1,44 @@ # -*- coding: utf-8 -*- -#*************************************************************************** -#* * -#* Copyright (c) 2015 Dan Falck * -#* * -#* This program is free software; you can redistribute it and/or modify * -#* it under the terms of the GNU Lesser General Public License (LGPL) * -#* as published by the Free Software Foundation; either version 2 of * -#* the License, or (at your option) any later version. * -#* for detail see the LICENCE text file. * -#* * -#* This program is distributed in the hope that it will be useful, * -#* but WITHOUT ANY WARRANTY; without even the implied warranty of * -#* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * -#* GNU Library General Public License for more details. * -#* * -#* You should have received a copy of the GNU Library General Public * -#* License along with this program; if not, write to the Free Software * -#* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * -#* USA * -#* * -#*************************************************************************** +# *************************************************************************** +# * * +# * Copyright (c) 2015 Dan Falck * +# * * +# * This program is free software; you can redistribute it and/or modify * +# * it under the terms of the GNU Lesser General Public License (LGPL) * +# * as published by the Free Software Foundation; either version 2 of * +# * the License, or (at your option) any later version. * +# * for detail see the LICENCE text file. * +# * * +# * This program is distributed in the hope that it will be useful, * +# * but WITHOUT ANY WARRANTY; without even the implied warranty of * +# * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * +# * GNU Library General Public License for more details. * +# * * +# * You should have received a copy of the GNU Library General Public * +# * License along with this program; if not, write to the Free Software * +# * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * +# * USA * +# * * +# *************************************************************************** ''' Used for CNC machine plane selection G17,G18,G19 ''' -import FreeCAD,FreeCADGui,Path,PathGui -from PathScripts import PathProject -from PySide import QtCore,QtGui +import FreeCAD +import FreeCADGui +import Path +from PySide import QtCore, QtGui # Qt tanslation handling try: _encoding = QtGui.QApplication.UnicodeUTF8 + def translate(context, text, disambig=None): return QtGui.QApplication.translate(context, text, disambig, _encoding) except AttributeError: def translate(context, text, disambig=None): return QtGui.QApplication.translate(context, text, disambig) + class Plane: def __init__(self,obj): obj.addProperty("App::PropertyEnumeration", "SelectionPlane","Path",QtCore.QT_TRANSLATE_NOOP("App::Property","Orientation plane of CNC path")) @@ -43,13 +46,12 @@ def __init__(self,obj): obj.addProperty("App::PropertyBool","Active","Path",QtCore.QT_TRANSLATE_NOOP("App::Property","Make False, to prevent operation from generating code")) obj.Proxy = self - def execute(self,obj): + def execute(self, obj): clonelist = ['XY', 'XZ', 'YZ'] cindx = clonelist.index(str(obj.SelectionPlane)) pathlist = ['G17', 'G18', 'G19'] -# obj.Path = Path.Path(pathlist[cindx]) - labelindx = clonelist.index(obj.SelectionPlane)+1 - obj.Label = "Plane"+str(labelindx) + labelindx = clonelist.index(obj.SelectionPlane) + 1 + obj.Label = "Plane" + str(labelindx) if obj.Active: obj.Path = Path.Path(pathlist[cindx]) obj.ViewObject.Visibility = True @@ -59,67 +61,74 @@ def execute(self,obj): class _ViewProviderPlane: - def __init__(self,vobj): #mandatory + + def __init__(self, vobj): # mandatory vobj.Proxy = self mode = 2 - vobj.setEditorMode('LineWidth',mode) - vobj.setEditorMode('MarkerColor',mode) - vobj.setEditorMode('NormalColor',mode) - vobj.setEditorMode('ShowFirstRapid',mode) - vobj.setEditorMode('DisplayMode',mode) - vobj.setEditorMode('BoundingBox',mode) - vobj.setEditorMode('Selectable',mode) - vobj.setEditorMode('ShapeColor',mode) - vobj.setEditorMode('Transparency',mode) - vobj.setEditorMode('Visibility',mode) - - - def __getstate__(self): #mandatory + vobj.setEditorMode('LineWidth', mode) + vobj.setEditorMode('MarkerColor', mode) + vobj.setEditorMode('NormalColor', mode) + vobj.setEditorMode('ShowFirstRapid', mode) + vobj.setEditorMode('DisplayMode', mode) + vobj.setEditorMode('BoundingBox', mode) + vobj.setEditorMode('Selectable', mode) + vobj.setEditorMode('ShapeColor', mode) + vobj.setEditorMode('Transparency', mode) + vobj.setEditorMode('Visibility', mode) + + def __getstate__(self): # mandatory return None - def __setstate__(self,state): #mandatory + def __setstate__(self, state): # mandatory return None - def getIcon(self): #optional + def getIcon(self): # optional return ":/icons/Path-Plane.svg" - def onChanged(self,vobj,prop): #optional + def onChanged(self, vobj, prop): # optional mode = 2 - vobj.setEditorMode('LineWidth',mode) - vobj.setEditorMode('MarkerColor',mode) - vobj.setEditorMode('NormalColor',mode) - vobj.setEditorMode('ShowFirstRapid',mode) - vobj.setEditorMode('DisplayMode',mode) - vobj.setEditorMode('BoundingBox',mode) - vobj.setEditorMode('Selectable',mode) - vobj.setEditorMode('ShapeColor',mode) - vobj.setEditorMode('Transparency',mode) - vobj.setEditorMode('Visibility',mode) - - def updateData(self,vobj,prop): #optional + vobj.setEditorMode('LineWidth', mode) + vobj.setEditorMode('MarkerColor', mode) + vobj.setEditorMode('NormalColor', mode) + vobj.setEditorMode('ShowFirstRapid', mode) + vobj.setEditorMode('DisplayMode', mode) + vobj.setEditorMode('BoundingBox', mode) + vobj.setEditorMode('Selectable', mode) + vobj.setEditorMode('ShapeColor', mode) + vobj.setEditorMode('Transparency', mode) + vobj.setEditorMode('Visibility', mode) + + def updateData(self, vobj, prop): # optional # this is executed when a property of the APP OBJECT changes pass - def setEdit(self,vobj,mode): #optional + def setEdit(self, vobj, mode): # optional # this is executed when the object is double-clicked in the tree pass - def unsetEdit(self,vobj,mode): #optional + def unsetEdit(self, vobj, mode): # optional # this is executed when the user cancels or terminates edit mode pass + class CommandPathPlane: + def GetResources(self): - return {'Pixmap' : 'Path-Plane', - 'MenuText': QtCore.QT_TRANSLATE_NOOP("Path_Plane","Selection Plane"), + return {'Pixmap': 'Path-Plane', + 'MenuText': QtCore.QT_TRANSLATE_NOOP("Path_Plane", "Selection Plane"), 'Accel': "P, P", - 'ToolTip': QtCore.QT_TRANSLATE_NOOP("Path_Plane","Create a Selection Plane object")} + 'ToolTip': QtCore.QT_TRANSLATE_NOOP("Path_Plane", "Create a Selection Plane object")} def IsActive(self): - return not FreeCAD.ActiveDocument is None + if FreeCAD.ActiveDocument is not None: + for o in FreeCAD.ActiveDocument.Objects: + if o.Name[:3] == "Job": + return True + return False def Activated(self): - FreeCAD.ActiveDocument.openTransaction(translate("Path_Plane","Create a Selection Plane object")) + FreeCAD.ActiveDocument.openTransaction( + translate("Path_Plane", "Create a Selection Plane object")) FreeCADGui.addModule("PathScripts.PathPlane") snippet = ''' import Path @@ -130,7 +139,7 @@ def Activated(self): PathScripts.PathPlane.Plane(obj) obj.Active = True PathScripts.PathPlane._ViewProviderPlane(obj.ViewObject) -PathUtils.addToProject(obj) +PathUtils.addToJob(obj) ''' @@ -138,11 +147,9 @@ def Activated(self): FreeCAD.ActiveDocument.commitTransaction() FreeCAD.ActiveDocument.recompute() -if FreeCAD.GuiUp: +if FreeCAD.GuiUp: # register the FreeCAD command - FreeCADGui.addCommand('Path_Plane',CommandPathPlane()) + FreeCADGui.addCommand('Path_Plane', CommandPathPlane()) FreeCAD.Console.PrintLog("Loading PathPlane... done\n") - - diff --git a/src/Mod/Path/PathScripts/PathPocket.py b/src/Mod/Path/PathScripts/PathPocket.py index 719e67484b39..0a0d22a1ba4e 100644 --- a/src/Mod/Path/PathScripts/PathPocket.py +++ b/src/Mod/Path/PathScripts/PathPocket.py @@ -516,7 +516,7 @@ def Activated(self): FreeCADGui.doCommand('obj.RampAngle = 3.0') FreeCADGui.doCommand('obj.RampSize = 0.75') FreeCADGui.doCommand('obj.HelixSize = 0.75') - FreeCADGui.doCommand('PathScripts.PathUtils.addToProject(obj)') + FreeCADGui.doCommand('PathScripts.PathUtils.addToJob(obj)') FreeCAD.ActiveDocument.commitTransaction() FreeCAD.ActiveDocument.recompute() diff --git a/src/Mod/Path/PathScripts/PathPost.py b/src/Mod/Path/PathScripts/PathPost.py index 0fa97dc97fb6..bd2dbadf2238 100644 --- a/src/Mod/Path/PathScripts/PathPost.py +++ b/src/Mod/Path/PathScripts/PathPost.py @@ -1,37 +1,38 @@ # -*- coding: utf-8 -*- -#*************************************************************************** -#* * -#* Copyright (c) 2015 Dan Falck * -#* * -#* This program is free software; you can redistribute it and/or modify * -#* it under the terms of the GNU Lesser General Public License (LGPL) * -#* as published by the Free Software Foundation; either version 2 of * -#* the License, or (at your option) any later version. * -#* for detail see the LICENCE text file. * -#* * -#* This program is distributed in the hope that it will be useful, * -#* but WITHOUT ANY WARRANTY; without even the implied warranty of * -#* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * -#* GNU Library General Public License for more details. * -#* * -#* You should have received a copy of the GNU Library General Public * -#* License along with this program; if not, write to the Free Software * -#* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * -#* USA * -#* * -#*************************************************************************** -''' Post Process command that will make use of the Output File and Post Processor entries in PathProject ''' -import FreeCAD, FreeCADGui -import Path, PathScripts,PathGui -from PathScripts import PostUtils -from PathScripts import PathProject -import os,sys -from PySide import QtCore,QtGui +# *************************************************************************** +# * * +# * Copyright (c) 2015 Dan Falck * +# * * +# * This program is free software; you can redistribute it and/or modify * +# * it under the terms of the GNU Lesser General Public License (LGPL) * +# * as published by the Free Software Foundation; either version 2 of * +# * the License, or (at your option) any later version. * +# * for detail see the LICENCE text file. * +# * * +# * This program is distributed in the hope that it will be useful, * +# * but WITHOUT ANY WARRANTY; without even the implied warranty of * +# * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * +# * GNU Library General Public License for more details. * +# * * +# * You should have received a copy of the GNU Library General Public * +# * License along with this program; if not, write to the Free Software * +# * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * +# * USA * +# * * +# *************************************************************************** +''' Post Process command that will make use of the Output File and Post Processor entries in PathJob ''' +import FreeCAD +import FreeCADGui +import PathScripts +import os +import sys +from PySide import QtCore, QtGui # Qt tanslation handling try: _encoding = QtGui.QApplication.UnicodeUTF8 + def translate(context, text, disambig=None): return QtGui.QApplication.translate(context, text, disambig, _encoding) except AttributeError: @@ -40,51 +41,66 @@ def translate(context, text, disambig=None): class CommandPathPost: + def GetResources(self): - return {'Pixmap' : 'Path-Post', - 'MenuText': QtCore.QT_TRANSLATE_NOOP("Path_Post","Post Process"), + return {'Pixmap': 'Path-Post', + 'MenuText': QtCore.QT_TRANSLATE_NOOP("Path_Post", "Post Process"), 'Accel': "P, P", - 'ToolTip': QtCore.QT_TRANSLATE_NOOP("Path_Post","Post Process the selected Project")} + 'ToolTip': QtCore.QT_TRANSLATE_NOOP("Path_Post", "Post Process the selected Job")} def IsActive(self): - return not FreeCAD.ActiveDocument is None + if FreeCAD.ActiveDocument is not None: + for o in FreeCAD.ActiveDocument.Objects: + if o.Name[:3] == "Job": + return True + return False def Activated(self): - FreeCAD.ActiveDocument.openTransaction(translate("Path_Post","Post Process the Selected path(s)")) + FreeCAD.ActiveDocument.openTransaction( + translate("Path_Post", "Post Process the Selected path(s)")) FreeCADGui.addModule("PathScripts.PathPost") - #select the PathProject that you want to post output from + # select the Path Job that you want to post output from obj = FreeCADGui.Selection.getSelection() - #default to the dumper post and default .tap file - postname = "dumper_post" + # default to the dumper post and default .tap file + postname = "dumper" filename = "tmp.tap" - #check if the user has a project and has set the default post and output filename - if hasattr(obj[0],"Group") and hasattr(obj[0],"Path"): - #Check for a machine and use the post processor if it's set + print "in activated" + + # check if the user has a project and has set the default post and + # output filename + if hasattr(obj[0], "Group") and hasattr(obj[0], "Path"): + # # Check for a selected post post processor if it's set proj = obj[0] - postobj = None - for p in obj[0].Group: - if p.Name == "Machine": - postobj = p - - #need to check for existance of these: obj.PostProcessor, obj.OutputFile - if postobj and postobj.PostProcessor: - sys.path.append(os.path.split(postobj.PostProcessor)[0]) - lessextn = os.path.splitext(postobj.PostProcessor)[0] - postname = os.path.split(lessextn)[1] - - if proj.OutputFile: - filename = proj.OutputFile - + # postobj = None + # for p in obj[0].Group: + # if p.Name == "Machine": + # postobj = p + + if hasattr(obj[0], "PostProcessor"): + postobj = obj[0] + + # need to check for existance of these: obj.PostProcessor, + # obj.OutputFile + if postobj and postobj.PostProcessor: + sys.path.append(os.path.split(postobj.PostProcessor)[0]) + lessextn = os.path.splitext(postobj.PostProcessor)[0] + postname = os.path.split(lessextn)[1] + + if proj.OutputFile: + filename = proj.OutputFile + + postname += "_post" exec "import %s as current_post" % postname - current_post.export(obj,filename) + reload(current_post) + current_post.export(obj, filename) FreeCAD.ActiveDocument.commitTransaction() FreeCAD.ActiveDocument.recompute() -if FreeCAD.GuiUp: +if FreeCAD.GuiUp: # register the FreeCAD command - FreeCADGui.addCommand('Path_Post',CommandPathPost()) + FreeCADGui.addCommand('Path_Post', CommandPathPost()) FreeCAD.Console.PrintLog("Loading PathPost... done\n") diff --git a/src/Mod/Path/PathScripts/PathProfile.py b/src/Mod/Path/PathScripts/PathProfile.py index 43aefa624c25..f40f8d676ce9 100644 --- a/src/Mod/Path/PathScripts/PathProfile.py +++ b/src/Mod/Path/PathScripts/PathProfile.py @@ -32,7 +32,6 @@ if FreeCAD.GuiUp: import FreeCADGui from PySide import QtCore, QtGui - from DraftTools import translate # Qt tanslation handling try: _encoding = QtGui.QApplication.UnicodeUTF8 @@ -452,7 +451,11 @@ def GetResources(self): 'ToolTip': QtCore.QT_TRANSLATE_NOOP("PathProfile", "Creates a Path Profile object from selected faces")} def IsActive(self): - return FreeCAD.ActiveDocument is not None + if FreeCAD.ActiveDocument is not None: + for o in FreeCAD.ActiveDocument.Objects: + if o.Name[:3] == "Job": + return True + return False def Activated(self): ztop = 10.0 @@ -477,7 +480,7 @@ def Activated(self): FreeCADGui.doCommand('obj.Direction = "CW"') FreeCADGui.doCommand('obj.UseComp = False') FreeCADGui.doCommand('obj.PlungeAngle = 90.0') - FreeCADGui.doCommand('PathScripts.PathUtils.addToProject(obj)') + FreeCADGui.doCommand('PathScripts.PathUtils.addToJob(obj)') FreeCAD.ActiveDocument.commitTransaction() FreeCAD.ActiveDocument.recompute() diff --git a/src/Mod/Path/PathScripts/PathProject.py b/src/Mod/Path/PathScripts/PathProject.py deleted file mode 100644 index 6189a55a9111..000000000000 --- a/src/Mod/Path/PathScripts/PathProject.py +++ /dev/null @@ -1,161 +0,0 @@ -# -*- coding: utf-8 -*- - -# *************************************************************************** -# * * -# * Copyright (c) 2014 Yorik van Havre * -# * * -# * This program is free software; you can redistribute it and/or modify * -# * it under the terms of the GNU Lesser General Public License (LGPL) * -# * as published by the Free Software Foundation; either version 2 of * -# * the License, or (at your option) any later version. * -# * for detail see the LICENCE text file. * -# * * -# * This program is distributed in the hope that it will be useful, * -# * but WITHOUT ANY WARRANTY; without even the implied warranty of * -# * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * -# * GNU Library General Public License for more details. * -# * * -# * You should have received a copy of the GNU Library General Public * -# * License along with this program; if not, write to the Free Software * -# * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * -# * USA * -# * * -# *************************************************************************** - -import FreeCAD -import Path -from PySide import QtCore, QtGui - -FreeCADGui = None -if FreeCAD.GuiUp: - import FreeCADGui - -"""Path Project object and FreeCAD command""" - -# Qt tanslation handling -try: - _encoding = QtGui.QApplication.UnicodeUTF8 - - def translate(context, text, disambig=None): - return QtGui.QApplication.translate(context, text, disambig, _encoding) -except AttributeError: - def translate(context, text, disambig=None): - return QtGui.QApplication.translate(context, text, disambig) - - -class ObjectPathProject: - - def __init__(self, obj): - # obj.addProperty("App::PropertyFile", "PostProcessor", "CodeOutput", "Select the Post Processor file for this project") - obj.addProperty("App::PropertyFile", "OutputFile", "CodeOutput", QtCore.QT_TRANSLATE_NOOP("App::Property","The NC output file for this project")) - obj.setEditorMode("OutputFile", 0) # set to default mode - obj.addProperty("App::PropertyString", "Description", "Path", QtCore.QT_TRANSLATE_NOOP("App::Property","An optional description for this project")) - obj.Proxy = self - - def __getstate__(self): - return None - - def __setstate__(self, state): - return None - - def onChanged(self, obj, prop): - pass - - def execute(self, obj): - cmds = [] - for child in obj.Group: - if child.isDerivedFrom("Path::Feature"): - if obj.UsePlacements: - for c in child.Path.Commands: - cmds.append(c.transform(child.Placement)) - else: - cmds.extend(child.Path.Commands) - if cmds: - path = Path.Path(cmds) - obj.Path = path - - -class ViewProviderProject: - - def __init__(self, vobj): - vobj.Proxy = self - mode = 2 - vobj.setEditorMode('BoundingBox', mode) - vobj.setEditorMode('DisplayMode', mode) - vobj.setEditorMode('Selectable', mode) - vobj.setEditorMode('ShapeColor', mode) - vobj.setEditorMode('Transparency', mode) - - def __getstate__(self): # mandatory - return None - - def __setstate__(self, state): # mandatory - return None - - def getIcon(self): - return ":/icons/Path-Project.svg" - - def onChanged(self, vobj, prop): - mode = 2 - vobj.setEditorMode('BoundingBox', mode) - vobj.setEditorMode('DisplayMode', mode) - vobj.setEditorMode('Selectable', mode) - vobj.setEditorMode('ShapeColor', mode) - vobj.setEditorMode('Transparency', mode) - - -class CommandProject: - - def GetResources(self): - return {'Pixmap': 'Path-Project', - 'MenuText': QtCore.QT_TRANSLATE_NOOP("Path_Project", "Project"), - 'Accel': "P, P", - 'ToolTip': QtCore.QT_TRANSLATE_NOOP("Path_Project", "Creates a Path Project object")} - - def IsActive(self): - return FreeCAD.ActiveDocument is not None - - def Activated(self): - incl = [] - sel = FreeCADGui.Selection.getSelection() - for obj in sel: - if obj.isDerivedFrom("Path::Feature"): - incl.append(obj) - FreeCAD.ActiveDocument.openTransaction( - translate("Path_Project", "Create Project")) - CommandProject.Create(incl) - FreeCAD.ActiveDocument.commitTransaction() - FreeCAD.ActiveDocument.recompute() - - @staticmethod - def Create(pathChildren=[]): - """Code to create a project""" - # FreeCADGui.addModule("PathScripts.PathProject") - import PathScripts.PathUtils as PU - if not PU.findProj() is None: - FreeCAD.Console.PrintError( - "A Path project already exists in this document\n") - return - - obj = FreeCAD.ActiveDocument.addObject( - "Path::FeatureCompoundPython", "Project") - ObjectPathProject(obj) - if pathChildren: - for child in pathChildren: - pathChildren.append(FreeCAD.ActiveDocument.getObject(obj.Name)) - obj.Group = pathChildren - ViewProviderProject(obj.ViewObject) - - # create a machine obj - import PathScripts - PathScripts.PathMachine.CommandPathMachine.Create() - PathScripts.PathLoadTool.CommandPathLoadTool.Create() - - return obj - - -if FreeCAD.GuiUp: - # register the FreeCAD command - FreeCADGui.addCommand('Path_Project', CommandProject()) - -FreeCAD.Console.PrintLog("Loading PathProject... done\n") diff --git a/src/Mod/Path/PathScripts/PathRemote.py b/src/Mod/Path/PathScripts/PathRemote.py index a4778a328a07..8e0d78c3e4a2 100644 --- a/src/Mod/Path/PathScripts/PathRemote.py +++ b/src/Mod/Path/PathScripts/PathRemote.py @@ -31,10 +31,6 @@ if FreeCAD.GuiUp: import FreeCADGui from PySide import QtCore, QtGui - from DraftTools import translate -else: - def translate(ctxt, txt): - return txt __title__ = "Path Remote Operation" __author__ = "sliptonic (Brad Collette)" @@ -303,7 +299,11 @@ def GetResources(self): 'ToolTip': QtCore.QT_TRANSLATE_NOOP("Path_Remote", "Request a Path from a remote cloud service")} def IsActive(self): - return FreeCAD.ActiveDocument is not None + if FreeCAD.ActiveDocument is not None: + for o in FreeCAD.ActiveDocument.Objects: + if o.Name[:3] == "Job": + return True + return False def Activated(self): ztop = 10.0 @@ -322,7 +322,7 @@ def Activated(self): FreeCADGui.doCommand('obj.StepDown = ' + str((ztop-zbottom)/8)) FreeCADGui.doCommand('obj.FinalDepth=' + str(zbottom)) - FreeCADGui.doCommand('PathScripts.PathUtils.addToProject(obj)') + FreeCADGui.doCommand('PathScripts.PathUtils.addToJob(obj)') FreeCAD.ActiveDocument.commitTransaction() FreeCAD.ActiveDocument.recompute() diff --git a/src/Mod/Path/PathScripts/PathSanity.py b/src/Mod/Path/PathScripts/PathSanity.py index 7953e2de8683..d7af7199c04f 100644 --- a/src/Mod/Path/PathScripts/PathSanity.py +++ b/src/Mod/Path/PathScripts/PathSanity.py @@ -41,7 +41,6 @@ def translate(context, text, disambig=None): def review(obj): - limits = False "checks the selected project for common errors" toolcontrolcount = 0 for item in obj.Group: @@ -69,8 +68,6 @@ def review(obj): if item.X_Max == item.X_Min or item.Y_Max == item.Y_Min: FreeCAD.Console.PrintWarning(translate("Path_Sanity", "It appears the machine limits haven't been set. Not able to check path extents.\n")) - else: - limits = True if toolcontrolcount == 0: 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")) @@ -84,7 +81,11 @@ def GetResources(self): 'ToolTip': QtCore.QT_TRANSLATE_NOOP("Path_Sanity","Check the Path Project for common errors")} def IsActive(self): - return not FreeCAD.ActiveDocument is None + 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 diff --git a/src/Mod/Path/PathScripts/PathSimpleCopy.py b/src/Mod/Path/PathScripts/PathSimpleCopy.py index adadea6350ee..2b5af97f155d 100644 --- a/src/Mod/Path/PathScripts/PathSimpleCopy.py +++ b/src/Mod/Path/PathScripts/PathSimpleCopy.py @@ -1,35 +1,36 @@ # -*- coding: utf-8 -*- +# *************************************************************************** +# * * +# * Copyright (c) 2015 Yorik van Havre * +# * * +# * This program is free software; you can redistribute it and/or modify * +# * it under the terms of the GNU Lesser General Public License (LGPL) * +# * as published by the Free Software Foundation; either version 2 of * +# * the License, or (at your option) any later version. * +# * for detail see the LICENCE text file. * +# * * +# * This program is distributed in the hope that it will be useful, * +# * but WITHOUT ANY WARRANTY; without even the implied warranty of * +# * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * +# * GNU Library General Public License for more details. * +# * * +# * You should have received a copy of the GNU Library General Public * +# * License along with this program; if not, write to the Free Software * +# * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * +# * USA * +# * * +# *************************************************************************** -#*************************************************************************** -#* * -#* Copyright (c) 2015 Yorik van Havre * -#* * -#* This program is free software; you can redistribute it and/or modify * -#* it under the terms of the GNU Lesser General Public License (LGPL) * -#* as published by the Free Software Foundation; either version 2 of * -#* the License, or (at your option) any later version. * -#* for detail see the LICENCE text file. * -#* * -#* This program is distributed in the hope that it will be useful, * -#* but WITHOUT ANY WARRANTY; without even the implied warranty of * -#* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * -#* GNU Library General Public License for more details. * -#* * -#* You should have received a copy of the GNU Library General Public * -#* License along with this program; if not, write to the Free Software * -#* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * -#* USA * -#* * -#*************************************************************************** - -import FreeCAD,FreeCADGui,Path,PathGui -from PySide import QtCore,QtGui +import FreeCAD +import FreeCADGui +from PySide import QtCore, QtGui """Path SimpleCopy command""" # Qt tanslation handling try: _encoding = QtGui.QApplication.UnicodeUTF8 + def translate(context, text, disambig=None): return QtGui.QApplication.translate(context, text, disambig, _encoding) except AttributeError: @@ -39,35 +40,43 @@ def translate(context, text, disambig=None): class CommandPathSimpleCopy: - def GetResources(self): - return {'Pixmap' : 'Path-SimpleCopy', - 'MenuText': QtCore.QT_TRANSLATE_NOOP("Path_SimpleCopy","Simple Copy"), + return {'Pixmap': 'Path-SimpleCopy', + 'MenuText': QtCore.QT_TRANSLATE_NOOP("Path_SimpleCopy", "Simple Copy"), 'Accel': "P, Y", - 'ToolTip': QtCore.QT_TRANSLATE_NOOP("Path_SimpleCopy","Creates a non-parametric copy of another path")} + 'ToolTip': QtCore.QT_TRANSLATE_NOOP("Path_SimpleCopy", "Creates a non-parametric copy of another path")} def IsActive(self): - return not FreeCAD.ActiveDocument is None - + 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: - FreeCAD.Console.PrintError(translate("Path_SimpleCopy","Please select exactly one path object\n")) + FreeCAD.Console.PrintError( + translate("Path_SimpleCopy", "Please select exactly one path object\n")) return if not(selection[0].isDerivedFrom("Path::Feature")): - FreeCAD.Console.PrintError(translate("Path_SimpleCopy","Please select exactly one path object\n")) + FreeCAD.Console.PrintError( + translate("Path_SimpleCopy", "Please select exactly one path object\n")) return - - FreeCAD.ActiveDocument.openTransaction(translate("Path_SimpleCopy","Simple Copy")) + + FreeCAD.ActiveDocument.openTransaction( + translate("Path_SimpleCopy", "Simple Copy")) FreeCADGui.addModule("PathScripts.PathUtils") - FreeCADGui.doCommand('obj = FreeCAD.ActiveDocument.addObject("Path::Feature","'+selection[0].Name+ '_copy")') - FreeCADGui.doCommand('obj.Path = FreeCAD.ActiveDocument.'+selection[0].Name+'.Path') - FreeCADGui.doCommand('PathScripts.PathUtils.addToProject(obj)') + FreeCADGui.doCommand( + 'obj = FreeCAD.ActiveDocument.addObject("Path::Feature","' + selection[0].Name + '_copy")') + FreeCADGui.doCommand( + 'obj.Path = FreeCAD.ActiveDocument.' + selection[0].Name + '.Path') + FreeCADGui.doCommand('PathScripts.PathUtils.addToJob(obj)') FreeCAD.ActiveDocument.commitTransaction() FreeCAD.ActiveDocument.recompute() -if FreeCAD.GuiUp: +if FreeCAD.GuiUp: # register the FreeCAD command - FreeCADGui.addCommand('Path_SimpleCopy',CommandPathSimpleCopy()) + FreeCADGui.addCommand('Path_SimpleCopy', CommandPathSimpleCopy()) diff --git a/src/Mod/Path/PathScripts/PathStock.py b/src/Mod/Path/PathScripts/PathStock.py index c79c6ec68fbb..5e676de0c408 100644 --- a/src/Mod/Path/PathScripts/PathStock.py +++ b/src/Mod/Path/PathScripts/PathStock.py @@ -1,43 +1,45 @@ # -*- coding: utf-8 -*- - -#*************************************************************************** -#* * -#* Copyright (c) 2015 Dan Falck * -#* * -#* This program is free software; you can redistribute it and/or modify * -#* it under the terms of the GNU Lesser General Public License (LGPL) * -#* as published by the Free Software Foundation; either version 2 of * -#* the License, or (at your option) any later version. * -#* for detail see the LICENCE text file. * -#* * -#* This program is distributed in the hope that it will be useful, * -#* but WITHOUT ANY WARRANTY; without even the implied warranty of * -#* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * -#* GNU Library General Public License for more details. * -#* * -#* You should have received a copy of the GNU Library General Public * -#* License along with this program; if not, write to the Free Software * -#* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * -#* USA * -#* * -#*************************************************************************** +# *************************************************************************** +# * * +# * Copyright (c) 2015 Dan Falck * +# * * +# * This program is free software; you can redistribute it and/or modify * +# * it under the terms of the GNU Lesser General Public License (LGPL) * +# * as published by the Free Software Foundation; either version 2 of * +# * the License, or (at your option) any later version. * +# * for detail see the LICENCE text file. * +# * * +# * This program is distributed in the hope that it will be useful, * +# * but WITHOUT ANY WARRANTY; without even the implied warranty of * +# * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * +# * GNU Library General Public License for more details. * +# * * +# * You should have received a copy of the GNU Library General Public * +# * License along with this program; if not, write to the Free Software * +# * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * +# * USA * +# * * +# *************************************************************************** '''used to create material stock around a machined part- for visualization ''' -import Draft,Part -import FreeCAD, FreeCADGui +import FreeCAD +import FreeCADGui from FreeCAD import Vector from PySide import QtCore, QtGui - +import Part # Qt tanslation handling try: _encoding = QtGui.QApplication.UnicodeUTF8 + def translate(context, text, disambig=None): return QtGui.QApplication.translate(context, text, disambig, _encoding) except AttributeError: def translate(context, text, disambig=None): return QtGui.QApplication.translate(context, text, disambig) + class Stock: + def __init__(self, obj): "Make stock" obj.addProperty("App::PropertyFloat","Length_Allowance","Stock",QtCore.QT_TRANSLATE_NOOP("App::Property","extra allownace from part width")).Length_Allowance = 1.0 @@ -49,7 +51,7 @@ def __init__(self, obj): def __getstate__(self): return None - def __setstate__(self,state): + def __setstate__(self, state): return None def execute(self, obj): @@ -62,45 +64,49 @@ def execute(self, obj): self.Zmin = obj.Base.Shape.BoundBox.ZMin self.Zmax = obj.Base.Shape.BoundBox.ZMax - self.length = self.Xmax -self.Xmin+obj.Length_Allowance*2.0 - self.width = self.Ymax - self.Ymin+obj.Width_Allowance*2.0 - self.height = self.Zmax - self.Zmin+obj.Height_Allowance*2.0 - self.pnt = Vector(self.Xmin-obj.Length_Allowance , self.Ymin-obj.Width_Allowance, self.Zmin-obj.Height_Allowance) + self.length = self.Xmax - self.Xmin + obj.Length_Allowance * 2.0 + self.width = self.Ymax - self.Ymin + obj.Width_Allowance * 2.0 + self.height = self.Zmax - self.Zmin + obj.Height_Allowance * 2.0 + self.pnt = Vector(self.Xmin - obj.Length_Allowance, self.Ymin - + obj.Width_Allowance, self.Zmin - obj.Height_Allowance) + + obj.Shape = Part.makeBox( + self.length, self.width, self.height, self.pnt) - obj.Shape = Part.makeBox(self.length,self.width,self.height,self.pnt) class _ViewProviderStock: - def __init__(self,obj): #mandatory -# obj.addProperty("App::PropertyFloat","SomePropertyName","PropertyGroup","Description of this property") + def __init__(self, obj): # mandatory + # obj.addProperty("App::PropertyFloat","SomePropertyName","PropertyGroup","Description of this property") obj.Proxy = self - def __getstate__(self): #mandatory + def __getstate__(self): # mandatory return None - def __setstate__(self,state): #mandatory + def __setstate__(self, state): # mandatory return None - def getIcon(self): #optional + def getIcon(self): # optional return ":/icons/Path-Stock.svg" - def attach(self, vobj): #optional + def attach(self, vobj): # optional self.Object = vobj.Object - class CommandPathStock: + def GetResources(self): - return {'Pixmap' : 'Path-Stock', - 'MenuText': QtCore.QT_TRANSLATE_NOOP("PathStock","Stock"), + return {'Pixmap': 'Path-Stock', + 'MenuText': QtCore.QT_TRANSLATE_NOOP("PathStock", "Stock"), 'Accel': "P, S", - 'ToolTip': QtCore.QT_TRANSLATE_NOOP("PathStock","Creates a 3D object to represent raw stock to mill the part out of")} + 'ToolTip': QtCore.QT_TRANSLATE_NOOP("PathStock", "Creates a 3D object to represent raw stock to mill the part out of")} def IsActive(self): - return not FreeCAD.ActiveDocument is None + return FreeCAD.ActiveDocument is not None def Activated(self): - FreeCAD.ActiveDocument.openTransaction(translate("PathStock","Creates a 3D object to represent raw stock to mill the part out of")) + FreeCAD.ActiveDocument.openTransaction(translate( + "PathStock", "Creates a 3D object to represent raw stock to mill the part out of")) FreeCADGui.addModule("PathScripts.PathStock") snippet = ''' import FreeCADGui @@ -111,7 +117,7 @@ def Activated(self): obj =FreeCAD.ActiveDocument.addObject('Part::FeaturePython',sel[0].Name+('_Stock')) PathScripts.PathStock.Stock(obj) PathScripts.PathStock._ViewProviderStock(obj.ViewObject) - PathScripts.PathUtils.addToProject(obj) + PathScripts.PathUtils.addToJob(obj) baseobj = sel[0] obj.Base = baseobj FreeCADGui.ActiveDocument.getObject(sel[0].Name+("_Stock")).ShapeColor = (0.3333,0.6667,1.0000) @@ -124,9 +130,8 @@ def Activated(self): ''' FreeCADGui.doCommand(snippet) -if FreeCAD.GuiUp: +if FreeCAD.GuiUp: # register the FreeCAD command - FreeCADGui.addCommand('Path_Stock',CommandPathStock()) + FreeCADGui.addCommand('Path_Stock', CommandPathStock()) FreeCAD.Console.PrintLog("Loading PathStock... done\n") - diff --git a/src/Mod/Path/PathScripts/PathStop.py b/src/Mod/Path/PathScripts/PathStop.py index 2e340a61b9ed..32ef3f98c09f 100644 --- a/src/Mod/Path/PathScripts/PathStop.py +++ b/src/Mod/Path/PathScripts/PathStop.py @@ -1,124 +1,131 @@ # -*- coding: utf-8 -*- - -#*************************************************************************** -#* * -#* Copyright (c) 2015 Dan Falck * -#* * -#* This program is free software; you can redistribute it and/or modify * -#* it under the terms of the GNU Lesser General Public License (LGPL) * -#* as published by the Free Software Foundation; either version 2 of * -#* the License, or (at your option) any later version. * -#* for detail see the LICENCE text file. * -#* * -#* This program is distributed in the hope that it will be useful, * -#* but WITHOUT ANY WARRANTY; without even the implied warranty of * -#* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * -#* GNU Library General Public License for more details. * -#* * -#* You should have received a copy of the GNU Library General Public * -#* License along with this program; if not, write to the Free Software * -#* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * -#* USA * -#* * -#*************************************************************************** +# *************************************************************************** +# * * +# * Copyright (c) 2015 Dan Falck * +# * * +# * This program is free software; you can redistribute it and/or modify * +# * it under the terms of the GNU Lesser General Public License (LGPL) * +# * as published by the Free Software Foundation; either version 2 of * +# * the License, or (at your option) any later version. * +# * for detail see the LICENCE text file. * +# * * +# * This program is distributed in the hope that it will be useful, * +# * but WITHOUT ANY WARRANTY; without even the implied warranty of * +# * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * +# * GNU Library General Public License for more details. * +# * * +# * You should have received a copy of the GNU Library General Public * +# * License along with this program; if not, write to the Free Software * +# * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * +# * USA * +# * * +# *************************************************************************** ''' Used for CNC machine Stops for Path module. Create an Optional or Mandatory Stop.''' -import FreeCAD,FreeCADGui,Path,PathGui -from PathScripts import PathProject -from PySide import QtCore,QtGui +import FreeCAD +import FreeCADGui +import Path +from PySide import QtCore, QtGui # Qt tanslation handling try: _encoding = QtGui.QApplication.UnicodeUTF8 + def translate(context, text, disambig=None): return QtGui.QApplication.translate(context, text, disambig, _encoding) except AttributeError: def translate(context, text, disambig=None): return QtGui.QApplication.translate(context, text, disambig) + class Stop: def __init__(self,obj): obj.addProperty("App::PropertyEnumeration", "Stop", "Path", QtCore.QT_TRANSLATE_NOOP("App::Property","Add Optional or Mandatory Stop to the program")) obj.Stop=['Optional', 'Mandatory'] obj.Proxy = self mode = 2 - obj.setEditorMode('Placement',mode) - + obj.setEditorMode('Placement', mode) def __getstate__(self): return None - def __setstate__(self,state): + def __setstate__(self, state): return None - def onChanged(self,obj,prop): + def onChanged(self, obj, prop): pass # FreeCAD.ActiveDocument.recompute() - def execute(self,obj): + def execute(self, obj): if obj.Stop == 'Optional': word = 'M1' else: word = 'M0' - output ="" - output = word+'\n' + output = "" + output = word + '\n' path = Path.Path(output) obj.Path = path + class _ViewProviderStop: - def __init__(self,vobj): #mandatory -# obj.addProperty("App::PropertyFloat","SomePropertyName","PropertyGroup","Description of this property") + def __init__(self, vobj): # mandatory + # obj.addProperty("App::PropertyFloat","SomePropertyName","PropertyGroup","Description of this property") vobj.Proxy = self mode = 2 - vobj.setEditorMode('LineWidth',mode) - vobj.setEditorMode('MarkerColor',mode) - vobj.setEditorMode('NormalColor',mode) - vobj.setEditorMode('ShowFirstRapid',mode) - vobj.setEditorMode('DisplayMode',mode) - vobj.setEditorMode('BoundingBox',mode) - vobj.setEditorMode('Selectable',mode) - vobj.setEditorMode('ShapeColor',mode) - vobj.setEditorMode('Transparency',mode) - vobj.setEditorMode('Visibility',mode) - - - def __getstate__(self): #mandatory + vobj.setEditorMode('LineWidth', mode) + vobj.setEditorMode('MarkerColor', mode) + vobj.setEditorMode('NormalColor', mode) + vobj.setEditorMode('ShowFirstRapid', mode) + vobj.setEditorMode('DisplayMode', mode) + vobj.setEditorMode('BoundingBox', mode) + vobj.setEditorMode('Selectable', mode) + vobj.setEditorMode('ShapeColor', mode) + vobj.setEditorMode('Transparency', mode) + vobj.setEditorMode('Visibility', mode) + + def __getstate__(self): # mandatory return None - def __setstate__(self,state): #mandatory + def __setstate__(self, state): # mandatory return None - def getIcon(self): #optional + def getIcon(self): # optional return ":/icons/Path-Stop.svg" - def onChanged(self,vobj,prop): #optional + def onChanged(self, vobj, prop): # optional mode = 2 - vobj.setEditorMode('LineWidth',mode) - vobj.setEditorMode('MarkerColor',mode) - vobj.setEditorMode('NormalColor',mode) - vobj.setEditorMode('ShowFirstRapid',mode) - vobj.setEditorMode('DisplayMode',mode) - vobj.setEditorMode('BoundingBox',mode) - vobj.setEditorMode('Selectable',mode) - vobj.setEditorMode('ShapeColor',mode) - vobj.setEditorMode('Transparency',mode) - vobj.setEditorMode('Visibility',mode) + vobj.setEditorMode('LineWidth', mode) + vobj.setEditorMode('MarkerColor', mode) + vobj.setEditorMode('NormalColor', mode) + vobj.setEditorMode('ShowFirstRapid', mode) + vobj.setEditorMode('DisplayMode', mode) + vobj.setEditorMode('BoundingBox', mode) + vobj.setEditorMode('Selectable', mode) + vobj.setEditorMode('ShapeColor', mode) + vobj.setEditorMode('Transparency', mode) + vobj.setEditorMode('Visibility', mode) class CommandPathStop: + def GetResources(self): - return {'Pixmap' : 'Path-Stop', - 'MenuText': QtCore.QT_TRANSLATE_NOOP("Path_Stop","Stop"), + return {'Pixmap': 'Path-Stop', + 'MenuText': QtCore.QT_TRANSLATE_NOOP("Path_Stop", "Stop"), 'Accel': "P, C", - 'ToolTip': QtCore.QT_TRANSLATE_NOOP("Path_Stop","Add Optional or Mandatory Stop to the program")} + 'ToolTip': QtCore.QT_TRANSLATE_NOOP("Path_Stop", "Add Optional or Mandatory Stop to the program")} def IsActive(self): - return not FreeCAD.ActiveDocument is None + if FreeCAD.ActiveDocument is not None: + for o in FreeCAD.ActiveDocument.Objects: + if o.Name[:3] == "Job": + return True + return False def Activated(self): - FreeCAD.ActiveDocument.openTransaction(translate("Path_Stop","Add Optional or Mandatory Stop to the program")) + FreeCAD.ActiveDocument.openTransaction( + translate("Path_Stop", "Add Optional or Mandatory Stop to the program")) FreeCADGui.addModule("PathScripts.PathStop") snippet = ''' import Path @@ -129,15 +136,15 @@ def Activated(self): PathScripts.PathStop.Stop(obj) PathScripts.PathStop._ViewProviderStop(obj.ViewObject) -PathUtils.addToProject(obj) +PathUtils.addToJob(obj) ''' FreeCADGui.doCommand(snippet) FreeCAD.ActiveDocument.commitTransaction() FreeCAD.ActiveDocument.recompute() -if FreeCAD.GuiUp: +if FreeCAD.GuiUp: # register the FreeCAD command - FreeCADGui.addCommand('Path_Stop',CommandPathStop()) + FreeCADGui.addCommand('Path_Stop', CommandPathStop()) FreeCAD.Console.PrintLog("Loading PathStop... done\n") diff --git a/src/Mod/Path/PathScripts/PathSurface.py b/src/Mod/Path/PathScripts/PathSurface.py index b49319bea170..71fd7b2c170e 100644 --- a/src/Mod/Path/PathScripts/PathSurface.py +++ b/src/Mod/Path/PathScripts/PathSurface.py @@ -29,10 +29,6 @@ if FreeCAD.GuiUp: import FreeCADGui from PySide import QtCore, QtGui - from DraftTools import translate -else: - def translate(ctxt, txt): - return txt __title__ = "Path Surface Operation" __author__ = "sliptonic (Brad Collette)" @@ -372,7 +368,11 @@ def GetResources(self): 'ToolTip': QtCore.QT_TRANSLATE_NOOP("Path_Surface", "Creates a Path Surfacing object")} def IsActive(self): - return FreeCAD.ActiveDocument is not None + if FreeCAD.ActiveDocument is not None: + for o in FreeCAD.ActiveDocument.Objects: + if o.Name[:3] == "Job": + return True + return False def Activated(self): @@ -396,7 +396,7 @@ def Activated(self): FreeCADGui.doCommand('obj.SampleInterval = 0.4') FreeCADGui.doCommand('obj.FinalDepth=' + str(zbottom)) - FreeCADGui.doCommand('PathScripts.PathUtils.addToProject(obj)') + FreeCADGui.doCommand('PathScripts.PathUtils.addToJob(obj)') FreeCAD.ActiveDocument.commitTransaction() FreeCAD.ActiveDocument.recompute() diff --git a/src/Mod/Path/PathScripts/PathToolLenOffset.py b/src/Mod/Path/PathScripts/PathToolLenOffset.py index 7c14d078bdec..f4713a3142a2 100644 --- a/src/Mod/Path/PathScripts/PathToolLenOffset.py +++ b/src/Mod/Path/PathScripts/PathToolLenOffset.py @@ -1,41 +1,44 @@ # -*- coding: utf-8 -*- - -#*************************************************************************** -#* * -#* Copyright (c) 2015 Dan Falck * -#* * -#* This program is free software; you can redistribute it and/or modify * -#* it under the terms of the GNU Lesser General Public License (LGPL) * -#* as published by the Free Software Foundation; either version 2 of * -#* the License, or (at your option) any later version. * -#* for detail see the LICENCE text file. * -#* * -#* This program is distributed in the hope that it will be useful, * -#* but WITHOUT ANY WARRANTY; without even the implied warranty of * -#* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * -#* GNU Library General Public License for more details. * -#* * -#* You should have received a copy of the GNU Library General Public * -#* License along with this program; if not, write to the Free Software * -#* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * -#* USA * -#* * -#*************************************************************************** +# *************************************************************************** +# * * +# * Copyright (c) 2015 Dan Falck * +# * * +# * This program is free software; you can redistribute it and/or modify * +# * it under the terms of the GNU Lesser General Public License (LGPL) * +# * as published by the Free Software Foundation; either version 2 of * +# * the License, or (at your option) any later version. * +# * for detail see the LICENCE text file. * +# * * +# * This program is distributed in the hope that it will be useful, * +# * but WITHOUT ANY WARRANTY; without even the implied warranty of * +# * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * +# * GNU Library General Public License for more details. * +# * * +# * You should have received a copy of the GNU Library General Public * +# * License along with this program; if not, write to the Free Software * +# * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * +# * USA * +# * * +# *************************************************************************** ''' Used for CNC machine Tool Length Offsets ie G43H2''' -import FreeCAD,FreeCADGui,Path,PathGui -from PathScripts import PathProject,PathUtils -from PySide import QtCore,QtGui +import FreeCAD +import FreeCADGui +import Path +from PathScripts import PathUtils +from PySide import QtCore, QtGui # Qt tanslation handling try: _encoding = QtGui.QApplication.UnicodeUTF8 + def translate(context, text, disambig=None): return QtGui.QApplication.translate(context, text, disambig, _encoding) except AttributeError: def translate(context, text, disambig=None): return QtGui.QApplication.translate(context, text, disambig) + class ToolLenOffset: def __init__(self,obj): obj.addProperty("App::PropertyIntegerConstraint", "HeightNumber","HeightOffset",QtCore.QT_TRANSLATE_NOOP("App::Property","The Height offset number of the active tool")) @@ -44,13 +47,14 @@ def __init__(self,obj): obj.addProperty("App::PropertyBool","Active","HeightOffset",QtCore.QT_TRANSLATE_NOOP("App::Property","Make False, to prevent operation from generating code")) obj.Proxy = self mode = 2 - obj.setEditorMode('Placement',mode) + obj.setEditorMode('Placement', mode) - def execute(self,obj): + def execute(self, obj): - command = 'G43H'+str(obj.HeightNumber)+'G0Z'+str(obj.Height.Value) + command = 'G43H' + str(obj.HeightNumber) + \ + 'G0Z' + str(obj.Height.Value) obj.Path = Path.Path(command) - obj.Label = "Height"+str(obj.HeightNumber) + obj.Label = "Height" + str(obj.HeightNumber) if obj.Active: obj.Path = Path.Path(command) obj.ViewObject.Visibility = True @@ -59,89 +63,95 @@ def execute(self,obj): obj.ViewObject.Visibility = False # tie the HeightNumber to the PathLoadTool object ToolNumber - if len(obj.InList)>0: #check to see if obj is in the Project group yet + if len(obj.InList) > 0: # check to see if obj is in the Project group yet project = obj.InList[0] - tl = int(PathUtils.changeTool(obj,project)) - obj.HeightNumber= tl + tl = int(PathUtils.changeTool(obj, project)) + obj.HeightNumber = tl - def onChanged(self,obj,prop): + def onChanged(self, obj, prop): if prop == "HeightNumber": - obj.Label = "Height"+str(obj.HeightNumber) + obj.Label = "Height" + str(obj.HeightNumber) class _ViewProviderTLO: - def __init__(self,vobj): #mandatory + + def __init__(self, vobj): # mandatory vobj.Proxy = self mode = 2 - vobj.setEditorMode('LineWidth',mode) - vobj.setEditorMode('MarkerColor',mode) - vobj.setEditorMode('NormalColor',mode) - vobj.setEditorMode('ShowFirstRapid',mode) - vobj.setEditorMode('DisplayMode',mode) - vobj.setEditorMode('BoundingBox',mode) - vobj.setEditorMode('Selectable',mode) - vobj.setEditorMode('ShapeColor',mode) - vobj.setEditorMode('Transparency',mode) - vobj.setEditorMode('Visibility',mode) - - - def __getstate__(self): #mandatory + vobj.setEditorMode('LineWidth', mode) + vobj.setEditorMode('MarkerColor', mode) + vobj.setEditorMode('NormalColor', mode) + vobj.setEditorMode('ShowFirstRapid', mode) + vobj.setEditorMode('DisplayMode', mode) + vobj.setEditorMode('BoundingBox', mode) + vobj.setEditorMode('Selectable', mode) + vobj.setEditorMode('ShapeColor', mode) + vobj.setEditorMode('Transparency', mode) + vobj.setEditorMode('Visibility', mode) + + def __getstate__(self): # mandatory return None - def __setstate__(self,state): #mandatory + def __setstate__(self, state): # mandatory return None - def getIcon(self): #optional + def getIcon(self): # optional return ":/icons/Path-LengthOffset.svg" - def onChanged(self,vobj,prop): #optional + def onChanged(self, vobj, prop): # optional mode = 2 - vobj.setEditorMode('LineWidth',mode) - vobj.setEditorMode('MarkerColor',mode) - vobj.setEditorMode('NormalColor',mode) - vobj.setEditorMode('ShowFirstRapid',mode) - vobj.setEditorMode('DisplayMode',mode) - vobj.setEditorMode('BoundingBox',mode) - vobj.setEditorMode('Selectable',mode) - vobj.setEditorMode('ShapeColor',mode) - vobj.setEditorMode('Transparency',mode) - vobj.setEditorMode('Visibility',mode) - - def updateData(self,vobj,prop): #optional + vobj.setEditorMode('LineWidth', mode) + vobj.setEditorMode('MarkerColor', mode) + vobj.setEditorMode('NormalColor', mode) + vobj.setEditorMode('ShowFirstRapid', mode) + vobj.setEditorMode('DisplayMode', mode) + vobj.setEditorMode('BoundingBox', mode) + vobj.setEditorMode('Selectable', mode) + vobj.setEditorMode('ShapeColor', mode) + vobj.setEditorMode('Transparency', mode) + vobj.setEditorMode('Visibility', mode) + + def updateData(self, vobj, prop): # optional # this is executed when a property of the APP OBJECT changes pass - def setEdit(self,vobj,mode): #optional + def setEdit(self, vobj, mode): # optional # this is executed when the object is double-clicked in the tree pass - def unsetEdit(self,vobj,mode): #optional + def unsetEdit(self, vobj, mode): # optional # this is executed when the user cancels or terminates edit mode pass class CommandPathToolLenOffset: + def GetResources(self): - return {'Pixmap' : 'Path-LengthOffset', - 'MenuText': QtCore.QT_TRANSLATE_NOOP("Path_ToolLenOffset","Tool Length Offset"), + return {'Pixmap': 'Path-LengthOffset', + 'MenuText': QtCore.QT_TRANSLATE_NOOP("Path_ToolLenOffset", "Tool Length Offset"), 'Accel': "P, T", - 'ToolTip': QtCore.QT_TRANSLATE_NOOP("Path_ToolLenOffset","Create a Tool Length Offset object")} + 'ToolTip': QtCore.QT_TRANSLATE_NOOP("Path_ToolLenOffset", "Create a Tool Length Offset object")} def IsActive(self): - return not FreeCAD.ActiveDocument is None + if FreeCAD.ActiveDocument is not None: + for o in FreeCAD.ActiveDocument.Objects: + if o.Name[:3] == "Job": + return True + return False def Activated(self): - FreeCAD.ActiveDocument.openTransaction(translate("Path_ToolLenOffset","Create a Selection Plane object")) + FreeCAD.ActiveDocument.openTransaction( + translate("Path_ToolLenOffset", "Create a Selection Plane object")) FreeCADGui.addModule("PathScripts.PathToolLenOffset") snippet = ''' import Path import PathScripts -from PathScripts import PathProject,PathUtils +from PathScripts import PathJob,PathUtils obj = FreeCAD.ActiveDocument.addObject("Path::FeaturePython","HeightOffset") PathScripts.PathToolLenOffset.ToolLenOffset(obj) obj.Active = True PathScripts.PathToolLenOffset._ViewProviderTLO(obj.ViewObject) -project = PathUtils.addToProject(obj) +project = PathUtils.addToJob(obj) tl = PathUtils.changeTool(obj,project) if tl: @@ -153,12 +163,8 @@ def Activated(self): FreeCAD.ActiveDocument.commitTransaction() FreeCAD.ActiveDocument.recompute() -if FreeCAD.GuiUp: +if FreeCAD.GuiUp: # register the FreeCAD command FreeCADGui.addCommand('Path_ToolLenOffset', CommandPathToolLenOffset()) - -FreeCAD.Console.PrintLog("Loading PathToolLenOffset... done\n") - - - +FreeCAD.Console.PrintLog("Loading PathToolLenOffset... done\n") diff --git a/src/Mod/Path/PathScripts/PathToolLibraryManager.py b/src/Mod/Path/PathScripts/PathToolLibraryManager.py new file mode 100644 index 000000000000..a2ac92922ef2 --- /dev/null +++ b/src/Mod/Path/PathScripts/PathToolLibraryManager.py @@ -0,0 +1,593 @@ +# -*- coding: utf-8 -*- + +# *************************************************************************** +# * * +# * Copyright (c) 2014 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) * +# * as published by the Free Software Foundation; either version 2 of * +# * the License, or (at your option) any later version. * +# * for detail see the LICENCE text file. * +# * * +# * This program is distributed in the hope that it will be useful, * +# * but WITHOUT ANY WARRANTY; without even the implied warranty of * +# * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * +# * GNU Library General Public License for more details. * +# * * +# * You should have received a copy of the GNU Library General Public * +# * License along with this program; if not, write to the Free Software * +# * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * +# * USA * +# * * +# *************************************************************************** + +import FreeCAD +import xml.sax +import FreeCADGui +import Path +import os +from PySide import QtCore, QtGui + +try: + _encoding = QtGui.QApplication.UnicodeUTF8 + + def _translate(context, text, disambig): + return QtGui.QApplication.translate(context, text, disambig, _encoding) +except AttributeError: + def _translate(context, text, disambig): + return QtGui.QApplication.translate(context, text, disambig) + + +# Tooltable XML readers +class FreeCADTooltableHandler(xml.sax.ContentHandler): + # http://www.tutorialspoint.com/python/python_xml_processing.htm + + def __init__(self): + self.tooltable = None + self.tool = None + self.number = None + + # Call when an element is found + def startElement(self, tag, attributes): + if tag == "Tooltable": + self.tooltable = Path.Tooltable() + elif tag == "Toolslot": + self.number = int(attributes["number"]) + elif tag == "Tool": + self.tool = Path.Tool() + self.tool.Name = str(attributes["name"]) + self.tool.ToolType = str(attributes["type"]) + self.tool.Material = str(attributes["mat"]) + # for some reason without the following line I get an error + #print attributes["diameter"] + self.tool.Diameter = float(attributes["diameter"]) + self.tool.LengthOffset = float(attributes["length"]) + self.tool.FlatRadius = float(attributes["flat"]) + self.tool.CornerRadius = float(attributes["corner"]) + self.tool.CuttingEdgeAngle = float(attributes["angle"]) + self.tool.CuttingEdgeHeight = float(attributes["height"]) + + # Call when an elements ends + def endElement(self, tag): + if tag == "Toolslot": + if self.tooltable and self.tool and self.number: + self.tooltable.setTool(self.number, self.tool) + self.number = None + self.tool = None + + +class HeeksTooltableHandler(xml.sax.ContentHandler): + + def __init__(self): + self.tooltable = Path.Tooltable() + self.tool = None + self.number = None + + # Call when an element is found + def startElement(self, tag, attributes): + if tag == "Tool": + self.tool = Path.Tool() + self.number = int(attributes["tool_number"]) + self.tool.Name = str(attributes["title"]) + elif tag == "params": + t = str(attributes["type"]) + if t == "drill": + self.tool.ToolType = "Drill" + elif t == "center_drill_bit": + self.tool.ToolType = "CenterDrill" + elif t == "end_mill": + self.tool.ToolType = "EndMill" + elif t == "slot_cutter": + self.tool.ToolType = "SlotCutter" + elif t == "ball_end_mill": + self.tool.ToolType = "BallEndMill" + elif t == "chamfer": + self.tool.ToolType = "Chamfer" + elif t == "engraving_bit": + self.tool.ToolType = "Engraver" + m = str(attributes["material"]) + if m == "0": + self.tool.Material = "HighSpeedSteel" + elif m == "1": + self.tool.Material = "Carbide" + # for some reason without the following line I get an error + #print attributes["diameter"] + self.tool.Diameter = float(attributes["diameter"]) + self.tool.LengthOffset = float(attributes["tool_length_offset"]) + self.tool.FlatRadius = float(attributes["flat_radius"]) + self.tool.CornerRadius = float(attributes["corner_radius"]) + self.tool.CuttingEdgeAngle = float( + attributes["cutting_edge_angle"]) + self.tool.CuttingEdgeHeight = float( + attributes["cutting_edge_height"]) + + # Call when an elements ends + def endElement(self, tag): + if tag == "Tool": + if self.tooltable and self.tool and self.number: + self.tooltable.setTool(self.number, self.tool) + self.number = None + self.tool = None + + +class ToolLibraryManager(): + ''' + The Tool Library is a list of individual tool tables. Each + Tool Table can contain n tools. The tool library will be persisted to user + preferences and all or part of the library can be exported to other formats + ''' + + def __init__(self): + self.ToolLibrary = [] + self.prefs = FreeCAD.ParamGet("User parameter:BaseApp/Preferences/Mod/Path") + return + + def saveMainLibrary(self, tooltable): + '''Persists the permanent library to FreeCAD user preferences''' + tmpstring = tooltable.Content + self.prefs.SetString("ToolLibrary", tmpstring) + return True + + def getLists(self): + '''Builds the list of all Tool Table lists''' + tablelist = [] + toollist = "
" + tablelist.append(toollist) + + # Get ToolTables from any open CNC jobs + for o in FreeCAD.ActiveDocument.Objects: + if "Proxy" in o.PropertiesList: + if hasattr(o, "Tooltable"): + toollist = o.Label + tablelist.append(toollist) + return tablelist + + def _findList(self, listname): + tt = None + if listname == "
": + tmpstring = self.prefs.GetString("ToolLibrary", "") + if tmpstring != "": + Handler = FreeCADTooltableHandler() + xml.sax.parseString(tmpstring, Handler) + tt = Handler.tooltable + else: + tt = Path.Tooltable() + else: + for o in FreeCAD.ActiveDocument.Objects: + if o.Label == listname: + tt = o.Tooltable + return tt + + def getTool(self, listname, toolnum): + tt = self._findList(listname) + return tt.getTool(toolnum) + + def getTools(self, tablename): + '''returns the tool data for a given table''' + tooldata = [] + tt = self._findList(tablename) + headers = ["","Tool Num.","Name","Tool Type","Material","Diameter","Length Offset","Flat Radius","Corner Radius","Cutting Edge Angle","Cutting Edge Height"] + model = QtGui.QStandardItemModel() + model.setHorizontalHeaderLabels(headers) + if tt: + if len(tt.Tools) == 0: + tooldata.append([]) + for number, t in tt.Tools.iteritems(): + + itemcheck = QtGui.QStandardItem() + itemcheck.setCheckable(True) + itemNumber = QtGui.QStandardItem(str(number)) + itemName = QtGui.QStandardItem(t.Name) + itemToolType = QtGui.QStandardItem(t.ToolType) + itemMaterial = QtGui.QStandardItem(t.Material) + itemDiameter = QtGui.QStandardItem(str(t.Diameter)) + itemLengthOffset = QtGui.QStandardItem(str(t.LengthOffset)) + itemFlatRadius = QtGui.QStandardItem(str(t.FlatRadius)) + itmCornerRadius = QtGui.QStandardItem(str(t.CornerRadius)) + itemCuttingEdgeAngle = QtGui.QStandardItem(str(t.CuttingEdgeAngle)) + itemCuttingEdgeHeight = QtGui.QStandardItem(str(t.CuttingEdgeHeight)) + + row = [itemcheck, itemNumber, itemName, itemToolType, itemMaterial, itemDiameter, itemLengthOffset, itemFlatRadius, itmCornerRadius, itemCuttingEdgeAngle, itemCuttingEdgeHeight] + model.appendRow(row) + + return model + + # methods for importing and exporting + def read(self, filename, listname): + "imports a tooltable from a file" + parser = xml.sax.make_parser() + parser.setFeature(xml.sax.handler.feature_namespaces, 0) + if os.path.splitext(filename[0])[1].lower() == ".tooltable": + Handler = HeeksTooltableHandler() + else: + Handler = FreeCADTooltableHandler() + parser.setContentHandler(Handler) + parser.parse(str(filename[0])) + if not Handler.tooltable: + return None + + ht = Handler.tooltable + tt = self._findList(listname) + for t in ht.Tools: + newt = ht.getTool(t).copy() + tt.addTools(newt) + if listname == "
": + self.saveMainLibrary(tt) + return True + + def write(self, filename, listname): + "exports the tooltable to a file" + tt = self._findList(listname) + if tt: + fil = open(str(filename[0]), "wb") + fil.write('\n') + fil.write(tt.Content) + fil.close() + print "Written ", filename[0] + + def addnew(self, listname, tool, position = None): + "adds a new tool at the end of the table" + tt = self._findList(listname) + if position is None: + tt.addTools(tool) + newID = tt.Tools.keys()[-1] + else: + tt.setTool(position, tool) + newID = position + + if listname == "
": + return self.saveMainLibrary(tt) + return newID + + def updateTool(self, listname, toolnum, tool): + '''updates tool data''' + tt = self._findList(listname) + tt.deleteTool(toolnum) + tt.setTool(toolnum, tool) + if listname == "
": + return self.saveMainLibrary(tt) + return True + + def moveup(self, number, listname): + "moves a tool to a lower number, if possible" + if number < 2: + return False + target = number - 1 + tt = self._findList(listname) + + t1 = tt.getTool(number).copy() + tt.deleteTool(number) + if target in tt.Tools.keys(): + t2 = tt.getTool(target).copy() + tt.deleteTool(target) + tt.setTool(number, t2) + tt.setTool(target, t1) + if listname == "
": + self.saveMainLibrary(tt) + return True + + def movedown(self, number, listname): + "moves a tool to a higher number, if possible" + tt = self._findList(listname) + target = number + 1 + t1 = tt.getTool(number).copy() + tt.deleteTool(number) + if target in tt.Tools.keys(): + t2 = tt.getTool(target).copy() + tt.deleteTool(target) + tt.setTool(number, t2) + tt.setTool(target, t1) + if listname == "
": + self.saveMainLibrary(tt) + return True + + def delete(self, number, listname): + '''deletes a tool from the current list''' + tt = self._findList(listname) + tt.deleteTool(number) + if listname == "
": + self.saveMainLibrary(tt) + return True + + def createToolController(self, job, tool): + pass + + def exportListHeeks(self, tooltable): + '''exports one or more Lists as a HeeksCNC tooltable''' + pass + + def exportListLinuxCNC(self, tooltable): + '''exports one or more Lists as a LinuxCNC tooltable''' + pass + + def exportListXML(self, tooltable): + '''exports one or more Lists as an XML file''' + pass + +class EditorPanel(): + + def __init__(self): + #self.form = FreeCADGui.PySideUic.loadUi(FreeCAD.getHomePath() + "Mod/Path/ToolLibraryEditor.ui") + self.form = FreeCADGui.PySideUic.loadUi(":/panels/ToolLibraryEditor.ui") + #self.editform = FreeCADGui.PySideUic.loadUi(FreeCAD.getHomePath() + "Mod/Path/ToolEdit.ui") + self.editform = FreeCADGui.PySideUic.loadUi(":/panels/ToolEdit.ui") + self.TLM = ToolLibraryManager() + + data = self.TLM.getLists() + self.listmodel = QtGui.QStandardItemModel(self.form.listView) +# self.listmodel = QtGui.QStringListModel(data) + for i in data: + item = QtGui.QStandardItem(i) + self.listmodel.appendRow(item) + + self.form.listView.setModel(self.listmodel) + #self.form.listView.setCurrentIndex(0) + self.form.ToolsList.resizeColumnsToContents() + + def accept(self): + pass + + def reject(self): + FreeCADGui.Control.closeDialog() + FreeCAD.ActiveDocument.recompute() + + def getFields(self): + pass + + def getType(self, tooltype): + "gets a combobox index number for a given type or viceversa" + toolslist = ["Drill", "CenterDrill", "CounterSink", "CounterBore", + "Reamer", "Tap", "EndMill", "SlotCutter", "BallEndMill", + "ChamferMill", "CornerRound", "Engraver"] + if isinstance(tooltype, str): + if tooltype in toolslist: + return toolslist.index(tooltype) + 1 + else: + return 0 + else: + if tooltype == 0: + return "Undefined" + else: + return toolslist[tooltype - 1] + + def getMaterial(self, material): + "gets a combobox index number for a given material or viceversa" + matslist = ["HighSpeedSteel", "HighCarbonToolSteel", "CastAlloy", + "Carbide", "Ceramics", "Diamond", "Sialon"] + if isinstance(material, str): + if material in matslist: + return matslist.index(material) + 1 + else: + return 0 + else: + if material == 0: + return "Undefined" + else: + return matslist[material - 1] + + def addTool(self): + t = Path.Tool() + print (t) + editform = FreeCADGui.PySideUic.loadUi(":/panels/ToolEdit.ui") + r = editform.exec_() + if r: + if editform.NameField.text(): + t.Name = str(editform.NameField.text()) + t.ToolType = self.getType(editform.TypeField.currentIndex()) + t.Material = self.getMaterial(editform.MaterialField.currentIndex()) + t.Diameter = editform.DiameterField.value() + t.LengthOffset = editform.LengthOffsetField.value() + t.FlatRadius = editform.FlatRadiusField.value() + t.CornerRadius = editform.CornerRadiusField.value() + t.CuttingEdgeAngle = editform.CuttingEdgeAngleField.value() + t.CuttingEdgeHeight = editform.CuttingEdgeHeightField.value() + + listname = self.form.listView.selectedIndexes()[0].data() + if self.TLM.addnew(listname, t) is True: + self.loadTable(self.form.listView.selectedIndexes()[0]) + + def setFields(self): + index = self.listmodel.index(0, 0, QtCore.QModelIndex()) + self.form.listView.setFocus() + sm = self.form.listView.selectionModel() + sm.select(index, sm.Select) + + def open(self): + pass + + def loadTable(self, curr): + tooldata = self.TLM.getTools(curr.data()) + self.form.ToolsList.setModel(tooldata) + + def moveUp(self): + "moves a tool to a lower number, if possible" + item = self.form.ToolsList.selectedIndexes()[1].data() + if item: + number = int(item) + listname = self.form.listView.selectedIndexes()[0].data() + + if self.TLM.moveup(number, listname) is True: + self.loadTable(self.form.listView.selectedIndexes()[0]) + + def moveDown(self): + "moves a tool to a higher number, if possible" + item = self.form.ToolsList.selectedIndexes()[1].data() + if item: + number = int(item) + listname = self.form.listView.selectedIndexes()[0].data() + if self.TLM.movedown(number, listname) is True: + self.loadTable(self.form.listView.selectedIndexes()[0]) + + def delete(self): + '''deletes a tool''' + item = self.form.ToolsList.selectedIndexes()[1].data() + if item: + number = int(item) + listname = self.form.listView.selectedIndexes()[0].data() + if self.TLM.delete(number, listname) is True: + self.loadTable(self.form.listView.selectedIndexes()[0]) + + def editTool(self, currItem): + row = currItem.row() + value = currItem.sibling(row, 1).data() + listname = self.form.listView.selectedIndexes()[0].data() + toolnum = int(value) + tool = self.TLM.getTool(listname, toolnum) + editform = FreeCADGui.PySideUic.loadUi(":/panels/ToolEdit.ui") + + editform.NameField.setText(tool.Name) + editform.TypeField.setCurrentIndex(self.getType(tool.ToolType)) + editform.MaterialField.setCurrentIndex(self.getMaterial(tool.Material)) + editform.DiameterField.setValue(tool.Diameter) + editform.LengthOffsetField.setValue(tool.LengthOffset) + editform.FlatRadiusField.setValue(tool.FlatRadius) + editform.CornerRadiusField.setValue(tool.CornerRadius) + editform.CuttingEdgeAngleField.setValue(tool.CuttingEdgeAngle) + editform.CuttingEdgeHeightField.setValue(tool.CuttingEdgeHeight) + + r = editform.exec_() + if r: + if editform.NameField.text(): + tool.Name = str(editform.NameField.text()) + tool.ToolType = self.getType(editform.TypeField.currentIndex()) + tool.Material = self.getMaterial(editform.MaterialField.currentIndex()) + tool.Diameter = editform.DiameterField.value() + tool.LengthOffset = editform.LengthOffsetField.value() + tool.FlatRadius = editform.FlatRadiusField.value() + tool.CornerRadius = editform.CornerRadiusField.value() + tool.CuttingEdgeAngle = editform.CuttingEdgeAngleField.value() + tool.CuttingEdgeHeight = editform.CuttingEdgeHeightField.value() + + if self.TLM.updateTool(listname, toolnum, tool) is True: + self.loadTable(self.form.listView.selectedIndexes()[0]) + + def importFile(self): + "imports a tooltable from a file" + filename = QtGui.QFileDialog.getOpenFileName(self.form, _translate( + "TooltableEditor", "Open tooltable", None), None, _translate("TooltableEditor", "Tooltable XML (*.xml);;HeeksCAD tooltable (*.tooltable)", None)) + if filename: + listname = self.form.listView.selectedIndexes()[0].data() + if self.TLM.read(filename, listname): + self.loadTable(self.form.listView.selectedIndexes()[0]) + + + def exportFile(self): + "imports a tooltable from a file" + filename = QtGui.QFileDialog.getSaveFileName(self.form, _translate("TooltableEditor", "Save tooltable", None), None, _translate("TooltableEditor", "Tooltable XML (*.xml)", None)) + + if filename: + listname = self.form.listView.selectedIndexes()[0].data() + self.TLM.write(filename, listname) + + def copyTools(self): + tools = [] + model = self.form.ToolsList.model() + for i in range(model.rowCount()): + item = model.item(i, 0) + if item.checkState(): + item = model.index(i, 1) + tools.append(item.data()) + if len(tools) == 0: + return + + targets = self.TLM.getLists() + currList = self.form.listView.selectedIndexes()[0].data() + + for target in targets: + if target == currList: + targets.remove(target) + + if len(targets) == 0: + FreeCAD.Console.PrintWarning("no place to go") + return + + else: + form = FreeCADGui.PySideUic.loadUi(":/panels/DlgToolCopy.ui") + form.cboTarget.addItems(targets) + r = form.exec_() + if r is False: + return None + else: + targetlist = form.cboTarget.currentText() + for toolnum in tools: + tool = self.TLM.getTool(currList, int(toolnum)) + newtoolid = self.TLM.addnew(targetlist, tool.copy(), int(toolnum)) + if form.chkMakeController.checkState() == QtCore.Qt.CheckState.Checked and targetlist != "
": + snippet = ''' +import Path, PathScripts +from PathScripts import PathUtils, PathLoadTool +obj = FreeCAD.ActiveDocument.addObject("Path::FeaturePython","TC") +PathScripts.PathLoadTool.LoadTool(obj) +PathScripts.PathLoadTool._ViewProviderLoadTool(obj.ViewObject) +obj.ToolNumber = %d +PathUtils.addToJob(obj, "%s") +App.activeDocument().recompute() +''' % (newtoolid, targetlist) + FreeCADGui.doCommand(snippet) + + def getStandardButtons(self): + return int(QtGui.QDialogButtonBox.Ok) + + def setupUi(self): + # Connect Signals and Slots + self.form.ButtonNewTool.clicked.connect(self.addTool) + #self.form.listWidget.currentItemChanged.connect(self.loadTable) + sm = self.form.listView.selectionModel() + sm.currentChanged.connect(self.loadTable) + self.form.ButtonImport.clicked.connect(self.importFile) + self.form.ButtonExport.clicked.connect(self.exportFile) + self.form.ButtonDown.clicked.connect(self.moveDown) + self.form.ButtonUp.clicked.connect(self.moveUp) + self.form.ButtonDelete.clicked.connect(self.delete) + self.form.ToolsList.doubleClicked.connect(self.editTool) + self.form.btnCopyTools.clicked.connect(self.copyTools) + + self.setFields() + +class CommandToolLibraryEdit(): + def edit(self): + editor = EditorPanel() + editor.setupUi() + + r = editor.form.exec_() + if r: + pass + + def GetResources(self): + return {'Pixmap' : 'Path-ToolTable', + 'MenuText': QtCore.QT_TRANSLATE_NOOP("Path_ToolTable","Edit the Tool Library"), + 'ToolTip': QtCore.QT_TRANSLATE_NOOP("Path_ToolTable","Edit the Tool Library")} + + def IsActive(self): + return not FreeCAD.ActiveDocument is None + + def Activated(self): + + self.edit() + + +if FreeCAD.GuiUp: + # register the FreeCAD command + FreeCADGui.addCommand('Path_ToolLibraryEdit',CommandToolLibraryEdit()) + diff --git a/src/Mod/Path/PathScripts/PathToolTableEdit.py b/src/Mod/Path/PathScripts/PathToolTableEdit.py index debc9b4b53ec..2aa59b587ae4 100644 --- a/src/Mod/Path/PathScripts/PathToolTableEdit.py +++ b/src/Mod/Path/PathScripts/PathToolTableEdit.py @@ -1,62 +1,79 @@ # -*- coding: utf-8 -*- -#*************************************************************************** -#* * -#* Copyright (c) 2015 Dan Falck * -#* * -#* This program is free software; you can redistribute it and/or modify * -#* it under the terms of the GNU Lesser General Public License (LGPL) * -#* as published by the Free Software Foundation; either version 2 of * -#* the License, or (at your option) any later version. * -#* for detail see the LICENCE text file. * -#* * -#* This program is distributed in the hope that it will be useful, * -#* but WITHOUT ANY WARRANTY; without even the implied warranty of * -#* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * -#* GNU Library General Public License for more details. * -#* * -#* You should have received a copy of the GNU Library General Public * -#* License along with this program; if not, write to the Free Software * -#* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * -#* USA * -#* * -#*************************************************************************** - -import FreeCAD,FreeCADGui -from PySide import QtCore,QtGui +# *************************************************************************** +# * * +# * Copyright (c) 2015 Dan Falck * +# * * +# * This program is free software; you can redistribute it and/or modify * +# * it under the terms of the GNU Lesser General Public License (LGPL) * +# * as published by the Free Software Foundation; either version 2 of * +# * the License, or (at your option) any later version. * +# * for detail see the LICENCE text file. * +# * * +# * This program is distributed in the hope that it will be useful, * +# * but WITHOUT ANY WARRANTY; without even the implied warranty of * +# * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * +# * GNU Library General Public License for more details. * +# * * +# * You should have received a copy of the GNU Library General Public * +# * License along with this program; if not, write to the Free Software * +# * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * +# * USA * +# * * +# *************************************************************************** + +import FreeCAD +import FreeCADGui +from PySide import QtCore, QtGui # Qt tanslation handling try: _encoding = QtGui.QApplication.UnicodeUTF8 + def translate(context, text, disambig=None): return QtGui.QApplication.translate(context, text, disambig, _encoding) except AttributeError: def translate(context, text, disambig=None): return QtGui.QApplication.translate(context, text, disambig) + class CommandPathToolTableEdit: + def GetResources(self): - return {'Pixmap' : 'Path-ToolTable', - 'MenuText': QtCore.QT_TRANSLATE_NOOP("Path_ToolTableEdit","EditToolTable"), + return {'Pixmap': 'Path-ToolTable', + 'MenuText': QtCore.QT_TRANSLATE_NOOP("Path_ToolTableEdit", "EditToolTable"), 'Accel': "P, T", - 'ToolTip': QtCore.QT_TRANSLATE_NOOP("Path_ToolTableEdit","Edits a Tool Table in a selected Project")} + 'ToolTip': QtCore.QT_TRANSLATE_NOOP("Path_ToolTableEdit", "Edits a Tool Table in a selected Project")} def IsActive(self): - return not FreeCAD.ActiveDocument is None + return FreeCAD.ActiveDocument is not None def Activated(self): - FreeCAD.ActiveDocument.openTransaction(translate("Path_ToolTableEdit","Edits a Tool Table in a selected Project")) - FreeCADGui.doCommand("from PathScripts import TooltableEditor") - FreeCADGui.doCommand("from PathScripts import PathUtils") - FreeCADGui.doCommand('machine = PathUtils.findMachine()') - FreeCADGui.doCommand('TooltableEditor.edit(machine.Name)') + FreeCAD.ActiveDocument.openTransaction( + translate("Path_ToolTableEdit", "Edits a Tool Table in a selected Project")) + snippet = ''' +from PathScripts import TooltableEditor +from PathScripts import PathUtils +sel = Gui.Selection.getSelectionEx()[0] +obj=sel.Object +if "Tooltable" in obj.PropertiesList: + TooltableEditor.edit(obj.Name) +''' + FreeCADGui.doCommand(snippet) + + # FreeCADGui.doCommand("from PathScripts import TooltableEditor") + # FreeCADGui.doCommand("from PathScripts import PathUtils") + # FreeCADGui.doCommand("sel = Gui.Selection.getSelectionEx()[0]") + # FreeCADGui.doCommand("obj=sel.Object") + # FreeCADGui.doCommand('job = PathUtils.findParentJob(obj)') + # FreeCADGui.doCommand('TooltableEditor.edit(job.Name)') FreeCAD.ActiveDocument.commitTransaction() FreeCAD.ActiveDocument.recompute() -if FreeCAD.GuiUp: + +if FreeCAD.GuiUp: # register the FreeCAD command - FreeCADGui.addCommand('Path_ToolTableEdit',CommandPathToolTableEdit()) + FreeCADGui.addCommand('Path_ToolTableEdit', CommandPathToolTableEdit()) FreeCAD.Console.PrintLog("Loading PathToolTableEdit... done\n") - diff --git a/src/Mod/Path/PathScripts/PathUtils.py b/src/Mod/Path/PathScripts/PathUtils.py index 5fa057cf508c..588d4e75ba25 100644 --- a/src/Mod/Path/PathScripts/PathUtils.py +++ b/src/Mod/Path/PathScripts/PathUtils.py @@ -23,6 +23,7 @@ # *************************************************************************** '''PathUtils -common functions used in PathScripts for filterig, sorting, and generating gcode toolpath data ''' import FreeCAD +import FreeCADGui import Part import math import Path @@ -30,9 +31,9 @@ from DraftGeomUtils import findWires import DraftVecUtils import PathScripts -from PathScripts import PathProject +from PathScripts import PathJob import itertools - +from PySide import QtGui def cleanedges(splines, precision): '''cleanedges([splines],precision). Convert BSpline curves, Beziers, to arcs that can be used for cnc paths. @@ -240,16 +241,6 @@ def edge_to_path(lastpt, edge, Z): endpt = arcstartpt center = edge.Curve.Center relcenter = center.sub(lastpt) - - # start point and end point fall together in the given output precision? - if fmt(startpt.x) == fmt(endpt.x) and fmt(startpt.y) == fmt(endpt.y): - if edge.Length < 0.5 * 2 * math.pi * edge.Curve.Radius: - # because it is a very small circle -> omit, as that gcode would produce a full circle - return endpt, "" - else: - # it is an actual full circle, emit a line for this - pass - # FreeCAD.Console.PrintMessage("arc startpt= " + str(startpt)+ "\n") # FreeCAD.Console.PrintMessage("arc midpt= " + str(midpt)+ "\n") # FreeCAD.Console.PrintMessage("arc endpt= " + str(endpt)+ "\n") @@ -387,12 +378,9 @@ def SortPath(wire, Side, radius, clockwise, firstedge=None, SegLen=0.5): sortededges = Part.__sortEdges__(edgelist) newwire = findWires(sortededges)[0] - print "newwire is clockwise: " + str(is_clockwise(newwire)) if is_clockwise(newwire) is not clockwise: newwire.reverse() - print "newwire is clockwise: " + str(is_clockwise(newwire)) - if Side == 'Left': # we use the OCC offset feature offset = newwire.makeOffset(radius) # tool is outside line @@ -403,9 +391,7 @@ def SortPath(wire, Side, radius, clockwise, firstedge=None, SegLen=0.5): offset = newwire.makeOffset(0.0) else: offset = newwire - print "offset wire is clockwise: " + str(is_clockwise(offset)) offset.reverse() - print "offset wire is clockwise: " + str(is_clockwise(offset)) return offset @@ -455,9 +441,9 @@ def MakePath(wire, Side, radius, clockwise, ZClearance, StepDown, ZStart, ZFinal # numbers/height offset numbers based on previously active toolnumbers -def changeTool(obj, proj): +def changeTool(obj, job): tlnum = 0 - for p in proj.Group: + for p in job.Group: if not hasattr(p, "Group"): if isinstance(p.Proxy, PathScripts.PathLoadTool.LoadTool) and p.ToolNumber > 0: tlnum = p.ToolNumber @@ -470,16 +456,14 @@ def changeTool(obj, proj): if g == obj: return tlnum - def getLastTool(obj): toolNum = obj.ToolNumber if obj.ToolNumber == 0: # find tool from previous toolchange - proj = findProj() - toolNum = changeTool(obj, proj) + job = findJob() + toolNum = changeTool(obj, job) return getTool(obj, toolNum) - def getLastToolLoad(obj): # This walks up the hierarchy and tries to find the closest preceding # toolchange. @@ -523,51 +507,68 @@ def getLastToolLoad(obj): continue return tc - def getTool(obj, number=0): "retrieves a tool from a hosting object with a tooltable, if any" for o in obj.InList: if o.TypeId == "Path::FeatureCompoundPython": - for m in o.Group: - if hasattr(m, "Tooltable"): - return m.Tooltable.getTool(number) - # not found? search one level up - for o in obj.InList: - return getTool(o, number) + if hasattr(o, "Tooltable"): + return o.Tooltable.getTool(number) return None +def findParentJob(obj): + '''retrieves a parent job object for an operation or other Path object''' + for i in obj.InList: + if isinstance(i.Proxy, PathScripts.PathJob.ObjectPathJob): + return i + return None -def findProj(): +def GetJobs(jobname = None): + '''returns all jobs in the current document. If name is given, returns that job''' + jobs = [] for o in FreeCAD.ActiveDocument.Objects: if "Proxy" in o.PropertiesList: - if isinstance(o.Proxy, PathProject.ObjectPathProject): - return o + if isinstance(o.Proxy, PathJob.ObjectPathJob): + if jobname is not None: + if o.Name == jobname: + jobs.append(o) + else: + jobs.append(o) + return jobs + +def addToJob(obj, jobname = None): + if jobname is not None: + jobs = GetJobs(jobname) + if len(jobs) == 1: + job = jobs[0] + else: + FreeCAD.Console.PrintError("Didn't find the job") + return None + else: + jobs = GetJobs() + if len(jobs) == 0: + job = PathJob.CommandJob.Create() -def findMachine(): - '''find machine object for the tooltable editor ''' - for o in FreeCAD.ActiveDocument.Objects: - if "Proxy" in o.PropertiesList: - if isinstance(o.Proxy, PathScripts.PathMachine.Machine): - return o - - -def addToProject(obj): - """Adds a path obj to this document, if no PathParoject exists it's created on the fly""" - p = FreeCAD.ParamGet("User parameter:BaseApp/Preferences/Mod/Path") - if p.GetBool("pathAutoProject", True): - project = findProj() - if not project: - project = PathProject.CommandProject.Create() - g = project.Group - g.append(obj) - project.Group = g - return project - return None + elif len(jobs) == 1: + job = jobs[0] + else: + form = FreeCADGui.PySideUic.loadUi(FreeCAD.getHomePath() + "Mod/Path/DlgJobChooser.ui") + mylist = [i.Name for i in jobs] + form.cboProject.addItems(mylist) + r = form.exec_() + if r is False: + return None + else: + print form.cboProject.currentText() + job = [i for i in jobs if i.Name == form.cboProject.currentText()][0] + g = job.Group + g.append(obj) + job.Group = g + return job def getLastZ(obj): - ''' find the last z value in the project ''' + ''' find the last z value in the job ''' lastZ = "" for g in obj.Group: for c in g.Path.Commands: @@ -576,30 +577,6 @@ def getLastZ(obj): lastZ = c.Parameters['Z'] return lastZ - -def frange(start, stop, step, finish): - x = [] - curdepth = start - if step == 0: - return x - # do the base cuts until finishing round - while curdepth >= stop + step + finish: - curdepth = curdepth - step - if curdepth <= stop + finish: - curdepth = stop + finish - x.append(curdepth) - - # we might have to do a last pass or else finish round might be too far - # away - if curdepth - stop > finish: - x.append(stop + finish) - - # do the the finishing round - if curdepth >= stop: - curdepth = stop - x.append(curdepth) - - return x def rapid(x=None, y=None, z=None): """ Returns gcode string to perform a rapid move.""" retstr = "G00" @@ -772,6 +749,7 @@ def rampPlunge(edge, rampangle, destZ, startZ): class depth_params: + '''calculates the intermediate depth values for various operations given the starting, ending, and stepdown parameters''' def __init__(self, clearance_height, rapid_safety_space, start_depth, step_down, z_finish_depth, final_depth, user_depths=None): self.clearance_height = clearance_height diff --git a/src/Mod/Path/PathScripts/ToolAdd.ui b/src/Mod/Path/PathScripts/ToolAdd.ui new file mode 100644 index 000000000000..ac93c772ed41 --- /dev/null +++ b/src/Mod/Path/PathScripts/ToolAdd.ui @@ -0,0 +1,190 @@ + + + Dialog + + + + 0 + 0 + 423 + 435 + + + + Dialog + + + + + + Tool Properties + + + + QFormLayout::AllNonFixedFieldsGrow + + + + + Name + + + + + + + + + + Type + + + + + + + + + + Material + + + + + + + + + + Diameter + + + + + + + mm + + + + + + + Length Offset + + + + + + + mm + + + + + + + Flat Radius + + + + + + + mm + + + + + + + Corner Radius + + + + + + + mm + + + + + + + Cutting Edge Angle + + + + + + + ° + + + + + + + Cutting Edge Height + + + + + + + mm + + + + + + + + + + Qt::Horizontal + + + QDialogButtonBox::Cancel|QDialogButtonBox::Ok + + + + + + + + + buttonBox + accepted() + Dialog + accept() + + + 248 + 254 + + + 157 + 274 + + + + + buttonBox + rejected() + Dialog + reject() + + + 316 + 260 + + + 286 + 274 + + + + + diff --git a/src/Mod/Path/PathScripts/toollibrarymanager.py b/src/Mod/Path/PathScripts/toollibrarymanager.py new file mode 100644 index 000000000000..f161758bc6b0 --- /dev/null +++ b/src/Mod/Path/PathScripts/toollibrarymanager.py @@ -0,0 +1,242 @@ +# -*- coding: utf-8 -*- + +# *************************************************************************** +# * * +# * Copyright (c) 2014 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) * +# * as published by the Free Software Foundation; either version 2 of * +# * the License, or (at your option) any later version. * +# * for detail see the LICENCE text file. * +# * * +# * This program is distributed in the hope that it will be useful, * +# * but WITHOUT ANY WARRANTY; without even the implied warranty of * +# * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * +# * GNU Library General Public License for more details. * +# * * +# * You should have received a copy of the GNU Library General Public * +# * License along with this program; if not, write to the Free Software * +# * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * +# * USA * +# * * +# *************************************************************************** + +import FreeCAD +import xml.sax +import FreeCADGui +import Path +import Draft +import Part +import os + +from PySide import QtCore, QtGui + +try: + _encoding = QtGui.QApplication.UnicodeUTF8 + + def _translate(context, text, disambig): + return QtGui.QApplication.translate(context, text, disambig, _encoding) +except AttributeError: + def _translate(context, text, disambig): + return QtGui.QApplication.translate(context, text, disambig) + + +# Tooltable XML readers + +class FreeCADTooltableHandler(xml.sax.ContentHandler): + # http://www.tutorialspoint.com/python/python_xml_processing.htm + + def __init__(self): + self.tooltable = None + self.tool = None + self.number = None + + # Call when an element is found + def startElement(self, tag, attributes): + if tag == "Tooltable": + self.tooltable = Path.Tooltable() + elif tag == "Toolslot": + self.number = int(attributes["number"]) + elif tag == "Tool": + self.tool = Path.Tool() + self.tool.Name = str(attributes["name"]) + self.tool.ToolType = str(attributes["type"]) + self.tool.Material = str(attributes["mat"]) + # for some reason without the following line I get an error + print attributes["diameter"] + self.tool.Diameter = float(attributes["diameter"]) + self.tool.LengthOffset = float(attributes["length"]) + self.tool.FlatRadius = float(attributes["flat"]) + self.tool.CornerRadius = float(attributes["corner"]) + self.tool.CuttingEdgeAngle = float(attributes["angle"]) + self.tool.CuttingEdgeHeight = float(attributes["height"]) + + # Call when an elements ends + def endElement(self, tag): + if tag == "Toolslot": + if self.tooltable and self.tool and self.number: + self.tooltable.setTool(self.number, self.tool) + self.number = None + self.tool = None + + +class HeeksTooltableHandler(xml.sax.ContentHandler): + + def __init__(self): + self.tooltable = Path.Tooltable() + self.tool = None + self.number = None + + # Call when an element is found + def startElement(self, tag, attributes): + if tag == "Tool": + self.tool = Path.Tool() + self.number = int(attributes["tool_number"]) + self.tool.Name = str(attributes["title"]) + elif tag == "params": + t = str(attributes["type"]) + if t == "drill": + self.tool.ToolType = "Drill" + elif t == "center_drill_bit": + self.tool.ToolType = "CenterDrill" + elif t == "end_mill": + self.tool.ToolType = "EndMill" + elif t == "slot_cutter": + self.tool.ToolType = "SlotCutter" + elif t == "ball_end_mill": + self.tool.ToolType = "BallEndMill" + elif t == "chamfer": + self.tool.ToolType = "Chamfer" + elif t == "engraving_bit": + self.tool.ToolType = "Engraver" + m = str(attributes["material"]) + if m == "0": + self.tool.Material = "HighSpeedSteel" + elif m == "1": + self.tool.Material = "Carbide" + # for some reason without the following line I get an error + print attributes["diameter"] + self.tool.Diameter = float(attributes["diameter"]) + self.tool.LengthOffset = float(attributes["tool_length_offset"]) + self.tool.FlatRadius = float(attributes["flat_radius"]) + self.tool.CornerRadius = float(attributes["corner_radius"]) + self.tool.CuttingEdgeAngle = float( + attributes["cutting_edge_angle"]) + self.tool.CuttingEdgeHeight = float( + attributes["cutting_edge_height"]) + + # Call when an elements ends + def endElement(self, tag): + if tag == "Tool": + if self.tooltable and self.tool and self.number: + self.tooltable.setTool(self.number, self.tool) + self.number = None + self.tool = None + + +class ToolLibraryManager(): + ''' + The Tool Library is a list of individual tool tables. Each + Tool Table can contain n tools. The tool library will be persisted to user + preferences and all or part of the library can be exported to other formats + ''' + + def __init__(self): + self.ToolLibrary = [] + self.prefs = FreeCAD.ParamGet("User parameter:BaseApp/Preferences/Mod/Path/ToolLibrary") + return + + def saveLibrary(self): + '''Persists the entire library to FreeCAD user preferences''' + tmpstring = "" + for table in self.ToolLibrary: + if table["listtype"] == 'User': + tmpstring += table["list"].Content + self.prefs.SetString("ToolLibrary", tmpstring) + + # FreeCAD.ConfigSet("PathToolTable:" + table[0], table[2].Content) + + def loadLibrary(self): + '''Loads the current library from FreeCAD user preferences''' + # Get persisted libraries from user prefs + tmpstring = self.prefs.GetString("ToolLibrary", "") + ToolLibrary = [] + if tmpstring != "": + Handler = FreeCADTooltableHandler() + try: + xml.sax.parseString(tmpstring, Handler) + tt = Handler.tooltable + toollist = {'name': "main", 'listtype': "User", 'list': tt} + ToolLibrary.append(toollist) + except: + FreeCAD.Console.PrintError( + "Unable to import tools from user preferences") + + # Get ToolTables from any open CNC jobs + for o in FreeCAD.ActiveDocument.Objects: + if "Proxy" in o.PropertiesList: + if hasattr(o, "Tooltable"): + toollist = {'name': o.Name, + 'listtype': "Job", 'list': o.Tooltable} + ToolLibrary.append(toollist) + self.ToolLibrary = ToolLibrary + return self.ToolLibrary + + # methods for lists + def addList(self, tablename, listtype="User", TL=None): + '''Add a new tooltable to the user library''' + if TL is None: + TL = Path.Tooltable() + toollist = {'name': tablename, 'listtype': listtype, 'list': TL} + self.ToolLibrary.append(toollist) + return TL + + def deleteList(self, tablename): + '''Delete all lists from the user library with the given listname''' + for l in self.ToolLibrary: + if l['name'] == tablename: + # maybe check if tools exist in list + self.ToolLibrary.remove(l) + return + + def findList(self, tablename): + '''Finds and returns list by name''' + returnlist = [] + for l in self.ToolLibrary: + if l['name'] == tablename: + returnlist.append(l) + return returnlist + + # methods for importing and exporting + def read(self): + "imports a tooltable from a file" + filename = QtGui.QFileDialog.getOpenFileName(None, _translate("ToolLibraryManager", "Import tooltable", None), None, _translate( + "ToolLibraryManager", "Tooltable XML (*.xml);;HeeksCAD tooltable (*.tooltable)", None)) + if filename: + parser = xml.sax.make_parser() + parser.setFeature(xml.sax.handler.feature_namespaces, 0) + if os.path.splitext(filename[0])[1].lower() == ".tooltable": + Handler = HeeksTooltableHandler() + else: + Handler = FreeCADTooltableHandler() + parser.setContentHandler(Handler) + parser.parse(str(filename[0])) + if Handler.tooltable: + self.addList(filename[0], Handler.tooltable) + # self.reset() + + def createToolController(self, job, tool): + pass + + def exportListHeeks(self, tooltable): + '''exports one or more Lists as a HeeksCNC tooltable''' + pass + + def exportListLinuxCNC(self, tooltable): + '''exports one or more Lists as a LinuxCNC tooltable''' + pass + + def exportListXML(self, tooltable): + '''exports one or more Lists as an XML file''' + pass