Commit Graph
63 Commits
Author SHA1 Message Date
Hakan SevenandClaude Opus 5.5 68330ce39e Merge pull request #1747 from schoeller/reference_only_entities
Reference-only entities (plugin API v9): a scene-scoped, in-memory
designation for plugin-owned display geometry, plus HostNotification
dispatch to native plugins so they can re-mark on DocumentOpened.

Resolves the new DeltaSnapshot site in block_editor.rs.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-14 23:46:42 +03:00
Sebastian 50db12b169 refactor(scene): reference-only designation becomes a scene-scoped set (API v9)
Per the upstream review of the XDATA-based storage: the host no longer writes
its own state into the saved file. The marker record under the host-owned OCS
APPID, the on-first-use APPID registration and the verbatim-EED rewrite
handling are removed; the single source of truth is a scene-scoped in-memory
set of entity handles (Scene::reference_only) that dies with the drawing tab,
so a reopened file starts undesignated and the owning plugin re-marks on the
document-opened notification.

All behaviour sites are unchanged, driven by the set: the wire stamp moves
from an XDATA read to a set lookup threaded through the tessellation
pipelines (tessellate_entity and the dimension text path take the handle set
as a plain parameter), and the pick filters, selection retains and
update/erase refusals read Scene::is_reference_only.

Undo keeps the entity-write contract: set mutations are recorded as explicit
first-touch before/after values on each history delta (the parametric-
constraints channel pattern). A designation inside a plugin push_undo scope
joins it, a scope-less change is one step of its own, an idempotent re-mark
records nothing, erasing a designated entity drops the set entry with the
entity, and undo/redo restores entity and designation together.

The round-trip test is inverted: reference_only_designation_is_not_written_
to_dwg_or_dxf now asserts the marker appears in neither format's bytes, that
no OCS APPID or marker record survives a reload, and that the designation
stays live in memory.
2026-10-14 21:12:17 +02:00
Hakan SevenandClaude Opus 5.5 fcf1cedf52 feat(select): Ctrl+click picks one segment of a polyline
Ctrl+click on a polyline selects the segment under the cursor (again to
drop it); several segments can be picked. Only the picked segments are
highlighted, and MOVE, ROTATE, SCALE and MIRROR then change just their
vertices, so the neighbouring segments stretch to follow. Any other
selected objects are transformed whole as before.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-13 22:14:56 +03:00
Sebastian d24adc39b5 feat(scene): reference-only entities refuse the edit paths (API v9 host)
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.
2026-10-13 12:38:53 +02:00
turbuczn 09cf99f85c feat: Add advanced selection filter 2026-10-12 22:27:19 +02:00
Karim Jerbi 9cf9ff2c5c style: apply cargo fmt across workspace 2026-10-11 03:14:29 +01:00
Hakan SevenandClaude Opus 5.5 443b935a3f chore: bump codec d28fd71, kernel a03e4f0, graph 79bdc4b
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>
2026-10-02 00:08:55 +03:00
Karim Jerbi 801882314f perf(explode): batch erasure, section map, pre-sized vectors
EXPLODE apply 504ms -> 61ms (-88%), geometry 70.2ms -> 58.1ms (-17%) on the 2,500-compound fixture.
2026-09-28 06:58:47 +01:00
ramox81andClaude Opus 5.5 2e397aec99 VPCLIP arc options, visible linked clip boundaries, XCLIP depth rejection
- VPCLIP arc mode takes Angle, CEnter, Direction, Radius and Second pt with
  the reference prompts, and CLose closes with a tangent arc; the arc math
  is shared with PLINE.
- Viewport clip boundaries from MVIEW and VPCLIP stay visible; picking or
  erasing a boundary takes its viewport along.
- XCLIP Clipdepth: a rejected front plane keeps the old front plane and
  clears the back plane.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-25 12:22:44 +03:00
