refactor: split four oversized files into submodule trees
Break up the four giant files (~29k lines total) into focused submodule
directories, one concern per file. Pure mechanical moves — behavior is
unchanged.
- app/update.rs (9650) -> app/update/{mod,viewport,command,style,file,
dynamic,dialog,util}. The 384-arm update_inner match stays in mod.rs
with thin delegating arms; the 66 fattest arm bodies move to topic
methods. Arm set preserved exactly (384 -> 384).
- scene/mod.rs (9017) -> scene/{mod,entity,tess,hittest,layout,paper,
mspace,project,selection,modify,group_layer,preview}. The impl Scene
body is split across files via inherent-impl-per-file; struct, ctor,
fields and load-time helpers stay in the root. fn count 123 -> 123.
- app/commands.rs (6082) -> app/commands/* grouped by command family.
The 233-arm dispatch match becomes source-ordered per-family
dispatch_* handlers, preserving first-match precedence (233 -> 233).
- app/view.rs (4686) -> app/view/{mod,overlay,modal,viewcube,controls}.
Largest file drops from 9650 to 3343. Builds clean; app launches and
loads plugins with no panic.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-26 22:51:29 +03:00
|
|
|
use super::{Message, OpenCADStudio};
|
|
|
|
|
use crate::command::CadCommand;
|
|
|
|
|
use crate::scene::Scene;
|
|
|
|
|
use iced::Task;
|
|
|
|
|
use std::path::PathBuf;
|
|
|
|
|
|
|
|
|
|
mod blocks;
|
|
|
|
|
mod dim;
|
|
|
|
|
mod display;
|
|
|
|
|
mod draw;
|
|
|
|
|
mod fileops;
|
|
|
|
|
mod inquiry;
|
|
|
|
|
mod layerprops;
|
|
|
|
|
mod layers;
|
|
|
|
|
mod styleprops;
|
|
|
|
|
mod view;
|
|
|
|
|
|
|
|
|
|
// `DrawOrderRefCommand` lives in the `view` family file but is referenced by
|
|
|
|
|
// path (`commands::DrawOrderRefCommand`) from `update.rs`, so re-export it at
|
|
|
|
|
// the module root to keep that path valid.
|
|
|
|
|
pub(crate) use view::DrawOrderRefCommand;
|
|
|
|
|
|
|
|
|
|
impl OpenCADStudio {
|
|
|
|
|
/// First `"{prefix}{n}"` (n ≥ 1) not already used by a block record in the
|
|
|
|
|
/// active drawing. Used to auto-name a paste-as-block definition.
|
2026-08-05 21:37:56 +01:00
|
|
|
pub(super) fn unique_block_name(&self, prefix: &str) -> String {
|
refactor: split four oversized files into submodule trees
Break up the four giant files (~29k lines total) into focused submodule
directories, one concern per file. Pure mechanical moves — behavior is
unchanged.
- app/update.rs (9650) -> app/update/{mod,viewport,command,style,file,
dynamic,dialog,util}. The 384-arm update_inner match stays in mod.rs
with thin delegating arms; the 66 fattest arm bodies move to topic
methods. Arm set preserved exactly (384 -> 384).
- scene/mod.rs (9017) -> scene/{mod,entity,tess,hittest,layout,paper,
mspace,project,selection,modify,group_layer,preview}. The impl Scene
body is split across files via inherent-impl-per-file; struct, ctor,
fields and load-time helpers stay in the root. fn count 123 -> 123.
- app/commands.rs (6082) -> app/commands/* grouped by command family.
The 233-arm dispatch match becomes source-ordered per-family
dispatch_* handlers, preserving first-match precedence (233 -> 233).
- app/view.rs (4686) -> app/view/{mod,overlay,modal,viewcube,controls}.
Largest file drops from 9650 to 3343. Builds clean; app launches and
loads plugins with no panic.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-26 22:51:29 +03:00
|
|
|
let i = self.active_tab;
|
|
|
|
|
let mut n = 1;
|
|
|
|
|
loop {
|
|
|
|
|
let name = format!("{prefix}{n}");
|
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 <noreply@anthropic.com>
2026-06-29 08:23:58 +03:00
|
|
|
if self.tabs[i]
|
|
|
|
|
.scene
|
|
|
|
|
.document
|
|
|
|
|
.block_records
|
|
|
|
|
.get(&name)
|
|
|
|
|
.is_none()
|
|
|
|
|
{
|
refactor: split four oversized files into submodule trees
Break up the four giant files (~29k lines total) into focused submodule
directories, one concern per file. Pure mechanical moves — behavior is
unchanged.
- app/update.rs (9650) -> app/update/{mod,viewport,command,style,file,
dynamic,dialog,util}. The 384-arm update_inner match stays in mod.rs
with thin delegating arms; the 66 fattest arm bodies move to topic
methods. Arm set preserved exactly (384 -> 384).
- scene/mod.rs (9017) -> scene/{mod,entity,tess,hittest,layout,paper,
mspace,project,selection,modify,group_layer,preview}. The impl Scene
body is split across files via inherent-impl-per-file; struct, ctor,
fields and load-time helpers stay in the root. fn count 123 -> 123.
- app/commands.rs (6082) -> app/commands/* grouped by command family.
The 233-arm dispatch match becomes source-ordered per-family
dispatch_* handlers, preserving first-match precedence (233 -> 233).
- app/view.rs (4686) -> app/view/{mod,overlay,modal,viewcube,controls}.
Largest file drops from 9650 to 3343. Builds clean; app launches and
loads plugins with no panic.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-26 22:51:29 +03:00
|
|
|
return name;
|
|
|
|
|
}
|
|
|
|
|
n += 1;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
pub(super) fn dispatch_command(&mut self, cmd: &str) -> Task<Message> {
|
2026-06-27 14:45:51 +03:00
|
|
|
self.dispatch_command_inner(cmd, false)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// Dispatch a verb typed at the interactive command line, falling back to
|
|
|
|
|
/// the closest autocomplete suggestion when the verb matches no command
|
|
|
|
|
/// family. Lets a partial command run on Enter (`BAC` → `BACKGROUND`),
|
|
|
|
|
/// the standard DWG command-line behavior. The fallback only fires for
|
|
|
|
|
/// genuinely unknown verbs, so complete aliases that resolve through a
|
|
|
|
|
/// dispatch family (`LT`, `ZO`, …) still run as typed. Programmatic
|
|
|
|
|
/// callers (ribbon, plugins, headless automation) use `dispatch_command`
|
|
|
|
|
/// and never get silent substitution.
|
|
|
|
|
pub(super) fn dispatch_command_or_suggest(&mut self, cmd: &str) -> Task<Message> {
|
|
|
|
|
self.dispatch_command_inner(cmd, true)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fn dispatch_command_inner(&mut self, cmd: &str, allow_suggest: bool) -> Task<Message> {
|
refactor: split four oversized files into submodule trees
Break up the four giant files (~29k lines total) into focused submodule
directories, one concern per file. Pure mechanical moves — behavior is
unchanged.
- app/update.rs (9650) -> app/update/{mod,viewport,command,style,file,
dynamic,dialog,util}. The 384-arm update_inner match stays in mod.rs
with thin delegating arms; the 66 fattest arm bodies move to topic
methods. Arm set preserved exactly (384 -> 384).
- scene/mod.rs (9017) -> scene/{mod,entity,tess,hittest,layout,paper,
mspace,project,selection,modify,group_layer,preview}. The impl Scene
body is split across files via inherent-impl-per-file; struct, ctor,
fields and load-time helpers stay in the root. fn count 123 -> 123.
- app/commands.rs (6082) -> app/commands/* grouped by command family.
The 233-arm dispatch match becomes source-ordered per-family
dispatch_* handlers, preserving first-match precedence (233 -> 233).
- app/view.rs (4686) -> app/view/{mod,overlay,modal,viewcube,controls}.
Largest file drops from 9650 to 3343. Builds clean; app launches and
loads plugins with no panic.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-26 22:51:29 +03:00
|
|
|
let i = self.active_tab;
|
feat(alias): centralize command aliases in user-editable ocad.pgp (#286/#288)
Command aliases (L→LINE, CC→COPYCLIP) were scattered across dispatch match
arms and CommandRegistration name arrays. Move them all into a single
user-editable file:
- assets/ocad.pgp: shipped default alias table (ALIAS,*COMMAND format),
embedded and copied to config/ocad.pgp on first launch; only that user
copy is read after. AA→AREA default closes #286.
- resolve_alias() rewrites the leading command token at the top of
dispatch_command_inner, so aliases resolve for every path (families,
plugins, Repeat menu). Args after the first space are untouched.
- Autocomplete hides alias keys and, when the whole input is an alias,
surfaces its target command as the top (highlighted) suggestion so the
highlight matches what Enter runs (AA→AREA, L→LINE).
- ALIASEDIT opens a new editor modal (add/edit/delete rows) with an Apply
button; Apply persists to ocad.pgp, closing discards unapplied edits.
- Strip alias tokens from all 8 dispatch match-arm files and 71 module
CommandRegistration arrays, keeping canonical/synonym/distinct-command
names. ocad.pgp is now the sole source: deleting or remapping an alias
there takes effect. CUI stays on the keyboard-shortcut panel.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-10 12:39:22 +03:00
|
|
|
// Expand a command alias ("L" → "LINE") on the leading token before any
|
|
|
|
|
// routing, so every path below (Start-tab gate, plugins, all dispatch
|
|
|
|
|
// families, the Repeat menu) sees the canonical command. Arguments after
|
|
|
|
|
// the first space are left untouched. A non-alias passes through as-is.
|
|
|
|
|
let resolved = self.resolve_alias(cmd);
|
|
|
|
|
let cmd = resolved.as_deref().unwrap_or(cmd);
|
fix(input): stop drafting-aid keys from cancelling the command
F8 reached ORTHO as an ordinary command, and dispatching a command tears
down whatever is running first: the active command dropped, its preview
cleared, its base point forgotten. So pressing F8 partway through a LINE
abandoned the line, and during a MOVE it took the dragged ghost with it.
A function key gets pressed mid-command — that is what it is for.
Toggles that only flip a flag now skip the teardown: ORTHO, GRID, SNAP,
POLAR, and the drafting-settings popup. None of them starts a command,
opens a document or reads geometry, so there is nothing for the teardown
to protect.
F7, F9 and F10 came through the same path and were broken the same way;
they are fixed with F8. F3, F11 and F12 already had messages of their
own and were never affected.
Closes #677
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-08 00:48:25 +03:00
|
|
|
// A drafting aid only flips a flag, so it must not disturb whatever is
|
|
|
|
|
// already running: pressing F8 partway through a LINE means "constrain
|
|
|
|
|
// the rest of this line", not "abandon it". Everything below tears the
|
|
|
|
|
// running command down, so a transparent one skips straight past it.
|
|
|
|
|
// (#677)
|
|
|
|
|
if is_transparent(cmd) {
|
|
|
|
|
return self
|
|
|
|
|
.dispatch_families(cmd, i)
|
|
|
|
|
.unwrap_or_else(Task::none);
|
|
|
|
|
}
|
refactor: split four oversized files into submodule trees
Break up the four giant files (~29k lines total) into focused submodule
directories, one concern per file. Pure mechanical moves — behavior is
unchanged.
- app/update.rs (9650) -> app/update/{mod,viewport,command,style,file,
dynamic,dialog,util}. The 384-arm update_inner match stays in mod.rs
with thin delegating arms; the 66 fattest arm bodies move to topic
methods. Arm set preserved exactly (384 -> 384).
- scene/mod.rs (9017) -> scene/{mod,entity,tess,hittest,layout,paper,
mspace,project,selection,modify,group_layer,preview}. The impl Scene
body is split across files via inherent-impl-per-file; struct, ctor,
fields and load-time helpers stay in the root. fn count 123 -> 123.
- app/commands.rs (6082) -> app/commands/* grouped by command family.
The 233-arm dispatch match becomes source-ordered per-family
dispatch_* handlers, preserving first-match precedence (233 -> 233).
- app/view.rs (4686) -> app/view/{mod,overlay,modal,viewcube,controls}.
Largest file drops from 9650 to 3343. Builds clean; app launches and
loads plugins with no panic.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-26 22:51:29 +03:00
|
|
|
// Starting a command closes any open ribbon dropdown (e.g. a style
|
|
|
|
|
// combo left open) so it does not stay stuck behind the new tool.
|
|
|
|
|
self.ribbon.close_dropdown();
|
feat(select): offer the selection modes at "Select objects"
Only Previous and Last were on offer, so Window, Crossing, Fence, the two
polygons and All could not be reached at all -- and with no keyboard to
type them into, the buttons were the only way in.
Window and Crossing fix the sense of the next box. Dragging derives that
from the direction the corner travels and would overwrite it the moment
the corner moved, so the derivation stands down while a keyword holds it.
Add and Remove decide what a pick does for the rest of the round: Remove
subtracts the way Shift already does, rather than through PICKADD, which
decides whether a pick *replaces* the set and so would have wiped
everything gathered so far. Both are dropped when the next command
starts, since neither outlives the selection that asked for them.
Fence and the polygons are picked point by point, which TRIM and EXTEND
already ask for. That gesture -- the points, the rubber-banded dashed
preview, whether the path closes -- moves into one place both bind to,
and the two preview builders duplicated in trim.rs go with it.
A fence is not the polygon test with crossing set: that closes the point
list and counts whatever lies inside, so a line drawn past a row of
objects would take everything behind it too. It gets a hit test that only
counts a real intersection, and skips the area-based geometry entirely.
The lasso gathered its hits from wires, hatches, block hatches, meshes and
block meshes inline; the new modes need the same list, and a second copy
would drift. Both now come through `Scene::path_hit_handles`.
Closes #596
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-07 13:32:11 +03:00
|
|
|
// Selection keywords last only for the round that asked for them: a
|
|
|
|
|
// Remove or a fixed Window sense must not quietly still be in force
|
|
|
|
|
// when the next command asks for objects. (#596)
|
|
|
|
|
self.select_remove_mode = false;
|
|
|
|
|
{
|
|
|
|
|
let mut selection = self.tabs[i].scene.selection.borrow_mut();
|
|
|
|
|
selection.box_crossing_locked = false;
|
|
|
|
|
}
|
refactor: split four oversized files into submodule trees
Break up the four giant files (~29k lines total) into focused submodule
directories, one concern per file. Pure mechanical moves — behavior is
unchanged.
- app/update.rs (9650) -> app/update/{mod,viewport,command,style,file,
dynamic,dialog,util}. The 384-arm update_inner match stays in mod.rs
with thin delegating arms; the 66 fattest arm bodies move to topic
methods. Arm set preserved exactly (384 -> 384).
- scene/mod.rs (9017) -> scene/{mod,entity,tess,hittest,layout,paper,
mspace,project,selection,modify,group_layer,preview}. The impl Scene
body is split across files via inherent-impl-per-file; struct, ctor,
fields and load-time helpers stay in the root. fn count 123 -> 123.
- app/commands.rs (6082) -> app/commands/* grouped by command family.
The 233-arm dispatch match becomes source-ordered per-family
dispatch_* handlers, preserving first-match precedence (233 -> 233).
- app/view.rs (4686) -> app/view/{mod,overlay,modal,viewcube,controls}.
Largest file drops from 9650 to 3343. Builds clean; app launches and
loads plugins with no panic.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-26 22:51:29 +03:00
|
|
|
// Cancel any running command before starting a new one.
|
|
|
|
|
if self.tabs[i].active_cmd.is_some() {
|
|
|
|
|
self.tabs[i].scene.clear_preview_wire();
|
|
|
|
|
self.tabs[i].active_cmd = None;
|
2026-07-03 16:05:54 +03:00
|
|
|
// Interrupting an ADDSELECTED draw with another command reverts its
|
|
|
|
|
// template-property override too (#239).
|
|
|
|
|
self.restore_add_selected_defaults();
|
refactor: split four oversized files into submodule trees
Break up the four giant files (~29k lines total) into focused submodule
directories, one concern per file. Pure mechanical moves — behavior is
unchanged.
- app/update.rs (9650) -> app/update/{mod,viewport,command,style,file,
dynamic,dialog,util}. The 384-arm update_inner match stays in mod.rs
with thin delegating arms; the 66 fattest arm bodies move to topic
methods. Arm set preserved exactly (384 -> 384).
- scene/mod.rs (9017) -> scene/{mod,entity,tess,hittest,layout,paper,
mspace,project,selection,modify,group_layer,preview}. The impl Scene
body is split across files via inherent-impl-per-file; struct, ctor,
fields and load-time helpers stay in the root. fn count 123 -> 123.
- app/commands.rs (6082) -> app/commands/* grouped by command family.
The 233-arm dispatch match becomes source-ordered per-family
dispatch_* handlers, preserving first-match precedence (233 -> 233).
- app/view.rs (4686) -> app/view/{mod,overlay,modal,viewcube,controls}.
Largest file drops from 9650 to 3343. Builds clean; app launches and
loads plugins with no panic.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-26 22:51:29 +03:00
|
|
|
}
|
2026-08-04 18:21:52 +03:00
|
|
|
// Starting any command leaves interactive navigation modes (their own
|
|
|
|
|
// command arms below re-enable the selected one).
|
refactor: split four oversized files into submodule trees
Break up the four giant files (~29k lines total) into focused submodule
directories, one concern per file. Pure mechanical moves — behavior is
unchanged.
- app/update.rs (9650) -> app/update/{mod,viewport,command,style,file,
dynamic,dialog,util}. The 384-arm update_inner match stays in mod.rs
with thin delegating arms; the 66 fattest arm bodies move to topic
methods. Arm set preserved exactly (384 -> 384).
- scene/mod.rs (9017) -> scene/{mod,entity,tess,hittest,layout,paper,
mspace,project,selection,modify,group_layer,preview}. The impl Scene
body is split across files via inherent-impl-per-file; struct, ctor,
fields and load-time helpers stay in the root. fn count 123 -> 123.
- app/commands.rs (6082) -> app/commands/* grouped by command family.
The 233-arm dispatch match becomes source-ordered per-family
dispatch_* handlers, preserving first-match precedence (233 -> 233).
- app/view.rs (4686) -> app/view/{mod,overlay,modal,viewcube,controls}.
Largest file drops from 9650 to 3343. Builds clean; app launches and
loads plugins with no panic.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-26 22:51:29 +03:00
|
|
|
self.tabs[i].pan_mode = false;
|
2026-08-04 18:21:52 +03:00
|
|
|
self.tabs[i].orbit_mode = false;
|
refactor: split four oversized files into submodule trees
Break up the four giant files (~29k lines total) into focused submodule
directories, one concern per file. Pure mechanical moves — behavior is
unchanged.
- app/update.rs (9650) -> app/update/{mod,viewport,command,style,file,
dynamic,dialog,util}. The 384-arm update_inner match stays in mod.rs
with thin delegating arms; the 66 fattest arm bodies move to topic
methods. Arm set preserved exactly (384 -> 384).
- scene/mod.rs (9017) -> scene/{mod,entity,tess,hittest,layout,paper,
mspace,project,selection,modify,group_layer,preview}. The impl Scene
body is split across files via inherent-impl-per-file; struct, ctor,
fields and load-time helpers stay in the root. fn count 123 -> 123.
- app/commands.rs (6082) -> app/commands/* grouped by command family.
The 233-arm dispatch match becomes source-ordered per-family
dispatch_* handlers, preserving first-match precedence (233 -> 233).
- app/view.rs (4686) -> app/view/{mod,overlay,modal,viewcube,controls}.
Largest file drops from 9650 to 3343. Builds clean; app launches and
loads plugins with no panic.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-26 22:51:29 +03:00
|
|
|
// Reset the last committed point so the first click of the new command
|
|
|
|
|
// is not constrained by ortho/polar relative to a previous command's endpoint.
|
|
|
|
|
self.last_point = None;
|
2026-06-27 16:32:40 +03:00
|
|
|
// Starting a command restarts the right-click cycle, so its first
|
|
|
|
|
// right-click acts as Enter rather than opening the context menu.
|
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 <noreply@anthropic.com>
2026-06-29 08:23:58 +03:00
|
|
|
self.tabs[i]
|
|
|
|
|
.scene
|
|
|
|
|
.selection
|
|
|
|
|
.borrow_mut()
|
|
|
|
|
.right_click_entered = false;
|
refactor: split four oversized files into submodule trees
Break up the four giant files (~29k lines total) into focused submodule
directories, one concern per file. Pure mechanical moves — behavior is
unchanged.
- app/update.rs (9650) -> app/update/{mod,viewport,command,style,file,
dynamic,dialog,util}. The 384-arm update_inner match stays in mod.rs
with thin delegating arms; the 66 fattest arm bodies move to topic
methods. Arm set preserved exactly (384 -> 384).
- scene/mod.rs (9017) -> scene/{mod,entity,tess,hittest,layout,paper,
mspace,project,selection,modify,group_layer,preview}. The impl Scene
body is split across files via inherent-impl-per-file; struct, ctor,
fields and load-time helpers stay in the root. fn count 123 -> 123.
- app/commands.rs (6082) -> app/commands/* grouped by command family.
The 233-arm dispatch match becomes source-ordered per-family
dispatch_* handlers, preserving first-match precedence (233 -> 233).
- app/view.rs (4686) -> app/view/{mod,overlay,modal,viewcube,controls}.
Largest file drops from 9650 to 3343. Builds clean; app launches and
loads plugins with no panic.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-26 22:51:29 +03:00
|
|
|
// A fresh command starts at the polar/cartesian default — clear
|
2026-07-27 16:15:28 +03:00
|
|
|
// any `,`-driven reshape and locked dynamic-input values from a
|
|
|
|
|
// previous command. Otherwise a bare Enter on the first point prompt
|
|
|
|
|
// can commit that stale coordinate instead of accepting the command's
|
|
|
|
|
// default (LIMITS then compares an unintended lower-left point with
|
|
|
|
|
// the displayed default upper-right).
|
refactor: split four oversized files into submodule trees
Break up the four giant files (~29k lines total) into focused submodule
directories, one concern per file. Pure mechanical moves — behavior is
unchanged.
- app/update.rs (9650) -> app/update/{mod,viewport,command,style,file,
dynamic,dialog,util}. The 384-arm update_inner match stays in mod.rs
with thin delegating arms; the 66 fattest arm bodies move to topic
methods. Arm set preserved exactly (384 -> 384).
- scene/mod.rs (9017) -> scene/{mod,entity,tess,hittest,layout,paper,
mspace,project,selection,modify,group_layer,preview}. The impl Scene
body is split across files via inherent-impl-per-file; struct, ctor,
fields and load-time helpers stay in the root. fn count 123 -> 123.
- app/commands.rs (6082) -> app/commands/* grouped by command family.
The 233-arm dispatch match becomes source-ordered per-family
dispatch_* handlers, preserving first-match precedence (233 -> 233).
- app/view.rs (4686) -> app/view/{mod,overlay,modal,viewcube,controls}.
Largest file drops from 9650 to 3343. Builds clean; app launches and
loads plugins with no panic.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-26 22:51:29 +03:00
|
|
|
self.dyn_user_reshaped = false;
|
2026-08-02 23:32:54 +03:00
|
|
|
self.dyn_coord_absolute = false;
|
2026-07-27 16:15:28 +03:00
|
|
|
self.tabs[i].dyn_fields.clear();
|
|
|
|
|
self.tabs[i].dyn_active = 0;
|
refactor: split four oversized files into submodule trees
Break up the four giant files (~29k lines total) into focused submodule
directories, one concern per file. Pure mechanical moves — behavior is
unchanged.
- app/update.rs (9650) -> app/update/{mod,viewport,command,style,file,
dynamic,dialog,util}. The 384-arm update_inner match stays in mod.rs
with thin delegating arms; the 66 fattest arm bodies move to topic
methods. Arm set preserved exactly (384 -> 384).
- scene/mod.rs (9017) -> scene/{mod,entity,tess,hittest,layout,paper,
mspace,project,selection,modify,group_layer,preview}. The impl Scene
body is split across files via inherent-impl-per-file; struct, ctor,
fields and load-time helpers stay in the root. fn count 123 -> 123.
- app/commands.rs (6082) -> app/commands/* grouped by command family.
The 233-arm dispatch match becomes source-ordered per-family
dispatch_* handlers, preserving first-match precedence (233 -> 233).
- app/view.rs (4686) -> app/view/{mod,overlay,modal,viewcube,controls}.
Largest file drops from 9650 to 3343. Builds clean; app launches and
loads plugins with no panic.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-26 22:51:29 +03:00
|
|
|
|
|
|
|
|
if let Some(path_str) = cmd.strip_prefix("OPEN_RECENT:") {
|
|
|
|
|
let path = PathBuf::from(path_str);
|
|
|
|
|
let size = std::fs::metadata(&path).map(|m| m.len()).unwrap_or(0);
|
|
|
|
|
return Task::done(Message::OpenPathPicked(Some((path, size))));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// The Start (welcome) tab has no drawing to act on, so a drawing
|
|
|
|
|
// command would silently do nothing. Allow only the commands that
|
|
|
|
|
// make sense there (create / open a document, or quit) and tell the
|
|
|
|
|
// user otherwise instead of running a no-op. See #96.
|
fix(start): let the welcome page's own buttons work (#388, #389)
Donate, Send Feedback, OCS Web and Manage > About all answered "No
drawing open — use New or Open first." and did nothing.
Two doors guarded the welcome tab and the outer one shadowed the inner.
`dispatch_command` already knew which commands stand alone — About,
Donate, Report and the links were all on its list — but
`on_ribbon_tool_click` refused every ribbon event before dispatch was
ever reached.
The welcome page's own buttons emit RibbonToolClick, so they are only
ever clickable while `is_start` holds: the refusal covered exactly the
case they exist in, and they had never worked. New Drawing / Open File /
Plugins send their own messages, which is why the page still looked
alive.
So the ribbon door now defers commands to dispatch and keeps refusing
only what touches the scene. The policy stays in one place instead of
being half-remembered in two. A drawing tool is still turned away on the
welcome tab (#299) — the wording just comes from dispatch now.
The same gap was swallowing tools the issues never mentioned: CUI and
ALIASEDIT configure the application, not a drawing, and were missing
from the list, so fixing only the ribbon door would have moved their
refusal one door down rather than removing it. HELP and CUILOAD /
CUIIMPORT join them.
The new test drives the real message path and fails on the old code with
the reported wording. It reads the allowlist from source rather than
dispatching DONATE / REPORT / WEBVERSION, which shell out to a browser —
that also fails the day someone adds a welcome-page button and forgets
the list.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-15 16:29:42 +03:00
|
|
|
// Anything that acts on the application rather than a drawing belongs
|
|
|
|
|
// here: document lifecycle, the links, and the app-wide configuration
|
|
|
|
|
// editors (shortcuts, aliases) — none of them read the scene. This is
|
|
|
|
|
// the single place that decides; `on_ribbon_tool_click` defers to it
|
|
|
|
|
// rather than keeping a second, blunter copy (#388, #389).
|
fix(ribbon): highlight follows each tool's mechanism; start-tab dimming (#355)
Tool highlights used to stick: every click set active_tool, but only
interactive commands and a hand-maintained per-modal list ever cleared
it, so one-shots (Cleanup/AUDIT, view actions) and unlisted dialogs
(Customization/ALIASEDIT, CUI, Plugin Manager…) stayed blue forever.
Now the rule is mechanical: state toggles light from state only (the
click highlight drops immediately), interactive commands stay lit
while running, dialog openers stay lit until the modal closes (generic
clear replaces the per-modal list), and one-shots never keep it — the
dispatch site turns the highlight off when nothing stayed running.
On the Start tab, tools whose command the start gate refuses now render
dimmed (grey icon + label) across all button styles, dropdowns and the
quick-access strip; start_allowed() is the single shared authority.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-22 00:13:48 +03:00
|
|
|
if self.tabs[i].is_start && !start_allowed(cmd) {
|
refactor: split four oversized files into submodule trees
Break up the four giant files (~29k lines total) into focused submodule
directories, one concern per file. Pure mechanical moves — behavior is
unchanged.
- app/update.rs (9650) -> app/update/{mod,viewport,command,style,file,
dynamic,dialog,util}. The 384-arm update_inner match stays in mod.rs
with thin delegating arms; the 66 fattest arm bodies move to topic
methods. Arm set preserved exactly (384 -> 384).
- scene/mod.rs (9017) -> scene/{mod,entity,tess,hittest,layout,paper,
mspace,project,selection,modify,group_layer,preview}. The impl Scene
body is split across files via inherent-impl-per-file; struct, ctor,
fields and load-time helpers stay in the root. fn count 123 -> 123.
- app/commands.rs (6082) -> app/commands/* grouped by command family.
The 233-arm dispatch match becomes source-ordered per-family
dispatch_* handlers, preserving first-match precedence (233 -> 233).
- app/view.rs (4686) -> app/view/{mod,overlay,modal,viewcube,controls}.
Largest file drops from 9650 to 3343. Builds clean; app launches and
loads plugins with no panic.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-26 22:51:29 +03:00
|
|
|
self.command_line
|
2026-08-02 22:09:25 +03:00
|
|
|
.push_info(crate::t!("No drawing open. Use NEW or OPEN to start a drawing.").as_ref());
|
refactor: split four oversized files into submodule trees
Break up the four giant files (~29k lines total) into focused submodule
directories, one concern per file. Pure mechanical moves — behavior is
unchanged.
- app/update.rs (9650) -> app/update/{mod,viewport,command,style,file,
dynamic,dialog,util}. The 384-arm update_inner match stays in mod.rs
with thin delegating arms; the 66 fattest arm bodies move to topic
methods. Arm set preserved exactly (384 -> 384).
- scene/mod.rs (9017) -> scene/{mod,entity,tess,hittest,layout,paper,
mspace,project,selection,modify,group_layer,preview}. The impl Scene
body is split across files via inherent-impl-per-file; struct, ctor,
fields and load-time helpers stay in the root. fn count 123 -> 123.
- app/commands.rs (6082) -> app/commands/* grouped by command family.
The 233-arm dispatch match becomes source-ordered per-family
dispatch_* handlers, preserving first-match precedence (233 -> 233).
- app/view.rs (4686) -> app/view/{mod,overlay,modal,viewcube,controls}.
Largest file drops from 9650 to 3343. Builds clean; app launches and
loads plugins with no panic.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-26 22:51:29 +03:00
|
|
|
return Task::none();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if crate::plugin::try_dispatch(self, i, cmd) {
|
|
|
|
|
// try_dispatch returns true for both finished commands and interactive
|
|
|
|
|
// commands that it just installed. If no command is now active, the
|
|
|
|
|
// tool was a one-shot and we must turn the ribbon highlight off here —
|
|
|
|
|
// normally apply_cmd_result does that, but plugin dispatch can return
|
|
|
|
|
// without producing a CmdResult.
|
2026-06-27 16:16:08 +03:00
|
|
|
self.command_line.record_recent(cmd);
|
refactor: split four oversized files into submodule trees
Break up the four giant files (~29k lines total) into focused submodule
directories, one concern per file. Pure mechanical moves — behavior is
unchanged.
- app/update.rs (9650) -> app/update/{mod,viewport,command,style,file,
dynamic,dialog,util}. The 384-arm update_inner match stays in mod.rs
with thin delegating arms; the 66 fattest arm bodies move to topic
methods. Arm set preserved exactly (384 -> 384).
- scene/mod.rs (9017) -> scene/{mod,entity,tess,hittest,layout,paper,
mspace,project,selection,modify,group_layer,preview}. The impl Scene
body is split across files via inherent-impl-per-file; struct, ctor,
fields and load-time helpers stay in the root. fn count 123 -> 123.
- app/commands.rs (6082) -> app/commands/* grouped by command family.
The 233-arm dispatch match becomes source-ordered per-family
dispatch_* handlers, preserving first-match precedence (233 -> 233).
- app/view.rs (4686) -> app/view/{mod,overlay,modal,viewcube,controls}.
Largest file drops from 9650 to 3343. Builds clean; app launches and
loads plugins with no panic.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-26 22:51:29 +03:00
|
|
|
if self.tabs[i].active_cmd.is_none() {
|
|
|
|
|
self.ribbon.deactivate_tool();
|
|
|
|
|
}
|
|
|
|
|
return Task::none();
|
|
|
|
|
}
|
|
|
|
|
|
2026-06-27 16:16:08 +03:00
|
|
|
// Command families are dispatched in source order (see
|
|
|
|
|
// `dispatch_families`); the first whose `match` arm matches handles it.
|
|
|
|
|
if let Some(t) = self.dispatch_families(cmd, i) {
|
|
|
|
|
// A command resolved — record it for the right-click Repeat menu so
|
|
|
|
|
// commands from every source (command line, ribbon, context menu,
|
|
|
|
|
// shortcuts) appear there, not only typed ones. Recorded after
|
|
|
|
|
// resolution so a partial verb completed via the suggestion
|
|
|
|
|
// fallback (`BAC`) stores the real command (`BACKGROUND`).
|
|
|
|
|
self.command_line.record_recent(cmd);
|
refactor: split four oversized files into submodule trees
Break up the four giant files (~29k lines total) into focused submodule
directories, one concern per file. Pure mechanical moves — behavior is
unchanged.
- app/update.rs (9650) -> app/update/{mod,viewport,command,style,file,
dynamic,dialog,util}. The 384-arm update_inner match stays in mod.rs
with thin delegating arms; the 66 fattest arm bodies move to topic
methods. Arm set preserved exactly (384 -> 384).
- scene/mod.rs (9017) -> scene/{mod,entity,tess,hittest,layout,paper,
mspace,project,selection,modify,group_layer,preview}. The impl Scene
body is split across files via inherent-impl-per-file; struct, ctor,
fields and load-time helpers stay in the root. fn count 123 -> 123.
- app/commands.rs (6082) -> app/commands/* grouped by command family.
The 233-arm dispatch match becomes source-ordered per-family
dispatch_* handlers, preserving first-match precedence (233 -> 233).
- app/view.rs (4686) -> app/view/{mod,overlay,modal,viewcube,controls}.
Largest file drops from 9650 to 3343. Builds clean; app launches and
loads plugins with no panic.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-26 22:51:29 +03:00
|
|
|
return t;
|
|
|
|
|
}
|
2026-06-27 16:16:08 +03:00
|
|
|
|
|
|
|
|
// No family matched. From the interactive command line, run the
|
|
|
|
|
// closest autocomplete suggestion instead of erroring, so a partial
|
|
|
|
|
// command completes on Enter (`BAC` → `BACKGROUND`). The verb's own
|
|
|
|
|
// input was already cleared, so rank against `cmd` directly.
|
|
|
|
|
if allow_suggest {
|
2026-07-04 23:01:53 +03:00
|
|
|
if let Some(top) = crate::ui::command_line::ranked_matches(
|
|
|
|
|
cmd,
|
|
|
|
|
&self.command_line.dynamic_commands,
|
feat(alias): centralize command aliases in user-editable ocad.pgp (#286/#288)
Command aliases (L→LINE, CC→COPYCLIP) were scattered across dispatch match
arms and CommandRegistration name arrays. Move them all into a single
user-editable file:
- assets/ocad.pgp: shipped default alias table (ALIAS,*COMMAND format),
embedded and copied to config/ocad.pgp on first launch; only that user
copy is read after. AA→AREA default closes #286.
- resolve_alias() rewrites the leading command token at the top of
dispatch_command_inner, so aliases resolve for every path (families,
plugins, Repeat menu). Args after the first space are untouched.
- Autocomplete hides alias keys and, when the whole input is an alias,
surfaces its target command as the top (highlighted) suggestion so the
highlight matches what Enter runs (AA→AREA, L→LINE).
- ALIASEDIT opens a new editor modal (add/edit/delete rows) with an Apply
button; Apply persists to ocad.pgp, closing discards unapplied edits.
- Strip alias tokens from all 8 dispatch match-arm files and 71 module
CommandRegistration arrays, keeping canonical/synonym/distinct-command
names. ocad.pgp is now the sole source: deleting or remapping an alias
there takes effect. CUI stays on the keyboard-shortcut panel.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-10 12:39:22 +03:00
|
|
|
&self.command_line.command_aliases,
|
2026-07-04 23:01:53 +03:00
|
|
|
)
|
|
|
|
|
.into_iter()
|
|
|
|
|
.next()
|
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 <noreply@anthropic.com>
2026-06-29 08:23:58 +03:00
|
|
|
{
|
2026-06-27 16:16:08 +03:00
|
|
|
if !top.eq_ignore_ascii_case(cmd) {
|
2026-07-04 23:01:53 +03:00
|
|
|
return self.dispatch_command_inner(&top, false);
|
2026-06-27 16:16:08 +03:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
self.command_line
|
2026-08-02 22:09:25 +03:00
|
|
|
.push_error(crate::tf!("Unknown command: {cmd}").as_ref());
|
2026-06-27 16:16:08 +03:00
|
|
|
self.finish_dispatch(cmd)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// Try each command family in source order, returning the first that
|
|
|
|
|
/// handles `cmd`, or `None` when none match. Each family returns
|
|
|
|
|
/// `Some(task)` for an arm it owns (early-returning or falling through to
|
|
|
|
|
/// `finish_dispatch`), or `None` to defer to the next — equivalent to one
|
|
|
|
|
/// sequential `match` over all arms.
|
|
|
|
|
fn dispatch_families(&mut self, cmd: &str, i: usize) -> Option<Task<Message>> {
|
|
|
|
|
if let Some(t) = self.dispatch_fileops(cmd, i) {
|
|
|
|
|
return Some(t);
|
|
|
|
|
}
|
refactor: split four oversized files into submodule trees
Break up the four giant files (~29k lines total) into focused submodule
directories, one concern per file. Pure mechanical moves — behavior is
unchanged.
- app/update.rs (9650) -> app/update/{mod,viewport,command,style,file,
dynamic,dialog,util}. The 384-arm update_inner match stays in mod.rs
with thin delegating arms; the 66 fattest arm bodies move to topic
methods. Arm set preserved exactly (384 -> 384).
- scene/mod.rs (9017) -> scene/{mod,entity,tess,hittest,layout,paper,
mspace,project,selection,modify,group_layer,preview}. The impl Scene
body is split across files via inherent-impl-per-file; struct, ctor,
fields and load-time helpers stay in the root. fn count 123 -> 123.
- app/commands.rs (6082) -> app/commands/* grouped by command family.
The 233-arm dispatch match becomes source-ordered per-family
dispatch_* handlers, preserving first-match precedence (233 -> 233).
- app/view.rs (4686) -> app/view/{mod,overlay,modal,viewcube,controls}.
Largest file drops from 9650 to 3343. Builds clean; app launches and
loads plugins with no panic.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-26 22:51:29 +03:00
|
|
|
if let Some(t) = self.dispatch_layers(cmd, i) {
|
2026-06-27 16:16:08 +03:00
|
|
|
return Some(t);
|
refactor: split four oversized files into submodule trees
Break up the four giant files (~29k lines total) into focused submodule
directories, one concern per file. Pure mechanical moves — behavior is
unchanged.
- app/update.rs (9650) -> app/update/{mod,viewport,command,style,file,
dynamic,dialog,util}. The 384-arm update_inner match stays in mod.rs
with thin delegating arms; the 66 fattest arm bodies move to topic
methods. Arm set preserved exactly (384 -> 384).
- scene/mod.rs (9017) -> scene/{mod,entity,tess,hittest,layout,paper,
mspace,project,selection,modify,group_layer,preview}. The impl Scene
body is split across files via inherent-impl-per-file; struct, ctor,
fields and load-time helpers stay in the root. fn count 123 -> 123.
- app/commands.rs (6082) -> app/commands/* grouped by command family.
The 233-arm dispatch match becomes source-ordered per-family
dispatch_* handlers, preserving first-match precedence (233 -> 233).
- app/view.rs (4686) -> app/view/{mod,overlay,modal,viewcube,controls}.
Largest file drops from 9650 to 3343. Builds clean; app launches and
loads plugins with no panic.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-26 22:51:29 +03:00
|
|
|
}
|
|
|
|
|
if let Some(t) = self.dispatch_blocks(cmd, i) {
|
2026-06-27 16:16:08 +03:00
|
|
|
return Some(t);
|
refactor: split four oversized files into submodule trees
Break up the four giant files (~29k lines total) into focused submodule
directories, one concern per file. Pure mechanical moves — behavior is
unchanged.
- app/update.rs (9650) -> app/update/{mod,viewport,command,style,file,
dynamic,dialog,util}. The 384-arm update_inner match stays in mod.rs
with thin delegating arms; the 66 fattest arm bodies move to topic
methods. Arm set preserved exactly (384 -> 384).
- scene/mod.rs (9017) -> scene/{mod,entity,tess,hittest,layout,paper,
mspace,project,selection,modify,group_layer,preview}. The impl Scene
body is split across files via inherent-impl-per-file; struct, ctor,
fields and load-time helpers stay in the root. fn count 123 -> 123.
- app/commands.rs (6082) -> app/commands/* grouped by command family.
The 233-arm dispatch match becomes source-ordered per-family
dispatch_* handlers, preserving first-match precedence (233 -> 233).
- app/view.rs (4686) -> app/view/{mod,overlay,modal,viewcube,controls}.
Largest file drops from 9650 to 3343. Builds clean; app launches and
loads plugins with no panic.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-26 22:51:29 +03:00
|
|
|
}
|
|
|
|
|
if let Some(t) = self.dispatch_draw(cmd, i) {
|
2026-06-27 16:16:08 +03:00
|
|
|
return Some(t);
|
refactor: split four oversized files into submodule trees
Break up the four giant files (~29k lines total) into focused submodule
directories, one concern per file. Pure mechanical moves — behavior is
unchanged.
- app/update.rs (9650) -> app/update/{mod,viewport,command,style,file,
dynamic,dialog,util}. The 384-arm update_inner match stays in mod.rs
with thin delegating arms; the 66 fattest arm bodies move to topic
methods. Arm set preserved exactly (384 -> 384).
- scene/mod.rs (9017) -> scene/{mod,entity,tess,hittest,layout,paper,
mspace,project,selection,modify,group_layer,preview}. The impl Scene
body is split across files via inherent-impl-per-file; struct, ctor,
fields and load-time helpers stay in the root. fn count 123 -> 123.
- app/commands.rs (6082) -> app/commands/* grouped by command family.
The 233-arm dispatch match becomes source-ordered per-family
dispatch_* handlers, preserving first-match precedence (233 -> 233).
- app/view.rs (4686) -> app/view/{mod,overlay,modal,viewcube,controls}.
Largest file drops from 9650 to 3343. Builds clean; app launches and
loads plugins with no panic.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-26 22:51:29 +03:00
|
|
|
}
|
|
|
|
|
if let Some(t) = self.dispatch_dim(cmd, i) {
|
2026-06-27 16:16:08 +03:00
|
|
|
return Some(t);
|
refactor: split four oversized files into submodule trees
Break up the four giant files (~29k lines total) into focused submodule
directories, one concern per file. Pure mechanical moves — behavior is
unchanged.
- app/update.rs (9650) -> app/update/{mod,viewport,command,style,file,
dynamic,dialog,util}. The 384-arm update_inner match stays in mod.rs
with thin delegating arms; the 66 fattest arm bodies move to topic
methods. Arm set preserved exactly (384 -> 384).
- scene/mod.rs (9017) -> scene/{mod,entity,tess,hittest,layout,paper,
mspace,project,selection,modify,group_layer,preview}. The impl Scene
body is split across files via inherent-impl-per-file; struct, ctor,
fields and load-time helpers stay in the root. fn count 123 -> 123.
- app/commands.rs (6082) -> app/commands/* grouped by command family.
The 233-arm dispatch match becomes source-ordered per-family
dispatch_* handlers, preserving first-match precedence (233 -> 233).
- app/view.rs (4686) -> app/view/{mod,overlay,modal,viewcube,controls}.
Largest file drops from 9650 to 3343. Builds clean; app launches and
loads plugins with no panic.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-26 22:51:29 +03:00
|
|
|
}
|
|
|
|
|
if let Some(t) = self.dispatch_inquiry(cmd, i) {
|
2026-06-27 16:16:08 +03:00
|
|
|
return Some(t);
|
refactor: split four oversized files into submodule trees
Break up the four giant files (~29k lines total) into focused submodule
directories, one concern per file. Pure mechanical moves — behavior is
unchanged.
- app/update.rs (9650) -> app/update/{mod,viewport,command,style,file,
dynamic,dialog,util}. The 384-arm update_inner match stays in mod.rs
with thin delegating arms; the 66 fattest arm bodies move to topic
methods. Arm set preserved exactly (384 -> 384).
- scene/mod.rs (9017) -> scene/{mod,entity,tess,hittest,layout,paper,
mspace,project,selection,modify,group_layer,preview}. The impl Scene
body is split across files via inherent-impl-per-file; struct, ctor,
fields and load-time helpers stay in the root. fn count 123 -> 123.
- app/commands.rs (6082) -> app/commands/* grouped by command family.
The 233-arm dispatch match becomes source-ordered per-family
dispatch_* handlers, preserving first-match precedence (233 -> 233).
- app/view.rs (4686) -> app/view/{mod,overlay,modal,viewcube,controls}.
Largest file drops from 9650 to 3343. Builds clean; app launches and
loads plugins with no panic.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-26 22:51:29 +03:00
|
|
|
}
|
|
|
|
|
if let Some(t) = self.dispatch_view(cmd, i) {
|
2026-06-27 16:16:08 +03:00
|
|
|
return Some(t);
|
refactor: split four oversized files into submodule trees
Break up the four giant files (~29k lines total) into focused submodule
directories, one concern per file. Pure mechanical moves — behavior is
unchanged.
- app/update.rs (9650) -> app/update/{mod,viewport,command,style,file,
dynamic,dialog,util}. The 384-arm update_inner match stays in mod.rs
with thin delegating arms; the 66 fattest arm bodies move to topic
methods. Arm set preserved exactly (384 -> 384).
- scene/mod.rs (9017) -> scene/{mod,entity,tess,hittest,layout,paper,
mspace,project,selection,modify,group_layer,preview}. The impl Scene
body is split across files via inherent-impl-per-file; struct, ctor,
fields and load-time helpers stay in the root. fn count 123 -> 123.
- app/commands.rs (6082) -> app/commands/* grouped by command family.
The 233-arm dispatch match becomes source-ordered per-family
dispatch_* handlers, preserving first-match precedence (233 -> 233).
- app/view.rs (4686) -> app/view/{mod,overlay,modal,viewcube,controls}.
Largest file drops from 9650 to 3343. Builds clean; app launches and
loads plugins with no panic.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-26 22:51:29 +03:00
|
|
|
}
|
|
|
|
|
if let Some(t) = self.dispatch_layerprops(cmd, i) {
|
2026-06-27 16:16:08 +03:00
|
|
|
return Some(t);
|
refactor: split four oversized files into submodule trees
Break up the four giant files (~29k lines total) into focused submodule
directories, one concern per file. Pure mechanical moves — behavior is
unchanged.
- app/update.rs (9650) -> app/update/{mod,viewport,command,style,file,
dynamic,dialog,util}. The 384-arm update_inner match stays in mod.rs
with thin delegating arms; the 66 fattest arm bodies move to topic
methods. Arm set preserved exactly (384 -> 384).
- scene/mod.rs (9017) -> scene/{mod,entity,tess,hittest,layout,paper,
mspace,project,selection,modify,group_layer,preview}. The impl Scene
body is split across files via inherent-impl-per-file; struct, ctor,
fields and load-time helpers stay in the root. fn count 123 -> 123.
- app/commands.rs (6082) -> app/commands/* grouped by command family.
The 233-arm dispatch match becomes source-ordered per-family
dispatch_* handlers, preserving first-match precedence (233 -> 233).
- app/view.rs (4686) -> app/view/{mod,overlay,modal,viewcube,controls}.
Largest file drops from 9650 to 3343. Builds clean; app launches and
loads plugins with no panic.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-26 22:51:29 +03:00
|
|
|
}
|
|
|
|
|
if let Some(t) = self.dispatch_styleprops(cmd, i) {
|
2026-06-27 16:16:08 +03:00
|
|
|
return Some(t);
|
refactor: split four oversized files into submodule trees
Break up the four giant files (~29k lines total) into focused submodule
directories, one concern per file. Pure mechanical moves — behavior is
unchanged.
- app/update.rs (9650) -> app/update/{mod,viewport,command,style,file,
dynamic,dialog,util}. The 384-arm update_inner match stays in mod.rs
with thin delegating arms; the 66 fattest arm bodies move to topic
methods. Arm set preserved exactly (384 -> 384).
- scene/mod.rs (9017) -> scene/{mod,entity,tess,hittest,layout,paper,
mspace,project,selection,modify,group_layer,preview}. The impl Scene
body is split across files via inherent-impl-per-file; struct, ctor,
fields and load-time helpers stay in the root. fn count 123 -> 123.
- app/commands.rs (6082) -> app/commands/* grouped by command family.
The 233-arm dispatch match becomes source-ordered per-family
dispatch_* handlers, preserving first-match precedence (233 -> 233).
- app/view.rs (4686) -> app/view/{mod,overlay,modal,viewcube,controls}.
Largest file drops from 9650 to 3343. Builds clean; app launches and
loads plugins with no panic.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-26 22:51:29 +03:00
|
|
|
}
|
|
|
|
|
if let Some(t) = self.dispatch_display(cmd, i) {
|
2026-06-27 16:16:08 +03:00
|
|
|
return Some(t);
|
2026-06-27 14:45:51 +03:00
|
|
|
}
|
2026-06-27 16:16:08 +03:00
|
|
|
None
|
refactor: split four oversized files into submodule trees
Break up the four giant files (~29k lines total) into focused submodule
directories, one concern per file. Pure mechanical moves — behavior is
unchanged.
- app/update.rs (9650) -> app/update/{mod,viewport,command,style,file,
dynamic,dialog,util}. The 384-arm update_inner match stays in mod.rs
with thin delegating arms; the 66 fattest arm bodies move to topic
methods. Arm set preserved exactly (384 -> 384).
- scene/mod.rs (9017) -> scene/{mod,entity,tess,hittest,layout,paper,
mspace,project,selection,modify,group_layer,preview}. The impl Scene
body is split across files via inherent-impl-per-file; struct, ctor,
fields and load-time helpers stay in the root. fn count 123 -> 123.
- app/commands.rs (6082) -> app/commands/* grouped by command family.
The 233-arm dispatch match becomes source-ordered per-family
dispatch_* handlers, preserving first-match precedence (233 -> 233).
- app/view.rs (4686) -> app/view/{mod,overlay,modal,viewcube,controls}.
Largest file drops from 9650 to 3343. Builds clean; app launches and
loads plugins with no panic.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-26 22:51:29 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// Shared tail run after a `dispatch_*` family handler whose matched arm
|
|
|
|
|
/// did not early-return. Focuses the command line whenever a command just
|
|
|
|
|
/// became active.
|
|
|
|
|
fn finish_dispatch(&mut self, cmd: &str) -> Task<Message> {
|
|
|
|
|
let i = self.active_tab;
|
|
|
|
|
if self.tabs[i].active_cmd.is_some() {
|
|
|
|
|
self.tabs[i].last_cmd = Some(cmd.to_string());
|
2026-07-27 16:15:28 +03:00
|
|
|
self.sync_dyn_fields();
|
refactor: split four oversized files into submodule trees
Break up the four giant files (~29k lines total) into focused submodule
directories, one concern per file. Pure mechanical moves — behavior is
unchanged.
- app/update.rs (9650) -> app/update/{mod,viewport,command,style,file,
dynamic,dialog,util}. The 384-arm update_inner match stays in mod.rs
with thin delegating arms; the 66 fattest arm bodies move to topic
methods. Arm set preserved exactly (384 -> 384).
- scene/mod.rs (9017) -> scene/{mod,entity,tess,hittest,layout,paper,
mspace,project,selection,modify,group_layer,preview}. The impl Scene
body is split across files via inherent-impl-per-file; struct, ctor,
fields and load-time helpers stay in the root. fn count 123 -> 123.
- app/commands.rs (6082) -> app/commands/* grouped by command family.
The 233-arm dispatch match becomes source-ordered per-family
dispatch_* handlers, preserving first-match precedence (233 -> 233).
- app/view.rs (4686) -> app/view/{mod,overlay,modal,viewcube,controls}.
Largest file drops from 9650 to 3343. Builds clean; app launches and
loads plugins with no panic.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-26 22:51:29 +03:00
|
|
|
self.focus_cmd_input()
|
|
|
|
|
} else {
|
|
|
|
|
Task::none()
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
fix(input): stop drafting-aid keys from cancelling the command
F8 reached ORTHO as an ordinary command, and dispatching a command tears
down whatever is running first: the active command dropped, its preview
cleared, its base point forgotten. So pressing F8 partway through a LINE
abandoned the line, and during a MOVE it took the dragged ghost with it.
A function key gets pressed mid-command — that is what it is for.
Toggles that only flip a flag now skip the teardown: ORTHO, GRID, SNAP,
POLAR, and the drafting-settings popup. None of them starts a command,
opens a document or reads geometry, so there is nothing for the teardown
to protect.
F7, F9 and F10 came through the same path and were broken the same way;
they are fixed with F8. F3, F11 and F12 already had messages of their
own and were never affected.
Closes #677
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-08 00:48:25 +03:00
|
|
|
/// Commands that toggle a drafting aid and nothing else.
|
|
|
|
|
///
|
|
|
|
|
/// They are reachable from a function key, and a function key gets pressed
|
|
|
|
|
/// mid-command — that is the point of it. Running them through the ordinary
|
|
|
|
|
/// path cancelled the active command, cleared its preview and dropped its base
|
|
|
|
|
/// point, so F8 during a MOVE both ended the move and made the dragged ghost
|
|
|
|
|
/// vanish. Nothing here starts a command, opens a document or reads geometry,
|
|
|
|
|
/// so there is nothing for the teardown to protect. (#677)
|
|
|
|
|
pub fn is_transparent(cmd: &str) -> bool {
|
|
|
|
|
matches!(
|
|
|
|
|
cmd,
|
|
|
|
|
"ORTHO" | "GRID" | "SNAP" | "POLAR" | "OSNAP" | "DSETTINGS"
|
|
|
|
|
)
|
|
|
|
|
}
|
|
|
|
|
|
fix(ribbon): highlight follows each tool's mechanism; start-tab dimming (#355)
Tool highlights used to stick: every click set active_tool, but only
interactive commands and a hand-maintained per-modal list ever cleared
it, so one-shots (Cleanup/AUDIT, view actions) and unlisted dialogs
(Customization/ALIASEDIT, CUI, Plugin Manager…) stayed blue forever.
Now the rule is mechanical: state toggles light from state only (the
click highlight drops immediately), interactive commands stay lit
while running, dialog openers stay lit until the modal closes (generic
clear replaces the per-modal list), and one-shots never keep it — the
dispatch site turns the highlight off when nothing stayed running.
On the Start tab, tools whose command the start gate refuses now render
dimmed (grey icon + label) across all button styles, dropdowns and the
quick-access strip; start_allowed() is the single shared authority.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-22 00:13:48 +03:00
|
|
|
/// Whether `cmd` makes sense on the Start (welcome) tab — document lifecycle,
|
|
|
|
|
/// links, and app-wide configuration; nothing that reads the scene. Single
|
|
|
|
|
/// source of truth: the dispatch gate refuses everything else, and the ribbon
|
|
|
|
|
/// dims the tools this rejects.
|
|
|
|
|
pub fn start_allowed(cmd: &str) -> bool {
|
|
|
|
|
matches!(
|
|
|
|
|
cmd,
|
|
|
|
|
"NEW"
|
|
|
|
|
| "OPEN"
|
|
|
|
|
| "EXIT"
|
|
|
|
|
| "QUIT"
|
|
|
|
|
| "REPORT"
|
|
|
|
|
| "CHANGELOG"
|
|
|
|
|
| "ABOUT"
|
2026-07-29 16:28:20 +03:00
|
|
|
| "PLUGINS"
|
|
|
|
|
| "PLUGINMANAGER"
|
fix(ribbon): highlight follows each tool's mechanism; start-tab dimming (#355)
Tool highlights used to stick: every click set active_tool, but only
interactive commands and a hand-maintained per-modal list ever cleared
it, so one-shots (Cleanup/AUDIT, view actions) and unlisted dialogs
(Customization/ALIASEDIT, CUI, Plugin Manager…) stayed blue forever.
Now the rule is mechanical: state toggles light from state only (the
click highlight drops immediately), interactive commands stay lit
while running, dialog openers stay lit until the modal closes (generic
clear replaces the per-modal list), and one-shots never keep it — the
dispatch site turns the highlight off when nothing stayed running.
On the Start tab, tools whose command the start gate refuses now render
dimmed (grey icon + label) across all button styles, dropdowns and the
quick-access strip; start_allowed() is the single shared authority.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-22 00:13:48 +03:00
|
|
|
| "DONATE"
|
|
|
|
|
| "WEBVERSION"
|
|
|
|
|
| "HELP"
|
2026-07-25 13:34:48 +03:00
|
|
|
| "PERF"
|
fix(ribbon): highlight follows each tool's mechanism; start-tab dimming (#355)
Tool highlights used to stick: every click set active_tool, but only
interactive commands and a hand-maintained per-modal list ever cleared
it, so one-shots (Cleanup/AUDIT, view actions) and unlisted dialogs
(Customization/ALIASEDIT, CUI, Plugin Manager…) stayed blue forever.
Now the rule is mechanical: state toggles light from state only (the
click highlight drops immediately), interactive commands stay lit
while running, dialog openers stay lit until the modal closes (generic
clear replaces the per-modal list), and one-shots never keep it — the
dispatch site turns the highlight off when nothing stayed running.
On the Start tab, tools whose command the start gate refuses now render
dimmed (grey icon + label) across all button styles, dropdowns and the
quick-access strip; start_allowed() is the single shared authority.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-22 00:13:48 +03:00
|
|
|
| "CUI"
|
|
|
|
|
| "ALIASEDIT"
|
|
|
|
|
| "CUILOAD"
|
|
|
|
|
| "CUIIMPORT"
|
|
|
|
|
)
|
|
|
|
|
}
|
|
|
|
|
|
refactor: split four oversized files into submodule trees
Break up the four giant files (~29k lines total) into focused submodule
directories, one concern per file. Pure mechanical moves — behavior is
unchanged.
- app/update.rs (9650) -> app/update/{mod,viewport,command,style,file,
dynamic,dialog,util}. The 384-arm update_inner match stays in mod.rs
with thin delegating arms; the 66 fattest arm bodies move to topic
methods. Arm set preserved exactly (384 -> 384).
- scene/mod.rs (9017) -> scene/{mod,entity,tess,hittest,layout,paper,
mspace,project,selection,modify,group_layer,preview}. The impl Scene
body is split across files via inherent-impl-per-file; struct, ctor,
fields and load-time helpers stay in the root. fn count 123 -> 123.
- app/commands.rs (6082) -> app/commands/* grouped by command family.
The 233-arm dispatch match becomes source-ordered per-family
dispatch_* handlers, preserving first-match precedence (233 -> 233).
- app/view.rs (4686) -> app/view/{mod,overlay,modal,viewcube,controls}.
Largest file drops from 9650 to 3343. Builds clean; app launches and
loads plugins with no panic.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-26 22:51:29 +03:00
|
|
|
// ── Autocomplete registry — one-shot commands ──────────────────────────────
|
|
|
|
|
// These commands dispatch a single action (file ops, view, layer/style
|
|
|
|
|
// managers, undo/redo, …) rather than installing an interactive `CadCommand`,
|
|
|
|
|
// so they have no module of their own to register from. They are surfaced for
|
|
|
|
|
// command-line autocomplete here. Internal dispatch tokens that the user never
|
|
|
|
|
// types (REFEDIT_BEGIN, REFCLOSE_SAVE, REFCLOSE_DISCARD) are intentionally
|
|
|
|
|
// excluded.
|
|
|
|
|
inventory::submit!(crate::command::CommandRegistration {
|
|
|
|
|
names: &[
|
feat(commands): integrate standard CAD commands and fix behavior gaps
Broad pass over the command set: integrate missing commands, wire
previously-unreachable ribbon/menu buttons, and correct name/behaviour
mismatches. Every UI command token now resolves (real handler where the
infrastructure exists, an honest "not yet implemented" status otherwise).
New commands:
- Draw: 3DPOLY, 2D solid (SO/SOLID2D), HELIX, TRACE, SKETCH, DIMCENTER
(DCE/CENTERMARK)
- Modify/inquiry: REVERSE, MEASUREGEOM (MEA), DBLIST
- Data/manage: BASE, OVERKILL (exact-duplicate removal), AUDIT (read-only
integrity report), SETVAR (system-variable get/set), SCRIPT (.scr runner),
FINDNONPURGEABLE
Behaviour fixes:
- LINE and SPLINE gain Close/Undo; AREA computes area/perimeter in f64
(correct at large coordinates)
- ATTEDIT/ATE unified so the alias and the ribbon button open the
interactive editor; -ATTEDIT is the command-line form
- Linear/aligned/radius/diameter dimensions gain a text override (Text) and
text angle (Angle) option
- INSERT gains Scale/Rotate options; COPY gains an Array option
- LINETYPE SET sets the current entity linetype; SETBYLAYER resets overrides
- UNDO accepts a step count
Integrations: standard dimension/block aliases (DLI/DRA/DAN, BMAKE,
EXPORTPDF, DDIM), drafting-aid and screen toggles (GRID/SNAP/POLAR/OSNAP/
DSETTINGS/CLEANSCREEN/QUICKPROPERTIES), viewport tiling
(CASCADE/HORIZONTAL/VERTICAL/VPJOIN), and customization entry points
(CUI/ALIASEDIT).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-28 19:27:35 +03:00
|
|
|
// Drafting-aid / display toggles + customization entry points wired in the
|
|
|
|
|
// dispatch families (no interactive command module of their own).
|
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 <noreply@anthropic.com>
2026-06-29 08:23:58 +03:00
|
|
|
"ALIASEDIT",
|
|
|
|
|
"CLEANSCREEN",
|
|
|
|
|
"CUI",
|
|
|
|
|
"DSETTINGS",
|
|
|
|
|
"GRID",
|
|
|
|
|
"OSNAP",
|
|
|
|
|
"POLAR",
|
|
|
|
|
"QUICKPROPERTIES",
|
|
|
|
|
"SNAP",
|
|
|
|
|
"OPTIONS",
|
|
|
|
|
"OP",
|
|
|
|
|
"SYNCPVIEWPORTS",
|
|
|
|
|
"VPSYNC",
|
feat(commands): integrate standard CAD commands and fix behavior gaps
Broad pass over the command set: integrate missing commands, wire
previously-unreachable ribbon/menu buttons, and correct name/behaviour
mismatches. Every UI command token now resolves (real handler where the
infrastructure exists, an honest "not yet implemented" status otherwise).
New commands:
- Draw: 3DPOLY, 2D solid (SO/SOLID2D), HELIX, TRACE, SKETCH, DIMCENTER
(DCE/CENTERMARK)
- Modify/inquiry: REVERSE, MEASUREGEOM (MEA), DBLIST
- Data/manage: BASE, OVERKILL (exact-duplicate removal), AUDIT (read-only
integrity report), SETVAR (system-variable get/set), SCRIPT (.scr runner),
FINDNONPURGEABLE
Behaviour fixes:
- LINE and SPLINE gain Close/Undo; AREA computes area/perimeter in f64
(correct at large coordinates)
- ATTEDIT/ATE unified so the alias and the ribbon button open the
interactive editor; -ATTEDIT is the command-line form
- Linear/aligned/radius/diameter dimensions gain a text override (Text) and
text angle (Angle) option
- INSERT gains Scale/Rotate options; COPY gains an Array option
- LINETYPE SET sets the current entity linetype; SETBYLAYER resets overrides
- UNDO accepts a step count
Integrations: standard dimension/block aliases (DLI/DRA/DAN, BMAKE,
EXPORTPDF, DDIM), drafting-aid and screen toggles (GRID/SNAP/POLAR/OSNAP/
DSETTINGS/CLEANSCREEN/QUICKPROPERTIES), viewport tiling
(CASCADE/HORIZONTAL/VERTICAL/VPJOIN), and customization entry points
(CUI/ALIASEDIT).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-28 19:27:35 +03:00
|
|
|
// Viewport-arrangement shortcuts (delegate to VPORTS configurations).
|
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 <noreply@anthropic.com>
2026-06-29 08:23:58 +03:00
|
|
|
"CASCADE",
|
|
|
|
|
"HORIZONTAL",
|
|
|
|
|
"VERTICAL",
|
|
|
|
|
"VPJOIN",
|
feat(commands): integrate standard CAD commands and fix behavior gaps
Broad pass over the command set: integrate missing commands, wire
previously-unreachable ribbon/menu buttons, and correct name/behaviour
mismatches. Every UI command token now resolves (real handler where the
infrastructure exists, an honest "not yet implemented" status otherwise).
New commands:
- Draw: 3DPOLY, 2D solid (SO/SOLID2D), HELIX, TRACE, SKETCH, DIMCENTER
(DCE/CENTERMARK)
- Modify/inquiry: REVERSE, MEASUREGEOM (MEA), DBLIST
- Data/manage: BASE, OVERKILL (exact-duplicate removal), AUDIT (read-only
integrity report), SETVAR (system-variable get/set), SCRIPT (.scr runner),
FINDNONPURGEABLE
Behaviour fixes:
- LINE and SPLINE gain Close/Undo; AREA computes area/perimeter in f64
(correct at large coordinates)
- ATTEDIT/ATE unified so the alias and the ribbon button open the
interactive editor; -ATTEDIT is the command-line form
- Linear/aligned/radius/diameter dimensions gain a text override (Text) and
text angle (Angle) option
- INSERT gains Scale/Rotate options; COPY gains an Array option
- LINETYPE SET sets the current entity linetype; SETBYLAYER resets overrides
- UNDO accepts a step count
Integrations: standard dimension/block aliases (DLI/DRA/DAN, BMAKE,
EXPORTPDF, DDIM), drafting-aid and screen toggles (GRID/SNAP/POLAR/OSNAP/
DSETTINGS/CLEANSCREEN/QUICKPROPERTIES), viewport tiling
(CASCADE/HORIZONTAL/VERTICAL/VPJOIN), and customization entry points
(CUI/ALIASEDIT).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-28 19:27:35 +03:00
|
|
|
// Standard aliases for existing commands.
|
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 <noreply@anthropic.com>
2026-06-29 08:23:58 +03:00
|
|
|
"BMAKE",
|
|
|
|
|
"EXPORTPDF",
|
2026-08-04 11:29:11 +03:00
|
|
|
"PRINTALL",
|
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 <noreply@anthropic.com>
2026-06-29 08:23:58 +03:00
|
|
|
"DDIM",
|
feat(commands): integrate standard CAD commands and fix behavior gaps
Broad pass over the command set: integrate missing commands, wire
previously-unreachable ribbon/menu buttons, and correct name/behaviour
mismatches. Every UI command token now resolves (real handler where the
infrastructure exists, an honest "not yet implemented" status otherwise).
New commands:
- Draw: 3DPOLY, 2D solid (SO/SOLID2D), HELIX, TRACE, SKETCH, DIMCENTER
(DCE/CENTERMARK)
- Modify/inquiry: REVERSE, MEASUREGEOM (MEA), DBLIST
- Data/manage: BASE, OVERKILL (exact-duplicate removal), AUDIT (read-only
integrity report), SETVAR (system-variable get/set), SCRIPT (.scr runner),
FINDNONPURGEABLE
Behaviour fixes:
- LINE and SPLINE gain Close/Undo; AREA computes area/perimeter in f64
(correct at large coordinates)
- ATTEDIT/ATE unified so the alias and the ribbon button open the
interactive editor; -ATTEDIT is the command-line form
- Linear/aligned/radius/diameter dimensions gain a text override (Text) and
text angle (Angle) option
- INSERT gains Scale/Rotate options; COPY gains an Array option
- LINETYPE SET sets the current entity linetype; SETBYLAYER resets overrides
- UNDO accepts a step count
Integrations: standard dimension/block aliases (DLI/DRA/DAN, BMAKE,
EXPORTPDF, DDIM), drafting-aid and screen toggles (GRID/SNAP/POLAR/OSNAP/
DSETTINGS/CLEANSCREEN/QUICKPROPERTIES), viewport tiling
(CASCADE/HORIZONTAL/VERTICAL/VPJOIN), and customization entry points
(CUI/ALIASEDIT).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-28 19:27:35 +03:00
|
|
|
// Inquiry: list the whole drawing database.
|
|
|
|
|
"DBLIST",
|
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 <noreply@anthropic.com>
2026-06-29 08:23:58 +03:00
|
|
|
// Layer management.
|
|
|
|
|
"LAYDEL",
|
feat(layers): add LAYTRANS to translate layers onto a standard
Drawings arrive from elsewhere carrying someone else's layer names, and
folding them into a set of house layers meant renaming and merging by
hand, one layer at a time.
LAYTRANS reads a layer set out of another drawing and moves this one onto
it. Given a file it maps every name the two already share and translates
at once, which is all most incoming drawings need. Bare, it opens a
translator: the drawing's layers on one side, the loaded set on the
other, mappings built up between them and applied only on Translate, so a
mapping can be reconsidered and the whole translation is a single undo
step. Mappings can be saved and read back, objects can be forced to
ByLayer so the target layer's properties are what actually shows, and the
result can be written out as a log.
The move itself is the one LAYMRG already made for a single pair, so
LAYMRG now goes through it too rather than keeping its own copy.
Three things fell out for free or nearly so. A standards file is a
drawing, so .dws and .dwt need nothing but a place in the file filter.
The entity list is flat and holds block definitions, so objects inside
blocks travel with everything else instead of being stranded on a layer
that no longer exists. And a target layer that this drawing already has
is left alone: the drawing has an opinion about it, and restyling it
would reach past what was asked for -- only newly created targets take
the standard's properties.
Mappings are saved beside the drawing rather than inside a DWS. That is
where AutoCAD keeps them, but putting them there would mean inventing a
place in the drawing that nothing else reads back.
Closes #624
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-07 16:51:15 +03:00
|
|
|
"LAYTRANS",
|
fix(units): make the units selector reach what it names
The status-bar units button wrote INSUNITS, which nothing on screen reads.
INSUNITS only tells the drawing how to scale content arriving from
elsewhere, so picking a unit relabelled the drawing and changed nothing
visible — the selector looked broken because the variable it moved was
invisible.
Point the button at LUNITS instead, the setting that decides how every
coordinate and distance is written, and give the three questions the word
"units" runs together a place each:
- The button offers the five length formats, each shown beside a sample of
itself, so Engineering and Architectural are told apart by sight.
- UNITS / DDUNITS opens a real dialog: length and angle format and
precision, the direction angle zero points, whether positive angles run
clockwise, and the insertion unit. Its sample comes from the same
formatters the drawing uses, so it cannot drift from the readout.
- DWGUNITS converts. Model geometry, viewport framing, the header's length
defaults and each dimension style's scale all move together in one undo
step; paper space is left alone, since the sheet is still the same sheet.
Locked layers are converted too — a half-converted drawing would be at
two scales at once.
The coordinate readout formatted at four decimal places whatever the
drawing asked for; it now goes through the same format_length the
properties panel uses. That made the angle formats reachable in turn, so
degrees-minutes-seconds now carries the d/'/" marks that say which
convention it is, and surveyor's units are written at all.
Typed input is still plain decimal: a length the readout writes as
5'-6 1/2" cannot yet be typed back. ANGBASE and ANGDIR are stored but not
yet applied to displayed directions.
Closes #668
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-07 19:59:09 +03:00
|
|
|
"DWGUNITS",
|
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 <noreply@anthropic.com>
2026-06-29 08:23:58 +03:00
|
|
|
"LAYMRG",
|
|
|
|
|
"LAYERSTATE",
|
|
|
|
|
"LAS",
|
|
|
|
|
"LMAN",
|
|
|
|
|
// 3D move (same operation as MOVE, which already works in 3D).
|
|
|
|
|
"3DMOVE",
|
|
|
|
|
// Quick leader (same as LEADER).
|
|
|
|
|
"QLEADER",
|
|
|
|
|
"QL",
|
|
|
|
|
// Restore the last-erased objects.
|
|
|
|
|
"OOPS",
|
|
|
|
|
// Plan (top) view.
|
2026-07-22 21:35:37 +03:00
|
|
|
"PICKADD",
|
|
|
|
|
"PICKDRAG",
|
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 <noreply@anthropic.com>
2026-06-29 08:23:58 +03:00
|
|
|
"PLAN",
|
|
|
|
|
// Current object colour (CECOLOR).
|
|
|
|
|
"COLOR",
|
|
|
|
|
"COLOUR",
|
|
|
|
|
"CECOLOR",
|
|
|
|
|
"DDCOLOR",
|
|
|
|
|
"BYLAYER",
|
|
|
|
|
// Synchronise block attributes.
|
|
|
|
|
"ATTSYNC",
|
|
|
|
|
// Drawing units picker.
|
|
|
|
|
"UNITS",
|
|
|
|
|
"UN",
|
|
|
|
|
"DDUNITS",
|
|
|
|
|
// Visual styles (mapped to the wireframe / shaded view).
|
|
|
|
|
"VSCURRENT",
|
|
|
|
|
"SHADEMODE",
|
|
|
|
|
// Raster image brightness / contrast / fade.
|
|
|
|
|
"ADJUST",
|
|
|
|
|
// Block list + block-attribute list (command-line forms).
|
|
|
|
|
"BLOCKPALETTE",
|
|
|
|
|
"BLOCKSPALETTE",
|
|
|
|
|
"ATTMAN",
|
|
|
|
|
"BATTMAN",
|
|
|
|
|
// Drawing-content overview.
|
|
|
|
|
"ADCENTER",
|
|
|
|
|
"CONTENTBROWSER",
|
|
|
|
|
"ADC",
|
|
|
|
|
// Annotation scale.
|
|
|
|
|
"ANNOSCALE",
|
|
|
|
|
"CANNOSCALE",
|
2026-08-02 12:00:15 +03:00
|
|
|
"ANNOALLVISIBLE",
|
|
|
|
|
"ANNOAUTOSCALE",
|
|
|
|
|
"ANNOUPDATE",
|
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 <noreply@anthropic.com>
2026-06-29 08:23:58 +03:00
|
|
|
"SCALELISTEDIT",
|
2026-07-13 22:38:29 +03:00
|
|
|
"OBJECTSCALE",
|
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 <noreply@anthropic.com>
2026-06-29 08:23:58 +03:00
|
|
|
// Import CSV into a table + LandXML survey points.
|
|
|
|
|
"DATALINK",
|
|
|
|
|
"LANDXMLIMPORT",
|
|
|
|
|
// Keyboard-shortcut (CUI) export / import.
|
|
|
|
|
"CUIEXPORT",
|
|
|
|
|
"CUIIMPORT",
|
|
|
|
|
"CUILOAD",
|
|
|
|
|
// Save every open drawing.
|
|
|
|
|
"SAVEALL",
|
|
|
|
|
// Draw-order: all text/dims to front or back.
|
|
|
|
|
"TEXTTOFRONT",
|
|
|
|
|
"TEXTTOBACK",
|
|
|
|
|
// Criteria-based selection (same as QSELECT) + copy with picked base.
|
|
|
|
|
"FILTER",
|
|
|
|
|
"FI",
|
|
|
|
|
"COPYBASE",
|
|
|
|
|
// Change justification of selected text/mtext.
|
|
|
|
|
"JUSTIFYTEXT",
|
|
|
|
|
// Command-line arithmetic calculator.
|
|
|
|
|
"CAL",
|
|
|
|
|
// Text tools: case, mask, width fit, sequential numbering, arc layout.
|
|
|
|
|
"TCASE",
|
|
|
|
|
"TEXTMASK",
|
|
|
|
|
"TEXTFIT",
|
2026-07-09 16:41:53 +03:00
|
|
|
"TEXTFILL",
|
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 <noreply@anthropic.com>
2026-06-29 08:23:58 +03:00
|
|
|
"TCOUNT",
|
|
|
|
|
"ARCTEXT",
|
|
|
|
|
// Jogged radius dimension.
|
|
|
|
|
"DIMJOGGED",
|
|
|
|
|
"DJO",
|
|
|
|
|
"DIMJOG",
|
|
|
|
|
// Mark objects annotative.
|
|
|
|
|
"OBJECTSCALE",
|
|
|
|
|
// Copy nested objects out of a block.
|
|
|
|
|
"NCOPY",
|
|
|
|
|
"NCOPYALL",
|
2026-06-29 09:04:18 +03:00
|
|
|
// Close tab, hidden-line / visual styles, calculator, hyperlink.
|
|
|
|
|
"CLOSE",
|
|
|
|
|
"HIDE",
|
|
|
|
|
"HI",
|
|
|
|
|
"VISUALSTYLES",
|
|
|
|
|
"QUICKCALC",
|
|
|
|
|
"QC",
|
|
|
|
|
"HYPERLINK",
|
|
|
|
|
"XOPEN",
|
2026-06-29 09:07:30 +03:00
|
|
|
"REGION",
|
|
|
|
|
"REG",
|
2026-06-29 09:10:57 +03:00
|
|
|
"ARCHIVE",
|
|
|
|
|
"ETRANSMIT",
|
2026-06-29 09:16:44 +03:00
|
|
|
"FLATSHOT",
|
|
|
|
|
"CONVTOSURFACE",
|
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 <noreply@anthropic.com>
2026-06-29 08:23:58 +03:00
|
|
|
// Slice/section + interference + press-pull/thicken + 3D transforms + wall/pyramid.
|
|
|
|
|
"SLICE",
|
|
|
|
|
"SL",
|
|
|
|
|
"INTERFERE",
|
|
|
|
|
"INF",
|
|
|
|
|
"PRESSPULL",
|
|
|
|
|
"THICKEN",
|
|
|
|
|
"3DROTATE",
|
|
|
|
|
"ROTATE3D",
|
|
|
|
|
"POLYSOLID",
|
|
|
|
|
"3DMIRROR",
|
|
|
|
|
"MIRROR3D",
|
|
|
|
|
"3DALIGN",
|
|
|
|
|
"ALIGN3D",
|
|
|
|
|
"SECTION",
|
|
|
|
|
"PYRAMID",
|
|
|
|
|
"PYR",
|
|
|
|
|
"SPLINEFIT",
|
|
|
|
|
"FITSPLINE",
|
|
|
|
|
// System variables (typeable directly).
|
|
|
|
|
"MIRRTEXT",
|
|
|
|
|
"ATTREQ",
|
|
|
|
|
"ATTDIA",
|
|
|
|
|
"DIMASSOC",
|
|
|
|
|
"ANGBASE",
|
|
|
|
|
"ANGDIR",
|
|
|
|
|
"REGENMODE",
|
|
|
|
|
"BLIPMODE",
|
|
|
|
|
"SPLFRAME",
|
|
|
|
|
"DELOBJ",
|
|
|
|
|
"PLINEGEN",
|
|
|
|
|
"PSLTSCALE",
|
|
|
|
|
"DISPSILH",
|
|
|
|
|
"WORLDVIEW",
|
|
|
|
|
"LIMCHECK",
|
|
|
|
|
"DRAGMODE",
|
|
|
|
|
"LUNITS",
|
|
|
|
|
"LUPREC",
|
|
|
|
|
"AUNITS",
|
|
|
|
|
"AUPREC",
|
|
|
|
|
"THICKNESS",
|
|
|
|
|
"ELEVATION",
|
|
|
|
|
"INSUNITS",
|
|
|
|
|
"SPLINETYPE",
|
|
|
|
|
"ISOLINES",
|
|
|
|
|
"DIMASO",
|
|
|
|
|
"DIMSHO",
|
|
|
|
|
"QTEXTMODE",
|
|
|
|
|
"PLIMCHECK",
|
|
|
|
|
"VISRETAIN",
|
|
|
|
|
"USRTIMER",
|
|
|
|
|
"ATTMODE",
|
|
|
|
|
"COORDS",
|
|
|
|
|
"OSMODE",
|
|
|
|
|
"PICKSTYLE",
|
|
|
|
|
"SPLINESEGS",
|
|
|
|
|
"SURFU",
|
|
|
|
|
"SURFV",
|
|
|
|
|
"SURFTYPE",
|
|
|
|
|
"SHADEDGE",
|
|
|
|
|
"MAXACTVP",
|
|
|
|
|
"CMLJUST",
|
|
|
|
|
"TEXTQLTY",
|
|
|
|
|
"SORTENTS",
|
|
|
|
|
"XCLIPFRAME",
|
|
|
|
|
"HALOGAP",
|
|
|
|
|
"TRACEWID",
|
|
|
|
|
"SKETCHINC",
|
feat(commands): integrate standard CAD commands and fix behavior gaps
Broad pass over the command set: integrate missing commands, wire
previously-unreachable ribbon/menu buttons, and correct name/behaviour
mismatches. Every UI command token now resolves (real handler where the
infrastructure exists, an honest "not yet implemented" status otherwise).
New commands:
- Draw: 3DPOLY, 2D solid (SO/SOLID2D), HELIX, TRACE, SKETCH, DIMCENTER
(DCE/CENTERMARK)
- Modify/inquiry: REVERSE, MEASUREGEOM (MEA), DBLIST
- Data/manage: BASE, OVERKILL (exact-duplicate removal), AUDIT (read-only
integrity report), SETVAR (system-variable get/set), SCRIPT (.scr runner),
FINDNONPURGEABLE
Behaviour fixes:
- LINE and SPLINE gain Close/Undo; AREA computes area/perimeter in f64
(correct at large coordinates)
- ATTEDIT/ATE unified so the alias and the ribbon button open the
interactive editor; -ATTEDIT is the command-line form
- Linear/aligned/radius/diameter dimensions gain a text override (Text) and
text angle (Angle) option
- INSERT gains Scale/Rotate options; COPY gains an Array option
- LINETYPE SET sets the current entity linetype; SETBYLAYER resets overrides
- UNDO accepts a step count
Integrations: standard dimension/block aliases (DLI/DRA/DAN, BMAKE,
EXPORTPDF, DDIM), drafting-aid and screen toggles (GRID/SNAP/POLAR/OSNAP/
DSETTINGS/CLEANSCREEN/QUICKPROPERTIES), viewport tiling
(CASCADE/HORIZONTAL/VERTICAL/VPJOIN), and customization entry points
(CUI/ALIASEDIT).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-28 19:27:35 +03:00
|
|
|
// Reset selected entities' overrides to follow their layer.
|
|
|
|
|
"SETBYLAYER",
|
|
|
|
|
// Remove duplicate objects; set drawing base point; audit integrity;
|
|
|
|
|
// read/write system variables.
|
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 <noreply@anthropic.com>
2026-06-29 08:23:58 +03:00
|
|
|
"OVERKILL",
|
|
|
|
|
"BASE",
|
|
|
|
|
"AUDIT",
|
|
|
|
|
"SETVAR",
|
|
|
|
|
"SCRIPT",
|
|
|
|
|
"SCR",
|
|
|
|
|
"FINDNONPURGEABLE",
|
|
|
|
|
"3DORBIT",
|
|
|
|
|
"3O",
|
|
|
|
|
"ABOUT",
|
|
|
|
|
"ATTDISP",
|
|
|
|
|
"ATTEXT",
|
|
|
|
|
"BACKGROUND",
|
|
|
|
|
"CDIMSTY",
|
|
|
|
|
"CELTSCALE",
|
|
|
|
|
"CHANGELOG",
|
|
|
|
|
"CHPROP",
|
|
|
|
|
"CLAYER",
|
|
|
|
|
"CLEAR",
|
|
|
|
|
"CLR",
|
|
|
|
|
"COLORSCHEME",
|
|
|
|
|
"COUNT",
|
|
|
|
|
"DATAEXTRACTION",
|
|
|
|
|
"DE",
|
|
|
|
|
"DESELALL",
|
|
|
|
|
"DESELECT",
|
|
|
|
|
"DIMSTYLE",
|
|
|
|
|
"DONATE",
|
|
|
|
|
"DRAWORDER",
|
|
|
|
|
"DWGPROP",
|
|
|
|
|
"DWGPROPS",
|
|
|
|
|
"EATTEXT",
|
|
|
|
|
"EXIT",
|
|
|
|
|
"EXPORT",
|
|
|
|
|
"EXPORTSTEP",
|
|
|
|
|
"EXPORTSTL",
|
2026-07-09 16:26:24 +03:00
|
|
|
"EXTRIM",
|
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 <noreply@anthropic.com>
2026-06-29 08:23:58 +03:00
|
|
|
"FILETAB",
|
|
|
|
|
"FIND",
|
|
|
|
|
"FLATTEN",
|
|
|
|
|
"HELP",
|
|
|
|
|
"HIDEOBJECTS",
|
|
|
|
|
"IM",
|
|
|
|
|
"IMAGE",
|
|
|
|
|
"IMAGEATTACH",
|
|
|
|
|
"IMPORTOBJ",
|
|
|
|
|
"ISOLATEOBJECTS",
|
|
|
|
|
"LA",
|
|
|
|
|
"LAYER",
|
|
|
|
|
"LAYERS",
|
|
|
|
|
"LAYISO",
|
|
|
|
|
"LAYON",
|
|
|
|
|
"LAYOUTMANAGER",
|
|
|
|
|
"LAYOUTPANEL",
|
|
|
|
|
"LAYOUTTAB",
|
|
|
|
|
"LAYTHW",
|
|
|
|
|
"LAYUNISO",
|
|
|
|
|
"LI",
|
|
|
|
|
"LINETYPE",
|
|
|
|
|
"LIST",
|
|
|
|
|
"LTSCALE",
|
|
|
|
|
"LWDISPLAY",
|
|
|
|
|
"MASSPROP",
|
|
|
|
|
"MLEADERSTYLE",
|
|
|
|
|
"MLSTYLE",
|
|
|
|
|
"MS",
|
|
|
|
|
"MSPACE",
|
|
|
|
|
"NAVVCUBE",
|
|
|
|
|
"NEW",
|
|
|
|
|
"OBJIMPORT",
|
|
|
|
|
"OPEN",
|
|
|
|
|
"ORTHO",
|
|
|
|
|
"P",
|
|
|
|
|
"PAN",
|
|
|
|
|
"PAGESETUP",
|
|
|
|
|
"PERF",
|
|
|
|
|
"PERSP",
|
|
|
|
|
"PLOT",
|
|
|
|
|
"PLOTSTYLE",
|
|
|
|
|
"PLOTSTYLEEDITOR",
|
|
|
|
|
"PLOTSTYLEPANEL",
|
|
|
|
|
"PR",
|
|
|
|
|
"PRINT",
|
|
|
|
|
"PROPERTIES",
|
|
|
|
|
"PROPS",
|
|
|
|
|
"PSPACE",
|
|
|
|
|
"PURGE",
|
2026-07-09 12:57:35 +03:00
|
|
|
"QP",
|
|
|
|
|
"QUICKPRINT",
|
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 <noreply@anthropic.com>
2026-06-29 08:23:58 +03:00
|
|
|
"QS",
|
|
|
|
|
"QSAVE",
|
|
|
|
|
"QSELECT",
|
|
|
|
|
"QUIT",
|
|
|
|
|
"REDO",
|
|
|
|
|
"RENAME",
|
|
|
|
|
"REPORT",
|
|
|
|
|
"SA",
|
|
|
|
|
"SAVE",
|
|
|
|
|
"SAVEAS",
|
|
|
|
|
"SCALETEXT",
|
|
|
|
|
"SELECTALL",
|
|
|
|
|
"SELECTSIMILAR",
|
|
|
|
|
"SELSIM",
|
feat(command): ADDSELECTED draws a new object like the selected one (#239)
Take the first selected entity as a template, adopt its general
properties (layer, colour, linetype, lineweight, linetype scale) as the
current defaults, then start the matching draw command so the object
drawn next inherits them.
Supports Point, Line, Circle, Arc, Ellipse, all polylines (PLINE), Text,
MText, Spline, Hatch, Solid, Ray and XLine; other types report that
creation is unsupported. Registered for command-line autocomplete.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-01 18:42:26 +03:00
|
|
|
// Draw a new object of the same type as the selected one. (#239)
|
|
|
|
|
"ADDSELECTED",
|
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 <noreply@anthropic.com>
2026-06-29 08:23:58 +03:00
|
|
|
"SHEETSET",
|
|
|
|
|
"SHORTCUTS",
|
|
|
|
|
"SSM",
|
|
|
|
|
"STEPOUT",
|
|
|
|
|
"STLOUT",
|
|
|
|
|
"STPOUT",
|
|
|
|
|
"STYLE",
|
|
|
|
|
"STYLESMANAGER",
|
|
|
|
|
"TABLESTYLE",
|
|
|
|
|
"TOOLPALETTES",
|
|
|
|
|
"TP",
|
|
|
|
|
"TS",
|
|
|
|
|
"U",
|
|
|
|
|
"UCS",
|
|
|
|
|
"UCSICON",
|
|
|
|
|
"UNDERLAY",
|
|
|
|
|
"UNDO",
|
|
|
|
|
"UNISOLATEOBJECTS",
|
|
|
|
|
"USERI",
|
|
|
|
|
"USERR",
|
|
|
|
|
"VIEW",
|
|
|
|
|
"VPORTS",
|
|
|
|
|
"VS",
|
|
|
|
|
"VW",
|
|
|
|
|
"WB",
|
|
|
|
|
"WBLOCK",
|
|
|
|
|
"WEBVERSION",
|
|
|
|
|
"XA",
|
|
|
|
|
"XATTACH",
|
|
|
|
|
"XDATA",
|
|
|
|
|
"XR",
|
|
|
|
|
"XREF",
|
|
|
|
|
"XRELOAD",
|
|
|
|
|
"ZOOM",
|
|
|
|
|
"ZS",
|
refactor: split four oversized files into submodule trees
Break up the four giant files (~29k lines total) into focused submodule
directories, one concern per file. Pure mechanical moves — behavior is
unchanged.
- app/update.rs (9650) -> app/update/{mod,viewport,command,style,file,
dynamic,dialog,util}. The 384-arm update_inner match stays in mod.rs
with thin delegating arms; the 66 fattest arm bodies move to topic
methods. Arm set preserved exactly (384 -> 384).
- scene/mod.rs (9017) -> scene/{mod,entity,tess,hittest,layout,paper,
mspace,project,selection,modify,group_layer,preview}. The impl Scene
body is split across files via inherent-impl-per-file; struct, ctor,
fields and load-time helpers stay in the root. fn count 123 -> 123.
- app/commands.rs (6082) -> app/commands/* grouped by command family.
The 233-arm dispatch match becomes source-ordered per-family
dispatch_* handlers, preserving first-match precedence (233 -> 233).
- app/view.rs (4686) -> app/view/{mod,overlay,modal,viewcube,controls}.
Largest file drops from 9650 to 3343. Builds clean; app launches and
loads plugins with no panic.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-26 22:51:29 +03:00
|
|
|
]
|
|
|
|
|
});
|