From e67fc4e706e8a183e4b55bd647e97c8d0affed33 Mon Sep 17 00:00:00 2001 From: Russell Johnson <47639332+Russ4262@users.noreply.github.com> Date: Sun, 30 Jun 2019 12:55:59 -0500 Subject: [PATCH] 3D Pocket: Upgrade to collective face processing! New property added: `HandleMultipleFeatures`. New property and related code allows for improved, and expected, 3D Pocket operations. Improvement combines faces selected to create one envelope to be processed as the path shape ('collectively' setting). Old behavior is available with 'Individually' setting. Enjoy! --- src/Mod/Path/PathScripts/PathPocket.py | 56 +++++++++++++++++++++++--- 1 file changed, 50 insertions(+), 6 deletions(-) diff --git a/src/Mod/Path/PathScripts/PathPocket.py b/src/Mod/Path/PathScripts/PathPocket.py index 9c505d81c2..01bff6be9d 100644 --- a/src/Mod/Path/PathScripts/PathPocket.py +++ b/src/Mod/Path/PathScripts/PathPocket.py @@ -21,6 +21,12 @@ # * USA * # * * # *************************************************************************** +# * * +# * Additional modifications and contributions beginning 2019 * +# * Focus: improve 3D facial pockets * +# * by Russell Johnson * +# * * +# *************************************************************************** import FreeCAD import Part @@ -31,7 +37,14 @@ import PathScripts.PathUtils as PathUtils from PySide import QtCore -__doc__ = "Class and implementation of the Pocket operation." +__title__ = "Path 3D Pocket Operation" +__author__ = "Yorik van Havre " +__url__ = "http://www.freecadweb.org" +__doc__ = "Class and implementation of the 3D Pocket operation." +__contributors__ = "russ4262 (Russell Johnson)" +__created__ = "2014" +__scriptVersion__ = "1a testing" +__lastModified__ = "2019-06-28 23:45 CST" LOGLEVEL = False @@ -41,6 +54,7 @@ if LOGLEVEL: else: PathLog.setLevel(PathLog.Level.INFO, PathLog.thisModule()) + # Qt translation handling def translate(context, text, disambig=None): return QtCore.QCoreApplication.translate(context, text, disambig) @@ -54,31 +68,58 @@ class ObjectPocket(PathPocketBase.ObjectPocket): def initPocketOp(self, obj): '''initPocketOp(obj) ... setup receiver''' + if not hasattr(obj, 'HandleMultipleFeatures'): + obj.addProperty('App::PropertyEnumeration', 'HandleMultipleFeatures', 'Pocket', QtCore.QT_TRANSLATE_NOOP('PathPocket', 'Choose how to process multiple Base Geometry features.')) + obj.HandleMultipleFeatures = ['Collectively', 'Individually'] pass + def opOnDocumentRestored(self, obj): + '''opOnDocumentRestored(obj) ... adds the properties if they doesn't exist.''' + self.initPocketOp(obj) + def pocketInvertExtraOffset(self): return False def areaOpShapes(self, obj): '''areaOpShapes(obj) ... return shapes representing the solids to be removed.''' PathLog.track() + PathLog.info("----- areaOpShapes() in PathPocket.py") removalshapes = [] if obj.Base: PathLog.debug("base items exist. Processing...") for base in obj.Base: PathLog.debug("Base item: {}".format(base)) + + # Check if all subs are faces + allFaceSubs = True + Faces = [] for sub in base[1]: if "Face" in sub: - shape = Part.makeCompound([getattr(base[0].Shape, sub)]) + Faces.append(getattr(base[0].Shape, sub)) else: - edges = [getattr(base[0].Shape, sub) for sub in base[1]] - shape = Part.makeFace(edges, 'Part::FaceMakerSimple') + allFaceSubs = False + break + if allFaceSubs is True and obj.HandleMultipleFeatures == 'Collectively': + shape = Part.makeCompound(Faces) env = PathUtils.getEnvelope(base[0].Shape, subshape=shape, depthparams=self.depthparams) obj.removalshape = env.cut(base[0].Shape) obj.removalshape.tessellate(0.1) removalshapes.append((obj.removalshape, False)) + else: + for sub in base[1]: + if "Face" in sub: + shape = Part.makeCompound([getattr(base[0].Shape, sub)]) + else: + edges = [getattr(base[0].Shape, sub) for sub in base[1]] + shape = Part.makeFace(edges, 'Part::FaceMakerSimple') + + env = PathUtils.getEnvelope(base[0].Shape, subshape=shape, depthparams=self.depthparams) + obj.removalshape = env.cut(base[0].Shape) + obj.removalshape.tessellate(0.1) + removalshapes.append((obj.removalshape, False)) + else: # process the job base object as a whole PathLog.debug("processing the whole job base object") for base in self.model: @@ -92,11 +133,14 @@ class ObjectPocket(PathPocketBase.ObjectPocket): '''areaOpSetDefaultValues(obj, job) ... set default values''' obj.StepOver = 100 obj.ZigZagAngle = 45 + obj.HandleMultipleFeatures = 'Collectively' + def SetupProperties(): - return PathPocketBase.SetupProperties() + return PathPocketBase.SetupProperties().append("HandleMultipleFeatures") -def Create(name, obj = None): + +def Create(name, obj=None): '''Create(name) ... Creates and returns a Pocket operation.''' if obj is None: obj = FreeCAD.ActiveDocument.addObject("Path::FeaturePython", name)