feat(commands): add FLATSHOT and CONVTOSURFACE
- FLATSHOT: project the selected solid's edges to 2D Line entities at Z=0 - CONVTOSURFACE: convert the selected solid(s) to Surface entities Both reuse the cached B-rep's edge wires. COMMANDS.md: 219/262. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
parent
6f9565e9f7
commit
c653a3f38e
4 changed files with 108 additions and 4 deletions
|
|
@ -230,9 +230,9 @@ Status of every standard CAD command in Open CAD Studio:
|
||||||
| `INTERFERE` | INF | Interference solid from overlap | ✅ |
|
| `INTERFERE` | INF | Interference solid from overlap | ✅ |
|
||||||
| `SECTION` | — | Cross-section outline of a solid | ✅ |
|
| `SECTION` | — | Cross-section outline of a solid | ✅ |
|
||||||
| `CONVTOSOLID` | — | Convert to solid | ❌ |
|
| `CONVTOSOLID` | — | Convert to solid | ❌ |
|
||||||
| `CONVTOSURFACE` | — | Convert to surface | ❌ |
|
| `CONVTOSURFACE` | — | Convert to surface | ✅ |
|
||||||
| `SECTIONPLANE` | — | Section plane object | ❌ |
|
| `SECTIONPLANE` | — | Section plane object | ❌ |
|
||||||
| `FLATSHOT` | — | 2D view from 3D | ❌ |
|
| `FLATSHOT` | — | 2D view from 3D | ✅ |
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|
@ -357,12 +357,12 @@ Status of every standard CAD command in Open CAD Studio:
|
||||||
| Text & Table | 10 | 7 | 1 | 2 |
|
| Text & Table | 10 | 7 | 1 | 2 |
|
||||||
| Layer | 19 | 17 | 0 | 2 |
|
| Layer | 19 | 17 | 0 | 2 |
|
||||||
| Block & Reference | 23 | 18 | 2 | 3 |
|
| Block & Reference | 23 | 18 | 2 | 3 |
|
||||||
| 3D Modeling | 27 | 23 | 0 | 4 |
|
| 3D Modeling | 27 | 25 | 0 | 2 |
|
||||||
| View & Navigation | 32 | 15 | 8 | 9 |
|
| View & Navigation | 32 | 15 | 8 | 9 |
|
||||||
| Inquiry | 12 | 12 | 0 | 0 |
|
| Inquiry | 12 | 12 | 0 | 0 |
|
||||||
| File & Plot | 17 | 16 | 0 | 1 |
|
| File & Plot | 17 | 16 | 0 | 1 |
|
||||||
| Manage & Customize | 22 | 13 | 3 | 6 |
|
| Manage & Customize | 22 | 13 | 3 | 6 |
|
||||||
| **Total** | **262** | **217** | **15** | **30** |
|
| **Total** | **262** | **219** | **15** | **28** |
|
||||||
|
|
||||||
> Counts include commands listed under more than one category (e.g. `SLICE`, `HELIX`,
|
> Counts include commands listed under more than one category (e.g. `SLICE`, `HELIX`,
|
||||||
> `MINSERT`, `SUBTRACT`/`UNION`/`INTERSECT` appear in both their 2D and 3D groups).
|
> `MINSERT`, `SUBTRACT`/`UNION`/`INTERSECT` appear in both their 2D and 3D groups).
|
||||||
|
|
|
||||||
|
|
@ -704,6 +704,16 @@ impl OpenCADStudio {
|
||||||
return Some(self.solid_interfere());
|
return Some(self.solid_interfere());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// FLATSHOT — flatten the selected solid's edges to 2D lines at Z=0.
|
||||||
|
"FLATSHOT" => {
|
||||||
|
return Some(self.solid_flatshot());
|
||||||
|
}
|
||||||
|
|
||||||
|
// CONVTOSURFACE — convert the selected solid(s) to surface entities.
|
||||||
|
"CONVTOSURFACE" => {
|
||||||
|
return Some(self.solid_convtosurface());
|
||||||
|
}
|
||||||
|
|
||||||
// POLYSOLID <width> <height> — extrude a selected polyline into a
|
// POLYSOLID <width> <height> — extrude a selected polyline into a
|
||||||
// wall-like solid.
|
// wall-like solid.
|
||||||
cmd if cmd == "POLYSOLID" || cmd.starts_with("POLYSOLID ") => {
|
cmd if cmd == "POLYSOLID" || cmd.starts_with("POLYSOLID ") => {
|
||||||
|
|
|
||||||
|
|
@ -346,6 +346,8 @@ inventory::submit!(crate::command::CommandRegistration {
|
||||||
"REG",
|
"REG",
|
||||||
"ARCHIVE",
|
"ARCHIVE",
|
||||||
"ETRANSMIT",
|
"ETRANSMIT",
|
||||||
|
"FLATSHOT",
|
||||||
|
"CONVTOSURFACE",
|
||||||
// Slice/section + interference + press-pull/thicken + 3D transforms + wall/pyramid.
|
// Slice/section + interference + press-pull/thicken + 3D transforms + wall/pyramid.
|
||||||
"SLICE",
|
"SLICE",
|
||||||
"SL",
|
"SL",
|
||||||
|
|
|
||||||
|
|
@ -748,4 +748,96 @@ impl super::OpenCADStudio {
|
||||||
.push_output(&format!("SPLINEFIT: fit a spline through {n} points."));
|
.push_output(&format!("SPLINEFIT: fit a spline through {n} points."));
|
||||||
Task::none()
|
Task::none()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// FLATSHOT — project the selected solid's edges onto the XY plane (Z=0) as
|
||||||
|
/// Line entities, giving a flattened 2D shot of the model. Reuses the cached
|
||||||
|
/// solid's edge wires (the same source SECTION uses).
|
||||||
|
pub(super) fn solid_flatshot(&mut self) -> Task<Message> {
|
||||||
|
use acadrust::types::Vector3;
|
||||||
|
use acadrust::Line;
|
||||||
|
let i = self.active_tab;
|
||||||
|
let handles: Vec<Handle> = self.tabs[i]
|
||||||
|
.scene
|
||||||
|
.selected
|
||||||
|
.iter()
|
||||||
|
.copied()
|
||||||
|
.filter(|h| self.tabs[i].scene.solid_models.contains_key(h))
|
||||||
|
.collect();
|
||||||
|
if handles.is_empty() {
|
||||||
|
self.command_line
|
||||||
|
.push_error("FLATSHOT: select a solid created this session.");
|
||||||
|
return Task::none();
|
||||||
|
}
|
||||||
|
self.push_undo_snapshot(i, "FLATSHOT");
|
||||||
|
let mut n = 0usize;
|
||||||
|
for h in &handles {
|
||||||
|
let solid = self.tabs[i].scene.solid_models[h].clone();
|
||||||
|
for w in solid_model::edge_wires(&solid) {
|
||||||
|
for seg in w.points.windows(2) {
|
||||||
|
let line = Line::from_points(
|
||||||
|
Vector3::new(seg[0].x, seg[0].y, 0.0),
|
||||||
|
Vector3::new(seg[1].x, seg[1].y, 0.0),
|
||||||
|
);
|
||||||
|
self.tabs[i].scene.add_entity(EntityType::Line(line));
|
||||||
|
n += 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
self.tabs[i].dirty = true;
|
||||||
|
self.refresh_properties();
|
||||||
|
self.command_line
|
||||||
|
.push_output(&format!("FLATSHOT: created {n} projected edge(s) at Z=0."));
|
||||||
|
Task::none()
|
||||||
|
}
|
||||||
|
|
||||||
|
/// CONVTOSURFACE — convert the selected solid(s) into Surface entities,
|
||||||
|
/// carrying the solid's edge wires (reuses the cached B-rep's edge wires).
|
||||||
|
pub(super) fn solid_convtosurface(&mut self) -> Task<Message> {
|
||||||
|
use acadrust::entities::{Surface, SurfaceKind, Wire as AWire};
|
||||||
|
use acadrust::types::Vector3;
|
||||||
|
let i = self.active_tab;
|
||||||
|
let handles: Vec<Handle> = self.tabs[i]
|
||||||
|
.scene
|
||||||
|
.selected
|
||||||
|
.iter()
|
||||||
|
.copied()
|
||||||
|
.filter(|h| self.tabs[i].scene.solid_models.contains_key(h))
|
||||||
|
.collect();
|
||||||
|
if handles.is_empty() {
|
||||||
|
self.command_line
|
||||||
|
.push_error("CONVTOSURFACE: select a solid created this session.");
|
||||||
|
return Task::none();
|
||||||
|
}
|
||||||
|
let mut surfaces: Vec<Surface> = Vec::new();
|
||||||
|
for h in &handles {
|
||||||
|
let solid = self.tabs[i].scene.solid_models[h].clone();
|
||||||
|
let awires: Vec<AWire> = solid_model::edge_wires(&solid)
|
||||||
|
.into_iter()
|
||||||
|
.map(|w| {
|
||||||
|
let mut aw = AWire::new();
|
||||||
|
aw.points = w
|
||||||
|
.points
|
||||||
|
.iter()
|
||||||
|
.map(|p| Vector3::new(p.x, p.y, p.z))
|
||||||
|
.collect();
|
||||||
|
aw
|
||||||
|
})
|
||||||
|
.collect();
|
||||||
|
let mut surf = Surface::new(SurfaceKind::Generic);
|
||||||
|
surf.wires = awires;
|
||||||
|
surf.common.layer = self.tabs[i].active_layer.clone();
|
||||||
|
surfaces.push(surf);
|
||||||
|
}
|
||||||
|
self.push_undo_snapshot(i, "CONVTOSURFACE");
|
||||||
|
self.tabs[i].scene.erase_entities(&handles);
|
||||||
|
let n = surfaces.len();
|
||||||
|
for surf in surfaces {
|
||||||
|
self.tabs[i].scene.add_entity(EntityType::Surface(surf));
|
||||||
|
}
|
||||||
|
self.tabs[i].dirty = true;
|
||||||
|
self.refresh_properties();
|
||||||
|
self.command_line
|
||||||
|
.push_output(&format!("CONVTOSURFACE: converted {n} solid(s) to surface(s)."));
|
||||||
|
Task::none()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue