Merge pull request #5403 from sliptonic/feature/splitArcsHelper

[Path] Feature/split arcs helper
This commit is contained in:
sliptonic
2022-01-21 13:14:47 -06:00
committed by GitHub
4 changed files with 104 additions and 21 deletions

View File

@@ -54,7 +54,7 @@ UseAbsoluteToolPaths = "UseAbsoluteToolPaths"
# Linear tolerance to use when generating Paths, eg when tessellating geometry
GeometryTolerance = "GeometryTolerance"
LibAreaCurveAccuracy = "LibAreaCurveAccuarcy"
LibAreaCurveAccuracy = "LibAreaCurveAccuracy"
WarningSuppressRapidSpeeds = "WarningSuppressRapidSpeeds"
WarningSuppressAllSpeeds = "WarningSuppressAllSpeeds"

View File

@@ -28,6 +28,10 @@ These are a common functions and classes for creating custom post processors.
from PySide import QtCore, QtGui
import FreeCAD
from PathMachineState import MachineState
import Path
import Part
from PathScripts.PathGeom import CmdMoveArc, edgeForCmd, cmdsForEdge
translate = FreeCAD.Qt.translate
@@ -193,3 +197,32 @@ def fcoms(string, commentsym):
else:
return string
return comment
def splitArcs(path):
"""filters a path object and replaces at G2/G3 moves with discrete G1
returns a Path object"""
prefGrp = FreeCAD.ParamGet("User parameter:BaseApp/Preferences/Mod/Path")
deflection = prefGrp.GetFloat("LibAreaCurveAccuarcy", 0.01)
results = []
if not isinstance(path, Path.Path):
raise TypeError("path must be a Path object")
machine = MachineState()
for command in path.Commands:
if command.Name not in CmdMoveArc:
machine.addCommand(command)
results.append(command)
continue
edge = edgeForCmd(command, machine.getPosition())
pts =edge.discretize(Deflection=deflection)
edges = [Part.makeLine(v1, v2) for v1, v2 in zip(pts, pts[1:])]
for edge in edges:
results.extend(cmdsForEdge(edge))
machine.addCommand(command)
return Path.Path(results)

View File

