diff --git a/src/Mod/Path/PathScripts/PathAreaOp.py b/src/Mod/Path/PathScripts/PathAreaOp.py index 0634cdf49c..0807b0d599 100644 --- a/src/Mod/Path/PathScripts/PathAreaOp.py +++ b/src/Mod/Path/PathScripts/PathAreaOp.py @@ -27,6 +27,7 @@ # with axis & rotation toggles and associated min/max values import FreeCAD +import FreeCADGui import Path import PathScripts.PathLog as PathLog import PathScripts.PathOp as PathOp @@ -36,8 +37,6 @@ import Draft # from PathScripts.PathUtils import waiting_effects from PySide import QtCore import math -if FreeCAD.GuiUp: - import FreeCADGui __title__ = "Base class for PathArea based operations." __author__ = "sliptonic (Brad Collette)" @@ -45,8 +44,8 @@ __url__ = "http://www.freecadweb.org" __doc__ = "Base class and properties for Path.Area based operations." __contributors__ = "mlampert [FreeCAD], russ4262 (Russell Johnson)" __createdDate__ = "2017" -__scriptVersion__ = "2e testing" -__lastModified__ = "2019-06-12 06:28 CST" +__scriptVersion__ = "2f testing" +__lastModified__ = "2019-06-12 14:12 CST" if False: PathLog.setLevel(PathLog.Level.DEBUG, PathLog.thisModule()) @@ -54,7 +53,6 @@ if False: else: PathLog.setLevel(PathLog.Level.INFO, PathLog.thisModule()) - # Qt translation handling def translate(context, text, disambig=None): return QtCore.QCoreApplication.translate(context, text, disambig) @@ -233,8 +231,6 @@ class ObjectOp(PathOp.ObjectOp): obj.FinalDepth.Value = finalDepth obj.OpStartDepth.Value = startDepth obj.OpFinalDepth.Value = finalDepth - # obj.OpStartDepth.UserString = str(startDepth) + ' mm' # Read-only - # obj.OpFinalDepth.UserString = str(finalDepth) + ' mm' # Read-only if obj.EnableRotation != 'Off': if self.initOpFinalDepth is None: @@ -380,8 +376,8 @@ class ObjectOp(PathOp.ObjectOp): if obj.StartDepth.Value == obj.OpStartDepth.Value: obj.StartDepth.Value = self.strDep - # Create visual axises for debugging purposes. - if PathLog.getLevel() == 2: + # Create visual axises when debugging. + if PathLog.getLevel(PathLog.thisModule()) == 4: self.visualAxis() else: self.strDep = obj.StartDepth.Value @@ -564,12 +560,12 @@ class ObjectOp(PathOp.ObjectOp): return [(xRotRad, yRotRad, zRotRad), (clrOfst, safOfst)] - def pocketRotationAnalysis(self, obj, norm, surf, prnt): - '''pocketRotationAnalysis(self, obj, norm, surf, prnt) + def faceRotationAnalysis(self, obj, norm, surf): + '''faceRotationAnalysis(self, obj, norm, surf) Determine X and Y independent rotation necessary to make normalAt = Z=1 (0,0,1) ''' PathLog.track() - praInfo = "pocketRotationAnalysis() in PathAreaOp.py" + praInfo = "faceRotationAnalysis() in PathAreaOp.py" rtn = False axis = 'X' orientation = 'X' @@ -677,8 +673,8 @@ class ObjectOp(PathOp.ObjectOp): else: praInfo += "\n - ... NO rotation triggered" - if prnt is True: - PathLog.info("praInfo: " + str(praInfo)) + PathLog.debug("\n" + str(praInfo)) + return (rtn, angle, axis, praInfo) def guiMessage(self, title, msg, show=False): @@ -722,6 +718,7 @@ class ObjectOp(PathOp.ObjectOp): zAx = 'zAxCyl' FreeCAD.ActiveDocument.addObject("App::DocumentObjectGroup","visualAxis") FreeCADGui.ActiveDocument.getObject('visualAxis').Visibility = False + vaGrp = FreeCAD.ActiveDocument.getObject("visualAxis") FreeCAD.ActiveDocument.addObject("Part::Cylinder", xAx) cyl = FreeCAD.ActiveDocument.getObject(xAx) @@ -730,11 +727,11 @@ class ObjectOp(PathOp.ObjectOp): cyl.Height = 0.01 cyl.Placement = FreeCAD.Placement(FreeCAD.Vector(0,0,0),FreeCAD.Rotation(FreeCAD.Vector(0,1,0),90)) cyl.purgeTouched() - FreeCAD.ActiveDocument.getObject("visualAxis").addObject(cyl) cylGui = FreeCADGui.ActiveDocument.getObject(xAx) cylGui.ShapeColor = (0.667,0.000,0.000) - cylGui.Transparency = 80 + cylGui.Transparency = 85 cylGui.Visibility = False + vaGrp.addObject(cyl) FreeCAD.ActiveDocument.addObject("Part::Cylinder", yAx) cyl = FreeCAD.ActiveDocument.getObject(yAx) @@ -742,12 +739,12 @@ class ObjectOp(PathOp.ObjectOp): cyl.Radius = self.yRotRad cyl.Height = 0.01 cyl.Placement = FreeCAD.Placement(FreeCAD.Vector(0,0,0),FreeCAD.Rotation(FreeCAD.Vector(1,0,0),90)) - FreeCAD.ActiveDocument.getObject("visualAxis").addObject(cyl) cyl.purgeTouched() cylGui = FreeCADGui.ActiveDocument.getObject(yAx) cylGui.ShapeColor = (0.000,0.667,0.000) - cylGui.Transparency = 80 + cylGui.Transparency = 85 cylGui.Visibility = False + vaGrp.addObject(cyl) if False: FreeCAD.ActiveDocument.addObject("Part::Cylinder", zAx) @@ -755,18 +752,19 @@ class ObjectOp(PathOp.ObjectOp): cyl.Label = zAx cyl.Radius = self.yRotRad cyl.Height = 0.01 - cyl.Placement = FreeCAD.Placement(FreeCAD.Vector(0,0,0),FreeCAD.Rotation(FreeCAD.Vector(1,0,0),90)) - FreeCAD.ActiveDocument.getObject("visualAxis").addObject(cyl) + # cyl.Placement = FreeCAD.Placement(FreeCAD.Vector(0,0,0),FreeCAD.Rotation(FreeCAD.Vector(1,0,0),90)) cyl.purgeTouched() cylGui = FreeCADGui.ActiveDocument.getObject(zAx) cylGui.ShapeColor = (0.000,0.000,0.498) - cylGui.Transparency = 80 + cylGui.Transparency = 85 cylGui.Visibility = False + vaGrp.addObject(cyl) + def useRotJobClones(self, cloneName): if FreeCAD.ActiveDocument.getObject('rotJobClones'): if cloneName == 'Delete': - if PathLog.getLevel() != 2: + if PathLog.getLevel(PathLog.thisModule()) < 4: for cln in FreeCAD.ActiveDocument.getObject('rotJobClones').Group: FreeCAD.ActiveDocument.removeObject(cln.Name) FreeCAD.ActiveDocument.removeObject('rotJobClones') @@ -854,7 +852,7 @@ class ObjectOp(PathOp.ObjectOp): clnStock.purgeTouched() return (clnBase, angle, clnStock, tag) - def applyInverseAngle(self, obj, clnBase, clnStock, axis, angle): + def applyInverseAngle(self, obj, clnBase, clnStock, axis, angle): if axis == 'X': vect = FreeCAD.Vector(1, 0, 0) elif axis == 'Y': @@ -864,12 +862,11 @@ class ObjectOp(PathOp.ObjectOp): clnStock = Draft.rotate(clnStock, (-2 * angle), center=FreeCAD.Vector(0.0, 0.0, 0.0), axis=vect, copy=False) clnBase.purgeTouched() clnStock.purgeTouched() - if obj.InverseAngle is False: - obj.InverseAngle = True - else: - obj.InverseAngle = False + # Update property and angle values + obj.InverseAngle = True angle = -1 * angle - PathLog.debug(" --Rotated to InverseAngle.") + + PathLog.info(translate("Path", "Rotated to inverse angle.")) return (clnBase, clnStock, angle) def calculateStartFinalDepths(self, obj, shape, stock): diff --git a/src/Mod/Path/PathScripts/PathPocketShape.py b/src/Mod/Path/PathScripts/PathPocketShape.py index 0188b74e89..c228b4f8d3 100644 --- a/src/Mod/Path/PathScripts/PathPocketShape.py +++ b/src/Mod/Path/PathScripts/PathPocketShape.py @@ -50,8 +50,8 @@ __url__ = "http://www.freecadweb.org" __doc__ = "Class and implementation of shape based Pocket operation." __contributors__ = "mlampert [FreeCAD], russ4262 (Russell Johnson)" __created__ = "2017" -__scriptVersion__ = "2e testing" -__lastModified__ = "2019-06-11 14:30 CST" +__scriptVersion__ = "2f testing" +__lastModified__ = "2019-06-12 14:12 CST" if False: PathLog.setLevel(PathLog.Level.DEBUG, PathLog.thisModule()) @@ -100,7 +100,7 @@ def extendWire(feature, wire, length): try: off2D = wire.makeOffset2D(length) except Exception as e: - PathLog.error("error: extendWire() off2D") + PathLog.error("extendWire(): wire.makeOffset2D()") PathLog.error(e) return False else: @@ -112,7 +112,7 @@ def extendWire(feature, wire, length): try: l0 = (ePts[0] - endPts[0]).Length except Exception as ee: - PathLog.error("error: extendWire() l0") + PathLog.error("extendWire(): (ePts[0] - endPts[0]).Length") PathLog.error(ee) return False else: @@ -174,7 +174,7 @@ class Extension(object): try: normal = tangent.cross(FreeCAD.Vector(0, 0, 1)).normalize() except: - PathLog.error(translate('PathPocket', 'Unable to getDirection(wire).')) + PathLog.error('getDirection(): tangent.cross(FreeCAD.Vector(0, 0, 1)).normalize()') return None else: poffPlus = e0.valueAt(midparam) + 0.01 * normal @@ -252,6 +252,7 @@ class ObjectPocket(PathPocketBase.ObjectPocket): def clasifySub(self, bs, sub): face = bs.Shape.getElement(sub) + def planarFaceFromExtrusionEdges(clsd): useFace = 'useFaceName' minArea = 0.0 @@ -262,7 +263,7 @@ class ObjectPocket(PathPocketBase.ObjectPocket): # Create planar face from edge mFF = Part.Face(Part.Wire(Part.__sortEdges__([edg]))) if mFF.isNull(): - PathLog.debug(' -Face(Part.Wire()) failed') + PathLog.debug('Face(Part.Wire()) failed') else: mFF.translate(FreeCAD.Vector(0, 0, face.BoundBox.ZMin - mFF.BoundBox.ZMin)) tmpFace = FreeCAD.ActiveDocument.addObject('Part::Feature', fName).Shape = mFF @@ -334,11 +335,11 @@ class ObjectPocket(PathPocketBase.ObjectPocket): msg += "\n
Bottom of pocket might be non-planar and/or not normal to spindle axis." msg += "\n
\n
3D pocket bottom is NOT available in this operation." msg = translate('Path', msg) - PathLog.error(msg) + PathLog.info(msg) title = translate('Path', 'Depth Warning') self.guiMessage(title, msg, False) else: - PathLog.error("Could not create a planar face from edges in {}.".format(sub)) + PathLog.error(translate("Path", "Failed to create a planar face from edges in {}.".format(sub))) else: PathLog.debug('type() == OTHER') PathLog.debug(' -type(face.Surface): {}'.format(type(face.Surface))) @@ -357,17 +358,17 @@ class ObjectPocket(PathPocketBase.ObjectPocket): (base, subsList) = obj.Base[p] go = False + # First, check all subs collectively for loop of faces if len(subsList) > 2: - # Check for loop of faces (go, norm, surf) = self.checkForFacesLoop(base, subsList) - if go is True: - PathLog.debug("Common Surface.Axis value found for loop faces.") + PathLog.debug("Common Surface.Axis or normalAt() value found for loop faces.") rtn = False - (rtn, angle, axis, praInfo) = self.pocketRotationAnalysis(obj, norm, surf, prnt=True) + subCount += 1 + (rtn, angle, axis, praInfo) = self.faceRotationAnalysis(obj, norm, surf) if rtn is True: - (clnBase, angle, clnStock, tag) = self.applyRotationalAnalysis(obj, base, angle, axis, len(subsList)) + (clnBase, angle, clnStock, tag) = self.applyRotationalAnalysis(obj, base, angle, axis, subCount) # Verify faces are correctly oriented - InverseAngle might be necessary PathLog.debug("Checking if faces are oriented correctly after rotation...") @@ -378,21 +379,25 @@ class ObjectPocket(PathPocketBase.ObjectPocket): rtn = False break if rtn is False: - if obj.AttemptInverseAngle is True: + if obj.AttemptInverseAngle is True and obj.InverseAngle is False: (clnBase, clnStock, angle) = self.applyInverseAngle(obj, clnBase, clnStock, axis, angle) else: - PathLog.error(" --Consider toggling the InverseAngle property and recomputing the operation.") + PathLog.info(translate("Path", "Consider toggling the InverseAngle property and recomputing the operation.")) tup = clnBase, subsList, angle, axis, clnStock else: - PathLog.error(" -Error with pocketRotationAnalysis()") + PathLog.debug("No rotation used") + axis = 'X' + angle = 0.0 + stock = PathUtils.findParentJob(obj).Stock + tup = base, subsList, angle, axis, stock # Eif allTuples.append(tup) baseSubsTuples.append(tup) # Eif if go is False: - PathLog.debug("Will process subs individually ...") + PathLog.debug(translate('Path', "Processing subs individually ...")) for sub in subsList: subCount += 1 if 'Face' in sub: @@ -401,26 +406,26 @@ class ObjectPocket(PathPocketBase.ObjectPocket): PathLog.debug(translate('Path', "Base Geometry sub: {}".format(sub))) face = base.Shape.getElement(sub) (norm, surf) = self.getFaceNormAndSurf(face) - (rtn, angle, axis, praInfo)= self.pocketRotationAnalysis(obj, norm, surf, prnt=True) + (rtn, angle, axis, praInfo)= self.faceRotationAnalysis(obj, norm, surf) if rtn is True: (clnBase, angle, clnStock, tag) = self.applyRotationalAnalysis(obj, base, angle, axis, subCount) # Verify faces are correctly oriented - InverseAngle might be necessary faceIA = clnBase.Shape.getElement(sub) (norm, surf) = self.getFaceNormAndSurf(faceIA) - (rtn, praAngle, praAxis, praInfo) = self.pocketRotationAnalysis(obj, norm, surf, prnt=False) + (rtn, praAngle, praAxis, praInfo) = self.faceRotationAnalysis(obj, norm, surf) if rtn is True: - PathLog.error(" --Face not aligned after initial rotation.") - if obj.AttemptInverseAngle is True: + PathLog.debug("Face not aligned after initial rotation.") + if obj.AttemptInverseAngle is True and obj.InverseAngle is False: (clnBase, clnStock, angle) = self.applyInverseAngle(obj, clnBase, clnStock, axis, angle) else: - PathLog.error(" --Consider toggling the InverseAngle property and recomputing the operation.") + PathLog.info(translate("Path", "Consider toggling the InverseAngle property and recomputing the operation.")) else: - PathLog.debug(" --Face appears to be oriented correctly.") + PathLog.debug("Face appears to be oriented correctly.") tup = clnBase, [sub], angle, axis, clnStock else: - PathLog.debug(str(sub) + ": no rotation used") + PathLog.debug(str(sub) + ": No rotation used") axis = 'X' angle = 0.0 stock = PathUtils.findParentJob(obj).Stock @@ -430,7 +435,7 @@ class ObjectPocket(PathPocketBase.ObjectPocket): baseSubsTuples.append(tup) else: ignoreSub = base.Name + '.' + sub - PathLog.error(translate('Path', "Selected object is not a face. Ignoring: {}".format(ignoreSub))) + PathLog.error(translate('Path', "Selected feature is not a Face. Ignoring: {}".format(ignoreSub))) # Eif # Efor # Efor @@ -464,6 +469,13 @@ class ObjectPocket(PathPocketBase.ObjectPocket): if clasifySub(self, subBase, sub) is False: PathLog.error(translate('PathPocket', 'Pocket does not support shape %s.%s') % (subBase.Label, sub)) + # Determine final depth as highest value of bottom boundbox of vertical face, + # in case of uneven faces on bottom + vFinDep = self.vert[0].BoundBox.ZMin + for vFace in self.vert: + if vFace.BoundBox.ZMin > vFinDep: + vFinDep = vFace.BoundBox.ZMin + # Determine if vertical faces for a loop: Extract planar loop wire as new horizontal face. self.vertical = PathGeom.combineConnectedShapes(self.vert) self.vWires = [TechDraw.findShapeOutline(shape, 1, FreeCAD.Vector(0, 0, 1)) for shape in self.vertical] for wire in self.vWires: @@ -476,7 +488,12 @@ class ObjectPocket(PathPocketBase.ObjectPocket): # title = translate("Path", "Face Selection Warning") # self.guiMessage(title, msg, True) else: + face.translate(FreeCAD.Vector(0, 0, vFinDep - face.BoundBox.ZMin)) self.horiz.append(face) + msg = translate('Path', 'Verify final depth of pocket shaped by vertical faces.') + PathLog.error(msg) + title = translate('Path', 'Depth Warning') + self.guiMessage(title, msg, False) # add faces for extensions self.exts = [] @@ -507,13 +524,16 @@ class ObjectPocket(PathPocketBase.ObjectPocket): for face in self.horizontal: # extrude all faces up to StartDepth and those are the removal shapes (strDep, finDep) = self.calculateStartFinalDepths(obj, face, stock) - # PathLog.debug("Extent depths are str: {}, and fin: {}".format(strDep, finDep)) extent = FreeCAD.Vector(0, 0, strDep - finDep) self.removalshapes.append((face.removeSplitter().extrude(extent), False, 'pathPocketShape', angle, axis, strDep, finDep)) + PathLog.debug("Extent depths are str: {}, and fin: {}".format(strDep, finDep)) # Efor face - # Efor + + # Adjust obj.FinalDepth.Value as needed. + if subCount == 1: + obj.FinalDepth.Value = finDep else: # process the job base object as a whole - PathLog.debug('Processing... whole base') + PathLog.debug(translate("Path", 'Processing model as a whole ...')) finDep = obj.FinalDepth.Value strDep = obj.StartDepth.Value self.outlines = [Part.Face(TechDraw.findShapeOutline(base.Shape, 1, FreeCAD.Vector(0, 0, 1))) for base in self.model] @@ -589,7 +609,7 @@ class ObjectPocket(PathPocketBase.ObjectPocket): wireName = 'tmpWire' + str(fCnt) wr = Part.Wire(Part.__sortEdges__(base.Shape.getElement(sub).Edges)) if wr.isNull(): - PathLog.error('Now wire created from {}'.format(sub)) + PathLog.debug('No wire created from {}'.format(sub)) return (False, 0, 0) else: tmpWire = FreeCAD.ActiveDocument.addObject('Part::Feature', wireName).Shape = wr @@ -624,12 +644,14 @@ class ObjectPocket(PathPocketBase.ObjectPocket): else: return round(val, 8) + # Sub Surface.Axis values of faces + # Vector of (0, 0, 0) will suggests a loop for sub in subsList: if 'Face' in sub: fCnt += 1 saSum = saSum.add(base.Shape.getElement(sub).Surface.Axis) - # PathLog.debug("saSum: {}".format(saSum)) + # Minimim of three faces required for loop to exist if fCnt < 3: go = False @@ -704,18 +726,20 @@ class ObjectPocket(PathPocketBase.ObjectPocket): if (rnded.y > 0.0 or rnded.z > 0.0) and vertLoopFace is None: vertLoopFace = fc saTotal = saTotal.add(rnded) - # PathLog.debug(" -saTotal: {}".format(saTotal)) + if saTotal == FreeCAD.Vector(0.0, 0.0, 0.0): if vertLoopFace is not None: go = True + if go is True: (norm, surf) = self.getFaceNormAndSurf(vertLoopFace) else: - PathLog.debug(translate('Path', ' -Can not identify loop.')) + PathLog.debug(translate('Path', 'Can not identify loop.')) if delTempNameList > 0: for tmpNm in tempNameList: FreeCAD.ActiveDocument.removeObject(tmpNm) + return (go, norm, surf) diff --git a/src/Mod/Path/PathScripts/PathProfileFaces.py b/src/Mod/Path/PathScripts/PathProfileFaces.py index 16e3dc439c..b8b2b20035 100644 --- a/src/Mod/Path/PathScripts/PathProfileFaces.py +++ b/src/Mod/Path/PathScripts/PathProfileFaces.py @@ -36,6 +36,14 @@ import numpy # from PathScripts.PathUtils import depth_params from PySide import QtCore +__title__ = "Path Profile Faces Operation" +__author__ = "sliptonic (Brad Collette)" +__url__ = "http://www.freecadweb.org" +__doc__ = "Path Profile operation based on faces." +__created__ = "2014" +__scriptVersion__ = "2f testing" +__lastModified__ = "2019-06-12 14:12 CST" + if False: PathLog.setLevel(PathLog.Level.DEBUG, PathLog.thisModule()) PathLog.trackModule(PathLog.thisModule()) @@ -46,14 +54,6 @@ else: def translate(context, text, disambig=None): return QtCore.QCoreApplication.translate(context, text, disambig) -__title__ = "Path Profile Faces Operation" -__author__ = "sliptonic (Brad Collette)" -__url__ = "http://www.freecadweb.org" -__doc__ = "Path Profile operation based on faces." -__created__ = "2014" -__scriptVersion__ = "2e testing" -__lastModified__ = "2019-06-11 14:30 CST" - class ObjectProfile(PathProfileBase.ObjectProfile): '''Proxy object for Profile operations based on faces.''' @@ -99,6 +99,7 @@ class ObjectProfile(PathProfileBase.ObjectProfile): shapes = [] self.profileshape = [] + finalDepths = [] baseSubsTuples = [] subCount = 0 @@ -114,25 +115,24 @@ class ObjectProfile(PathProfileBase.ObjectProfile): if isinstance(shape, Part.Face): rtn = False (norm, surf) = self.getFaceNormAndSurf(shape) - (rtn, angle, axis, praInfo)= self.pocketRotationAnalysis(obj, norm, surf, prnt=True) - PathLog.info("praInfo: \n" + str(praInfo)) + (rtn, angle, axis, praInfo)= self.faceRotationAnalysis(obj, norm, surf) if rtn is True: (clnBase, angle, clnStock, tag) = self.applyRotationalAnalysis(obj, base, angle, axis, subCount) # Verify faces are correctly oriented - InverseAngle might be necessary faceIA = getattr(clnBase.Shape, sub) (norm, surf) = self.getFaceNormAndSurf(faceIA) - (rtn, praAngle, praAxis, praInfo) = self.pocketRotationAnalysis(obj, norm, surf, prnt=False) + (rtn, praAngle, praAxis, praInfo) = self.faceRotationAnalysis(obj, norm, surf) if rtn is True: - PathLog.error(" --Face not aligned after initial rotation.") - if obj.AttemptInverseAngle is True: + PathLog.error(translate("Path", "Face appears misaligned after initial rotation.")) + if obj.AttemptInverseAngle is True and obj.InverseAngle is False: (clnBase, clnStock, angle) = self.applyInverseAngle(obj, clnBase, clnStock, axis, angle) else: - msg = "Consider toggling the 'InverseAngle' property and recomputing." + msg = translate("Path", "Consider toggling the 'InverseAngle' property and recomputing.") PathLog.error(msg) - title = 'Rotation Warning' - self.guiMessage(title, msg, False) + # title = translate("Path", 'Rotation Warning') + # self.guiMessage(title, msg, False) else: - PathLog.debug(" --Face appears to be oriented correctly.") + PathLog.debug("Face appears to be oriented correctly.") tup = clnBase, sub, tag, angle, axis, clnStock else: @@ -151,7 +151,7 @@ class ObjectProfile(PathProfileBase.ObjectProfile): msg = "Multiple faces in Base Geometry." msg += " Depth settings will be applied to all faces." msg = translate("Path", msg) - PathLog.error(msg) + PathLog.warning(msg) #title = translate("Path", "Depth Warning") #self.guiMessage(title, msg) (Tags, Grps) = self.sortTuplesByIndex(allTuples, 2) # return (TagList, GroupList) @@ -164,7 +164,7 @@ class ObjectProfile(PathProfileBase.ObjectProfile): baseSubsTuples.append(pair) # Efor else: - PathLog.info("Use Rotation feature(property) is 'Off'.") + PathLog.info(translate("Path", "EnableRotation property is 'Off'.")) stock = PathUtils.findParentJob(obj).Stock for (base, subList) in obj.Base: baseSubsTuples.append((base, subList, 0.0, 'X', stock)) @@ -192,8 +192,10 @@ class ObjectProfile(PathProfileBase.ObjectProfile): f = Part.makeFace(wire, 'Part::FaceMakerSimple') drillable = PathUtils.isDrillable(shape, wire) if (drillable and obj.processCircles) or (not drillable and obj.processHoles): + PathLog.track() # Recalculate depthparams (strDep, finDep) = self.calculateStartFinalDepths(obj, shape, stock) + finalDepths.append(finDep) PathLog.debug("Adjusted face depths strDep: {}, and finDep: {}".format(self.strDep, self.finDep)) finish_step = obj.FinishDepth.Value if hasattr(obj, "FinishDepth") else 0.0 self.depthparams = PathUtils.depth_params( @@ -205,7 +207,6 @@ class ObjectProfile(PathProfileBase.ObjectProfile): final_depth=finDep, #obj.FinalDepth.Value, user_depths=None) env = PathUtils.getEnvelope(shape, subshape=f, depthparams=self.depthparams) - PathLog.track() # shapes.append((env, True)) tup = env, True, 'pathProfileFaces', angle, axis, strDep, finDep shapes.append(tup) @@ -219,6 +220,7 @@ class ObjectProfile(PathProfileBase.ObjectProfile): if profileshape: # Recalculate depthparams (strDep, finDep) = self.calculateStartFinalDepths(obj, profileshape, stock) + finalDepths.append(finDep) PathLog.debug("Adjusted face depths strDep: {}, and finDep: {}".format(self.strDep, self.finDep)) finish_step = obj.FinishDepth.Value if hasattr(obj, "FinishDepth") else 0.0 self.depthparams = PathUtils.depth_params( @@ -235,7 +237,8 @@ class ObjectProfile(PathProfileBase.ObjectProfile): try: env = PathUtils.getEnvelope(base.Shape, subshape=profileshape, depthparams=self.depthparams) except Exception as ee: - PathLog.error(translate('Path', 'getEnvelope() failed to return an object.')) + # PathUtils.getEnvelope() failed to return an object. + PathLog.error(translate('Path', 'Unable to create path for face(s).')) else: # shapes.append((env, False)) tup = env, False, 'pathProfileFaces', angle, axis, strDep, finDep @@ -244,6 +247,7 @@ class ObjectProfile(PathProfileBase.ObjectProfile): for shape in faces: # Recalculate depthparams (strDep, finDep) = self.calculateStartFinalDepths(obj, shape, stock) + finalDepths.append(finDep) finish_step = obj.FinishDepth.Value if hasattr(obj, "FinishDepth") else 0.0 self.depthparams = PathUtils.depth_params( clearance_height=obj.ClearanceHeight.Value, @@ -257,7 +261,11 @@ class ObjectProfile(PathProfileBase.ObjectProfile): tup = env, False, 'pathProfileFaces', angle, axis, strDep, finDep shapes.append(tup) # Eif - # Efor + + # adjust FinalDepth as needed + finalDepth = min(finalDepths) + if obj.FinalDepth.Value < finalDepth: + obj.FinalDepth.Value = finalDepth else: # Try to build targets from the job base if 1 == len(self.model) and hasattr(self.model[0], "Proxy"): if isinstance(self.model[0].Proxy, ArchPanel.PanelSheet): # process the sheet @@ -295,7 +303,7 @@ class ObjectProfile(PathProfileBase.ObjectProfile): obj.processPerimeter = True obj.ReverseDirection = False obj.InverseAngle = False - obj.AttemptInverseAngle = False + obj.AttemptInverseAngle = True obj.B_AxisErrorOverride = False