Commit graph cad-editor/Cargo.lock
Author SHA1 Message Date
Hakan Seven
6d7eb94701 chore(deps): bump acadrust — keep \N column breaks distinct
The MTEXT parser turned `\N` into a plain paragraph, identical to `\P`, so
a multi-column MTEXT arrived with nothing left to lay columns out from —
and the writer sent every break back as `\P`, collapsing the columns for
good on round-trip. `MTextParagraph::starts_column` now carries it.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-17 16:47:47 +03:00
Hakan Seven
3bd5453c3b chore(deps): bump acadrust — surface class-based entities the reader can't type
Pulls acadrust 769741d: the classes reader never derived is_an_entity from
item_class_id, so the flag was false for every class and any class-based entity
without an explicit type mapping was decoded as an object and dropped. Drawings
carrying an application's custom entity silently lost it.

Surfaces such entities as EntityType::Unknown with their raw record and proxy
graphics, so the renderer can fall back to the cached outline the way AutoCAD
does for an object whose enabler is absent.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-17 12:47:51 +03:00
Hakan Seven
8f3cd33ff0 chore(deps): bump acadrust — fix linked raster images vanishing
Pulls acadrust dd4a4dc: the R2013+ has_ds bit was skipped for any entity
carrying preview graphics, which desynced every preview-bearing IMAGE and
WIPEOUT — an IMAGE's imagedef handle decoded one off, so the IMAGEDEF lookup
missed, the file path resolved to nothing and the linked image silently
disappeared. Regression since v0.8.1 (the has_ds gate landed in 208bb09).

