forked from 1b-agent/opencadstudio-upstream
Merge pull request #842 from gianlucafiore/feat/non-printing-layer
This commit is contained in:
commit
6c4f769d61
11 files changed
+317
-18
No files matched your search
@@ -2013,6 +2013,7 @@ pub enum Message {
|
||||
LayerToggleVisible(usize),
|
||||
LayerToggleLock(usize),
|
||||
LayerToggleFreeze(usize),
|
||||
LayerTogglePlot(usize),
|
||||
/// Sort the Layer Manager table by a clicked column header.
|
||||
LayerSort(crate::ui::window::layers::LayerSortCol),
|
||||
/// Toggle per-viewport freeze: (layer_index, vp_col_index)
|
||||
|
||||
@@ -171,8 +171,8 @@ fn plot_scene_content(
|
||||
let (mut paper_wires, mut model_wires) = scene.plot_wire_groups(render_mode_override);
|
||||
paper_wires.retain(|wire| wire.plot_visible);
|
||||
model_wires.retain(|wire| wire.plot_visible);
|
||||
let paper_hatches = scene.paper_canvas_hatches().as_ref().clone();
|
||||
let paper_wipeouts = scene.paper_canvas_wipeouts().as_ref().clone();
|
||||
let paper_hatches = scene.paper_plot_hatches().as_ref().clone();
|
||||
let paper_wipeouts = scene.paper_plot_wipeouts().as_ref().clone();
|
||||
if scene.current_layout == "Model" {
|
||||
let splits = crate::io::pdf_export::PlotGroupSplits {
|
||||
wires: paper_wires.len(),
|
||||
|
||||
@@ -2427,6 +2427,58 @@ impl OpenCADStudio {
|
||||
}
|
||||
Task::none()
|
||||
}
|
||||
Message::LayerTogglePlot(idx) => {
|
||||
let i = self.active_tab;
|
||||
|
||||
let plottable = self.tabs[i]
|
||||
.layers
|
||||
.layers
|
||||
.get(idx)
|
||||
.map(|layer| !layer.plottable);
|
||||
|
||||
let targets = self.layer_row_action_targets(i, idx);
|
||||
|
||||
if let Some(plottable) = plottable {
|
||||
if !targets.is_empty() {
|
||||
let undo = self.begin_layer_undo(i, "LAYER PLOT/NOPLOT", &targets);
|
||||
|
||||
for name in &targets {
|
||||
if let Some(layer) = self.tabs[i].scene.document.layers.get_mut(name) {
|
||||
layer.is_plottable = plottable;
|
||||
}
|
||||
|
||||
if let Some(layer) = self.tabs[i]
|
||||
.layers
|
||||
.layers
|
||||
.iter_mut()
|
||||
.find(|layer| &layer.name == name)
|
||||
{
|
||||
layer.plottable = plottable;
|
||||
}
|
||||
}
|
||||
|
||||
self.tabs[i].layers.refresh_sort();
|
||||
|
||||
self.tabs[i]
|
||||
.scene
|
||||
.invalidate_layer_dependencies(&targets);
|
||||
|
||||
self.tabs[i].dirty = true;
|
||||
self.commit_layer_undo(i, undo);
|
||||
|
||||
self.command_line.push_output(
|
||||
crate::tf!(
|
||||
"{} layer(s) set to {}",
|
||||
targets.len(),
|
||||
if plottable { "Plot" } else { "No Plot" }
|
||||
)
|
||||
.as_ref(),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Task::none()
|
||||
},
|
||||
|
||||
Message::LayerToggleVpFreeze(layer_idx, vp_col_idx) => {
|
||||
self.on_layer_toggle_vp_freeze(layer_idx, vp_col_idx)
|
||||
|
||||
+14
-5
@@ -196,6 +196,7 @@ pub(crate) fn append_insert_attribute_wires(
|
||||
ins_pat: [f32; 8],
|
||||
ins_lw_px: f32,
|
||||
ins_layer: render::InheritStyle,
|
||||
ins_layer_plottable: bool,
|
||||
bg_color: [f32; 4],
|
||||
is_xref: bool,
|
||||
pslt_factor: f32,
|
||||
@@ -212,11 +213,8 @@ pub(crate) fn append_insert_attribute_wires(
|
||||
if attmode == 0 {
|
||||
return;
|
||||
}
|
||||
// An annotative block scales as ONE uniform unit about its insertion point;
|
||||
// its attributes are carried by that scale (AutoCAD even forbids annotative
|
||||
// attributes inside annotative blocks, to avoid double-scaling). So pre-scale
|
||||
// the annotative attribute about the insertion point and tessellate it at a
|
||||
// neutral 1.0 — the text path must never scale it a second time.
|
||||
// Attributes inherit the annotative block scale. Pre-scale them here so
|
||||
// text tessellation stays at a neutral scale.
|
||||
let annotative = ins
|
||||
.common
|
||||
.extended_data
|
||||
@@ -260,6 +258,16 @@ pub(crate) fn append_insert_attribute_wires(
|
||||
} else {
|
||||
sub_color
|
||||
};
|
||||
let attr_plottable = if render::is_effective_layer_zero(&attr.common.layer) {
|
||||
ins_layer_plottable
|
||||
} else {
|
||||
document
|
||||
.layers
|
||||
.get(&attr.common.layer)
|
||||
.map(|layer| layer.is_plottable)
|
||||
.unwrap_or(true)
|
||||
};
|
||||
let attr_plottable = ins_layer_plottable && attr_plottable;
|
||||
let sub_aabb = crate::scene::entity_aabb(&attr_entity);
|
||||
let mut attr_wires = tessellate::tessellate(
|
||||
document,
|
||||
@@ -284,6 +292,7 @@ pub(crate) fn append_insert_attribute_wires(
|
||||
w.name = insert_handle.value().to_string();
|
||||
w.aci = sub_aci;
|
||||
w.aabb = sub_aabb;
|
||||
w.plot_visible &= attr_plottable;
|
||||
}
|
||||
wires.extend(attr_wires);
|
||||
}
|
||||
|
||||
Vendored
+54
-4
@@ -74,6 +74,7 @@ pub struct LocalWire {
|
||||
pub world_width: f32,
|
||||
pub plinegen: bool,
|
||||
pub plot_visible: bool,
|
||||
pub plot_l0: bool,
|
||||
pub hide_unselected: bool,
|
||||
/// Set at construction; used to discriminate fill-only GPU batches from
|
||||
/// stroke batches in [`StyleKey`]. Derived from
|
||||
@@ -108,6 +109,8 @@ pub struct NestedRef {
|
||||
pub xform: Transform,
|
||||
pub style: crate::scene::render_graph::InsertStyleSpec,
|
||||
pub instance_offsets: Vec<[f64; 3]>,
|
||||
pub plot_visible: bool,
|
||||
pub plot_l0: bool,
|
||||
/// XCLIP boundary for this nested insert, in the parent defn's local frame
|
||||
/// (`None` = unclipped). Baked at build time because the clip's spatial
|
||||
/// filter lives in `doc.objects`, which isn't reachable at expand time; on
|
||||
@@ -520,6 +523,14 @@ fn build_defn(
|
||||
if let Some(record) = baked.filter(|record| {
|
||||
!record.entity_handles.is_empty()
|
||||
}) {
|
||||
let table_plot_l0 = crate::scene::view::render::is_effective_layer_zero(
|
||||
&table.common.layer,
|
||||
);
|
||||
let table_plot_visible = doc
|
||||
.layers
|
||||
.get(&table.common.layer)
|
||||
.map(|layer| layer.is_plottable)
|
||||
.unwrap_or(true);
|
||||
let mut insert = acadrust::entities::Insert::new(
|
||||
record.name.clone(),
|
||||
table.insertion_point,
|
||||
@@ -544,7 +555,7 @@ fn build_defn(
|
||||
|leaf, context| {
|
||||
let mut placed = leaf.clone();
|
||||
placed.apply_transform(&context.transform);
|
||||
for wire in tessellate_sub_local(
|
||||
for mut wire in tessellate_sub_local(
|
||||
doc,
|
||||
&placed,
|
||||
anno_scale,
|
||||
@@ -553,6 +564,8 @@ fn build_defn(
|
||||
viewport,
|
||||
depth_map,
|
||||
) {
|
||||
wire.plot_visible &= table_plot_l0 || table_plot_visible;
|
||||
wire.plot_l0 |= table_plot_l0;
|
||||
subs.push(LocalSub::Wire(wire));
|
||||
}
|
||||
},
|
||||
@@ -628,12 +641,22 @@ fn build_nested_ref(
|
||||
.map(|filter| {
|
||||
crate::scene::pick::xclip::world_clip_polygon_for_transform(filter, &xform)
|
||||
});
|
||||
let plot_l0 = crate::scene::view::render::is_effective_layer_zero(
|
||||
&nested_ins.common.layer,
|
||||
);
|
||||
let plot_visible = doc
|
||||
.layers
|
||||
.get(&nested_ins.common.layer)
|
||||
.map(|layer| layer.is_plottable)
|
||||
.unwrap_or(true);
|
||||
|
||||
NestedRef {
|
||||
block_name: nested_ins.block_name.clone(),
|
||||
xform,
|
||||
style: crate::scene::render_graph::InsertStyleSpec::new(doc, nested_ins, viewport),
|
||||
instance_offsets: crate::scene::render_graph::array_offsets(nested_ins),
|
||||
plot_visible,
|
||||
plot_l0,
|
||||
clip_poly,
|
||||
local_rank: depth_map
|
||||
.get(&nested_ins.common.handle.value())
|
||||
@@ -679,6 +702,11 @@ fn tessellate_sub_local(
|
||||
// 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 = crate::scene::view::render::is_effective_layer_zero(&sub.common().layer);
|
||||
let layer_plottable = doc
|
||||
.layers
|
||||
.get(&sub.common().layer)
|
||||
.map(|layer| layer.is_plottable)
|
||||
.unwrap_or(true);
|
||||
let color_l0 =
|
||||
!has_book_color && on_l0 && sub.common().color == AcadColor::ByLayer;
|
||||
let transparency_l0 = on_l0 && sub.common().transparency.alpha() == 0;
|
||||
@@ -808,7 +836,9 @@ fn tessellate_sub_local(
|
||||
line_weight_px: lw_px,
|
||||
world_width: wire.world_width,
|
||||
plinegen: wire.plinegen,
|
||||
plot_visible: frame_mode.is_none_or(|mode| mode == 1),
|
||||
plot_visible: frame_mode.is_none_or(|mode| mode == 1)
|
||||
&& (on_l0 || layer_plottable),
|
||||
plot_l0: on_l0,
|
||||
hide_unselected: frame_mode == Some(0),
|
||||
is_fill_only,
|
||||
color_is_byblock: color_is_byblock && wire_on_base_color,
|
||||
@@ -921,6 +951,7 @@ pub fn expand_insert(
|
||||
// The INSERT's own layer style — layer-0 inheritance target for children.
|
||||
ins_layer: crate::scene::view::render::InheritStyle,
|
||||
ins_layer_aci: u8,
|
||||
ins_layer_plottable: bool,
|
||||
selected: bool,
|
||||
pslt_factor: f32,
|
||||
// World-space XY view AABB (with world_offset already subtracted, so the
|
||||
@@ -972,6 +1003,7 @@ pub fn expand_insert(
|
||||
ins_pat,
|
||||
ins_lw_px,
|
||||
ins_layer,
|
||||
ins_layer_plottable,
|
||||
selected,
|
||||
pslt_factor,
|
||||
is_xref,
|
||||
@@ -1051,6 +1083,8 @@ pub fn expand_insert(
|
||||
ins_lw_px,
|
||||
l0: ins_layer,
|
||||
l0_aci: ins_layer_aci,
|
||||
l0_plottable: ins_layer_plottable,
|
||||
plot_visible: ins_layer_plottable,
|
||||
selected,
|
||||
pslt_factor,
|
||||
view_aabb: None,
|
||||
@@ -1154,6 +1188,7 @@ fn expansion_prototype_key(
|
||||
ins_pat: [f32; 8],
|
||||
ins_lw_px: f32,
|
||||
ins_layer: crate::scene::view::render::InheritStyle,
|
||||
ins_layer_plottable: bool,
|
||||
selected: bool,
|
||||
pslt_factor: f32,
|
||||
is_xref: bool,
|
||||
@@ -1181,6 +1216,7 @@ fn expansion_prototype_key(
|
||||
insert_style.push(ins_layer.pat_len.to_bits());
|
||||
insert_style.extend(ins_layer.pat.map(f32::to_bits));
|
||||
insert_style.push(ins_layer.lw_px.to_bits());
|
||||
insert_style.push(ins_layer_plottable as u32);
|
||||
insert_style.push(pslt_factor.to_bits());
|
||||
insert_style.extend(bg_color.map(f32::to_bits));
|
||||
insert_style.push(anno_scale.to_bits());
|
||||
@@ -1283,6 +1319,8 @@ struct ExpandCtx<'a> {
|
||||
/// for child wires on layer "0" whose properties are ByLayer.
|
||||
l0: crate::scene::view::render::InheritStyle,
|
||||
l0_aci: u8,
|
||||
l0_plottable: bool,
|
||||
plot_visible: bool,
|
||||
selected: bool,
|
||||
pslt_factor: f32,
|
||||
// World-space XY view AABB (post world_offset). `None` = no culling.
|
||||
@@ -1317,6 +1355,8 @@ fn nested_prototype_key(
|
||||
style.push(ctx.l0.pat_len.to_bits());
|
||||
style.extend(ctx.l0.pat.map(f32::to_bits));
|
||||
style.push(ctx.l0.lw_px.to_bits());
|
||||
style.push(ctx.l0_plottable as u32);
|
||||
style.push(ctx.plot_visible as u32);
|
||||
style.push(ctx.pslt_factor.to_bits());
|
||||
style.extend(ctx.bg_color.map(f32::to_bits));
|
||||
NestedPrototypeKey {
|
||||
@@ -1724,6 +1764,11 @@ fn expand_defn(
|
||||
layer0_aci: ctx.l0_aci,
|
||||
};
|
||||
let nested_style = nref.style.resolve(parent_style);
|
||||
let nested_layer_plottable = if nref.plot_l0 {
|
||||
ctx.l0_plottable
|
||||
} else {
|
||||
nref.plot_visible
|
||||
};
|
||||
let inner_ctx = ExpandCtx {
|
||||
cache: ctx.cache,
|
||||
ins_color: nested_style.insert.0,
|
||||
@@ -1733,6 +1778,8 @@ fn expand_defn(
|
||||
ins_lw_px: nested_style.insert.3,
|
||||
l0: nested_style.layer0,
|
||||
l0_aci: nested_style.layer0_aci,
|
||||
l0_plottable: nested_layer_plottable,
|
||||
plot_visible: ctx.plot_visible && nested_layer_plottable,
|
||||
selected: ctx.selected,
|
||||
pslt_factor: ctx.pslt_factor,
|
||||
view_aabb: ctx.view_aabb,
|
||||
@@ -2023,6 +2070,9 @@ fn emit_wire(
|
||||
// batches stay merged.
|
||||
let local_depth = (lw.world_width > 0.0)
|
||||
.then(|| d_range.0 + lw.local_rank * d_range.1);
|
||||
let plot_visible = ctx.plot_visible
|
||||
&& lw.plot_visible
|
||||
&& (!lw.plot_l0 || ctx.l0_plottable);
|
||||
|
||||
let key = style_key(
|
||||
final_color,
|
||||
@@ -2038,7 +2088,7 @@ fn emit_wire(
|
||||
lw.is_fill_only,
|
||||
lw.fill_is_2d_solid,
|
||||
lw.fill_is_3d,
|
||||
lw.plot_visible,
|
||||
plot_visible,
|
||||
lw.hide_unselected,
|
||||
local_depth,
|
||||
);
|
||||
@@ -2067,7 +2117,7 @@ fn emit_wire(
|
||||
lw.is_fill_only,
|
||||
lw.fill_is_2d_solid,
|
||||
lw.fill_is_3d,
|
||||
lw.plot_visible,
|
||||
plot_visible,
|
||||
lw.hide_unselected,
|
||||
)
|
||||
});
|
||||
|
||||
@@ -339,8 +339,48 @@ pub(crate) fn tessellate_entity_dim_text(
|
||||
}
|
||||
wires
|
||||
}
|
||||
|
||||
pub(crate) fn tessellate_entity(
|
||||
document: &acadrust::CadDocument,
|
||||
selected: &HashSet<Handle>,
|
||||
active_viewport: Option<Handle>,
|
||||
bg_color: [f32; 4],
|
||||
anno_scale: f32,
|
||||
annotation_scale_handle: Option<Handle>,
|
||||
e: &EntityType,
|
||||
block_cache: Option<&cache::block_cache::BlockCache>,
|
||||
view_aabb: Option<[f32; 4]>,
|
||||
world_per_pixel: Option<f32>,
|
||||
paper_space: bool,
|
||||
) -> Vec<WireModel> {
|
||||
let mut wires = tessellate_entity_inner(
|
||||
document,
|
||||
selected,
|
||||
active_viewport,
|
||||
bg_color,
|
||||
anno_scale,
|
||||
annotation_scale_handle,
|
||||
e,
|
||||
block_cache,
|
||||
view_aabb,
|
||||
world_per_pixel,
|
||||
paper_space,
|
||||
);
|
||||
|
||||
let layer_plottable = document
|
||||
.layers
|
||||
.get(&e.common().layer)
|
||||
.map(|layer| layer.is_plottable)
|
||||
.unwrap_or(true);
|
||||
|
||||
if !layer_plottable {
|
||||
for wire in &mut wires {
|
||||
wire.plot_visible = false;
|
||||
}
|
||||
}
|
||||
|
||||
wires
|
||||
}
|
||||
fn tessellate_entity_inner(
|
||||
document: &acadrust::CadDocument,
|
||||
selected: &HashSet<Handle>,
|
||||
active_viewport: Option<Handle>,
|
||||
@@ -1056,6 +1096,11 @@ pub(crate) fn tessellate_entity(
|
||||
_ => None,
|
||||
})
|
||||
.unwrap_or(0);
|
||||
let ins_layer_plottable = document
|
||||
.layers
|
||||
.get(&ins.common.layer)
|
||||
.map(|layer| layer.is_plottable)
|
||||
.unwrap_or(true);
|
||||
let ip = glam::Vec3::new(
|
||||
(ins.insert_point.x) as f32,
|
||||
(ins.insert_point.y) as f32,
|
||||
@@ -1127,6 +1172,7 @@ pub(crate) fn tessellate_entity(
|
||||
ins_lw_px,
|
||||
ins_layer,
|
||||
ins_layer_aci,
|
||||
ins_layer_plottable,
|
||||
sel,
|
||||
pslt_factor,
|
||||
view_aabb,
|
||||
@@ -1181,6 +1227,7 @@ pub(crate) fn tessellate_entity(
|
||||
ins_pat,
|
||||
ins_lw_px,
|
||||
ins_layer,
|
||||
ins_layer_plottable,
|
||||
bg_color,
|
||||
is_xref,
|
||||
pslt_factor,
|
||||
|
||||
+67
-3
@@ -1144,9 +1144,58 @@ impl Scene {
|
||||
viewport,
|
||||
None,
|
||||
false,
|
||||
false,
|
||||
)
|
||||
}
|
||||
|
||||
fn layer_plottable_in_context(
|
||||
&self,
|
||||
entity: &EntityType,
|
||||
context: &crate::scene::render_graph::RenderContext,
|
||||
) -> bool {
|
||||
let common = entity.common();
|
||||
let layer = if crate::scene::view::render::is_effective_layer_zero(&common.layer) {
|
||||
context
|
||||
.insert_path
|
||||
.iter()
|
||||
.rev()
|
||||
.find(|insert| {
|
||||
!crate::scene::view::render::is_effective_layer_zero(&insert.common.layer)
|
||||
})
|
||||
.map(|insert| insert.common.layer.as_str())
|
||||
.unwrap_or(common.layer.as_str())
|
||||
} else {
|
||||
common.layer.as_str()
|
||||
};
|
||||
self.document
|
||||
.layers
|
||||
.get(layer)
|
||||
.map(|layer| layer.is_plottable)
|
||||
.unwrap_or(true)
|
||||
}
|
||||
|
||||
pub(super) fn instanced_plot_hatch_models(
|
||||
&self,
|
||||
layout_block: Handle,
|
||||
hatch_bg: [f32; 4],
|
||||
frozen: Option<&rustc_hash::FxHashSet<Handle>>,
|
||||
annotation_scale_handle: Option<Handle>,
|
||||
all_visible: bool,
|
||||
viewport: Option<Handle>,
|
||||
) -> Vec<HatchModel> {
|
||||
self.instanced_hatch_models_filtered(
|
||||
layout_block,
|
||||
hatch_bg,
|
||||
false,
|
||||
frozen,
|
||||
annotation_scale_handle,
|
||||
all_visible,
|
||||
viewport,
|
||||
None,
|
||||
false,
|
||||
true,
|
||||
)
|
||||
}
|
||||
/// 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
|
||||
@@ -1183,6 +1232,7 @@ impl Scene {
|
||||
self.active_viewport,
|
||||
Some(&targets),
|
||||
true,
|
||||
false,
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1197,6 +1247,7 @@ impl Scene {
|
||||
viewport: Option<Handle>,
|
||||
targets: Option<&rustc_hash::FxHashSet<Handle>>,
|
||||
include_preview_hidden: bool,
|
||||
plot_only: bool,
|
||||
) -> Vec<HatchModel> {
|
||||
let depth_map = self.draw_depth_map();
|
||||
let graph = crate::scene::render_graph::RenderSceneGraph::new(
|
||||
@@ -1213,10 +1264,15 @@ impl Scene {
|
||||
graph.walk_root(
|
||||
self.render_scene_root(layout_block),
|
||||
|entity, context| {
|
||||
let common = entity.common();
|
||||
|
||||
if plot_only && !self.layer_plottable_in_context(entity, context) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if context.is_instanced() {
|
||||
return true;
|
||||
}
|
||||
let common = entity.common();
|
||||
if self.object_isolation.hides(common.handle)
|
||||
|| (!include_preview_hidden
|
||||
&& self.preview_hidden.contains(&common.handle))
|
||||
@@ -1254,6 +1310,9 @@ impl Scene {
|
||||
let EntityType::Hatch(source_hatch) = entity else {
|
||||
return;
|
||||
};
|
||||
if plot_only && !self.layer_plottable_in_context(entity, context) {
|
||||
return;
|
||||
}
|
||||
let style = context.style_for(&self.document, entity);
|
||||
let preserve_white_mask = source_hatch.is_solid
|
||||
&& matches!(
|
||||
@@ -1352,6 +1411,7 @@ impl Scene {
|
||||
all_visible,
|
||||
bg_color,
|
||||
false,
|
||||
false,
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1363,6 +1423,7 @@ impl Scene {
|
||||
all_visible: bool,
|
||||
bg_color: [f32; 4],
|
||||
tint_insert_selection: bool,
|
||||
plot_only: bool,
|
||||
) -> Vec<HatchModel> {
|
||||
let depth_map = self.draw_depth_map();
|
||||
let graph = crate::scene::render_graph::RenderSceneGraph::new(
|
||||
@@ -1377,8 +1438,11 @@ impl Scene {
|
||||
graph.walk_root(
|
||||
self.render_scene_root(target_block),
|
||||
|entity, context| {
|
||||
context.is_instanced()
|
||||
|| !self.entity_temporarily_hidden(entity.common().handle)
|
||||
let common = entity.common();
|
||||
if plot_only && !self.layer_plottable_in_context(entity, context) {
|
||||
return false;
|
||||
}
|
||||
context.is_instanced() || !self.entity_temporarily_hidden(common.handle)
|
||||
},
|
||||
|entity, context| {
|
||||
let EntityType::Wipeout(source) = entity else {
|
||||
|
||||
@@ -8676,6 +8676,7 @@ impl Scene {
|
||||
}
|
||||
EntityType::Insert(insert) => {
|
||||
for attribute in &insert.attributes {
|
||||
add(&mut index.layers, &attribute.common.layer);
|
||||
add(&mut index.text_styles, &attribute.text_style);
|
||||
}
|
||||
}
|
||||
|
||||
+39
-3
@@ -482,6 +482,17 @@ impl Scene {
|
||||
models.extend(instanced);
|
||||
Arc::new(models)
|
||||
}
|
||||
pub fn paper_plot_hatches(&self) -> Arc<Vec<HatchModel>> {
|
||||
let layout_block = self.current_layout_block_handle();
|
||||
|
||||
Arc::new(self.plot_hatches_for_block(
|
||||
layout_block,
|
||||
None,
|
||||
self.paper_annotation_scale_handle(),
|
||||
self.annotation_all_visible(),
|
||||
false,
|
||||
))
|
||||
}
|
||||
|
||||
/// Plot-only hatch set for a specific block. Paper PDF generation uses this
|
||||
/// for the model block behind each floating viewport; unlike
|
||||
@@ -492,6 +503,7 @@ impl Scene {
|
||||
frozen: Option<&rustc_hash::FxHashSet<Handle>>,
|
||||
annotation_scale_handle: Option<Handle>,
|
||||
all_visible: bool,
|
||||
include_solids: bool,
|
||||
) -> Vec<HatchModel> {
|
||||
let layer_hidden = |layer: &str| {
|
||||
self.document
|
||||
@@ -500,6 +512,13 @@ impl Scene {
|
||||
.map(|l| l.flags.off || l.flags.frozen)
|
||||
.unwrap_or(false)
|
||||
};
|
||||
let layer_plottable = |layer: &str| {
|
||||
self.document
|
||||
.layers
|
||||
.get(layer)
|
||||
.map(|l| l.is_plottable)
|
||||
.unwrap_or(true)
|
||||
};
|
||||
let mut models = Vec::new();
|
||||
for (&handle, model) in self.hatches.iter() {
|
||||
let Some(source) = self.document.get_entity(handle) else {
|
||||
@@ -511,10 +530,14 @@ impl Scene {
|
||||
annotation_scale_handle,
|
||||
);
|
||||
let entity = contextual.as_ref();
|
||||
if !include_solids && matches!(entity, EntityType::Solid(_)) {
|
||||
continue;
|
||||
}
|
||||
let common = entity.common();
|
||||
if common.invisible
|
||||
|| self.entity_temporarily_hidden(handle)
|
||||
|| layer_hidden(&common.layer)
|
||||
|| !layer_plottable(&common.layer)
|
||||
|| self.layer_frozen_in(&common.layer, frozen)
|
||||
|| crate::scene::annotative::annotative_offscale_for(
|
||||
&self.document,
|
||||
@@ -554,10 +577,9 @@ impl Scene {
|
||||
}
|
||||
models.push(hatch);
|
||||
}
|
||||
models.extend(self.instanced_hatch_models(
|
||||
models.extend(self.instanced_plot_hatch_models(
|
||||
block,
|
||||
self.paper_bg_color,
|
||||
false,
|
||||
frozen,
|
||||
annotation_scale_handle,
|
||||
all_visible,
|
||||
@@ -583,6 +605,7 @@ impl Scene {
|
||||
all_visible,
|
||||
self.paper_bg_color,
|
||||
highlight_selection,
|
||||
true,
|
||||
)
|
||||
}
|
||||
|
||||
@@ -592,13 +615,26 @@ impl Scene {
|
||||
/// content viewport's GPU pipeline) don't get a second mis-projected
|
||||
/// copy on the paper sheet.
|
||||
pub fn paper_canvas_wipeouts(&self) -> Arc<Vec<HatchModel>> {
|
||||
let layout_block = self.current_layout_block_handle();
|
||||
Arc::new(self.wipeout_models_for_block_graph(
|
||||
layout_block,
|
||||
None,
|
||||
self.paper_annotation_scale_handle(),
|
||||
self.annotation_all_visible(),
|
||||
self.paper_bg_color,
|
||||
true,
|
||||
false,
|
||||
))
|
||||
}
|
||||
|
||||
pub fn paper_plot_wipeouts(&self) -> Arc<Vec<HatchModel>> {
|
||||
let layout_block = self.current_layout_block_handle();
|
||||
Arc::new(self.plot_wipeouts_for_block(
|
||||
layout_block,
|
||||
None,
|
||||
self.paper_annotation_scale_handle(),
|
||||
self.annotation_all_visible(),
|
||||
true,
|
||||
false,
|
||||
))
|
||||
}
|
||||
|
||||
|
||||
@@ -436,6 +436,7 @@ impl Scene {
|
||||
Some(&frozen),
|
||||
self.viewport_scale_handle(viewport.common.handle),
|
||||
self.annotation_all_visible(),
|
||||
true,
|
||||
);
|
||||
for hatch in hatches {
|
||||
if matches!(&hatch.pattern, HatchPattern::Pattern(_)) {
|
||||
|
||||
@@ -32,6 +32,7 @@ pub enum LayerSortCol {
|
||||
On,
|
||||
Freeze,
|
||||
Lock,
|
||||
Plot,
|
||||
Color,
|
||||
Linetype,
|
||||
Lineweight,
|
||||
@@ -86,6 +87,7 @@ pub struct Layer {
|
||||
pub visible: bool,
|
||||
pub frozen: bool,
|
||||
pub locked: bool,
|
||||
pub plottable: bool,
|
||||
pub color: AcadColor,
|
||||
pub linetype: String,
|
||||
pub lineweight: LineWeight,
|
||||
@@ -101,6 +103,7 @@ impl Layer {
|
||||
visible: true,
|
||||
frozen: false,
|
||||
locked: false,
|
||||
plottable: true,
|
||||
color,
|
||||
linetype: "Continuous".to_string(),
|
||||
lineweight: LineWeight::Default,
|
||||
@@ -214,6 +217,7 @@ impl LayerPanel {
|
||||
visible: !l.flags.off,
|
||||
frozen: l.flags.frozen,
|
||||
locked: l.flags.locked,
|
||||
plottable: l.is_plottable,
|
||||
color: l.color,
|
||||
linetype: if l.line_type.is_empty() {
|
||||
"Continuous".to_string()
|
||||
@@ -249,6 +253,10 @@ impl LayerPanel {
|
||||
self.apply_sort();
|
||||
}
|
||||
|
||||
pub fn refresh_sort(&mut self) {
|
||||
self.apply_sort();
|
||||
}
|
||||
|
||||
/// Reorder `self.layers` by the active sort column, preserving the current
|
||||
/// selection by name. No-op in document order (`sort_col == None`).
|
||||
fn apply_sort(&mut self) {
|
||||
@@ -275,6 +283,7 @@ impl LayerPanel {
|
||||
LayerSortCol::On => a.visible.cmp(&b.visible),
|
||||
LayerSortCol::Freeze => a.frozen.cmp(&b.frozen),
|
||||
LayerSortCol::Lock => a.locked.cmp(&b.locked),
|
||||
LayerSortCol::Plot => a.plottable.cmp(&b.plottable),
|
||||
LayerSortCol::Color => color_sort_key(a.color).cmp(&color_sort_key(b.color)),
|
||||
LayerSortCol::Linetype => {
|
||||
a.linetype.to_lowercase().cmp(&b.linetype.to_lowercase())
|
||||
@@ -392,6 +401,7 @@ impl LayerPanel {
|
||||
sortable_header(t!("On"), LayerSortCol::On, Length::Fixed(COL_ICON), sc, sa),
|
||||
sortable_header(t!("Freeze"), LayerSortCol::Freeze, Length::Fixed(COL_ICON), sc, sa),
|
||||
sortable_header(t!("Lock"), LayerSortCol::Lock, Length::Fixed(COL_ICON), sc, sa),
|
||||
sortable_header(t!("Plot"), LayerSortCol::Plot, Length::Fixed(COL_ICON), sc, sa),
|
||||
sortable_header(t!("Color"), LayerSortCol::Color, Length::Fixed(COL_COLOR), sc, sa),
|
||||
sortable_header(t!("Linetype"), LayerSortCol::Linetype, Length::Fixed(COL_LT), sc, sa),
|
||||
sortable_header(t!("Lineweight"), LayerSortCol::Lineweight, Length::Fixed(COL_LW), sc, sa),
|
||||
@@ -719,6 +729,31 @@ fn layer_row<'a>(
|
||||
let vis_svg = crate::ui::icons::layer_visible(layer.visible);
|
||||
let frz_svg = crate::ui::icons::layer_freeze(layer.frozen);
|
||||
let lck_svg = crate::ui::icons::layer_lock(layer.locked);
|
||||
let plot_icon: Element<'_, Message> = if layer.plottable {
|
||||
crate::ui::icons::themed(crate::ui::icons::PRINT, ICON_SZ)
|
||||
} else {
|
||||
row![
|
||||
crate::ui::icons::themed(crate::ui::icons::PRINT, ICON_SZ),
|
||||
crate::ui::icons::themed_danger(crate::ui::icons::CLOSE, ICON_SZ * 0.65),
|
||||
]
|
||||
.spacing(0)
|
||||
.align_y(iced::Center)
|
||||
.into()
|
||||
};
|
||||
|
||||
let plot_btn: Element<'_, Message> = button(plot_icon)
|
||||
.on_press(Message::LayerTogglePlot(index))
|
||||
.style(move |theme: &Theme, status| {
|
||||
layer_cell_button_style(theme, status, is_selected, index)
|
||||
})
|
||||
.padding(Padding {
|
||||
top: COMBO_PAD_V,
|
||||
bottom: COMBO_PAD_V,
|
||||
left: 4.0,
|
||||
right: 4.0,
|
||||
})
|
||||
.height(Length::Fixed(ROW_H))
|
||||
.into();
|
||||
|
||||
let status_dot: Element<'_, Message> = if is_current {
|
||||
crate::ui::icons::themed_success(crate::ui::icons::CHECK, 13.0)
|
||||
@@ -877,6 +912,9 @@ fn layer_row<'a>(
|
||||
container(svg_btn(lck_svg, Message::LayerToggleLock(index)))
|
||||
.width(Length::Fixed(COL_ICON))
|
||||
.align_x(iced::Center),
|
||||
container(plot_btn)
|
||||
.width(Length::Fixed(COL_ICON))
|
||||
.align_x(iced::Center),
|
||||
color_cell,
|
||||
lt_cell,
|
||||
lw_cell,
|
||||
|
||||
Reference in new issue
Block a user