From 548325c503a26211f10fb89737f1c620b7258305 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonas=20B=C3=A4hr?= Date: Sun, 3 Nov 2024 23:21:40 +0100 Subject: [PATCH] CAM: Add tests loading a helical path created with v0.21 This demonstrates a regression introduced with PR #14364, where documents containing helix operations cannot be recomputed any more (see #15643). This is in preparation for a fix and to ensure we don't break it again. The fixture has been created with the official mac build of FreeCAD-0.21.1 --- .../CAM/CAMTests/Fixtures/OpHelix_v0-21.FCStd | Bin 0 -> 30107 bytes src/Mod/CAM/CAMTests/PathTestUtils.py | 11 ++++ src/Mod/CAM/CAMTests/TestPathHelix.py | 48 ++++++++++++++++++ src/Mod/CAM/CMakeLists.txt | 12 +++++ 4 files changed, 71 insertions(+) create mode 100644 src/Mod/CAM/CAMTests/Fixtures/OpHelix_v0-21.FCStd diff --git a/src/Mod/CAM/CAMTests/Fixtures/OpHelix_v0-21.FCStd b/src/Mod/CAM/CAMTests/Fixtures/OpHelix_v0-21.FCStd new file mode 100644 index 0000000000000000000000000000000000000000..087665c9faa73db275db6a8bea43ef8110a9e965 GIT binary patch literal 30107 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 QNV%Asi;GH-{b{QIA67z)A^-pY literal 0 HcmV?d00001 diff --git a/src/Mod/CAM/CAMTests/PathTestUtils.py b/src/Mod/CAM/CAMTests/PathTestUtils.py index ffdbf01cd1..b12560f672 100644 --- a/src/Mod/CAM/CAMTests/PathTestUtils.py +++ b/src/Mod/CAM/CAMTests/PathTestUtils.py @@ -185,3 +185,14 @@ class PathTestBase(unittest.TestCase): self.assertEqual(len(pts0), len(pts1)) for i in range(len(pts0)): self.assertCoincide(pts0[i], pts1[i]) + + def assertSuccessfulRecompute(self, doc, *objs, msg=None): + """Asserts that the given objects can be successfully recomputed.""" + if len(objs) == 0: + doc.recompute() + objs = doc.Objects + else: + doc.recompute(objs) + failed_objects = [o.Name for o in objs if "Invalid" in o.State] + if len(failed_objects) > 0: + self.fail(msg or f"Recompute failed for {failed_objects}") diff --git a/src/Mod/CAM/CAMTests/TestPathHelix.py b/src/Mod/CAM/CAMTests/TestPathHelix.py index bd32272eb7..772f1ab231 100644 --- a/src/Mod/CAM/CAMTests/TestPathHelix.py +++ b/src/Mod/CAM/CAMTests/TestPathHelix.py @@ -20,6 +20,8 @@ # * * # *************************************************************************** +import pathlib + import Draft import FreeCAD import Path @@ -27,6 +29,8 @@ import Path.Main.Job as PathJob import Path.Op.Helix as PathHelix import CAMTests.PathTestUtils as PathTestUtils +FIXTURE_PATH = pathlib.Path(__file__).parent / "Fixtures" + Path.Log.setLevel(Path.Log.Level.INFO, Path.Log.thisModule()) # Path.Log.trackModule(Path.Log.thisModule()) @@ -126,3 +130,47 @@ class TestPathHelix(PathTestUtils.PathTestBase): self.assertRoughly( round(pos.Length / 10, 0), proxy.holeDiameter(op, model, sub) ) + + def testRecomputeHelixFromV021(self): + """Verify that we can still open and recompute a Helix created with older FreeCAD""" + self.tearDown() + self.doc = FreeCAD.openDocument(str(FIXTURE_PATH / "OpHelix_v0-21.FCStd")) + created_with = f"created with {self.doc.getProgramVersion()}" + + def check(helix, direction, start_side, cut_mode): + with self.subTest(f"{helix.Name}: {direction}, {start_side}, {cut_mode}"): + # no recompute yet, i.e. check original as precondition + self.assertEqual( + helix.Direction, + direction, + msg=f"Direction does not match fixture for helix {created_with}", + ) + self.assertEqual( + helix.StartSide, + start_side, + msg=f"StartSide does not match fixture for helix {created_with}", + ) + + # now see whether we can recompute the object from the old document + helix.enforceRecompute() + self.assertSuccessfulRecompute( + self.doc, helix, msg=f"Cannot recompute helix {created_with}" + ) + self.assertEqual( + helix.Direction, + direction, + msg=f"Direction changed after recomputing helix {created_with}", + ) + self.assertEqual( + helix.StartSide, + start_side, + msg=f"StartSide changed after recomputing helix {created_with}", + ) + # self.assertEqual(helix.CutMode, cut_mode, + # msg=f"CutMode not correctly derived for helix {created_with}") + + # object names and expected values defined in the fixture + check(self.doc.Helix, "CW", "Inside", "Conventional") + check(self.doc.Helix001, "CW", "Outside", "Climb") + check(self.doc.Helix002, "CCW", "Inside", "Climb") + check(self.doc.Helix003, "CCW", "Outside", "Conventional") diff --git a/src/Mod/CAM/CMakeLists.txt b/src/Mod/CAM/CMakeLists.txt index ad349d54c6..48b6bca114 100644 --- a/src/Mod/CAM/CMakeLists.txt +++ b/src/Mod/CAM/CMakeLists.txt @@ -349,6 +349,10 @@ SET(Tests_SRCS CAMTests/Tools/Shape/test-path-tool-bit-shape-00.fcstd ) +SET(Tests_Fixtures + CAMTests/Fixtures/OpHelix_v0-21.FCStd +) + SET(PathImages_Ops Images/Ops/chamfer.svg ) @@ -411,6 +415,7 @@ ADD_CUSTOM_TARGET(PathScripts ALL SET(test_files ${Path_Scripts} ${Tests_SRCS} + ${Tests_Fixtures} ) ADD_CUSTOM_TARGET(Tests ALL @@ -536,6 +541,13 @@ INSTALL( Mod/CAM/CAMTests ) +INSTALL( + FILES + ${Tests_Fixtures} + DESTINATION + Mod/CAM/CAMTests/Fixtures +) + INSTALL( DIRECTORY CAMTests/Tools