Commit Graph
76 Commits
Author SHA1 Message Date
Afonsop 6f429f2416 fix: close the review findings on the last web wave
Full verification of the XREF/data/ARCHIVE/worker wave (three
reviewers, one forensic) found no blockers and no crossfire damage;
five majors and several minors are fixed here.

- ARCHIVE now packages XREFs: the bytes registry added by the same
  commit is consulted (the in-code 'no xref store exists' comment was
  false within the commit), and the drawing is packaged only after
  the full save preparation — without it kernel solids shipped
  without their ACIS data.
- PendingClose stores the stable tab id instead of a vector index:
  the web save now completes asynchronously, and closing a lower tab
  during the serialization window shifted indices — closing the WRONG
  tab, or panicking on a stale one. All producers and consumers
  resolve the id at use.
- The xref bytes registry is capped (6 entries, oldest evicted): every
  open, drop, and pick registered full drawing bytes with no bound —
  an OOM waiting to happen. Reopened recents register too, so any
  entry path can serve as another drawing's xref.
- A re-picked data-link source with the same name but different bytes
  no longer silently replaces the first (the browser hands back bare
  names, so two same-named files collided and every reference read
  the newer pick): the pick is refused and the user is told why.
- The unresolved-xref warning lists file names (what to drop on the
  page), not internal block names; the ZIP writer refuses the ZIP64
  sentinel values (0xFFFF counts, 0xFFFFFFFF sizes/offsets) instead
  of emitting archives that send strict readers hunting for a ZIP64
  EOCD that is absent; docs note the worker-side saves.

Known follow-ups documented, not fixed here: the serde-skipped
ExtendedEntity/CadDocument raw bytes still drop on worker crossings
(needs acadrust accessors — upstream), and WBLOCK/SAVEALL/ARCHIVE
still serialize inline (the worker route is a small follow-up).
2026-09-18 00:32:59 +01:00
Afonsop c643a10ed9 web: raster images, WBLOCK/SAVEALL/SCRIPT/CTB/LAYTRANS/INSERT, filled TTF text
A fresh web-vs-desktop audit found the remaining gaps; this closes the
top ten.

Raster images: IMAGE attach read the picked file via image::open on a
name-only path (dead on wasm), and raster references inside opened
drawings decoded the same way. Picked bytes are now registered in a
name-keyed store (the PDF-underlay pattern), decoding runs from memory,
and dropped .png/.jpg/.bmp/.tif files register by name so unresolved
references in opened drawings re-resolve and render (and export to PDF).

Command gaps fixed with the bytes-at-pick / download_bytes pattern:
- WBLOCK now downloads the extracted block instead of failing on fs.
- SAVEALL saves every dirty tab instead of printing a no-op message.
- SCRIPT picks and reads the .scr file through the browser picker.
- CENTERLTYPEFILE picks the .lin/.dnl file and populates from text.
- Custom .ctb tables picked on web now parse, register for the
  session, appear in the plot dialog list, and apply (load_named
  previously returned builtin-only on wasm).
- LAYTRANS 'Load standards file' parses the picked drawing on the
  existing web worker.
- INSERT 'from file' in the block palette parses picked bytes and
  feeds the shared import path.

Text fidelity: TTF-named styles rendered as thin stroke glyphs on web
because the font database was empty. Fetched Noto faces are now
registered into it with a family alias table (Arial, Times New Roman,
Cambria, ... -> Noto Sans/Serif), so those styles render filled, shape,
export to PDF as vector fills, and appear in the style picker.
ViewCube labels request semibold again on web.

