From 069768669562b0b033a603ed6eca282ab933d693 Mon Sep 17 00:00:00 2001 From: Russell Johnson <47639332+Russ4262@users.noreply.github.com> Date: Sun, 2 Aug 2020 13:16:21 -0500 Subject: [PATCH 1/4] Path: PocketShape - Fixes ticket #4411 Existing code to determine if shape volume indeed existed, failed. Added additional pre-check for existing edges in shape to determine if shape geometry indeed exists. In forum: [Ticket #4411 - Can only generate pocket once for this shape, then it fails.](https://forum.freecadweb.org/viewtopic.php?style=3&f=15&t=49035). --- src/Mod/Path/PathScripts/PathAreaOp.py | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/Mod/Path/PathScripts/PathAreaOp.py b/src/Mod/Path/PathScripts/PathAreaOp.py index 067845c51d..0547f3ddcd 100644 --- a/src/Mod/Path/PathScripts/PathAreaOp.py +++ b/src/Mod/Path/PathScripts/PathAreaOp.py @@ -991,11 +991,13 @@ class ObjectOp(PathOp.ObjectOp): dwn = face.extrude(FreeCAD.Vector(0.0, 0.0, -5.0)) upCmn = base.Shape.common(up) dwnCmn = base.Shape.common(dwn) - if upCmn.Volume == 0.0: + # Identify orientation based on volumes of common() results + if len(upCmn.Edges) > 0 and round(upCmn.Volume, 6) == 0.0: return True - elif dwnCmn.Volume == 0.0: + elif len(dwnCmn.Edges) > 0 and round(dwnCmn.Volume, 6) == 0.0: return False - if dwnCmn.Volume > upCmn.Volume: + if (len(upCmn.Edges) > 0 and len(dwnCmn.Edges) > 0 and + round(dwnCmn.Volume, 6) > round(upCmn.Volume, 6)): return True return False From 986775ec1af4da1f390ba13de285a9c04e4ef4b4 Mon Sep 17 00:00:00 2001 From: Russell Johnson <47639332+Russ4262@users.noreply.github.com> Date: Sun, 2 Aug 2020 13:19:58 -0500 Subject: [PATCH 2/4] Path: Fix `InverseAngle` feature The `ReverseDirection` property is now hidden by default. It should not be necessary due to recent implementation of `isFaceUp()` method. --- src/Mod/Path/PathScripts/PathAreaOp.py | 11 ++++++----- src/Mod/Path/PathScripts/PathPocketShape.py | 20 ++++++++++++++------ 2 files changed, 20 insertions(+), 11 deletions(-) diff --git a/src/Mod/Path/PathScripts/PathAreaOp.py b/src/Mod/Path/PathScripts/PathAreaOp.py index 0547f3ddcd..012020953e 100644 --- a/src/Mod/Path/PathScripts/PathAreaOp.py +++ b/src/Mod/Path/PathScripts/PathAreaOp.py @@ -909,10 +909,11 @@ class ObjectOp(PathOp.ObjectOp): elif axis == 'Y': vect = FreeCAD.Vector(0, 1, 0) - if obj.InverseAngle is True: - angle = -1 * angle - if math.fabs(angle) == 0.0: - angle = 0.0 + # Commented out to fix PocketShape InverseAngle rotation problem + # if obj.InverseAngle is True: + # angle = -1 * angle + # if math.fabs(angle) == 0.0: + # angle = 0.0 # Create a temporary clone of model for rotational use. (clnBase, clnStock, tag) = self.cloneBaseAndStock(obj, base, angle, axis, subCount) @@ -939,7 +940,7 @@ class ObjectOp(PathOp.ObjectOp): clnStock.purgeTouched() # Update property and angle values obj.InverseAngle = True - obj.AttemptInverseAngle = False + # obj.AttemptInverseAngle = False angle = -1 * angle PathLog.debug(translate("Path", "Rotated to inverse angle.")) diff --git a/src/Mod/Path/PathScripts/PathPocketShape.py b/src/Mod/Path/PathScripts/PathPocketShape.py index e0141396be..95123ca791 100644 --- a/src/Mod/Path/PathScripts/PathPocketShape.py +++ b/src/Mod/Path/PathScripts/PathPocketShape.py @@ -299,13 +299,13 @@ class ObjectPocket(PathPocketBase.ObjectPocket): self.setEditorProperties(obj) def setEditorProperties(self, obj): + obj.setEditorMode('ReverseDirection', 2) if obj.EnableRotation == 'Off': - obj.setEditorMode('ReverseDirection', 2) obj.setEditorMode('InverseAngle', 2) obj.setEditorMode('AttemptInverseAngle', 2) obj.setEditorMode('LimitDepthToFace', 2) else: - obj.setEditorMode('ReverseDirection', 0) + # obj.setEditorMode('ReverseDirection', 0) obj.setEditorMode('InverseAngle', 0) obj.setEditorMode('AttemptInverseAngle', 0) obj.setEditorMode('LimitDepthToFace', 0) @@ -446,6 +446,7 @@ class ObjectPocket(PathPocketBase.ObjectPocket): for (base, subList) in obj.Base: baseSubsTuples.append((base, subList, 0.0, 'X', stock)) else: + PathLog.debug('Rotation is active...') for p in range(0, len(obj.Base)): (base, subsList) = obj.Base[p] isLoop = False @@ -478,8 +479,10 @@ class ObjectPocket(PathPocketBase.ObjectPocket): break if rtn is False: - PathLog.debug(translate("Path", "Face appears misaligned after initial rotation.")) - if obj.InverseAngle is False: + PathLog.debug(translate("Path", "Face appears misaligned after initial rotation.") + ' 1') + if obj.InverseAngle: + (clnBase, clnStock, angle) = self.applyInverseAngle(obj, clnBase, clnStock, axis, angle) + else: if obj.AttemptInverseAngle is True: (clnBase, clnStock, angle) = self.applyInverseAngle(obj, clnBase, clnStock, axis, angle) else: @@ -543,8 +546,13 @@ class ObjectPocket(PathPocketBase.ObjectPocket): angle -= 180.0 if rtn is True: - PathLog.debug(translate("Path", "Face appears misaligned after initial rotation.")) - if obj.InverseAngle is False: + PathLog.debug(translate("Path", "Face appears misaligned after initial rotation.") + ' 2') + if obj.InverseAngle: + (clnBase, clnStock, angle) = self.applyInverseAngle(obj, clnBase, clnStock, axis, angle) + if self.isFaceUp(clnBase, faceIA) is False: + PathLog.debug('isFaceUp is False') + angle += 180.0 + else: if obj.AttemptInverseAngle is True: (clnBase, clnStock, angle) = self.applyInverseAngle(obj, clnBase, clnStock, axis, angle) else: From 2528898cb578fab29e2d0d25d90ad6c60a4a69d8 Mon Sep 17 00:00:00 2001 From: Russell Johnson <47639332+Russ4262@users.noreply.github.com> Date: Sun, 2 Aug 2020 13:22:38 -0500 Subject: [PATCH 3/4] Path: Fix the rotational `LimitDepthToFace` feature --- src/Mod/Path/PathScripts/PathPocketShape.py | 27 ++++++++++++--------- 1 file changed, 15 insertions(+), 12 deletions(-) diff --git a/src/Mod/Path/PathScripts/PathPocketShape.py b/src/Mod/Path/PathScripts/PathPocketShape.py index 95123ca791..08b9729d27 100644 --- a/src/Mod/Path/PathScripts/PathPocketShape.py +++ b/src/Mod/Path/PathScripts/PathPocketShape.py @@ -657,14 +657,14 @@ class ObjectPocket(PathPocketBase.ObjectPocket): self.horizontal.append(shape) # extrude all faces up to StartDepth and those are the removal shapes - sD = obj.StartDepth.Value - fD = obj.FinalDepth.Value + start_dep = obj.StartDepth.Value clrnc = 0.5 for face in self.horizontal: - afD = fD + adj_final_dep = obj.FinalDepth.Value useAngle = angle shpZMin = face.BoundBox.ZMin - PathLog.debug('self.horizontal shpZMin: {}'.format(shpZMin)) + shpZMinVal = shpZMin + PathLog.debug('self.horizontal pre-shpZMin: {}'.format(shpZMin)) if self.isFaceUp(subBase, face) is False: useAngle += 180.0 invZ = (-2 * shpZMin) - clrnc @@ -672,21 +672,24 @@ class ObjectPocket(PathPocketBase.ObjectPocket): shpZMin = -1 * shpZMin else: face.translate(FreeCAD.Vector(0.0, 0.0, -1 * clrnc)) + PathLog.debug('self.horizontal post-shpZMin: {}'.format(shpZMin)) if obj.LimitDepthToFace is True and obj.EnableRotation != 'Off': - if shpZMin > obj.FinalDepth.Value: - afD = shpZMin - if sD <= afD: - sD = afD + 1.0 + if shpZMinVal > obj.FinalDepth.Value: + PathLog.debug('shpZMin > obj.FinalDepth.Value') + adj_final_dep = shpZMinVal # shpZMin + if start_dep <= adj_final_dep: + start_dep = adj_final_dep + 1.0 msg = translate('PathPocketShape', 'Start Depth is lower than face depth. Setting to ') - PathLog.warning(msg + ' {} mm.'.format(sD)) + PathLog.warning(msg + ' {} mm.'.format(start_dep)) + PathLog.debug('LimitDepthToFace adj_final_dep: {}'.format(adj_final_dep)) else: face.translate(FreeCAD.Vector(0, 0, obj.FinalDepth.Value - shpZMin)) - extent = FreeCAD.Vector(0, 0, sD - afD + clrnc) + extent = FreeCAD.Vector(0, 0, start_dep - shpZMin + clrnc) # adj_final_dep + clrnc) extShp = face.removeSplitter().extrude(extent) - self.removalshapes.append((extShp, False, 'pathPocketShape', useAngle, axis, sD, afD)) - PathLog.debug("Extent values are strDep: {}, finDep: {}, extrd: {}".format(sD, afD, extent)) + self.removalshapes.append((extShp, False, 'pathPocketShape', useAngle, axis, start_dep, adj_final_dep)) + PathLog.debug("Extent values are strDep: {}, finDep: {}, extrd: {}".format(start_dep, adj_final_dep, extent)) # Efor face # Efor From c7d34929ad136369a45cba6aa917aaad458194c2 Mon Sep 17 00:00:00 2001 From: Russell Johnson <47639332+Russ4262@users.noreply.github.com> Date: Sun, 2 Aug 2020 13:23:36 -0500 Subject: [PATCH 4/4] Path: Fix reference to undefined `ns`, and adjust comments This `ns` fix might need further attention after testing. The section to which it pertains deals with optimizing rotations between ops with similar rotational axes. --- src/Mod/Path/PathScripts/PathAreaOp.py | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/src/Mod/Path/PathScripts/PathAreaOp.py b/src/Mod/Path/PathScripts/PathAreaOp.py index 012020953e..676ec2e332 100644 --- a/src/Mod/Path/PathScripts/PathAreaOp.py +++ b/src/Mod/Path/PathScripts/PathAreaOp.py @@ -492,6 +492,7 @@ class ObjectOp(PathOp.ObjectOp): self.commandlist.append(Path.Command('G0', {'Z': obj.ClearanceHeight.Value, 'F': self.vertRapid})) # Raise cutter to safe height and rotate back to original orientation + # based on next rotational operation in job if self.rotateFlag is True: resetAxis = False lastJobOp = None @@ -517,12 +518,12 @@ class ObjectOp(PathOp.ObjectOp): PathLog.debug('Last Op, {}, has `EnableRotation` set to {}'.format(lastJobOp.Label, lastJobOp.EnableRotation)) if lastJobOp.EnableRotation != obj.EnableRotation: resetAxis = True - if ns == numShapes - 1: # If last shape, check next op EnableRotation setting - if nextJobOp is not None: - if hasattr(nextJobOp, 'EnableRotation'): - PathLog.debug('Next Op, {}, has `EnableRotation` set to {}'.format(nextJobOp.Label, nextJobOp.EnableRotation)) - if nextJobOp.EnableRotation != obj.EnableRotation: - resetAxis = True + # if ns == numShapes - 1: # If last shape, check next op EnableRotation setting + if nextJobOp is not None: + if hasattr(nextJobOp, 'EnableRotation'): + PathLog.debug('Next Op, {}, has `EnableRotation` set to {}'.format(nextJobOp.Label, nextJobOp.EnableRotation)) + if nextJobOp.EnableRotation != obj.EnableRotation: + resetAxis = True # Raise to safe height if rotation activated self.commandlist.append(Path.Command('G0', {'Z': obj.SafeHeight.Value, 'F': self.vertRapid})) @@ -748,8 +749,6 @@ class ObjectOp(PathOp.ObjectOp): else: praInfo += "\n - ... NO rotation triggered" - PathLog.debug("\n" + str(praInfo)) - return (rtn, angle, axis, praInfo) def guiMessage(self, title, msg, show=False): @@ -1013,7 +1012,7 @@ class ObjectOp(PathOp.ObjectOp): final_depth=finDep, user_depths=None) return cdp - +# Eclass def SetupProperties(): setup = ['EnableRotation']