Moved base functionality into PathOp and renamed AreaOp interface to areaOp...
This commit is contained in:
committed by
Yorik van Havre
parent
45b3233ab7
commit
f4c20e7c61
@@ -47,6 +47,7 @@ SET(PathScripts_SRCS
|
||||
PathScripts/PathLog.py
|
||||
PathScripts/PathMillFace.py
|
||||
PathScripts/PathMillFaceGui.py
|
||||
PathScripts/PathOp.py
|
||||
PathScripts/PathPlane.py
|
||||
PathScripts/PathPocket.py
|
||||
PathScripts/PathPocketBaseGui.py
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
import FreeCAD
|
||||
import Path
|
||||
import PathScripts.PathLog as PathLog
|
||||
import PathScripts.PathOp as PathOp
|
||||
import PathScripts.PathUtils as PathUtils
|
||||
|
||||
from PathScripts.PathUtils import depth_params
|
||||
@@ -43,48 +44,14 @@ PathLog.trackModule()
|
||||
def translate(context, text, disambig=None):
|
||||
return QtCore.QCoreApplication.translate(context, text, disambig)
|
||||
|
||||
FeatureTool = 0x0001
|
||||
FeatureDepths = 0x0002
|
||||
FeatureHeights = 0x0004
|
||||
FeatureStartPoint = 0x0008
|
||||
FeatureFinishDepth = 0x0010
|
||||
FeatureBaseFaces = 0x1001
|
||||
FeatureBaseEdges = 0x1002
|
||||
FeatureBasePanels = 0x1002
|
||||
class ObjectOp(PathOp.ObjectOp):
|
||||
|
||||
FeatureBaseGeometry = FeatureBaseFaces | FeatureBaseEdges | FeatureBasePanels
|
||||
def opFeatures(self, obj):
|
||||
return PathOp.FeatureTool | PathOp.FeatureDepths | PathOp.FeatureHeights | PathOp.FeatureStartPoint | self.areaOpFeatures(obj)
|
||||
|
||||
class ObjectOp(object):
|
||||
|
||||
def __init__(self, obj):
|
||||
def initOperation(self, obj):
|
||||
PathLog.track()
|
||||
|
||||
obj.addProperty("App::PropertyBool", "Active", "Path", QtCore.QT_TRANSLATE_NOOP("App::Property", "Make False, to prevent operation from generating code"))
|
||||
obj.addProperty("App::PropertyString", "Comment", "Path", QtCore.QT_TRANSLATE_NOOP("App::Property", "An optional comment for this Operation"))
|
||||
obj.addProperty("App::PropertyString", "UserLabel", "Path", QtCore.QT_TRANSLATE_NOOP("App::Property", "User Assigned Label"))
|
||||
|
||||
if FeatureBaseGeometry & self.opFeatures(obj):
|
||||
obj.addProperty("App::PropertyLinkSubList", "Base", "Path", QtCore.QT_TRANSLATE_NOOP("App::Property", "The base geometry for this operation"))
|
||||
|
||||
if FeatureTool & self.opFeatures(obj):
|
||||
obj.addProperty("App::PropertyLink", "ToolController", "Path", QtCore.QT_TRANSLATE_NOOP("App::Property", "The tool controller that will be used to calculate the path"))
|
||||
|
||||
if FeatureDepths & self.opFeatures(obj):
|
||||
obj.addProperty("App::PropertyDistance", "StepDown", "Depth", QtCore.QT_TRANSLATE_NOOP("App::Property", "Incremental Step Down of Tool"))
|
||||
obj.addProperty("App::PropertyDistance", "StartDepth", "Depth", QtCore.QT_TRANSLATE_NOOP("App::Property", "Starting Depth of Tool- first cut depth in Z"))
|
||||
obj.addProperty("App::PropertyDistance", "FinalDepth", "Depth", QtCore.QT_TRANSLATE_NOOP("App::Property", "Final Depth of Tool- lowest value in Z"))
|
||||
|
||||
if FeatureFinishDepth & self.opFeatures(obj):
|
||||
obj.addProperty("App::PropertyDistance", "FinishDepth", "Depth", QtCore.QT_TRANSLATE_NOOP("App::Property", "Maximum material removed on final pass."))
|
||||
|
||||
if FeatureHeights & self.opFeatures(obj):
|
||||
obj.addProperty("App::PropertyDistance", "ClearanceHeight", "Depth", QtCore.QT_TRANSLATE_NOOP("App::Property", "The height needed to clear clamps and obstructions"))
|
||||
obj.addProperty("App::PropertyDistance", "SafeHeight", "Depth", QtCore.QT_TRANSLATE_NOOP("App::Property", "Rapid Safety Height between locations."))
|
||||
|
||||
if FeatureStartPoint & self.opFeatures(obj):
|
||||
obj.addProperty("App::PropertyVector", "StartPoint", "Start Point", QtCore.QT_TRANSLATE_NOOP("App::Property", "The start point of this path"))
|
||||
obj.addProperty("App::PropertyBool", "UseStartPoint", "Start Point", QtCore.QT_TRANSLATE_NOOP("App::Property", "make True, if specifying a Start Point"))
|
||||
|
||||
# Debugging
|
||||
obj.addProperty("App::PropertyString", "AreaParams", "Path")
|
||||
obj.setEditorMode('AreaParams', 2) # hide
|
||||
@@ -93,23 +60,9 @@ class ObjectOp(object):
|
||||
obj.addProperty("Part::PropertyPartShape", "removalshape", "Path")
|
||||
obj.setEditorMode('removalshape', 2) # hide
|
||||
|
||||
self.initOperation(obj)
|
||||
obj.Proxy = self
|
||||
self.setDefaultValues(obj)
|
||||
self.initAreaOp(obj)
|
||||
|
||||
def __getstate__(self):
|
||||
return None
|
||||
|
||||
def __setstate__(self, state):
|
||||
return None
|
||||
|
||||
def opFeatures(self, obj):
|
||||
return FeatureTool | FeatureDepths | FeatureHeights | FeatureStartPoint | FeatureBaseGeometry | FeatureFinishDepth
|
||||
def opOnChanged(self, obj, prop):
|
||||
pass
|
||||
def opSetDefaultValues(self, obj):
|
||||
pass
|
||||
def opShapeForDepths(self, obj):
|
||||
def areaOpShapeForDepths(self, obj):
|
||||
job = PathUtils.findParentJob(obj)
|
||||
if job and job.Base:
|
||||
PathLog.debug("job=%s base=%s shape=%s" % (job, job.Base, job.Base.Shape))
|
||||
@@ -120,13 +73,15 @@ class ObjectOp(object):
|
||||
PathLog.warning(translate("PathAreaOp", "no job for op %s found.") % obj.Label)
|
||||
return None
|
||||
|
||||
|
||||
def onChanged(self, obj, prop):
|
||||
def areaOpOnChanged(self, obj, prop):
|
||||
pass
|
||||
|
||||
def opOnChanged(self, obj, prop):
|
||||
#PathLog.track(obj.Label, prop)
|
||||
if prop in ['AreaParams', 'PathParams', 'removalshape']:
|
||||
obj.setEditorMode(prop, 2)
|
||||
|
||||
if FeatureBaseGeometry & self.opFeatures(obj):
|
||||
if PathOp.FeatureBaseGeometry & self.opFeatures(obj):
|
||||
if prop == 'Base' and len(obj.Base) == 1:
|
||||
try:
|
||||
(base, sub) = obj.Base[0]
|
||||
@@ -162,19 +117,12 @@ class ObjectOp(object):
|
||||
if hasattr(obj, 'Side'):
|
||||
obj.Side = "Outside"
|
||||
|
||||
self.opOnChanged(obj, prop)
|
||||
self.areaOpOnChanged(obj, prop)
|
||||
|
||||
def setDefaultValues(self, obj):
|
||||
PathUtils.addToJob(obj)
|
||||
|
||||
obj.Active = True
|
||||
|
||||
if FeatureTool & self.opFeatures(obj):
|
||||
obj.ToolController = PathUtils.findToolController(obj)
|
||||
|
||||
if FeatureDepths & self.opFeatures(obj):
|
||||
def opSetDefaultValues(self, obj):
|
||||
if PathOp.FeatureDepths & self.opFeatures(obj):
|
||||
try:
|
||||
shape = self.opShapeForDepths(obj)
|
||||
shape = self.areaOpShapeForDepths(obj)
|
||||
except:
|
||||
shape = None
|
||||
|
||||
@@ -188,9 +136,9 @@ class ObjectOp(object):
|
||||
obj.FinalDepth = 0.0
|
||||
obj.StepDown = 1.0
|
||||
|
||||
if FeatureHeights & self.opFeatures(obj):
|
||||
if PathOp.FeatureHeights & self.opFeatures(obj):
|
||||
try:
|
||||
shape = self.opShapeForDepths(obj)
|
||||
shape = self.areaOpShapeForDepths(obj)
|
||||
except:
|
||||
shape = None
|
||||
|
||||
@@ -202,19 +150,15 @@ class ObjectOp(object):
|
||||
obj.ClearanceHeight = 10.0
|
||||
obj.SafeHeight = 8.0
|
||||
|
||||
if FeatureStartPoint & self.opFeatures(obj):
|
||||
obj.UseStartPoint = False
|
||||
self.areaOpSetDefaultValues(obj)
|
||||
|
||||
self.opSetDefaultValues(obj)
|
||||
|
||||
@waiting_effects
|
||||
def _buildPathArea(self, obj, baseobject, isHole, start, getsim):
|
||||
PathLog.track()
|
||||
area = Path.Area()
|
||||
area.setPlane(makeWorkplane(baseobject))
|
||||
area.add(baseobject)
|
||||
|
||||
areaParams = self.opAreaParams(obj, isHole)
|
||||
areaParams = self.areaOpAreaParams(obj, isHole)
|
||||
|
||||
heights = [i for i in self.depthparams]
|
||||
PathLog.debug('depths: {}'.format(heights))
|
||||
@@ -223,12 +167,12 @@ class ObjectOp(object):
|
||||
|
||||
PathLog.debug("Area with params: {}".format(area.getParams()))
|
||||
|
||||
sections = area.makeSections(mode=0, project=self.opUseProjection(obj), heights=heights)
|
||||
sections = area.makeSections(mode=0, project=self.areaOpUseProjection(obj), heights=heights)
|
||||
PathLog.debug("sections = %s" % sections)
|
||||
shapelist = [sec.getShape() for sec in sections]
|
||||
PathLog.debug("shapelist = %s" % shapelist)
|
||||
|
||||
pathParams = self.opPathParams(obj, isHole)
|
||||
pathParams = self.areaOpPathParams(obj, isHole)
|
||||
pathParams['shapes'] = shapelist
|
||||
pathParams['feedrate'] = self.horizFeed
|
||||
pathParams['feedrate_v'] = self.vertFeed
|
||||
@@ -259,17 +203,10 @@ class ObjectOp(object):
|
||||
|
||||
return pp, simobj
|
||||
|
||||
def execute(self, obj, getsim=False):
|
||||
def opExecute(self, obj, getsim=False):
|
||||
PathLog.track()
|
||||
self.endVector = None
|
||||
|
||||
if not obj.Active:
|
||||
path = Path.Path("(inactive operation)")
|
||||
obj.Path = path
|
||||
if obj.ViewObject:
|
||||
obj.ViewObject.Visibility = False
|
||||
return
|
||||
|
||||
self.depthparams = depth_params(
|
||||
clearance_height=obj.ClearanceHeight.Value,
|
||||
safe_height=obj.SafeHeight.Value,
|
||||
@@ -279,60 +216,21 @@ class ObjectOp(object):
|
||||
final_depth=obj.FinalDepth.Value,
|
||||
user_depths=None)
|
||||
|
||||
toolLoad = obj.ToolController
|
||||
if toolLoad is None or toolLoad.ToolNumber == 0:
|
||||
|
||||
FreeCAD.Console.PrintError("No Tool Controller is selected. We need a tool to build a Path.")
|
||||
return
|
||||
else:
|
||||
self.vertFeed = toolLoad.VertFeed.Value
|
||||
self.horizFeed = toolLoad.HorizFeed.Value
|
||||
self.vertRapid = toolLoad.VertRapid.Value
|
||||
self.horizRapid = toolLoad.HorizRapid.Value
|
||||
tool = toolLoad.Proxy.getTool(toolLoad)
|
||||
if not tool or tool.Diameter == 0:
|
||||
FreeCAD.Console.PrintError("No Tool found or diameter is zero. We need a tool to build a Path.")
|
||||
return
|
||||
else:
|
||||
self.radius = tool.Diameter/2
|
||||
|
||||
if FeatureStartPoint and obj.UseStartPoint:
|
||||
if PathOp.FeatureStartPoint and obj.UseStartPoint:
|
||||
start = obj.StartPoint
|
||||
else:
|
||||
start = FreeCAD.Vector()
|
||||
|
||||
commandlist = []
|
||||
commandlist.append(Path.Command("(" + obj.Label + ")"))
|
||||
|
||||
shapes = self.opShapes(obj, commandlist)
|
||||
shapes = self.areaOpShapes(obj)
|
||||
|
||||
sims = []
|
||||
for (shape, isHole) in shapes:
|
||||
try:
|
||||
(pp, sim) = self._buildPathArea(obj, shape, isHole, start, getsim)
|
||||
commandlist.extend(pp.Commands)
|
||||
self.commandlist.extend(pp.Commands)
|
||||
sims.append(sim)
|
||||
except Exception as e:
|
||||
FreeCAD.Console.PrintError(e)
|
||||
FreeCAD.Console.PrintError("Something unexpected happened. Check project and tool config.")
|
||||
|
||||
|
||||
# Let's finish by rapid to clearance...just for safety
|
||||
commandlist.append(Path.Command("G0", {"Z": obj.ClearanceHeight.Value}))
|
||||
|
||||
PathLog.track()
|
||||
path = Path.Path(commandlist)
|
||||
obj.Path = path
|
||||
return sims
|
||||
|
||||
def addBase(self, obj, base, sub=""):
|
||||
PathLog.track()
|
||||
baselist = obj.Base
|
||||
if baselist is None:
|
||||
baselist = []
|
||||
item = (base, sub)
|
||||
if item in baselist:
|
||||
PathLog.warning(translate("Path", "this object already in the list" + "\n"))
|
||||
else:
|
||||
baselist.append(item)
|
||||
obj.Base = baselist
|
||||
|
||||
@@ -24,10 +24,10 @@
|
||||
|
||||
import FreeCAD
|
||||
import FreeCADGui
|
||||
import Path
|
||||
import PathScripts.PathAreaOp as PathAreaOp
|
||||
import PathScripts.PathLog as PathLog
|
||||
import PathScripts.PathSelection as PathSelection
|
||||
import PathScripts.PathOp as PathOp
|
||||
import importlib
|
||||
|
||||
from PathScripts import PathUtils
|
||||
@@ -176,7 +176,7 @@ class TaskPanelBaseGeometryPage(TaskPanelPage):
|
||||
DataObjectSub = QtCore.Qt.ItemDataRole.UserRole + 1
|
||||
|
||||
def initPage(self, obj):
|
||||
self.supports = PathAreaOp.FeatureBaseGeometry
|
||||
self.supports = PathOp.FeatureBaseGeometry
|
||||
|
||||
def getForm(self):
|
||||
return FreeCADGui.PySideUic.loadUi(":/panels/PageBaseGeometryEdit.ui")
|
||||
@@ -205,11 +205,11 @@ class TaskPanelBaseGeometryPage(TaskPanelPage):
|
||||
#FreeCADGui.updateGui()
|
||||
|
||||
def supportsEdges(self):
|
||||
return self.supports & PathAreaOp.FeatureBaseEdges
|
||||
return self.supports & PathOp.FeatureBaseEdges
|
||||
def supportsFaces(self):
|
||||
return self.supports & PathAreaOp.FeatureBaseFaces
|
||||
return self.supports & PathOp.FeatureBaseFaces
|
||||
def supportsPanels(self):
|
||||
return self.supports & PathAreaOp.FeatureBasePanels
|
||||
return self.supports & PathOp.FeatureBasePanels
|
||||
|
||||
def featureName(self):
|
||||
if self.supportsEdges() and self.supportsFaces():
|
||||
@@ -341,19 +341,19 @@ class TaskPanel(object):
|
||||
self.deleteOnReject = deleteOnReject
|
||||
self.featurePages = []
|
||||
|
||||
if PathAreaOp.FeatureBaseGeometry & obj.Proxy.opFeatures(obj):
|
||||
if PathOp.FeatureBaseGeometry & obj.Proxy.opFeatures(obj):
|
||||
basePage = TaskPanelBaseGeometryPage(obj)
|
||||
basePage.supports = obj.Proxy.opFeatures(obj) & PathAreaOp.FeatureBaseGeometry
|
||||
basePage.supports = obj.Proxy.opFeatures(obj) & PathOp.FeatureBaseGeometry
|
||||
self.featurePages.append(basePage)
|
||||
|
||||
if PathAreaOp.FeatureDepths & obj.Proxy.opFeatures(obj):
|
||||
if PathAreaOp.FeatureFinishDepth & obj.Proxy.opFeatures(obj):
|
||||
if PathOp.FeatureDepths & obj.Proxy.opFeatures(obj):
|
||||
if PathOp.FeatureFinishDepth & obj.Proxy.opFeatures(obj):
|
||||
depthPage = TaskPanelDepthsPage(obj)
|
||||
else:
|
||||
depthPage = TaskPanelDepthsWoFinishPage(obj)
|
||||
self.featurePages.append(depthPage)
|
||||
|
||||
if PathAreaOp.FeatureHeights & obj.Proxy.opFeatures(obj):
|
||||
if PathOp.FeatureHeights & obj.Proxy.opFeatures(obj):
|
||||
self.featurePages.append(TaskPanelHeightsPage(obj))
|
||||
|
||||
opPage.setTitle(translate('PathAreaOp', 'Operation'))
|
||||
@@ -441,7 +441,7 @@ class TaskPanel(object):
|
||||
def setupUi(self):
|
||||
PathLog.track(self.deleteOnReject)
|
||||
|
||||
if self.deleteOnReject and PathAreaOp.FeatureBaseGeometry & self.obj.Proxy.opFeatures(self.obj):
|
||||
if self.deleteOnReject and PathOp.FeatureBaseGeometry & self.obj.Proxy.opFeatures(self.obj):
|
||||
sel = FreeCADGui.Selection.getSelectionEx()
|
||||
if len(sel) == 1 and sel[0].Object != self.obj:
|
||||
for page in self.featurePages:
|
||||
|
||||
@@ -26,9 +26,9 @@ from __future__ import print_function
|
||||
|
||||
import FreeCAD
|
||||
import Part
|
||||
import Path
|
||||
import PathScripts.PathAreaOp as PathAreaOp
|
||||
import PathScripts.PathLog as PathLog
|
||||
import PathScripts.PathOp as PathOp
|
||||
import PathScripts.PathUtils as PathUtils
|
||||
|
||||
from PySide import QtCore, QtGui
|
||||
@@ -56,10 +56,10 @@ __url__ = "http://www.freecadweb.org"
|
||||
|
||||
class ObjectFace(PathAreaOp.ObjectOp):
|
||||
|
||||
def opFeatures(self, obj):
|
||||
return PathAreaOp.FeatureTool | PathAreaOp.FeatureDepths | PathAreaOp.FeatureHeights | PathAreaOp.FeatureStartPoint | PathAreaOp.FeatureBaseFaces | PathAreaOp.FeatureFinishDepth
|
||||
def areaOpFeatures(self, obj):
|
||||
return PathOp.FeatureBaseFaces | PathOp.FeatureFinishDepth
|
||||
|
||||
def initOperation(self, obj):
|
||||
def initAreaOp(self, obj):
|
||||
|
||||
# Face Properties
|
||||
obj.addProperty("App::PropertyEnumeration", "CutMode", "Face", QtCore.QT_TRANSLATE_NOOP("App::Property", "The direction that the toolpath should go around the part ClockWise CW or CounterClockWise CCW"))
|
||||
@@ -78,7 +78,7 @@ class ObjectFace(PathAreaOp.ObjectOp):
|
||||
obj.OffsetPattern = ['ZigZag', 'Offset', 'Spiral', 'ZigZagOffset', 'Line', 'Grid', 'Triangle']
|
||||
|
||||
|
||||
def opOnChanged(self, obj, prop):
|
||||
def areaOpOnChanged(self, obj, prop):
|
||||
PathLog.track(prop)
|
||||
if prop == "StepOver" and obj.StepOver == 0:
|
||||
obj.StepOver = 1
|
||||
@@ -93,10 +93,10 @@ class ObjectFace(PathAreaOp.ObjectOp):
|
||||
obj.StartDepth = d.safe_height
|
||||
obj.FinalDepth = d.start_depth
|
||||
|
||||
def opUseProjection(self, obj):
|
||||
def areaOpUseProjection(self, obj):
|
||||
return False
|
||||
|
||||
def opAreaParams(self, obj, isHole):
|
||||
def areaOpAreaParams(self, obj, isHole):
|
||||
params = {}
|
||||
params['Fill'] = 0
|
||||
params['Coplanar'] = 0
|
||||
@@ -114,7 +114,7 @@ class ObjectFace(PathAreaOp.ObjectOp):
|
||||
|
||||
return params
|
||||
|
||||
def opPathParams(self, obj, isHole):
|
||||
def areaOpPathParams(self, obj, isHole):
|
||||
params = {}
|
||||
params['feedrate'] = self.horizFeed
|
||||
params['feedrate_v'] = self.vertFeed
|
||||
@@ -127,9 +127,7 @@ class ObjectFace(PathAreaOp.ObjectOp):
|
||||
|
||||
return params
|
||||
|
||||
def opShapes(self, obj, commandlist):
|
||||
commandlist.append(Path.Command("(" + obj.Label + ")"))
|
||||
|
||||
def areaOpShapes(self, obj):
|
||||
# Facing is done either against base objects
|
||||
if obj.Base:
|
||||
PathLog.debug("obj.Base: {}".format(obj.Base))
|
||||
@@ -165,7 +163,7 @@ class ObjectFace(PathAreaOp.ObjectOp):
|
||||
|
||||
return [(env, False)]
|
||||
|
||||
def opSetDefaultValues(self, obj):
|
||||
def areaOpSetDefaultValues(self, obj):
|
||||
obj.StepOver = 50
|
||||
obj.ZigZagAngle = 45.0
|
||||
|
||||
|
||||
@@ -24,7 +24,6 @@
|
||||
|
||||
import FreeCAD
|
||||
import FreeCADGui
|
||||
import Path
|
||||
import PathScripts.PathAreaOpGui as PathAreaOpGui
|
||||
import PathScripts.PathMillFace as PathMillFace
|
||||
import PathScripts.PathPocketBaseGui as PathPocketBaseGui
|
||||
|
||||
185
src/Mod/Path/PathScripts/PathOp.py
Normal file
185
src/Mod/Path/PathScripts/PathOp.py
Normal file
@@ -0,0 +1,185 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# ***************************************************************************
|
||||
# * *
|
||||
# * Copyright (c) 2017 sliptonic <shopinthewoods@gmail.com> *
|
||||
# * *
|
||||
# * 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
|
||||
import PathScripts.PathLog as PathLog
|
||||
import PathScripts.PathUtils as PathUtils
|
||||
|
||||
from PathScripts.PathUtils import waiting_effects
|
||||
from PySide import QtCore
|
||||
|
||||
__title__ = "Base class for all operations."
|
||||
__author__ = "sliptonic (Brad Collette)"
|
||||
__url__ = "http://www.freecadweb.org"
|
||||
|
||||
PathLog.setLevel(PathLog.Level.DEBUG, PathLog.thisModule())
|
||||
PathLog.trackModule()
|
||||
|
||||
# Qt tanslation handling
|
||||
def translate(context, text, disambig=None):
|
||||
return QtCore.QCoreApplication.translate(context, text, disambig)
|
||||
|
||||
FeatureTool = 0x0001
|
||||
FeatureDepths = 0x0002
|
||||
FeatureHeights = 0x0004
|
||||
FeatureStartPoint = 0x0008
|
||||
FeatureFinishDepth = 0x0010
|
||||
FeatureBaseFeatures = 0x1000
|
||||
FeatureBaseFaces = 0x2000
|
||||
FeatureBaseEdges = 0x4000
|
||||
FeatureBasePanels = 0x8000
|
||||
|
||||
FeatureBaseGeometry = FeatureBaseFeatures | FeatureBaseFaces | FeatureBaseEdges | FeatureBasePanels
|
||||
|
||||
class ObjectOp(object):
|
||||
|
||||
def __init__(self, obj):
|
||||
PathLog.track()
|
||||
|
||||
obj.addProperty("App::PropertyBool", "Active", "Path", QtCore.QT_TRANSLATE_NOOP("App::Property", "Make False, to prevent operation from generating code"))
|
||||
obj.addProperty("App::PropertyString", "Comment", "Path", QtCore.QT_TRANSLATE_NOOP("App::Property", "An optional comment for this Operation"))
|
||||
obj.addProperty("App::PropertyString", "UserLabel", "Path", QtCore.QT_TRANSLATE_NOOP("App::Property", "User Assigned Label"))
|
||||
|
||||
if FeatureBaseGeometry & self.opFeatures(obj):
|
||||
obj.addProperty("App::PropertyLinkSubList", "Base", "Path", QtCore.QT_TRANSLATE_NOOP("App::Property", "The base geometry for this operation"))
|
||||
|
||||
if FeatureTool & self.opFeatures(obj):
|
||||
obj.addProperty("App::PropertyLink", "ToolController", "Path", QtCore.QT_TRANSLATE_NOOP("App::Property", "The tool controller that will be used to calculate the path"))
|
||||
|
||||
if FeatureDepths & self.opFeatures(obj):
|
||||
obj.addProperty("App::PropertyDistance", "StepDown", "Depth", QtCore.QT_TRANSLATE_NOOP("App::Property", "Incremental Step Down of Tool"))
|
||||
obj.addProperty("App::PropertyDistance", "StartDepth", "Depth", QtCore.QT_TRANSLATE_NOOP("App::Property", "Starting Depth of Tool- first cut depth in Z"))
|
||||
obj.addProperty("App::PropertyDistance", "FinalDepth", "Depth", QtCore.QT_TRANSLATE_NOOP("App::Property", "Final Depth of Tool- lowest value in Z"))
|
||||
|
||||
if FeatureFinishDepth & self.opFeatures(obj):
|
||||
obj.addProperty("App::PropertyDistance", "FinishDepth", "Depth", QtCore.QT_TRANSLATE_NOOP("App::Property", "Maximum material removed on final pass."))
|
||||
|
||||
if FeatureHeights & self.opFeatures(obj):
|
||||
obj.addProperty("App::PropertyDistance", "ClearanceHeight", "Depth", QtCore.QT_TRANSLATE_NOOP("App::Property", "The height needed to clear clamps and obstructions"))
|
||||
obj.addProperty("App::PropertyDistance", "SafeHeight", "Depth", QtCore.QT_TRANSLATE_NOOP("App::Property", "Rapid Safety Height between locations."))
|
||||
|
||||
if FeatureStartPoint & self.opFeatures(obj):
|
||||
obj.addProperty("App::PropertyVector", "StartPoint", "Start Point", QtCore.QT_TRANSLATE_NOOP("App::Property", "The start point of this path"))
|
||||
obj.addProperty("App::PropertyBool", "UseStartPoint", "Start Point", QtCore.QT_TRANSLATE_NOOP("App::Property", "make True, if specifying a Start Point"))
|
||||
|
||||
self.initOperation(obj)
|
||||
|
||||
obj.Proxy = self
|
||||
self.setDefaultValues(obj)
|
||||
|
||||
def __getstate__(self):
|
||||
return None
|
||||
|
||||
def __setstate__(self, state):
|
||||
return None
|
||||
|
||||
def opFeatures(self, obj):
|
||||
return FeatureTool | FeatureDepths | FeatureHeights | FeatureStartPoint | FeatureBaseGeometry | FeatureFinishDepth
|
||||
def opOnChanged(self, obj, prop):
|
||||
pass
|
||||
def opSetDefaultValues(self, obj):
|
||||
pass
|
||||
|
||||
def onChanged(self, obj, prop):
|
||||
self.opOnChanged(obj, prop)
|
||||
|
||||
def setDefaultValues(self, obj, callOp = True):
|
||||
PathUtils.addToJob(obj)
|
||||
|
||||
obj.Active = True
|
||||
|
||||
if FeatureTool & self.opFeatures(obj):
|
||||
obj.ToolController = PathUtils.findToolController(obj)
|
||||
|
||||
if FeatureDepths & self.opFeatures(obj):
|
||||
obj.StartDepth = 1.0
|
||||
obj.FinalDepth = 0.0
|
||||
obj.StepDown = 1.0
|
||||
|
||||
if FeatureHeights & self.opFeatures(obj):
|
||||
obj.ClearanceHeight = 10.0
|
||||
obj.SafeHeight = 8.0
|
||||
|
||||
if FeatureStartPoint & self.opFeatures(obj):
|
||||
obj.UseStartPoint = False
|
||||
|
||||
self.opSetDefaultValues(obj)
|
||||
|
||||
@waiting_effects
|
||||
def execute(self, obj):
|
||||
PathLog.track()
|
||||
|
||||
if not obj.Active:
|
||||
path = Path.Path("(inactive operation)")
|
||||
obj.Path = path
|
||||
if obj.ViewObject:
|
||||
obj.ViewObject.Visibility = False
|
||||
return
|
||||
|
||||
tc = obj.ToolController
|
||||
if tc is None or tc.ToolNumber == 0:
|
||||
FreeCAD.Console.PrintError("No Tool Controller is selected. We need a tool to build a Path.")
|
||||
return
|
||||
else:
|
||||
self.vertFeed = tc.VertFeed.Value
|
||||
self.horizFeed = tc.HorizFeed.Value
|
||||
self.vertRapid = tc.VertRapid.Value
|
||||
self.horizRapid = tc.HorizRapid.Value
|
||||
tool = tc.Proxy.getTool(tc)
|
||||
if not tool or tool.Diameter == 0:
|
||||
FreeCAD.Console.PrintError("No Tool found or diameter is zero. We need a tool to build a Path.")
|
||||
return
|
||||
else:
|
||||
self.radius = tool.Diameter/2
|
||||
|
||||
if FeatureStartPoint and obj.UseStartPoint:
|
||||
start = obj.StartPoint
|
||||
else:
|
||||
start = FreeCAD.Vector()
|
||||
|
||||
self.commandlist = []
|
||||
self.commandlist.append(Path.Command("(" + obj.Label + ")"))
|
||||
|
||||
result = self.opExecute(obj)
|
||||
|
||||
# Let's finish by rapid to clearance...just for safety
|
||||
self.commandlist.append(Path.Command("G0", {"Z": obj.ClearanceHeight.Value}))
|
||||
|
||||
path = Path.Path(self.commandlist)
|
||||
obj.Path = path
|
||||
return result
|
||||
|
||||
def addBase(self, obj, base, sub):
|
||||
PathLog.track()
|
||||
baselist = obj.Base
|
||||
if baselist is None:
|
||||
baselist = []
|
||||
item = (base, sub)
|
||||
if item in baselist:
|
||||
PathLog.notice(translate("Path", "this object already in the list" + "\n"))
|
||||
else:
|
||||
baselist.append(item)
|
||||
obj.Base = baselist
|
||||
|
||||
@@ -24,9 +24,9 @@
|
||||
|
||||
import FreeCAD
|
||||
import Part
|
||||
import Path
|
||||
import PathScripts.PathAreaOp as PathAreaOp
|
||||
import PathScripts.PathLog as PathLog
|
||||
import PathScripts.PathOp as PathOp
|
||||
|
||||
from PathScripts import PathUtils
|
||||
from PySide import QtCore
|
||||
@@ -46,10 +46,10 @@ def translate(context, text, disambig=None):
|
||||
|
||||
class ObjectPocket(PathAreaOp.ObjectOp):
|
||||
|
||||
def opFeatures(self, obj):
|
||||
return PathAreaOp.FeatureTool | PathAreaOp.FeatureDepths | PathAreaOp.FeatureHeights | PathAreaOp.FeatureStartPoint | PathAreaOp.FeatureBaseFaces | PathAreaOp.FeatureFinishDepth
|
||||
def areaOpFeatures(self, obj):
|
||||
return PathOp.FeatureBaseFaces | PathOp.FeatureFinishDepth
|
||||
|
||||
def initOperation(self, obj):
|
||||
def initAreaOp(self, obj):
|
||||
PathLog.track()
|
||||
|
||||
# Pocket Properties
|
||||
@@ -64,10 +64,10 @@ class ObjectPocket(PathAreaOp.ObjectOp):
|
||||
obj.OffsetPattern = ['ZigZag', 'Offset', 'Spiral', 'ZigZagOffset', 'Line', 'Grid', 'Triangle']
|
||||
obj.addProperty("App::PropertyBool", "MinTravel", "Pocket", QtCore.QT_TRANSLATE_NOOP("App::Property", "Use 3D Sorting of Path"))
|
||||
|
||||
def opUseProjection(self, obj):
|
||||
def areaOpUseProjection(self, obj):
|
||||
return False
|
||||
|
||||
def opAreaParams(self, obj, isHole):
|
||||
def areaOpAreaParams(self, obj, isHole):
|
||||
params = {}
|
||||
params['Fill'] = 0
|
||||
params['Coplanar'] = 0
|
||||
@@ -83,7 +83,7 @@ class ObjectPocket(PathAreaOp.ObjectOp):
|
||||
params['PocketMode'] = Pattern.index(obj.OffsetPattern) + 1
|
||||
return params
|
||||
|
||||
def opPathParams(self, obj, isHole):
|
||||
def areaOpPathParams(self, obj, isHole):
|
||||
params = {}
|
||||
|
||||
# if MinTravel is turned on, set path sorting to 3DSort
|
||||
@@ -93,7 +93,7 @@ class ObjectPocket(PathAreaOp.ObjectOp):
|
||||
params['sort_mode'] = 2
|
||||
return params
|
||||
|
||||
def opShapes(self, obj, commandlist):
|
||||
def areaOpShapes(self, obj):
|
||||
PathLog.track()
|
||||
|
||||
job = PathUtils.findParentJob(obj)
|
||||
@@ -124,7 +124,7 @@ class ObjectPocket(PathAreaOp.ObjectOp):
|
||||
removalshapes = [(obj.removalshape, False)]
|
||||
return removalshapes
|
||||
|
||||
def opSetDefaultValues(self, obj):
|
||||
def areaOpSetDefaultValues(self, obj):
|
||||
obj.StepOver = 100
|
||||
obj.ZigZagAngle = 45
|
||||
|
||||
|
||||
@@ -24,7 +24,6 @@
|
||||
|
||||
import FreeCAD
|
||||
import FreeCADGui
|
||||
import Path
|
||||
import PathScripts.PathAreaOpGui as PathAreaOpGui
|
||||
import PathScripts.PathLog as PathLog
|
||||
import PathScripts.PathPocket as PathPocket
|
||||
|
||||
@@ -23,8 +23,6 @@
|
||||
# ***************************************************************************
|
||||
|
||||
import FreeCAD
|
||||
import FreeCADGui
|
||||
import Path
|
||||
import PathScripts.PathAreaOpGui as PathAreaOpGui
|
||||
import PathScripts.PathPocket as PathPocket
|
||||
import PathScripts.PathPocketBaseGui as PathPocketBaseGui
|
||||
|
||||
@@ -23,11 +23,9 @@
|
||||
# ***************************************************************************
|
||||
|
||||
import FreeCAD
|
||||
import Part
|
||||
import Path
|
||||
import PathScripts.PathAreaOp as PathAreaOp
|
||||
import PathScripts.PathUtils as PathUtils
|
||||
import PathScripts.PathLog as PathLog
|
||||
import PathScripts.PathOp as PathOp
|
||||
|
||||
from PySide import QtCore
|
||||
|
||||
@@ -57,10 +55,7 @@ __url__ = "http://www.freecadweb.org"
|
||||
|
||||
class ObjectProfile(PathAreaOp.ObjectOp):
|
||||
|
||||
def opFeatures(self, obj):
|
||||
return PathAreaOp.FeatureTool | PathAreaOp.FeatureDepths | PathAreaOp.FeatureHeights | PathAreaOp.FeatureStartPoint
|
||||
|
||||
def initOperation(self, obj):
|
||||
def initAreaOp(self, obj):
|
||||
# Profile Properties
|
||||
obj.addProperty("App::PropertyEnumeration", "Side", "Profile", QtCore.QT_TRANSLATE_NOOP("App::Property", "Side of edge that tool should cut"))
|
||||
obj.Side = ['Outside', 'Inside'] # side of profile that cutter is on in relation to direction of profile
|
||||
@@ -74,9 +69,7 @@ class ObjectProfile(PathAreaOp.ObjectOp):
|
||||
obj.addProperty("App::PropertyFloat", "MiterLimit", "Profile", QtCore.QT_TRANSLATE_NOOP("App::Property", "Maximum distance before a miter join is truncated"))
|
||||
obj.setEditorMode('MiterLimit', 2)
|
||||
|
||||
obj.Proxy = self
|
||||
|
||||
def onOpChanged(self, obj, prop):
|
||||
def areaOpOnChanged(self, obj, prop):
|
||||
if prop == "UseComp":
|
||||
if not obj.UseComp:
|
||||
obj.setEditorMode('Side', 2)
|
||||
@@ -89,19 +82,20 @@ class ObjectProfile(PathAreaOp.ObjectOp):
|
||||
else:
|
||||
obj.setEditorMode('MiterLimit', 2)
|
||||
|
||||
def opAreaParams(self, obj, isHole):
|
||||
def areaOpAreaParams(self, obj, isHole):
|
||||
params = {}
|
||||
params['Fill'] = 0
|
||||
params['Coplanar'] = 0
|
||||
params['SectionCount'] = -1
|
||||
|
||||
offset = 0.0
|
||||
if obj.UseComp:
|
||||
if obj.Side == 'Inside':
|
||||
params['Offset'] = 0 - self.radius+obj.OffsetExtra.Value
|
||||
else:
|
||||
params['Offset'] = self.radius+obj.OffsetExtra.Value
|
||||
else:
|
||||
params['Offset'] = 0.0
|
||||
offset = self.radius + obj.OffsetExtra.Value
|
||||
if obj.Side == 'Inside':
|
||||
offset = 0 - offset
|
||||
if isHole:
|
||||
offset = 0 - offset
|
||||
params['Offset'] = offset
|
||||
|
||||
jointype = ['Round', 'Square', 'Miter']
|
||||
params['JoinType'] = jointype.index(obj.JoinType)
|
||||
@@ -111,7 +105,7 @@ class ObjectProfile(PathAreaOp.ObjectOp):
|
||||
|
||||
return params
|
||||
|
||||
def opPathParams(self, obj, isHole):
|
||||
def areaOpPathParams(self, obj, isHole):
|
||||
params = {}
|
||||
|
||||
# Reverse the direction for holes
|
||||
@@ -127,10 +121,10 @@ class ObjectProfile(PathAreaOp.ObjectOp):
|
||||
|
||||
return params
|
||||
|
||||
def opUseProjection(self, obj):
|
||||
def areaOpUseProjection(self, obj):
|
||||
return True
|
||||
|
||||
def opSetDefaultValues(self, obj):
|
||||
def areaOpSetDefaultValues(self, obj):
|
||||
obj.Side = "Outside"
|
||||
obj.OffsetExtra = 0.0
|
||||
obj.Direction = "CW"
|
||||
|
||||
@@ -24,14 +24,13 @@
|
||||
|
||||
import FreeCAD
|
||||
import FreeCADGui
|
||||
import Path
|
||||
import PathScripts.PathAreaOpGui as PathAreaOpGui
|
||||
import PathScripts.PathLog as PathLog
|
||||
import PathScripts.PathProfileFaces as PathProfileFaces
|
||||
import PathScripts.PathSelection as PathSelection
|
||||
import PathScripts.PathUtils as PathUtils
|
||||
|
||||
from PathScripts import PathUtils
|
||||
from PySide import QtCore, QtGui
|
||||
from PySide import QtCore
|
||||
|
||||
def translate(context, text, disambig=None):
|
||||
return QtCore.QCoreApplication.translate(context, text, disambig)
|
||||
|
||||
@@ -59,19 +59,22 @@ class ObjectContour(PathProfileBase.ObjectProfile):
|
||||
def baseObject(self):
|
||||
return super(self.__class__, self)
|
||||
|
||||
def initOperation(self, obj):
|
||||
self.baseObject().initOperation(obj)
|
||||
def areaOpFeatures(self, obj):
|
||||
return 0
|
||||
|
||||
def initAreaOp(self, obj):
|
||||
self.baseObject().initAreaOp(obj)
|
||||
obj.setEditorMode('Side', 2) # it's always outside
|
||||
|
||||
def opSetDefaultValues(self, obj):
|
||||
self.baseObject().opSetDefaultValues(obj)
|
||||
def areaOpSetDefaultValues(self, obj):
|
||||
self.baseObject().areaOpSetDefaultValues(obj)
|
||||
obj.Side = 'Outside'
|
||||
|
||||
def opShapes(self, obj, commandlist):
|
||||
def areaOpShapes(self, obj):
|
||||
if obj.UseComp:
|
||||
commandlist.append(Path.Command("(Compensated Tool Path. Diameter: " + str(self.radius * 2) + ")"))
|
||||
self.commandlist.append(Path.Command("(Compensated Tool Path. Diameter: " + str(self.radius * 2) + ")"))
|
||||
else:
|
||||
commandlist.append(Path.Command("(Uncompensated Tool Path)"))
|
||||
self.commandlist.append(Path.Command("(Uncompensated Tool Path)"))
|
||||
|
||||
job = PathUtils.findParentJob(obj)
|
||||
|
||||
@@ -95,8 +98,8 @@ class ObjectContour(PathProfileBase.ObjectProfile):
|
||||
if hasattr(baseobject, "Shape") and not isPanel:
|
||||
return [(PathUtils.getEnvelope(partshape=baseobject.Shape, subshape=None, depthparams=self.depthparams), False)]
|
||||
|
||||
def opAreaParams(self, obj, isHole):
|
||||
params = self.baseObject().opAreaParams(obj, isHole)
|
||||
def areaOpAreaParams(self, obj, isHole):
|
||||
params = self.baseObject().areaOpAreaParams(obj, isHole)
|
||||
params['Coplanar'] = 2
|
||||
return params
|
||||
|
||||
|
||||
@@ -26,9 +26,10 @@ import FreeCAD
|
||||
import Part
|
||||
import Path
|
||||
import PathScripts.PathAreaOp as PathAreaOp
|
||||
import PathScripts.PathLog as PathLog
|
||||
import PathScripts.PathOp as PathOp
|
||||
import PathScripts.PathProfileBase as PathProfileBase
|
||||
import PathScripts.PathUtils as PathUtils
|
||||
import PathScripts.PathLog as PathLog
|
||||
|
||||
from DraftGeomUtils import findWires
|
||||
from PySide import QtCore
|
||||
@@ -62,10 +63,10 @@ class ObjectProfile(PathProfileBase.ObjectProfile):
|
||||
def baseObject(self):
|
||||
return super(self.__class__, self)
|
||||
|
||||
def opFeatures(self, obj):
|
||||
return self.baseObject().opFeatures(obj) | PathAreaOp.FeatureBaseEdges
|
||||
def areaOpFeatures(self, obj):
|
||||
return PathOp.FeatureBaseEdges
|
||||
|
||||
def opShapes(self, obj, commandlist):
|
||||
def areaOpShapes(self, obj):
|
||||
PathLog.track()
|
||||
|
||||
job = PathUtils.findParentJob(obj)
|
||||
@@ -73,12 +74,10 @@ class ObjectProfile(PathProfileBase.ObjectProfile):
|
||||
return
|
||||
baseobject = job.Base
|
||||
|
||||
commandlist.append(Path.Command("(" + obj.Label + ")"))
|
||||
|
||||
if obj.UseComp:
|
||||
commandlist.append(Path.Command("(Compensated Tool Path. Diameter: " + str(self.radius * 2) + ")"))
|
||||
self.commandlist.append(Path.Command("(Compensated Tool Path. Diameter: " + str(self.radius * 2) + ")"))
|
||||
else:
|
||||
commandlist.append(Path.Command("(Uncompensated Tool Path)"))
|
||||
self.commandlist.append(Path.Command("(Uncompensated Tool Path)"))
|
||||
|
||||
shapes = []
|
||||
if obj.Base:
|
||||
|
||||
@@ -27,8 +27,9 @@ import FreeCAD
|
||||
import Part
|
||||
import Path
|
||||
import PathScripts.PathAreaOp as PathAreaOp
|
||||
import PathScripts.PathProfileBase as PathProfileBase
|
||||
import PathScripts.PathLog as PathLog
|
||||
import PathScripts.PathOp as PathOp
|
||||
import PathScripts.PathProfileBase as PathProfileBase
|
||||
import PathScripts.PathUtils as PathUtils
|
||||
import numpy
|
||||
|
||||
@@ -54,33 +55,29 @@ class ObjectProfile(PathProfileBase.ObjectProfile):
|
||||
def baseObject(self):
|
||||
return super(self.__class__, self)
|
||||
|
||||
def initOperation(self, obj):
|
||||
self.baseObject().initOperation(obj)
|
||||
|
||||
def initAreaOp(self, obj):
|
||||
# Face specific Properties
|
||||
obj.addProperty("App::PropertyBool", "processHoles", "Profile", QtCore.QT_TRANSLATE_NOOP("App::Property", "Profile holes as well as the outline"))
|
||||
obj.addProperty("App::PropertyBool", "processPerimeter", "Profile", QtCore.QT_TRANSLATE_NOOP("App::Property", "Profile the outline"))
|
||||
obj.addProperty("App::PropertyBool", "processCircles", "Profile", QtCore.QT_TRANSLATE_NOOP("App::Property", "Profile round holes"))
|
||||
|
||||
obj.Proxy = self
|
||||
self.baseObject().initAreaOp(obj)
|
||||
|
||||
def opSetDefaultValues(self, obj):
|
||||
self.baseObject().opSetDefaultValues(obj)
|
||||
def areaOpSetDefaultValues(self, obj):
|
||||
self.baseObject().areaOpSetDefaultValues(obj)
|
||||
|
||||
obj.processHoles = False
|
||||
obj.processCircles = False
|
||||
obj.processPerimeter = True
|
||||
|
||||
def opFeatures(self, obj):
|
||||
return self.baseObject().opFeatures(obj) | PathAreaOp.FeatureBaseFaces
|
||||
|
||||
def opShapes(self, obj, commandlist):
|
||||
commandlist.append(Path.Command("(" + obj.Label + ")"))
|
||||
def areaOpFeatures(self, obj):
|
||||
return PathOp.FeatureBaseFaces
|
||||
|
||||
def areaOpShapes(self, obj):
|
||||
if obj.UseComp:
|
||||
commandlist.append(Path.Command("(Compensated Tool Path. Diameter: " + str(self.radius * 2) + ")"))
|
||||
self.commandlist.append(Path.Command("(Compensated Tool Path. Diameter: " + str(self.radius * 2) + ")"))
|
||||
else:
|
||||
commandlist.append(Path.Command("(Uncompensated Tool Path)"))
|
||||
self.commandlist.append(Path.Command("(Uncompensated Tool Path)"))
|
||||
|
||||
job = PathUtils.findParentJob(obj)
|
||||
if not job or not job.Base:
|
||||
|
||||
@@ -25,8 +25,8 @@
|
||||
|
||||
import FreeCAD
|
||||
import FreeCADGui
|
||||
import PathScripts.PathUtils as PathUtils
|
||||
import PathScripts.PathLog as PathLog
|
||||
import PathScripts.PathUtils as PathUtils
|
||||
|
||||
LOG_MODULE = 'PathSelection'
|
||||
PathLog.setLevel(PathLog.Level.INFO, LOG_MODULE)
|
||||
|
||||
Reference in New Issue
Block a user