docs/native-vs-web.md: the hatch and font rows were stale (both work on
web now), the GPU row claimed WebGPU is used where available (the
backend is pinned to OpenGL), and the parallelism row missed the parse
worker — all corrected.
2026-09-17 20:59:58 +01:00
Afonsop ebee7e5489 feat(help): open a generated command reference instead of Discussions (#1049)
HELP now opens docs/command-reference.md on GitHub — a 600-command
reference grouped by category with default shortcuts and selection
behavior, generated from the in-repo command registry. A staleness
test fails when the registry and the page drift apart; regenerate
with UPDATE_COMMAND_REFERENCE=1 cargo test command_reference. The
command-line notice is localized in all 21 languages.
2026-09-17 13:14:06 +01:00
Hakan Seven d738ebfcc6 Standardize parametric constraints and interoperability 2026-09-15 03:19:52 +03:00
Hakan Seven 753df67ee4 Complete parametric drawing interoperability 2026-09-14 23:51:37 +03:00
Hakan Seven 912b217d26 fix: delegate dimension transforms to cadcodec 2026-09-14 14:22:10 +03:00
Hakan Seven 010d23fa95 chore: sync reviewed dependency mains 2026-09-14 10:02:49 +03:00
Hakan Seven 2f741d689f fix: address open PR review findings 2026-09-14 09:45:37 +03:00
Hakan Seven fc1788df65 fix: export interoperable DWG constraint graphs 2026-09-14 02:57:33 +03:00
Hakan Seven 95bad2a3b2 Fix web folder paths and allow main-only web hotfix deployment 2026-09-13 20:30:12 +03:00
Hakan Seven 07acd1284c Render procedural checker materials correctly 2026-09-13 01:50:42 +03:00
PanosandClaude Opus 5 5f161bb037 Show the exact build in About, Copy Info, REPORT and --version
Builds from main reported only the release version (2026.36) even when
HEAD was hundreds of commits past the tag. build.rs now also emits
OCS_TAG_DISTANCE, OCS_COMMIT_DATE, OCS_BUILD_METADATA and
OCS_FULL_VERSION: a clean checkout of the release tag stays "2026.36",
anything else becomes "2026.36+194.gef189d77", with ".dirty" appended
for uncommitted changes and only the hash when no tag can be counted
from (shallow clone, tarball). OCS_APP_VERSION is unchanged so the
update check, donation gate, User-Agents and window title keep working.

The About dialog gains Build / Commit date / Profile cards, Copy Info,
the REPORT issue template and recovery reports carry the full version,
and `-V`/`--version` print it instead of Cargo's 2026.36.0. Release
workflows check out full history so release binaries see the tag.

Also fixes the build being marked dirty when there is no repository:
diff-index exits 128 there, not 1.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-12 16:19:40 +03:00
Hakan Seven 932bf970c6 Update CAD dependencies 2026-09-12 14:13:49 +03:00
Hakan Seven ef189d7781 Update CAD dependencies for DWG template fix 2026-09-11 21:42:29 +03:00
Hakan Seven 798379fbe0 Update dependencies after cadcodec PR 44 2026-09-11 19:13:22 +03:00
Hakan Seven 5e91e23752 Update codec and kernel dependencies 2026-09-11 18:52:31 +03:00
Hakan Seven 9b58ca8a93 Harden parametric sketch constraints 2026-09-11 09:45:57 +03:00
Felix RiestraandClaude Sonnet 5 cf33a1d019 Add DWG/DXF-native constraint persistence alongside the XRecord format
Implements docs/dwg_constraint_compatibility_design.md's staged plan in
full: materializes the sketch-constraint set as acadrust's real
AssocNetwork/Assoc2dConstraintGroup object graph on save, additive to
the existing OCS_SKETCH_CONSTRAINTS XRecord, so files also carry
constraints AutoCAD/BricsCAD recognize as their own native objects
(per Hakan's request on the upstream project). Covers every
ConstraintKind, including AssocVariable wiring for named-parameter
driving values, and clears+rebuilds on each save.

DWG round-trips the full dependency chain; DXF only keeps the
constraint-group shell since acadrust's own DXF writer deliberately
omits AssocDependency-family objects. Both behaviors are covered by
tests and documented in the design doc's progress section, along with
two other implementation-time findings (skipping the NOD-anchored
top-level network, and the DWG writer's root-node/connections wire
format).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-09 17:26:53 +02:00
Felix RiestraandClaude Sonnet 5 5d93476c01 Add DWG-native constraint compatibility design doc
Hakan (upstream maintainer) asked for the sketch-constraint system to
persist using the constraint object model already exposed in acadrust/
cadcodec (Assoc2dConstraintGroup, AssocConstraintNode), so a file saved
by OpenCADStudio carries constraints AutoCAD/BricsCAD recognize as
their own native objects, not just an opaque custom XRecord blob.

Covers:
- The full ConstraintKind -> AssocConstraintNodeData mapping table,
  grounded in build_constraint's actual refs shapes (the real contract,
  not the doc comments).
- The geometry-node mapping for SketchRef (line/circle/arc/point
  references) onto Line/BoundedLine/Circle/Arc/ImplicitPoint nodes.
- The AssocNetwork -> AssocAction -> Assoc2dConstraintGroup graph shape
  actually needed, not just a flat data swap.
- A proposed additive persistence strategy: write both our own
  OCS_SKETCH_CONSTRAINTS XRecord and the native graph, since our model
  carries things (DrivingValue::Named) the native graph can't yet
  losslessly express.
- Known gaps: Equal has no length/radius sub-kind split natively,
  several AutoCAD constraint types we don't model at all, Tangent
  involving an Arc (a pre-existing gap in the constraint system,
  unrelated to DWG compatibility).

Three of five open questions are resolved against Autodesk's own
primary sources rather than left as inference: the ObjectARX 2012 SDK's
own C++ headers (mirrored on GitHub, Autodesk's own copyright notice
grants free use/distribution -- it's the SDK Autodesk publishes for
third-party interop) and Autodesk's live public ObjectARX reference
site. Confirmed: the associative network's dictionary key
("ACAD_ASSOCNETWORK"), the AcDb::ImplicitPointType enum settling how
SketchRef's point markers map to constraint geometry nodes, and that
AssocVariable's evaluator field can be left empty (Autodesk's own doc:
"the default evaluator for current acad version will be used"). Two
questions remain and need a real write-then-open test rather than more
reading: whether AutoCAD tolerates a partially-populated graph, and
DWG version gating on fields not yet checked.

