copy_all scanned the selection for an OLE frame once per matrix before copying.
It now looks at the objects once and then only tests each matrix.
Covered by the existing refusal tests (classic_polar_array_refuses_a_turned_frame_but_not_an_upright_one).
A sign in a hex pair is no longer accepted; only the 310 groups holding the 98-byte header are decoded and rewritten, in place and without cloning the payload; the corner lookup is one allocation-free pass; the io ole_frame test module is not built for wasm like its DWG siblings; Unknown::is_ole_frame replaces five copies of the type check. Tests: a_plus_sign_in_ole_data_is_not_hex, a_large_ole_payload_only_rewrites_its_leading_groups.
ARRAYPATH with align and polar arrays that rotate items refused part way, leaving the earlier copies in the drawing. Every copy's matrix is now checked before the first copy is made. The refusal text names the other unsupported transforms. Test: arraypath_refuses_before_adding_any_copy.
ole_frame_accepts took only a translation, so SCALE on a selection with a frame failed as a whole. A uniform positive scale keeps the frame axis-aligned and upper-left, so the corner rewrite handles it; rotation and mirroring are still refused. Tests: scale_carries_an_ole_frame_with_the_rest_of_the_selection, mocoro_scales_an_ole_frame, ole_frame_accepts_translations_and_uniform_positive_scales_only.
There was no OOPS. It now brings back what the last ERASE removed (the
Delete key too), or BLOCK deleting the objects it makes a block of, as
AutoCAD 2024 does (accoreconsole, the drawing's entnext order read
back):
- Each object keeps its handle and goes back directly above the object
that was under it, or under the one that was above it when that is
gone. An erase records both neighbours (EntityStore::neighbours).
- Only the last erase counts; entdel doesn't. OOPS says nothing and is
one undo step.
- An object stays out when it is already in the drawing, when an undo
took the drawing back to before it was made, when its layer, block or
layout is gone, and, during REFEDIT, when it isn't in the working set.
REFCLOSE forgets the working copies; the Block Editor has an OOPS of
its own.
- The command's label is in the 17 interface catalogs.
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Co-authored-by: Brandon Thomas <echelon@gmail.com>
MOCORO refuses a rotate or scale step on an OLE frame up front, before an earlier move or copy
is applied. refuse_ole_frames ignores a frame on a locked layer for in-place edits, as
edit_entities does. Tests: mocoro_refuses_before_it_changes_anything,
a_locked_ole_frame_does_not_block_an_in_place_rotation.
Main moved the edit loop into edit_entities and gave SCALE its own scale_entities, so the
merged check no longer compiled (CI: m not in scope). The refusal is now one helper that
transform_entities and scale_entities call before anything changes.
ole_frame read 10/20 and 11/21 from inside 102 groups; it now skips them as the DXF reader does.
A window-selected OLE2FRAME was left in place by MOVE/COPY. A DWG save writes the position from
the corner groups (checked by write + read-back), so MOVE/COPY now shift them; transforms that
would not keep it axis aligned return an error before anything changes.
AutoCAD 2024's SCALE is a uniform 3D scale about the base point: every Z
and elevation scales about the base point's Z (the current ELEVATION for a
point given without one) and every thickness by the factor. cadcraft
scaled X and Y only. The JSON form also takes a Z with the base point.
OFFSET's copy now keeps the source's height: a line's end Zs, a circle's
or arc's centre Z, a polyline's elevation. A circle's or arc's copy has no
thickness and a polyline's keeps it, as AutoCAD makes them.
Grip scaling, ALIGN's scale option and MOCORO stay 2D: their base point is
often a grip or snapped point whose Z cadcraft doesn't keep.
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
* Refuse mirror lines whose points are closer than the geometry EPS
Found while testing crates/engine/src/cmd/modify/transform.rs:run_mirror (coincidence check `a.near(b, 1e-12)`), with crates/geom/src/mat.rs:43-47 (Mat3::mirror)
Co-Authored-By: Claude Haiku 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
* mirror: the interactive prompt also refuses points closer than the geometry EPS
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
---------
Co-authored-by: Claude Haiku 5.5 <noreply@anthropic.com>
Co-authored-by: Brandon Thomas <echelon@gmail.com>