Hakan SevenandClaude Opus 5.5 f537aff75c feat: node graph overlay; move to opencadcodec/opencadkernel/opencadgraph
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>
2026-09-25 07:34:23 +03:00
huanldandClaude Opus 5.5 279a87418e feat(automation): entity, block, publishing and REST operations from the fork
The operations docs/automation/API-SPEC.md (PR #1383) describes, brought
over from huaninstratech/OpenCADStudio so the specification no longer runs
ahead of the code:

- entity CRUD: entities_create, entities_delete, entities_transform,
  entities_copy_to, and `where` filters on query
- blocks and export: block_define, block_delete, a normalised wblock
- publishing: layout_create, page_setup_set, plot (per_page included)
- metadata: sysvar, xdata_set / xdata_get, file_identity
- collections: group_create, selection_set_save / load
- control plane: batch, events, view_focus, close
- the REST transport: `--http <port>`, the /api/v1 routes and their
  OpenAPI 3 description
- person-in-the-loop picks: user_select and getpoint, hosted by the GUI
  over the same REST routes, with on-screen pending signals

Taken from the fork's commits b7a7ed80, 69396b42, 64f1cf6a, c3aafc8e,
bb5a7bfa, 52317a5c, 50d293ba, b90e194f, 517c6397, 53a5c4c9, a49ac045,
37de5a46, a78b1822, 6d9aed2a, 33f522da, 5b5cafe2, 02a7e78d, 94df40dc,
fd5bc14d, 485fac61 and 2c5fc994.

Left out on purpose: 37de5a46 also removed the donation surface (the
Patreon fetch, the donation prompt, the Start-page supporters rail, the
DONATE command and its locale strings) and replaced the About dialog's call
to action; that is the fork's own product decision and stays out. The
fork's version bump and its unrelated IFC/BIM work are not part of this.

Adapted while porting: the REST server and the GUI bridge are desktop-only
and a template start is refused in the web build, so the wasm target still
compiles; the two plot tests read the PDF through the shared stream helper,
because exported streams are Flate-compressed; the benches set the new
crosshair field; comments and docs describe each operation in its own
terms rather than by another product's API names.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-24 13:41:07 +03:00
Felix Riestra 8648225ac5 Merge remote-tracking branch 'origin/main' into plugin/host-model-api
# Conflicts:
#	crates/ocs_plugin_api/src/process/v4.rs
#	src/app/update/mod.rs
2026-09-19 23:58:01 +02:00
Felix Riestra 11d5614991 Add versioned scripting host model and entity coverage 2026-09-19 01:13:24 +02:00
ramox81 6a1c649016 Fix Properties hyperlink collection editor 2026-09-17 18:17:25 +03:00
Hakan Seven 08bb17b0b8 Fix constraint editing and glyph feedback 2026-09-15 21:55:40 +03:00
Hakan Seven c9eeb6f66e Merge pull request #1284 from ramox81/codex/autoconstrain-parity
# Conflicts:
#	Cargo.lock
#	Cargo.toml
#	src/app/view/mod.rs
#	src/ui/overlay.rs
2026-09-15 12:38:41 +03:00
Hakan Seven dfe8b77cca Merge PR #1280 and expose constraint value visibility 2026-09-15 11:55:05 +03:00
ramox81 66be530655 Complete automatic constraint behavior 2026-09-15 11:47:28 +03:00
Felix RiestraandClaude Sonnet 5 ed2e0fbc4a Wire up the Properties panel's Parameters section
PropValue::ParamRow/ParamAddRow, the PropParamInput/Commit/Delete/AddNew
messages, their command_driver handlers (on_prop_param_commit/_delete/
_add_new, resolve_named_parameter_edit), and their render functions all
already existed — but nothing ever constructed the "Parameters" section
that would route data to them, so the whole inline add/rename/redefine/
delete workflow was unreachable from the UI. Adds that missing section
to the no-selection page in refresh_properties, alongside a new
PropValue::ParamsVisibilityToggle header row (mirrors the existing
show_constraint_values setting) for toggling whether constraint pills
show their driven value/parameter name.

Users can now manage named parameters inline in the Properties panel
(live resolved values, add/rename/redefine/delete) as an alternative to
the separate PARAMETERS modal, which continues to work unchanged.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-15 01:26:48 +02:00
Felix RiestraandClaude Sonnet 5 59ae38ae1a Add per-constraint delete; fix named-parameter reference bugs
Constraint delete: a Properties-panel row delete button, viewport
click-to-select on a constraint glyph pill with Delete-key support, and a
right-click "Delete Constraint" menu item — all routed through one
undoable Scene::selected_constraint-aware path.

Fixes two named-parameter bugs found while testing that feature:
- DIMCONSTRAINT: a parameter named like a mode-switch keyword ("r", "d",
  "a", "x", "y") could never be referenced, since the keyword check ran
  before the parameter-name check.
- PARAMETERS modal Apply rebuilt Scene::named_parameters but never
  refreshed the Properties panel, leaving renamed/deleted rows stale
  until an unrelated refresh (e.g. a selection change) happened to occur.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-15 01:08:34 +02:00
Hakan Seven 84836b0f0c Merge pull request #1234 with safe hyperlink routing 2026-09-13 21:03:30 +03:00
ysdirector 171fc48987 feat(viewport): Ctrl+click opens an entity PE_URL hyperlink
Entities that carry the standard PE_URL XDATA record (what HYPERLINK writes)
can now be followed from the canvas: Ctrl+click opens the link in the system
browser and consumes the click, so no box/lasso selection starts.

- scene::selection::pe_url_of() reads the record with the same rule as the
  Properties panel hyperlink field; unit-tested.
- The ViewCube/compass hit region wins over a hyperlink drawn beneath it.
- Unchanged behaviour when Ctrl is not held or the entity has no link.
2026-09-13 23:53:50 +08:00
Felix RiestraandClaude Sonnet 5 bd9a2d08f7 Add Properties-panel Constraints/Parameters sections, a constraint-pill
value toggle, and redesigned constraint-ribbon icons

Properties panel:
- New "Parameters" section (shown with no selection) listing every named
  parameter with inline name/formula editing, add, and delete, backed by
  new PropValue::ParamRow/ParamAddRow and command_driver handlers
  (resolve_named_parameter_edit, on_prop_param_commit/_delete/_add_new).
  A fresh parameter's formula now defaults to "1", not "0" — a 0-length
  seed value is a genuine solver singularity for a Distance constraint
  driven by that parameter, with no defined direction to grow back out of.
- New "Constraints" section (shown for a single selected entity) listing
  every constraint touching it as a clickable PropValue::EntityLink that
  selects the linked entities in the viewport, danger-tinted when the
  constraint conflicts.

Constraint pills:
- New Options > General toggle, "Show values and parameter names on
  constraint markers" (on by default, persisted). Off, every pill shows
  just its bare glyph instead of glyph+driven-value/parameter-name — the
  glyph alone is enough to see a constraint is present, without the value
  text covering nearby geometry on a dense sketch.

Constraint-ribbon icons:
- Replaced all 18 unicode/letter glyph icons (including the plain "F",
  "L", "M", "S" letters) with proper SVGs under assets/icons/constrain/,
  matching the Modify section's two-color style (#B4B6B9 white / #6DB7ED
  blue, consistent stroke width). Tangent reuses the Draw section's
  white-arc-plus-blue-dots motif.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-10 23:16:11 +02:00
Hakan Seven f69f0b32be fix(sectionplane): persist and clip section modes correctly 2026-09-09 20:53:05 +03:00
Hakan Seven 9b112e3ac0 fix: finalize reviewed drawing and interaction paths
Reset stale geometry when automation replaces a drawing and resolve material paths from its directory. Cover precise indexed snapping, large-coordinate line intersections, leader ordering, invalid image buffers and browser clipboard fallback. Preserve Options dialog resizing.

Validation: cargo test --workspace --all-features (866 passed); wasm32 application check; Node clipboard regression check; Python binding tests (3 passed).
2026-09-09 13:33:14 +03:00
Hakan Seven 973af87d58 fix: keep exact snapping, source drawing data and adaptive options layout
Resolve curve intersections through cadkernel, retain empty exact results, gather analytic candidates independently of tessellation, and bound material uploads. Preserve large MINSERT data while limiting rendering work; remove obsolete review narratives.
2026-09-09 13:17:30 +03:00
Hakan Seven cba2680be0 fix: preserve web builds and leader selection order 2026-09-09 13:10:21 +03:00
Panos d02ce08349 Make a large selection scale with the drawing
Selecting a whole drawing was unusable on a 186 468-entity file. Four costs
scaled with the selection where they did not have to.

Every selected handle triggered a walk of the entire document to find LEADERs
pointing at it. On the file this came from, selecting 471 583 entities in a
585 786-entity drawing did not finish inside eight minutes. A reverse index
built once per geometry epoch answers the same question; a test asserts it
returns exactly what the walk returned, including the case of two leaders on
one annotation.

Group expansion asked the selection about every group: for each selected
handle it scanned each group's own member list. Asking each group once
whether it holds anything selected turns that around.

Selecting and deselecting went one entity at a time, and `deselect_entity`
rebuilt the ordered list with a `retain` per handle, so removing N of M
walked the order list N times. Both now take a slice.

Grips were built for every selected entity. AutoCAD stops at GRIPOBJLIMIT,
and the DWG header does not carry the variable, so its default of 100 stands
in for it.

The remaining two commits are measurement: `select-commit` reports the phases
of a selection separately, which is what showed the bulk paths had been added
to the press-drag branch while a click-move-click window goes through a
different one entirely.
2026-09-09 10:29:24 +03:00
Hakan Seven 4972bbed70 Fix issues found while integrating performance PRs 2026-09-08 17:33:02 +03:00
PanosandClaude Opus 5 5e5a810ee5 perf: stop rebuilding the selection filter list on every drawn point
`view-detail` on an edit frame:

    total=105.6ms  chrome=105.4   [every other section 0.0]

and the edit latency measurement puts ~102 ms of a 192 ms drawn point in
the gap between the handler returning and the scene primitive being built
— which is that same `chrome`.

The status bar asks for `entity_type_names_in_layout` on every frame to
populate the selection-filter menu, and the cache behind it was keyed on
`geometry_epoch`. Every drawn point bumps that epoch, so every drawn point
walked all 444 937 handles a model space owns to answer a question the
line did not change: adding a line to a drawing that already has lines
leaves the set of type names exactly as it was.

The cache now carries the set alongside the list, and folds edits in from
the delta journal — the same incremental shape `entity_index` already
uses. Additions can only grow the set, so they are applied directly and
the existing `Arc` is handed back untouched when nothing new appeared. A
removal can retire a type and cannot be resolved from a handle that is
already gone, so those still fall back to the full walk.

`entity_type_name` returns a literal for every arm but one — `Extended`
borrows its class name from the entity — so the set holds owned strings,
and the hot path tests `contains` before allocating.

Tested: a second line of an existing type must hand back the same `Arc`,
a new type must still appear, and the folded answer must equal what a
rebuild from scratch produces.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-08 16:42:21 +03:00
Hakan Seven de3fe2fdf1 Remove native and web compiler warnings
Reuse the application library from the binary entry point instead of compiling the module tree twice. Keep desktop-only transports and caches out of web builds, remove unused test code, and check executable targets in CI.
2026-09-05 13:21:02 +03:00
Hakan Seven 9d991d7feb Bound GPU uploads and complete Greek and performance integration 2026-09-04 20:26:29 +03:00
PanosandClaude Opus 5 f1efc73cbe perf: stop rescanning every entity to fill the selection-filter menu
Pan and even plain cursor movement over the canvas ran at ~8 fps on a
large drawing. Nothing rendered was responsible: the GPU idled at 0-8%,
encoding no scene at all changed nothing, and vertices, pixels and draw
calls could each be cut without moving the number. `view` was the frame
-- 110 ms of it against 3-6 ms on a small drawing -- and inside `view`
it was the status bar.

The status bar builds the selection-filter menu, which asks for the
distinct entity type names in the layout. That call cloned the layout's
entire handle list (1 166 357 handles, ~9 MB), then did a map lookup, a
String allocation and a BTreeSet insert for each one. About 107 ms of a
110 ms frame, to produce roughly twenty names, for a menu that is only
visible when opened.

Cache the result against geometry_epoch and the layout block, since it
only changes when entities are added or removed, and make the scan
itself borrow the handle list rather than clone it and collect &str,
allocating only for the names it returns.

The immediate-mode UI rebuilds every widget on every mouse move, which is
fine as long as nothing in that path is O(document). This was.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-04 16:20:30 +03:00
ramox81 1a913ee640 Fix revolve angle and wireframe display 2026-09-03 16:24:43 +03:00
Hakan Seven 6d6defa0ad fix(color): show color book identity 2026-09-01 08:44:28 +03:00
Hakan Seven 7ea4f338f6 fix(render): preserve transparency inheritance
Resolve ByBlock alpha independently from color and keep explicit opaque values from falling back to layer transparency.

Pin the matching cadcodec API across desktop, plugin, and web targets.

Refs HakanSeven12/cadcodec#2
2026-08-31 22:48:57 +03:00
Hakan Seven 217f20d8bc fix(clipboard): preserve pasted content
Reset cross-document ownership, include non-wire and locked objects, and rebuild image caches for embedded OLE content.

Refs #934
2026-08-29 22:40:59 +03:00
Hakan Seven ff1f873633 fix(mleader): repair creation and editing 2026-08-28 19:36:48 +03:00
ramox81 cce25be83a Complete multileader creation and property behavior 2026-08-27 17:35:47 +03:00
Hakan Seven 81e7add1dd fix(tolerance): complete workflow integration
Sync current main and companion codec changes before preserving unsupported frame rows, rendering in the entity plane, and sharing final layout metrics with placement preview.
2026-08-27 00:14:08 +03:00
Karim Jerbi 7215faae44 feat(properties): make inherited properties editable, align dropdowns, and switch transparency to EditChoice
Enable in-place editing of inherited properties in the Properties panel:
- Transparency: Switch to PropValue::EditChoice with ByLayer and ByBlock presets to allow direct typing of any numeric percentage value (0..90%) without combo_box autocomplete interference.
- Select-all-on-click: Integrate EditChoice text inputs into build_field_key_map with dedicated widget IDs, preserving click-to-select-all across editable fields.
- Material: Provide bounded preset choices (ByLayer, ByBlock, Global, and active custom material) to avoid scanning large drawing dictionaries.
- Plot style: Implement mode-aware behavior with interactive Choice in STB mode and ReadOnlyWithTooltip in CTB mode.
- Read-only tooltips: Introduce PropValue::ReadOnlyWithTooltip to provide contextual explanations for locked fields while preserving mouse text selection and clipboard copying.
- Dropdown alignment & unified borders: Fix EditChoice internal input/caret background clipping so the container's 1px neutral/active border surrounds the entire control identically to Lineweight and text inputs.
- Document defaults & aggregation: Synchronize document header defaults when editing with No selection, and aggregate heterogeneous multi-selections (*VARIES*).
2026-08-23 23:20:34 +01:00
Hakan Seven bb49f92e99 fix(model): repair solid booleans
Track selection order for directional subtraction and use the kernel fixes for periodic curved-face intersections.\n\nRefs #816
2026-08-20 16:00:20 +03:00
Hakan Seven 5e62da464e fix(properties): preserve literal text
Separate numeric fields from names and content so only numeric property values are evaluated as expressions.

Refs #809
2026-08-20 14:58:12 +03:00
gianlucafiore 2d1ee0d936 fix: improve classic leader behavior and annotation linkage 2026-08-13 11:58:54 -03:00
Hakan Seven 0be9c41773 fix(layers): protect locked entities
Keep locked-layer objects selectable for inspection while suppressing grips, property edits, command mutations, and stale editor writes.
2026-08-12 12:46:41 +03:00
Hakan Seven 4ac10187c2 fix(model): preserve solid history lifecycle 2026-08-11 20:10:23 +03:00
Hakan Seven afc94dce13 feat(qselect): expand filter workflow
Refs #511
2026-08-05 13:40:53 +03:00
Hakan Seven 8050fc79fd fix(scene): clear selection after erase 2026-07-28 17:35:21 +03:00
Hakan Seven 05b044f367 perf(scene): make geometry edits incremental
Avoid full document, cache, and GPU rebuilds for entity deltas so add, delete, history, selection, and live polyline edits stay responsive on large drawings.
2026-07-28 17:16:27 +03:00
Hakan Seven 731df4a725 feat(cad): integrate standard codec coverage
Render, edit, query, select, and explode newly decoded standard entity variants. Pin acadifc de8d6b5 and preserve None color semantics.
2026-07-26 19:30:43 +03:00