Suggested staged approach: prove out Horizontal/Vertical on a single
Line first (sidesteps the value-dependency wiring), verify it opens
cleanly in real AutoCAD/BricsCAD or a DWG inspector, before writing
more of the graph on an unverified foundation. Design only -- no
implementation yet.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-09 14:48:02 +02:00
Felix RiestraandClaude Sonnet 5 7cddf31bcb Add named parameters, UI scale setting, OPTIONS/OP dispatch, and help manual
Named parameters (docs/named_parameters_design.md, stages 3-4):
- ParameterTable (src/scene/named_parameters.rs): a document-wide table of
  named formulas, each resolved through a shared expression evaluator with
  cross-parameter references, cycle detection, and division-by-zero/parse
  error reporting. SketchConstraint::driving_param becomes DrivingValue
  (Literal | Named) instead of a bare f64, resolved at solve time by
  sketch_solve::build_constraint via Scene::named_parameters.
- Persistence (src/scene/named_parameters_persist.rs): same lazy XRecord
  model sketch_persist.rs already established, synced around open/save.
  Bumps the sketch-constraint XRecord's own format version (1 -> 2) since
  DrivingValue's shape doesn't line up with a version-1 blob's bytes.
- PARAMETERS command and its editor (src/ui/window/named_parameters.rs):
  add/remove/edit rows, live validation, duplicate-name detection: Apply
  defines the table and re-solves every constraint scope with a
  named-parameter-driven constraint (command_driver.rs). Distance/Angle
  constraint prompts (modules/draw/constrain/value.rs) now accept either a
  literal or an existing parameter's name, mirroring how the constraint's
  own value prompt already worked.
- Undo scope-down carried over from this project's own established pattern
  (constraint-system stage 9): the geometry an Apply moves is one undo
  step, but the parameter table edit itself has no undo entry yet — a
  documented follow-up, not a silent gap.

UI scale setting (src/app/settings.rs, app/mod.rs, ui/window/options.rs):
  a whole-interface scale percentage (50-200%), wired directly into iced's
  own per-window scale_factor hook rather than per-panel font-size
  plumbing, so it applies immediately to every panel, dialog, and the
  ribbon at once. Persisted alongside the existing lineweight-display-scale
  setting.

OPTIONS/OP command dispatch (app/commands/view.rs, app/commands/mod.rs):
  OPTIONS was registered for autocomplete but had no dispatch arm — the
  Start-tab welcome screen's own button was the only way to reach it.
  Found live-testing the UI-scale setting, unrelated to that feature
  itself. "OP" is AutoCAD's own short alias.

help/: a new self-contained static user-help manual (manual.md as the
authored source, tools/build_help.py splits it into the committed static
HTML pages plus search index) — not yet wired into the application.

64 new/updated tests across the named-parameters and constraint-prompt
changes.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-09 13:50:08 +02:00
Felix Riestra e2d39b049d Merge branch 'main' into feature/parametric-constraint-system
# Conflicts:
#	src/app/automation.rs
#	src/app/mod.rs
#	src/ui/ribbon/widgets.rs
2026-09-09 13:35:07 +02:00
Hakan Seven 4ddd19f6e8 feat(mcp): describe complete CAD record schemas 2026-09-09 01:01:44 +03:00
Hakan Seven 8f574c8388 feat(mcp): expose complete drawing records 2026-09-08 23:59:13 +03:00
Felix RiestraandClaude Sonnet 5 63a74b19a9 Add persistent sketch-constraint system (ocs_gcs port) and named-parameters handoff docs
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 <noreply@anthropic.com>
2026-09-08 22:19:23 +02:00
Hakan Seven d35a93c6e8 Avoid reserved MCP session argument 2026-09-07 19:34:31 +03:00
Hakan Seven 2ebad14586 fix(web): capture save previews from the browser canvas
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
2026-09-06 13:14:56 +03:00
Hakan Seven cb88f2ded6 Accelerate native MCP workflows 2026-09-05 19:03:16 +03:00
Hakan Seven 0e4f755e6f Make native MCP self-describing 2026-09-05 18:22:05 +03:00
Hakan Seven 9129c85f97 Add Greek README translation and language links 2026-09-05 14:52:45 +03:00
Hakan Seven 13afc1479f Automate weekly releases and synchronize application versions 2026-09-05 02:13:20 +03:00
Hakan Seven 28d3aa5be2 Harden native MCP compatibility 2026-09-05 01:36:23 +03:00
Hakan Seven cbb4015760 Remove MCP bundle distribution 2026-09-05 01:10:13 +03:00
Hakan Seven afbf826b0c Ship client-neutral MCP bundles 2026-09-04 23:58:39 +03:00
Hakan Seven 071e224d26 Add client-neutral native MCP control 2026-09-04 23:27:03 +03:00
Hakan Seven 28cc473062 Add persistent live OpenCADStudio control 2026-09-04 22:25:55 +03:00
Hakan Seven 0d766be3df fix(plugins): preserve document path encoding
Keep OS-native path data intact across IPC instead of replacing non-UTF-8 bytes.

Refs #901
2026-08-29 16:00:18 +03:00
Hakan Seven 2842f6dc58 fix(plugins): gate on_load behind API v5
BREAKING CHANGE: plugins using on_load must target API v5 and declare api_version = 5.

Refs #901
2026-08-29 15:57:26 +03:00
Hakan Seven 466ab99c63 fix(plugins): enforce rustc compatibility
BREAKING CHANGE: API v4+ plugin packages must declare the exact rustc version used to build the binary.

Refs #901
2026-08-29 15:54:41 +03:00
Sebastian ed3e064a47 feat(plugins): include rustc version in plugin compatibility gate
OpenCADStudio/plugins#901

- Record the host's rustc --version output in the embedded version_info.json.
- Add rustc_version/rustc_declared/rustc_compatible to plugin manifests and
  release metadata, mirroring the existing acadrust gate.
