Download src/Mod/CAM/CAMTests/TestPathDressupDogboneII.py from AbdulElahGwaith/FreeCAD: direct link, hf CLI and curl.
- Browser
- Download file 26.3 kB
-
https://huggingface.co/AbdulElahGwaith/FreeCAD/resolve/main/src/Mod/CAM/CAMTests/TestPathDressupDogboneII.py
- Command line
-
hf download hf://AbdulElahGwaith/FreeCAD/src/Mod/CAM/CAMTests/TestPathDressupDogboneII.py
-
curl -L -o TestPathDressupDogboneII.py https://huggingface.co/AbdulElahGwaith/FreeCAD/resolve/main/src/Mod/CAM/CAMTests/TestPathDressupDogboneII.py
26.3 kB
| # SPDX-License-Identifier: LGPL-2.1-or-later | |
| # *************************************************************************** | |
| # * Copyright (c) 2022 sliptonic <shopinthewoods@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 Path | |
| import Path.Base.Generator.dogboneII as dogboneII | |
| import Path.Base.Language as PathLanguage | |
| import Path.Dressup.DogboneII | |
| import CAMTests.PathTestUtils as PathTestUtils | |
| import math | |
| PI = math.pi | |
| class MockTB(object): | |
| def __init__(self, dia): | |
| self.Name = "ToolBit" | |
| self.Label = "ToolBit" | |
| self.Diameter = FreeCAD.Units.Quantity(dia, FreeCAD.Units.Length) | |
| class MockTC(object): | |
| def __init__(self, dia=2): | |
| self.Name = "TC" | |
| self.Label = "TC" | |
| self.Tool = MockTB(dia) | |
| class MockOp(object): | |
| def __init__(self, path, dia=2): | |
| self.Name = "OP" | |
| self.Label = "OP" | |
| self.Path = Path.Path(path) | |
| self.ToolController = MockTC(dia) | |
| class MockFeaturePython(object): | |
| def __init__(self, name): | |
| self.prop = {} | |
| self.addProperty("App::PropertyString", "Name", val=name) | |
| self.addProperty("App::PropertyString", "Label", val=name) | |
| self.addProperty("App::PropertyLink", "Proxy") | |
| self.addProperty("Path::Path", "Path", val=Path.Path()) | |
| def addProperty(self, typ, name, grp=None, desc=None, val=None): | |
| self.prop[name] = (typ, val) | |
| def setEditorMode(self, name, mode): | |
| pass | |
| def __setattr__(self, name, val): | |
| if name == "prop": | |
| return super().__setattr__(name, val) | |
| self.prop[name] = (self.prop[name][0], val) | |
| def __getattr__(self, name): | |
| if name == "prop": | |
| return super().__getattr__(name) | |
| typ, val = self.prop.get(name, (None, None)) | |
| if typ is None and val is None: | |
| raise AttributeError | |
| if typ == "App::PropertyLength": | |
| if type(val) == float or type(val) == int: | |
| return FreeCAD.Units.Quantity(val, FreeCAD.Units.Length) | |
| return FreeCAD.Units.Quantity(val) | |
| return val | |
| def CreateDressup(path): | |
| op = MockOp(path) | |
| obj = MockFeaturePython("DressupDogbone") | |
| db = Path.Dressup.DogboneII.Proxy(obj, op) | |
| obj.Proxy = db | |
| return obj | |
| def MNVR(gcode, begin=None): | |
| # 'turns out the replace() isn't really necessary | |
| # leave it here anyway for clarity | |
| return PathLanguage.Maneuver.FromGCode(gcode.replace("/", "\n"), begin) | |
| def INSTR(gcode, begin=None): | |
| return MNVR(gcode, begin).instr[0] | |
| def KINK(gcode, begin=None): | |
| maneuver = MNVR(gcode, begin) | |
| if len(maneuver.instr) != 2: | |
| return None | |
| return dogboneII.Kink(maneuver.instr[0], maneuver.instr[1]) | |
| class TestDressupDogboneII(PathTestUtils.PathTestBase): | |
| """Unit tests for the DogboneII dressup.""" | |
| def assertEqualPath(self, path, s): | |
| def cmd2str(cmd): | |
| param = [ | |
| f"{k}{v:g}" if Path.Geom.isRoughly(0, v - int(v)) else f"{k}{v:.2f}" | |
| for k, v in cmd.Parameters.items() | |
| ] | |
| return f"{cmd.Name}{''.join(param)}" | |
| p = "/".join([cmd2str(cmd) for cmd in path.Commands]) | |
| self.assertEqual(p, s) | |
| def test00(self): | |
| """Verify adaptive length""" | |
| def adaptive(k, a, n): | |
| return Path.Dressup.DogboneII.calc_length_adaptive(k, a, n, n) | |
| if True: | |
| # horizontal bones | |
| self.assertRoughly(adaptive(KINK("G1X1/G1X2"), 0, 1), 0) | |
| self.assertRoughly(adaptive(KINK("G1X1/G1Y1"), 0, 1), 1) | |
| self.assertRoughly(adaptive(KINK("G1X1/G1X2Y1"), 0, 1), 0.414214) | |
| self.assertRoughly(adaptive(KINK("G1X1/G1X0Y1"), 0, 1), 2.414211) | |
| self.assertRoughly(adaptive(KINK("G1X1/G1X0"), 0, 1), 1) | |
| self.assertRoughly(adaptive(KINK("G1X1/G1X0Y-1"), 0, 1), 2.414211) | |
| self.assertRoughly(adaptive(KINK("G1X1/G1X1Y-1"), 0, 1), 1) | |
| self.assertRoughly(adaptive(KINK("G1X1/G1X2Y-1"), 0, 1), 0.414214) | |
| self.assertRoughly(adaptive(KINK("G1X1Y1/G1X0Y2"), 0, 1), 0.414214) | |
| if True: | |
| # more horizontal and some vertical bones | |
| self.assertRoughly(adaptive(KINK("G1Y1/G1Y2"), 0, 1), 0) | |
| self.assertRoughly(adaptive(KINK("G1Y1/G1Y1X1"), PI, 1), 1) | |
| self.assertRoughly(adaptive(KINK("G1Y1/G1Y2X1"), PI, 1), 0.089820) | |
| self.assertRoughly(adaptive(KINK("G1Y1/G1Y2X1"), PI / 2, 1), 0.414214) | |
| self.assertRoughly(adaptive(KINK("G1Y1/G1Y0X1"), PI / 2, 1), 2.414211) | |
| self.assertRoughly(adaptive(KINK("G1Y1/G1Y0"), 0, 1), 1) | |
| self.assertRoughly(adaptive(KINK("G1Y1/G1Y0X-1"), PI / 2, 1), 2.414211) | |
| self.assertRoughly(adaptive(KINK("G1Y1/G1Y1X-1"), 0, 1), 1) | |
| self.assertRoughly(adaptive(KINK("G1Y1/G1Y2X-1"), 0, 1), 0.089820) | |
| self.assertRoughly(adaptive(KINK("G1Y1/G1Y2X-1"), PI / 2, 1), 0.414214) | |
| if True: | |
| # dogbones | |
| self.assertRoughly(adaptive(KINK("G1X1/G1Y1"), -PI / 4, 1), 0.414214) | |
| self.assertRoughly(adaptive(KINK("G1X1/G1X0Y1"), -PI / 8, 1), 1.613126) | |
| self.assertRoughly(adaptive(KINK("G1X1/G1Y-1"), PI / 4, 1), 0.414214) | |
| self.assertRoughly(adaptive(KINK("G1X1/G1X0Y-1"), PI / 8, 1), 1.613126) | |
| self.assertRoughly(adaptive(KINK("G1Y1/G1X-1"), PI / 4, 1), 0.414214) | |
| self.assertRoughly(adaptive(KINK("G1Y1/G1X1"), 3 * PI / 4, 1), 0.414214) | |
| self.assertRoughly(adaptive(KINK("G1Y-1/G1X1"), -3 * PI / 4, 1), 0.414214) | |
| self.assertRoughly(adaptive(KINK("G1Y-1/G1X-1"), -PI / 4, 1), 0.414214) | |
| self.assertRoughly(adaptive(KINK("G1X1Y1/G1X0Y2"), 0, 1), 0.414214) | |
| self.assertRoughly(adaptive(KINK("G1X-1Y1/G1X0Y2"), PI, 1), 0.414214) | |
| self.assertRoughly(adaptive(KINK("G1X1Y1/G1X2Y0"), PI / 2, 2), 0.828428) | |
| self.assertRoughly(adaptive(KINK("G1X-1Y-1/G1X-2Y0"), -PI / 2, 2), 0.828428) | |
| self.assertRoughly(adaptive(KINK("G1X-1Y1/G1X-2Y0"), PI / 2, 2), 0.828428) | |
| self.assertRoughly(adaptive(KINK("G1X1Y-1/G1X2Y0"), -PI / 2, 2), 0.828428) | |
| def test01(self): | |
| """Verify nominal length""" | |
| def nominal(k, a, n): | |
| return Path.Dressup.DogboneII.calc_length_nominal(k, a, n, 0) | |
| # neither angle nor kink matter | |
| self.assertRoughly(nominal(KINK("G1X1/G1X2"), 0, 13), 13) | |
| self.assertRoughly(nominal(KINK("G1X1/G1X2"), PI / 2, 13), 13) | |
| self.assertRoughly(nominal(KINK("G1X1/G1X2"), PI, 13), 13) | |
| self.assertRoughly(nominal(KINK("G1X1/G1X2"), -PI / 2, 13), 13) | |
| self.assertRoughly(nominal(KINK("G1X8/G1X12"), 0, 13), 13) | |
| self.assertRoughly(nominal(KINK("G1X9/G1X0"), 0, 13), 13) | |
| self.assertRoughly(nominal(KINK("G1X7/G1X9"), 0, 13), 13) | |
| self.assertRoughly(nominal(KINK("G1X5/G1X1"), 0, 13), 13) | |
| def test02(self): | |
| """Verify custom length""" | |
| def custom(k, a, c): | |
| return Path.Dressup.DogboneII.calc_length_custom(k, a, 0, c) | |
| # neither angle nor kink matter | |
| self.assertRoughly(custom(KINK("G1X1/G1X2"), 0, 7), 7) | |
| self.assertRoughly(custom(KINK("G1X1/G1X2"), PI / 2, 7), 7) | |
| self.assertRoughly(custom(KINK("G1X1/G1X2"), PI, 7), 7) | |
| self.assertRoughly(custom(KINK("G1X1/G1X2"), -PI / 2, 7), 7) | |
| self.assertRoughly(custom(KINK("G1X8/G1X12"), 0, 7), 7) | |
| self.assertRoughly(custom(KINK("G1X9/G1X0"), 0, 7), 7) | |
| self.assertRoughly(custom(KINK("G1X7/G1X9"), 0, 7), 7) | |
| self.assertRoughly(custom(KINK("G1X5/G1X1"), 0, 7), 7) | |
| def test10(self): | |
| """Verify basic op dressup""" | |
| obj = CreateDressup("G1X10/G1Y20") | |
| obj.Incision = Path.Dressup.DogboneII.Incision.Fixed | |
| obj.Style = Path.Dressup.DogboneII.Style.Tbone_H | |
| # bones on right side | |
| obj.Side = Path.Dressup.DogboneII.Side.Right | |
| obj.Proxy.execute(obj) | |
| self.assertEqualPath(obj.Path, "G1X10/G1X11/G1X10/G1Y20") | |
| # no bones on left side | |
| obj.Side = Path.Dressup.DogboneII.Side.Left | |
| obj.Proxy.execute(obj) | |
| self.assertEqualPath(obj.Path, "G1X10/G1Y20") | |
| def test11(self): | |
| """Verify retaining non-move instructions""" | |
| obj = CreateDressup("G1X10/(some comment)/G1Y20") | |
| obj.Incision = Path.Dressup.DogboneII.Incision.Fixed | |
| obj.Style = Path.Dressup.DogboneII.Style.Tbone_H | |
| # bone on right side | |
| obj.Side = Path.Dressup.DogboneII.Side.Right | |
| obj.Proxy.execute(obj) | |
| self.assertEqualPath(obj.Path, "G1X10/(some comment)/G1X11/G1X10/G1Y20") | |
| # no bone on left side | |
| obj.Side = Path.Dressup.DogboneII.Side.Left | |
| obj.Proxy.execute(obj) | |
| self.assertEqualPath(obj.Path, "G1X10/(some comment)/G1Y20") | |
| def test20(self): | |
| """Verify bone on plunge moves""" | |
| obj = CreateDressup("G0Z10/G1Z0/G1X10/G1Y10/G1X0/G1Y0/G0Z10") | |
| obj.Incision = Path.Dressup.DogboneII.Incision.Fixed | |
| obj.Style = Path.Dressup.DogboneII.Style.Tbone_H | |
| obj.Side = Path.Dressup.DogboneII.Side.Right | |
| obj.Proxy.execute(obj) | |
| self.assertEqualPath( | |
| obj.Path, | |
| "G0Z10/G1Z0/G1X10/G1X11/G1X10/G1Y10/G1X11/G1X10/G1X0/G1X-1/G1X0/G1Y0/G1X-1/G1X0/G0Z10", | |
| ) | |
| def test21(self): | |
| """Verify ignoring plunge moves that don't connect""" | |
| obj = CreateDressup("G0Z10/G1Z0/G1X10/G1Y10/G1X0/G1Y5/G0Z10") | |
| obj.Incision = Path.Dressup.DogboneII.Incision.Fixed | |
| obj.Style = Path.Dressup.DogboneII.Style.Tbone_H | |
| obj.Side = Path.Dressup.DogboneII.Side.Right | |
| obj.Proxy.execute(obj) | |
| self.assertEqualPath( | |
| obj.Path, | |
| "G0Z10/G1Z0/G1X10/G1X11/G1X10/G1Y10/G1X11/G1X10/G1X0/G1X-1/G1X0/G1Y5/G0Z10", | |
| ) | |
| def test30(self): | |
| """Verify TBone_V style""" | |
| def check_tbone(d, i, path, out, right): | |
| obj = CreateDressup(f"({d}.{i:02})/{path}") | |
| obj.Incision = Path.Dressup.DogboneII.Incision.Fixed | |
| if right: | |
| obj.Side = Path.Dressup.DogboneII.Side.Right | |
| else: | |
| obj.Side = Path.Dressup.DogboneII.Side.Left | |
| obj.Style = Path.Dressup.DogboneII.Style.Tbone_V | |
| obj.Proxy.execute(obj) | |
| self.assertEqualPath(obj.Path, f"({d}.{i:02})/{out}") | |
| # test data with a horizontal lead in | |
| test_data_h = [ | |
| # top right quadrant | |
| ("G1X10Y0/G1X10Y10", "G1X10Y0/G1Y-1/G1Y0/G1X10Y10", True), | |
| ("G1X10Y0/G1X20Y10", "G1X10Y0/G1Y-1/G1Y0/G1X20Y10", True), | |
| ("G1X10Y0/G1X90Y10", "G1X10Y0/G1Y-1/G1Y0/G1X90Y10", True), | |
| ("G1X10Y0/G1X0Y10", "G1X10Y0/G1Y-1/G1Y0/G1X0Y10", True), | |
| # bottom right quadrant | |
| ("G1X10Y0/G1X90Y-10", "G1X10Y0/G1Y1/G1Y0/G1X90Y-10", False), | |
| ("G1X10Y0/G1X20Y-10", "G1X10Y0/G1Y1/G1Y0/G1X20Y-10", False), | |
| ("G1X10Y0/G1X10Y-10", "G1X10Y0/G1Y1/G1Y0/G1X10Y-10", False), | |
| ("G1X10Y0/G1X0Y-10", "G1X10Y0/G1Y1/G1Y0/G1X0Y-10", False), | |
| # top left quadrant | |
| ("G1X-10Y0/G1X-10Y10", "G1X-10Y0/G1Y-1/G1Y0/G1X-10Y10", False), | |
| ("G1X-10Y0/G1X-20Y10", "G1X-10Y0/G1Y-1/G1Y0/G1X-20Y10", False), | |
| ("G1X-10Y0/G1X-90Y10", "G1X-10Y0/G1Y-1/G1Y0/G1X-90Y10", False), | |
| ("G1X-10Y0/G1X-0Y10", "G1X-10Y0/G1Y-1/G1Y0/G1X-0Y10", False), | |
| # bottom left quadrant | |
| ("G1X-10Y0/G1X-90Y-10", "G1X-10Y0/G1Y1/G1Y0/G1X-90Y-10", True), | |
| ("G1X-10Y0/G1X-20Y-10", "G1X-10Y0/G1Y1/G1Y0/G1X-20Y-10", True), | |
| ("G1X-10Y0/G1X-10Y-10", "G1X-10Y0/G1Y1/G1Y0/G1X-10Y-10", True), | |
| ("G1X-10Y0/G1X-0Y-10", "G1X-10Y0/G1Y1/G1Y0/G1X-0Y-10", True), | |
| ] | |
| for i, (path, out, right) in enumerate(test_data_h): | |
| check_tbone("h", i, path, out, right) | |
| # test data with a vertical lead in | |
| test_data_v = [ | |
| # top right quadrant | |
| ("G1X0Y10/G1X10Y10", "G1X0Y10/G1Y11/G1Y10/G1X10Y10", False), | |
| ("G1X0Y10/G1X10Y20", "G1X0Y10/G1Y11/G1Y10/G1X10Y20", False), | |
| ("G1X0Y10/G1X10Y90", "G1X0Y10/G1Y11/G1Y10/G1X10Y90", False), | |
| ("G1X0Y10/G1X10Y0", "G1X0Y10/G1Y11/G1Y10/G1X10Y0", False), | |
| # bottom right quadrant | |
| ("G1X0Y-10/G1X10Y-90", "G1X0Y-10/G1Y-11/G1Y-10/G1X10Y-90", True), | |
| ("G1X0Y-10/G1X10Y-20", "G1X0Y-10/G1Y-11/G1Y-10/G1X10Y-20", True), | |
| ("G1X0Y-10/G1X10Y-10", "G1X0Y-10/G1Y-11/G1Y-10/G1X10Y-10", True), | |
| ("G1X0Y-10/G1X10Y-0", "G1X0Y-10/G1Y-11/G1Y-10/G1X10Y-0", True), | |
| # top left quadrant | |
| ("G1X0Y10/G1X-10Y10", "G1X0Y10/G1Y11/G1Y10/G1X-10Y10", True), | |
| ("G1X0Y10/G1X-10Y20", "G1X0Y10/G1Y11/G1Y10/G1X-10Y20", True), | |
| ("G1X0Y10/G1X-10Y90", "G1X0Y10/G1Y11/G1Y10/G1X-10Y90", True), | |
| ("G1X0Y10/G1X-10Y0", "G1X0Y10/G1Y11/G1Y10/G1X-10Y0", True), | |
| # bottom left quadrant | |
| ("G1X0Y-10/G1X-10Y-90", "G1X0Y-10/G1Y-11/G1Y-10/G1X-10Y-90", False), | |
| ("G1X0Y-10/G1X-10Y-20", "G1X0Y-10/G1Y-11/G1Y-10/G1X-10Y-20", False), | |
| ("G1X0Y-10/G1X-10Y-10", "G1X0Y-10/G1Y-11/G1Y-10/G1X-10Y-10", False), | |
| ("G1X0Y-10/G1X-10Y-0", "G1X0Y-10/G1Y-11/G1Y-10/G1X-10Y-0", False), | |
| ] | |
| for i, (path, out, right) in enumerate(test_data_v): | |
| check_tbone("v", i, path, out, right) | |
| def test40(self): | |
| """Verify TBone_S style""" | |
| def check_tbone_s(d, i, path, out, right): | |
| obj = CreateDressup(f"(m{d}.{i:02})/{path}") | |
| obj.Incision = Path.Dressup.DogboneII.Incision.Fixed | |
| if right: | |
| obj.Side = Path.Dressup.DogboneII.Side.Right | |
| else: | |
| obj.Side = Path.Dressup.DogboneII.Side.Left | |
| obj.Style = Path.Dressup.DogboneII.Style.Tbone_S | |
| obj.Proxy.execute(obj) | |
| self.assertEqualPath(obj.Path, f"(m{d}.{i:02})/{out}") | |
| # short edge m0 | |
| test_data_0 = [ | |
| # CCW | |
| ("G1X10/G1Y20", "G1X10/G1Y-1/G1Y0/G1Y20", True), | |
| ("G1X10Y10/G1X-10Y30", "G1X10Y10/G1X10.71Y9.29/G1X10Y10/G1X-10Y30", True), | |
| ("G1Y10/G1X-20", "G1Y10/G1X1/G1X0/G1X-20", True), | |
| ( | |
| "G1X-10Y10/G1X-30Y-10", | |
| "G1X-10Y10/G1X-9.29Y10.71/G1X-10Y10/G1X-30Y-10", | |
| True, | |
| ), | |
| ("G1X-10/G1Y-20", "G1X-10/G1Y1/G1Y0/G1Y-20", True), | |
| ( | |
| "G1X-10Y-10/G1X10Y-30", | |
| "G1X-10Y-10/G1X-10.71Y-9.29/G1X-10Y-10/G1X10Y-30", | |
| True, | |
| ), | |
| ("G1Y-10/G1X20", "G1Y-10/G1X-1/G1X0/G1X20", True), | |
| ("G1X10Y-10/G1X30Y10", "G1X10Y-10/G1X9.29Y-10.71/G1X10Y-10/G1X30Y10", True), | |
| # CW | |
| ("G1X10/G1Y-20", "G1X10/G1Y1/G1Y0/G1Y-20", False), | |
| ("G1X10Y10/G1X30Y-10", "G1X10Y10/G1X9.29Y10.71/G1X10Y10/G1X30Y-10", False), | |
| ("G1Y10/G1X20", "G1Y10/G1X-1/G1X0/G1X20", False), | |
| ( | |
| "G1X-10Y10/G1X10Y30", | |
| "G1X-10Y10/G1X-10.71Y9.29/G1X-10Y10/G1X10Y30", | |
| False, | |
| ), | |
| ("G1X-10/G1Y20", "G1X-10/G1Y-1/G1Y0/G1Y20", False), | |
| ( | |
| "G1X-10Y-10/G1X-30Y10", | |
| "G1X-10Y-10/G1X-9.29Y-10.71/G1X-10Y-10/G1X-30Y10", | |
| False, | |
| ), | |
| ("G1Y-10/G1X-20", "G1Y-10/G1X1/G1X0/G1X-20", False), | |
| ( | |
| "G1X10Y-10/G1X-10Y-30", | |
| "G1X10Y-10/G1X10.71Y-9.29/G1X10Y-10/G1X-10Y-30", | |
| False, | |
| ), | |
| ] | |
| for i, (path, out, right) in enumerate(test_data_0): | |
| check_tbone_s("0", i, path, out, right) | |
| # short edge m1 | |
| test_data_1 = [ | |
| # CCW | |
| ("G1X20/G1Y10", "G1X20/G1X21/G1X20/G1Y10", True), | |
| ("G1X20Y20/G1X10Y30", "G1X20Y20/G1X20.71Y20.71/G1X20Y20/G1X10Y30", True), | |
| ("G1Y20/G1X-10", "G1Y20/G1Y21/G1Y20/G1X-10", True), | |
| ( | |
| "G1X-20Y20/G1X-30Y10", | |
| "G1X-20Y20/G1X-20.71Y20.71/G1X-20Y20/G1X-30Y10", | |
| True, | |
| ), | |
| ("G1X-20/G1Y-10", "G1X-20/G1X-21/G1X-20/G1Y-10", True), | |
| ( | |
| "G1X-20Y-20/G1X-10Y-30", | |
| "G1X-20Y-20/G1X-20.71Y-20.71/G1X-20Y-20/G1X-10Y-30", | |
| True, | |
| ), | |
| ("G1Y-20/G1X10", "G1Y-20/G1Y-21/G1Y-20/G1X10", True), | |
| ( | |
| "G1X20Y-20/G1X30Y-10", | |
| "G1X20Y-20/G1X20.71Y-20.71/G1X20Y-20/G1X30Y-10", | |
| True, | |
| ), | |
| # CW | |
| ("G1X20/G1Y-10", "G1X20/G1X21/G1X20/G1Y-10", False), | |
| ("G1X20Y20/G1X30Y10", "G1X20Y20/G1X20.71Y20.71/G1X20Y20/G1X30Y10", False), | |
| ("G1Y20/G1X10", "G1Y20/G1Y21/G1Y20/G1X10", False), | |
| ( | |
| "G1X-20Y20/G1X-10Y30", | |
| "G1X-20Y20/G1X-20.71Y20.71/G1X-20Y20/G1X-10Y30", | |
| False, | |
| ), | |
| ("G1X-20/G1Y10", "G1X-20/G1X-21/G1X-20/G1Y10", False), | |
| ( | |
| "G1X-20Y-20/G1X-30Y-10", | |
| "G1X-20Y-20/G1X-20.71Y-20.71/G1X-20Y-20/G1X-30Y-10", | |
| False, | |
| ), | |
| ("G1Y-20/G1X-10", "G1Y-20/G1Y-21/G1Y-20/G1X-10", False), | |
| ( | |
| "G1X20Y-20/G1X10Y-30", | |
| "G1X20Y-20/G1X20.71Y-20.71/G1X20Y-20/G1X10Y-30", | |
| False, | |
| ), | |
| ] | |
| for i, (path, out, right) in enumerate(test_data_1): | |
| check_tbone_s("1", i, path, out, right) | |
| def test50(self): | |
| """Verify TBone_L style""" | |
| def check_tbone_l(d, i, path, out, right): | |
| obj = CreateDressup(f"(m{d}.{i:02})/{path}") | |
| obj.Incision = Path.Dressup.DogboneII.Incision.Fixed | |
| if right: | |
| obj.Side = Path.Dressup.DogboneII.Side.Right | |
| else: | |
| obj.Side = Path.Dressup.DogboneII.Side.Left | |
| obj.Style = Path.Dressup.DogboneII.Style.Tbone_L | |
| obj.Proxy.execute(obj) | |
| self.assertEqualPath(obj.Path, f"(m{d}.{i:02})/{out}") | |
| # long edge m1 | |
| test_data_1 = [ | |
| # CCW | |
| ("G1X10/G1Y20", "G1X10/G1X11/G1X10/G1Y20", True), | |
| ("G1X10Y10/G1X-10Y30", "G1X10Y10/G1X10.71Y10.71/G1X10Y10/G1X-10Y30", True), | |
| ("G1Y10/G1X-20", "G1Y10/G1Y11/G1Y10/G1X-20", True), | |
| ( | |
| "G1X-10Y10/G1X-30Y-10", | |
| "G1X-10Y10/G1X-10.71Y10.71/G1X-10Y10/G1X-30Y-10", | |
| True, | |
| ), | |
| ("G1X-10/G1Y-20", "G1X-10/G1X-11/G1X-10/G1Y-20", True), | |
| ( | |
| "G1X-10Y-10/G1X10Y-30", | |
| "G1X-10Y-10/G1X-10.71Y-10.71/G1X-10Y-10/G1X10Y-30", | |
| True, | |
| ), | |
| ("G1Y-10/G1X20", "G1Y-10/G1Y-11/G1Y-10/G1X20", True), | |
| ( | |
| "G1X10Y-10/G1X30Y10", | |
| "G1X10Y-10/G1X10.71Y-10.71/G1X10Y-10/G1X30Y10", | |
| True, | |
| ), | |
| # CW | |
| ("G1X10/G1Y-20", "G1X10/G1X11/G1X10/G1Y-20", False), | |
| ("G1X10Y10/G1X30Y-10", "G1X10Y10/G1X10.71Y10.71/G1X10Y10/G1X30Y-10", False), | |
| ("G1Y10/G1X20", "G1Y10/G1Y11/G1Y10/G1X20", False), | |
| ( | |
| "G1X-10Y10/G1X10Y30", | |
| "G1X-10Y10/G1X-10.71Y10.71/G1X-10Y10/G1X10Y30", | |
| False, | |
| ), | |
| ("G1X-10/G1Y20", "G1X-10/G1X-11/G1X-10/G1Y20", False), | |
| ( | |
| "G1X-10Y-10/G1X-30Y10", | |
| "G1X-10Y-10/G1X-10.71Y-10.71/G1X-10Y-10/G1X-30Y10", | |
| False, | |
| ), | |
| ("G1Y-10/G1X-20", "G1Y-10/G1Y-11/G1Y-10/G1X-20", False), | |
| ( | |
| "G1X10Y-10/G1X-10Y-30", | |
| "G1X10Y-10/G1X10.71Y-10.71/G1X10Y-10/G1X-10Y-30", | |
| False, | |
| ), | |
| ] | |
| for i, (path, out, right) in enumerate(test_data_1): | |
| check_tbone_l("1", i, path, out, right) | |
| # long edge m0 | |
| test_data_0 = [ | |
| # CCW | |
| ("G1X20/G1Y10", "G1X20/G1Y-1/G1Y0/G1Y10", True), | |
| ("G1X20Y20/G1X10Y30", "G1X20Y20/G1X20.71Y19.29/G1X20Y20/G1X10Y30", True), | |
| ("G1Y20/G1X-10", "G1Y20/G1X1/G1X0/G1X-10", True), | |
| ( | |
| "G1X-20Y20/G1X-30Y10", | |
| "G1X-20Y20/G1X-19.29Y20.71/G1X-20Y20/G1X-30Y10", | |
| True, | |
| ), | |
| ("G1X-20/G1Y-10", "G1X-20/G1Y1/G1Y0/G1Y-10", True), | |
| ( | |
| "G1X-20Y-20/G1X-10Y-30", | |
| "G1X-20Y-20/G1X-20.71Y-19.29/G1X-20Y-20/G1X-10Y-30", | |
| True, | |
| ), | |
| ("G1Y-20/G1X10", "G1Y-20/G1X-1/G1X0/G1X10", True), | |
| ( | |
| "G1X20Y-20/G1X30Y-10", | |
| "G1X20Y-20/G1X19.29Y-20.71/G1X20Y-20/G1X30Y-10", | |
| True, | |
| ), | |
| # CW | |
| ("G1X20/G1Y-10", "G1X20/G1Y1/G1Y0/G1Y-10", False), | |
| ("G1X20Y20/G1X30Y10", "G1X20Y20/G1X19.29Y20.71/G1X20Y20/G1X30Y10", False), | |
| ("G1Y20/G1X10", "G1Y20/G1X-1/G1X0/G1X10", False), | |
| ( | |
| "G1X-20Y20/G1X-10Y30", | |
| "G1X-20Y20/G1X-20.71Y19.29/G1X-20Y20/G1X-10Y30", | |
| False, | |
| ), | |
| ("G1X-20/G1Y10", "G1X-20/G1Y-1/G1Y0/G1Y10", False), | |
| ( | |
| "G1X-20Y-20/G1X-30Y-10", | |
| "G1X-20Y-20/G1X-19.29Y-20.71/G1X-20Y-20/G1X-30Y-10", | |
| False, | |
| ), | |
| ("G1Y-20/G1X-10", "G1Y-20/G1X1/G1X0/G1X-10", False), | |
| ( | |
| "G1X20Y-20/G1X10Y-30", | |
| "G1X20Y-20/G1X20.71Y-19.29/G1X20Y-20/G1X10Y-30", | |
| False, | |
| ), | |
| ] | |
| for i, (path, out, right) in enumerate(test_data_0): | |
| check_tbone_l("0", i, path, out, right) | |
| def test60(self): | |
| """Verify Dogbone style""" | |
| obj = CreateDressup("G1X10/G1Y20") | |
| obj.Incision = Path.Dressup.DogboneII.Incision.Fixed | |
| obj.Side = Path.Dressup.DogboneII.Side.Right | |
| obj.Style = Path.Dressup.DogboneII.Style.Dogbone | |
| obj.Proxy.execute(obj) | |
| self.assertEqualPath(obj.Path, "G1X10/G1X10.71Y-0.71/G1X10Y0/G1Y20") | |
| def test70(self): | |
| """Verify custom length.""" | |
| obj = CreateDressup("G0Z10/G1Z0/G1X10/G1Y10/G1X0/G1Y0/G0Z10") | |
| obj.Style = Path.Dressup.DogboneII.Style.Tbone_H | |
| obj.Side = Path.Dressup.DogboneII.Side.Right | |
| obj.Incision = Path.Dressup.DogboneII.Incision.Custom | |
| obj.Custom = 3 | |
| obj.Proxy.execute(obj) | |
| self.assertEqualPath( | |
| obj.Path, | |
| "G0Z10/G1Z0/G1X10/G1X13/G1X10/G1Y10/G1X13/G1X10/G1X0/G1X-3/G1X0/G1Y0/G1X-3/G1X0/G0Z10", | |
| ) | |
| obj.Custom = 2 | |
| obj.Proxy.execute(obj) | |
| self.assertEqualPath( | |
| obj.Path, | |
| "G0Z10/G1Z0/G1X10/G1X12/G1X10/G1Y10/G1X12/G1X10/G1X0/G1X-2/G1X0/G1Y0/G1X-2/G1X0/G0Z10", | |
| ) | |
| def test80(self): | |
| """Verify adaptive length.""" | |
| obj = CreateDressup("G1X10/G1Y20") | |
| obj.Incision = Path.Dressup.DogboneII.Incision.Adaptive | |
| obj.Side = Path.Dressup.DogboneII.Side.Right | |
| obj.Style = Path.Dressup.DogboneII.Style.Dogbone | |
| obj.Proxy.execute(obj) | |
| self.assertEqualPath(obj.Path, "G1X10/G1X10.29Y-0.29/G1X10Y0/G1Y20") | |
| def test81(self): | |
| """Verify adaptive length II.""" | |
| obj = CreateDressup("G1X10/G1X20Y20") | |
| obj.Incision = Path.Dressup.DogboneII.Incision.Adaptive | |
| obj.Side = Path.Dressup.DogboneII.Side.Right | |
| obj.Style = Path.Dressup.DogboneII.Style.Dogbone | |
| obj.Proxy.execute(obj) | |
| self.assertEqualPath(obj.Path, "G1X10/G1X10.09Y-0.15/G1X10Y0/G1X20Y20") | |
| def test90(self): | |
| """Verify dogbone blacklist""" | |
| obj = CreateDressup("G0Z10/G1Z0/G1X10/G1Y10/G1X0/G1Y0/G0Z10") | |
| obj.Incision = Path.Dressup.DogboneII.Incision.Fixed | |
| obj.Style = Path.Dressup.DogboneII.Style.Tbone_H | |
| obj.Side = Path.Dressup.DogboneII.Side.Right | |
| obj.BoneBlacklist = [0, 2] | |
| obj.Proxy.execute(obj) | |
| self.assertEqualPath( | |
| obj.Path, "G0Z10/G1Z0/G1X10/G1Y10/G1X11/G1X10/G1X0/G1Y0/G1X-1/G1X0/G0Z10" | |
| ) | |
| return obj | |
| def test91(self): | |
| """Verify dogbone on dogbone""" | |
| obj = self.test90() | |
| obj2 = MockFeaturePython("DressupDogbone001") | |
| db2 = Path.Dressup.DogboneII.Proxy(obj2, obj) | |
| obj2.Proxy = db2 | |
| obj2.Incision = Path.Dressup.DogboneII.Incision.Fixed | |
| obj2.Style = Path.Dressup.DogboneII.Style.Tbone_H | |
| obj2.Side = Path.Dressup.DogboneII.Side.Right | |
| obj2.BoneBlacklist = [1] | |
| obj2.Proxy.execute(obj2) | |
| self.assertEqualPath( | |
| obj2.Path, | |
| "G0Z10/G1Z0/G1X10/G1X11/G1X10/G1Y10/G1X11/G1X10/G1X0/G1X-1/G1X0/G1Y0/G1X-1/G1X0/G0Z10", | |
| ) | |