Split base hole processing into separate class.

This commit is contained in:
Markus Lampert
2017-08-08 09:41:06 -07:00
committed by Yorik van Havre
parent 26b9c67da6
commit bddcb28424
2 changed files with 37 additions and 190 deletions

View File

@@ -20,6 +20,7 @@ SET(PathScripts_SRCS
PathCommands.py
PathScripts/PathAreaOp.py
PathScripts/PathArray.py
PathScripts/PathCircularHoleBase.py
PathScripts/PathComment.py
PathScripts/PathCompoundExtended.py
PathScripts/PathCopy.py

View File

@@ -27,19 +27,14 @@ from __future__ import print_function
import ArchPanel
import FreeCAD
import Path
import PathScripts.PathCircularHoleBase as PathCircularHoleBase
import PathScripts.PathLog as PathLog
import PathScripts.PathOp as PathOp
import PathScripts.PathUtils as PathUtils
import string
import sys
from PathScripts.PathUtils import fmt, waiting_effects
from PySide import QtCore
# xrange is not available in python3
if sys.version_info.major >= 3:
xrange = range
if False:
PathLog.setLevel(PathLog.Level.DEBUG, PathLog.thisModule())
PathLog.trackModule(PathLog.thisModule())
@@ -53,10 +48,11 @@ def translate(context, text, disambig=None):
return QtCore.QCoreApplication.translate(context, text, disambig)
class ObjectDrilling(PathOp.ObjectOp):
class ObjectDrilling(PathCircularHoleBase.ObjectOp):
def opFeatures(self, obj):
return PathOp.FeatureTool | PathOp.FeatureDepths | PathOp.FeatureHeights | PathOp.FeatureBaseGeometry
def circularHoleFeatures(self, obj):
# drilling works on anything
return PathOp.FeatureBaseGeometry
def initOperation(self, obj):
@@ -71,197 +67,47 @@ class ObjectDrilling(PathOp.ObjectOp):
obj.addProperty("App::PropertyDistance", "RetractHeight", "Depth", QtCore.QT_TRANSLATE_NOOP("App::Property", "The height where feed starts and height during retract tool when path is finished"))
self.vertFeed = 0.0
self.horizFeed = 0.0
self.vertRapid = 0.0
self.horizRapid = 0.0
def baseIsArchPanel(self, obj, base):
return hasattr(base, "Proxy") and isinstance(base.Proxy, ArchPanel.PanelSheet)
def getArchPanelEdge(self, obj, base, sub):
ids = string.split(sub, '.')
holeId = int(ids[0])
wireId = int(ids[1])
edgeId = int(ids[2])
for holeNr, hole in enumerate(base.Proxy.getHoles(base, transform=True)):
if holeNr == holeId:
for wireNr, wire in enumerate(hole.Wires):
if wireNr == wireId:
for edgeNr, edge in enumerate(wire.Edges):
if edgeNr == edgeId:
return edge
def holeDiameter(self, obj, base, sub):
if self.baseIsArchPanel(obj, base):
edge = self.getArchPanelEdge(obj, base, sub)
return edge.BoundBox.XLength
shape = base.Shape.getElement(sub)
if shape.ShapeType == 'Vertex':
return 0
# for all other shapes the diameter is just the dimension in X
return shape.BoundBox.XLength
def holePosition(self, obj, base, sub):
if self.baseIsArchPanel(obj, base):
edge = self.getArchPanelEdge(obj, base, sub)
center = edge.Curve.Center
return FreeCAD.Vector(center.x, center.y, 0)
shape = base.Shape.getElement(sub)
if shape.ShapeType == 'Vertex':
return FreeCAD.Vector(shape.X, shape.Y, 0)
if shape.ShapeType == 'Edge':
return FreeCAD.Vector(shape.Curve.Center.x, shape.Curve.Center.y, 0)
if shape.ShapeType == 'Face':
return FreeCAD.Vector(shape.Surface.Center.x, shape.Surface.Center.y, 0)
PathLog.error('This is bad')
def isHoleEnabled(self, obj, base, sub):
name = "%s.%s" % (base.Name, sub)
return not name in obj.Disabled
def opExecute(self, obj):
def circularHoleExecute(self, obj, holes):
PathLog.track()
self.commandlist.append(Path.Command("(Begin Drilling)"))
tiplength = 0.0
if obj.AddTipLength:
tiplength = PathUtils.drillTipLength(tool)
if len(obj.Base) == 0:
job = PathUtils.findParentJob(obj)
if not job or not job.Base:
return
baseobject = job.Base
holes = PathUtils.sort_jobs(holes, ['x', 'y'])
self.commandlist.append(Path.Command('G90'))
self.commandlist.append(Path.Command(obj.ReturnLevel))
# rapid to clearance height
self.commandlist.append(Path.Command('G0', {'Z': obj.ClearanceHeight.Value, 'F': self.vertRapid}))
# rapid to first hole location, with spindle still retracted:
# Arch PanelSheet
features = []
fbb = None
if self.baseIsArchPanel(obj, baseobject):
holeshapes = baseobject.Proxy.getHoles(baseobject, transform=True)
tooldiameter = obj.ToolController.Proxy.getTool(obj.ToolController).Diameter
for holeNr, hole in enumerate(holeshapes):
PathLog.debug('Entering new HoleShape')
for wireNr, wire in enumerate(hole.Wires):
PathLog.debug('Entering new Wire')
for edgeNr, edge in enumerate(wire.Edges):
if PathUtils.isDrillable(baseobject, edge, tooldiameter):
PathLog.debug('Found drillable hole edges: {}'.format(edge))
features.append((baseobject, "%d.%d.%d" % (holeNr, wireNr, edgeNr)))
p0 = holes[0]
self.commandlist.append(Path.Command('G0', {'X': p0['x'], 'Y': p0['y'], 'F': self.horizRapid}))
# move tool to clearance plane
self.commandlist.append(Path.Command('G0', {'Z': obj.ClearanceHeight.Value, 'F': self.vertRapid}))
else:
features = self.findHoles(obj, baseobject)
for base,sub in features:
shape = base.Shape.getElement(sub)
fbb = fbb.united(shape.BoundBox) if fbb else shape.BoundBox
obj.Base = features
self.setDepths(obj, obj.Base[0][0].Shape.BoundBox, fbb)
obj.Disabled = []
cmd = "G81"
cmdParams = {}
cmdParams['Z'] = obj.FinalDepth.Value - tiplength
cmdParams['F'] = self.vertFeed
cmdParams['R'] = obj.RetractHeight.Value
if obj.PeckEnabled and obj.PeckDepth.Value > 0:
cmd = "G83"
cmdParams['Q'] = obj.PeckDepth.Value
elif obj.DwellEnabled and obj.DwellTime > 0:
cmd = "G82"
cmdParams['P'] = obj.DwellTime
locations = []
self.commandlist.append(Path.Command("(Begin Drilling)"))
for p in holes:
params = {}
params['X'] = p['x']
params['Y'] = p['y']
params.update(cmdParams)
self.commandlist.append(Path.Command(cmd, params))
for base, subs in obj.Base:
for sub in subs:
if self.isHoleEnabled(obj, base, sub):
pos = self.holePosition(obj, base, sub)
locations.append({'x': pos.x, 'y': pos.y})
if len(locations) > 0:
locations = PathUtils.sort_jobs(locations, ['x', 'y'])
self.commandlist.append(Path.Command('G90'))
self.commandlist.append(Path.Command(obj.ReturnLevel))
# rapid to clearance height
self.commandlist.append(Path.Command('G0', {'Z': obj.ClearanceHeight.Value, 'F': self.vertRapid}))
# rapid to first hole location, with spindle still retracted:
p0 = locations[0]
self.commandlist.append(Path.Command('G0', {'X': p0['x'], 'Y': p0['y'], 'F': self.horizRapid}))
# move tool to clearance plane
self.commandlist.append(Path.Command('G0', {'Z': obj.ClearanceHeight.Value, 'F': self.vertRapid}))
cmd = "G81"
cmdParams = {}
cmdParams['Z'] = obj.FinalDepth.Value - tiplength
cmdParams['F'] = self.vertFeed
cmdParams['R'] = obj.RetractHeight.Value
if obj.PeckEnabled and obj.PeckDepth.Value > 0:
cmd = "G83"
cmdParams['Q'] = obj.PeckDepth.Value
elif obj.DwellEnabled and obj.DwellTime > 0:
cmd = "G82"
cmdParams['P'] = obj.DwellTime
for p in locations:
params = {}
params['X'] = p['x']
params['Y'] = p['y']
params.update(cmdParams)
self.commandlist.append(Path.Command(cmd, params))
self.commandlist.append(Path.Command('G80'))
def setDepths(self, obj, bb, fbb):
if bb and fbb:
obj.StartDepth = bb.ZMax
obj.ClearanceHeight = bb.ZMax + 5.0
obj.SafeHeight = bb.ZMax + 3.0
obj.RetractHeight = bb.ZMax + 1.0
if fbb.ZMax < bb.ZMax:
obj.FinalDepth = fbb.ZMax
else:
obj.FinalDepth = bb.ZMin
else:
obj.StartDepth = 5.0
obj.ClearanceHeight = 10.0
obj.SafeHeight = 8.0
obj.RetractHeight = 6.0
def findHoles(self, obj, baseobject):
import DraftGeomUtils as dgu
shape = baseobject.Shape
PathLog.track('obj: {} shape: {}'.format(obj, shape))
holelist = []
features = []
# tooldiameter = obj.ToolController.Proxy.getTool(obj.ToolController).Diameter
tooldiameter = None
PathLog.debug('search for holes larger than tooldiameter: {}: '.format(tooldiameter))
if dgu.isPlanar(shape):
PathLog.debug("shape is planar")
for i in range(len(shape.Edges)):
candidateEdgeName = "Edge" + str(i + 1)
e = shape.getElement(candidateEdgeName)
if PathUtils.isDrillable(shape, e, tooldiameter):
PathLog.debug('edge candidate: {} (hash {})is drillable '.format(e, e.hashCode()))
x = e.Curve.Center.x
y = e.Curve.Center.y
diameter = e.BoundBox.XLength
holelist.append({'featureName': candidateEdgeName, 'feature': e, 'x': x, 'y': y, 'd': diameter, 'enabled': True})
features.append((baseobject, candidateEdgeName))
PathLog.debug("Found hole feature %s.%s" % (baseobject.Label, candidateEdgeName))
else:
PathLog.debug("shape is not planar")
for i in range(len(shape.Faces)):
candidateFaceName = "Face" + str(i + 1)
f = shape.getElement(candidateFaceName)
if PathUtils.isDrillable(shape, f, tooldiameter):
PathLog.debug('face candidate: {} is drillable '.format(f))
x = f.Surface.Center.x
y = f.Surface.Center.y
diameter = f.BoundBox.XLength
holelist.append({'featureName': candidateFaceName, 'feature': f, 'x': x, 'y': y, 'd': diameter, 'enabled': True})
features.append((baseobject, candidateFaceName))
PathLog.debug("Found hole feature %s.%s" % (baseobject.Label, candidateFaceName))
PathLog.debug("holes found: {}".format(holelist))
return features
self.commandlist.append(Path.Command('G80'))
def opSetDefaultValues(self, obj):
obj.RetractHeight = 10