- Reject API v4+ plugins whose declared rustc differs from the host, with a
  clear one-line error message.
- Propagate the rustc gate through the marketplace, install flow, and UI.
- Update plugin architecture docs to describe the new ABI metadata.
2026-08-29 10:34:47 +02: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
Hakan Seven 7aa19f6869 docs: update workspace screenshot 2026-08-22 15:51:15 +03:00
Hakan Seven e9a3a357ee docs: update modeling screenshot 2026-08-22 15:47:52 +03:00
Hakan Seven cfbf3233be docs: add Bulgarian README 2026-08-22 13:17:00 +03:00
Hakan Seven c465bcf624 feat(web): add SEO landing page 2026-08-22 09:33:38 +03:00
Hakan Seven 405da13a65 docs: move translations under docs/readme 2026-08-15 22:14:22 +03:00
Hakan SevenandClaude Opus 5 273f482aee refactor: retire the solid3d feature — the web build gets solids too
The feature existed for one reason: truck's mesh and boolean crates reach
`vtkio → xz2 → lzma-sys`, a C library that cannot cross-compile to wasm32. So
the web build dropped it, and with it the Model tab, solid tessellation and
ACIS import — all of which quietly did nothing in the browser.

cadkernel is pure Rust and has no C dependency, so none of that holds any
more. The feature gated exactly two things by the end, `acis_export` and the
save-path sync that calls it, and both are as portable as everything around
them. Removing it means the web build makes primitives, runs booleans, draws
ACIS solids read from a file, and writes them back out as exact geometry — the
same as the desktop build.

Verified against all three: native, `--no-default-features`, and an actual
`wasm32-unknown-unknown` check rather than an assumption about one.

The docs claimed otherwise in four places and are corrected. `tessellation.md`
in particular was organised around whether an entity "goes through truck",
which is no longer a question anything can be asked — the three paths are now
a kernel B-rep mesh, a curve sampled through `entities::curve`, or geometry
emitted directly, and the per-entity table is updated to match.

`index.html` no longer passes `data-cargo-no-default-features`; there are no
features left to turn off.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-10 01:28:25 +03:00
Hakan Seven fcc6e1f8e1 fix(web): link plugins to desktop app
Keep browser entry points visible while explaining that native
plugins require a desktop install.

Refs #567
2026-07-29 16:28:20 +03:00
Hakan Seven 2424eeb74d fix(web): hide unsupported plugin manager
Fixes #567
2026-07-29 16:17:17 +03:00
Hakan Seven 4e25e88c31 feat(plugins): redesign plugin manager 2026-07-29 14:27:32 +03:00
Karim Jerbi 73b05e1dec perf(core): cache ribbon_groups() with OnceLock, avoid per-frame tree allocations
Change CadModule::ribbon_groups() from -> Vec<RibbonGroup> to -> &[RibbonGroup],
backed by a per-module OnceLock cache. The ribbon group tree is static data
(&'static str, Copy enums) that was being fully reconstructed — Vecs, String
clones, enum discriminants — on every call, including all three per-frame
call sites (view(), dropdown_overlay(), style_combo_overlay()).

- 7 built-in modules + 2 plugin templates cache via function-local OnceLock.
  Safe because each is a unit struct with exactly one instance per process
  (plugins run in isolated child processes; see PluginProcess::spawn()).
- SharedCadModule avoids the static pattern entirely, storing groups in an
  instance field (owned.rs).
- IPC runner converts &RibbonGroup -> OwnedRibbonGroup directly via new
  From<&T> impls, avoiding an intermediate clone.
- render_small/render_large and the two make_tool_row closures now borrow
  (&RibbonItem, &[ToolDef]) instead of taking ownership, so the view loop
  doesn't need to clone items to satisfy the old by-value signatures.
- Various match-ergonomics deref fixes (*id, *default, *icon, etc.) from
  the &RibbonItem pattern change.
2026-07-02 21:00:57 +01:00