forked from 1b-agent/opencadstudio-upstream
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:
1 parent
313a0eacfd
commit
e78e137664
3 files changed
+69
-1
No files matched your search
@@ -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" => {
|
||||
|
||||
@@ -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",
|
||||
}
|
||||
}
|
||||
@@ -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(),
|
||||
|
||||
Reference in new issue
Block a user