fix(xref): preserve layer-zero colors
Treat namespaced XREF layer |0 as layer zero during block inheritance so ByLayer geometry keeps its source color.\n\nCloses #437
This commit is contained in:
parent
a0558e187c
commit
7a1c0ead0d
5 changed files with 32 additions and 14 deletions
7
src/scene/cache/block_cache.rs
vendored
7
src/scene/cache/block_cache.rs
vendored
|
|
@ -531,7 +531,9 @@ fn build_nested_ref(
|
|||
nested_ins.common.line_weight,
|
||||
LineWeight::ByLayer | LineWeight::Default
|
||||
),
|
||||
layer_is_zero: nested_ins.common.layer == "0",
|
||||
layer_is_zero: crate::scene::view::render::is_effective_layer_zero(
|
||||
&nested_ins.common.layer,
|
||||
),
|
||||
l0,
|
||||
instance_offsets: array_offsets(nested_ins),
|
||||
clip_poly,
|
||||
|
|
@ -572,7 +574,7 @@ fn tessellate_sub_local(
|
|||
// Layer-0 rule: a child on layer "0" with ByLayer properties inherits the
|
||||
// INSERT's layer at expand time. Flag each ByLayer property so emit_wire
|
||||
// can override the cached (layer-0-resolved) value with the insert layer's.
|
||||
let on_l0 = sub.common().layer == "0";
|
||||
let on_l0 = crate::scene::view::render::is_effective_layer_zero(&sub.common().layer);
|
||||
let color_l0 = on_l0 && sub.common().color == AcadColor::ByLayer;
|
||||
let lt_l0 = on_l0 && {
|
||||
let lt = &sub.common().linetype;
|
||||
|
|
@ -1649,4 +1651,3 @@ fn array_offsets(ins: &acadrust::entities::Insert) -> Vec<[f64; 3]> {
|
|||
}
|
||||
offsets
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -756,7 +756,8 @@ pub(crate) fn tessellate_entity(
|
|||
// they should inherit from the Dimension entity.
|
||||
let sub_color_is_byblock =
|
||||
sub.common().color == acadrust::types::Color::ByBlock;
|
||||
let sub_is_l0_bylayer = sub.common().layer == "0"
|
||||
let sub_is_l0_bylayer =
|
||||
view::render::is_effective_layer_zero(&sub.common().layer)
|
||||
&& sub.common().color == acadrust::types::Color::ByLayer;
|
||||
let sub_wires = tessellate_entity(
|
||||
document,
|
||||
|
|
@ -909,7 +910,8 @@ pub(crate) fn tessellate_entity(
|
|||
};
|
||||
let sub_color_is_byblock =
|
||||
sub.common().color == acadrust::types::Color::ByBlock;
|
||||
let sub_is_l0_bylayer = sub.common().layer == "0"
|
||||
let sub_is_l0_bylayer =
|
||||
view::render::is_effective_layer_zero(&sub.common().layer)
|
||||
&& sub.common().color == acadrust::types::Color::ByLayer;
|
||||
let mut placed = sub.clone();
|
||||
{
|
||||
|
|
|
|||
|
|
@ -983,11 +983,12 @@ impl Scene {
|
|||
// mirroring expand_insert's nested resolution: ByBlock →
|
||||
// parent source; layer-0 + ByLayer → parent layer-0
|
||||
// target; else the nested insert's own resolved style.
|
||||
let on_l0 = crate::scene::view::render::is_effective_layer_zero(
|
||||
&nins.common.layer,
|
||||
);
|
||||
let child_ins_color = if nins.common.color == Color::ByBlock {
|
||||
sub_ins_color
|
||||
} else if nins.common.layer == "0"
|
||||
&& nins.common.color == Color::ByLayer
|
||||
{
|
||||
} else if on_l0 && nins.common.color == Color::ByLayer {
|
||||
sub_l0.color
|
||||
} else {
|
||||
crate::scene::view::render::render_style_for(
|
||||
|
|
@ -996,7 +997,7 @@ impl Scene {
|
|||
)
|
||||
.0
|
||||
};
|
||||
let child_l0 = if nins.common.layer == "0" {
|
||||
let child_l0 = if on_l0 {
|
||||
sub_l0
|
||||
} else {
|
||||
crate::scene::view::render::layer_render_style(
|
||||
|
|
|
|||
|
|
@ -3973,9 +3973,11 @@ impl Scene {
|
|||
) -> ([f32; 4], [f32; 4]) {
|
||||
use acadrust::types::Color;
|
||||
let bg = self.current_bg();
|
||||
let on_l0 =
|
||||
crate::scene::view::render::is_effective_layer_zero(&ins.common.layer);
|
||||
let child_ins_color = if ins.common.color == Color::ByBlock {
|
||||
parent_ins_color
|
||||
} else if ins.common.layer == "0" && ins.common.color == Color::ByLayer {
|
||||
} else if on_l0 && ins.common.color == Color::ByLayer {
|
||||
parent_l0
|
||||
} else {
|
||||
crate::scene::view::render::adapt_to_bg(
|
||||
|
|
@ -3987,7 +3989,7 @@ impl Scene {
|
|||
bg,
|
||||
)
|
||||
};
|
||||
let child_l0 = if ins.common.layer == "0" {
|
||||
let child_l0 = if on_l0 {
|
||||
parent_l0
|
||||
} else {
|
||||
crate::scene::view::render::adapt_to_bg(
|
||||
|
|
@ -4013,9 +4015,10 @@ impl Scene {
|
|||
let (ins_color, l0_color) = inherit?;
|
||||
use acadrust::types::Color;
|
||||
let common = e.common();
|
||||
let on_l0 = crate::scene::view::render::is_effective_layer_zero(&common.layer);
|
||||
let mut c = if common.color == Color::ByBlock {
|
||||
ins_color
|
||||
} else if common.layer == "0" && common.color == Color::ByLayer {
|
||||
} else if on_l0 && common.color == Color::ByLayer {
|
||||
// Inherit the insert layer's RGB but keep the solid's own alpha,
|
||||
// matching the wire/hatch path (render_style_for_block_sub).
|
||||
[l0_color[0], l0_color[1], l0_color[2], own_alpha]
|
||||
|
|
@ -5650,4 +5653,3 @@ mod delta_undo_tests {
|
|||
assert_eq!(ms_occurrences(&scene, copy_h), 1);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -918,6 +918,18 @@ pub(crate) fn layer_render_style(document: &CadDocument, layer_name: &str) -> In
|
|||
}
|
||||
}
|
||||
|
||||
/// Whether a block child uses layer-0 inheritance semantics.
|
||||
///
|
||||
/// XREF merge keeps dependent layers distinct by namespacing them as
|
||||
/// `xref|layer`; its source layer `0` therefore becomes `xref|0` but must still
|
||||
/// inherit through the containing INSERT exactly like an unprefixed layer 0.
|
||||
pub(crate) fn is_effective_layer_zero(layer_name: &str) -> bool {
|
||||
layer_name.eq_ignore_ascii_case("0")
|
||||
|| layer_name
|
||||
.rsplit_once('|')
|
||||
.is_some_and(|(_, dependent)| dependent.eq_ignore_ascii_case("0"))
|
||||
}
|
||||
|
||||
/// Like `render_style_for` but resolves a block sub-entity's inherited
|
||||
/// properties: ByBlock inherits the INSERT's style, and (the layer-0 rule) a
|
||||
/// sub-entity on layer "0" with ByLayer properties inherits the INSERT's
|
||||
|
|
@ -934,7 +946,7 @@ pub(crate) fn render_style_for_block_sub(
|
|||
) -> ([f32; 4], f32, [f32; 8], f32, u8) {
|
||||
let (color, pat_len, pat, lw_px, aci) = render_style_for(document, e);
|
||||
let common = e.common();
|
||||
let on_l0 = common.layer == "0";
|
||||
let on_l0 = is_effective_layer_zero(&common.layer);
|
||||
|
||||
let final_color = if common.color == AcadColor::ByBlock {
|
||||
insert_color
|
||||
|
|
|
|||
Loading…
Reference in a new issue