fix(hatch): follow block grip movement
This commit is contained in:
parent
c17e31c1ed
commit
c4c673336c
3 changed files with 79 additions and 9 deletions
|
|
@ -1026,6 +1026,61 @@ impl Scene {
|
||||||
hatch_bg: [f32; 4],
|
hatch_bg: [f32; 4],
|
||||||
tint_selected: bool,
|
tint_selected: bool,
|
||||||
frozen: Option<&rustc_hash::FxHashSet<Handle>>,
|
frozen: Option<&rustc_hash::FxHashSet<Handle>>,
|
||||||
|
) -> Vec<HatchModel> {
|
||||||
|
self.exploded_insert_hatch_models_filtered(
|
||||||
|
layout_block,
|
||||||
|
hatch_bg,
|
||||||
|
tint_selected,
|
||||||
|
frozen,
|
||||||
|
None,
|
||||||
|
false,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Build live hatch overlays for INSERT grip previews. The edited INSERT
|
||||||
|
/// is intentionally hidden from the resident scene while its current
|
||||||
|
/// document entity moves, so include that hidden target and reuse the full
|
||||||
|
/// block-expansion path for nested inserts, inherited styles and XCLIP.
|
||||||
|
pub(super) fn preview_insert_hatch_models(&self, handles: &[Handle]) -> Vec<HatchModel> {
|
||||||
|
let targets: rustc_hash::FxHashSet<Handle> = handles
|
||||||
|
.iter()
|
||||||
|
.copied()
|
||||||
|
.filter(|&handle| {
|
||||||
|
matches!(self.document.get_entity(handle), Some(EntityType::Insert(_)))
|
||||||
|
})
|
||||||
|
.collect();
|
||||||
|
if targets.is_empty() {
|
||||||
|
return Vec::new();
|
||||||
|
}
|
||||||
|
let hatch_bg = if self.current_layout != "Model" {
|
||||||
|
self.paper_bg_color
|
||||||
|
} else {
|
||||||
|
self.bg_color
|
||||||
|
};
|
||||||
|
let frozen: rustc_hash::FxHashSet<Handle> = self
|
||||||
|
.interaction_viewport_frozen_layers()
|
||||||
|
.into_iter()
|
||||||
|
.flatten()
|
||||||
|
.copied()
|
||||||
|
.collect();
|
||||||
|
self.exploded_insert_hatch_models_filtered(
|
||||||
|
self.interaction_block_handle(),
|
||||||
|
hatch_bg,
|
||||||
|
true,
|
||||||
|
(!frozen.is_empty()).then_some(&frozen),
|
||||||
|
Some(&targets),
|
||||||
|
true,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn exploded_insert_hatch_models_filtered(
|
||||||
|
&self,
|
||||||
|
layout_block: Handle,
|
||||||
|
hatch_bg: [f32; 4],
|
||||||
|
tint_selected: bool,
|
||||||
|
frozen: Option<&rustc_hash::FxHashSet<Handle>>,
|
||||||
|
targets: Option<&rustc_hash::FxHashSet<Handle>>,
|
||||||
|
include_preview_hidden: bool,
|
||||||
) -> Vec<HatchModel> {
|
) -> Vec<HatchModel> {
|
||||||
let layer_hidden = |layer: &str| {
|
let layer_hidden = |layer: &str| {
|
||||||
self.document
|
self.document
|
||||||
|
|
@ -1117,8 +1172,13 @@ impl Scene {
|
||||||
let EntityType::Insert(ins) = contextual.as_ref() else {
|
let EntityType::Insert(ins) = contextual.as_ref() else {
|
||||||
continue;
|
continue;
|
||||||
};
|
};
|
||||||
|
if targets.is_some_and(|targets| !targets.contains(&ins.common.handle)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
let temporarily_hidden = self.object_isolation.hides(ins.common.handle)
|
||||||
|
|| (!include_preview_hidden && self.preview_hidden.contains(&ins.common.handle));
|
||||||
if ins.common.invisible
|
if ins.common.invisible
|
||||||
|| self.entity_temporarily_hidden(ins.common.handle)
|
|| temporarily_hidden
|
||||||
|| layer_hidden(&ins.common.layer)
|
|| layer_hidden(&ins.common.layer)
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
|
|
|
||||||
|
|
@ -5104,14 +5104,19 @@ impl Scene {
|
||||||
let cache = self.hatch_cache.borrow();
|
let cache = self.hatch_cache.borrow();
|
||||||
match cache.get(&space) {
|
match cache.get(&space) {
|
||||||
// Selection tint is baked in, so the selected set must also
|
// Selection tint is baked in, so the selected set must also
|
||||||
// match; category = a changed handle that is a hatch/solid fill.
|
// match; category = a changed direct fill or an INSERT
|
||||||
|
// whose expanded block tree can contain hatch fills.
|
||||||
Some((cached_epoch, cached_sel, arc))
|
Some((cached_epoch, cached_sel, arc))
|
||||||
if *cached_sel == sel_sig
|
if *cached_sel == sel_sig
|
||||||
&& self.category_cache_valid(
|
&& self.category_cache_valid(
|
||||||
*cached_epoch,
|
*cached_epoch,
|
||||||
CACHE_CATEGORY_HATCH,
|
CACHE_CATEGORY_HATCH | CACHE_CATEGORY_INSERT_HATCH,
|
||||||
|h| {
|
|h| {
|
||||||
self.hatches.contains_key(&h)
|
self.hatches.contains_key(&h)
|
||||||
|
|| matches!(
|
||||||
|
self.document.get_entity(h),
|
||||||
|
Some(EntityType::Insert(_))
|
||||||
|
)
|
||||||
},
|
},
|
||||||
) =>
|
) =>
|
||||||
{
|
{
|
||||||
|
|
@ -5149,11 +5154,12 @@ impl Scene {
|
||||||
fn selected_hatch_sig(&self) -> u64 {
|
fn selected_hatch_sig(&self) -> u64 {
|
||||||
let mut sig = 0u64;
|
let mut sig = 0u64;
|
||||||
let mut count = 0u64;
|
let mut count = 0u64;
|
||||||
for h in self
|
for &h in &self.selected {
|
||||||
.selected
|
if !self.hatches.contains_key(&h)
|
||||||
.iter()
|
&& !matches!(self.document.get_entity(h), Some(EntityType::Insert(_)))
|
||||||
.filter(|handle| self.hatches.contains_key(handle))
|
{
|
||||||
{
|
continue;
|
||||||
|
}
|
||||||
count += 1;
|
count += 1;
|
||||||
sig ^= h.value().wrapping_mul(0x9E37_79B9_7F4A_7C15);
|
sig ^= h.value().wrapping_mul(0x9E37_79B9_7F4A_7C15);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -18,8 +18,12 @@ impl Scene {
|
||||||
pub fn set_preview_hatches(&mut self, handles: &[Handle]) {
|
pub fn set_preview_hatches(&mut self, handles: &[Handle]) {
|
||||||
let mut models = Vec::new();
|
let mut models = Vec::new();
|
||||||
for &handle in handles {
|
for &handle in handles {
|
||||||
|
// Keep the existing direct Hatch/Solid preview path. INSERT has no
|
||||||
|
// entry in `self.hatches`, so this is a no-op for it and the full
|
||||||
|
// block expansion below supplies its fills.
|
||||||
self.append_preview_hatch(handle, &mut models);
|
self.append_preview_hatch(handle, &mut models);
|
||||||
}
|
}
|
||||||
|
models.extend(self.preview_insert_hatch_models(handles));
|
||||||
self.preview_hatches = std::sync::Arc::new(models);
|
self.preview_hatches = std::sync::Arc::new(models);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue