Path: Add some Adaptive unit tests
Also includes alphabetical sort of affected lists in CMakeLists and TestPathApp files. Unit tests focus around feature selection capabilities.
This commit is contained in:
@@ -194,7 +194,14 @@ SET(Tools_Shape_SRCS
|
||||
|
||||
SET(PathTests_SRCS
|
||||
PathTests/__init__.py
|
||||
PathTests/boxtest.fcstd
|
||||
PathTests/PathTestUtils.py
|
||||
PathTests/test_adaptive.fcstd
|
||||
PathTests/test_centroid_00.ngc
|
||||
PathTests/test_geomop.fcstd
|
||||
PathTests/test_holes00.fcstd
|
||||
PathTests/test_linuxcnc_00.ngc
|
||||
PathTests/TestPathAdaptive.py
|
||||
PathTests/TestPathCore.py
|
||||
PathTests/TestPathDeburr.py
|
||||
PathTests/TestPathDepthParams.py
|
||||
@@ -220,11 +227,6 @@ SET(PathTests_SRCS
|
||||
PathTests/Tools/Bit/test-path-tool-bit-bit-00.fctb
|
||||
PathTests/Tools/Library/test-path-tool-bit-library-00.fctl
|
||||
PathTests/Tools/Shape/test-path-tool-bit-shape-00.fcstd
|
||||
PathTests/boxtest.fcstd
|
||||
PathTests/test_centroid_00.ngc
|
||||
PathTests/test_geomop.fcstd
|
||||
PathTests/test_holes00.fcstd
|
||||
PathTests/test_linuxcnc_00.ngc
|
||||
)
|
||||
|
||||
SET(PathImages_Ops
|
||||
|
||||
544
src/Mod/Path/PathTests/TestPathAdaptive.py
Normal file
544
src/Mod/Path/PathTests/TestPathAdaptive.py
Normal file
@@ -0,0 +1,544 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# ***************************************************************************
|
||||
# * Copyright (c) 2021 Russell Johnson (russ4262) <russ4262@gmail.com> *
|
||||
# * *
|
||||
# * This program is free software; you can redistribute it and/or modify *
|
||||
# * it under the terms of the GNU Lesser General Public License (LGPL) *
|
||||
# * as published by the Free Software Foundation; either version 2 of *
|
||||
# * the License, or (at your option) any later version. *
|
||||
# * for detail see the LICENCE text file. *
|
||||
# * *
|
||||
# * This program is distributed in the hope that it will be useful, *
|
||||
# * but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
# * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
# * GNU Library General Public License for more details. *
|
||||
# * *
|
||||
# * You should have received a copy of the GNU Library General Public *
|
||||
# * License along with this program; if not, write to the Free Software *
|
||||
# * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 *
|
||||
# * USA *
|
||||
# * *
|
||||
# ***************************************************************************
|
||||
|
||||
import FreeCAD
|
||||
import Part
|
||||
import PathScripts.PathJob as PathJob
|
||||
import PathScripts.PathAdaptive as PathAdaptive
|
||||
import PathScripts.PathGeom as PathGeom
|
||||
from PathTests.PathTestUtils import PathTestBase
|
||||
if FreeCAD.GuiUp:
|
||||
import PathScripts.PathAdaptiveGui as PathAdaptiveGui
|
||||
import PathScripts.PathJobGui as PathJobGui
|
||||
|
||||
|
||||
class TestPathAdaptive(PathTestBase):
|
||||
'''Unit tests for the Adaptive operation.'''
|
||||
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
'''setUpClass()...
|
||||
This method is called upon instantiation of this test class. Add code and objects here
|
||||
that are needed for the duration of the test() methods in this class. In other words,
|
||||
set up the 'global' test environment here; use the `setUp()` method to set up a 'local'
|
||||
test environment.
|
||||
This method does not have access to the class `self` reference, but it
|
||||
is able to call static methods within this same class.
|
||||
'''
|
||||
|
||||
# Create a new document and create test geometry
|
||||
# doc_title = "TestAdaptive"
|
||||
# doc = FreeCAD.newDocument(doc_title)
|
||||
# cls._createTestGeometry(doc)
|
||||
|
||||
# Open existing document with test geometry
|
||||
doc = FreeCAD.open(FreeCAD.getHomePath() + 'Mod/Path/PathTests/test_adaptive.fcstd')
|
||||
|
||||
# Create Job object, adding geometry objects from file opened above
|
||||
job = PathJob.Create('Job', [doc.Fusion], None)
|
||||
job.GeometryTolerance.Value = 0.001
|
||||
if FreeCAD.GuiUp:
|
||||
job.ViewObject.Proxy = PathJobGui.ViewProvider(job.ViewObject)
|
||||
|
||||
# Instantiate an Adaptive operation for quering available properties
|
||||
prototype = PathAdaptive.Create("Adaptive")
|
||||
prototype.Base = [(doc.Fusion, ["Face3"])]
|
||||
prototype.Label = "Prototype"
|
||||
_addViewProvider(prototype)
|
||||
|
||||
doc.recompute()
|
||||
|
||||
@classmethod
|
||||
def tearDownClass(cls):
|
||||
'''tearDownClass()...
|
||||
This method is called prior to destruction of this test class. Add code and objects here
|
||||
that cleanup the test environment after the test() methods in this class have been executed.
|
||||
This method does not have access to the class `self` reference. This method
|
||||
is able to call static methods within this same class.
|
||||
'''
|
||||
# FreeCAD.Console.PrintMessage("TestPathAdaptive.tearDownClass()\n")
|
||||
|
||||
# Do not close document unless unit tests are commandline only
|
||||
if FreeCAD.GuiUp:
|
||||
pass
|
||||
else:
|
||||
FreeCAD.closeDocument(FreeCAD.ActiveDocument.Name)
|
||||
|
||||
@staticmethod
|
||||
def _createTestGeometry(doc):
|
||||
'''_createTestGeometry(doc)...
|
||||
This contains the instructions to create test geometry for the unit tests in this class.
|
||||
A simple example creation is provided.
|
||||
'''
|
||||
|
||||
# Create a square donut
|
||||
box0 = doc.addObject('Part::Box', 'Box0') # Box
|
||||
box0.Length = 50.0
|
||||
box0.Width = 50.0
|
||||
box0.Height = 10.0
|
||||
box1 = doc.addObject('Part::Box', 'Box1') # Box001
|
||||
box1.Length = 10.0 # X
|
||||
box1.Width = 10.0 # Y
|
||||
box1.Height = 20.0 # Z
|
||||
box1.Placement = FreeCAD.Placement(FreeCAD.Vector(10.0, 10.0, -5.0), FreeCAD.Rotation(FreeCAD.Vector(0,0,1), 0))
|
||||
cut0 = doc.addObject('Part::Cut', 'Cut0')
|
||||
cut0.Base = box0
|
||||
cut0.Tool = box1
|
||||
doc.recompute()
|
||||
|
||||
# Setup and tear down methods called before and after each unit test
|
||||
def setUp(self):
|
||||
'''setUp()...
|
||||
This method is called prior to each `test()` method. Add code and objects here
|
||||
that are needed for multiple `test()` methods.
|
||||
'''
|
||||
self.doc = FreeCAD.ActiveDocument
|
||||
self.con = FreeCAD.Console
|
||||
|
||||
def tearDown(self):
|
||||
'''tearDown()...
|
||||
This method is called after each test() method. Add cleanup instructions here.
|
||||
Such cleanup instructions will likely undo those in the setUp() method.
|
||||
'''
|
||||
pass
|
||||
|
||||
# Unit tests
|
||||
def test00(self):
|
||||
'''test00() Empty test: Verify default property values.'''
|
||||
return
|
||||
|
||||
def test01(self):
|
||||
'''test01() Verify path generated on Face3.'''
|
||||
|
||||
# Instantiate a Adaptive operation and set Base Geometry
|
||||
adaptive = PathAdaptive.Create('Adaptive')
|
||||
adaptive.Base = [(self.doc.Fusion, ["Face3"])] # (base, subs_list)
|
||||
adaptive.Label = "test01+"
|
||||
adaptive.Comment = "test01() Verify path generated on Face3."
|
||||
|
||||
# Set additional operation properties
|
||||
# setDepthsAndHeights(adaptive)
|
||||
adaptive.FinishingProfile = False
|
||||
adaptive.HelixAngle = 75.0
|
||||
adaptive.HelixDiameterLimit.Value = 1.0
|
||||
adaptive.LiftDistance.Value = 1.0
|
||||
adaptive.StepOver = 75
|
||||
adaptive.UseOutline = False
|
||||
adaptive.setExpression('StepDown', None)
|
||||
adaptive.StepDown.Value = 20.0 # Have to set expression to None before numerical value assignment
|
||||
|
||||
_addViewProvider(adaptive)
|
||||
self.doc.recompute()
|
||||
|
||||
# moves = getGcodeMoves(adaptive.Path.Commands, includeRapids=False)
|
||||
# operationMoves = "; ".join(moves)
|
||||
# self.con.PrintMessage("test00_moves: " + operationMoves + "\n")
|
||||
|
||||
# self.assertTrue(expected_moves_test01 == operationMoves,
|
||||
# "expected_moves_test01: {}\noperationMoves: {}".format(expected_moves_test01, operationMoves))
|
||||
self.assertTrue(len(adaptive.Path.Commands) > 100, "Command count not greater than 100.")
|
||||
|
||||
def test02(self):
|
||||
'''test02() Verify path generated on adjacent, combined Face3 and Face10. The Z heights are different.'''
|
||||
|
||||
# Instantiate a Adaptive operation and set Base Geometry
|
||||
adaptive = PathAdaptive.Create('Adaptive')
|
||||
adaptive.Base = [(self.doc.Fusion, ["Face3", "Face10"])] # (base, subs_list)
|
||||
adaptive.Label = "test02+"
|
||||
adaptive.Comment = "test02() Verify path generated on adjacent, combined Face3 and Face10. The Z heights are different."
|
||||
|
||||
# Set additional operation properties
|
||||
# setDepthsAndHeights(adaptive)
|
||||
adaptive.FinishingProfile = False
|
||||
adaptive.HelixAngle = 75.0
|
||||
adaptive.HelixDiameterLimit.Value = 1.0
|
||||
adaptive.LiftDistance.Value = 1.0
|
||||
adaptive.StepOver = 75
|
||||
adaptive.UseOutline = False
|
||||
adaptive.setExpression('StepDown', None)
|
||||
adaptive.StepDown.Value = 20.0 # Have to set expression to None before numerical value assignment
|
||||
|
||||
_addViewProvider(adaptive)
|
||||
self.doc.recompute()
|
||||
|
||||
self.assertTrue(len(adaptive.Path.Commands) > 100, "Command count not greater than 100.")
|
||||
|
||||
def test03(self):
|
||||
'''test03() Verify path generated on adjacent, combined Face3 and Face10. The Z heights are different.'''
|
||||
|
||||
# Instantiate a Adaptive operation and set Base Geometry
|
||||
adaptive = PathAdaptive.Create('Adaptive')
|
||||
adaptive.Base = [(self.doc.Fusion, ["Face3", "Face10"])] # (base, subs_list)
|
||||
adaptive.Label = "test03+"
|
||||
adaptive.Comment = "test03() Verify path generated on adjacent, combined Face3 and Face10. The Z heights are different."
|
||||
|
||||
# Set additional operation properties
|
||||
# setDepthsAndHeights(adaptive)
|
||||
adaptive.FinishingProfile = False
|
||||
adaptive.HelixAngle = 75.0
|
||||
adaptive.HelixDiameterLimit.Value = 1.0
|
||||
adaptive.LiftDistance.Value = 1.0
|
||||
adaptive.StepOver = 75
|
||||
adaptive.UseOutline = True
|
||||
adaptive.setExpression('StepDown', None)
|
||||
adaptive.StepDown.Value = 20.0 # Have to set expression to None before numerical value assignment
|
||||
|
||||
_addViewProvider(adaptive)
|
||||
self.doc.recompute()
|
||||
|
||||
self.assertTrue(len(adaptive.Path.Commands) > 100, "Command count not greater than 100.")
|
||||
|
||||
def test04(self):
|
||||
'''test04() Verify path generated non-closed edges with differing Z-heights that are closed with Z=1 projection: "Edge9", "Edge2", "Edge8", "Edge15", "Edge30", "Edge31", "Edge29", "Edge19".'''
|
||||
|
||||
# Instantiate a Adaptive operation and set Base Geometry
|
||||
adaptive = PathAdaptive.Create('Adaptive')
|
||||
adaptive.Base = [(self.doc.Fusion, ["Edge9", "Edge2", "Edge8", "Edge15", "Edge30", "Edge31", "Edge29", "Edge19"])] # (base, subs_list)
|
||||
adaptive.Label = "test04+"
|
||||
adaptive.Comment = 'test04() Verify path generated non-closed edges with differing Z-heights that are closed with Z=1 projection: "Edge9", "Edge2", "Edge8", "Edge15", "Edge30", "Edge31", "Edge29", "Edge19".'
|
||||
|
||||
# Set additional operation properties
|
||||
# setDepthsAndHeights(adaptive)
|
||||
adaptive.FinishingProfile = False
|
||||
adaptive.HelixAngle = 75.0
|
||||
adaptive.HelixDiameterLimit.Value = 1.0
|
||||
adaptive.LiftDistance.Value = 1.0
|
||||
adaptive.StepOver = 75
|
||||
adaptive.UseOutline = False
|
||||
adaptive.setExpression('StepDown', None)
|
||||
adaptive.StepDown.Value = 20.0 # Have to set expression to None before numerical value assignment
|
||||
|
||||
_addViewProvider(adaptive)
|
||||
self.doc.recompute()
|
||||
|
||||
self.assertTrue(len(adaptive.Path.Commands) > 100, "Command count not greater than 100.")
|
||||
|
||||
def test05(self):
|
||||
'''test05() Verify path generated closed wire with differing Z-heights: "Edge13", "Edge7", "Edge9", "Edge2", "Edge8", "Edge15", "Edge30", "Edge31", "Edge29", "Edge19".'''
|
||||
|
||||
# Instantiate a Adaptive operation and set Base Geometry
|
||||
adaptive = PathAdaptive.Create('Adaptive')
|
||||
adaptive.Base = [(self.doc.Fusion, ["Edge13", "Edge7", "Edge9", "Edge2", "Edge8", "Edge15", "Edge30", "Edge31", "Edge29", "Edge19"])] # (base, subs_list)
|
||||
adaptive.Label = "test05+"
|
||||
adaptive.Comment = 'test05() Verify path generated closed wire with differing Z-heights: "Edge13", "Edge7", "Edge9", "Edge2", "Edge8", "Edge15", "Edge30", "Edge31", "Edge29", "Edge19".'
|
||||
|
||||
# Set additional operation properties
|
||||
# setDepthsAndHeights(adaptive)
|
||||
adaptive.FinishingProfile = False
|
||||
adaptive.HelixAngle = 75.0
|
||||
adaptive.HelixDiameterLimit.Value = 1.0
|
||||
adaptive.LiftDistance.Value = 1.0
|
||||
adaptive.StepOver = 75
|
||||
adaptive.UseOutline = False
|
||||
adaptive.setExpression('StepDown', None)
|
||||
adaptive.StepDown.Value = 20.0 # Have to set expression to None before numerical value assignment
|
||||
|
||||
_addViewProvider(adaptive)
|
||||
self.doc.recompute()
|
||||
|
||||
self.assertTrue(len(adaptive.Path.Commands) > 100, "Command count not greater than 100.")
|
||||
|
||||
def test06(self):
|
||||
'''test06() Verify path generated with outer and inner edge loops at same Z height: "Edge15", "Edge30", "Edge31", "Edge29", "Edge19", "Edge18", "Edge35", "Edge32", "Edge34", "Edge33".'''
|
||||
|
||||
# Instantiate a Adaptive operation and set Base Geometry
|
||||
adaptive = PathAdaptive.Create('Adaptive')
|
||||
adaptive.Base = [(self.doc.Fusion, ["Edge15", "Edge30", "Edge31", "Edge29", "Edge19", "Edge18", "Edge35", "Edge32", "Edge34", "Edge33"])] # (base, subs_list)
|
||||
adaptive.Label = "test06+"
|
||||
adaptive.Comment = 'test06() Verify path generated with outer and inner edge loops at same Z height: "Edge15", "Edge30", "Edge31", "Edge29", "Edge19", "Edge18", "Edge35", "Edge32", "Edge34", "Edge33".'
|
||||
|
||||
# Set additional operation properties
|
||||
# setDepthsAndHeights(adaptive)
|
||||
adaptive.FinishingProfile = False
|
||||
adaptive.HelixAngle = 75.0
|
||||
adaptive.HelixDiameterLimit.Value = 1.0
|
||||
adaptive.LiftDistance.Value = 1.0
|
||||
adaptive.StepOver = 75
|
||||
adaptive.UseOutline = False
|
||||
adaptive.setExpression('StepDown', None)
|
||||
adaptive.StepDown.Value = 20.0 # Have to set expression to None before numerical value assignment
|
||||
|
||||
_addViewProvider(adaptive)
|
||||
self.doc.recompute()
|
||||
|
||||
# Check command count
|
||||
self.assertTrue(len(adaptive.Path.Commands) > 100, "Command count not greater than 100.")
|
||||
|
||||
# Check if any paths originate inside inner hole of donut. They should not.
|
||||
isInBox = False
|
||||
edges = [self.doc.Fusion.Shape.getElement(e) for e in ["Edge35", "Edge32", "Edge33", "Edge34"]]
|
||||
square = Part.Wire(edges)
|
||||
sqrBB = square.BoundBox
|
||||
minPoint = FreeCAD.Vector(sqrBB.XMin, sqrBB.YMin, 0.0)
|
||||
maxPoint = FreeCAD.Vector(sqrBB.XMax, sqrBB.YMax, 0.0)
|
||||
for c in adaptive.Path.Commands:
|
||||
if pathOriginatesInBox(c, minPoint, maxPoint):
|
||||
isInBox = True
|
||||
break
|
||||
self.assertFalse(isInBox, "Paths originating within the inner hole.")
|
||||
|
||||
def test07(self):
|
||||
'''test07() Verify path generated on donut-shaped Face10.'''
|
||||
|
||||
# Instantiate a Adaptive operation and set Base Geometry
|
||||
adaptive = PathAdaptive.Create('Adaptive')
|
||||
adaptive.Base = [(self.doc.Fusion, ["Face10"])] # (base, subs_list)
|
||||
adaptive.Label = "test07+"
|
||||
adaptive.Comment = "test07() Verify path generated on donut-shaped Face10."
|
||||
|
||||
# Set additional operation properties
|
||||
# setDepthsAndHeights(adaptive)
|
||||
adaptive.FinishingProfile = False
|
||||
adaptive.HelixAngle = 75.0
|
||||
adaptive.HelixDiameterLimit.Value = 1.0
|
||||
adaptive.LiftDistance.Value = 1.0
|
||||
adaptive.StepOver = 75
|
||||
adaptive.UseOutline = False
|
||||
adaptive.setExpression('StepDown', None)
|
||||
adaptive.StepDown.Value = 20.0 # Have to set expression to None before numerical value assignment
|
||||
|
||||
_addViewProvider(adaptive)
|
||||
self.doc.recompute()
|
||||
|
||||
self.assertTrue(len(adaptive.Path.Commands) > 100, "Command count not greater than 100.")
|
||||
|
||||
# Check if any paths originate inside inner hole of donut. They should not.
|
||||
isInBox = False
|
||||
edges = [self.doc.Fusion.Shape.getElement(e) for e in ["Edge35", "Edge32", "Edge33", "Edge34"]]
|
||||
square = Part.Wire(edges)
|
||||
sqrBB = square.BoundBox
|
||||
minPoint = FreeCAD.Vector(sqrBB.XMin, sqrBB.YMin, 0.0)
|
||||
maxPoint = FreeCAD.Vector(sqrBB.XMax, sqrBB.YMax, 0.0)
|
||||
for c in adaptive.Path.Commands:
|
||||
if pathOriginatesInBox(c, minPoint, maxPoint):
|
||||
isInBox = True
|
||||
break
|
||||
self.assertFalse(isInBox, "Paths originating within the inner hole.")
|
||||
|
||||
# Set Adaptive op to only use the outline of the face.
|
||||
adaptive.UseOutline = True
|
||||
self.doc.recompute()
|
||||
|
||||
# Check if any paths originate inside inner hole of donut. They should not.
|
||||
isInBox = False
|
||||
edges = [self.doc.Fusion.Shape.getElement(e) for e in ["Edge35", "Edge32", "Edge33", "Edge34"]]
|
||||
square = Part.Wire(edges)
|
||||
sqrBB = square.BoundBox
|
||||
minPoint = FreeCAD.Vector(sqrBB.XMin, sqrBB.YMin, 0.0)
|
||||
maxPoint = FreeCAD.Vector(sqrBB.XMax, sqrBB.YMax, 0.0)
|
||||
for c in adaptive.Path.Commands:
|
||||
if pathOriginatesInBox(c, minPoint, maxPoint):
|
||||
isInBox = True
|
||||
break
|
||||
self.assertTrue(isInBox, "No paths originating within the inner hole.")
|
||||
# Eclass
|
||||
|
||||
|
||||
def setDepthsAndHeights(op, strDep=20.0, finDep=0.0):
|
||||
'''setDepthsAndHeights(op, strDep=20.0, finDep=0.0)... Sets default depths and heights for `op` passed to it'''
|
||||
|
||||
# Set start and final depth in order to eliminate effects of stock (and its default values)
|
||||
op.setExpression('StartDepth', None)
|
||||
op.StartDepth.Value = strDep
|
||||
op.setExpression('FinalDepth', None)
|
||||
op.FinalDepth.Value = finDep
|
||||
|
||||
# Set step down so as to only produce one layer path
|
||||
op.setExpression('StepDown', None)
|
||||
op.StepDown.Value = 20.0
|
||||
|
||||
# Set Heights
|
||||
# default values used
|
||||
|
||||
def getGcodeMoves(cmdList, includeRapids=True, includeLines=True, includeArcs=True):
|
||||
'''getGcodeMoves(cmdList, includeRapids=True, includeLines=True, includeArcs=True)...
|
||||
Accepts command dict and returns point string coordinate.
|
||||
'''
|
||||
gcode_list = list()
|
||||
last = FreeCAD.Vector(0.0, 0.0, 0.0)
|
||||
for c in cmdList:
|
||||
p = c.Parameters
|
||||
name = c.Name
|
||||
if includeRapids and name in ["G0", "G00"]:
|
||||
gcode = name
|
||||
x = last.x
|
||||
y = last.y
|
||||
z = last.z
|
||||
if p.get("X"):
|
||||
x = round(p["X"], 2)
|
||||
gcode += " X" + str(x)
|
||||
if p.get("Y"):
|
||||
y = round(p["Y"], 2)
|
||||
gcode += " Y" + str(y)
|
||||
if p.get("Z"):
|
||||
z = round(p["Z"], 2)
|
||||
gcode += " Z" + str(z)
|
||||
last.x = x
|
||||
last.y = y
|
||||
last.z = z
|
||||
gcode_list.append(gcode)
|
||||
elif includeLines and name in ["G1", "G01"]:
|
||||
gcode = name
|
||||
x = last.x
|
||||
y = last.y
|
||||
z = last.z
|
||||
if p.get("X"):
|
||||
x = round(p["X"], 2)
|
||||
gcode += " X" + str(x)
|
||||
if p.get("Y"):
|
||||
y = round(p["Y"], 2)
|
||||
gcode += " Y" + str(y)
|
||||
if p.get("Z"):
|
||||
z = round(p["Z"], 2)
|
||||
gcode += " Z" + str(z)
|
||||
last.x = x
|
||||
last.y = y
|
||||
last.z = z
|
||||
gcode_list.append(gcode)
|
||||
elif includeArcs and name in ["G2", "G3", "G02", "G03"]:
|
||||
gcode = name
|
||||
x = last.x
|
||||
y = last.y
|
||||
z = last.z
|
||||
i = 0.0
|
||||
j = 0.0
|
||||
k = 0.0
|
||||
if p.get("I"):
|
||||
i = round(p["I"], 2)
|
||||
gcode += " I" + str(i)
|
||||
if p.get("J"):
|
||||
j = round(p["J"], 2)
|
||||
gcode += " J" + str(j)
|
||||
if p.get("K"):
|
||||
k = round(p["K"], 2)
|
||||
gcode += " K" + str(k)
|
||||
|
||||
if p.get("X"):
|
||||
x = round(p["X"], 2)
|
||||
gcode += " X" + str(x)
|
||||
if p.get("Y"):
|
||||
y = round(p["Y"], 2)
|
||||
gcode += " Y" + str(y)
|
||||
if p.get("Z"):
|
||||
z = round(p["Z"], 2)
|
||||
gcode += " Z" + str(z)
|
||||
|
||||
gcode_list.append(gcode)
|
||||
last.x = x
|
||||
last.y = y
|
||||
last.z = z
|
||||
return gcode_list
|
||||
|
||||
|
||||
def pathOriginatesInBox(cmd, minPoint, maxPoint):
|
||||
p = cmd.Parameters
|
||||
name = cmd.Name
|
||||
if name in ["G0", "G00", "G1", "G01"]:
|
||||
if p.get("X") and p.get("Y"):
|
||||
x = p.get("X")
|
||||
y = p.get("Y")
|
||||
if x > minPoint.x and y > minPoint.y and x < maxPoint.x and y < maxPoint.y:
|
||||
return True
|
||||
return False
|
||||
|
||||
|
||||
|
||||
def _addViewProvider(adaptiveOp):
|
||||
if FreeCAD.GuiUp:
|
||||
PathOpGui = PathAdaptiveGui.PathOpGui
|
||||
cmdRes = PathAdaptiveGui.Command.res
|
||||
adaptiveOp.ViewObject.Proxy = PathOpGui.ViewProvider(adaptiveOp.ViewObject, cmdRes)
|
||||
|
||||
|
||||
# Expected moves for unit tests
|
||||
expected_moves_test01 = "G1 X32.5 Y32.5 Z5.0; \
|
||||
G1 X17.5 Y32.5 Z5.0; \
|
||||
G1 X17.5 Y30.0 Z5.0; \
|
||||
G1 X32.5 Y30.0 Z5.0; \
|
||||
G1 X32.5 Y27.5 Z5.0; \
|
||||
G1 X17.5 Y27.5 Z5.0; \
|
||||
G1 X17.5 Y25.0 Z5.0; \
|
||||
G1 X32.5 Y25.0 Z5.0; \
|
||||
G1 X32.5 Y22.5 Z5.0; \
|
||||
G1 X17.5 Y22.5 Z5.0; \
|
||||
G1 X17.5 Y20.0 Z5.0; \
|
||||
G1 X32.5 Y20.0 Z5.0; \
|
||||
G1 X32.5 Y17.5 Z5.0; \
|
||||
G1 X17.5 Y17.5 Z5.0"
|
||||
|
||||
expected_moves_test02 = "G1 X22.5 Y-17.5 Z15.0; \
|
||||
G1 X22.5 Y-22.5 Z15.0; \
|
||||
G1 X17.5 Y-22.5 Z15.0; \
|
||||
G1 X17.5 Y-17.5 Z15.0; \
|
||||
G1 X22.5 Y-17.5 Z15.0; \
|
||||
G1 X21.25 Y-18.75 Z15.0; \
|
||||
G1 X21.25 Y-21.25 Z15.0; \
|
||||
G1 X18.75 Y-21.25 Z15.0; \
|
||||
G1 X18.75 Y-18.75 Z15.0; \
|
||||
G1 X21.25 Y-18.75 Z15.0"
|
||||
|
||||
expected_moves_test03 = "G1 X32.5 Y-22.5 Z5.0; \
|
||||
G1 X32.5 Y-22.76 Z5.0; \
|
||||
G3 I2.4 J-12.0 K0.0 X27.5 Y-25.01 Z5.0; \
|
||||
G1 X27.5 Y-25.0 Z5.0; \
|
||||
G1 X27.5 Y-22.5 Z5.0; \
|
||||
G1 X32.5 Y-22.5 Z5.0; \
|
||||
G1 X25.02 Y-27.5 Z5.0; \
|
||||
G3 I9.66 J-7.36 K0.0 X22.76 Y-32.5 Z5.0; \
|
||||
G1 X22.5 Y-32.5 Z5.0; \
|
||||
G1 X22.5 Y-27.5 Z5.0; \
|
||||
G1 X25.0 Y-27.5 Z5.0; \
|
||||
G1 X25.02 Y-27.5 Z5.0"
|
||||
|
||||
expected_moves_test04 = "G1 X25.0 Y-15.0 Z15.0; \
|
||||
G1 X15.0 Y-15.0 Z15.0; \
|
||||
G1 X15.0 Y-25.0 Z15.0; \
|
||||
G1 X25.0 Y-25.0 Z15.0; \
|
||||
G1 X25.0 Y-22.5 Z15.0; \
|
||||
G1 X22.5 Y-22.5 Z15.0; \
|
||||
G1 X22.5 Y-17.5 Z15.0; \
|
||||
G1 X17.5 Y-17.5 Z15.0; \
|
||||
G1 X17.5 Y-22.5 Z15.0; \
|
||||
G1 X22.5 Y-22.5 Z15.0; \
|
||||
G1 X25.0 Y-22.5 Z15.0; \
|
||||
G1 X25.0 Y-15.0 Z15.0"
|
||||
|
||||
expected_moves_test05 = "G1 X32.5 Y32.5 Z5.0; \
|
||||
G1 X32.5 Y17.5 Z5.0; \
|
||||
G1 X17.5 Y17.5 Z5.0; \
|
||||
G1 X17.5 Y32.5 Z5.0; \
|
||||
G1 X32.5 Y32.5 Z5.0; \
|
||||
G1 X30.0 Y30.0 Z5.0; \
|
||||
G1 X30.0 Y20.0 Z5.0; \
|
||||
G1 X20.0 Y20.0 Z5.0; \
|
||||
G1 X20.0 Y30.0 Z5.0; \
|
||||
G1 X30.0 Y30.0 Z5.0; \
|
||||
G1 X27.5 Y27.5 Z5.0; \
|
||||
G1 X27.5 Y22.5 Z5.0; \
|
||||
G1 X22.5 Y22.5 Z5.0; \
|
||||
G1 X22.5 Y27.5 Z5.0; \
|
||||
G1 X27.5 Y27.5 Z5.0; \
|
||||
G1 X26.25 Y26.25 Z5.0; \
|
||||
G1 X26.25 Y23.75 Z5.0; \
|
||||
G1 X23.75 Y23.75 Z5.0; \
|
||||
G1 X23.75 Y26.25 Z5.0; \
|
||||
G1 X26.25 Y26.25 Z5.0"
|
||||
BIN
src/Mod/Path/PathTests/test_adaptive.fcstd
Normal file
BIN
src/Mod/Path/PathTests/test_adaptive.fcstd
Normal file
Binary file not shown.
@@ -22,50 +22,57 @@
|
||||
|
||||
import TestApp
|
||||
|
||||
from PathTests.TestPathLog import TestPathLog
|
||||
from PathTests.TestPathPreferences import TestPathPreferences
|
||||
from PathTests.TestPathPropertyBag import TestPathPropertyBag
|
||||
from PathTests.TestPathCore import TestPathCore
|
||||
#from PathTests.TestPathPost import PathPostTestCases
|
||||
from PathTests.TestPathGeom import TestPathGeom
|
||||
from PathTests.TestPathOpTools import TestPathOpTools
|
||||
from PathTests.TestPathUtil import TestPathUtil
|
||||
# from PathTests.TestPathPost import PathPostTestCases
|
||||
from PathTests.TestPathAdaptive import TestPathAdaptive
|
||||
"""
|
||||
from PathTests.TestPathCore import TestPathCore
|
||||
from PathTests.TestPathDeburr import TestPathDeburr
|
||||
from PathTests.TestPathDepthParams import depthTestCases
|
||||
from PathTests.TestPathDressupHoldingTags import TestHoldingTags
|
||||
from PathTests.TestPathDressupDogbone import TestDressupDogbone
|
||||
from PathTests.TestPathStock import TestPathStock
|
||||
from PathTests.TestPathTool import TestPathTool
|
||||
from PathTests.TestPathToolBit import TestPathToolBit
|
||||
from PathTests.TestPathTooltable import TestPathTooltable
|
||||
from PathTests.TestPathToolController import TestPathToolController
|
||||
from PathTests.TestPathDressupHoldingTags import TestHoldingTags
|
||||
from PathTests.TestPathGeom import TestPathGeom
|
||||
from PathTests.TestPathHelix import TestPathHelix
|
||||
from PathTests.TestPathLog import TestPathLog
|
||||
from PathTests.TestPathOpTools import TestPathOpTools
|
||||
from PathTests.TestPathPreferences import TestPathPreferences
|
||||
from PathTests.TestPathPropertyBag import TestPathPropertyBag
|
||||
from PathTests.TestPathSetupSheet import TestPathSetupSheet
|
||||
from PathTests.TestPathDeburr import TestPathDeburr
|
||||
from PathTests.TestPathHelix import TestPathHelix
|
||||
from PathTests.TestPathVoronoi import TestPathVoronoi
|
||||
from PathTests.TestPathThreadMilling import TestPathThreadMilling
|
||||
from PathTests.TestPathVcarve import TestPathVcarve
|
||||
from PathTests.TestPathStock import TestPathStock
|
||||
from PathTests.TestPathThreadMilling import TestPathThreadMilling
|
||||
from PathTests.TestPathTool import TestPathTool
|
||||
from PathTests.TestPathToolBit import TestPathToolBit
|
||||
from PathTests.TestPathToolController import TestPathToolController
|
||||
from PathTests.TestPathTooltable import TestPathTooltable
|
||||
from PathTests.TestPathUtil import TestPathUtil
|
||||
from PathTests.TestPathVcarve import TestPathVcarve
|
||||
from PathTests.TestPathVoronoi import TestPathVoronoi
|
||||
"""
|
||||
|
||||
# dummy usage to get flake8 and lgtm quiet
|
||||
False if TestApp.__name__ else True
|
||||
False if TestPathLog.__name__ else True
|
||||
False if TestPathCore.__name__ else True
|
||||
False if TestPathGeom.__name__ else True
|
||||
False if TestPathOpTools.__name__ else True
|
||||
False if TestPathUtil.__name__ else True
|
||||
"""
|
||||
False if depthTestCases.__name__ else True
|
||||
False if TestHoldingTags.__name__ else True
|
||||
False if TestApp.__name__ else True
|
||||
False if TestDressupDogbone.__name__ else True
|
||||
False if TestPathStock.__name__ else True
|
||||
False if TestPathTool.__name__ else True
|
||||
False if TestPathTooltable.__name__ else True
|
||||
False if TestPathToolController.__name__ else True
|
||||
False if TestPathSetupSheet.__name__ else True
|
||||
False if TestHoldingTags.__name__ else True
|
||||
"""
|
||||
False if TestPathAdaptive.__name__ else True
|
||||
"""
|
||||
False if TestPathCore.__name__ else True
|
||||
False if TestPathDeburr.__name__ else True
|
||||
False if TestPathGeom.__name__ else True
|
||||
False if TestPathHelix.__name__ else True
|
||||
False if TestPathLog.__name__ else True
|
||||
False if TestPathOpTools.__name__ else True
|
||||
False if TestPathPreferences.__name__ else True
|
||||
False if TestPathToolBit.__name__ else True
|
||||
False if TestPathVoronoi.__name__ else True
|
||||
False if TestPathThreadMilling.__name__ else True
|
||||
False if TestPathVcarve.__name__ else True
|
||||
False if TestPathPropertyBag.__name__ else True
|
||||
|
||||
False if TestPathSetupSheet.__name__ else True
|
||||
False if TestPathStock.__name__ else True
|
||||
False if TestPathThreadMilling.__name__ else True
|
||||
False if TestPathTool.__name__ else True
|
||||
False if TestPathToolBit.__name__ else True
|
||||
False if TestPathToolController.__name__ else True
|
||||
False if TestPathTooltable.__name__ else True
|
||||
False if TestPathUtil.__name__ else True
|
||||
False if TestPathVcarve.__name__ else True
|
||||
False if TestPathVoronoi.__name__ else True
|
||||
"""
|
||||
|
||||
Reference in New Issue
Block a user