The skip is now narrowed to MULTILEADER, the one type actually observed to
omit the bit; IMAGE, WIPEOUT and MULTILEADER all decode correctly.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-17 12:22:01 +03:00
Hakan Seven
1d6a04183e feat(render): draw DGN line-style symbols on linetypes
Linetypes converted from MicroStation DGN keep their pattern in DGN line-style
objects (empty standard LTYPE), so entities using them drew as a plain line and
lost the symbols (e.g. a pipe's end circles). Walk the line-style tree
(resolved by name to its LSDefinition), collect the symbol components' anonymous
blocks, and draw each at the host polyline's endpoints, scaled by the symbol's
decoded scale (geometry / scale) so it matches the drawing (verified: a 0.75
ellipse renders at the file's intended 0.375 radius).

Bumps acadrust to 8e18c6b (DGN line-style symbol-scale decode). First pass: the
stroke dash pattern and exact per-vertex placement need more of the line-style
leaf decoded; the base line still draws solid.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-16 21:48:06 +03:00
Hakan Seven
7647fb427c chore(deps): bump acadrust to the DGN line-style reader
Picks up acadrust 6508b76: reads DGN line-style objects (AcDbLS*) into the
document's dgn_ls_definitions / dgn_ls_components tables. No OCS code consumes
them yet — that lands with the linetype linkage and renderer.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-16 19:54:08 +03:00
Hakan Seven
0e18b5bb33 feat(mline): render multilines from their MLINESTYLE + complex linetypes
Multilines were drawn with a fixed ±scale/2 two-line guess in the entity
colour, ignoring the MLINESTYLE entirely, so a drawing's custom style (per-
element offsets, colours and linetypes) was lost — a red/yellow multiline
rendered as a white box.

- mline.rs: resolve the MLINESTYLE (by style_handle, then name) and build one
  parallel line per element from its offset x scale + justification shift.
- tessellate.rs: special-case MLINE (like Leader) to emit one WireModel per
  element in the element's own colour, CPU-dashing every element through
  apply_along so the parallel lines stay in phase.
- linetypes.rs: render a drawing's OWN complex linetypes (embedded text/shape),
  document definition first and the bundled .lin catalog only as a fallback, so
  a file-defined text linetype like PLYN shows its text.
- Run the dash/glyph layout in a local frame (f64 origin subtracted, re-split to
  double-single after) so spacing stays precise at UTM coordinates, and pass
  tracking = 1.0 so embedded text keeps its letter spacing.

Cargo.lock pins acadrust to the MLINE->MLINESTYLE handle-link reader fix.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-16 18:44:15 +03:00
Hakan Seven
60c70ba023 release: v0.8.3 2026-07-16 11:57:34 +03:00
Hakan Seven
9a86a7394c build(deps): compile acadrust from the OpenAEC-Foundation/acadifc fork
Point the acadrust patch at the OpenAEC-Foundation/acadifc fork (still the
`acadrust` crate). Its main carries the Arc copy-on-write entity storage that
makes the undo document clone O(entities) refcount bumps instead of a full deep
copy — cutting the per-edit snapshot on a 788k-entity drawing from ~1.7s to
~70ms. No source changes here: acadrust`s public API is unchanged.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-15 07:55:27 +03:00
Hakan Seven
4bcf5063e9 release: v0.8.2
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-14 22:29:21 +03:00
Hakan Seven
8fb6c0339d deps: bump acadrust to d1e198b (DXF dimension block_name)
Picks up the DXF fix that reads DIMENSION group code 2, so dimensions
imported from DXF keep their baked *D block and render (their text no
longer drifts vs the DWG of the same drawing).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-14 13:59:57 +03:00
Hakan Seven
61502d8c2d deps: bump acadrust to 6365020 (MULTILEADER annotative default false)
Picks up the DXF over-annotative MULTILEADER fix (companion to the MTEXT
one): enable_annotation_scale now defaults false and DXF reads code 293.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-14 13:44:59 +03:00
Hakan Seven
64b4560708 deps: bump acadrust to 2af0eb5 (MTEXT is_annotative default false)
Picks up the DXF over-annotative-MTEXT fix: acadrust now defaults
MTEXT.is_annotative to false, so imported DXF MTEXT is no longer flagged
annotative and over-scaled in annotation-scaled viewports.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-14 13:34:28 +03:00
Hakan Seven
c0844ad55c feat(annotative): synthesize per-object contexts + editable UI
Make objects genuinely annotative — carrying real per-scale
representations that interoperate with other CAD apps — rather than just
a native flag. `create_annotation_context` synthesizes the extension-dict
chain (AcDbContextDataManager -> ACDB_ANNOTATIONSCALES -> per-scale leaf)
from the entity's placement; the editable Annotative toggle now covers
Text and block references as well as MText/MLeader; and a new
"Annotation Object Scale" dialog (OBJECTSCALE) adds/removes an object's
per-scale memberships. Requires the acadrust ObjectContextData encoder
(Cargo.lock bump).

Also fixes a render bug where objects carrying an *empty*
ACDB_ANNOTATIONSCALES (a single-representation marker with no per-scale
reps) were treated as annotative and (mis)scaled by the annotation factor
in scaled paper viewports, ballooning the text: an object is now
annotative-by-context only when its scale collection is non-empty, so
such objects render at their base geometry.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-13 22:38:29 +03:00
Hakan Seven
d005cc4ab1 feat(props): make dim-line colour editable for leaders and dimensions
The "Dim line color" row on Leader and Dimension entities was
read-only: an earlier attempt wired it to Leader.override_color, which
acadrust never serialises, so the pick was lost on save. Store it
instead as a standard ACAD_DSTYLE per-object dimension-style override
(DXF code 176, an ACI index) through the existing dim_override codec,
so it round-trips through both DWG and DXF like the other dim
overrides. RGB picks collapse to the nearest ACI, matching the rest of
the dim-colour stack (dimension styles are index-only through the file
layer). The renderer prefers the override over the style's DIMCLRD.

The write branch is guarded to leaders and dimensions so a mixed
selection cannot stamp the override onto other entity types.

Bumps acadrust to c9fe982, which carries parsed XDATA onto dimensions
on DXF read (it was dropping common.extended_data), so the dimension
override persists on DXF save as well as DWG.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-13 17:31:09 +03:00
Hakan Seven
0c4272fbb0 chore(release): bump to 0.8.1
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-13 14:38:56 +03:00
Hakan Seven
e378998dc3 chore(deps): bump acadrust — write entity XDATA to DXF
Pulls the acadrust fix that emits XDATA for every entity on DXF save (not
just hatches), so the leader dimension overrides and hyperlinks now
round-trip through DXF as well as DWG.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-13 01:14:15 +03:00
Hakan Seven
15d1bdbdfe chore(deps): bump acadrust — read model-space CANNOSCALE from DWG
Picks up the DWG reader reflecting CANNOSCALE from the AcDbVariableDictionary
into the header, so the status-bar annotation-scale pill shows the drawing's
real model-space scale (e.g. 1:70) instead of the "1:1" default.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-12 19:36:46 +03:00
Hakan Seven
d62057b869 feat(properties): show Annotative state + applied annotation scale
Resolve, per selected entity, whether it is annotative (from its text /
dimension / multileader style, or its own flag) and — when annotative — the
name(s) of the annotation scale(s) applied to it, shown as a read-only
"Annotative scale" row (Text / MText / Leader / MLeader).

The applied scale is read from the entity's per-scale object-context leaves
via the new acadrust CadDocument.context_scales map (context leaf ->
AcDbScale handle), walked from the entity's extension dictionary
(AcDbContextDataManager -> ACDB_ANNOTATIONSCALES). Bumps acadrust to pick up
that parsing.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-12 19:26:11 +03:00
Hakan Seven
208bb099d5 chore(deps): bump acadrust — MLeader/WIPEOUT preview has_ds parse fix (#347)
Pulls acadrust 4ac3d68: entities with proxy/preview vector graphics
(MULTILEADER, WIPEOUT) omit the R2013+ has_ds_data bit, so reading it
desynced the record and produced garbage MultiLeader text_location
(~2e39 → NaN glyphs). The labels now parse with finite locations and
render through the existing MText SDF path.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-12 11:36:33 +03:00
Hakan Seven
f3482e8b3e chore(release): bump to 0.8.0
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-11 02:32:06 +03:00
Hakan Seven
3c57260ddb fix(thumbnailer-win): make the COM DLL compile on the MSVC target
First real Windows build surfaced errors that a Linux host couldn't catch:

* Enable the missing `windows` feature gates (Win32_System_LibraryLoader,
  Win32_System_SystemServices, Win32_Security — the last brings in the
  `Ex` registry APIs) so the imports resolve.
* Depend on `windows-core`: the `#[implement]` macro expands to
  `windows_core::` paths, which need the crate nameable in the root.
* `IClassFactory::LockServer` takes `Win32::Foundation::BOOL`, not a
  `core` BOOL.
* Name the returned image type via a new `dwg_thumbnailer::RgbaImage`
  re-export instead of a direct `image` dependency.

Verified with `cargo check --target x86_64-pc-windows-gnu -p
dwg-thumbnailer-win` (and the native check still passes).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-11 02:11:22 +03:00
Hakan Seven
ba3b3202e8 feat(thumbnails): embed DWG previews and wire cross-platform file thumbnails
Round-trip a raster preview through the DWG's embedded preview slot and
surface it to the OS file managers, so drawings show their contents in
Explorer / Finder / Nautilus instead of a generic document icon.

OCS:
* io::thumbnail — rasterize the scene to a BMP DIB on save (embedded via
  acadrust's new Preview type) and read it back on open for the Start
  page recent list; `--dwg-thumbnail IN OUT SIZE` CLI extracts a badged
  PNG for external thumbnailers.
* io::file_association::install_thumbnailer — self-install the OS
  integration on startup: Linux writes a .thumbnailer + hicolor mimetype
  icons; Windows registers the IThumbnailProvider DLL under HKCU.

Shared core:
* crates/dwg-thumbnailer — lean (image-only) preview extractor + the
  `badge_dwg` full-width "DWG" band, used by every platform so the
  ribbon is single-sourced. Ships an rlib+staticlib.
* crates/dwg-thumbnailer-win — IThumbnailProvider COM in-proc server
  (cfg(windows), CI-built as a workspace member).
* macos/ — QuickLook thumbnail extension (Swift + C-ABI bridge to the
  core staticlib), assembled into a .appex.

Icons & packaging (single SVG source -> per-platform assets in CI):
* assets/mimetypes/image-vnd.{dwg,dxf}.svg — themed file icons.
* packaging: WiX ships dwg/dxf.ico + the thumbnail DLL and points the
  ProgIds at them; Info.plist gets CFBundleTypeIconFile + the QuickLook
  extension in Contents/PlugIns.
* release.yml — generate .ico (Windows) and .icns (macOS) from the SVGs,
  build the QuickLook .appex, and bundle everything.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-11 01:27:17 +03:00
Hakan Seven
5c4ba97c5f feat(thumbnail): embed a DWG preview on save, show it on the Start page
Generate a small wire-raster thumbnail when saving a DWG and embed it via
acadrust's preview API, so OCS drawings show a thumbnail in file browsers
and other CAD applications. Read the embedded preview back cheaply (file
header + preview bytes only, no full parse) to show a thumbnail per file
in the Start page's Recent Documents panel.

- io/thumbnail.rs: CPU rasterizer (current-layout wires -> BMP DIB) plus
  a preview-only reader/decoder (BMP/PNG -> iced handle) for the Start
  page.
- Embedded on save via stamp_thumbnail on both save paths.
- recent_thumbs cache filled on config load / recents change (never from
  a view); a thumbnail is drawn beside each recent file.

Requires acadrust at 3111694 (preview read/write), already pinned in
Cargo.lock.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-10 23:03:23 +03:00
Hakan Seven
dc7117f203 refactor(config): consolidate settings into one grouped settings.json
App preferences were spread across six flat plain-text files (settings.txt,
recent.txt, recent_limit.txt, statusbar.txt, ribbon.txt, plot.txt), each with a
bespoke line parser and no grouping. Replace them with a single grouped JSON,
serialized via serde (enabling the derive feature; serde_json was already a
dependency).

- New app/config.rs: AppConfig { settings, recent, statusbar, ribbon, plot } →
  <config>/settings.json (pretty JSON), load()/save().
- Make UserSettings, StatusBarConfig/StatusPill, CollapseMode and
  PlotDialogState serde-derived; #[serde(skip)] marks the plot dialog's runtime
  fields so only print preferences persist. Their bespoke .txt load/save is
  removed.
- App gains current_config/apply_config/save_config: one AppConfig::load at
  startup distributes into live state; every settings-change site
  (persist_settings_if_changed, recent add/remove/limit, status-bar pill
  toggle, ribbon density, plot commit) routes through save_config, which diffs
  against the last write to avoid thrashing.
- Clean start: the old flat files are ignored (no migration). ocad.pgp stays a
  separate hand-editable file.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-10 16:41:34 +03:00
Hakan Seven
f5b8a7d993 chore(deps): bump acadrust for *Model_Space block-record fix
Picks up acadrust 716d4b4: DWG reader synthesizes the mandatory
*Model_Space/*Paper_Space block records when a file's BLOCK_HEADER for
them never materialised, so model-space geometry is no longer dropped on
save (file shrank + reopened blank).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-10 11:33:40 +03:00
Hakan Seven
3928f1cfa5 chore(release): v0.7.9 2026-07-10 00:17:32 +03:00
Hakan Seven
9838cd6d83 fix(dxf): stop writing a duplicate *Active viewport (#319)
Opening a DXF whose active viewport is stored uppercase (*ACTIVE),
editing and re-saving produced a file with two full-window model-space
viewports — the file's own *ACTIVE plus a fresh *Active we add on save.
The reserved viewport name is case-insensitive, so the two didn't
collapse and other CAD apps drew them one on top of the other, which
read as the copied objects being linked / "reacting as one".

save_model_tiles_to_vports dropped existing active viewports with a
case-sensitive `name != "*Active"` filter, so an uppercase *ACTIVE
survived and sat next to the new entry. Route every *Active comparison
(save filter + camera/tile restore) through a case-insensitive
is_active_vport_name helper so the file's record is recognised and
replaced instead of duplicated.

Also bumps acadrust to #99f75fe (merged PR #1): the ASCII DXF writer now
emits shortest round-trippable floats instead of the full 16-digit
expansion, halving the round-tripped file size.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-09 22:36:00 +03:00
Hakan Seven
26cab3b712 fix(dxf): bump acadrust for DXF hatch pattern parsing (#330)
Pulls acadrust f1f4dbf, which makes the DXF reader parse hatch pattern
definition lines (and types group code 79 correctly) so custom/dashed
patterns load identically to the DWG instead of collapsing to flat
horizontal lines.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-09 20:42:55 +03:00
Hakan Seven
f91e45a62a chore(release): v0.7.8
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-09 00:42:01 +03:00
Hakan Seven
82203f2f22 chore: bump acadrust — read/write layer true-color on DXF (#223)
Pulls acadrust d32c9cf so DXF import reads RGB layer colours (code 420)
instead of collapsing every true-colour layer to Index(7)/white; ByLayer
entities then resolve to the correct colour.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-08 16:07:55 +03:00
Hakan Seven
0e368934ea chore: release v0.7.7 2026-07-08 00:33:34 +03:00
Hakan Seven
d528a3e2a5 feat(text): parse TEXT via acadrust + extend SDF text to MTEXT
Two related steps for the text pipeline:

- TEXT parsing now goes through acadrust's parse_plain_text (like MTEXT
  uses parse_mtext). text::acad_text_encode parses the value's %% codes —
  including %%u/%%o underline/overline and %%nnn — and re-encodes to the
  stroke tessellator's \L/\O + resolved-Unicode grammar, so OCS no longer
  tokenizes TEXT %% codes itself. (ATTRIB/TOLERANCE/DIMENSION still use the
  local tokenizer for now.) Bumps the acadrust pin to the commit that
  completes the TEXT/MTEXT control-code set.

- SDF text (OCS_TEXT_SDF) now covers MTEXT and every text-producing
  entity, not just top-level TEXT. TextStroke carries a GlyphRun (layout
  params); the collector walks convert()'s TruckObject::Text runs and
  applies annotation scale exactly as tessellate does for strokes.
  layout_glyph_quads shares lff::tokenize_run so %% specials resolve and
  \L/\O decorations are skipped (decoration LINES in SDF are still TODO).

Verified: stroke rendering unchanged with the flag off; SDF glyphs render
correctly for TEXT and MTEXT with OCS_TEXT_SDF=1. 154 lib tests green.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-07 00:53:19 +03:00
Hakan Seven
b88e5e4ad5 refactor(mtext): parse MTEXT via acadrust, drop OCS's own parser
OCS maintained a second MTEXT inline-code parser that duplicated
acadrust's `mtext_format::parse_mtext`. Replace it with an adapter
(`adapt_mtext_paragraphs`) that maps acadrust's structured MTextDocument
onto the existing layout types (`MTextLine`/`RunState`); the layout
engine (`layout_mtext`, `mtext_line_count`, and their callers) is
unchanged. Removed the hand-rolled `parse_mtext_paragraphs*` and its
helpers.

Validated during migration by a differential test (adapter vs the old
parser matched byte-for-byte over a 20-case corpus) and confirmed
rendering identically in the app; the differential test is replaced with
adapter-only unit tests. Relies on acadrust's new `MTextScalar` to tell
absolute `\H` from relative `\Hx` (bumped the acadrust pin).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-07 00:04:11 +03:00
Hakan Seven
ced42daff5 chore(release): v0.7.6 2026-07-05 21:05:51 +03:00
Hakan Seven
c91593ab9c perf(render): bump acadrust for O(1) ACIS record lookup
Pull in acadrust 4d51947, which makes SatDocument::record() an O(1) hit
instead of a linear scan. Tessellating an ACIS-heavy drawing was
O(records²) per solid; this drops the post-load mesh build for Clinic.dwg
(~9900 xref'd solids) from ~2.2s to ~0.85s of parallel tessellation, with
identical geometry.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-05 01:25:57 +03:00
Hakan Seven
13de968ee9 perf(xref): fix O(n²) AcDs parse and skip host re-tessellation
Opening a drawing that xrefs several 3D-heavy DWGs (e.g. Clinic.dwg with
5 discipline files) took ~137s, effectively all of it inside the DWG
parser's AcDs SAB blob extraction.

Bump the acadrust pin to ceef045, which bounds the AcDs end-marker search
so a missing marker family no longer scans the whole buffer per record.
Total xref resolve for Clinic.dwg drops from ~97s to ~4s.

Also make the post-xref mesh pass incremental: the host solids were
already tessellated by the background loader and the merge assigns fresh
handles to every imported entity, so `populate_missing_meshes_from_document`
keeps the cached host meshes and tessellates only the merged xref solids
instead of clearing and rebuilding the whole document.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-05 00:38:38 +03:00
Hakan Seven
60872da62a chore(deps): bump acadrust to f76e41a for the xref save fix
Picks up the acadrust change that writes xref blocks as external
references instead of serializing their resolved contents as owned
entities. An xref attached with XATTACH now survives a save + reopen as
a reference instead of being bound/exploded into loose objects.

Closes #268

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-04 22:40:25 +03:00
Hakan Seven
23d9a261b1 chore(release): v0.7.5 2026-07-04 20:18:47 +03:00
Hakan Seven
e515fa3156 feat(spline): draw fit-point splines via Catmull-Rom interpolation
A spline stored by fit points (DWG R2013+ scenario 2) has no control points
or knots, so the renderer — which built its curve from control points —
produced nothing and the spline was invisible. When a spline has fewer than
two control points but at least two fit points, interpolate a smooth
Catmull-Rom curve through the fit points and emit it as a dense polyline.
Open ends use reflected phantom points; closed/periodic splines wrap.

Pairs with the acadrust bump (e8e422a) that decodes the R2013+ fit-point
scenario correctly — together they make the fit-point spline in
Annotation-2D-Mesh-Solid-BIM.dwg render.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-04 19:52:56 +03:00
Hakan Seven
a8c368aef9 chore(deps): bump acadrust to 4f0599a (ENC transparency field-order + opacity fix)
Fixes entity transparency dropping to opaque on DWG read (e.g. the 85%
area-highlight solids in Clinic_Architectural.dwg). The ENC codec read/wrote
the transparency BL before the rgb BL (real order is rgb then transparency)
and stored the on-disk opacity byte without inverting to the internal
transparency-amount representation.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-04 14:48:15 +03:00
Hakan Seven
c94e50a8e1 chore(deps): bump acadrust (AcDs pre-table blob pool — HVAC 2446/2446 vs reference)
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-04 07:22:31 +03:00
Hakan Seven
a360da25fb chore(deps): bump acadrust to edfe3bd (AcDs record-table data-offset blob pairing)
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-04 07:00:24 +03:00
Hakan Seven
d6ad3100fe chore(deps): bump acadrust to f65a7e4 (AcDs record-table blob pairing)
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-04 05:49:45 +03:00
Hakan Seven
33f1150fad chore(release): v0.7.4 2026-07-04 01:46:33 +03:00
Hakan Seven
b3ead4f691 chore(deps): bump acadrust to 063da6f (AcDs SAB blob handle-pairing fix)
Fixes BIM 3D solids rendering at wrong positions — the AcDs SAB blob→solid
pairing now follows handle order instead of object-stream order, so every
solid gets its own geometry and body transform. Corrects the regression that
broke 3D solids in 0.7.3 (they were correct in 0.7.2) and places wall/floor
solids that previously piled near the origin.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-04 01:42:31 +03:00
Hakan Seven
313a0eacfd chore(deps): bump acadrust to 6d5c47b (issue 225 — DWG opens in strict readers)
Pulls the acadrust fixes that make a saved DWG containing 3D solids open
cleanly in a strict conformance reader: the AcDsPrototype datastore section is
now built correctly (segment-header ds_version, datidx, and the handle-sorted
search index) so 3D solids keep their geometry instead of being dropped, and a
dim-style/block handle collision on read is repaired so layouts round-trip.
Validated end-to-end on two real 107- and 273-solid files.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-03 21:17:04 +03:00
Hakan Seven
f4fffa1359 chore(release): v0.7.3
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-03 16:55:43 +03:00
Hakan Seven
f9b6834ad9 feat(export): exact ACIS geometry for planar solids on save
OCS models 3-D solids with truck, but extrude/boolean results carried no ACIS
body, so other CAD apps dropped them on open. Add an exact planar exporter and
run it at save time.

- scene::convert::acis_export::planar_solid_to_sat walks a truck Solid whose
  faces are all planes bounded by straight edges into a vertex/face-ring mesh
  and builds an exact ACIS body via acadrust's build_planar_body. Curved
  faces/edges return None (left for the NURBS path). A signed-volume check
  flips the winding if the shell comes out inside-out.
- OpenCADStudio::sync_truck_solids_to_acis fills in ACIS geometry for every
  cached truck solid that still has none, just before a Save / Save-As, so the
  written DWG/DXF carries real modeler geometry.
- Bump acadrust to 9142a50 (build_planar_body + classic-ACIS AcDs roundtrip fix).

Booleans (already cached as truck solids) now export exact geometry. Extruded
polygons will too once the EXTRUDE command caches its truck solid (a separate
change kept out of this commit because command_driver.rs holds unrelated
in-progress edits).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-03 15:43:37 +03:00
Hakan Seven
b5bee92335 chore(deps): bump acadrust to e06182f (AcDs 3DSOLID fix, issue 225)
Pulls the acadrust fix that links R2013+ 3DSOLID/REGION/BODY geometry to its
AcDs SAB blob (writes the has_ds_data flag, corrects the AcDsPrototype header,
and pairs blobs in object-stream order). DWG files saved with 3D solids now
reopen with their geometry intact in AutoCAD/BricsCAD instead of being dropped
as an empty data stream.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-03 07:04:07 +03:00
Hakan Seven
1523eda00f feat(properties): fill solid-history + viewport clipped rows
Bump acadrust to ef0e231 (region/body history handle + viewport clip
boundary now stored) and populate the rows the builders left blank:

- Solid3D / Body "Show History": derived from the history handle's
  presence (there is no separate stored bool — the DWG carries only the
  H 350 history link).
- Body "History": the history handle, matching how Solid3D already shows
  it.
- Viewport "Clipped": Yes when the clip-boundary handle is non-NULL.

Hatch Origin X/Y and Boundary retention stay blank by design: they are
not part of the persisted AcDbHatch record in DWG or DXF (retention is a
BHATCH command setting), so there is nothing to read.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-03 00:17:58 +03:00