forked from 1b-agent/opencadstudio-upstream
feat(commands): expand standard CAD command coverage
Integrate a large batch of standard CAD commands and fix several name/behaviour mismatches, with no product references in code. 3D solids (reusing the truck B-rep pipeline): - SLICE, INTERFERE, PRESSPULL, POLYSOLID, PYRAMID, SECTION - 3DROTATE, 3DMIRROR, 3DALIGN (cached-solid transforms) Annotation / text: - ARCTEXT, SPLINEFIT (Catmull-Rom to Bezier), DIMJOGGED, OBJECTSCALE (XData markers honoured by the existing geometry-gen / tessellator) Blocks / misc: - NCOPY (block-content extraction via explode_entity) - OPTIONS, SYNCPVIEWPORTS, THICKEN, plus earlier toggles, aliases, system variables, and layer/style/view commands POINTCLOUD/RECAP and UNDERLAYLAYERS/UOSNAP are intentionally left out: they require a proprietary binary / PDF-layer parser, a GPU point renderer, and real test files. Co-Authored-By: Claude Opus 4.8 <[email protected]>
This commit is contained in:
1 parent
76ef544cda
commit
c19c18c2f2
24 files changed
+4405
-216
No files matched your search
+42
-20
@@ -57,7 +57,6 @@ fn format_size(bytes: u64) -> String {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
mod command;
|
||||
mod dialog;
|
||||
mod dynamic;
|
||||
@@ -163,7 +162,6 @@ impl OpenCADStudio {
|
||||
self.otrack_active = None;
|
||||
}
|
||||
|
||||
|
||||
fn update_inner(&mut self, msg: Message) -> Task<Message> {
|
||||
match msg {
|
||||
// Web: a drawing referenced a script whose Noto subset isn't loaded
|
||||
@@ -270,7 +268,9 @@ impl OpenCADStudio {
|
||||
Task::none()
|
||||
}
|
||||
|
||||
Message::FileOpened(Ok((name, path, doc, caches))) => self.on_file_opened(name, path, doc, caches),
|
||||
Message::FileOpened(Ok((name, path, doc, caches))) => {
|
||||
self.on_file_opened(name, path, doc, caches)
|
||||
}
|
||||
|
||||
Message::FileOpened(Err(e)) => {
|
||||
// If the user cancelled, the overlay was already cleared and
|
||||
@@ -363,7 +363,9 @@ impl OpenCADStudio {
|
||||
)
|
||||
}
|
||||
|
||||
Message::WblockSaveResult(block_name, Some(path)) => self.on_wblock_save_result_some(block_name, path),
|
||||
Message::WblockSaveResult(block_name, Some(path)) => {
|
||||
self.on_wblock_save_result_some(block_name, path)
|
||||
}
|
||||
|
||||
Message::WblockSaveResult(_, None) => Task::none(),
|
||||
|
||||
@@ -585,7 +587,9 @@ impl OpenCADStudio {
|
||||
Task::none()
|
||||
}
|
||||
|
||||
Message::RibbonToolClick { tool_id, event } => self.on_ribbon_tool_click(tool_id, event),
|
||||
Message::RibbonToolClick { tool_id, event } => {
|
||||
self.on_ribbon_tool_click(tool_id, event)
|
||||
}
|
||||
Message::PluginFileDialogResult { command, path } => {
|
||||
if let Some(path) = path {
|
||||
// Dispatch "<command> <path>" with original case intact —
|
||||
@@ -888,7 +892,9 @@ impl OpenCADStudio {
|
||||
Task::none()
|
||||
}
|
||||
|
||||
Message::LayerToggleVpFreeze(layer_idx, vp_col_idx) => self.on_layer_toggle_vp_freeze(layer_idx, vp_col_idx),
|
||||
Message::LayerToggleVpFreeze(layer_idx, vp_col_idx) => {
|
||||
self.on_layer_toggle_vp_freeze(layer_idx, vp_col_idx)
|
||||
}
|
||||
|
||||
Message::LayerNew => self.on_layer_new(),
|
||||
|
||||
@@ -1220,9 +1226,7 @@ impl OpenCADStudio {
|
||||
if name.is_empty() || name == "WCS" {
|
||||
self.tabs[i].active_ucs = None;
|
||||
self.command_line.push_output("UCS: World");
|
||||
} else if let Some(named) =
|
||||
self.tabs[i].scene.document.ucss.get(&name).cloned()
|
||||
{
|
||||
} else if let Some(named) = self.tabs[i].scene.document.ucss.get(&name).cloned() {
|
||||
self.tabs[i].active_ucs = Some(named);
|
||||
self.command_line.push_output(&format!("UCS: {}", name));
|
||||
}
|
||||
@@ -1515,6 +1519,11 @@ impl OpenCADStudio {
|
||||
let handles: Vec<_> = self.tabs[i].scene.selected.iter().cloned().collect();
|
||||
if !handles.is_empty() {
|
||||
self.push_undo_snapshot(i, "ERASE");
|
||||
// Stash the erased entities so OOPS can restore them.
|
||||
self.oops_cache = handles
|
||||
.iter()
|
||||
.filter_map(|h| self.tabs[i].scene.document.get_entity(*h).cloned())
|
||||
.collect();
|
||||
self.tabs[i].scene.erase_entities(&handles);
|
||||
self.tabs[i].dirty = true;
|
||||
self.refresh_properties();
|
||||
@@ -1861,7 +1870,9 @@ impl OpenCADStudio {
|
||||
self.push_undo_snapshot(i, "CHPROP");
|
||||
for &handle in &handles {
|
||||
if let Some(entity) = self.tabs[i].scene.document.get_entity_mut(handle) {
|
||||
crate::scene::view::dispatch::apply_common_prop(entity, "layer", &layer);
|
||||
crate::scene::view::dispatch::apply_common_prop(
|
||||
entity, "layer", &layer,
|
||||
);
|
||||
}
|
||||
}
|
||||
self.invalidate_property_targets(i, &handles);
|
||||
@@ -1914,7 +1925,9 @@ impl OpenCADStudio {
|
||||
self.push_undo_snapshot(i, "CHPROP");
|
||||
for &handle in &handles {
|
||||
if let Some(entity) = self.tabs[i].scene.document.get_entity_mut(handle) {
|
||||
crate::scene::view::dispatch::apply_common_prop(entity, "linetype", <);
|
||||
crate::scene::view::dispatch::apply_common_prop(
|
||||
entity, "linetype", <,
|
||||
);
|
||||
}
|
||||
}
|
||||
self.invalidate_property_targets(i, &handles);
|
||||
@@ -1934,10 +1947,12 @@ impl OpenCADStudio {
|
||||
for &handle in &handles {
|
||||
if let Some(entity) = self.tabs[i].scene.document.get_entity_mut(handle) {
|
||||
match field {
|
||||
"invisible" => crate::scene::view::dispatch::toggle_invisible(entity),
|
||||
_ => {
|
||||
crate::scene::view::dispatch::apply_geom_prop(entity, field, "toggle")
|
||||
"invisible" => {
|
||||
crate::scene::view::dispatch::toggle_invisible(entity)
|
||||
}
|
||||
_ => crate::scene::view::dispatch::apply_geom_prop(
|
||||
entity, field, "toggle",
|
||||
),
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1948,7 +1963,9 @@ impl OpenCADStudio {
|
||||
Task::none()
|
||||
}
|
||||
|
||||
Message::PropGeomChoiceChanged { field, value } => self.on_prop_geom_choice_changed(field, value),
|
||||
Message::PropGeomChoiceChanged { field, value } => {
|
||||
self.on_prop_geom_choice_changed(field, value)
|
||||
}
|
||||
|
||||
Message::PropGeomInput { field, value } => {
|
||||
self.tabs[self.active_tab]
|
||||
@@ -2334,8 +2351,7 @@ impl OpenCADStudio {
|
||||
.entry(repo.clone())
|
||||
.or_insert_with(|| first.clone());
|
||||
}
|
||||
self.marketplace_status =
|
||||
format!("{repo}: {} installable release(s)", tags.len());
|
||||
self.marketplace_status = format!("{repo}: {} installable release(s)", tags.len());
|
||||
self.repo_release_tags.insert(repo, tags);
|
||||
Task::none()
|
||||
}
|
||||
@@ -2496,7 +2512,9 @@ impl OpenCADStudio {
|
||||
|
||||
Message::UnsavedDialogSave => self.on_unsaved_dialog_save(),
|
||||
|
||||
Message::UnsavedPickedSavePath(Some(path)) => self.on_unsaved_picked_save_path_some(path),
|
||||
Message::UnsavedPickedSavePath(Some(path)) => {
|
||||
self.on_unsaved_picked_save_path_some(path)
|
||||
}
|
||||
|
||||
Message::UnsavedPickedSavePath(None) => {
|
||||
// User cancelled the save-as dialog — re-open the confirmation dialog.
|
||||
@@ -3196,8 +3214,12 @@ impl OpenCADStudio {
|
||||
};
|
||||
Task::none()
|
||||
}
|
||||
Message::MLeaderStyleSetEnum { field, value } => self.on_mleader_style_set_enum(field, value),
|
||||
Message::MLeaderStyleSetHandle { field, value } => self.on_mleader_style_set_handle(field, value),
|
||||
Message::MLeaderStyleSetEnum { field, value } => {
|
||||
self.on_mleader_style_set_enum(field, value)
|
||||
}
|
||||
Message::MLeaderStyleSetHandle { field, value } => {
|
||||
self.on_mleader_style_set_handle(field, value)
|
||||
}
|
||||
Message::MLeaderStyleApply => self.on_mleader_style_apply(),
|
||||
|
||||
// ── DimStyle Dialog ───────────────────────────────────────────────
|
||||
|
||||
Reference in new issue
Block a user