Skip to content

fix: close color painting gizmo before batch match apply - #950

Closed
wudi901 wants to merge 1 commit into
Snapmaker:build_platform_engineeringfrom
wudi901:codex/fix-batch-match-painting-gizmo-cache
Closed

wudi901 wants to merge 1 commit into
Snapmaker:build_platform_engineeringfrom
wudi901:codex/fix-batch-match-painting-gizmo-cache

Conversation

@wudi901

@wudi901 wudi901 commented Sep 30, 2026 •

Copy link
Copy Markdown

Description

Batch color-mix match rewrites painted extruder ids directly in the model (apply_batch_match_to_model + cleanup_unused_filaments_after_batch_match). While the Color Painting gizmo is open it keeps its own editing copy of that painting data in m_triangle_selectors, and its data_changed() only reloads the selectors when the extruder count changes — a same-count palette rewrite takes the colors-only branch and keeps stale facet→extruder assignments. Two consequences:

  • with the painting panel open, the applied match rendered wrong (gizmo renders from its stale copy), and
  • any subsequent stroke/gap-fill/erase-all committed via update_model_object() wrote the stale copy back over the applied match (durable corruption).

Fix: after the match apply finishes (model is final), force a re-deserialize of the gizmo's editing copy from the model via the new GLGizmoMmuSegmentation::refresh_from_model() (init_extruders_data() + init_model_triangle_selectors() — the same reload pairing data_changed() already uses on count changes). The panel stays open and the user's selected filament is preserved when possible.

Both canvases are covered (3D view and assemble view each own a GLGizmosManager instance); the call is a no-op where the gizmo is not active.

Screenshots/Recordings/Graphs

UI behavior change only (open painting panel now re-syncs in place instead of showing stale data); no visual layout change to capture.

Tests

Manual verification steps (wx UI event-loop path, not unit-testable):

  1. Open the Color Painting gizmo, paint multiple colors, then run Color Mixing Match and confirm the match.
    • Expected: the painting panel stays open and the 3D view immediately shows the matched palette/mapping (no stale colors).
  2. With the panel still open, paint one more stroke, then close/reopen the gizmo.
    • Expected: the stroke applies on top of the matched mapping and survives (no stale write-back).
  3. Regression: run Color Mixing Match with the painting gizmo closed.
    • Expected: behavior unchanged.
  4. Repeat step 1 in the assemble view.
    • Expected: same correct re-sync on the assemble canvas.

@wudi901
wudi901 changed the base branch from main to build_platform_engineering September 30, 2026 07:53

@wudi901 wudi901 left a comment

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Self-review (REQUEST_CHANGES-equivalent — 1 blocking finding)

Scope: 1 commit, +13 in src/slic3r/GUI/Plater.cpp (base build_platform_engineering, 0 behind base).

Verified correct:

  • Placement: after result.success, before any palette/filament/painting mutation — gizmo cache is dropped before the model rewrite.
  • reset_all_states() on gizmo Off clears m_triangle_selectors without writing back — no new overwrite risk.
  • API usage mirrors existing compiled call sites (Plater.cpp ~L16900 same chain; GUI_ObjectList.cpp ~L1457 same manager pattern); 140-col limit respected; comment explains WHY.

Blocking (P2) — see inline comment: guard only checks the 3D-view canvas manager. Each canvas owns its own GLGizmosManager; painter gizmos support the assemble view (CanvasAssembleView branches in GLGizmoPainterBase.cpp:100/147/312; accessor Plater::get_assmeble_canvas3D() at Plater.hpp:693). If Color Painting is active on the assemble canvas, the stale-cache bug survives. Reset both managers — reset_all_states() is a no-op when nothing is active there.

Process note: no CI ran for this fork PR (0 check-runs on head SHA); full Windows build not run in the review sandbox. Compile risk minimal (mirrored patterns), but tick CI / local build_release_vs2022.bat before merge.

Comment thread src/slic3r/GUI/Plater.cpp Outdated
// over the applied match. Close it before mutating the model so the
// model stays the single source of truth (same reset pattern the
// object-list color-paint toggle uses).
GLGizmosManager& gizmos_mgr = wxGetApp().plater()->get_view3D_canvas3D()->get_gizmos_manager();

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

[P2] Assemble-view painting gizmo is not covered by this guard.

Only get_view3D_canvas3D()->get_gizmos_manager() is checked, but every canvas owns its own GLGizmosManager and painter gizmos explicitly support the assemble view (CanvasAssembleView branches in src/slic3r/GUI/Gizmos/GLGizmoPainterBase.cpp:100/147/312, accessor Plater::get_assmeble_canvas3D() at src/slic3r/GUI/Plater.hpp:693). If Color Painting is open on the assemble canvas when the match is applied, its m_triangle_selectors cache stays stale — the exact bug this PR fixes, on the other canvas.

Suggested fix (no-op when nothing is active on that manager):

Plater* batch_plater = wxGetApp().plater();
for (GLCanvas3D* cnv : { batch_plater->get_view3D_canvas3D(), batch_plater->get_assmeble_canvas3D() }) {
    if (cnv == nullptr) continue;
    GLGizmosManager& gizmos_mgr = cnv->get_gizmos_manager();
    if (gizmos_mgr.get_current_type() == GLGizmosManager::EType::MmSegmentation)
        gizmos_mgr.reset_all_states();
}

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Addressed in e96f1c9 — approach switched from closing the gizmo to re-deserializing its editing copy from the final model state:

  • New public GLGizmoMmuSegmentation::refresh_from_model() calls init_extruders_data() + init_model_triangle_selectors() — the same reload pairing data_changed() already uses on count changes, but unconditional, so same-count rewrites also re-sync.
  • Called after cleanup_unused_filaments_after_batch_match() (model final), before the final canvas/panel refreshes.
  • Both canvases covered (3D view + assemble view each own a GLGizmosManager), no-op where the gizmo isn't active — this also fixes the assemble-view gap raised here.
  • UX preserved: the painting panel stays open; the selected filament is kept when still present.

@wudi901
wudi901 force-pushed the codex/fix-batch-match-painting-gizmo-cache branch from 6c06e81 to e96f1c9 Compare September 30, 2026 09:24
@zhangzhend0ng
zhangzhend0ng deleted the branch Snapmaker:build_platform_engineering September 30, 2026 10:06
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants