The right-edge toolbar of a REFEDIT session now shows the definition
being edited (REFEDITNAME) as an accent pill with the number of objects
in the working set, Add to / Remove from Working Set buttons with their
own icons (REFSET Add / Remove, straight to object selection), and
Save / Discard in a separate group below a rule.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
ARRAYEDIT picks an associative array (or takes the preselected one) and
its Source option opens the objects every item repeats in the Block
Editor; saving there updates all items at once. Counts and spacings stay
in Properties.
Refs #1109
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
With the new Associative option on (the default), ARRAYRECT and
ARRAYPOLAR build the array the way the drawing format stores one: the
selected objects move into an anonymous source block, an anonymous
array block holds one ByBlock reference to it per item, an INSERT of
the array block takes their place, and an AcDbAssocAction with an
AcDbAssocArrayActionBody, its three dependencies, the BaseNormal /
Origin / basePoint parameters and the value parameters tie them
together in the model-space network. The array is then edited from
Properties like an array read from a file.
The option flips with AS and is remembered for the session; on a
rotated working plane the commands keep making plain copies. Saving
drops the action of an array whose reference was erased or exploded.
Checked: created arrays reopen as associative with their parameters
and items, and the ODA converter reads the saved DWG without errors.
Refs #1109
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
TXTEXP replaces each selected TEXT and MTEXT with one polyline per
glyph contour, on the text's layer and with its properties: a
lightweight polyline for flat text, a 3D polyline for tilted text.
The outlines come from the same glyph tessellation the text renders
with, so stroke fonts give their strokes and outline fonts their
closed contours.
Refs D#1665
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Delegate INSERT and MINSERT explosion to the document-aware codec implementation, removing duplicate attribute and base-point handling. Update workspace, kernel and graph pins together and cover rotated arrays with a nonzero base.
Enforce constant attribute flag in ATTEDIT dialog by presenting constant attributes as disabled and ignoring modifications. When exploding an insert, restore block-definition attribute definitions as transformed ATTDEF entities while dropping instance attribute values.
Filleting a polyline segment with a line or arc moved the segment's
vertex and left the polyline closed and the other object separate, so a
closed shape bent into an unexpected outline. The polyline is now
opened if closed, cut at the fillet point keeping the picked side, and
the fillet arc and the trimmed line or arc are joined onto it as one
polyline, as the reference does.
Refs #1422
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
TRIM already takes objects selected before the command as cutting
edges; EXTEND ignored them and extended to the nearest object in the
path. It now takes them as boundary edges the same way.
Fixes#1732
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
world = insert_point + Rot * Scale * (P - base_point). Attribute placement, EXPLODE, XCLIP storage, REFEDIT's working copy, the UCS reframe of attributes and the dynamic-block visibility grip ignored the base point and were offset by Rot*Scale*base. They now share insert_transform_with_base. Creation stores a ZERO base and redefine resets it; a no-op redefine moves nothing; the Block Definition dialog prefills the base from the definition. XCLIP filters stored by older builds keep their old displacement.
bake_dimension_blocks copied the dimension's whole EntityCommon, including its extension dictionary handle, into every baked child, so many entities claimed one dictionary and file validation reported an error per entity. Baked children now get no extension dictionary. The same defect is fixed in define_transformed_block and the cross-document paste clone. Each has a test.
#1692 limited no-trim FILLET to two lines and refused arcs and polyline
segments, which #1558 already filleted without trimming (only the arc is
added). It also turned T/N at the object prompts into silent toggles, so
the Trim option no longer reached its Trim/No trim prompt and the choice
was not saved. Keep the arc bookkeeping it added (the new arc can be
picked next, and stays on the picked layer), restore every pair and the
Trim prompt.
CHAMFER's new no-trim mode starts from and saves the same TRIMMODE value
as FILLET instead of always starting trimmed.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The informational clippy job fails on two pre-existing literals
(also failing on main, surfaced on this PR's merge): the trim
tangency test's angle list used 3.14 where pi was meant — use the
constant; the point-cloud light-direction fixture in render.rs uses
a hand-tuned 0.318 component that only looks like 1/pi — keep the
tuned value and allow the lint on that statement.
- Implement Apollonius PPC (Point-Point-Curve) and multi-tangent CCP solvers for lines in arc.rs
- Support tangent line snapping for all 3-input arc combinations (Tangent-Point-Point, Point-Tangent-Point, Tangent-Tangent-Point, Tangent-Point-Tangent, Point-Tangent-Tangent)
- Resolve TangentGeom::Line f32 truncation in snap.rs to preserve true f64 key vertices during tangent evaluation and TangentObject construction
- Preserve strict CUT_TOLERANCE (1e-7) in trim.rs while ensuring tangent contact points are detected accurately
- Add unit tests for line tangency solvers, tangent trim detection, and angular precision sweeps
- Pins: codec 8189f83, kernel a82f17d, graph d3558bb (all manifests and
the python plugin lock).
- MASSPROP reports volume, centroid, inertia, products, radii of
gyration and principal moments of 3D solids and bodies from their
B-rep (exact where analytic, else from a fine mesh).
- OFFSET of ellipses and splines through the kernel's curve offset.
- FILLET between circles, ellipses and splines through the kernel's
curve-curve fillet, trimming arcs and open splines to the tangents.
The kernel bump brings the DWG ACIS audit fixes: slices, booleans and
press/pull on cones, slanted cylinder sections, survey coordinates,
spline walls and touching parts.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
3DROTATE (ROTATE3D) took the drawing's rotation path, so a polyline only
turned in its own plane. It now asks for a base point, an axis — X, Y, Z
or a second point — and an angle, and rotates the selection about that
axis in space.
Fixes#1641
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- Dynamic-input fields take ' and " and read 2'9" / 3' as lengths (#937)
- STRETCH on a selection made by a crossing window stretches through that
window and goes straight to the base point (#1068)
- STRETCH's crossing-window steps show no coordinate boxes (#657)
- Collapsed ribbon panel titles wrap at words, never mid-word (#920)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Fixes:
- Font prompt no longer lists bundled ltypeshp/qcadshp shape files (#1626)
- Wide polylines step at a discontinuous segment width; PEDIT marks the
current vertex; keyword steps refresh the command preview (#1628)
- Radius-0 fillet drops the zero-length segment it left, so the corner
fillets again (#1422)
- FILLET Trim / No trim option (#1558)
- True-colour wires plot in their own colour; colour picker stores the
value it shows (#1621)
- Model tab keeps its page setup; "Save changes to layout" in Model (#1620)
- QNEW default template in Options > Files; .dwt in the open dialog
(#1134, #1113)
- GRIDUNIT / GRIDMODE / PERSPECTIVE variables (#1618, #1524)
- PTYPE (#1433)
- ZOOM nX / nXP (#1465)
- CHSPACE between model and paper space through a viewport (#1428)
- Moving a dimension keeps its automatic text placement
- Shell icon; "&&" button labels (#1554)
- LINETYPE Load from a .lin file (#1588)
- XLINE / RAY hide the crosshair arms (#1437)
- Dynamic-input boxes keep clear of the crosshair and each other (#1546)
- Snap marker colour setting, dark default on light canvases
(#1497, #1229, #1128)
- Dimension style precision as a 0.00 pattern dropdown (#1426)
- Node graph nodes left of the origin no longer clip away (#1592)
- Collapse button in the command history header (#1094)
- Freeze-in-current-viewport toggle in the ribbon layer list (#1466)
- Geometric Center object snap for closed polylines (#1369)
New strings translated in all 21 locales.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The DXF reader keeps marker identities on the block record but never materializes the entities, so block_entity_handle/block_end_handle dangle after every DXF load (reopened baked *D dimension blocks hit this every time). Re-create missing sentinels at load finalize, reusing the file handle when free and minting otherwise. Idempotent and DWG-safe: loads whose markers already resolve are untouched. Pinned by dimlinear_survives_save_reload_with_baked_geometry.
With objects already selected, OFFSET opens at the side step with the
preview following the cursor instead of asking for a distance first
(#422). At the side step a typed distance places the offset at once on
the cursor's side, and a negative one on the other side; Enter at the
start repeats the last distance (#418). Erase and Layer, which lived on
the skipped distance step, are offered there too. With nothing selected
the distance-first flow is unchanged.
The opposite side is found by mirroring the cursor through its nearest
point on the outline, capped at half the offset distance so it cannot
cross a narrow gap back to the cursor's own side. Two new prompts are
added to the catalog and every locale.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
#1567 made every vertex a trim limit, so a polyline no edge crosses lost
the clicked segment and a trimmed piece stopped at the next corner instead
of running on to the next cutting edge. Vertices are no cuts again, a
polyline with no cut is left alone, and its own crossings cut it only when
it is among the cutting edges. The crossing window's unused pick corner is
dropped.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Real BT/Tj text objects ride alongside the vector outlines (Tr 3,
zero visual change): runs preserved at layout time, TTF styles embedded
as allsorts subsets with ToUnicode, width-matched Tm, clip-culled.
WireModel literals moved to ..Default::default() tails.
Codec: PRs #71-#74 merged (MPOLYGON layout, multiline ATTDEF/ATTRIB DXF,
DXF MATERIAL/ACSH matrix, restorable SAT/SAB + history roots) and issues
#55 #64-#69 fixed. EntityType now boxes Surface, Extended, Table,
MultiLeader and Helix (2344 B -> 848 B per entity): construction sites
wrap in Box, the entity traits forward through Box, and the python
plugin generator converts with into(). Kernel: PR #70 (cuboid ring
winding).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Once edited, a dimension is drawn live instead of from its *D block;
on the #898 drawing that differed in three places:
- Oblique / architectural-tick strokes were DIMASZ/2 to each side, the
block's are DIMASZ/sqrt(2) (its unit stroke runs corner to corner).
- Arrowheads and ticks shared the dimension line's wire, so a dashed
dim line broke its ticks into stubs. They get their own solid wire
(and explode as lines as before).
- A diameter's user-positioned text was lifted by the DIMTAD offset even
when the stored point already was the text's middle, as a file saved
elsewhere writes it; it is lifted only when it lies on the leader
(#1323's case).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
flatten_plan 2,289 -> 1,098-1,144 us (-50..-52%); flatten_scene_apply 1,213 -> 789-813 us (-33..-35% vs baseline; -28.5% same-session O2-vs-O1, drift-corrected).
Pre-sizes collect/plan vectors and adds Scene::update_entities so FLATTEN issues one geometry bump per batch instead of per entity; single update_entity keeps its exact bump-per-call semantics.
Moves the flatten projection fns and command helpers into modules/draw/modify/flatten.rs (behavior unchanged) and adds flatten_plan / flatten_scene_apply to the COMMANDS suite.
A running command only knew the entities that existed when it started;
committed results are now handed back to it, and OFFSET adds them to its
pick set.
Fixes#673
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
EXPLODE left MTEXT untouched. Each laid-out run becomes a TEXT at its own
baseline origin, height, rotation and width, keeping inline colours.
Fixes#760
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
#1511 added an orthogonal ellipse projection and a nearest-end
arc_parameter to draw/modify/geom.rs, the latter shadowing the kernel
function of the same name. Both now live in opencadkernel 237827e and
are re-exported here, so every kernel caller gets them too.
test_coincident_line_and_arc_grip_move only printed values and asserted
nothing; removed.
Pins opencadkernel 237827e, opencadgraph fe36957.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- The Frames list shows the drawing's frame state (hide / display and plot /
display but not plot / frames vary), follows commands, undo and document
switches, and lists the mixed state as a disabled item.
- DWFFRAME and DGNFRAME are frame variables of their own, kept in the header,
and FRAME sets them with the others.
- Out-of-range frame values say "Requires an integer between 0 and 2." and
ask again; a set value reports "Regenerating model.".
- IMAGEFRAME is stored in the image variables as bits (2 is written as 3) and
a drawing without them uses the profile value, which setting IMAGEFRAME
updates and the settings file keeps.
- Raster images, PDF underlays and wipeouts are picked on their frame only;
underlay snap geometry is never picked.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Shares the benchmark harness between both suites, extracts the plan/batch/apply helpers out of the EXPLODE command arm, and adds the command_benchmarks target.
The codec and kernel repositories and crates are renamed opencadcodec and
opencadkernel. Inside OCS they are depended on under short keys, so code
reads `codec::`, `kernel::` and the new `graph::` (opencadgraph, the node
graph engine). File-format and protocol spellings stay as they were: the
ACIS product id `acadrust`, the ACADRUST_* switches and the plugin
version keys `acadrust_version` / `acadrust_source`.
A button left of MCP on the command line opens a translucent node graph
over the viewport, with a palette of object, input, math, logic, list,
text and geometry nodes added by click or drag. An object node owns
drawing entities and its rows are the Properties panel's own rows for
them: the single-object page is extracted from refresh_properties as
entity_property_sections, values use the control protocol's
property_json, and writes go through set_property_value with a property
target override, so the panel, MCP and the graph share one read/write
path. A list reaching an object row makes one entity per element. Each
graph action is one undo step; the canvas pans and zooms.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Implement the complete Block Definition dialog window launched via BLOCK
and BMAKE commands, featuring standard CAD layout, workflows, and entity
creation pipelines.
- Dialog UI & Layout:
- 2-column compact CAD grid with synchronized vertical heights (580 × 390px).
- Editable combobox with existing block names, invalid character validation,
and inline redefinition badge.
- Multi-line text editor widget for block descriptions (replacing single-line input).
- Quick Select (QSELECT) button integration restoring dialog state upon completion.
- Confirmation guard when attempting to redefine an existing block definition.
- Centered radio buttons, clean coordinate inputs, and accessible keyboard shortcuts.
- Base Point & On-Screen Workflow:
- BlockOnScreenCommand strictly enforces prompt sequencing: Base point is
prompted before object selection.
- Dynamically recalculates world_to_block and block_to_world affine transforms
when base point is specified on-screen, preventing stale (0,0,0) normalization.
- Supports Retain, Convert to block (INSERT placement), and Delete modes.
- Explode Enforcement:
- Guarded EXPLODE command to prevent decomposing blocks flagged as non-explodable.
- Dynamic Themed Icons:
- Added pick_point.svg, select_objects.svg, quick_select.svg, and warning_triangle.svg.
- Routed all icons through the semantic theming engine so line work (#B4B6B9)
and accents (#6DB7ED) adapt automatically to the active theme.
- Tests:
- Added unit tests for retain/convert/delete modes, redefinition, explodable flag,
on-screen base point transform recalculation, and command sequencing.