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" => {
+7
View File
@@ -92,8 +92,15 @@ pub fn dxf_name(e: &EntityType) -> &'static str {
EntityType::AttributeDefinition(_) => "ATTDEF",
EntityType::AttributeEntity(_) => "ATTRIB",
EntityType::Leader(_) => "LEADER",
EntityType::MultiLeader(_) => "MULTILEADER",
EntityType::Tolerance(_) => "TOLERANCE",
EntityType::Shape(_) => "SHAPE",
EntityType::Solid(_) => "SOLID",
EntityType::Solid3D(_) => "3DSOLID",
EntityType::Region(_) => "REGION",
EntityType::Body(_) => "BODY",
EntityType::Surface(_) => "SURFACE",
EntityType::Mesh(_) => "MESH",
_ => "ENTITY",
}
}
+13 -1
View File
@@ -957,6 +957,18 @@ impl Scene {
} else {
self.images_arc()
};
// The paper sheet shows the layout's own 2-D content (fills, borders,
// annotation) — never the model's 3-D solids. Those are drawn inside
// the floating content viewports, whose model camera + per-viewport
// scissor place and clip them correctly. Feeding the model mesh set to
// the sheet piles every solid onto the paper origin, because the sheet
// camera works in paper coordinates, not model space — the same reason
// the sheet excludes model hatches and wires above.
let meshes = if inst.paper_sheet {
Arc::new(Vec::new())
} else {
self.meshes_arc()
};
Some(ViewportData {
wires: all_wires,
@@ -966,7 +978,7 @@ impl Scene {
hatches,
wipeout_hatches,
images,
meshes: self.meshes_arc(),
meshes,
uniforms,
cam_rotation: inst.camera.view_rotation_mat() * self.viewcube_ucs_mat(),
compass_rotation: inst.camera.view_rotation_mat(),