Commit Graph
434 Commits
Author SHA1 Message Date
Dylan M. Taylor 4d2e46fc33 Format imports so the CI fmt gate passes 2026-10-25 19:13:25 -04:00
Dylan M. Taylor 86385d63a9 refactor: replace wildcard imports with explicit ones (S2208, batch_04) 2026-10-25 19:13:25 -04:00
Dylan M. Taylor c41c7424c3 refactor: replace wildcard imports with explicit ones (S2208, batch_04) 2026-10-25 19:13:25 -04:00
Dylan M. Taylor 004287d919 refactor: explicit imports instead of wildcards (S2208, batch_03) (#2040)
* refactor: replace wildcard imports with explicit ones (S2208, batch_03)

* refactor: replace wildcard imports with explicit ones (S2208, batch_03)

* Format imports so the CI fmt gate passes
2026-10-25 18:18:33 -04:00
Dylan M. Taylor 656dd4d09a refactor: explicit imports instead of wildcards (S2208, batch_00) (#2037)
* refactor: replace wildcard imports with explicit ones (S2208, batch_00)

* refactor: replace wildcard imports with explicit ones (S2208, batch_00)

Explicit lists now resolve the names each file uses, and the test
module keeps its glob so it still sees the parent's items.
2026-10-25 18:18:29 -04:00
MarekSpodBiedry d73e379fd2 Autosave no longer writes the old host as recovery when the Block Editor's changes can't be composed (#918) (#980) 2026-10-25 12:25:48 -04:00
MarekSpodBiedry d0a1ea5268 Table commands reject a malformed handle instead of using the selected table (#934) (#970) 2026-10-25 12:25:31 -04:00
0de051049c Keep associative-array parameters when an xref is loaded (#943) (#966)
* Keep associative-array parameters when an xref is loaded (#943)

* xref load test: initialise Ctx's new bytes counter

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

---------

Co-authored-by: Brandon Thomas <echelon@gmail.com>
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-25 12:25:24 -04:00
1c85d339c3 Reject negative or out-of-range minutes/seconds in D'" angles (#2116)
Found while testing crates/engine/src/units.rs:333-340 (parse_dms)

Co-authored-by: Claude Haiku 5.5 <noreply@anthropic.com>
Co-authored-by: Brandon Thomas <echelon@gmail.com>
2026-10-25 12:15:42 -04:00
Nicholas Gower 5acec7d0be PLOTWINDOW: pick both corners even with ORTHO on (#1893)
* PLOTWINDOW: pick both corners even with ORTHO on

PLOTWINDOW's opposite-corner prompt used Prompt::base, so the canvas bent
the picked point onto the nearest axis with ORTHOMODE on: the second corner
landed above/beside the first, the window had no width or height, and
set_plot_window refused it. The prompt now uses Prompt::corner, the flag
ZOOM Window, RECTANG and ARRAYRECT already use to keep a rectangle's
opposite corner free of ortho. The first corner sets the base as before, so
the rubber band and direct distance entry still work.

Regression test drives the interactive machine through snap_cursor with
ORTHOMODE on, picks two non-axis-aligned corners and checks the stored
window keeps both extents; an ordinary LINE prompt still follows ortho.

Fixes #1641

* docs: document the functions touched by #1641
2026-10-25 12:13:53 -04:00
NetterSilverandClaude Haiku 5.5 31de470926 Fall back to decimal for huge engineering-unit distances (#2114)
Found while testing crates/engine/src/units.rs:18-27 (format_distance, LUNITS 3 branch)

Co-authored-by: Claude Haiku 5.5 <noreply@anthropic.com>
2026-10-25 12:13:39 -04:00
NetterSilverandClaude Haiku 5.5 52aae9c1fb Fix wcmatch returning nil for patterns with many '*' wildcards (#2078)
Found while testing crates/engine/src/lisp/builtins.rs:798-800 (glob_inner depth limit; depth is incremented per '*' at line 808)

Co-authored-by: Claude Haiku 5.5 <noreply@anthropic.com>
2026-10-25 12:13:28 -04:00
Marco Arnulfo a89be5f2dd A Fix on a derived point (a line's midpoint, an arc's end) holds the position it had before the edit (#2077) 2026-10-25 12:13:25 -04:00
NetterSilverandClaude Haiku 5.5 a4a3a342a0 Fix format_angle zeroing radians near a full turn at low precision (#2073)
Found while testing crates/engine/src/units.rs:124-127 (wrap_full_turn, used at line 106 for AUNITS 3 and at lines 105 and 120)

Co-authored-by: Claude Haiku 5.5 <noreply@anthropic.com>
2026-10-25 12:13:21 -04:00
Marco Arnulfo 36fcc896f7 GETVAR CECOLOR reads back as text, as in AutoCAD (follow-up to #2014) (#2069)
CECOLOR now reads "BYLAYER", "BYBLOCK", the index as text ("1" after
"red") or "RGB:r,g,b" for a true colour, from getvar, LISP and the
SETVAR ? list, where it was the ACI number (256, 0, 1, or the nearest
index of a true colour). The header still keeps the index and
CECOLOR_RGB, so DXF output and new objects are unchanged.

SETVAR CECOLOR takes "RGB:r,g,b" too, so a value saved with getvar
can be set back, true colour included.
2026-10-25 12:13:18 -04:00
Dylan M. TaylorandClaude Sonnet 5.5 b37b7ceb7b refactor: replace wildcard imports with explicit ones (S2208, batch_09) (#2046)
Co-authored-by: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-25 12:13:04 -04:00
skylar taylor-barrick f2b35e957e Migrate CADCraft to egui 0.37 (#2119)
* egui037: migrate CADCraft UI and preserve font notices

* M0: clarify screenshot cancellation after issue

* Document migration UI contracts and regression assertions
2026-10-25 10:48:48 -04:00
aiongg c6c3aefe3f COMPAREEXPORT: a dimension whose block can't be copied is drawn again in the comparison color; Volume's second point says it needs a point; comments say only dimensions leave anonymous block names out 2026-10-25 05:06:46 +00:00
aiongg b34477d580 cargo fmt 2026-10-25 04:41:25 +00:00
aiongg 23d44cd9c8 MEASUREGEOM Volume: the height can be given by two points, and Enter at the height prompt says a height is required 2026-10-25 04:26:14 +00:00
aiongg 8296bbc642 THICKNESS: a typed value out of range is reported as such and the prompt asks again 2026-10-25 04:22:57 +00:00
aiongg b90d68ec34 BLOCKREPLACE: a dynamic block or a replacement that references the block is refused when its name is given, and the prompt asks again 2026-10-25 04:17:52 +00:00
aiongg c42763ba0f CUTCLIP and CUTBASE leave the clipboard alone when every object is on a locked layer, and say how many were locked 2026-10-25 04:12:57 +00:00
aiongg 642c3a59a3 COMPAREEXPORT: free block and style names come from a next-index counter per name base instead of a scan from 1 2026-10-25 04:04:14 +00:00
aiongg 53049d82e0 COMPAREEXPORT: keep #2049's *D copies of dimension blocks 2026-10-25 03:58:15 +00:00
aiongg e23a362c54 Merge storytold/cadcraft#2049 (commits after the batch) 2026-10-25 03:57:25 +00:00
aiongg 8171c9be17 DIMTFILL and DIMTFILLCLR are written in DIMSTYLE only when set; COMPAREEXPORT redraws dimensions instead of copying their blocks, and gaps.md notes its groups 2026-10-25 03:43:34 +00:00
dotCooCoo 4dbcbfdaaa COMPAREEXPORT: dimension block copies stay *D blocks, and image paths count in block reuse
A dimension's block took a recolored copy named COMPARE_<tag>_D1, and
the DXF writer redraws a dimension whose block is not a *D block, so
saving the snapshot replaced geometry read from a file. The copy now
gets a free *D name.

A named block both drawings define was reused when its images and
data links had the same relative paths, even when they were relative
to different folders. These paths are now taken from each drawing's
folder before the blocks are compared.
2026-10-24 19:37:44 -07:00
aiongg 429554b389 COMPAREEXPORT: tests move into the engine's it suite (the hook test joins tests/compare.rs); the copy drops constraint display exceptions for objects it doesn't hold 2026-10-25 02:35:48 +00:00
aiongg 1b0cefce9c Merge storytold/cadcraft#2049
# Conflicts:
#	docs/gaps.md
2026-10-25 02:23:03 +00:00
aiongg e1cab10d01 Merge storytold/cadcraft#2089
# Conflicts:
#	crates/engine/src/cmd/utility.rs
2026-10-25 02:22:50 +00:00
aiongg 05cad7db49 Merge storytold/cadcraft#2085
# Conflicts:
#	crates/engine/src/cmd/utility.rs
#	crates/engine/tests/it/inquiry_keywords.rs
2026-10-25 02:22:40 +00:00
aiongg 4e73fb5bb3 Merge storytold/cadcraft#2079
# Conflicts:
#	docs/parity-checklist.md
2026-10-25 02:22:16 +00:00
aiongg 84e3478863 Merge storytold/cadcraft#2071
# Conflicts:
#	docs/parity-checklist.md
2026-10-25 02:22:16 +00:00
aiongg fac2d18df6 Merge storytold/cadcraft#2065
# Conflicts:
#	docs/parity-checklist.md
2026-10-25 02:22:16 +00:00
aiongg 23a0bd4fdb Merge storytold/cadcraft#2054
# Conflicts:
#	docs/parity-checklist.md
2026-10-25 02:22:16 +00:00
aiongg 75c54ce35d Merge storytold/cadcraft#2056 2026-10-25 02:21:58 +00:00
aiongg 313fab8827 Merge storytold/cadcraft#2101 2026-10-25 02:21:58 +00:00
aiongg bda4a9924c Merge storytold/cadcraft#2106 2026-10-25 02:21:58 +00:00
dotCooCoo 20087b4b5f COMPAREEXPORT: multiline attributes take the comparison color too
A multiline attribute is drawn from its own multiline text, so an
inline color code in it overrode the comparison color set on the
attribute: an unchanged attribute could stay red, or a removed one
green. The export now takes the inline colors out of the multiline
text of a reference's attributes and of attribute definitions in the
recolored blocks, as it does for MTEXT and multileader text.
2026-10-24 19:16:04 -07:00
dotCooCoo 5685085add COMPAREEXPORT: a block whose objects are hidden or thicker in the other drawing is copied as PART_2
The comparison of a named block both drawings define counted each
object's geometry, layer, color, linetype, lineweight and linetype
scale. A block whose line was hidden, more transparent, thicker or
extruded another way in the other drawing counted as the same, so the
other drawing's references drew with this drawing's definition. These
properties now count as well.
2026-10-24 18:52:56 -07:00
dotCooCoo 32be8a655e COMPAREEXPORT: a dimension block with another generated name does not make PART differ
A named block such as PART was compared with the other drawing's by the
blocks it draws, including a dimension's block. That block's generated
name (`*D1` here, `*D3` there) was part of its signature, so the same
PART counted as different and was copied as PART_2 with a copy of the
dimension block. The comparison now leaves out an anonymous block's
name and compares its contents.
2026-10-24 18:43:16 -07:00
dotCooCoo 1271b06b02 Refuse negative values for whole-number DIM* variables
DimStyle::apply_fields rounded a value for a whole-number field such as
DIMDEC or DIMTMOVE and clamped it to 0..255, so DIMDEC -1 became 0 and
DIMALTD "300" became 255. DIMSTYLE, DIMOVERRIDE and the SETVAR overrides
that new dimensions take all accepted these values.

A value below 0 or one that rounds above 255 is now refused, as an
out-of-range value is. DIMADEC still takes -1. A lineweight given as
-1, -2 or -3 (ByLayer, ByBlock, Default) is no longer read as 0 when
the style's lineweight is positive, and a lineweight above 211 given as
text is refused instead of read as 211.
2026-10-24 16:34:50 -07:00
dotCooCoo 6dc336160d SETVAR refuses DIM* values the dimension style refuses
SETVAR wrote a DIM* variable to the drawing header without checking it,
so values such as DIMTMOVE 3, DIMATFIT 7 or DIMLWD 500 were accepted.
New dimensions then ignored them, because the style override goes
through DimStyle::apply_fields, which refuses them.

SETVAR now runs the value through apply_fields on a copy of the current
dimension style, as DIMSTYLE and DIMOVERRIDE do, and reports an invalid
value instead of writing it.
2026-10-24 15:22:26 -07:00
dotCooCoo 8a64e42100 DIMTFILL: dimension text gets a background in the drawing's background color or in DIMTFILLCLR
DIMTFILL and DIMTFILLCLR were not modeled, so a dimension's text never had a
background and lines under it stayed visible. Dimension styles now carry both
variables. DIMTFILL 1 hides what is drawn under the text in the drawing's
background color, and DIMTFILL 2 fills the box in DIMTFILLCLR. The box is the
text box widened by DIMGAP on every side. The arc length symbol over the text
and the DIMINSPECT frame are drawn over the background.

The variables work with SETVAR, DIMOVERRIDE and the style fields. DXF stores
them as DIMSTYLE groups 69 and 70 from R2007 and in the style's CADCRAFT
xdata in older files; the reader skips the record's flags, which also use 70.
For DIMTFILL 2, the dimension's *D block and EXPLODE add a SOLID in
DIMTFILLCLR under the text. A dimension drawn from the *D block it was read
with gets a background around each of the block's texts, before the block's
first text or first segment of the text's marks, except for a text that a
SOLID of the block already covers. The background stays after the drawing is
saved and reopened.
2026-10-24 14:11:01 -07:00
aiongg fcfdf33001 Merge pull request #1556 from silaghis/fix/stretch-ortho-window
Keep rectangle opposite corners free of ortho (STRETCH window and friends)
2026-10-24 16:15:54 -04:00
dotCooCoo 898b539630 COMPAREEXPORT: a block left out at the block limit is reported when this drawing's differs
Past the limit on blocks copied, a block of the other drawing that this
drawing also defines was skipped without a note, and the red group drew
this drawing's definition even when the two differed. Such a block now
counts as left out unless both drawings' blocks draw the same thing, so
the export says that some blocks were too many to copy.
2026-10-24 11:50:33 -07:00
dotCooCoo bfa30e2192 MEASUREGEOM: Tools > Inquiry > Radius asks for the object, and Radius measures polyline arcs
Tools > Inquiry > Radius had no prompts, so with nothing selected it
stopped with "`handle` is required". It now asks "Select arc or circle"
and reports the radius and diameter of the arc or circle picked. A
selected arc or circle is still measured at once.

MEASUREGEOM's Radius option and Tools > Inquiry > Radius also measure
the arc segment of a polyline under the pick. radius.measure takes an
optional `point`, and for a polyline it measures the arc segment nearest
that point.
2026-10-24 11:34:08 -07:00
dotCooCoo 432cbfb106 COMPAREEXPORT: a named block whose dimension draws another block is copied as PART_2
A named block that holds a dimension was kept as this drawing's
definition when only the block the dimension draws differed between the
drawings, so the red group drew this drawing's dimension graphics. The
export's block comparison now covers a dimension's block, as it covers a
multileader's.
2026-10-24 11:24:50 -07:00
dotCooCoo 596ea36465 MEASUREGEOM: malformed points and volumes past f64's range are errors
AREA and Volume measured the selected object when `points` was given but
was not a list of points; they now report an error, and only an absent
or null `points` measures the selection. A volume too large for f64
(an area times a height) is an error in the JSON form. At the typed
prompt, a volume or an Add/Subtract volume running total too large for
f64 makes the prompt say "The volume is too large." and ask for the
height again, where it reported "Volume = 0" or "Total volume = 0".
2026-10-24 11:11:51 -07:00