@@ -28,15 +28,17 @@ import PathScripts.PathJob
import PathScripts.PathPost
import PathScripts.PathToolController
import PathScripts.PathUtil
import PathScripts.PostUtils as PostUtils
import difflib
import unittest
import Path
WriteDebugOutput = False
class PathPostTestCases(unittest.TestCase):
class PathPostTestCases(unittest.TestCase):
def setUp(self):
testfile = FreeCAD.getHomePath() + 'Mod/Path/PathTests/boxtest.fcstd'
testfile = FreeCAD.getHomePath() + "Mod/Path/PathTests/boxtest.fcstd"
self.doc = FreeCAD.open(testfile)
self.job = FreeCAD.ActiveDocument.getObject("Job")
self.postlist = []
@@ -54,54 +56,100 @@ class PathPostTestCases(unittest.TestCase):
def testLinuxCNC(self):
from PathScripts.post import linuxcnc_post as postprocessor
args = '--no-header --no-line-numbers --no-comments --no-show-editor --precision=2'
gcode = postprocessor.export(self.postlist, 'gcode.tmp', args)
referenceFile = FreeCAD.getHomePath() + 'Mod/Path/PathTests/test_linuxcnc_00.ngc'
with open(referenceFile, 'r') as fp:
args = (
"--no-header --no-line-numbers --no-comments --no-show-editor --precision=2"
)
gcode = postprocessor.export(self.postlist, "gcode.tmp", args)
referenceFile = (
FreeCAD.getHomePath() + "Mod/Path/PathTests/test_linuxcnc_00.ngc"
)
with open(referenceFile, "r") as fp:
refGCode = fp.read()
# Use if this test fails in order to have a real good look at the changes
if WriteDebugOutput:
with open('testLinuxCNC.tmp', 'w') as fp:
with open("testLinuxCNC.tmp", "w") as fp:
fp.write(gcode)
if gcode != refGCode:
msg = ''.join(difflib.ndiff(gcode.splitlines(True), refGCode.splitlines(True)))
msg = "".join(
difflib.ndiff(gcode.splitlines(True), refGCode.splitlines(True))
)
self.fail("linuxcnc output doesn't match: " + msg)
def testLinuxCNCImperial(self):
from PathScripts.post import linuxcnc_post as postprocessor
args = '--no-header --no-line-numbers --no-comments --no-show-editor --precision=2 --inches'
gcode = postprocessor.export(self.postlist, 'gcode.tmp', args)
referenceFile = FreeCAD.getHomePath() + 'Mod/Path/PathTests/test_linuxcnc_10.ngc'
with open(referenceFile, 'r') as fp:
args = "--no-header --no-line-numbers --no-comments --no-show-editor --precision=2 --inches"
gcode = postprocessor.export(self.postlist, "gcode.tmp", args)
referenceFile = (
FreeCAD.getHomePath() + "Mod/Path/PathTests/test_linuxcnc_10.ngc"
)
with open(referenceFile, "r") as fp:
refGCode = fp.read()
# Use if this test fails in order to have a real good look at the changes
if WriteDebugOutput:
with open('testLinuxCNCImplerial.tmp', 'w') as fp:
with open("testLinuxCNCImplerial.tmp", "w") as fp:
fp.write(gcode)
if gcode != refGCode:
msg = ''.join(difflib.ndiff(gcode.splitlines(True), refGCode.splitlines(True)))
msg = "".join(
difflib.ndiff(gcode.splitlines(True), refGCode.splitlines(True))
)
self.fail("linuxcnc output doesn't match: " + msg)
def testCentroid(self):
from PathScripts.post import centroid_post as postprocessor
args = '--no-header --no-line-numbers --no-comments --no-show-editor --axis-precision=2 --feed-precision=2'
gcode = postprocessor.export(self.postlist, 'gcode.tmp', args)
referenceFile = FreeCAD.getHomePath() + 'Mod/Path/PathTests/test_centroid_00.ngc'
with open(referenceFile, 'r') as fp:
args = "--no-header --no-line-numbers --no-comments --no-show-editor --axis-precision=2 --feed-precision=2"
gcode = postprocessor.export(self.postlist, "gcode.tmp", args)
referenceFile = (
FreeCAD.getHomePath() + "Mod/Path/PathTests/test_centroid_00.ngc"
)
with open(referenceFile, "r") as fp:
refGCode = fp.read()
# Use if this test fails in order to have a real good look at the changes
if WriteDebugOutput:
with open('testCentroid.tmp', 'w') as fp:
with open("testCentroid.tmp", "w") as fp:
fp.write(gcode)
if gcode != refGCode:
msg = ''.join(difflib.ndiff(gcode.splitlines(True), refGCode.splitlines(True)))
msg = "".join(
difflib.ndiff(gcode.splitlines(True), refGCode.splitlines(True))
)
self.fail("linuxcnc output doesn't match: " + msg)
class TestPathPostUtils(unittest.TestCase):
def testSplitArcs(self):
commands = [
Path.Command("G1 X-7.5 Y5.0 Z0.0"),
Path.Command("G2 I2.5 J0.0 K0.0 X-5.0 Y7.5 Z0.0"),
Path.Command("G1 X5.0 Y7.5 Z0.0"),
Path.Command("G2 I0.0 J-2.5 K0.0 X7.5 Y5.0 Z0.0"),
Path.Command("G1 X7.5 Y-5.0 Z0.0"),
Path.Command("G2 I-2.5 J0.0 K0.0 X5.0 Y-7.5 Z0.0"),
Path.Command("G1 X-5.0 Y-7.5 Z0.0"),
Path.Command("G2 I0.0 J2.5 K0.0 X-7.5 Y-5.0 Z0.0"),
Path.Command("G1 X-7.5 Y0.0 Z0.0"),
]
testpath = Path.Path(commands)
self.assertTrue(len(testpath.Commands) == 9)
self.assertTrue(len([c for c in testpath.Commands if c.Name in ['G2', 'G3']]) == 4)
results = PostUtils.splitArcs(testpath)
self.assertTrue(len(results.Commands) == 117)
self.assertTrue(len([c for c in results.Commands if c.Name in ['G2', 'G3']]) == 0)

View File

@@ -37,6 +37,7 @@ from PathTests.TestPathHelixGenerator import TestPathHelixGenerator
from PathTests.TestPathLog import TestPathLog
from PathTests.TestPathOpTools import TestPathOpTools
# from PathTests.TestPathPost import PathPostTestCases
from PathTests.TestPathPost import TestPathPostUtils
from PathTests.TestPathPreferences import TestPathPreferences
from PathTests.TestPathPropertyBag import TestPathPropertyBag
from PathTests.TestPathRotationGenerator import TestPathRotationGenerator
@@ -66,6 +67,7 @@ False if TestPathHelpers.__name__ else True
False if TestPathLog.__name__ else True
False if TestPathOpTools.__name__ else True
# False if TestPathPost.__name__ else True
False if TestPathPostUtils.__name__ else True
False if TestPathPreferences.__name__ else True
False if TestPathPropertyBag.__name__ else True
False if TestPathRotationGenerator.__name__ else True