Skip to content

Refactor: modernize cmake, boost, qt, and others to the latest or near latest#2463

Merged
basisunus merged 167 commits into
masterfrom
refactor
Jul 3, 2026
Merged

Refactor: modernize cmake, boost, qt, and others to the latest or near latest#2463
basisunus merged 167 commits into
masterfrom
refactor

Conversation

@basisunus

Copy link
Copy Markdown
Contributor

Built on Windows 10 with Visual Studio 2022.
Runs on Windows.
Some issues with vector out of bound, possibly initialization issues and qt related.

@dcwhite

dcwhite commented Jun 18, 2026

Copy link
Copy Markdown
Member

🤖 Follow-up from the Claude review (posted via @dcwhite).

I empirically verified the "flags preserved" claim from my earlier review: generated compile_commands.json for both a baseline build and this refactor branch, then diffed the actual per-file compile commands across 1,390 common translation units.

Result: warning flags and compiler/codegen flags are byte-for-byte identical across every file. The only deltas are preprocessor defines, all of which are intentional consequences of the Boost/Qt/Python modernization. Full breakdown in the comment below. 👇

@dcwhite

dcwhite commented Jun 18, 2026

Copy link
Copy Markdown
Member

🤖 Empirical verification of compiler flags / warning settings (Claude review, via @dcwhite)

Method: built compile_commands.json for a baseline tree and this refactor tree with -DCMAKE_EXPORT_COMPILE_COMMANDS=ON, then diffed the actual per-file compile commands. 1,390 common translation units compared.

Warning & compiler flags: identical ✅

Category Result across 1,390 files
-W warning flags Zero differences — no file gains or loses a warning flag
Codegen / language flags (-std=, -O*, -f*, -stdlib=, -arch, -g, …) Zero differences

Boost include treatment: still -isystem

Every Boost include in the refactor build still arrives via -isystem (1,288 files), zero via plain -I — so Boost-header warnings stay suppressed even though the explicit INCLUDE_DIRECTORIES(SYSTEM …) line was removed. The imported find_package(Boost CONFIG) targets mark their includes as system. No regression.

Only preprocessor defines changed — all intentional

Define Direction Reason
BOOST_NO_CXX11_ALLOCATOR, BOOST_PYTHON_STATIC_LIB/MODULE removed old variable-based Boost config; superseded by the new no-lib defines
BOOST_SYSTEM_NO_LIB, BOOST_FILESYSTEM_NO_LIB, BOOST_FILESYSTEM_STATIC_LINK added the new compile definitions in this PR
QWT_DLL (55 files) removed Qwt switched DLL → static
QT_SVG_LIB, QT_PRINTSUPPORT_LIB added now propagated automatically from the Qt::Svg / Qt::PrintSupport imported targets
python3.11python3.13 paths changed refactor bumps Python 3.11 → 3.13 (this is exactly why the hardcoded python313.lib matches today — see inline comment)

Caveat: the baseline tree compared here was a recent non-master feature branch, and the refactor tree includes a later fix-python-test merge. The only 2 files unique to the baseline (OffscreenGLRenderer.cc + its moc_) are a branch-divergence artifact, not a refactor removal.

Net: warning settings and compiler flags are preserved exactly; the refactor changes only which library-selection defines are set, all deliberately.

@dcwhite

dcwhite commented Jun 23, 2026

Copy link
Copy Markdown
Member

All green! Although first we should merge #2527 to master, then back here, to check the older Mac builds.

@basisunus

Copy link
Copy Markdown
Contributor Author

Was the Qt UI blip addressed? I just asked Copilot because I found it might be related to the OpenGL rendering I was piping with Vtk. I haven't tried the solution but will do if it's not addressed so far.
Good catch — this is actually a known side-effect of mixing QOpenGLWidget into an existing Qt UI hierarchy, especially in large apps like SCIRun.

What you're seeing:

“main window is closed/minimized briefly and shows up again”

is almost certainly caused by Qt re-creating the underlying OpenGL surface and backing store when your QOpenGLWidget is inserted.


✅ Why this happens

QOpenGLWidget is not a normal widget. Internally it:

  1. Creates an offscreen framebuffer (FBO)
  2. Hooks into Qt’s composition system
  3. Forces a reconfiguration of the window surface

When added dynamically (like when ViewScene is created), Qt may:

  • Recreate the native window
  • Reinitialize the backing store
  • Trigger a temporary hide/show of the top-level window

👉 This appears as:

  • brief minimize
  • flicker
  • window disappearing and reappearing

🔴 Why it started happening after removing those flags

Before, you had:

WA_NativeWindow
WA_PaintOnScreen

Those forced:

  • direct native window rendering
  • bypass of Qt composition

👉 That avoided the surface reconfiguration (but broke rendering)

Now:

✅ You're using proper QOpenGLWidget behavior
❗ Qt is doing the correct (but disruptive) surface rebuild


✅ Most likely triggers in your setup

1. Creating the widget late (dynamic insertion)

If ViewScene is:

  • created after main window is already shown
  • then inserted into layout

👉 Qt may rebuild the window surface


2. Surface format mismatch

If your OpenGL format differs from the main window:

👉 Qt must recreate the entire context stack


3. Multiple GL widgets or mixed surfaces

If SCIRun uses:

  • existing GL widgets
  • or native rendering elsewhere

👉 introducing QOpenGLWidget forces uniformity


✅ How to fix / stabilize it

✅ Fix 1: Set global surface format early (VERY important)

Do this before QApplication is created:

QSurfaceFormat fmt;
fmt.setDepthBufferSize(24);
fmt.setStencilBufferSize(8);
fmt.setVersion(3, 3);  // match your renderer
fmt.setProfile(QSurfaceFormat::CoreProfile);

QSurfaceFormat::setDefaultFormat(fmt);

👉 This avoids runtime surface rebuilds.


✅ Fix 2: Create the widget earlier

Instead of creating VtkQWidget when the module is added:

👉 Create it upfront (or placeholder it)

This avoids dynamic surface changes.


✅ Fix 3: Avoid mixing native + GL widgets

Make sure:

  • no QGLWidget (old)
  • no WA_NativeWindow elsewhere
  • no custom native painting

✅ Fix 4: Disable updates during insertion (quick workaround)

Wrap creation with:

mainWindow->setUpdatesEnabled(false);

// create and insert VtkQWidget

mainWindow->setUpdatesEnabled(true);
mainWindow->update();

👉 This suppresses the visible flicker/minimize.


✅ Fix 5 (diagnostic): force repaint behavior

Sometimes helps identify the issue:

setUpdateBehavior(QOpenGLWidget::NoPartialUpdate);

✅ What this is NOT

This is NOT:

  • a crash
  • a GL failure
  • a bad context

👉 It's just Qt rebuilding surfaces correctly.


✅ Practical recommendation

For now:

👉 Ignore the flicker if it only happens once on creation

Then continue your pipeline work.

Later, refine with:

  • early initialization
  • unified surface format

✅ TL;DR

  • Removing those attributes was ✅ correct
  • Flicker/minimize = Qt reconfiguring window surface
  • Caused by introducing QOpenGLWidget dynamically
  • Fix by:
    • setting global QSurfaceFormat early ✅
    • creating widget earlier ✅
    • optionally disabling updates during insertion ✅

🚀 Good news

This actually means:

✅ Your OpenGL path is now correctly configured

You’re ready for the next step:
👉 VTK offscreen → OpenGL texture → display


If you want, I can now give you a clean, modern texture upload path (no glDrawPixels, fully correct for Qt + GL).

@basisunus

Copy link
Copy Markdown
Contributor Author

The issue that main window hides and then shows when viewscene is added has been fixed by adding a dummy OpenGL window.

@dcwhite

dcwhite commented Jun 26, 2026

Copy link
Copy Markdown
Member

The issue that main window hides and then shows when viewscene is added has been fixed by adding a dummy OpenGL window.

I just love these funky Qt hacky fixes. SCIRun is littered with them.

@dcwhite

dcwhite commented Jul 1, 2026

Copy link
Copy Markdown
Member

Found concrete crash details across the jobs. Here's the breakdown, grouped by root cause:

1. Missing switch case (dominant failure — ~870 test failures)

ConsoleCommandFactory.cc:43 has no case GlobalCommands::ImportNetworkFile:, unlike GuiCommandFactory.cc:57 which does. Every headless import test hits the default: throw immediately:

Critical error! Unhandled exception: Unknown global command type.

Affects linux-headless-regression, windows-headless-regression, all three mac-headless-*-slim jobs.

