Adds a 'Usage from a plugin' subsection to the v9 section: build + designate
inside one push_undo scope; refresh in place via clone -> edit -> replace
(the designation travels with the entity); refusal and idempotency rules;
and the snapshot-path note that out-of-process plugins resolve entities by
iterating document().entities() (a received DocumentSnapshot does not serve
get_entity lookups).
Document the designation in the host-model capability table and its own
section, and record the increment in the completion-plan ledger with the
storage decision, the behaviour split and the test evidence.
Host side of HostApi::set_reference_only: plugin-owned display geometry that
renders and snaps normally but must not be edited or picked by the person at
the screen, while the owning plugin keeps full write access through the host.
- Storage: a human-readable marker value in an XDATA record under the
host-owned OCS APPID (registered on first use; foreign values survive
verbatim; stale verbatim DWG EED is dropped on rewrite), so the flag
round-trips DWG and DXF with the entity and cannot collide with plugin
APPID namespaces.
- Grips: refresh_selected_grips yields none for a reference-only entity and
an active grip edit on a newly designated target is cancelled like a
locked-layer one.
- Picking: a reference-only wire flag extends the snap_only skips in every
hit test, so a click passes through to the editable entity underneath, and
box, window, lasso, fence and select-all gathers skip the designation;
fills, solids and instanced meshes are excluded through the shared
candidate handle set.
- Write policy: built-in user paths treat a reference-only entity like a
locked-layer one (Scene::update_entity / update_entities refuse,
erase_entities skips), while the plugin-owned variants
(update_entity_plugin / erase_entities_plugin, mirroring the
remove_entities editor split) and the whole HostSession surface write
through. The MCP entities read exposes a top-level reference_only boolean
and set_properties refuses with the reference_only failure code.
- Undo: the entity-write contract - a change joins a plugin-opened push_undo
scope, a scope-less change is one undo step of its own, refusals and
idempotent re-marks record nothing.
- Known limit: entities nested inside block instances (the block cache
rebuilds instance wires without the flag).
Evidence: marking_flags_and_unmarking_clears,
foreign_values_under_the_host_app_id_survive, other_apps_are_untouched,
reference_only_refusals_record_no_undo_step,
reference_only_designation_composes_undo_like_entity_writes,
reference_only_survives_dxf_and_dwg_round_trips,
user_paths_refuse_and_plugin_paths_write_reference_only_entities,
select_all_visible_skips_reference_only_entities,
clicks_pass_through_reference_only_wires,
box_selections_skip_reference_only_wires,
entities_records_expose_the_reference_only_designation.
The HostApi gains set_reference_only(handle, reference_only): a plugin can
designate display geometry it owns and refreshes. The entity renders like any
other, but the built-in edit paths treat it like an entity on a locked layer,
while the owning plugin keeps full write access (update, erase, XDATA).
- Appended at the trait tail with a refusing default so plugins keep compiling
against older hosts; the loader gate range is untouched.
- IPC: SetReferenceOnly / SetReferenceOnlyResult round-trip through the
shared dispatch, the V3 client and the V4 client, with the shared document
cache invalidated on success.
- build.rs version_info and manifest API_VERSION bumped to 9 in lockstep.
- Evidence: reference_only_request_and_response_roundtrip (bincode round-trip
of the request and both response payloads).
In a tilted 3D view a grip followed the cursor onto the screen plane
through the orbit target, so a circle or arc jumped to another radius and
a polyline vertex left its plane. A model-space grip now moves in the UCS
XY plane at its own elevation (the screen plane only when seen edge-on).
A solid stays drawn while its grip moves, and its own edges were still
snap candidates: a cone's base radius landed on its own side. The edited
entities are left out of the grip's snap set.
Fixes#1033
Co-Authored-By: Claude Opus 5.5 <[email protected]>
The new pointer op sends moves (canvas pixels, or a world point projected
through the camera the cursor edits with), button presses/releases and
wheel steps in order, and reports the cursor's world point after each, so
grip drags and picks go through the same cursor path as the mouse.
click now projects through that editing camera too (it used the model
camera inside an entered viewport), and the grips read reports each
grip's constraint axis.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
Expose creation fields, constraints and examples for the 11 supported types without expanding startup tool schemas. Share the creation contract and constructor with execution to keep accepted inputs consistent.
Validation: MCP, contract/factory and entity creation regression tests.
"Requires a number." and "Requires 0 or 1 only, or option keyword."
had no catalogue entry, so every locale showed them in English.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
DIST printed the raw world angle (-180..180) while the Properties panel
and typed directions follow the drawing's base angle and direction.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
Renaming a layer or a style was only applied on Enter; clicking anywhere
else dropped the typed name. A click that moves focus off a field whose
text changed now commits it. New and Copy in the style managers open the
generated name for renaming, so a new style can be named right away.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
Windows 10/11 retired IApplicationAssociationRegistrationUI's advanced
dialog; it fails with 0x80070490 and the user was left with only an
error. Open Settings > Default apps on the app's registered page instead.
Refs #725
Co-Authored-By: Claude Opus 5.5 <[email protected]>
A layout opened for the first time - one whose sheet viewport had to be
made, or one created in this session - gets a viewport centred on the
printable area, 0.8 of its width and height, zoomed to the model's
extents, while LAYOUTCREATEVIEWPORT is on. The profile variable takes
ON/OFF or 1/0 and is kept with the settings.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
A new drawing is metric with metre insertion units, but its annotation
multiplier stayed at Scene::new()'s unitless 1 while opened files and
CANNOSCALE convert paper millimetres into drawing units (0.001 at 1:1).
Annotative text and dimensions were drawn 1000x too large until the
first scale change, then shrank to their real size and looked gone,
also after switching back to 1:1.
One helper now derives the multiplier from the header; new drawings,
file open and every INSUNITS change (UNITS, the units popup, DWGUNITS,
SETVAR) go through it.
Fixes#1674
Co-Authored-By: Claude Opus 5.5 <[email protected]>
- The Image tab gains an Adjust card: X/Y offset in pixels (-2000..2000)
and X/Y scale (-10..10, tenth steps, a negative scale mirrors, zero keeps
the image's scale) with spinners and Reset, inactive while the image is
stretched; Keep aspect ratio is a switch and makes both scales follow.
- The preview shows the image at its offset and scale, tiled when tiled,
and a stretched image kept to its aspect ratio covers the view.
- Automation: step=<field>,+1|-1 and reset; offset/scale take any numbers.
- Shaded with edges, Shades of Gray and Sketchy have catalog entries in
every language.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
The web control channel gains a save operation that serializes the
active drawing in the requested format and returns it as base64 in the
reply, clearing the dirty flag, the counterpart of opening from bytes.
A host page can also define window.openCadStudioSaveFile(name, bytes)
to receive every saved or exported file in place of a browser
download; while it is set no file picker opens.
Fixes#1704Fixes#1705
Co-Authored-By: Claude Opus 5.5 <[email protected]>
Hatches are drawn before the wires and write depth, so a transparent
hatch above lines in draw order still hid them through the depth test.
Transparent hatches now go to their own renderer drawn after the wires:
the lines behind show through the blend and the lines in front still
win the depth test.
Fixes#1720
Co-Authored-By: Claude Opus 5.5 <[email protected]>
A polyline band was stroked like a pen line, with round caps and round
joins, and each segment as its own path, so corners came out rounded
and overlapping. Bands now use butt caps and mitre joins in one path,
and a tapered band fills each segment's quad so a zero-width segment
stays a thin line.
Fixes#1721
Co-Authored-By: Claude Opus 5.5 <[email protected]>
*.pat files in <config>/patterns and *.lin files in <config>/linetypes
are read after the bundled catalogs, next to the fonts folder SHX
files already resolve from.
Fixes#1725
Co-Authored-By: Claude Opus 5.5 <[email protected]>
- The background image texture is not an sRGB view: the image is drawn with
its own colours, as the solid and gradient colours are.
- An entered paper-space viewport shows its named visual style (Realistic,
...) in the render-mode picker, and a mode picked there is recorded as the
viewport's visual style.
- The view_background automation action takes offset=x,y and scale=x,y.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
add_entity_clone reset handle, owner and mode but kept the source extension dictionary handle, so a copy claimed a dictionary its document does not own. The clone now gets no extension dictionary, like baked and transformed-block children. Failing-first test included.
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 <[email protected]>
A headless plot with plot_style loaded the layout's stored page setup,
which put the layout's CTB back in place and, when that file was not in
the plot styles folder, failed the plot with "not loaded". The
requested table now stays active for every page.
Bump codec ddf0fd2 (viewport on state from DXF group 68, so viewports
written without bit 0x8000 show their contents), kernel b80079a,
graph 45c9649.
Refs #1739
Co-Authored-By: Claude Opus 5.5 <[email protected]>
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 <[email protected]>
The pasted block is defined around the clipboard base, so its origin
is already that point, but the insertion still subtracted the base and
landed the block offset from the pick. The base now only positions the
world-space preview, and it stays f64.
Fixes#1731
Co-Authored-By: Claude Opus 5.5 <[email protected]>
Sync clients, indexers and virus scanners open a freshly written file
for a moment without delete sharing, which refuses ReplaceFileW with a
sharing violation. Saving straight after Save As into a Dropbox folder
hit this every time. The replace now retries for about two seconds
before reporting the file in use.
Fixes#1712
Co-Authored-By: Claude Opus 5.5 <[email protected]>
The button runs QNEW since #1635, and QNEW was missing from the
commands the Start screen allows, so it was refused until a drawing
was open.
Fixes#1728
Co-Authored-By: Claude Opus 5.5 <[email protected]>
- Selection filter: condition rows name INSERT as a block reference, as
the object-type list does since #1726 (shared qselect_type_label).
- MCP: re-pin the tool schema digest for the view_background action
added in #1722.
- -VIEW: fix an indentation slip and wrap two long lines from #1722.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
A layout plotted by window drew its sheet at the paper-space origin, so
the title block sat on the grey background away from the paper. The
sheet now centres on the plot window, or sits at the plot offset from it
when the plot is not centred.
Bump codec 8aa574a (polyline vertices in owned-handle order, which fixes
self-crossing viewport clip boundaries), kernel d79bb30, graph 4810ee0.
Fixes#1678
Co-Authored-By: Claude Opus 5.5 <[email protected]>
#1286 added the drag-to-install Applications symlink to
packaging/build_macos_signed.sh, but official DMGs come from release.yml,
which still ran `hdiutil create -srcfolder OpenCADStudio.app`. That image
holds only the app, so the merge had no effect on the downloads #769 is
about.
Stage the app beside an /Applications symlink, as the signing script
does, and build the image from that folder. A new step mounts the result
and fails the job unless the app is present, `Applications` points at
/Applications, and the app's signature still verifies. Untagged runs
upload the DMG as a workflow artifact, as the snap job does, so the
layout can be checked without cutting a release.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
The web build was only deployed to the live site, so a specific version
could not be pinned. The bundle is now zipped before the site data is
added and uploaded to the release; hotfixes built from main skip it.
Closes#1706
Co-Authored-By: Claude Opus 5.5 <[email protected]>