fix(render): repaint on layer/property edits (#231)
Layer color/linetype/lineweight and MATCHPROP edits set the document dirty flag but never bumped geometry_epoch. The wire caches key on that epoch and bake a ByLayer entity's resolved color at tessellation time, so they returned stale wires until a new entity forced a rebuild. Bump geometry on those four handlers so the edit repaints immediately. Also remove REGEN/REGENALL/REDRAW/REDRWALL: the GPU raster pipeline keeps the display continuously in sync, so on-demand regen/redraw is a no-op concept in OCS. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
parent
a994a148fe
commit
f6a7b0885f
6 changed files with 29 additions and 12 deletions
|
|
@ -243,8 +243,6 @@ Status of every standard CAD command in Open CAD Studio:
|
|||
| `ZOOM` | Z | Zoom | ✅ |
|
||||
| `PAN` | P | Pan | ✅ |
|
||||
| `ORBIT` | 3DO | 3D orbit | ✅ |
|
||||
| `REGEN` | RE | Regenerate drawing | ✅ |
|
||||
| `REDRAW` | R | Redraw viewport | ✅ |
|
||||
| `VPORTS` | — | Viewport configuration | ✅ |
|
||||
| `VPJOIN` | — | Join viewports | ✅ |
|
||||
| `SYNCPVIEWPORTS` | VPSYNC | Sync viewport display settings | ✅ |
|
||||
|
|
|
|||
|
|
@ -764,6 +764,10 @@ impl OpenCADStudio {
|
|||
}
|
||||
}
|
||||
self.tabs[i].dirty = true;
|
||||
// Color / linetype / lineweight are baked into the cached
|
||||
// wires at tessellation time; bump the geometry epoch so the
|
||||
// matched objects repaint instead of holding their old look.
|
||||
self.tabs[i].scene.bump_geometry();
|
||||
self.refresh_properties();
|
||||
self.command_line
|
||||
.push_info(&format!("Properties matched to {} object(s).", dest.len()));
|
||||
|
|
|
|||
|
|
@ -3,12 +3,6 @@ use super::*;
|
|||
impl OpenCADStudio {
|
||||
pub(super) fn dispatch_display(&mut self, cmd: &str, i: usize) -> Option<Task<Message>> {
|
||||
match cmd {
|
||||
// ── Display refresh (no-op in GPU raster pipeline) ────────────────
|
||||
"REGEN" | "REGENALL" | "REDRAW" | "REDRWALL" => {
|
||||
// Display is always up-to-date in the GPU raster pipeline.
|
||||
self.command_line.push_output("Display regenerated.");
|
||||
}
|
||||
|
||||
// Interactive pan: left-drag pans the view until Esc. The only pan
|
||||
// path when there is no middle mouse button (trackpad / web).
|
||||
"PAN" | "P" => {
|
||||
|
|
|
|||
|
|
@ -511,10 +511,6 @@ inventory::submit!(crate::command::CommandRegistration {
|
|||
"QSELECT",
|
||||
"QUIT",
|
||||
"REDO",
|
||||
"REDRAW",
|
||||
"REDRWALL",
|
||||
"REGEN",
|
||||
"REGENALL",
|
||||
"RENAME",
|
||||
"REPORT",
|
||||
"SA",
|
||||
|
|
|
|||
|
|
@ -964,6 +964,10 @@ impl OpenCADStudio {
|
|||
pl.color = new_color;
|
||||
}
|
||||
self.tabs[i].dirty = true;
|
||||
// ByLayer color is baked into the cached wires at
|
||||
// tessellation time, so bump the geometry epoch to
|
||||
// invalidate the wire cache and repaint with the new color.
|
||||
self.tabs[i].scene.bump_geometry();
|
||||
}
|
||||
self.tabs[i].layers.color_picker_row = None;
|
||||
self.tabs[i].layers.color_full_palette = false;
|
||||
|
|
@ -984,6 +988,8 @@ impl OpenCADStudio {
|
|||
pl.linetype = lt;
|
||||
}
|
||||
self.tabs[i].dirty = true;
|
||||
// Linetype is baked into the cached wires; repaint.
|
||||
self.tabs[i].scene.bump_geometry();
|
||||
}
|
||||
}
|
||||
Task::none()
|
||||
|
|
@ -1001,6 +1007,8 @@ impl OpenCADStudio {
|
|||
pl.lineweight = lw;
|
||||
}
|
||||
self.tabs[i].dirty = true;
|
||||
// Lineweight is baked into the cached wires; repaint.
|
||||
self.tabs[i].scene.bump_geometry();
|
||||
}
|
||||
}
|
||||
Task::none()
|
||||
|
|
|
|||
|
|
@ -1148,6 +1148,23 @@ mod layer0_inherit_tests {
|
|||
assert_eq!(&c[..3], &ins[..3], "ByBlock child uses the insert's color");
|
||||
}
|
||||
|
||||
// A *top-level* (non-block-child) entity on layer 0 with ByLayer colour
|
||||
// resolves layer 0's own colour and follows it when the layer is recoloured.
|
||||
// Regression guard for the issue 231 layer-0 repaint path.
|
||||
#[test]
|
||||
fn toplevel_layer0_bylayer_follows_layer_color() {
|
||||
let mut d = doc();
|
||||
let e = child("0", Color::ByLayer);
|
||||
let before = render_style_for(&d, &e).0;
|
||||
if let Some(l) = d.layers.get_mut("0") {
|
||||
l.color = Color::Index(3); // recolour layer 0 -> green
|
||||
}
|
||||
let after = render_style_for(&d, &e).0;
|
||||
let green = tess_util::aci_to_rgba(&Color::Index(3));
|
||||
assert_eq!(&after[..3], &green[..3], "top-level layer-0 ByLayer must follow layer 0's colour");
|
||||
assert_ne!(&before[..3], &after[..3], "colour must change after recolour");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn explicit_color_wins_even_on_layer0() {
|
||||
let d = doc();
|
||||
|
|
|
|||
Loading…
Reference in a new issue