Commit graph

2,248 commits

Author SHA1 Message Date
Hakan Seven
e37b77e426 feat(model): persist solid creation history 2026-08-11 19:52:17 +03:00
Hakan Seven
dc6dc2256d fix(model): sync solid render interaction 2026-08-11 19:39:01 +03:00
Hakan Seven
ed21681d48 feat(model): preview primitive height 2026-08-11 19:39:01 +03:00
gianlucafiore
d76dcd8426
Merge pull request #741 from gianlucafiore/feature/objectscale-dialog
Add annotation object scale access from Properties
2026-08-11 12:10:41 -03:00
gianlucafiore
9741195c2c feat: add object scale button to properties 2026-08-11 12:08:55 -03:00
Hakan Seven
6cafea92bc fix(web): preserve DWG render state
Carry rendering fields omitted by document serialization and normalize block origins before building web caches.
2026-08-11 17:16:46 +03:00
Hakan Seven
a1f64d7663 fix(render): restore solid surface rendering
Keep viewport styles from disabling selected shaded modes.\n\nPack mesh shader inputs to stay within WebGL limits.
2026-08-11 15:44:40 +03:00
gianlucafiore
e0ead249b6
Merge pull request #740 from gianlucafiore/fix/dimension-properties-editable
Fix dimension styles incorrectly treated as read-only
2026-08-11 08:45:12 -03:00
gianlucafiore
3a752029cd fix: allow editing dimension styles 2026-08-11 08:40:54 -03:00
Hakan Seven
7775e3d2c9 chore(release): prepare v0.9.5 2026-08-11 13:18:51 +03:00
Hakan Seven
6fdd090176 fix(ui): restore start actions and web copy
Route About info through browser clipboard on WASM.
Let Start-page links reach the existing command allowlist.

Refs #707
Refs #738
2026-08-11 13:15:09 +03:00
Hakan Seven
70f65270aa refactor(properties): remove detail sections 2026-08-11 12:49:28 +03:00
Hakan Seven
de6f6c933b fix(acis): use kernel angle policy 2026-08-11 12:49:20 +03:00
Hakan Seven
c00ee3d924 fix(acis): use source fit tolerance 2026-08-11 10:17:22 +03:00
gianlucafiore
aedd0b8d2d
Merge pull request #735 from gianlucafiore/feature/plotstyle-color-picker
Fix CTB plotting for inherited block colors
2026-08-10 20:02:19 -03:00
gianlucafiore
efc881d5bc Merge remote-tracking branch 'upstream/main' into feature/plotstyle-color-picker 2026-08-10 20:00:13 -03:00
Karim Jerbi
d9016e7196
Merge pull request #734 from KarimJerbi/feature/redraw-regen
Add REDRAW / REDRAWALL / REGEN / REGENALL commands- #721
2026-08-10 23:59:14 +01:00
gianlucafiore
97c904796e fix(plot): preserve inherited ACI for block plotting 2026-08-10 19:57:24 -03:00
Karim Jerbi
f3d8904fc7 fix(alias): only advance the migration marker after the merge persists
Advancing ocad.pgp.version (or the web counterpart) could succeed while the
merged alias table write failed, so a later launch skipped migration against a
stale file and permanently lost the new aliases. Gate the version write on the
alias-table write (native fs::write / web set_item) succeeding.
2026-08-10 23:49:43 +01:00
Karim Jerbi
7013aa8cbb fix(alias): migrate new default aliases into existing profiles
Existing installs only got newly-added default aliases when storage was
absent; load_aliases parsed an already-present ocad.pgp or web alias table
verbatim, so R/RA/RE/REA remained unknown to profiles seeded before version 2.

