Extracted and added tests for chamfer tool depth and offset calculations.
This commit is contained in:
@@ -33,7 +33,7 @@ import math
|
||||
|
||||
from PySide import QtCore
|
||||
|
||||
if True:
|
||||
if False:
|
||||
PathLog.setLevel(PathLog.Level.DEBUG, PathLog.thisModule())
|
||||
PathLog.trackModule(PathLog.thisModule())
|
||||
else:
|
||||
@@ -80,6 +80,7 @@ def orientWire(w, forward=True):
|
||||
return wire
|
||||
|
||||
def isCircleAt(edge, center):
|
||||
'''isCircleAt(edge, center) ... helper function returns True if edge is a circle at the given center.'''
|
||||
if Circel == type(edge.Curve) or ArcOfCircle == type(edge.Curve):
|
||||
return PathGeom.pointsCoincide(edge.Curve.Center, center)
|
||||
return False
|
||||
@@ -206,6 +207,21 @@ def offsetWire(wire, base, offset, forward):
|
||||
edges = [PathGeom.flipEdge(edge) for edge in rightSideEdges]
|
||||
return Part.Wire(edges)
|
||||
|
||||
def toolDepthAndOffset(width, extraDepth, tool):
|
||||
'''toolDepthAndOffset(width, extraDepth, tool) ... return tuple for given parameters.'''
|
||||
angle = tool.CuttingEdgeAngle
|
||||
if 0 == angle:
|
||||
angle = 180
|
||||
tan = math.tan(math.radians(angle/2))
|
||||
|
||||
toolDepth = 0 if 0 == tan else width / tan
|
||||
extraDepth = extraDepth
|
||||
depth = toolDepth + extraDepth
|
||||
toolOffset = tool.FlatRadius
|
||||
extraOffset = tool.Diameter/2 - width if 180 == angle else extraDepth / tan
|
||||
offset = toolOffset + extraOffset
|
||||
return (depth, offset)
|
||||
|
||||
class ObjectChamfer(PathEngraveBase.ObjectOp):
|
||||
'''Proxy class for Chamfer operation.'''
|
||||
|
||||
@@ -213,23 +229,14 @@ class ObjectChamfer(PathEngraveBase.ObjectOp):
|
||||
return PathOp.FeatureTool | PathOp.FeatureHeights | PathOp.FeatureBaseEdges | PathOp.FeatureBaseFaces
|
||||
|
||||
def initOperation(self, obj):
|
||||
obj.addProperty("App::PropertyDistance", "Width", "Chamfer", QtCore.QT_TRANSLATE_NOOP("PathChamfer", "The desired width of the chamfer"))
|
||||
obj.addProperty("App::PropertyDistance", "ExtraDepth", "Chamfer", QtCore.QT_TRANSLATE_NOOP("PathChamfer", "The additional depth of the tool path"))
|
||||
obj.addProperty("App::PropertyEnumeration", "Join", "Chamfer", QtCore.QT_TRANSLATE_NOOP("PathChamfer", "How to join chamfer segments"))
|
||||
obj.addProperty('App::PropertyDistance', 'Width', 'Chamfer', QtCore.QT_TRANSLATE_NOOP('PathChamfer', 'The desired width of the chamfer'))
|
||||
obj.addProperty('App::PropertyDistance', 'ExtraDepth', 'Chamfer', QtCore.QT_TRANSLATE_NOOP('PathChamfer', 'The additional depth of the tool path'))
|
||||
obj.addProperty('App::PropertyEnumeration', 'Join', 'Chamfer', QtCore.QT_TRANSLATE_NOOP('PathChamfer', 'How to join chamfer segments'))
|
||||
obj.Join = ['Round', 'Miter']
|
||||
obj.setEditorMode('Join', 2) # hide for now
|
||||
|
||||
def opExecute(self, obj):
|
||||
angle = self.tool.CuttingEdgeAngle
|
||||
if 0 == angle:
|
||||
angle = 180
|
||||
tan = math.tan(math.radians(angle/2))
|
||||
|
||||
toolDepth = 0 if 0 == tan else obj.Width.Value / tan
|
||||
extraDepth = obj.ExtraDepth.Value
|
||||
depth = toolDepth + extraDepth
|
||||
toolOffset = self.tool.FlatRadius
|
||||
extraOffset = self.tool.Diameter/2 - obj.Width.Value if 180 == angle else obj.ExtraDepth.Value / tan
|
||||
offset = toolOffset + extraOffset
|
||||
(depth, offset) = toolDepthAndOffset(obj.Width.Value, obj.ExtraDepth.Value, self.tool)
|
||||
|
||||
self.basewires = []
|
||||
self.adjusted_basewires = []
|
||||
|
||||
@@ -466,3 +466,65 @@ class TestPathChamfer(PathTestUtils.PathTestBase):
|
||||
self.assertRoughly(radius, e.Curve.Radius)
|
||||
self.assertCoincide(Vector(0, 0, -1), e.Curve.Axis)
|
||||
|
||||
|
||||
def test50(self):
|
||||
'''Verify chamfer depth and offset for an end mill.'''
|
||||
tool = Path.Tool()
|
||||
tool.Diameter = 20
|
||||
tool.FlatRadius = 0
|
||||
tool.CuttingEdgeAngle = 180
|
||||
|
||||
(depth, offset) = PathChamfer.toolDepthAndOffset(1, 0.01, tool)
|
||||
self.assertRoughly(0.01, depth)
|
||||
self.assertRoughly(9, offset)
|
||||
|
||||
# legacy tools - no problem, same result
|
||||
tool.CuttingEdgeAngle = 0
|
||||
|
||||
(depth, offset) = PathChamfer.toolDepthAndOffset(1, 0.01, tool)
|
||||
self.assertRoughly(0.01, depth)
|
||||
self.assertRoughly(9, offset)
|
||||
|
||||
def test51(self):
|
||||
'''Verify chamfer depth and offset for a 90° v-bit.'''
|
||||
tool = Path.Tool()
|
||||
tool.FlatRadius = 0
|
||||
tool.CuttingEdgeAngle = 90
|
||||
|
||||
(depth, offset) = PathChamfer.toolDepthAndOffset(1, 0, tool)
|
||||
self.assertRoughly(1, depth)
|
||||
self.assertRoughly(0, offset)
|
||||
|
||||
(depth, offset) = PathChamfer.toolDepthAndOffset(1, 0.2, tool)
|
||||
self.assertRoughly(1.2, depth)
|
||||
self.assertRoughly(0.2, offset)
|
||||
|
||||
def test52(self):
|
||||
'''Verify chamfer depth and offset for a 90° v-bit with non 0 flat radius.'''
|
||||
tool = Path.Tool()
|
||||
tool.FlatRadius = 0.3
|
||||
tool.CuttingEdgeAngle = 90
|
||||
|
||||
(depth, offset) = PathChamfer.toolDepthAndOffset(1, 0, tool)
|
||||
self.assertRoughly(1, depth)
|
||||
self.assertRoughly(0.3, offset)
|
||||
|
||||
(depth, offset) = PathChamfer.toolDepthAndOffset(2, 0.2, tool)
|
||||
self.assertRoughly(2.2, depth)
|
||||
self.assertRoughly(0.5, offset)
|
||||
|
||||
def test53(self):
|
||||
'''Verify chamfer depth and offset for a 60° v-bit with non 0 flat radius.'''
|
||||
tool = Path.Tool()
|
||||
tool.FlatRadius = 10
|
||||
tool.CuttingEdgeAngle = 60
|
||||
|
||||
td = 1.73205
|
||||
|
||||
(depth, offset) = PathChamfer.toolDepthAndOffset(1, 0, tool)
|
||||
self.assertRoughly(td, depth)
|
||||
self.assertRoughly(10, offset)
|
||||
|
||||
(depth, offset) = PathChamfer.toolDepthAndOffset(3, 1, tool)
|
||||
self.assertRoughly(td * 3 + 1, depth)
|
||||
self.assertRoughly(10 + td, offset)
|
||||
|
||||
Reference in New Issue
Block a user