forked from 1b-agent/opencadstudio-upstream
fix(viewport): apply per-viewport layer freeze to fills, images and meshes
A content viewport that froze layers still drew those layers' hatches, 2-D solids, images, OLE frames and 3-D solids — only its wires honoured `Viewport.frozen_layers`. A viewport meant to be empty (all content layers frozen) leaked the whole model instead. viewport_data_for fed content viewports the full model hatch/wipeout/ image/mesh sets with no per-viewport frozen filter. Thread the viewport's frozen-layer set through the builders (synced_hatch_models, exploded_insert_hatch_models, wipeout_models, image_models, mesh_models, instanced_block_meshes) via Scene::layer_frozen_in — the same layer-name→handle→membership test the wire path uses — and expose *_for_viewport accessors that cache the filtered set per order-independent frozen-set signature (viewports sharing a frozen set share the build; an empty set returns the shared unfiltered arc, so model tiles and non-freezing viewports are byte-identical). Each viewport renders in its own pipeline slot with the hatch upload gated on geometry_epoch, so a per-viewport filtered set uploads once per epoch rather than every frame. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
1 parent
fd33810057
commit
b884e33f38
4 files changed
+222
-28
No files matched your search
+25
-3
@@ -568,7 +568,10 @@ impl Scene {
|
||||
self.bump_geometry();
|
||||
}
|
||||
|
||||
pub(super) fn synced_hatch_models(&self) -> Vec<HatchModel> {
|
||||
pub(super) fn synced_hatch_models(
|
||||
&self,
|
||||
frozen: Option<&rustc_hash::FxHashSet<Handle>>,
|
||||
) -> Vec<HatchModel> {
|
||||
let layout_block = self.current_layout_block_handle();
|
||||
|
||||
let layer_hidden = |layer: &str| {
|
||||
@@ -606,6 +609,11 @@ impl Scene {
|
||||
if c.invisible || layer_hidden(&c.layer) {
|
||||
return false;
|
||||
}
|
||||
// Per-viewport layer freeze: a content viewport that freezes
|
||||
// this layer hides its fills too, not just its wires.
|
||||
if self.layer_frozen_in(&c.layer, frozen) {
|
||||
return false;
|
||||
}
|
||||
// Reject block-defn-only hatches (entities owned by a
|
||||
// BLOCK record that's neither model nor a paper layout
|
||||
// block) — they're tessellated separately via Insert
|
||||
@@ -686,7 +694,7 @@ impl Scene {
|
||||
// layout block and materialize its fills at world position. Shared with
|
||||
// the export path so a plot draws them identically. (tint_selected =
|
||||
// true applies the screen selection highlight.)
|
||||
models.extend(self.exploded_insert_hatch_models(layout_block, hatch_bg, true));
|
||||
models.extend(self.exploded_insert_hatch_models(layout_block, hatch_bg, true, frozen));
|
||||
|
||||
// Wide LwPolyline / Polyline2D bands are no longer hatch fills at
|
||||
// model level: a flat band is drawn by expanding its centre-line wire
|
||||
@@ -717,6 +725,7 @@ impl Scene {
|
||||
layout_block: Handle,
|
||||
hatch_bg: [f32; 4],
|
||||
tint_selected: bool,
|
||||
frozen: Option<&rustc_hash::FxHashSet<Handle>>,
|
||||
) -> Vec<HatchModel> {
|
||||
let layer_hidden = |layer: &str| {
|
||||
self.document
|
||||
@@ -748,6 +757,11 @@ impl Scene {
|
||||
if ins.common.invisible || layer_hidden(&ins.common.layer) {
|
||||
continue;
|
||||
}
|
||||
// Per-viewport freeze: an INSERT on a layer frozen in this content
|
||||
// viewport hides the whole instance, its internal fills included.
|
||||
if self.layer_frozen_in(&ins.common.layer, frozen) {
|
||||
continue;
|
||||
}
|
||||
if !self.belongs_to_visible_block(
|
||||
ins.common.handle,
|
||||
ins.common.owner_handle,
|
||||
@@ -880,7 +894,10 @@ impl Scene {
|
||||
|
||||
/// Wipeout fill models — rendered in a separate pass AFTER wires so that
|
||||
/// wipeouts correctly mask everything below them in the draw order.
|
||||
pub(crate) fn wipeout_models(&self) -> Vec<HatchModel> {
|
||||
pub(crate) fn wipeout_models(
|
||||
&self,
|
||||
frozen: Option<&rustc_hash::FxHashSet<Handle>>,
|
||||
) -> Vec<HatchModel> {
|
||||
let is_paper = self.current_layout != "Model";
|
||||
let bg_color: [f32; 4] = if is_paper {
|
||||
self.paper_bg_color
|
||||
@@ -910,6 +927,11 @@ impl Scene {
|
||||
{
|
||||
continue;
|
||||
}
|
||||
// Per-viewport freeze: a wipeout on a layer frozen in this content
|
||||
// viewport is hidden along with the rest of that layer.
|
||||
if self.layer_frozen_in(&entity.common().layer, frozen) {
|
||||
continue;
|
||||
}
|
||||
// Per-entity world_offset selection so paper-layout content
|
||||
// viewports still see model-block wipeouts at the right local
|
||||
// coordinates (same rationale as hatches).
|
||||
|
||||
Reference in new issue
Block a user