pocket black
This commit is contained in:
@@ -30,7 +30,8 @@ from PySide import QtCore
|
||||
|
||||
# lazily loaded modules
|
||||
from lazy_loader.lazy_loader import LazyLoader
|
||||
Part = LazyLoader('Part', globals(), 'Part')
|
||||
|
||||
Part = LazyLoader("Part", globals(), "Part")
|
||||
|
||||
__title__ = "Path 3D Pocket Operation"
|
||||
__author__ = "Yorik van Havre <yorik@uncreated.net>"
|
||||
@@ -51,32 +52,64 @@ def translate(context, text, disambig=None):
|
||||
|
||||
|
||||
class ObjectPocket(PathPocketBase.ObjectPocket):
|
||||
'''Proxy object for Pocket operation.'''
|
||||
"""Proxy object for Pocket operation."""
|
||||
|
||||
def pocketOpFeatures(self, obj):
|
||||
return PathOp.FeatureNoFinalDepth
|
||||
|
||||
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']
|
||||
if not hasattr(obj, 'AdaptivePocketStart'):
|
||||
obj.addProperty('App::PropertyBool', 'AdaptivePocketStart', 'Pocket', QtCore.QT_TRANSLATE_NOOP('App::Property', 'Use adaptive algorithm to eliminate excessive air milling above planar pocket top.'))
|
||||
if not hasattr(obj, 'AdaptivePocketFinish'):
|
||||
obj.addProperty('App::PropertyBool', 'AdaptivePocketFinish', 'Pocket', QtCore.QT_TRANSLATE_NOOP('App::Property', 'Use adaptive algorithm to eliminate excessive air milling below planar pocket bottom.'))
|
||||
if not hasattr(obj, 'ProcessStockArea'):
|
||||
obj.addProperty('App::PropertyBool', 'ProcessStockArea', 'Pocket', QtCore.QT_TRANSLATE_NOOP('App::Property', 'Process the model and stock in an operation with no Base Geometry selected.'))
|
||||
"""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"]
|
||||
if not hasattr(obj, "AdaptivePocketStart"):
|
||||
obj.addProperty(
|
||||
"App::PropertyBool",
|
||||
"AdaptivePocketStart",
|
||||
"Pocket",
|
||||
QtCore.QT_TRANSLATE_NOOP(
|
||||
"App::Property",
|
||||
"Use adaptive algorithm to eliminate excessive air milling above planar pocket top.",
|
||||
),
|
||||
)
|
||||
if not hasattr(obj, "AdaptivePocketFinish"):
|
||||
obj.addProperty(
|
||||
"App::PropertyBool",
|
||||
"AdaptivePocketFinish",
|
||||
"Pocket",
|
||||
QtCore.QT_TRANSLATE_NOOP(
|
||||
"App::Property",
|
||||
"Use adaptive algorithm to eliminate excessive air milling below planar pocket bottom.",
|
||||
),
|
||||
)
|
||||
if not hasattr(obj, "ProcessStockArea"):
|
||||
obj.addProperty(
|
||||
"App::PropertyBool",
|
||||
"ProcessStockArea",
|
||||
"Pocket",
|
||||
QtCore.QT_TRANSLATE_NOOP(
|
||||
"App::Property",
|
||||
"Process the model and stock in an operation with no Base Geometry selected.",
|
||||
),
|
||||
)
|
||||
|
||||
def opOnDocumentRestored(self, obj):
|
||||
'''opOnDocumentRestored(obj) ... adds the properties if they doesn't exist.'''
|
||||
"""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.'''
|
||||
"""areaOpShapes(obj) ... return shapes representing the solids to be removed."""
|
||||
PathLog.track()
|
||||
|
||||
subObjTups = []
|
||||
@@ -102,34 +135,51 @@ class ObjectPocket(PathPocketBase.ObjectPocket):
|
||||
if len(Faces) == 0:
|
||||
allSubsFaceType = False
|
||||
|
||||
if allSubsFaceType is True and obj.HandleMultipleFeatures == 'Collectively':
|
||||
if (
|
||||
allSubsFaceType is True
|
||||
and obj.HandleMultipleFeatures == "Collectively"
|
||||
):
|
||||
(fzmin, fzmax) = self.getMinMaxOfFaces(Faces)
|
||||
if obj.FinalDepth.Value < fzmin:
|
||||
PathLog.warning(translate('PathPocket', 'Final depth set below ZMin of face(s) selected.'))
|
||||
PathLog.warning(
|
||||
translate(
|
||||
"PathPocket",
|
||||
"Final depth set below ZMin of face(s) selected.",
|
||||
)
|
||||
)
|
||||
|
||||
if obj.AdaptivePocketStart is True or obj.AdaptivePocketFinish is True:
|
||||
if (
|
||||
obj.AdaptivePocketStart is True
|
||||
or obj.AdaptivePocketFinish is True
|
||||
):
|
||||
pocketTup = self.calculateAdaptivePocket(obj, base, subObjTups)
|
||||
if pocketTup is not False:
|
||||
obj.removalshape = pocketTup[0]
|
||||
removalshapes.append(pocketTup) # (shape, isHole, detail)
|
||||
else:
|
||||
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.tessellate(0.1)
|
||||
removalshapes.append((obj.removalshape, False, '3DPocket')) # (shape, isHole, detail)
|
||||
removalshapes.append(
|
||||
(obj.removalshape, False, "3DPocket")
|
||||
) # (shape, isHole, detail)
|
||||
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')
|
||||
shape = Part.makeFace(edges, "Part::FaceMakerSimple")
|
||||
|
||||
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.tessellate(0.1)
|
||||
removalshapes.append((obj.removalshape, False, '3DPocket'))
|
||||
removalshapes.append((obj.removalshape, False, "3DPocket"))
|
||||
|
||||
else: # process the job base object as a whole
|
||||
PathLog.debug("processing the whole job base object")
|
||||
@@ -137,36 +187,40 @@ class ObjectPocket(PathPocketBase.ObjectPocket):
|
||||
if obj.ProcessStockArea is True:
|
||||
job = PathUtils.findParentJob(obj)
|
||||
|
||||
stockEnvShape = PathUtils.getEnvelope(job.Stock.Shape, subshape=None, depthparams=self.depthparams)
|
||||
stockEnvShape = PathUtils.getEnvelope(
|
||||
job.Stock.Shape, subshape=None, depthparams=self.depthparams
|
||||
)
|
||||
|
||||
obj.removalshape = stockEnvShape.cut(base.Shape)
|
||||
# obj.removalshape.tessellate(0.1)
|
||||
else:
|
||||
env = PathUtils.getEnvelope(base.Shape, subshape=None, depthparams=self.depthparams)
|
||||
env = PathUtils.getEnvelope(
|
||||
base.Shape, subshape=None, depthparams=self.depthparams
|
||||
)
|
||||
obj.removalshape = env.cut(base.Shape)
|
||||
# obj.removalshape.tessellate(0.1)
|
||||
|
||||
removalshapes.append((obj.removalshape, False, '3DPocket'))
|
||||
removalshapes.append((obj.removalshape, False, "3DPocket"))
|
||||
|
||||
return removalshapes
|
||||
|
||||
def areaOpSetDefaultValues(self, obj, job):
|
||||
'''areaOpSetDefaultValues(obj, job) ... set default values'''
|
||||
"""areaOpSetDefaultValues(obj, job) ... set default values"""
|
||||
obj.StepOver = 100
|
||||
obj.ZigZagAngle = 45
|
||||
obj.HandleMultipleFeatures = 'Collectively'
|
||||
obj.HandleMultipleFeatures = "Collectively"
|
||||
obj.AdaptivePocketStart = False
|
||||
obj.AdaptivePocketFinish = False
|
||||
obj.ProcessStockArea = False
|
||||
|
||||
# methods for eliminating air milling with some pockets: adpative start and finish
|
||||
def calculateAdaptivePocket(self, obj, base, subObjTups):
|
||||
'''calculateAdaptivePocket(obj, base, subObjTups)
|
||||
"""calculateAdaptivePocket(obj, base, subObjTups)
|
||||
Orient multiple faces around common facial center of mass.
|
||||
Identify edges that are connections for adjacent faces.
|
||||
Attempt to separate unconnected edges into top and bottom loops of the pocket.
|
||||
Trim the top and bottom of the pocket if available and requested.
|
||||
return: tuple with pocket shape information'''
|
||||
return: tuple with pocket shape information"""
|
||||
low = []
|
||||
high = []
|
||||
removeList = []
|
||||
@@ -203,23 +257,35 @@ class ObjectPocket(PathPocketBase.ObjectPocket):
|
||||
highFaceShape = Part.Face(Part.Wire(Part.__sortEdges__(allEdges)))
|
||||
except Exception as ee:
|
||||
PathLog.warning(ee)
|
||||
PathLog.error(translate("Path", "A planar adaptive start is unavailable. The non-planar will be attempted."))
|
||||
PathLog.error(
|
||||
translate(
|
||||
"Path",
|
||||
"A planar adaptive start is unavailable. The non-planar will be attempted.",
|
||||
)
|
||||
)
|
||||
tryNonPlanar = True
|
||||
else:
|
||||
makeHighFace = 1
|
||||
|
||||
if tryNonPlanar is True:
|
||||
try:
|
||||
highFaceShape = Part.makeFilledFace(Part.__sortEdges__(allEdges)) # NON-planar face method
|
||||
highFaceShape = Part.makeFilledFace(
|
||||
Part.__sortEdges__(allEdges)
|
||||
) # NON-planar face method
|
||||
except Exception as eee:
|
||||
PathLog.warning(eee)
|
||||
PathLog.error(translate("Path", "The non-planar adaptive start is also unavailable.") + "(1)")
|
||||
PathLog.error(
|
||||
translate(
|
||||
"Path", "The non-planar adaptive start is also unavailable."
|
||||
)
|
||||
+ "(1)"
|
||||
)
|
||||
isHighFacePlanar = False
|
||||
else:
|
||||
makeHighFace = 2
|
||||
|
||||
if makeHighFace > 0:
|
||||
FreeCAD.ActiveDocument.addObject('Part::Feature', 'topEdgeFace')
|
||||
FreeCAD.ActiveDocument.addObject("Part::Feature", "topEdgeFace")
|
||||
highFace = FreeCAD.ActiveDocument.ActiveObject
|
||||
highFace.Shape = highFaceShape
|
||||
removeList.append(highFace.Name)
|
||||
@@ -228,9 +294,22 @@ class ObjectPocket(PathPocketBase.ObjectPocket):
|
||||
if makeHighFace == 2:
|
||||
mx = hzmax + obj.StepDown.Value
|
||||
mn = hzmin - obj.StepDown.Value
|
||||
if highFace.Shape.BoundBox.ZMax > mx or highFace.Shape.BoundBox.ZMin < mn:
|
||||
PathLog.warning("ZMaxDiff: {}; ZMinDiff: {}".format(highFace.Shape.BoundBox.ZMax - mx, highFace.Shape.BoundBox.ZMin - mn))
|
||||
PathLog.error(translate("Path", "The non-planar adaptive start is also unavailable.") + "(2)")
|
||||
if (
|
||||
highFace.Shape.BoundBox.ZMax > mx
|
||||
or highFace.Shape.BoundBox.ZMin < mn
|
||||
):
|
||||
PathLog.warning(
|
||||
"ZMaxDiff: {}; ZMinDiff: {}".format(
|
||||
highFace.Shape.BoundBox.ZMax - mx,
|
||||
highFace.Shape.BoundBox.ZMin - mn,
|
||||
)
|
||||
)
|
||||
PathLog.error(
|
||||
translate(
|
||||
"Path", "The non-planar adaptive start is also unavailable."
|
||||
)
|
||||
+ "(2)"
|
||||
)
|
||||
isHighFacePlanar = False
|
||||
makeHighFace = 0
|
||||
else:
|
||||
@@ -252,7 +331,7 @@ class ObjectPocket(PathPocketBase.ObjectPocket):
|
||||
PathLog.error("An adaptive finish is unavailable.")
|
||||
isLowFacePlanar = False
|
||||
else:
|
||||
FreeCAD.ActiveDocument.addObject('Part::Feature', 'bottomEdgeFace')
|
||||
FreeCAD.ActiveDocument.addObject("Part::Feature", "bottomEdgeFace")
|
||||
lowFace = FreeCAD.ActiveDocument.ActiveObject
|
||||
lowFace.Shape = lowFaceShape
|
||||
removeList.append(lowFace.Name)
|
||||
@@ -279,9 +358,12 @@ class ObjectPocket(PathPocketBase.ObjectPocket):
|
||||
step_down=obj.StepDown.Value,
|
||||
z_finish_step=finish_step,
|
||||
final_depth=finDep,
|
||||
user_depths=None)
|
||||
user_depths=None,
|
||||
)
|
||||
shape = Part.makeCompound(Faces)
|
||||
env = PathUtils.getEnvelope(base[0].Shape, subshape=shape, depthparams=depthparams)
|
||||
env = PathUtils.getEnvelope(
|
||||
base[0].Shape, subshape=shape, depthparams=depthparams
|
||||
)
|
||||
cuts.append(env.cut(base[0].Shape))
|
||||
|
||||
# Might need to change to .cut(job.Stock.Shape) if pocket has no bottom
|
||||
@@ -305,8 +387,11 @@ class ObjectPocket(PathPocketBase.ObjectPocket):
|
||||
step_down=obj.StepDown.Value,
|
||||
z_finish_step=finish_step,
|
||||
final_depth=finDep1,
|
||||
user_depths=None)
|
||||
envTop = PathUtils.getEnvelope(base[0].Shape, subshape=highFace.Shape, depthparams=depthparams1)
|
||||
user_depths=None,
|
||||
)
|
||||
envTop = PathUtils.getEnvelope(
|
||||
base[0].Shape, subshape=highFace.Shape, depthparams=depthparams1
|
||||
)
|
||||
cbi = len(cuts) - 1
|
||||
cuts.append(cuts[cbi].cut(envTop))
|
||||
|
||||
@@ -326,8 +411,11 @@ class ObjectPocket(PathPocketBase.ObjectPocket):
|
||||
step_down=obj.StepDown.Value,
|
||||
z_finish_step=finish_step,
|
||||
final_depth=finDep2,
|
||||
user_depths=None)
|
||||
envBottom = PathUtils.getEnvelope(base[0].Shape, subshape=lowFace.Shape, depthparams=depthparams2)
|
||||
user_depths=None,
|
||||
)
|
||||
envBottom = PathUtils.getEnvelope(
|
||||
base[0].Shape, subshape=lowFace.Shape, depthparams=depthparams2
|
||||
)
|
||||
cbi = len(cuts) - 1
|
||||
cuts.append(cuts[cbi].cut(envBottom))
|
||||
|
||||
@@ -335,9 +423,10 @@ class ObjectPocket(PathPocketBase.ObjectPocket):
|
||||
sdi = len(starts) - 1
|
||||
fdi = len(finals) - 1
|
||||
cbi = len(cuts) - 1
|
||||
pocket = (cuts[cbi], False, '3DPocket')
|
||||
pocket = (cuts[cbi], False, "3DPocket")
|
||||
if FreeCAD.GuiUp:
|
||||
import FreeCADGui
|
||||
|
||||
for rn in removeList:
|
||||
FreeCADGui.ActiveDocument.getObject(rn).Visibility = False
|
||||
|
||||
@@ -347,11 +436,12 @@ class ObjectPocket(PathPocketBase.ObjectPocket):
|
||||
return pocket
|
||||
|
||||
def orderFacesAroundCenterOfMass(self, subObjTups):
|
||||
'''orderFacesAroundCenterOfMass(subObjTups)
|
||||
"""orderFacesAroundCenterOfMass(subObjTups)
|
||||
Order list of faces by center of mass in angular order around
|
||||
average center of mass for all faces. Positive X-axis is zero degrees.
|
||||
return: subObjTups [ordered/sorted]'''
|
||||
return: subObjTups [ordered/sorted]"""
|
||||
import math
|
||||
|
||||
newList = []
|
||||
vectList = []
|
||||
comList = []
|
||||
@@ -364,7 +454,7 @@ class ObjectPocket(PathPocketBase.ObjectPocket):
|
||||
return vectItem[3]
|
||||
|
||||
def getFaceIdx(sub):
|
||||
return int(sub.replace('Face', '')) - 1
|
||||
return int(sub.replace("Face", "")) - 1
|
||||
|
||||
# get CenterOfMass for each face and add to sumCenterOfMass for average calculation
|
||||
for (sub, face) in subObjTups:
|
||||
@@ -382,22 +472,26 @@ class ObjectPocket(PathPocketBase.ObjectPocket):
|
||||
|
||||
# calculate vector (mag, direct) for each face from avgCom
|
||||
for (sub, face, com) in comList:
|
||||
adjCom = com.sub(avgCom) # effectively treats avgCom as origin for each face.
|
||||
mag = math.sqrt(adjCom.x**2 + adjCom.y**2) # adjCom.Length without Z values
|
||||
adjCom = com.sub(
|
||||
avgCom
|
||||
) # effectively treats avgCom as origin for each face.
|
||||
mag = math.sqrt(
|
||||
adjCom.x ** 2 + adjCom.y ** 2
|
||||
) # adjCom.Length without Z values
|
||||
drctn = 0.0
|
||||
# Determine direction of vector
|
||||
if adjCom.x > 0.0:
|
||||
if adjCom.y > 0.0: # Q1
|
||||
drctn = math.degrees(math.atan(adjCom.y/adjCom.x))
|
||||
drctn = math.degrees(math.atan(adjCom.y / adjCom.x))
|
||||
elif adjCom.y < 0.0:
|
||||
drctn = -math.degrees(math.atan(adjCom.x/adjCom.y)) + 270.0
|
||||
drctn = -math.degrees(math.atan(adjCom.x / adjCom.y)) + 270.0
|
||||
elif adjCom.y == 0.0:
|
||||
drctn = 0.0
|
||||
elif adjCom.x < 0.0:
|
||||
if adjCom.y < 0.0:
|
||||
drctn = math.degrees(math.atan(adjCom.y/adjCom.x)) + 180.0
|
||||
drctn = math.degrees(math.atan(adjCom.y / adjCom.x)) + 180.0
|
||||
elif adjCom.y > 0.0:
|
||||
drctn = -math.degrees(math.atan(adjCom.x/adjCom.y)) + 90.0
|
||||
drctn = -math.degrees(math.atan(adjCom.x / adjCom.y)) + 90.0
|
||||
elif adjCom.y == 0.0:
|
||||
drctn = 180.0
|
||||
elif adjCom.x == 0.0:
|
||||
@@ -434,8 +528,8 @@ class ObjectPocket(PathPocketBase.ObjectPocket):
|
||||
return newList
|
||||
|
||||
def findSharedEdges(self, subObjTups):
|
||||
'''findSharedEdges(self, subObjTups)
|
||||
Find connected edges given a group of faces'''
|
||||
"""findSharedEdges(self, subObjTups)
|
||||
Find connected edges given a group of faces"""
|
||||
checkoutList = []
|
||||
searchedList = []
|
||||
shared = []
|
||||
@@ -471,7 +565,11 @@ class ObjectPocket(PathPocketBase.ObjectPocket):
|
||||
for ei2 in range(0, len(face2.Edges)):
|
||||
edg2 = face2.Edges[ei2]
|
||||
if edg1.isSame(edg2) is True:
|
||||
PathLog.debug("{}.Edges[{}] connects at {}.Edges[{}]".format(sub1, ei1, sub2, ei2))
|
||||
PathLog.debug(
|
||||
"{}.Edges[{}] connects at {}.Edges[{}]".format(
|
||||
sub1, ei1, sub2, ei2
|
||||
)
|
||||
)
|
||||
shared.append((sub1, face1, ei1))
|
||||
touching[sub1].append(ei1)
|
||||
touching[sub2].append(ei2)
|
||||
@@ -486,8 +584,8 @@ class ObjectPocket(PathPocketBase.ObjectPocket):
|
||||
return (shared, touchingCleaned)
|
||||
|
||||
def identifyUnconnectedEdges(self, subObjTups, touching):
|
||||
'''identifyUnconnectedEdges(subObjTups, touching)
|
||||
Categorize unconnected edges into two groups, if possible: low and high'''
|
||||
"""identifyUnconnectedEdges(subObjTups, touching)
|
||||
Categorize unconnected edges into two groups, if possible: low and high"""
|
||||
# Identify unconnected edges
|
||||
# (should be top edge loop if all faces form loop with bottom face(s) included)
|
||||
high = []
|
||||
@@ -518,7 +616,7 @@ class ObjectPocket(PathPocketBase.ObjectPocket):
|
||||
com = FreeCAD.Vector(0, 0, 0)
|
||||
com.add(edg0.CenterOfMass)
|
||||
com.add(edg1.CenterOfMass)
|
||||
avgCom = FreeCAD.Vector(com.x/2.0, com.y/2.0, com.z/2.0)
|
||||
avgCom = FreeCAD.Vector(com.x / 2.0, com.y / 2.0, com.z / 2.0)
|
||||
if avgCom.z > face.CenterOfMass.z:
|
||||
high.extend(holding)
|
||||
else:
|
||||
@@ -534,9 +632,9 @@ class ObjectPocket(PathPocketBase.ObjectPocket):
|
||||
return (low, high)
|
||||
|
||||
def hasCommonVertex(self, edge1, edge2, show=False):
|
||||
'''findCommonVertexIndexes(edge1, edge2, show=False)
|
||||
"""findCommonVertexIndexes(edge1, edge2, show=False)
|
||||
Compare vertexes of two edges to identify a common vertex.
|
||||
Returns the vertex index of edge1 to which edge2 is connected'''
|
||||
Returns the vertex index of edge1 to which edge2 is connected"""
|
||||
if show is True:
|
||||
PathLog.info("New findCommonVertex()... ")
|
||||
|
||||
@@ -561,9 +659,9 @@ class ObjectPocket(PathPocketBase.ObjectPocket):
|
||||
return -1
|
||||
|
||||
def groupConnectedEdges(self, holding):
|
||||
'''groupConnectedEdges(self, holding)
|
||||
"""groupConnectedEdges(self, holding)
|
||||
Take edges and determine which are connected.
|
||||
Group connected chains/loops into: low and high'''
|
||||
Group connected chains/loops into: low and high"""
|
||||
holds = []
|
||||
grps = []
|
||||
searched = []
|
||||
@@ -607,7 +705,7 @@ class ObjectPocket(PathPocketBase.ObjectPocket):
|
||||
|
||||
while len(holds) > 0:
|
||||
if loops > 500:
|
||||
PathLog.error('BREAK --- LOOPS LIMIT of 500 ---')
|
||||
PathLog.error("BREAK --- LOOPS LIMIT of 500 ---")
|
||||
break
|
||||
save = False
|
||||
|
||||
@@ -701,8 +799,8 @@ class ObjectPocket(PathPocketBase.ObjectPocket):
|
||||
return (low, high)
|
||||
|
||||
def getMinMaxOfFaces(self, Faces):
|
||||
'''getMinMaxOfFaces(Faces)
|
||||
return the zmin and zmax values for given set of faces or edges.'''
|
||||
"""getMinMaxOfFaces(Faces)
|
||||
return the zmin and zmax values for given set of faces or edges."""
|
||||
zmin = Faces[0].BoundBox.ZMax
|
||||
zmax = Faces[0].BoundBox.ZMin
|
||||
for f in Faces:
|
||||
@@ -718,7 +816,7 @@ def SetupProperties():
|
||||
|
||||
|
||||
def Create(name, obj=None, parentJob=None):
|
||||
'''Create(name) ... Creates and returns a Pocket operation.'''
|
||||
"""Create(name) ... Creates and returns a Pocket operation."""
|
||||
if obj is None:
|
||||
obj = FreeCAD.ActiveDocument.addObject("Path::FeaturePython", name)
|
||||
obj.Proxy = ObjectPocket(obj, name, parentJob)
|
||||
|
||||
Reference in New Issue
Block a user