Introduce a versioned default merge: track the default-table version each
profile has seen (wordless ocad.pgp.version marker / localStorage key) and
fold in only the aliases introduced after that version, never overwriting
user-defined mappings or resurrecting deliberately removed aliases. On first
migration the merged table and the advanced marker are persisted so later
launches skip the already-delivered aliases.
2026-08-10 23:39:46 +01:00
Karim Jerbi
de1c1798a0 fix(scene): cfg-gate test-only refresh_pending_any to silence dead-code warning 2026-08-10 23:26:27 +01:00
Karim Jerbi
319710f36b test(commands): alias R routes like REDRAW 2026-08-10 23:26:27 +01:00
Karim Jerbi
d2e18ead38 feat(aliases): R/RA/RE/REA for REDRAW/REGEN; register verbs 2026-08-10 23:26:26 +01:00
Karim Jerbi
692bb3babf feat(commands): REDRAW/REDRAWALL/REGEN/REGENALL 2026-08-10 23:26:26 +01:00
Karim Jerbi
7ace7fef9e feat(render): per-viewport REDRAW force_rasterize through builders to prepare gate 2026-08-10 23:26:26 +01:00
Karim Jerbi
df103575b9 feat(scene): REDRAW refresh request resolved to per-viewport instance ids 2026-08-10 23:26:26 +01:00
gianlucafiore
4d15ac88b2
Merge pull request #733 from gianlucafiore/feature/plotstyle-color-picker
Improve plot style editor and PLOT integration
2026-08-10 19:11:43 -03:00
gianlucafiore
e2e4bfdcd4 feat(plotstyle): improve CTB editor workflow 2026-08-10 19:09:40 -03:00
Hakan Seven
22a294c705 build(deps): update cadkernel revision 2026-08-10 21:14:53 +03:00
gianlucafiore
c4322f4cbf
Merge pull request #730 from gianlucafiore/fix/ltscale-line-arc-ellipse
Fix linetype scaling for lines, arcs and ellipses
2026-08-10 15:11:54 -03:00
gianlucafiore
d22d0a272c fix(linetype): preserve patterns for basic curve entities 2026-08-10 15:10:42 -03:00
gianlucafiore
1cd1b89250
Merge pull request #729 from gianlucafiore/fix/705-grip-dynamic-input
Add dynamic input and precision snapping to 2D grip editing
2026-08-10 13:30:27 -03:00
Hakan Seven
3b6a4d1c4e build(deps): update cadkernel revision 2026-08-10 19:29:12 +03:00
gianlucafiore
86d7226df6 feat(grips): add dynamic input and precision snapping 2026-08-10 13:26:35 -03:00
Hakan Seven
873c36beb3 build(deps): update cadkernel revision 2026-08-10 16:32:26 +03:00
Hakan Seven
c943dfe391 fix(render): draw spatial curves and widths 2026-08-10 16:30:43 +03:00
Hakan Seven
ac8183ec91 refactor(cad): use direct stack dependencies 2026-08-10 15:03:31 +03:00
Hakan Seven
3b4fbabdba build: update acadifc revision 2026-08-10 14:13:43 +03:00
Hakan Seven
5a9de73096 build: update acadifc revision 2026-08-10 12:46:23 +03:00
Hakan Seven
96be8214f9 feat(tess): use angular sampling
Route curve, hatch, sweep, loft, surface, edge, and isoline tessellation through the shared kernel policy.
2026-08-10 12:12:16 +03:00
gianlucafiore
f607422c9d
Merge pull request #718 from gianlucafiore/feature/cad-color-picker
Add CAD indexed color picker with recent colors
2026-08-10 06:08:13 -03:00
Hakan Seven
dc998fe46b refactor(tess): move solid sampling to kernel
Remove local face, edge, spline, sweep, loft, and silhouette
samplers. Meshes and overlays share the kernel tolerance and edge
schedule.
2026-08-10 10:18:53 +03:00
gianlucafiore
4697e8cc33 feat(color): add CAD indexed color picker 2026-08-09 23:40:55 -03:00
Hakan Seven
60f5bca0d4 fix(tess): sample a solid's faces as finely as the edges drawn over them
The shaded surface of a curved solid was visibly coarser than its own
wireframe: the wire ran along the true rim while the facets cut inside it.

Two things were wrong, and only one was the tolerance.

`facet_res` is a resolution multiplier — the same one `scale_lod` divides the
fallback sampler's chord fraction by — and the kernel path was using it as a
sag in world units. At the default that asks for a whole unit of departure, so
nothing smaller than a metre subdivided at all and a face was only ever as
round as its own boundary. It is a fraction of each surface's own radius now,
which carries no assumption about the drawing's units.

And it is the *edges'* fraction, shared from `EDGE_CHORD_FRAC` rather than
copied. Those edges are drawn over these faces; sampling the two differently
is what put the wire across a facet instead of along its corners. `facet_res`
is deliberately not applied either, since the edges it must line up with are
built once at highest detail and never scaled.

A torus is measured by its tube rather than its ring — the tube is the tighter
bend, and sampling to the ring leaves the section a hexagon.

The primitive-volume test claimed a mesh can never read over its true size.
That holds for a convex solid, where every chord lies inside; a torus is not
one, and across the inside of its tube the chords fall outside the material.
It passed before only because the sampling was too coarse to show it.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-10 03:17:12 +03:00
Hakan Seven
afb4fd4733 fix(tess): sample a curve against its own size, not an absolute length
Round things came out with too few sides in drawings measured in metres, and
zooming in did not help.

The chord tolerance was floored at five thousandths of a world unit. That is
a fine sampling for a part measured in millimetres and a coarse one for a
building measured in metres: a ten-centimetre pipe got about ten sides and a
five-centimetre bolt about seven. The floor was also what stopped the frame
asking for better, so closing the camera on one changed nothing.

