From a5a88e5b59f287e73bdc78fcc52ceaccde2d0e1a Mon Sep 17 00:00:00 2001 From: sliptonic Date: Thu, 22 Jun 2017 10:43:44 -0500 Subject: [PATCH] Path: remove obsolete code from cmake also refactored depthparams and fixes to depths on various operations --- src/Mod/Path/CMakeLists.txt | 2 - .../Gui/Resources/panels/ProfileEdgesEdit.ui | 19 ++--- src/Mod/Path/PathScripts/PathContour.py | 44 ++++++----- src/Mod/Path/PathScripts/PathMillFace.py | 41 ++++------ src/Mod/Path/PathScripts/PathPocket.py | 59 +++++++------- src/Mod/Path/PathScripts/PathProfile.py | 30 +++---- src/Mod/Path/PathScripts/PathProfileEdges.py | 26 ++++--- src/Mod/Path/PathScripts/PathSanity.py | 46 +++++------ src/Mod/Path/PathScripts/PathSurface.py | 3 +- src/Mod/Path/PathScripts/PathUtils.py | 78 ++++++++++++++----- src/Mod/Path/PathTests/TestPathDepthParams.py | 34 ++++---- 11 files changed, 209 insertions(+), 173 deletions(-) diff --git a/src/Mod/Path/CMakeLists.txt b/src/Mod/Path/CMakeLists.txt index 8379ba9a87..4f8e06e831 100644 --- a/src/Mod/Path/CMakeLists.txt +++ b/src/Mod/Path/CMakeLists.txt @@ -18,7 +18,6 @@ INSTALL( SET(PathScripts_SRCS PathCommands.py - PathScripts/PathAreaUtils.py PathScripts/PathArray.py PathScripts/PathComment.py PathScripts/PathCompoundExtended.py @@ -40,7 +39,6 @@ SET(PathScripts_SRCS PathScripts/PathHop.py PathScripts/PathInspect.py PathScripts/PathJob.py - PathScripts/PathKurveUtils.py PathScripts/PathLog.py PathScripts/PathMillFace.py PathScripts/PathPlane.py diff --git a/src/Mod/Path/Gui/Resources/panels/ProfileEdgesEdit.ui b/src/Mod/Path/Gui/Resources/panels/ProfileEdgesEdit.ui index b61ff37120..fce6b1c7aa 100644 --- a/src/Mod/Path/Gui/Resources/panels/ProfileEdgesEdit.ui +++ b/src/Mod/Path/Gui/Resources/panels/ProfileEdgesEdit.ui @@ -33,8 +33,8 @@ 0 0 - 334 - 348 + 285 + 277 @@ -111,8 +111,8 @@ 0 0 - 334 - 320 + 120 + 96 @@ -181,8 +181,8 @@ 0 0 - 334 - 320 + 154 + 68 @@ -290,7 +290,7 @@ - 2 + 0 @@ -302,11 +302,6 @@ Right - - - On - - diff --git a/src/Mod/Path/PathScripts/PathContour.py b/src/Mod/Path/PathScripts/PathContour.py index 62bf2334a9..23b77599f8 100644 --- a/src/Mod/Path/PathScripts/PathContour.py +++ b/src/Mod/Path/PathScripts/PathContour.py @@ -136,21 +136,22 @@ class ObjectContour: else: profileparams['Offset'] = self.radius+obj.OffsetExtra.Value - depthparams = depth_params( - clearance_height=obj.ClearanceHeight.Value, - rapid_safety_space=obj.SafeHeight.Value, - start_depth=obj.StartDepth.Value, - step_down=obj.StepDown.Value, - z_finish_step=0.0, - final_depth=obj.FinalDepth.Value, - user_depths=None) + # depthparams = depth_params( + # clearance_height=obj.ClearanceHeight.Value, + # safe_height=obj.SafeHeight.Value, + # start_depth=obj.StartDepth.Value, + # step_down=obj.StepDown.Value, + # z_finish_step=0.0, + # final_depth=obj.FinalDepth.Value, + # user_depths=None) - PathLog.debug('depths: {}'.format(depthparams.get_depths())) + heights = [i for i in self.depthparams] + PathLog.debug('depths: {}'.format(heights)) profile.setParams(**profileparams) obj.AreaParams = str(profile.getParams()) PathLog.debug("Contour with params: {}".format(profile.getParams())) - sections = profile.makeSections(mode=0, project=True, heights=depthparams.get_depths()) + sections = profile.makeSections(mode=0, project=True, heights=heights) shapelist = [sec.getShape() for sec in sections] params = {'shapes': shapelist, @@ -181,7 +182,7 @@ class ObjectContour: profileparams['Thicken'] = True #{'Fill':0, 'Coplanar':0, 'Project':True, 'SectionMode':2, 'Thicken':True} profileparams['ToolRadius']= self.radius - self.radius *.005 profile.setParams(**profileparams) - sec = profile.makeSections(mode=0, project=False, heights=depthparams.get_depths())[-1].getShape() + sec = profile.makeSections(mode=0, project=False, heights=heights)[-1].getShape() simobj = sec.extrude(FreeCAD.Vector(0,0,baseobject.BoundBox.ZMax)) return pp, simobj @@ -193,8 +194,7 @@ class ObjectContour: if not obj.Active: path = Path.Path("(inactive operation)") obj.Path = path - if obj.ViewObject: - obj.ViewObject.Visibility = False + obj.ViewObject.Visibility = False return commandlist = [] @@ -215,6 +215,15 @@ class ObjectContour: else: self.radius = tool.Diameter/2 + self.depthparams = depth_params( + clearance_height=obj.ClearanceHeight.Value, + safe_height=obj.SafeHeight.Value, + start_depth=obj.StartDepth.Value, + step_down=obj.StepDown.Value, + z_finish_step=0.0, + final_depth=obj.FinalDepth.Value, + user_depths=None) + commandlist.append(Path.Command("(" + obj.Label + ")")) if obj.UseComp: @@ -250,8 +259,8 @@ class ObjectContour: FreeCAD.Console.PrintError("Something unexpected happened. Unable to generate a contour path. Check project and tool config.") if hasattr(baseobject, "Shape") and not isPanel: - bb = baseobject.Shape.BoundBox - env = PathUtils.getEnvelope(partshape=baseobject.Shape, subshape=None, stockheight=bb.ZLength + (obj.StartDepth.Value-bb.ZMax)) + #bb = baseobject.Shape.BoundBox + env = PathUtils.getEnvelope(partshape=baseobject.Shape, subshape=None, depthparams=self.depthparams) try: (pp, sim) = self._buildPathArea(obj, env, start=obj.StartPoint,getsim=getsim) commandlist.extend(pp.Commands) @@ -264,9 +273,8 @@ class ObjectContour: path = Path.Path(commandlist) obj.Path = path - if obj.ViewObject: - obj.ViewObject.Visibility = True - return sim + obj.ViewObject.Visibility = True + return sim class _ViewProviderContour: diff --git a/src/Mod/Path/PathScripts/PathMillFace.py b/src/Mod/Path/PathScripts/PathMillFace.py index b27b4a25ce..40fc1723a4 100644 --- a/src/Mod/Path/PathScripts/PathMillFace.py +++ b/src/Mod/Path/PathScripts/PathMillFace.py @@ -32,6 +32,7 @@ from FreeCAD import Vector import PathScripts.PathLog as PathLog from PathScripts.PathUtils import waiting_effects from PathScripts.PathUtils import makeWorkplane +from PathScripts.PathUtils import depth_params LOG_MODULE = 'PathMillFace' PathLog.setLevel(PathLog.Level.INFO, LOG_MODULE) @@ -165,7 +166,6 @@ class ObjectFace: @waiting_effects def _buildPathArea(self, obj, baseobject): """build the face path using PathArea""" - from PathScripts.PathUtils import depth_params PathLog.track() boundary = Path.Area() @@ -186,18 +186,11 @@ class ObjectFace: Pattern = ['ZigZag', 'Offset', 'Spiral', 'ZigZagOffset', 'Line', 'Grid', 'Triangle'] pocketparams['PocketMode'] = Pattern.index(obj.OffsetPattern) + 1 - depthparams = depth_params( - clearance_height=obj.ClearanceHeight.Value, - rapid_safety_space=obj.SafeHeight.Value, - start_depth=obj.StartDepth.Value, - step_down=obj.StepDown, - z_finish_step=obj.FinishDepth.Value, - final_depth=obj.FinalDepth.Value, - user_depths=None) + heights = [i for i in self.depthparams] boundary.setParams(**pocketparams) obj.AreaParams = str(boundary.getParams()) - sections = boundary.makeSections(mode=0, project=False, heights=depthparams.get_depths()) + sections = boundary.makeSections(mode=0, project=False, heights=heights) shapelist = [sec.getShape() for sec in sections] params = {'shapes': shapelist, @@ -214,22 +207,7 @@ class ObjectFace: PathLog.debug("Generating Path with params: {}".format(params)) pp = Path.fromShapes(**params) - # if True: - # from PathScripts.PathUtils import CollisionTester - # parentJob = PathUtils.findParentJob(obj) - # if parentJob is None: - # pass - # base = parentJob.Base - # if base is None: - # pass - # pocketparams['Thicken'] = True #{'Fill':0, 'Coplanar':0, 'Project':True, 'SectionMode':2, 'Thicken':True} - # pocketparams['ToolRadius']= self.radius - self.radius *.005 - # boundary.setParams(**pocketparams) - # sec = boundary.makeSections(heights=[0.0])[0].getShape() - # cutPath = sec.extrude(FreeCAD.Vector(0,0,baseobject.BoundBox.ZMax)) - # c = CollisionTester() - # c.getCollisionSim(base.Shape, cutPath) return pp def execute(self, obj): @@ -244,6 +222,15 @@ class ObjectFace: toolLoad = obj.ToolController + self.depthparams = depth_params( + clearance_height=obj.ClearanceHeight.Value, + safe_height=obj.SafeHeight.Value, + start_depth=obj.StartDepth.Value, + step_down=obj.StepDown, + z_finish_step=obj.FinishDepth.Value, + final_depth=obj.FinalDepth.Value, + user_depths=None) + 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 @@ -298,9 +285,9 @@ class ObjectFace: bb = planeshape.BoundBox if obj.BoundaryShape == 'Boundbox': bbperim = Part.makeBox(bb.XLength, bb.YLength, 1, Vector(bb.XMin, bb.YMin, bb.ZMin), Vector(0, 0, 1)) - env = PathUtils.getEnvelope(partshape=bbperim, stockheight=bb.ZLength + (obj.StartDepth.Value-bb.ZMax)) + env = PathUtils.getEnvelope(partshape=bbperim, depthparams=self.depthparams) else: - env = PathUtils.getEnvelope(partshape=planeshape, stockheight=bb.ZLength + (obj.StartDepth.Value-bb.ZMax)) + env = PathUtils.getEnvelope(partshape=planeshape, depthparams=self.depthparams) try: commandlist.extend(self._buildPathArea(obj, env).Commands) diff --git a/src/Mod/Path/PathScripts/PathPocket.py b/src/Mod/Path/PathScripts/PathPocket.py index c1db84b3cb..500a2c7249 100644 --- a/src/Mod/Path/PathScripts/PathPocket.py +++ b/src/Mod/Path/PathScripts/PathPocket.py @@ -38,7 +38,7 @@ if FreeCAD.GuiUp: LOG_MODULE = 'PathPocket' PathLog.setLevel(PathLog.Level.INFO, LOG_MODULE) -PathLog.trackModule('PathPocket') +#PathLog.trackModule('PathPocket') FreeCAD.setLogLevel('Path.Area', 0) @@ -174,9 +174,6 @@ class ObjectPocket: pocket.setPlane(Part.makeCircle(10)) pocket.add(envelopeshape) - removalshape = FreeCAD.ActiveDocument.addObject("Part::Feature", "Envelope") - removalshape.Shape = envelopeshape - stepover = (self.radius * 2) * (float(obj.StepOver)/100) pocketparams = {'Fill': 0, @@ -195,16 +192,10 @@ class ObjectPocket: obj.AreaParams = str(pocket.getParams()) PathLog.debug("Pocketing with params: {}".format(pocket.getParams())) - depthparams = depth_params( - clearance_height=obj.ClearanceHeight.Value, - rapid_safety_space=obj.SafeHeight.Value, - start_depth=obj.StartDepth.Value, - step_down=obj.StepDown.Value, - z_finish_step=0.0, - final_depth=obj.FinalDepth.Value, - user_depths=None) + heights = [i for i in self.depthparams] + PathLog.debug('pocket section heights: {}'.format(heights)) + sections = pocket.makeSections(mode=0, project=False, heights=heights) - sections = pocket.makeSections(mode=0, project=False, heights=depthparams.get_depths()) shapelist = [sec.getShape() for sec in sections] params = {'shapes': shapelist, @@ -222,11 +213,11 @@ class ObjectPocket: if getsim: pocketparams['Thicken'] = True pocketparams['ToolRadius']= self.radius - self.radius *.005 + pocketparams['Stepdown'] = -1 pocket.setParams(**pocketparams) - #pocket.makeSections(mode=0, project=False, heights=depthparams.get_depths()) + #pocket.makeSections(mode=0, project=False, heights=heights) simobj = pocket.getShape().extrude(FreeCAD.Vector(0,0,obj.StepDown.Value)) - removalshape = FreeCAD.ActiveDocument.addObject("Part::Feature", "simshape") - removalshape.Shape = simobj + #removalshape = FreeCAD.ActiveDocument.addObject("Part::Feature", "simshape") return pp, simobj @@ -248,6 +239,15 @@ class ObjectPocket: if baseobject is None: return + self.depthparams = depth_params( + clearance_height=obj.ClearanceHeight.Value, + safe_height=obj.SafeHeight.Value, + start_depth=obj.StartDepth.Value, + step_down=obj.StepDown.Value, + z_finish_step=0.0, + 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.") @@ -275,13 +275,13 @@ class ObjectPocket: edges = [getattr(b[0].Shape, sub) for sub in b[1]] shape = Part.makeFace(edges, 'Part::FaceMakerSimple') - env = PathUtils.getEnvelope(baseobject.Shape, subshape=shape, stockheight=obj.StartDepth) + env = PathUtils.getEnvelope(baseobject.Shape, subshape=shape, depthparams=self.depthparams) if PathLog.getLevel(PathLog.thisModule()) == PathLog.Level.DEBUG: removalshape=FreeCAD.ActiveDocument.addObject("Part::Feature","removalshape") - removalshape.Shape = env.cut(baseobject.Shape) + removalshape.Shape = env try: - (pp, sim) = self._buildPathArea(obj, env.cut(baseobject.Shape), getsim=getsim) + (pp, sim) = self._buildPathArea(obj, env, getsim=getsim) if sim is not None: simlist.append(sim) commandlist.extend(pp.Commands) @@ -291,9 +291,9 @@ class ObjectPocket: else: # process the job base object as a whole PathLog.debug("processing the whole job base object") - env = PathUtils.getEnvelope(baseobject.Shape, subshape=None, stockheight=obj.StartDepth) + env = PathUtils.getEnvelope(baseobject.Shape, subshape=None, depthparams=self.depthparams) try: - (pp, sim) = self._buildPathArea(obj, env.cut(baseobject.Shape), getsim=getsim) + (pp, sim) = self._buildPathArea(obj, env, getsim=getsim) commandlist.extend(pp.Commands) if sim is not None: simlist.append(sim) @@ -309,13 +309,18 @@ class ObjectPocket: path = Path.Path(commandlist) obj.Path = path obj.ViewObject.Visibility = True - if len(simlist) == 0: - return None - if len(simlist) > 1: - return simlist[0].fuse(simlist[1:]) - else: - return simlist[0] + PathLog.debug(simlist) + simshape = None + if len(simlist) > 1: + simshape=simlist[0].fuse(simlist[1:]) + elif len(simlist) == 1: + simshape = simlist[0] + + if simshape is not None and PathLog.getLevel(PathLog.thisModule()) == PathLog.Level.DEBUG: + sim=FreeCAD.ActiveDocument.addObject("Part::Feature","simshape") + sim.Shape = simshape + return simshape class _CommandSetPocketStartPoint: def GetResources(self): diff --git a/src/Mod/Path/PathScripts/PathProfile.py b/src/Mod/Path/PathScripts/PathProfile.py index 888ec8c6e1..7d57c3dd9b 100644 --- a/src/Mod/Path/PathScripts/PathProfile.py +++ b/src/Mod/Path/PathScripts/PathProfile.py @@ -176,16 +176,9 @@ class ObjectProfile: # PathLog.debug("About to profile with params: {}".format(profileparams)) PathLog.debug("About to profile with params: {}".format(profile.getParams())) - depthparams = depth_params( - clearance_height=obj.ClearanceHeight.Value, - rapid_safety_space=obj.SafeHeight.Value, - start_depth=obj.StartDepth.Value, - step_down=obj.StepDown.Value, - z_finish_step=0.0, - final_depth=obj.FinalDepth.Value, - user_depths=None) + heights = [i for i in self.depthparams] - sections = profile.makeSections(mode=0, project=True, heights=depthparams.get_depths()) + sections = profile.makeSections(mode=0, project=True, heights=heights) shapelist = [sec.getShape() for sec in sections] params = {'shapes': shapelist, @@ -218,7 +211,7 @@ class ObjectProfile: profileparams['Thicken'] = True #{'Fill':0, 'Coplanar':0, 'Project':True, 'SectionMode':2, 'Thicken':True} profileparams['ToolRadius']= self.radius - self.radius *.005 profile.setParams(**profileparams) - sec = profile.makeSections(mode=0, project=False, heights=depthparams.get_depths())[-1].getShape() + sec = profile.makeSections(mode=0, project=False, heights=heights)[-1].getShape() simobj = sec.extrude(FreeCAD.Vector(0,0,baseobject.BoundBox.ZMax)) return pp, simobj @@ -232,6 +225,15 @@ class ObjectProfile: obj.ViewObject.Visibility = False return + self.depthparams = depth_params( + clearance_height=obj.ClearanceHeight.Value, + safe_height=obj.SafeHeight.Value, + start_depth=obj.StartDepth.Value, + step_down=obj.StepDown.Value, + z_finish_step=0.0, + final_depth=obj.FinalDepth.Value, + user_depths=None) + commandlist = [] toolLoad = obj.ToolController if toolLoad is None or toolLoad.ToolNumber == 0: @@ -281,7 +283,7 @@ class ObjectProfile: f = Part.makeFace(wire, 'Part::FaceMakerSimple') drillable = PathUtils.isDrillable(baseobject.Shape, wire) if (drillable and obj.processCircles) or (not drillable and obj.processHoles): - env = PathUtils.getEnvelope(baseobject.Shape, subshape=f, stockheight=obj.StartDepth) + env = PathUtils.getEnvelope(baseobject.Shape, subshape=f, depthparams=self.depthparams) try: (pp, sim) = self._buildPathArea(obj, baseobject=env, isHole=True, start=None, getsim=getsim) commandlist.extend(pp.Commands) @@ -293,7 +295,7 @@ class ObjectProfile: profileshape = Part.makeCompound(faces) if obj.processPerimeter: - env = PathUtils.getEnvelope(baseobject.Shape, subshape=profileshape, stockheight=obj.StartDepth) + env = PathUtils.getEnvelope(baseobject.Shape, subshape=profileshape, depthparams=self.depthparams) try: (pp, sim) = self._buildPathArea(obj, baseobject=env, start=None, getsim=getsim) commandlist.extend(pp.commands) @@ -309,7 +311,7 @@ class ObjectProfile: for shape in shapes: for wire in shape.Wires: f = Part.makeFace(wire, 'Part::FaceMakerSimple') - env = PathUtils.getEnvelope(baseobject.Shape, subshape=f, stockheight=obj.StartDepth) + env = PathUtils.getEnvelope(baseobject.Shape, subshape=f, depthparams=self.depthparams) try: (pp, sim) = self._buildPathArea(obj, baseobject=env, isHole=False, start=None, getsim=getsim) commandlist.extend(pp.commands) @@ -323,7 +325,7 @@ class ObjectProfile: drillable = PathUtils.isDrillable(baseobject.Proxy, wire) if (drillable and obj.processCircles) or (not drillable and obj.processHoles): f = Part.makeFace(wire, 'Part::FaceMakerSimple') - env = PathUtils.getEnvelope(baseobject.Shape, subshape=f, stockheight=obj.StartDepth) + env = PathUtils.getEnvelope(baseobject.Shape, subshape=f, depthparams=self.depthparams) try: (pp, sim) = self._buildPathArea(obj, baseobject=env, isHole=True, start=None, getsim=getsim) commandlist.extend(pp.commands) diff --git a/src/Mod/Path/PathScripts/PathProfileEdges.py b/src/Mod/Path/PathScripts/PathProfileEdges.py index 70efb1782d..6a395bb690 100644 --- a/src/Mod/Path/PathScripts/PathProfileEdges.py +++ b/src/Mod/Path/PathScripts/PathProfileEdges.py @@ -166,16 +166,8 @@ class ObjectProfile: PathLog.debug("About to profile with params: {}".format(profile.getParams())) - depthparams = depth_params( - clearance_height=obj.ClearanceHeight.Value, - rapid_safety_space=obj.SafeHeight.Value, - start_depth=obj.StartDepth.Value, - step_down=obj.StepDown.Value, - z_finish_step=0.0, - final_depth=obj.FinalDepth.Value, - user_depths=None) - - sections = profile.makeSections(mode=0, project=True, heights=depthparams.get_depths()) + heights = [i for i in self.depthparams] + sections = profile.makeSections(mode=0, project=True, heights=heights) shapelist = [sec.getShape() for sec in sections] params = {'shapes': shapelist, @@ -202,7 +194,7 @@ class ObjectProfile: profileparams['Thicken'] = True #{'Fill':0, 'Coplanar':0, 'Project':True, 'SectionMode':2, 'Thicken':True} profileparams['ToolRadius']= self.radius - self.radius *.005 profile.setParams(**profileparams) - sec = profile.makeSections(mode=0, project=False, heights=depthparams.get_depths())[-1].getShape() + sec = profile.makeSections(mode=0, project=False, heights=heights)[-1].getShape() simobj = sec.extrude(FreeCAD.Vector(0,0,baseobject.BoundBox.ZMax)) return pp, simobj @@ -211,6 +203,7 @@ class ObjectProfile: def execute(self, obj, getsim=False): # import Part # math #DraftGeomUtils commandlist = [] + sim = None if not obj.Active: path = Path.Path("(inactive operation)") @@ -225,6 +218,15 @@ class ObjectProfile: if baseobject is None: return + self.depthparams = depth_params( + clearance_height=obj.ClearanceHeight.Value, + safe_height=obj.SafeHeight.Value, + start_depth=obj.StartDepth.Value, + step_down=obj.StepDown.Value, + z_finish_step=0.0, + 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.") @@ -264,7 +266,7 @@ class ObjectProfile: zShift = b[0].Shape.BoundBox.ZMin - f.BoundBox.ZMin newPlace = FreeCAD.Placement(FreeCAD.Vector(0, 0, zShift), f.Placement.Rotation) f.Placement = newPlace - env = PathUtils.getEnvelope(baseobject.Shape, subshape=f, stockheight=obj.StartDepth) + env = PathUtils.getEnvelope(baseobject.Shape, subshape=f, depthparams=self.depthparams) try: (pp, sim) = self._buildPathArea(obj, baseobject=env, start=obj.StartPoint, getsim=getsim) diff --git a/src/Mod/Path/PathScripts/PathSanity.py b/src/Mod/Path/PathScripts/PathSanity.py index 64728c0466..3c2ed291d8 100644 --- a/src/Mod/Path/PathScripts/PathSanity.py +++ b/src/Mod/Path/PathScripts/PathSanity.py @@ -29,13 +29,17 @@ from __future__ import print_function from PySide import QtCore import FreeCAD import FreeCADGui -#import PathScripts.PathUtils as PU import PathScripts -import PathScripts.PathCollision as PC +import PathScripts.PathLog as PathLog +# import PathScripts.PathCollision as PC # Qt tanslation handling def translate(context, text, disambig=None): return QtCore.QCoreApplication.translate(context, text, disambig) +LOG_MODULE = 'PathSanity' +PathLog.setLevel(PathLog.Level.INFO, LOG_MODULE) +#PathLog.trackModule('PathSanity') + class CommandPathSanity: baseobj=None @@ -68,45 +72,41 @@ class CommandPathSanity: for item in obj.Group: print("Checking: " + item.Label) - if isinstance(item.Proxy, PathScripts.PathLoadTool.LoadTool): + if isinstance(item.Proxy, PathScripts.PathToolController.ToolController): toolcontrolcount += 1 self.__checkTC(item) if isinstance(item.Proxy, PathScripts.PathContour.ObjectContour): if item.Active: operationcount +=1 - simobj = item.Proxy.execute(item, getsim=True) - if simobj is not None: - print ('collision detected') - PC.getCollisionObject(self.baseobj, simobj) - #r.original = self.baseobj + # simobj = item.Proxy.execute(item, getsim=True) + # if simobj is not None: + # print ('collision detected') + # PC.getCollisionObject(self.baseobj, simobj) if isinstance(item.Proxy, PathScripts.PathProfile.ObjectProfile): if item.Active: operationcount +=1 - simobj = item.Proxy.execute(item, getsim=True) - if simobj is not None: - print ('collision detected') - PC.getCollisionObject(self.baseobj, simobj) - #r.original = self.baseobj + # simobj = item.Proxy.execute(item, getsim=True) + # if simobj is not None: + # print ('collision detected') + # PC.getCollisionObject(self.baseobj, simobj) if isinstance(item.Proxy, PathScripts.PathProfileEdges.ObjectProfile): if item.Active: operationcount +=1 - simobj = item.Proxy.execute(item, getsim=True) - if simobj is not None: - print ('collision detected') - PC.getCollisionObject(self.baseobj, simobj) - #r.original = self.baseobj + # simobj = item.Proxy.execute(item, getsim=True) + # if simobj is not None: + # print ('collision detected') + # PC.getCollisionObject(self.baseobj, simobj) if isinstance(item.Proxy, PathScripts.PathPocket.ObjectPocket): if item.Active: operationcount +=1 - simobj = item.Proxy.execute(item, getsim=True) - if simobj is not None: - print ('collision detected') - PC.getCollisionObject(self.baseobj, simobj) - #r.original = self.baseobj + # simobj = item.Proxy.execute(item, getsim=True) + # if simobj is not None: + # print ('collision detected') + # PC.getCollisionObject(self.baseobj, simobj) if isinstance(item.Proxy, PathScripts.PathDrilling.ObjectDrilling): if item.Active: diff --git a/src/Mod/Path/PathScripts/PathSurface.py b/src/Mod/Path/PathScripts/PathSurface.py index 48120ef3cb..0500ef3769 100644 --- a/src/Mod/Path/PathScripts/PathSurface.py +++ b/src/Mod/Path/PathScripts/PathSurface.py @@ -169,7 +169,8 @@ class ObjectSurface: surface = s t_before = time.time() - zheights = depthparams.get_depths() + zheights = [i for i in depthparams] + wl = ocl.Waterline() # wl = ocl.AdaptiveWaterline() # this is slower, ca 60 seconds on i7 # CPU diff --git a/src/Mod/Path/PathScripts/PathUtils.py b/src/Mod/Path/PathScripts/PathUtils.py index a67c523337..f2001a8f46 100644 --- a/src/Mod/Path/PathScripts/PathUtils.py +++ b/src/Mod/Path/PathScripts/PathUtils.py @@ -38,7 +38,7 @@ from PySide import QtGui LOG_MODULE = 'PathUtils' PathLog.setLevel(PathLog.Level.INFO, LOG_MODULE) -# PathLog.trackModule('PathUtils') +#PathLog.trackModule('PathUtils') FreeCAD.setLogLevel('Path.Area', 0) @@ -243,7 +243,7 @@ def makeWorkplane(shape): return c -def getEnvelope(partshape, subshape=None, stockheight=None): +def getEnvelope(partshape, subshape=None, depthparams=None): ''' getEnvelope(partshape, stockheight=None) returns a shape corresponding to the partshape silhouette extruded to height. @@ -252,11 +252,13 @@ def getEnvelope(partshape, subshape=None, stockheight=None): partshape = solid object stockheight = float - Absolute Z height of the top of material before cutting. ''' - PathLog.track(partshape, subshape, stockheight) + PathLog.track(partshape, subshape, depthparams) # if partshape.Volume == 0.0: #Not a 3D object # return None + + zShift = 0 if subshape is not None: if isinstance(subshape, Part.Face): PathLog.debug('processing a face') @@ -267,22 +269,31 @@ def getEnvelope(partshape, subshape=None, stockheight=None): PathLog.debug("About to section with params: {}".format(area.getParams())) sec = area.makeSections(heights=[0.0], project=True)[0].getShape() - zShift = partshape.BoundBox.ZMin - subshape.BoundBox.ZMin + # zShift = partshape.BoundBox.ZMin - subshape.BoundBox.ZMin PathLog.debug('partshapeZmin: {}, subshapeZMin: {}, zShift: {}'.format(partshape.BoundBox.ZMin, subshape.BoundBox.ZMin, zShift)) - newPlace = FreeCAD.Placement(FreeCAD.Vector(0, 0, zShift), sec.Placement.Rotation) - sec.Placement = newPlace else: area = Path.Area(Fill=2, Coplanar=0).add(partshape) area.setPlane(makeWorkplane(partshape)) sec = area.makeSections(heights=[0.0], project=True)[0].getShape() - if stockheight is not None: - eLength = float(stockheight)-partshape.BoundBox.ZMin - PathLog.debug('boundbox zMIN: {} elength: {}'.format(partshape.BoundBox.ZMin, eLength)) - envelopeshape = sec.extrude(FreeCAD.Vector(0, 0, eLength)) + # If depthparams are passed, use it to calculate bottom and height of + # envelope + if depthparams is not None: +# eLength = float(stockheight)-partshape.BoundBox.ZMin + eLength = depthparams.safe_height - depthparams.final_depth + #envelopeshape = sec.extrude(FreeCAD.Vector(0, 0, eLength)) + zShift = depthparams.final_depth - sec.BoundBox.ZMin + PathLog.debug('boundbox zMIN: {} elength: {} zShift {}'.format(partshape.BoundBox.ZMin, eLength, zShift)) else: - envelopeshape = sec.extrude(FreeCAD.Vector(0, 0, partshape.BoundBox.ZLength)) + eLength = partshape.BoundBox.ZLength - sec.BoundBox.ZMin + + # Shift the section based on selection and depthparams. + newPlace = FreeCAD.Placement(FreeCAD.Vector(0, 0, zShift), sec.Placement.Rotation) + sec.Placement = newPlace + + # Extrude the section to top of Boundbox or desired height + envelopeshape = sec.extrude(FreeCAD.Vector(0, 0, eLength)) if PathLog.getLevel(PathLog.thisModule()) == PathLog.Level.DEBUG: removalshape = FreeCAD.ActiveDocument.addObject("Part::Feature", "Envelope") removalshape.Shape = envelopeshape @@ -672,26 +683,27 @@ def sort_jobs(locations, keys, attractors=[]): class depth_params: '''calculates the intermediate depth values for various operations given the starting, ending, and stepdown parameters - (self, clearance_height, rapid_safety_space, start_depth, step_down, z_finish_depth, final_depth, [user_depths=None]) + (self, clearance_height, safe_height, start_depth, step_down, z_finish_depth, final_depth, [user_depths=None], equalstep=False) Note: if user_depths are supplied, only user_depths will be used. clearance_height: Height to clear all obstacles - rapid_safety_space: Height to rapid between locations - start_depth: Top of Stock + safe_height: Height to clear raw stock material + start_depth: Top of Model step_down: Distance to step down between passes (always positive) z_finish_step: Maximum amount of material to remove on the final pass final_depth: Lowest point of the cutting operation user_depths: List of specified depths + equalstep: Boolean. If True, steps down except Z_finish_depth will be balanced. ''' - def __init__(self, clearance_height, rapid_safety_space, start_depth, step_down, z_finish_step, final_depth, user_depths=None, equalstep=False): - '''self, clearance_height, rapid_safety_space, start_depth, step_down, z_finish_depth, final_depth, [user_depths=None]''' + def __init__(self, clearance_height, safe_height, start_depth, step_down, z_finish_step, final_depth, user_depths=None, equalstep=False): + '''self, clearance_height, safe_height, start_depth, step_down, z_finish_depth, final_depth, [user_depths=None], equalstep=False''' if z_finish_step > step_down: raise ValueError('z_finish_step must be less than step_down') self.__clearance_height = clearance_height - self.__rapid_safety_space = math.fabs(rapid_safety_space) + self.__safe_height = math.fabs(safe_height) self.__start_depth = start_depth self.__step_down = math.fabs(step_down) self.__z_finish_step = math.fabs(z_finish_step) @@ -712,33 +724,59 @@ class depth_params: @property def clearance_height(self): """ - Height of all vises, clamps, and other obstructions. Rapid moves at clearance height + Height of all vises, clamps, and other obstructions. Rapid moves at clearance height are always assumed to be safe from collision. """ return self.__clearance_height @property - def rapid_safety_space(self): - return self.__rapid_safety_space + def safe_height(self): + """ + Height of top of raw stock material. Rapid moves above safe height are + assumed to be safe within an operation. May not be safe between + operations or tool changes. + All moves below safe height except retraction should be at feed rate. + """ + return self.__safe_height @property def start_depth(self): + """ + Start Depth is the top of the model. + """ return self.__start_depth @property def step_down(self): + """ + Maximum step down value between passes. Step-Down may be less than + this value, especially if equalstep is True. + """ return self.__step_down @property def z_finish_depth(self): + """ + The amount of material to remove on the finish pass. If given, the + final pass will remove exactly this amount. + """ return self.__z_finish_depth @property def final_depth(self): + """ + The height of the cutter during the last pass or finish pass if + z_finish_pass is given. + """ return self.__final_depth @property def user_depths(self): + """ + Returns a list of the user_specified depths. If user_depths were given + in __init__, these depths override all calculation and only these are + used. + """ return self.__user_depths def __get_depths(self, equalstep=False): diff --git a/src/Mod/Path/PathTests/TestPathDepthParams.py b/src/Mod/Path/PathTests/TestPathDepthParams.py index c8f4ed3e88..02e441236d 100644 --- a/src/Mod/Path/PathTests/TestPathDepthParams.py +++ b/src/Mod/Path/PathTests/TestPathDepthParams.py @@ -30,7 +30,7 @@ class depthTestCases(unittest.TestCase): def test00(self): '''Stepping down to zero ''' clearance_height= 15 - rapid_safety_space = 12 + safe_height = 12 start_depth = 10 step_down = 2 @@ -40,7 +40,7 @@ class depthTestCases(unittest.TestCase): expected =[8,6,4,2,1,0] - d = PU.depth_params(clearance_height, rapid_safety_space, start_depth, step_down, z_finish_step, final_depth, user_depths) + d = PU.depth_params(clearance_height, safe_height, start_depth, step_down, z_finish_step, final_depth, user_depths) r = [i for i in d] self.assertListEqual (r, expected) @@ -48,7 +48,7 @@ class depthTestCases(unittest.TestCase): '''Stepping from zero to a negative depth ''' clearance_height= 10 - rapid_safety_space = 5 + safe_height = 5 start_depth = 0 step_down = 2 @@ -58,14 +58,14 @@ class depthTestCases(unittest.TestCase): expected =[-2, -4, -6, -8, -10] - d = PU.depth_params(clearance_height, rapid_safety_space, start_depth, step_down, z_finish_step, final_depth, user_depths) + d = PU.depth_params(clearance_height, safe_height, start_depth, step_down, z_finish_step, final_depth, user_depths) r = [i for i in d] self.assertListEqual (r, expected) def test20(self): '''Start and end are equal or start lower than finish ''' clearance_height= 15 - rapid_safety_space = 12 + safe_height = 12 start_depth = 10 step_down = 2 @@ -75,7 +75,7 @@ class depthTestCases(unittest.TestCase): expected =[10] - d = PU.depth_params(clearance_height, rapid_safety_space, start_depth, step_down, z_finish_step, final_depth, user_depths) + d = PU.depth_params(clearance_height, safe_height, start_depth, step_down, z_finish_step, final_depth, user_depths) r = [i for i in d] self.assertListEqual (r, expected) @@ -84,14 +84,14 @@ class depthTestCases(unittest.TestCase): expected =[] - d = PU.depth_params(clearance_height, rapid_safety_space, start_depth, step_down, z_finish_step, final_depth, user_depths) + d = PU.depth_params(clearance_height, safe_height, start_depth, step_down, z_finish_step, final_depth, user_depths) r = [i for i in d] self.assertListEqual (r, expected) def test30(self): '''User Parameters passed in''' clearance_height= 10 - rapid_safety_space = 5 + safe_height = 5 start_depth = 0 step_down = 2 @@ -101,14 +101,14 @@ class depthTestCases(unittest.TestCase): expected =[2, 4, 8, 10, 11, 12] - d = PU.depth_params(clearance_height, rapid_safety_space, start_depth, step_down, z_finish_step, final_depth, user_depths) + d = PU.depth_params(clearance_height, safe_height, start_depth, step_down, z_finish_step, final_depth, user_depths) r = [i for i in d] self.assertListEqual (r, expected) def test40(self): '''z_finish_step passed in.''' clearance_height= 10 - rapid_safety_space = 5 + safe_height = 5 start_depth = 0 step_down = 2 @@ -118,7 +118,7 @@ class depthTestCases(unittest.TestCase): expected =[-2, -4, -6, -8, -9, -10] - d = PU.depth_params(clearance_height, rapid_safety_space, start_depth, step_down, z_finish_step, final_depth, user_depths) + d = PU.depth_params(clearance_height, safe_height, start_depth, step_down, z_finish_step, final_depth, user_depths) r = [i for i in d] self.assertListEqual (r, expected) @@ -126,7 +126,7 @@ class depthTestCases(unittest.TestCase): def test50(self): '''stepping down with equalstep=True''' clearance_height= 10 - rapid_safety_space = 5 + safe_height = 5 start_depth = 10 step_down = 3 @@ -136,7 +136,7 @@ class depthTestCases(unittest.TestCase): expected =[7.5, 5.0, 2.5, 0] - d = PU.depth_params(clearance_height, rapid_safety_space, start_depth, step_down, z_finish_step, final_depth, user_depths, equalstep=True) + d = PU.depth_params(clearance_height, safe_height, start_depth, step_down, z_finish_step, final_depth, user_depths, equalstep=True) r = [i for i in d] self.assertListEqual (r, expected) @@ -144,7 +144,7 @@ class depthTestCases(unittest.TestCase): def test60(self): '''stepping down with equalstep=True and a finish depth''' clearance_height= 10 - rapid_safety_space = 5 + safe_height = 5 start_depth = 10 step_down = 3 @@ -154,14 +154,14 @@ class depthTestCases(unittest.TestCase): expected =[7.0, 4.0, 1.0, 0] - d = PU.depth_params(clearance_height, rapid_safety_space, start_depth, step_down, z_finish_step, final_depth, user_depths, equalstep=True) + d = PU.depth_params(clearance_height, safe_height, start_depth, step_down, z_finish_step, final_depth, user_depths, equalstep=True) r = [i for i in d] self.assertListEqual (r, expected) def test70(self): '''stepping down with stepdown greater than total depth''' clearance_height= 10 - rapid_safety_space = 5 + safe_height = 5 start_depth = 10 step_down = 20 @@ -171,7 +171,7 @@ class depthTestCases(unittest.TestCase): expected =[1.0, 0] - d = PU.depth_params(clearance_height, rapid_safety_space, start_depth, step_down, z_finish_step, final_depth, user_depths) + d = PU.depth_params(clearance_height, safe_height, start_depth, step_down, z_finish_step, final_depth, user_depths) r = [i for i in d] self.assertListEqual (r, expected)