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 *
|
# * USA *
|
||||||
# * *
|
# * *
|
||||||
# ***************************************************************************
|
# ***************************************************************************
|
||||||
|
# * *
|
||||||
|
# * Additional modifications and contributions beginning 2019 *
|
||||||
|
# * Focus: improve 3D facial pockets *
|
||||||
|
# * by Russell Johnson <russ4262@gmail.com> *
|
||||||
|
# * *
|
||||||
|
# ***************************************************************************
|
||||||
|
|
||||||
import FreeCAD
|
import FreeCAD
|
||||||
import Part
|
import Part
|
||||||
@@ -31,7 +37,14 @@ import PathScripts.PathUtils as PathUtils
|
|||||||
|
|
||||||
from PySide import QtCore
|
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
|
LOGLEVEL = False
|
||||||
|
|
||||||
@@ -41,6 +54,7 @@ if LOGLEVEL:
|
|||||||
else:
|
else:
|
||||||
PathLog.setLevel(PathLog.Level.INFO, PathLog.thisModule())
|
PathLog.setLevel(PathLog.Level.INFO, PathLog.thisModule())
|
||||||
|
|
||||||
|
|
||||||
# Qt translation handling
|
# Qt translation handling
|
||||||
def translate(context, text, disambig=None):
|
def translate(context, text, disambig=None):
|
||||||
return QtCore.QCoreApplication.translate(context, text, disambig)
|
return QtCore.QCoreApplication.translate(context, text, disambig)
|
||||||
@@ -54,31 +68,58 @@ class ObjectPocket(PathPocketBase.ObjectPocket):
|
|||||||
|
|
||||||
def initPocketOp(self, obj):
|
def initPocketOp(self, obj):
|
||||||
'''initPocketOp(obj) ... setup receiver'''
|
'''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
|
pass
|
||||||
|
|
||||||
|
def opOnDocumentRestored(self, obj):
|
||||||
|
'''opOnDocumentRestored(obj) ... adds the properties if they doesn't exist.'''
|
||||||
|
self.initPocketOp(obj)
|
||||||
|
|
||||||
def pocketInvertExtraOffset(self):
|
def pocketInvertExtraOffset(self):
|
||||||
return False
|
return False
|
||||||
|
|
||||||
def areaOpShapes(self, obj):
|
def areaOpShapes(self, obj):
|
||||||
'''areaOpShapes(obj) ... return shapes representing the solids to be removed.'''
|
'''areaOpShapes(obj) ... return shapes representing the solids to be removed.'''
|
||||||
PathLog.track()
|
PathLog.track()
|
||||||
|
PathLog.info("----- areaOpShapes() in PathPocket.py")
|
||||||
|
|
||||||
removalshapes = []
|
removalshapes = []
|
||||||
if obj.Base:
|
if obj.Base:
|
||||||
PathLog.debug("base items exist. Processing...")
|
PathLog.debug("base items exist. Processing...")
|
||||||
for base in obj.Base:
|
for base in obj.Base:
|
||||||
PathLog.debug("Base item: {}".format(base))
|
PathLog.debug("Base item: {}".format(base))
|
||||||
|
|
||||||
|
# Check if all subs are faces
|
||||||
|
allFaceSubs = True
|
||||||
|
Faces = []
|
||||||
for sub in base[1]:
|
for sub in base[1]:
|
||||||
if "Face" in sub:
|
if "Face" in sub:
|
||||||
shape = Part.makeCompound([getattr(base[0].Shape, sub)])
|
Faces.append(getattr(base[0].Shape, sub))
|
||||||
else:
|
else:
|
||||||
edges = [getattr(base[0].Shape, sub) for sub in base[1]]
|
allFaceSubs = False
|
||||||
shape = Part.makeFace(edges, 'Part::FaceMakerSimple')
|
break
|
||||||
|
|
||||||
|
if allFaceSubs is True and obj.HandleMultipleFeatures == 'Collectively':
|
||||||
|
shape = Part.makeCompound(Faces)
|
||||||
env = PathUtils.getEnvelope(base[0].Shape, subshape=shape, depthparams=self.depthparams)
|
env = PathUtils.getEnvelope(base[0].Shape, subshape=shape, depthparams=self.depthparams)
|
||||||
obj.removalshape = env.cut(base[0].Shape)
|
obj.removalshape = env.cut(base[0].Shape)
|
||||||
obj.removalshape.tessellate(0.1)
|
obj.removalshape.tessellate(0.1)
|
||||||
removalshapes.append((obj.removalshape, False))
|
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
|
else: # process the job base object as a whole
|
||||||
PathLog.debug("processing the whole job base object")
|
PathLog.debug("processing the whole job base object")
|
||||||
for base in self.model:
|
for base in self.model:
|
||||||
@@ -92,11 +133,14 @@ class ObjectPocket(PathPocketBase.ObjectPocket):
|
|||||||
'''areaOpSetDefaultValues(obj, job) ... set default values'''
|
'''areaOpSetDefaultValues(obj, job) ... set default values'''
|
||||||
obj.StepOver = 100
|
obj.StepOver = 100
|
||||||
obj.ZigZagAngle = 45
|
obj.ZigZagAngle = 45
|
||||||
|
obj.HandleMultipleFeatures = 'Collectively'
|
||||||
|
|
||||||
|
|
||||||
def SetupProperties():
|
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.'''
|
'''Create(name) ... Creates and returns a Pocket operation.'''
|
||||||
if obj is None:
|
if obj is None:
|
||||||
obj = FreeCAD.ActiveDocument.addObject("Path::FeaturePython", name)
|
obj = FreeCAD.ActiveDocument.addObject("Path::FeaturePython", name)
|
||||||
|
|||||||
Reference in New Issue
Block a user