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!
This commit is contained in:
@@ -21,6 +21,12 @@
|
||||
# * USA *
|
||||
# * *
|
||||
# ***************************************************************************
|
||||
# * *
|
||||
# * Additional modifications and contributions beginning 2019 *
|
||||
# * Focus: improve 3D facial pockets *
|
||||
# * by Russell Johnson <russ4262@gmail.com> *
|
||||
# * *
|
||||
# ***************************************************************************
|
||||
|
||||
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 <yorik@uncreated.net>"
|
||||
__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)
|
||||
|
||||
Reference in New Issue
Block a user