A chord height is an absolute length, so any fixed value carries an assumption
about the drawing's units. Bounded against the curve's own radius instead,
which carries none. The two ends are really segment counts: a circle gets at
least about fifty sides and never more than about a hundred and sixty,
wherever the camera is and whatever the drawing is measured in. Between them
the frame still decides, so a curve fills in as the camera closes on it.

Straight runs keep the frame's own tolerance — there is no curvature to
sample, and two ends are all a line has.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-10 02:44:52 +03:00
Hakan Seven
35a2714025 fix(camera): keep the eye's coordinates out of the view basis
A drawing placed at UTM shimmered as the camera moved.

The relative-to-eye path exists so the large eye translation never enters an
f32 matrix, and it zeroed the translation column to make sure. But the basis
was built first, by `look_at(eye, target)` with both positions cast to f32 —
and at (639792, 4517057) that grid is half a metre across in y. Rounding both
ends and then subtracting them left a direction that changed as the camera
moved, so the whole view basis jittered. Zeroing the translation afterwards
came too late to help: the damage was in the rotation.

It never needed the positions. The eye is `target + rotation·Z·distance`, so
the direction between them is the rotation's own Z — a unit vector carrying no
coordinate at all.

Two tests. Where the camera stands must not reach the matrix, which is the
property being restored; and at the origin, where the old construction had no
large coordinates to lose, the two must agree exactly — which is what says
this kept the same basis rather than turning the view round.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-10 02:36:28 +03:00
Hakan Seven
7c9366e362 fix(acis): read a lifted body at a tolerance a real file can meet
Faces were being dropped for sitting a nanometre off their own plane.

An edge is shared by two faces and in a real file cannot lie exactly on both:
the two surfaces were fitted separately and written to finite precision. Asked
for exactness, the kernel decides the edge is not on its plane, declines to
project it, and the face goes undrawn — silently, since a face that cannot be
expressed is reported as absent rather than as an error.

A micrometre in a drawing measured in metres recovers twenty-six walls of one
building. Loosening further buys almost nothing — a hundredth of this finds
one more face in sixty thousand — and past that it would start accepting
geometry that really is wrong, so it stops here.

With the tube fix that came with the kernel bump, VILLA_NEU_IFC3.dwg now
meshes 59015 of its 59033 faces, from 58922.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-10 02:23:58 +03:00
Hakan Seven
60ec29375f chore: take the kernel and codec that draw the missing faces
Two faults kept faces out of a lifted solid, and both looked like a document
problem rather than a reader one — the lift reported no loss at all.

An edge's stored parameter pair can span the right length from the wrong
place, putting a straight curve beside the face it bounds instead of along
it. And a loop's coedges are not always listed in the order the ring runs,
which the old chaining could not fix: it reversed the next piece in the list,
where what was needed was a different piece.

Either one leaves a ring that crosses itself, which ear clipping declines, so
the face is dropped without a word.

Handle 176 of Annotation-2D-Mesh-Solid-BIM.dwg now meshes all fourteen of its
faces, where it managed ten. Across that file: 105 of 107 solids complete, 865
of 867 faces. Across VILLA_NEU_IFC3.dwg: 672 of 763 solids, 58922 of 59033
faces.

The fallback sampler stays until that reaches all of them — a complete mesh is
what stops it running, and 111 faces still need it.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-10 02:12:06 +03:00
Hakan Seven
5a2aa13b74 fix(acis): fill a planar face's holes in the fallback sampler too
A face with a hole came out with the hole solid and the material around it
missing. Handle 176 of Annotation-2D-Mesh-Solid-BIM.dwg is one.

`tess_plane_face` read `face.first_loop()` and fan-triangulated it, on the
grounds that holes were the kernel path's job. Two things make that wrong.
Nothing says the outer loop is listed first, so when a hole came first the
hole got filled and the boundary was ignored. And the kernel path does not
always win: when its mesh is incomplete, `tessellate_acis` runs both and keeps
whichever produced more triangles — which is not a measure of being right.

Every loop is read now, flattened into the plane's own frame, and triangulated
with the widest ring bounding and the rest cutting into it — the same rule the
kernel uses, and by area rather than by listing order.

This is interim. The fallback should not exist at all: the kernel already
lifts these bodies with no loss and meshes ten of handle 176's fourteen faces.
The four it drops are planar rectangles whose boundary projects with one
edge's `v` mirrored, so the ring self-crosses and ear clipping declines it —
a `pcurve` fault, not a missing feature. Fixing that makes the mesh complete,
and a complete mesh means the fallback never runs and can go.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-10 01:56:57 +03:00
Hakan Seven
13d3c7d803 chore: take the kernel with the outer-ring fix
Faces with holes were drawing the hole filled and the material around it
missing. Handle 176 in Annotation-2D-Mesh-Solid-BIM.dwg is one.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-10 01:45:12 +03:00