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}

Reply via email to