2. Eigen upgrade broke tensor/matrix assumptions (real regressions from this PR's stated goal)

Three distinct crashes, all Eigen assertion failures that didn't fire before the version bump:

  • Core_Datatypes_Tests aborts on DyadicTensorTest.DifferentDimensionsNotEquivalent: Assertion failed: (dimensions_match(...)), TensorAssign.h:146 — the test intentionally compares mismatched-dimension tensors, but newer Eigen hard-asserts instead of the old graceful-failure path.
  • .Test.ExampleNetwork.negative_tensors_srn and negative_tensors_normals_deubg_srn abort: Assertion failed: (rows() == cols()), function inverse, InverseImpl.h:351 — some tensor-field module is calling .inverse() on a non-square matrix while processing real network data.
  • Algorithms_DataIO_Tests: WriteMatrixTest.CanPrintSparseMatrix fails (not crash) — sparse matrix's internal entry ordering changed ((1,0) (_,_) (-1.4,2) expected vs (1,0) (-1.4,2) (_,_) actual), consistent with Eigen changing SparseMatrix internal storage/compression behavior.

These three point at the same theme: code that relied on old Eigen internals/behavior needs updating for the new version, in the tensor and sparse-matrix code paths.

3. Python embedding crash (also likely tied to the Python 3.13 bump in this PR)

Engine_Python_Tests aborts the whole process on its second test:

Fatal Python error: PyImport_AppendInittab: PyImport_AppendInittab() may not be called after Py_Initialize()

Something in the interpreter setup registers a module inittab entry per-test instead of once before Py_Initialize() — worked under the old Python version, fails now.

4. Pre-existing fragile test path (probably unrelated to this PR)

LegacyNetworkFileImporterTests::SetUpTestSuite reads TestResources::rootDir() / "../../src/Interface/Application/Resources/LegacyModuleImporter.xml" — a relative path assuming the test-data checkout sits two directories under the source root. In CI (SCIRunTestData cloned separately) this fails with "read error", causing all 15 LegacyNetworkFileImporterTests to skip. Worth flagging separately since it's a test-infra issue, not a code regression.


Bottom line: findings #1#3 are real regressions introduced by this modernization PR and should block merge until fixed; #4 is a pre-existing CI fragility. None of this shows up in the PR's check marks because of the blanket continue-on-error: true on every test step.

@dcwhite

dcwhite commented Jul 1, 2026

Copy link
Copy Markdown
Member

Found concrete crash details across the jobs. Here's the breakdown, grouped by root cause:

1. Missing switch case (dominant failure — ~870 test failures)

ConsoleCommandFactory.cc:43 has no case GlobalCommands::ImportNetworkFile:, unlike GuiCommandFactory.cc:57 which does. Every headless import test hits the default: throw immediately:

Critical error! Unhandled exception: Unknown global command type.

Affects linux-headless-regression, windows-headless-regression, all three mac-headless-*-slim jobs.

This I will fix so the import tests aren't making so much noise

2. Eigen upgrade broke tensor/matrix assumptions (real regressions from this PR's stated goal)

Three distinct crashes, all Eigen assertion failures that didn't fire before the version bump:

  • Core_Datatypes_Tests aborts on DyadicTensorTest.DifferentDimensionsNotEquivalent: Assertion failed: (dimensions_match(...)), TensorAssign.h:146 — the test intentionally compares mismatched-dimension tensors, but newer Eigen hard-asserts instead of the old graceful-failure path.
  • .Test.ExampleNetwork.negative_tensors_srn and negative_tensors_normals_deubg_srn abort: Assertion failed: (rows() == cols()), function inverse, InverseImpl.h:351 — some tensor-field module is calling .inverse() on a non-square matrix while processing real network data.
  • Algorithms_DataIO_Tests: WriteMatrixTest.CanPrintSparseMatrix fails (not crash) — sparse matrix's internal entry ordering changed ((1,0) (_,_) (-1.4,2) expected vs (1,0) (-1.4,2) (_,_) actual), consistent with Eigen changing SparseMatrix internal storage/compression behavior.

These three point at the same theme: code that relied on old Eigen internals/behavior needs updating for the new version, in the tensor and sparse-matrix code paths.

@jessdtate @basisunus A real regression from a library upgrade. Fix before merge or after?

3. Python embedding crash (also likely tied to the Python 3.13 bump in this PR)

Engine_Python_Tests aborts the whole process on its second test:

Fatal Python error: PyImport_AppendInittab: PyImport_AppendInittab() may not be called after Py_Initialize()

Something in the interpreter setup registers a module inittab entry per-test instead of once before Py_Initialize() — worked under the old Python version, fails now.

I already have a fix for this on another branch

4. Pre-existing fragile test path (probably unrelated to this PR)

LegacyNetworkFileImporterTests::SetUpTestSuite reads TestResources::rootDir() / "../../src/Interface/Application/Resources/LegacyModuleImporter.xml" — a relative path assuming the test-data checkout sits two directories under the source root. In CI (SCIRunTestData cloned separately) this fails with "read error", causing all 15 LegacyNetworkFileImporterTests to skip. Worth flagging separately since it's a test-infra issue, not a code regression.

Not sure about this one, will wait until 1 is fixed

Bottom line: findings #1#3 are real regressions introduced by this modernization PR and should block merge until fixed; #4 is a pre-existing CI fragility. None of this shows up in the PR's check marks because of the blanket continue-on-error: true on every test step.

Comment thread src/Interface/Application/SCIRunMainWindow.cc
Comment thread src/Interface/Application/GuiApplication.cc

@dcwhite dcwhite left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Phew!

@basisunus
basisunus merged commit dcbe7d9 into master Jul 3, 2026
38 of 39 checks passed
@basisunus
basisunus deleted the refactor branch July 3, 2026 01:45
dcwhite added a commit that referenced this pull request Jul 4, 2026
- Mark PR #2463 as merged (2026-07-03), note Intel Mac CI addition
- Fix OSPRay version: scirun-build-2.10 (not v2.10.1)
- Correct Qt note: 6.3.1+ and 6.10 known to work
- Add markdown formatting and table to dependencies.md
- Remove stale reference to refactor branch in how-to section

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants