- Modify COPYCLIP command to write entities as JSON to system clipboard
- Modify CUTCLIP command to write cut entities as JSON to system clipboard
- Modify COPYBASE_AT command to write copied entities as JSON to system clipboard
- Entities are serialized as JSON with base point coordinates for cross-platform support
- Clipboard data format: OCS_CLIPBOARD_JSON header + base point + entity data
- Works in web (WASM) build via Clipboard API and native builds via iced clipboard
This fixes the issue where copy command didn't persist to system clipboard in web browser,
allowing proper paste operations and clipboard sharing between application instances.
Co-authored-by: Copilot <[email protected]>
- Modify COPYCLIP command to write entities as JSON to system clipboard
- Modify CUTCLIP command to write cut entities as JSON to system clipboard
- Modify COPYBASE_AT command to write copied entities as JSON to system clipboard
- Entities are serialized as JSON with base point coordinates for cross-platform support
- Clipboard data format: OCS_CLIPBOARD_JSON header + base point + entity data
- Works in web (WASM) build via Clipboard API and native builds via iced clipboard
This fixes the issue where copy command didn't persist to system clipboard in web browser,
allowing proper paste operations and clipboard sharing between application instances.
Co-authored-by: Copilot <[email protected]>
- Changed button padding from [5, 10] to [4, 8] to match layout tabs
- Changed container left padding from 6.0 to 2.0 for consistent spacing
- Plus button now has same distance from Start tab as from Layout tabs
Co-authored-by: Copilot <[email protected]>
Ports FreeCAD's planegcs 2D geometric constraint solver to Rust as a new
crates/ocs_gcs workspace member, and wires it into the document/scene model
as a persistent SketchConstraintSet: Coincident, Horizontal/Vertical,
Parallel/Perpendicular, Equal, Tangent, Distance, Angle and Radius
constraints that re-solve live (including mid-drag, not just on release),
render glyphs and a DOF badge, flag conflicts with a one-click resolver
pill, and round-trip through save/load via an XRecord blob.
Also includes docs/command_reference.md (a statically generated reference
of every registered command and its prompt sequence) and
docs/named_parameters_design.md + docs/backlog.md, which hand off the next
queued feature (a named-parameter/expression table) and consolidate every
deliberate scope-down and open gap found along the way, so a fresh session
has a complete starting point.
Co-Authored-By: Claude Sonnet 5 <[email protected]>
The first measurement showed four consecutive edits at ~192 ms each with
a handler cost of 0.55 ms. That is below the `update` line's 5 ms
threshold, so the log reports the latency but not what asked for it —
and whether a live command preview is bumping the geometry epoch on every
mouse move is exactly the question the numbers raise.
`nav-prepare` now carries the message label alongside the op.
Co-Authored-By: Claude Opus 5 <[email protected]>
Drawing a point in a large drawing feels slow, and nothing currently
measures the thing the user actually waits for. `update` times the message
handler, `wires-build` and friends time the rebuild, but the span between
them — press to the frame that shows the new geometry — has no number.
Navigation already has exactly that plumbing: `record_nav_perf` stamps an
instant when the input arrives, `prepare` and `encode` pick it up, and
`nav-prepare` / `nav-render` report `input`, `build`, `prepare` and
`elapsed` from the original event.
`NavPerfOp::Edit` reuses it. `update` snapshots `geometry_epoch` before
dispatch and stamps the sample when it moved, so any message that changed
geometry — a drawn point, a grip commit, an undo — reports its full
latency rather than only the handler's share.
Diagnostic only: `record_nav_perf` sets a pending sample and nothing else,
so no LOD or settle behaviour changes.
Nothing is optimised here on purpose. Four call sites feed the snapper
along different branches, and picking one to instrument before knowing
which dominates is how the earlier rounds of this work were wasted.
Co-Authored-By: Claude Opus 5 <[email protected]>
Double-click / "Open With" never puts the file on argv — Finder always
delivers it as a kAEOpenDocuments Apple Event instead, which nothing in
this app listened for, so it just showed "cannot open files in this
format" even though the file association itself was registered
correctly.
The standard fix, implementing application:openURLs: on this app's own
NSApplicationDelegate, isn't available here: winit already installs
its own delegate to own window/lifecycle events, NSApplication has
exactly one delegate slot, and winit's class doesn't implement the
open-document method.
This bypasses the delegate protocol and registers directly with the
lower-level Apple Event Manager (AEInstallEventHandler) instead — the
same mechanism AppKit's delegate forwarding is itself built on, and
independent of who owns the delegate. Registration happens on the
iced Subscription's first poll rather than in main() before app::run()
— registering earlier gets silently overwritten by winit's own
NSApplication startup, confirmed by testing against a real `open -a`
rather than assumed from Apple's docs.
This handles a file opened while the app is already running. A cold
launch (app not running yet) needs a different mechanism, in the
following commit.
Co-Authored-By: Claude Sonnet 5 <[email protected]>
Add the typed document facade and plugin IPC adapter. Prepare bulk edits
before mutation, preserve undo and dirty state, keep profile elevations,
validate numeric inputs and session bindings, and generate Python constructors
with typed results.
Reuse existing entity transforms and profile conversion. Compute mass
properties and closed-surface bounds in cadkernel; pin its main revision
6a5e6fc2822f6af6b2611cd605b44437b35158f0. Keep plugin API metadata at version 6.
Validation: 646 native application tests, 597 kernel tests, 12 document API
tests, 91 plugin API tests, 3 Python tests, default/IPC feature builds and
wasm32 check passed.
Delete the thin re-export file; src/app/doc_api.rs now uses ocs_doc_api::convert
directly (use ocs_doc_api::convert + convert::* call sites). Remove the
mod doc_api_convert registration from src/app/mod.rs.
The conversion logic already lives in the crate (src/convert.rs) from the prior
move; the shim was redundant. 623 host lib + 38 doc_api tests green.
Move the 503-line host-independent entity-conversion module (acadrust EntityType
<-> DTO conversions, transform_entity_geometry, entity_to_profile_curves,
bulge_arc_segment, entity_bounds, entity_kind_name, points_aabb) from
src/app/doc_api_convert.rs into crates/ocs_doc_api/src/convert.rs (host feature).
The host file is now a thin re-export (pub use ocs_doc_api::convert::*) so all
existing crate::app::doc_api_convert::* paths keep working unchanged. Zero
coupling risk (the module only touches acadrust + crate DTOs).
623 host lib + 8 crate + 3 consistency green.
- layouts.json: append the 6 missing ops (CreateDimensionRadius/Diameter/Angular,
CreateAttributeDefinition, CreateTable, CreateDimensionAngular2Ln); regenerate
binding_schema.json + api_reference.md wire vocabulary (all 28 ops).
- Helix bounds: bound the evaluated spline control polygon (was a degenerate
single-start-point AABB).
- points_aabb: empty -> Geometry::Empty('entity has no points to bound'), not
UnknownId (the entity exists; don't misclassify as stale/deleted).
- mass_properties: accuracy-first fine tessellation + graceful degradation to the
approximate meshes.metrics value when the cold-tess budget is exhausted (large
distinct-solid batches no longer hard-fail).
- IMPLEMENTATION.md: Volume/Centroid rows + accuracy paragraph + test count (618)
consistent with the final design.
- 618 host lib + 8 crate + 3 consistency green.
- mass_properties: query path now uses fine mesh_body(0.1, 1e-4) for near-analytic
volume/centroid; the render-mesh metrics cache (coarse display LOD) no longer
shadows query accuracy. Memoized per (handle, epoch); cold-tess budget kept.
- IMPLEMENTATION.md: accuracy item done.
- Test accurate_volume_centroid_sphere_and_cube (sphere within 0.5% of 4/3*pi*r^3,
centroid at centre, cube exact) -> 617 host lib green.
Capture the rendered canvas during the clean frame instead of requesting synchronous GPU buffer readback. Preserve embedded previews and allow saving when canvas readback is denied. Add a browser save and reopen regression check.
Fixes#1021