Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package FreeCAD for openSUSE:Factory checked in at 2026-04-10 23:44:50 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/FreeCAD (Old) and /work/SRC/openSUSE:Factory/.FreeCAD.new.21863 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "FreeCAD" Fri Apr 10 23:44:50 2026 rev:59 rq:1345224 version:1.1.0 Changes: -------- +++ only whitespace diff in changes, re-diffing --- /work/SRC/openSUSE:Factory/FreeCAD/FreeCAD.changes 2026-03-06 18:22:15.669297333 +0100 +++ /work/SRC/openSUSE:Factory/.FreeCAD.new.21863/FreeCAD.changes 2026-04-10 23:44:53.595275134 +0200 @@ -1,0 +2,19 @@ +Thu Mar 26 02:33:58 UTC 2026 - Stefan BrĂ¼ns <[email protected]> + +- Update to version 1.1.0 + For details, see https://wiki.freecad.org/Release_notes_1.1 +- Drop: + * Add-property-read-write-test.patch + * Fix-Eigen3-version-search.patch + * Fix-test-failure-temporary-file-race.patch + * disable-test46-test47.patch + * 0001-fix-issue-23829-build-with-boost-v1.89-and-greater.patch + * 0001-Implement-math.comb-fallback-for-Python-3.6.patch +- Rebase: + * freecad-opengl.patch +- Add: + * CAM_PathOpUtil_Fix_linter.patch + * Fix_CAM_PathOpUtil_OCCT_7_9.patch +- Remove separate ondselsolver source, included in tarball + +------------------------------------------------------------------- Old: ---- 0001-Implement-math.comb-fallback-for-Python-3.6.patch 0001-fix-issue-23829-build-with-boost-v1.89-and-greater.patch Add-property-read-write-test.patch Fix-Eigen3-version-search.patch Fix-test-failure-temporary-file-race.patch FreeCAD-1.0.2.tar.gz disable-test46-test47.patch ondselsolver-09d6175a2ba6.zip New: ---- CAM_PathOpUtil_Fix_linter.patch Fix_CAM_PathOpUtil_OCCT_7_9.patch FreeCAD-1.1.0.tar.gz ----------(Old B)---------- Old:/work/SRC/openSUSE:Factory/.FreeCAD.new.21863/FreeCAD.changes- * 0001-fix-issue-23829-build-with-boost-v1.89-and-greater.patch /work/SRC/openSUSE:Factory/.FreeCAD.new.21863/FreeCAD.changes: * 0001-Implement-math.comb-fallback-for-Python-3.6.patch /work/SRC/openSUSE:Factory/.FreeCAD.new.21863/FreeCAD.changes-- Rebase: Old:/work/SRC/openSUSE:Factory/.FreeCAD.new.21863/FreeCAD.changes- * disable-test46-test47.patch /work/SRC/openSUSE:Factory/.FreeCAD.new.21863/FreeCAD.changes: * 0001-fix-issue-23829-build-with-boost-v1.89-and-greater.patch /work/SRC/openSUSE:Factory/.FreeCAD.new.21863/FreeCAD.changes- * 0001-Implement-math.comb-fallback-for-Python-3.6.patch Old:/work/SRC/openSUSE:Factory/.FreeCAD.new.21863/FreeCAD.changes-- Drop: /work/SRC/openSUSE:Factory/.FreeCAD.new.21863/FreeCAD.changes: * Add-property-read-write-test.patch /work/SRC/openSUSE:Factory/.FreeCAD.new.21863/FreeCAD.changes- * Fix-Eigen3-version-search.patch Old:/work/SRC/openSUSE:Factory/.FreeCAD.new.21863/FreeCAD.changes- * Add-property-read-write-test.patch /work/SRC/openSUSE:Factory/.FreeCAD.new.21863/FreeCAD.changes: * Fix-Eigen3-version-search.patch /work/SRC/openSUSE:Factory/.FreeCAD.new.21863/FreeCAD.changes- * Fix-test-failure-temporary-file-race.patch Old:/work/SRC/openSUSE:Factory/.FreeCAD.new.21863/FreeCAD.changes- * Fix-Eigen3-version-search.patch /work/SRC/openSUSE:Factory/.FreeCAD.new.21863/FreeCAD.changes: * Fix-test-failure-temporary-file-race.patch /work/SRC/openSUSE:Factory/.FreeCAD.new.21863/FreeCAD.changes- * disable-test46-test47.patch Old:/work/SRC/openSUSE:Factory/.FreeCAD.new.21863/FreeCAD.changes- * Fix-test-failure-temporary-file-race.patch /work/SRC/openSUSE:Factory/.FreeCAD.new.21863/FreeCAD.changes: * disable-test46-test47.patch /work/SRC/openSUSE:Factory/.FreeCAD.new.21863/FreeCAD.changes- * 0001-fix-issue-23829-build-with-boost-v1.89-and-greater.patch ----------(Old E)---------- ----------(New B)---------- New:/work/SRC/openSUSE:Factory/.FreeCAD.new.21863/FreeCAD.changes-- Add: /work/SRC/openSUSE:Factory/.FreeCAD.new.21863/FreeCAD.changes: * CAM_PathOpUtil_Fix_linter.patch /work/SRC/openSUSE:Factory/.FreeCAD.new.21863/FreeCAD.changes- * Fix_CAM_PathOpUtil_OCCT_7_9.patch New:/work/SRC/openSUSE:Factory/.FreeCAD.new.21863/FreeCAD.changes- * CAM_PathOpUtil_Fix_linter.patch /work/SRC/openSUSE:Factory/.FreeCAD.new.21863/FreeCAD.changes: * Fix_CAM_PathOpUtil_OCCT_7_9.patch /work/SRC/openSUSE:Factory/.FreeCAD.new.21863/FreeCAD.changes-- Remove separate ondselsolver source, included in tarball ----------(New E)---------- ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ FreeCAD-test.spec ++++++ --- /var/tmp/diff_new_pack.RyzDvw/_old 2026-04-10 23:44:58.243466352 +0200 +++ /var/tmp/diff_new_pack.RyzDvw/_new 2026-04-10 23:44:58.259467010 +0200 @@ -17,16 +17,14 @@ Name: FreeCAD-test -Version: 1.0.2 +Version: 1.1.0 Release: 0 Summary: Meta source package that runs the FreeCAD testsuite when built License: GPL-2.0-or-later AND LGPL-2.0-or-later Group: Productivity/Graphics/CAD URL: https://www.freecadweb.org/ BuildRequires: FreeCAD = %{version} -%if 0%{?suse_version} > 1500 BuildRequires: gmsh -%endif # Test suite fails on 32bit and I don't want to debug that anymore ExcludeArch: %ix86 %arm ppc s390 s390x ++++++ FreeCAD.spec ++++++ --- /var/tmp/diff_new_pack.RyzDvw/_old 2026-04-10 23:44:58.499476884 +0200 +++ /var/tmp/diff_new_pack.RyzDvw/_new 2026-04-10 23:44:58.507477213 +0200 @@ -42,37 +42,27 @@ %endif Name: FreeCAD -Version: 1.0.2 +Version: 1.1.0 Release: 0 Summary: General Purpose 3D CAD Modeler License: GPL-2.0-or-later AND LGPL-2.0-or-later Group: Productivity/Graphics/CAD URL: https://www.freecad.org/ -# https://github.com/FreeCAD/FreeCAD/releases/download/%%{version}/freecad_source.tar.gz -Source0: https://github.com/FreeCAD/FreeCAD/archive/refs/tags/%{version}.tar.gz#/%{name}-%{version}.tar.gz -Source1: https://github.com/FreeCAD/OndselSolver/archive/09d6175a2ba69e7016fcecc4f384946a2f84f92d.zip#/ondselsolver-09d6175a2ba6.zip +Source0: https://github.com/FreeCAD/FreeCAD/releases/download/%{version}/freecad_source_%{version}.tar.gz#/%{name}-%{version}.tar.gz # PATCH-FIX-UPSTREAM Patch0: 0001-Gui-Quarter-Add-missing-OpenGL-includes.patch # PATCH-FIX-OPENSUSE Patch1: 0001-Avoid-catching-SIGSEGV-defer-to-system-services.patch # PATCH-FIX-OPENSUSE -Patch2: 0001-Implement-math.comb-fallback-for-Python-3.6.patch -# PATCH-FIX-OPENSUSE Patch3: 0001-Mod-CAM-Add-missing-OpenGL-includes.patch # PATCH-FIX-UPSTREAM -Patch8: 0001-fix-issue-23829-build-with-boost-v1.89-and-greater.patch -# PATCH-FIX-UPSTREAM Patch9: 0001-Fix-variable-name-for-OpenGL-library.patch # PATCH-FIX-OPENSUSE Patch14: freecad-opengl.patch -# PATCH-FIX-UPSTREAM -- Prereq for Fix-test-failure-temporary-file-race.patch -Patch16: https://github.com/FreeCAD/FreeCAD/commit/6f23f01e509348a6755ad3c465a3d7ffd758ee03.patch#/Add-property-read-write-test.patch -# PATCH-FIX-UPSTREAM -Patch17: https://github.com/FreeCAD/FreeCAD/commit/a0e1a31623e334d7186e687c33fad3887e91ee2e.patch#/Fix-test-failure-temporary-file-race.patch # PATCH-FIX-UPSTREAM -Patch18: https://github.com/FreeCAD/FreeCAD/commit/8547e798fb3b0f51953b18a2cb98f60aec0a7e33.patch#/Fix-Eigen3-version-search.patch -# PATCH-FIX-OPENSUSE -Patch100: disable-test46-test47.patch +Patch15: https://github.com/FreeCAD/FreeCAD/commit/06bc4f61e06fb4215ae7e5014c9870262dfe3577.patch#/CAM_PathOpUtil_Fix_linter.patch +# PATCH-FIX-UPSTREAM -- https://github.com/FreeCAD/FreeCAD/commit/a18f77f3b81c15677973e2ea14274c73200470f1 +Patch16: Fix_CAM_PathOpUtil_OCCT_7_9.patch # Test suite fails on 32bit and I don't want to debug that anymore ExcludeArch: %ix86 %arm ppc s390 s390x @@ -116,7 +106,7 @@ BuildRequires: unzip # Qt & python3 -BuildRequires: python3-devel >= 3.6.9 +BuildRequires: python3-devel >= 3.10.0 BuildRequires: python3-matplotlib BuildRequires: python3-pivy >= 0.6.8 BuildRequires: python3-ply @@ -159,6 +149,7 @@ # For Arch & Draft workbench Requires: python3-pivy +Requires: python3-typing_extensions # For FEM workbench Requires: python3-PyYAML @@ -190,21 +181,9 @@ This package contains the files needed for development with FreeCAD. %prep -%autosetup -N -b 1 +%autosetup -c -N %autopatch -p1 -rmdir ./src/3rdParty/OndselSolver -mv ../OndselSolver-* ./src/3rdParty/OndselSolver - -# Use system gtest - https://github.com/FreeCAD/FreeCAD/issues/10126 -sed -i -e 's/add_subdirectory(lib)/find_package(GTest)/' \ - -e 's/ gtest_main/ GTest::gtest_main/' \ - -e 's/ gmock_main/ GTest::gmock_main/' \ - tests/CMakeLists.txt \ - tests/src/Mod/*/CMakeLists.txt -# Lower Python minimum version for Leap 15.x -sed -i -e 's/3.8/3.6/' cMake/FreeCAD_Helpers/SetupPython.cmake - # fix env-script-interpreter sed -i '1 s@#!.*@#!%{__python3}@' \ src/Mod/AddonManager/AddonManager.py \ @@ -266,6 +245,7 @@ -DBUILD_ENABLE_CXX_STD:STRING="C++17" \ -DFREECAD_USE_QT_DIALOG:BOOL=OFF \ -DFREECAD_USE_EXTERNAL_FMT:BOOL=TRUE \ + -DFREECAD_USE_EXTERNAL_GTEST:BOOL=TRUE \ -DFREECAD_USE_EXTERNAL_PIVY:BOOL=TRUE \ -DBUILD_OPENSCAD:BOOL=ON \ -DBUILD_FLAT_MESH:BOOL=ON \ @@ -323,7 +303,9 @@ %check export QT_QPA_PLATFORM=offscreen -%ctest --test-dir tests +# FileInfoTests are racy, https://github.com/FreeCAD/FreeCAD/issues/28737 +%ctest --test-dir tests --exclude-regex FileInfoTest +%ctest --test-dir tests --parallel 1 --tests-regex FileInfoTest %post -p /sbin/ldconfig ++++++ 0001-Gui-Quarter-Add-missing-OpenGL-includes.patch ++++++ --- /var/tmp/diff_new_pack.RyzDvw/_old 2026-04-10 23:44:58.727486264 +0200 +++ /var/tmp/diff_new_pack.RyzDvw/_new 2026-04-10 23:44:58.751487251 +0200 @@ -19,18 +19,14 @@ index 5e1f89e04d..18f418e19e 100644 --- a/src/Gui/Quarter/QuarterWidget.cpp +++ b/src/Gui/Quarter/QuarterWidget.cpp -@@ -72,6 +72,11 @@ - #include <Inventor/SbByteBuffer.h> +@@ -58,6 +58,7 @@ + # include <config.h> + # ifdef HAVE_GL_GL_H + # include <GL/gl.h> ++# include <GL/glext.h> + # endif #endif -+#if !defined(FC_OS_MACOSX) -+# include <GL/gl.h> -+# include <GL/glext.h> -+#endif -+ - #include <Inventor/SbColor.h> - #include <Inventor/SbViewportRegion.h> - #include <Inventor/SoDB.h> @@ -131,10 +136,6 @@ using namespace SIM::Coin3D::Quarter; #define PRIVATE(obj) obj->pimpl ++++++ CAM_PathOpUtil_Fix_linter.patch ++++++ >From 06bc4f61e06fb4215ae7e5014c9870262dfe3577 Mon Sep 17 00:00:00 2001 From: tarman3 <[email protected]> Date: Mon, 24 Nov 2025 23:21:36 +0200 Subject: [PATCH] CAM: OpUtil - Fix linter errors --- src/Mod/CAM/CAMTests/TestPathOpUtil.py | 90 +++++++++++++------------- src/Mod/CAM/Path/Op/Util.py | 19 +++--- 2 files changed, 54 insertions(+), 55 deletions(-) diff --git a/src/Mod/CAM/CAMTests/TestPathOpUtil.py b/src/Mod/CAM/CAMTests/TestPathOpUtil.py index 0aef98c6fffd..8bf7e3748007 100644 --- a/src/Mod/CAM/CAMTests/TestPathOpUtil.py +++ b/src/Mod/CAM/CAMTests/TestPathOpUtil.py @@ -317,7 +317,7 @@ def test22(self): lastAngle = None refAngle = math.pi / 3 for e in wire.Edges: - if Part.Circle == type(e.Curve): + if isinstance(e.Curve, Part.Circle): self.assertRoughly(5, e.Curve.Radius) self.assertCoincide(Vector(0, 0, -1), e.Curve.Axis) else: @@ -365,15 +365,15 @@ def test32(self): wire = PathOpUtil.offsetWire(getWire(obj.Tool), getPositiveShape(obj), 3, True) self.assertEqual(8, len(wire.Edges)) - self.assertEqual(4, len([e for e in wire.Edges if Part.Line == type(e.Curve)])) - self.assertEqual(4, len([e for e in wire.Edges if Part.Circle == type(e.Curve)])) + self.assertEqual(4, len([e for e in wire.Edges if isinstance(e.Curve, Part.Line)])) + self.assertEqual(4, len([e for e in wire.Edges if isinstance(e.Curve, Part.Circle)])) for e in wire.Edges: - if Part.Line == type(e.Curve): + if isinstance(e.Curve, Part.Line): if Path.Geom.isRoughly(e.Vertexes[0].Point.x, e.Vertexes[1].Point.x): self.assertEqual(40, e.Length) if Path.Geom.isRoughly(e.Vertexes[0].Point.y, e.Vertexes[1].Point.y): self.assertEqual(60, e.Length) - if Part.Circle == type(e.Curve): + if isinstance(e.Curve, Part.Circle): self.assertRoughly(3, e.Curve.Radius) self.assertCoincide(Vector(0, 0, -1), e.Curve.Axis) self.assertTrue(PathOpUtil.isWireClockwise(wire)) @@ -381,15 +381,15 @@ def test32(self): # change offset orientation wire = PathOpUtil.offsetWire(getWire(obj.Tool), getPositiveShape(obj), 3, False) self.assertEqual(8, len(wire.Edges)) - self.assertEqual(4, len([e for e in wire.Edges if Part.Line == type(e.Curve)])) - self.assertEqual(4, len([e for e in wire.Edges if Part.Circle == type(e.Curve)])) + self.assertEqual(4, len([e for e in wire.Edges if isinstance(e.Curve, Part.Line)])) + self.assertEqual(4, len([e for e in wire.Edges if isinstance(e.Curve, Part.Circle)])) for e in wire.Edges: - if Part.Line == type(e.Curve): + if isinstance(e.Curve, Part.Line): if Path.Geom.isRoughly(e.Vertexes[0].Point.x, e.Vertexes[1].Point.x): self.assertEqual(40, e.Length) if Path.Geom.isRoughly(e.Vertexes[0].Point.y, e.Vertexes[1].Point.y): self.assertEqual(60, e.Length) - if Part.Circle == type(e.Curve): + if isinstance(e.Curve, Part.Circle): self.assertRoughly(3, e.Curve.Radius) self.assertCoincide(Vector(0, 0, +1), e.Curve.Axis) self.assertFalse(PathOpUtil.isWireClockwise(wire)) @@ -400,25 +400,25 @@ def test33(self): wire = PathOpUtil.offsetWire(getWire(obj.Tool), getPositiveShape(obj), 3, True) self.assertEqual(6, len(wire.Edges)) - self.assertEqual(3, len([e for e in wire.Edges if Part.Line == type(e.Curve)])) - self.assertEqual(3, len([e for e in wire.Edges if Part.Circle == type(e.Curve)])) + self.assertEqual(3, len([e for e in wire.Edges if isinstance(e.Curve, Part.Line)])) + self.assertEqual(3, len([e for e in wire.Edges if isinstance(e.Curve, Part.Circle)])) length = 60 * math.sin(math.radians(60)) for e in wire.Edges: - if Part.Line == type(e.Curve): + if isinstance(e.Curve, Part.Line): self.assertRoughly(length, e.Length) - if Part.Circle == type(e.Curve): + if isinstance(e.Curve, Part.Circle): self.assertRoughly(3, e.Curve.Radius) self.assertCoincide(Vector(0, 0, -1), e.Curve.Axis) # change offset orientation wire = PathOpUtil.offsetWire(getWire(obj.Tool), getPositiveShape(obj), 3, False) self.assertEqual(6, len(wire.Edges)) - self.assertEqual(3, len([e for e in wire.Edges if Part.Line == type(e.Curve)])) - self.assertEqual(3, len([e for e in wire.Edges if Part.Circle == type(e.Curve)])) + self.assertEqual(3, len([e for e in wire.Edges if isinstance(e.Curve, Part.Line)])) + self.assertEqual(3, len([e for e in wire.Edges if isinstance(e.Curve, Part.Circle)])) for e in wire.Edges: - if Part.Line == type(e.Curve): + if isinstance(e.Curve, Part.Line): self.assertRoughly(length, e.Length) - if Part.Circle == type(e.Curve): + if isinstance(e.Curve, Part.Circle): self.assertRoughly(3, e.Curve.Radius) self.assertCoincide(Vector(0, 0, +1), e.Curve.Axis) @@ -428,26 +428,26 @@ def test34(self): wire = PathOpUtil.offsetWire(getWire(obj.Tool), getPositiveShape(obj), 3, True) self.assertEqual(6, len(wire.Edges)) - self.assertEqual(3, len([e for e in wire.Edges if Part.Line == type(e.Curve)])) - self.assertEqual(3, len([e for e in wire.Edges if Part.Circle == type(e.Curve)])) + self.assertEqual(3, len([e for e in wire.Edges if isinstance(e.Curve, Part.Line)])) + self.assertEqual(3, len([e for e in wire.Edges if isinstance(e.Curve, Part.Circle)])) length = 40 radius = 20 + 3 for e in wire.Edges: - if Part.Line == type(e.Curve): + if isinstance(e.Curve, Part.Line): self.assertRoughly(length, e.Length) - if Part.Circle == type(e.Curve): + if isinstance(e.Curve, Part.Circle): self.assertRoughly(radius, e.Curve.Radius) self.assertCoincide(Vector(0, 0, -1), e.Curve.Axis) # change offset orientation wire = PathOpUtil.offsetWire(getWire(obj.Tool), getPositiveShape(obj), 3, False) self.assertEqual(6, len(wire.Edges)) - self.assertEqual(3, len([e for e in wire.Edges if Part.Line == type(e.Curve)])) - self.assertEqual(3, len([e for e in wire.Edges if Part.Circle == type(e.Curve)])) + self.assertEqual(3, len([e for e in wire.Edges if isinstance(e.Curve, Part.Line)])) + self.assertEqual(3, len([e for e in wire.Edges if isinstance(e.Curve, Part.Circle)])) for e in wire.Edges: - if Part.Line == type(e.Curve): + if isinstance(e.Curve, Part.Line): self.assertRoughly(length, e.Length) - if Part.Circle == type(e.Curve): + if isinstance(e.Curve, Part.Circle): self.assertRoughly(radius, e.Curve.Radius) self.assertCoincide(Vector(0, 0, +1), e.Curve.Axis) @@ -476,7 +476,7 @@ def test36(self): wire = PathOpUtil.offsetWire(getWire(obj.Tool), getNegativeShape(obj), 3, True) self.assertEqual(4, len(wire.Edges)) - self.assertEqual(4, len([e for e in wire.Edges if Part.Line == type(e.Curve)])) + self.assertEqual(4, len([e for e in wire.Edges if isinstance(e.Curve, Part.Line)])) for e in wire.Edges: if Path.Geom.isRoughly(e.Vertexes[0].Point.x, e.Vertexes[1].Point.x): self.assertRoughly(34, e.Length) @@ -487,7 +487,7 @@ def test36(self): # change offset orientation wire = PathOpUtil.offsetWire(getWire(obj.Tool), getNegativeShape(obj), 3, False) self.assertEqual(4, len(wire.Edges)) - self.assertEqual(4, len([e for e in wire.Edges if Part.Line == type(e.Curve)])) + self.assertEqual(4, len([e for e in wire.Edges if isinstance(e.Curve, Part.Line)])) for e in wire.Edges: if Path.Geom.isRoughly(e.Vertexes[0].Point.x, e.Vertexes[1].Point.x): self.assertRoughly(34, e.Length) @@ -501,7 +501,7 @@ def test37(self): wire = PathOpUtil.offsetWire(getWire(obj.Tool), getNegativeShape(obj), 3, True) self.assertEqual(3, len(wire.Edges)) - self.assertEqual(3, len([e for e in wire.Edges if Part.Line == type(e.Curve)])) + self.assertEqual(3, len([e for e in wire.Edges if isinstance(e.Curve, Part.Line)])) length = 48 * math.sin(math.radians(60)) for e in wire.Edges: self.assertRoughly(length, e.Length) @@ -510,7 +510,7 @@ def test37(self): # change offset orientation wire = PathOpUtil.offsetWire(getWire(obj.Tool), getNegativeShape(obj), 3, False) self.assertEqual(3, len(wire.Edges)) - self.assertEqual(3, len([e for e in wire.Edges if Part.Line == type(e.Curve)])) + self.assertEqual(3, len([e for e in wire.Edges if isinstance(e.Curve, Part.Line)])) for e in wire.Edges: self.assertRoughly(length, e.Length) self.assertTrue(PathOpUtil.isWireClockwise(wire)) @@ -521,26 +521,26 @@ def test38(self): wire = PathOpUtil.offsetWire(getWire(obj.Tool), getNegativeShape(obj), 3, True) self.assertEqual(6, len(wire.Edges)) - self.assertEqual(3, len([e for e in wire.Edges if Part.Line == type(e.Curve)])) - self.assertEqual(3, len([e for e in wire.Edges if Part.Circle == type(e.Curve)])) + self.assertEqual(3, len([e for e in wire.Edges if isinstance(e.Curve, Part.Line)])) + self.assertEqual(3, len([e for e in wire.Edges if isinstance(e.Curve, Part.Circle)])) length = 40 radius = 20 - 3 for e in wire.Edges: - if Part.Line == type(e.Curve): + if isinstance(e.Curve, Part.Line): self.assertRoughly(length, e.Length) - if Part.Circle == type(e.Curve): + if isinstance(e.Curve, Part.Circle): self.assertRoughly(radius, e.Curve.Radius) self.assertCoincide(Vector(0, 0, +1), e.Curve.Axis) # change offset orientation wire = PathOpUtil.offsetWire(getWire(obj.Tool), getNegativeShape(obj), 3, False) self.assertEqual(6, len(wire.Edges)) - self.assertEqual(3, len([e for e in wire.Edges if Part.Line == type(e.Curve)])) - self.assertEqual(3, len([e for e in wire.Edges if Part.Circle == type(e.Curve)])) + self.assertEqual(3, len([e for e in wire.Edges if isinstance(e.Curve, Part.Line)])) + self.assertEqual(3, len([e for e in wire.Edges if isinstance(e.Curve, Part.Circle)])) for e in wire.Edges: - if Part.Line == type(e.Curve): + if isinstance(e.Curve, Part.Line): self.assertRoughly(length, e.Length) - if Part.Circle == type(e.Curve): + if isinstance(e.Curve, Part.Circle): self.assertRoughly(radius, e.Curve.Radius) self.assertCoincide(Vector(0, 0, -1), e.Curve.Axis) @@ -642,7 +642,7 @@ def test42(self): self.assertCoincide(Vector(-x, y, 0), wire.Edges[0].Vertexes[0].Point) self.assertCoincide(Vector(+x, y, 0), wire.Edges[-1].Vertexes[1].Point) - rEdges = [e for e in wire.Edges if Part.Circle == type(e.Curve)] + rEdges = [e for e in wire.Edges if isinstance(e.Curve, Part.Circle)] self.assertEqual(1, len(rEdges)) self.assertCoincide(Vector(0, 20, 0), rEdges[0].Curve.Center) @@ -654,7 +654,7 @@ def test42(self): self.assertCoincide(Vector(+x, y, 0), wire.Edges[0].Vertexes[0].Point) self.assertCoincide(Vector(-x, y, 0), wire.Edges[-1].Vertexes[1].Point) - rEdges = [e for e in wire.Edges if Part.Circle == type(e.Curve)] + rEdges = [e for e in wire.Edges if isinstance(e.Curve, Part.Circle)] self.assertEqual(1, len(rEdges)) self.assertCoincide(Vector(0, 20, 0), rEdges[0].Curve.Center) @@ -686,7 +686,7 @@ def test43(self): self.assertCoincide(Vector(-x, y, 0), wire.Edges[0].Vertexes[0].Point) self.assertCoincide(Vector(+x, y, 0), wire.Edges[-1].Vertexes[1].Point) - rEdges = [e for e in wire.Edges if Part.Circle == type(e.Curve)] + rEdges = [e for e in wire.Edges if isinstance(e.Curve, Part.Circle)] self.assertEqual(1, len(rEdges)) self.assertCoincide(Vector(0, 20, 0), rEdges[0].Curve.Center) @@ -698,7 +698,7 @@ def test43(self): self.assertCoincide(Vector(+x, y, 0), wire.Edges[0].Vertexes[0].Point) self.assertCoincide(Vector(-x, y, 0), wire.Edges[-1].Vertexes[1].Point) - rEdges = [e for e in wire.Edges if Part.Circle == type(e.Curve)] + rEdges = [e for e in wire.Edges if isinstance(e.Curve, Part.Circle)] self.assertEqual(1, len(rEdges)) self.assertCoincide(Vector(0, 20, 0), rEdges[0].Curve.Center) @@ -801,7 +801,7 @@ def test46(self): self.assertCoincide(Vector(+x, y, 0), wire.Edges[0].Vertexes[0].Point) self.assertCoincide(Vector(-x, y, 0), wire.Edges[-1].Vertexes[1].Point) - rEdges = [e for e in wire.Edges if Part.Circle == type(e.Curve)] + rEdges = [e for e in wire.Edges if isinstance(e.Curve, Part.Circle)] self.assertEqual(0, len(rEdges)) # offset the other way @@ -810,7 +810,7 @@ def test46(self): self.assertCoincide(Vector(-x, y, 0), wire.Edges[0].Vertexes[0].Point) self.assertCoincide(Vector(+x, y, 0), wire.Edges[-1].Vertexes[1].Point) - rEdges = [e for e in wire.Edges if Part.Circle == type(e.Curve)] + rEdges = [e for e in wire.Edges if isinstance(e.Curve, Part.Circle)] self.assertEqual(0, len(rEdges)) def test47(self): @@ -839,7 +839,7 @@ def test47(self): self.assertCoincide(Vector(+x, y, 0), wire.Edges[0].Vertexes[0].Point) self.assertCoincide(Vector(-x, y, 0), wire.Edges[-1].Vertexes[1].Point) - rEdges = [e for e in wire.Edges if Part.Circle == type(e.Curve)] + rEdges = [e for e in wire.Edges if isinstance(e.Curve, Part.Circle)] self.assertEqual(0, len(rEdges)) # offset the other way @@ -848,7 +848,7 @@ def test47(self): self.assertCoincide(Vector(-x, y, 0), wire.Edges[0].Vertexes[0].Point) self.assertCoincide(Vector(+x, y, 0), wire.Edges[-1].Vertexes[1].Point) - rEdges = [e for e in wire.Edges if Part.Circle == type(e.Curve)] + rEdges = [e for e in wire.Edges if isinstance(e.Curve, Part.Circle)] self.assertEqual(0, len(rEdges)) def test50(self): diff --git a/src/Mod/CAM/Path/Op/Util.py b/src/Mod/CAM/Path/Op/Util.py index a8639e78c770..5035371c1c90 100644 --- a/src/Mod/CAM/Path/Op/Util.py +++ b/src/Mod/CAM/Path/Op/Util.py @@ -22,7 +22,6 @@ # * * # *************************************************************************** -from PySide.QtCore import QT_TRANSLATE_NOOP import FreeCAD import Path import math @@ -56,12 +55,12 @@ def debugEdge(label, e): return p0 = e.valueAt(e.FirstParameter) p1 = e.valueAt(e.LastParameter) - if Part.Line == type(e.Curve): + if isinstance(e.Curve, Part.Line): print( "%s Part.makeLine((%.2f, %.2f, %.2f), (%.2f, %.2f, %.2f))" % (label, p0.x, p0.y, p0.z, p1.x, p1.y, p1.z) ) - elif Part.Circle == type(e.Curve): + elif isinstance(e.Curve, Part.Circle): r = e.Curve.Radius c = e.Curve.Center a = e.Curve.Axis @@ -139,9 +138,9 @@ def _isWireClockwise(w): # handle wires consisting of a single circle or 2 edges where one is an arc. # in both cases, because the edges are expected to be oriented correctly, the orientation can be # determined by looking at (one of) the circle curves. - if 2 >= len(w.Edges) and Part.Circle == type(w.Edges[0].Curve): + if len(w.Edges) <= 2 and isinstance(w.Edges[0].Curve, Part.Circle): return 0 > w.Edges[0].Curve.Axis.z - if 2 == len(w.Edges) and Part.Circle == type(w.Edges[1].Curve): + if len(w.Edges) == 2 and isinstance(w.Edges[1].Curve, Part.Circle): return 0 > w.Edges[1].Curve.Axis.z # for all other wires we presume they are polygonial and refer to Gauss @@ -183,10 +182,10 @@ def offsetWire(wire, base, offset, forward, Side=None): """ Path.Log.track("offsetWire") - if 1 == len(wire.Edges): + if len(wire.Edges) == 1: edge = wire.Edges[0] curve = edge.Curve - if Part.Circle == type(curve) and wire.isClosed(): + if isinstance(curve, Part.Circle) and wire.isClosed(): # it's a full circle and there are some problems with that, see # https://www.freecad.org/wiki/Part%20Offset2D # it's easy to construct them manually though @@ -205,7 +204,7 @@ def offsetWire(wire, base, offset, forward, Side=None): return Part.Wire([new_edge]) - if Part.Circle == type(curve) and not wire.isClosed(): + if isinstance(curve, Part.Circle) and not wire.isClosed(): # Process arc segment z = -1 if forward else 1 l1 = math.sqrt( @@ -257,7 +256,7 @@ def offsetWire(wire, base, offset, forward, Side=None): return Part.Wire([edge]) - if Part.Line == type(curve) or Part.LineSegment == type(curve): + if isinstance(curve, (Part.Line, Part.LineSegment)): # offsetting a single edge doesn't work because there is an infinite # possible planes into which the edge could be offset # luckily, the plane here must be the XY-plane ... @@ -351,7 +350,7 @@ def isInside(edge): def isCircleAt(edge, center): """isCircleAt(edge, center) ... helper function returns True if edge is a circle at the given center.""" - if Part.Circle == type(edge.Curve) or Part.ArcOfCircle == type(edge.Curve): + if isinstance(edge.Curve, (Part.Circle, Part.ArcOfCircle)): return Path.Geom.pointsCoincide(edge.Curve.Center, center) return False ++++++ Fix_CAM_PathOpUtil_OCCT_7_9.patch ++++++ >From a18f77f3b81c15677973e2ea14274c73200470f1 Mon Sep 17 00:00:00 2001 From: FilippoR <[email protected]> Date: Fri, 6 Mar 2026 18:31:05 +0100 Subject: [PATCH] fix CAMTests.TestPathOpUtil.TestPathOpUtil.test46 & test47 (#28038) * fix CAMTests.TestPathOpUtil.TestPathOpUtil.test46 * fix CAMTests.TestPathOpUtil.TestPathOpUtil.test47 * disable CAMTests.TestTestPost.TestTestPost.test00190 --- src/Mod/CAM/CAMTests/TestPathOpUtil.py | 45 ++++++++++++++++---------- src/Mod/CAM/CAMTests/TestTestPost.py | 2 ++ src/Mod/CAM/Path/Op/Util.py | 22 +++++++------ 3 files changed, 42 insertions(+), 27 deletions(-) diff --git a/src/Mod/CAM/CAMTests/TestPathOpUtil.py b/src/Mod/CAM/CAMTests/TestPathOpUtil.py index 8bf7e3748007..87867b1d9686 100644 --- a/src/Mod/CAM/CAMTests/TestPathOpUtil.py +++ b/src/Mod/CAM/CAMTests/TestPathOpUtil.py @@ -815,12 +815,11 @@ def test46(self): def test47(self): """Check offsetting multiple backwards inside edges.""" - # This is exactly the same as test36 except that the wire is flipped to make - # sure it's orientation doesn't matter + # This is similar to test46 except that the wire is flipped to verify + # that wire offsetting works regardless of input wire orientation obj = self.doc.getObjectsByLabel("offset-edge")[0] w = getWireInside(obj) - length = 20 * math.cos(math.pi / 6) # let's offset the other two legs lEdges = [ @@ -830,26 +829,38 @@ def test47(self): ] self.assertEqual(2, len(lEdges)) + # Test with flipped wire - the algorithm should handle it w = Path.Geom.flipWire(Part.Wire(lEdges)) wire = PathOpUtil.offsetWire(w, obj.Shape, 2, True) - x = length / 2 - 2 * math.cos(math.pi / 6) - y = -5 - 2 * math.sin(math.pi / 6) - - self.assertCoincide(Vector(+x, y, 0), wire.Edges[0].Vertexes[0].Point) - self.assertCoincide(Vector(-x, y, 0), wire.Edges[-1].Vertexes[1].Point) - - rEdges = [e for e in wire.Edges if isinstance(e.Curve, Part.Circle)] - self.assertEqual(0, len(rEdges)) + # Check structural properties rather than exact coordinates + # Verify the wire is valid and has geometry + self.assertIsNotNone(wire) + self.assertGreater(len(wire.Edges), 0) + # All edges should be lines (no circles for inside edges) + lEdges_result = [e for e in wire.Edges if isinstance(e.Curve, Part.Line)] + self.assertGreater(len(lEdges_result), 0) + # Check that edge lengths are consistent with offset geometry + total_length = 0 + for e in wire.Edges: + self.assertGreater(e.Length, 0) + total_length += e.Length + # Result should have meaningful length after offset + self.assertGreater(total_length, 0) - # offset the other way + # offset the other way - this should also work wire = PathOpUtil.offsetWire(Part.Wire(lEdges), obj.Shape, 2, False) - self.assertCoincide(Vector(-x, y, 0), wire.Edges[0].Vertexes[0].Point) - self.assertCoincide(Vector(+x, y, 0), wire.Edges[-1].Vertexes[1].Point) - - rEdges = [e for e in wire.Edges if isinstance(e.Curve, Part.Circle)] - self.assertEqual(0, len(rEdges)) + # Check the same structural properties + self.assertIsNotNone(wire) + self.assertGreater(len(wire.Edges), 0) + lEdges_result = [e for e in wire.Edges if isinstance(e.Curve, Part.Line)] + self.assertGreater(len(lEdges_result), 0) + total_length = 0 + for e in wire.Edges: + self.assertGreater(e.Length, 0) + total_length += e.Length + self.assertGreater(total_length, 0) def test50(self): """Orient an already oriented wire""" diff --git a/src/Mod/CAM/Path/Op/Util.py b/src/Mod/CAM/Path/Op/Util.py index 5035371c1c90..db4b8cdf4c1e 100644 --- a/src/Mod/CAM/Path/Op/Util.py +++ b/src/Mod/CAM/Path/Op/Util.py @@ -345,7 +345,8 @@ def isInside(edge): if not longestWire or longestWire.Length < w.Length: longestWire = w - debugWire("outside", Part.Wire(outside)) + if len(outside) >= 2: + debugWire("outside", Part.Wire(outside)) debugWire("longest", longestWire) def isCircleAt(edge, center): @@ -398,15 +399,16 @@ def isCircleAt(edge, center): # figure out if all the left sided edges or the right sided edges are the ones # that are 'outside'. However, we return the full side. edges = leftSideEdges - for e in longestWire.Edges: - for e0 in rightSideEdges: - if Path.Geom.edgesMatch(e, e0): - edges = rightSideEdges - Path.Log.debug("#use right side edges") - if not forward: - Path.Log.debug("#reverse") - edges.reverse() - return orientWire(Part.Wire(edges), None) + if longestWire: + for e in longestWire.Edges: + for e0 in rightSideEdges: + if Path.Geom.edgesMatch(e, e0): + edges = rightSideEdges + Path.Log.debug("#use right side edges") + if not forward: + Path.Log.debug("#reverse") + edges.reverse() + return orientWire(Part.Wire(edges), None) # at this point we have the correct edges and they are in the order for forward # traversal (climb milling). If that's not what we want just reverse the order, ++++++ FreeCAD-1.0.2.tar.gz -> FreeCAD-1.1.0.tar.gz ++++++ /work/SRC/openSUSE:Factory/FreeCAD/FreeCAD-1.0.2.tar.gz /work/SRC/openSUSE:Factory/.FreeCAD.new.21863/FreeCAD-1.1.0.tar.gz differ: char 4, line 1 ++++++ freecad-opengl.patch ++++++ --- /var/tmp/diff_new_pack.RyzDvw/_old 2026-04-10 23:44:59.351511935 +0200 +++ /var/tmp/diff_new_pack.RyzDvw/_new 2026-04-10 23:44:59.379513087 +0200 @@ -11,16 +11,8 @@ simple(Coin3D "${COIN3D_VERSION} [${COIN3D_LIBRARIES}] [${COIN3D_INCLUDE_DIRS}]") --- a/src/Gui/CMakeLists.txt +++ b/src/Gui/CMakeLists.txt -@@ -68,6 +68,7 @@ if(MSVC) - FreeCADApp - ${COIN3D_LIBRARIES} - ${OPENGL_gl_LIBRARY} -+ ${OPENGL_LIBRARY} - ) - - if(FREECAD_USE_3DCONNEXION_LEGACY) -@@ -82,6 +83,7 @@ else(MSVC) - ${COIN3D_LIBRARIES} +@@ -113,6 +113,7 @@ else(MSVC) + FreeCADApp ${Boost_LIBRARIES} ${OPENGL_gl_LIBRARY} + ${OPENGL_LIBRARY}
