fix(paper): keep model 3D solids off the paper-space sheet

The paper layout sheet pass reused the full model mesh set, so every
top-level 3D solid piled onto the paper origin — the sheet camera works
in paper coordinates, not model space. Guard `meshes` on
`inst.paper_sheet` the same way wires/hatches/images already are: the
sheet shows only paper-native content; the model's solids render inside
the floating content viewports (model camera + per-viewport scissor).

Also name 3DSOLID/REGION/BODY/SURFACE/MESH/SOLID/MULTILEADER in dxf_name
(they fell through to "ENTITY"), and add a SELHANDLES diagnostic that
reports the active space plus a per-type / per-block selection breakdown.

Co-Authored-By: Claude Opus 4.8 <[email protected]>
This commit is contained in:
Hakan SevenandClaude Opus 4.8 committed 2026-07-03 23:29:18 +03:00
1 parent 313a0eacfd
commit e78e137664
3 files changed
+69 -1

No files matched your search

+49
View File
@@ -115,6 +115,55 @@ impl OpenCADStudio {
}
}
// SELHANDLES — report the current selection for diagnostics: the
// active space (Model / which paper layout), a per-type and
// per-block breakdown, and the raw comma-separated hex handle list
// (so what renders on screen can be compared against the file).
"SELHANDLES" | "SELH" => {
let scene = &self.tabs[i].scene;
let selected = scene.selected_entities();
if selected.is_empty() {
self.command_line
.push_error("SELHANDLES: no entities selected. Select entities first.");
} else {
use std::collections::BTreeMap;
let space = if scene.current_layout == "Model" {
"Model space".to_string()
} else {
format!("Paper space '{}'", scene.current_layout)
};
let mut handles: Vec<u64> = Vec::with_capacity(selected.len());
let mut type_counts: BTreeMap<&'static str, usize> = BTreeMap::new();
let mut block_counts: BTreeMap<String, usize> = BTreeMap::new();
for (h, e) in &selected {
handles.push(h.value());
*type_counts
.entry(crate::entities::names::dxf_name(e))
.or_default() += 1;
if let acadrust::EntityType::Insert(ins) = e {
*block_counts.entry(ins.block_name.clone()).or_default() += 1;
}
}
handles.sort_unstable();
let types: Vec<String> =
type_counts.iter().map(|(t, n)| format!("{t}×{n}")).collect();
let list: Vec<String> = handles.iter().map(|h| format!("{:X}", h)).collect();
let mut msg = format!(
"SELHANDLES: {} selected in {}\n Types: {}",
handles.len(),
space,
types.join(", ")
);
if !block_counts.is_empty() {
let blocks: Vec<String> =
block_counts.iter().map(|(b, n)| format!("{b}×{n}")).collect();
msg.push_str(&format!("\n Blocks: {}", blocks.join(", ")));
}
msg.push_str(&format!("\n Handles: {}", list.join(",")));
self.command_line.push_output(&msg);
}
}
// DBLIST — list data for every entity in the drawing (LIST over the
// whole database rather than the current selection).
"DBLIST" => {