632 Commits
Author SHA1 Message Date
jyvikoandClaude Opus 5.5 4a8d34d619 ui: XY plot in the results panel, drawn by the energy plot's code (#94)
XY Plot opens a section in the results panel: a quantity picker, the
series from results.xy plotted against the step's own axis with the
frame or mode shown marked (a click shows the nearest), nodal fields
read at the probed node, and Export CSV through results.xy. The energy
plot and the XY plot share one line-plot function.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01UhhZMBTviDQxZvwnyP89fo
2026-10-16 05:31:33 -04:00
jyvikoandClaude Opus 5.5 9a8469cf4b mesh: a projection query searches the face's own triangles (#402)
Projecting a point onto one B-rep face searched one box tree over every triangle of the
boundary, skipping the other faces' triangles: when other faces lie nearer the point than the
target face, it walked most of the tree before reaching a triangle it could use. Smoothing a
projected mesh projects every boundary node many times, onto every face of its target group,
so the Pi 5 enclosure base spent 95 % of its 11 minutes there. Each face (and each face pair's
curve) now has a tree of its own: the same nearest triangle, found among its own boxes only.

Ties between triangles at the same distance went to whichever the tree's walk met first; they
now go to the lowest triangle, so the result no longer depends on how a tree is built. With
that rule the per-face trees and the whole-boundary tree give bitwise the same mesh.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01UhhZMBTviDQxZvwnyP89fo
2026-10-16 04:54:14 -04:00
jyvikoandClaude Opus 5.5 cbd60a7985 results: results.xy, a quantity against the load factor, time or mode (#94)
A nodal field at a node per frame (nonlinear static displacements from
load factor 0, explicit frames, heat temperatures) or per mode, the
explicit energies and histories, history nodes, and the frequencies or
buckling load factors; capped at 100000 points with `every`; stale
results refused; `path` writes a two-column CSV. XY Plot is ready.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01UhhZMBTviDQxZvwnyP89fo
2026-10-16 04:33:06 -04:00
jyvikoandClaude Opus 5.5 47e92eebb1 mesh: a plan's frame cut on an opening's end face moves one element out of it (#455)
The crank arm's back pocket ends on the planes x = 48 and x = 130, its frame sides. The plan
put its frame cuts there; the kernel cannot cut along a face (#427), so both were skipped and
the cell between the bosses swept the pocket's rounded ends into fans. A frame side on a face
of the body now moves one element out of the opening (away from the rectangle's middle),
leaving a strip one element wide; both cuts are made.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01UhhZMBTviDQxZvwnyP89fo
2026-10-16 03:59:29 -04:00
jyvikoandClaude Opus 5.5 bf61ae8406 mesh: smoothing visits nodes in their own order again (#402)
#462 visited nodes by a mirror-invariant key (distance from the centroid). On the cup with a
handle that order sweeps ring by ring round the axis and converges worse in its 100 sweeps: the
refined cup fell to a scaled Jacobian of 0.481 (needs 0.5, #440). In the lattice's own order
it holds, and the order gained the enclosure base little (its corners differ by 0.02 either
way), so it goes; the compass search's lift to 0.7 stays.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01UhhZMBTviDQxZvwnyP89fo
2026-10-16 03:42:47 -04:00
jyvikoandClaude Opus 5.5 4d6d69ee6d mesh: smoothing lifts elements up to 0.7 and visits mirror twins alike (#402)
The compass search after the sweeps only lifted elements below 0.5 (the quality floor), so a
mesh whose worst elements sat just above it stayed there: every corner of an enclosure base
stopped at a scaled Jacobian of 0.50-0.52 where its walls meet the corner bosses. It now lifts
every element below 0.7, never lowering another below the lower of its own value and 0.5.

The sweeps and the search are Gauss-Seidel, so the node order shaped the result and mirror
image corners smoothed differently. Nodes are now visited by a key that a mirror or a quarter
turn about the nodes' centroid keeps (distance from it, then the sorted offsets along the
axes). What spread is left between mirrored corners (0.686 vs 0.702 on the test base) is most likely the projection onto the body's
tessellation, which the kernel does not make mirror symmetric (not yet proven).

Co-Authored-By: Claude Opus 5.5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01UhhZMBTviDQxZvwnyP89fo
2026-10-16 03:05:43 -04:00
jyvikoandClaude Opus 5.5 e79ba866a1 engine: draw geometry.check findings as viewport markers
geometry.check keeps its findings on the session (not an edit: not journalled,
saved or undone) while the checked design stays open; the picture and the app's
viewport draw the faces of small, sliver and near faces in the marker colour,
short edges as thick lines and a dot at each finding over everything. `mark:
false` or a clean check clears them.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01UhhZMBTviDQxZvwnyP89fo
2026-10-16 02:47:14 -04:00
jyvikoandClaude Opus 5.5 f8b92fcd89 ui: element faces and edges as element:side lists
A Sides field kind: element faces or edges typed as element:side with
ranges (1-20:3, 25:1), no row cap, and Use selection for picked faces.
Set and mesh-tag forms use it instead of a JSON box (#449).

Co-Authored-By: Claude Opus 5.5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01UhhZMBTviDQxZvwnyP89fo
2026-10-16 02:30:24 -04:00
jyvikoandClaude Opus 5.5 9b705f5334 ui: fluid boundary face and obstacle faces as typed fields
The boundary's 'at' is a box face or an obstacle body and face
(NameOr); the domain's obstacle faces are rows of a face and its wall
condition (#449).

Co-Authored-By: Claude Opus 5.5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01UhhZMBTviDQxZvwnyP89fo
2026-10-16 02:14:58 -04:00
jyvikoandClaude Opus 5.5 98e96921e6 ui: mirror plane and images as typed fields
Two field kinds: NameOr (a name as a bare string, or an object of fields)
and RefText (a text per item of a collection). The mirror's plane is a
datum plane or a point and normal; its images a body name per body
(#449).

Co-Authored-By: Claude Opus 5.5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01UhhZMBTviDQxZvwnyP89fo
2026-10-16 01:51:04 -04:00
jyvikoandClaude Opus 5.5 d17cf414f7 ui: block divisions and bias as two or three typed fields
A Tuple field kind: min_len to labels.len() positive numbers, whole when
asked, trailing blanks left out. The block's divisions and bias use it
instead of a JSON box (#449).

Co-Authored-By: Claude Opus 5.5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01UhhZMBTviDQxZvwnyP89fo
2026-10-16 01:42:51 -04:00
jyvikoandClaude Opus 5.5 e4d1f6c7da ui: one number or one per axis for conductivity, expansion and point mass
A PerAxis field kind: one value for every direction, or Per axis ticked
for one per axis. Thermal conductivity and expansion and the point mass
use it instead of a JSON box (#449).

Co-Authored-By: Claude Opus 5.5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01UhhZMBTviDQxZvwnyP89fo
2026-10-16 01:38:26 -04:00
jyvikoandClaude Opus 5.5 b18195ff89 ui: table rows on one line under column headers
Co-Authored-By: Claude Opus 5.5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01UhhZMBTviDQxZvwnyP89fo
2026-10-16 01:34:38 -04:00
jyvikoandClaude Opus 5.5 61f0d42ec4 ui: nonlinear load path as a table of fraction and factor
Kind::Points gains its columns, so a list of number rows other than
[x, y, z] gets the same typed editor; the load path uses it (#449).

Co-Authored-By: Claude Opus 5.5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01UhhZMBTviDQxZvwnyP89fo
2026-10-16 01:34:38 -04:00
jyvikoandClaude Opus 5.5 1c18a463e7 app: the windows-sys features WriteFile and MiniDumpWriteDump need (#299)
Co-Authored-By: Claude Opus 5.5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01UhhZMBTviDQxZvwnyP89fo
2026-10-16 01:11:58 -04:00
jyvikoandClaude Opus 5.5 af9b4bb222 app: startup steps in the crash journal, and a Windows exception filter (#299)
egui-wgpu's startup hook and the app's own steps (window, app setup, viewport
pipelines, first frame, running) go into the journal. On Windows,
native_crash.rs (adapted from SolidCraft, the only module allowed unsafe code;
the app crate now denies instead of forbids it) writes the exception code,
faulting module and offset and a minidump. A nightly/on-demand CI job runs the
app's tests on Windows, including a child that faults on purpose.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01UhhZMBTviDQxZvwnyP89fo
2026-10-16 01:11:58 -04:00
jyvikoandClaude Opus 5.5 ed25de6521 engine: crash reports name the startup step, the renderer and a native crash (#299)
The journal keeps the startup step the app is in (phase) and the renderer
(set_environment) across rebases; an unclean exit before the first frame is
reported "during startup (<step>, N s after launch)". native_paths() is where
a native exception filter writes what it caught and a minidump; the next
start puts the exception code, module+offset and thread into the report and
moves the minidump into its folder. Adapted from SolidCraft's crash.rs.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01UhhZMBTviDQxZvwnyP89fo
2026-10-16 01:11:58 -04:00
jyvikoandClaude Opus 5.5 ead489592c ui: arc-length displacement limit as typed fields
The step form's displacement limit was a raw JSON box; it is now a group
of node, direction and displacement fields (#449).

Co-Authored-By: Claude Opus 5.5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01UhhZMBTviDQxZvwnyP89fo
2026-10-16 00:50:12 -04:00
jyvikoandClaude Opus 5.5 7a5363e07b app: leave SIGHUP alone so nohup keeps the app running (#248 follow-up)
#445 also closed the window on SIGHUP, which overrides the SIG_IGN that
`nohup fieldcraft &` sets so the app outlives its terminal. A safe API cannot
ask whether a signal was ignored at launch, so SIGHUP keeps its default.
SIGTERM and SIGINT still close the window the normal way.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01UhhZMBTviDQxZvwnyP89fo
2026-10-16 00:47:35 -04:00
jyvikoandClaude Opus 5.5 9a30c7d9ed mesh: the one-to-one sweep names a body that ends at several levels (#444)
The crank ends at 8, 16, 20 and 22 mm, so no one-to-one sweep takes it.
The sweep met one of those caps as a linking face and reported "linking
face has no top side". A plane parallel to the source that only part of a
ring reaches is now named as what it is, with extrude pointed to. The arm's
profile alone sweeps as well as extrude does.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01UhhZMBTviDQxZvwnyP89fo
2026-10-16 00:33:55 -04:00
jyvikoandClaude Opus 5.5 0b7dda95f7 mesh: an enclosure's corner bosses are ringed where its walls join them (#402)
A boss the body's walls run into had its circle crossed by the walls' planes, so the projection
layout refused it and the plan fell back to swept cells, fanning round the boss and its hole.
Such a boss is now framed by the square round its whole circle, subdivided by the planes that
cross it; every square inside (the hole's, the core) is divided alike, so the ring's blocks meet
the walls node to node. On the walls' side the frame stops at their inner plane and its corner
projects onto the middle of the inner fillet, which the ring takes in (a boss just touching the
fillet included: no sliver). Cylinders a fillet's history names but that are a ring's circle are
the ring's faces. Rings are built per patch of grid cells, the one-cell O-grid being the
simplest patch.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01UhhZMBTviDQxZvwnyP89fo
2026-10-16 00:29:24 -04:00
jyvikoandClaude Opus 5.5 02b408c499 app: a termination signal closes the window the normal way, not as a crash (#248)
SIGTERM, SIGINT and SIGHUP ended the process on the spot: no last autosave,
and the crash journal left behind became an unclean_exit report at the next
start. The report on #248's machine ("ended without a clean exit between
commands (last: control ui.capture)") has that exact signature and is
reproduced by kill -TERM after a capture; 500 captures of the solved
crank-mirror (50 app runs), 30 CLI snapshots and 250 MCP headless
screenshots exited cleanly. The first signal now asks the window to close;
a second ends the process with the signal's default action.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01UhhZMBTviDQxZvwnyP89fo
2026-10-16 00:24:26 -04:00
jyvikoandClaude Opus 5.5 3d38753cad geometry: a partition the kernel can only nudge off its plane is refused (#427)
The kernel's last-resort boolean retry moves the tool 1.3 µm and turns it
2 µrad. For a partition that puts the cut beside the face it was meant to
run along and leaves a cell bounded by slivers (the open boundary at x = 130
on the crank half). halves() now refuses a result-altering retry and names it.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01UhhZMBTviDQxZvwnyP89fo
2026-10-16 00:20:02 -04:00
jyvikoandClaude Opus 5.5 1af87f1f98 mesh: a disk's O-grid follows the region's elongation (#198)
A smooth loop (straight sides running tangent into arcs, as a slot or a
rounded pocket) is meshed as a disk. Its middle block was a square halfway
to the loop's quarter points, which on the crank's 6:1 pocket floor
squashed elements to a scaled Jacobian of 0.16. The block is now a
rectangle on the region's principal axes, inset by the same distance all
round (the old square on a circle), its corners paired with the loop nodes
nearest their diagonals, its sides spaced as the nodes they pair with, and
the O-grid is smoothed (untangled first) before the validity check.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01UhhZMBTviDQxZvwnyP89fo
2026-10-15 23:55:02 -04:00
jyvikoandClaude Opus 5.5 e9801e4528 ui: draw the marked elements in the error colour
Co-Authored-By: Claude Opus 5.5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01UhhZMBTviDQxZvwnyP89fo
2026-10-15 23:32:47 -04:00
jyvikoandClaude Opus 5.5 75b8c7e26e engine: mesh.quality.mark marks the elements below quality limits as a set
Co-Authored-By: Claude Opus 5.5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01UhhZMBTviDQxZvwnyP89fo
2026-10-15 23:32:47 -04:00
jyvikoandClaude Opus 5.5 33d69fc53d mesh: list the elements that fail quality limits, worst first
Co-Authored-By: Claude Opus 5.5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01UhhZMBTviDQxZvwnyP89fo
2026-10-15 23:32:47 -04:00
jyvikoandClaude Opus 5.5 44de124d9d engine: geometry.check reports what is small against the element size
Co-Authored-By: Claude Opus 5.5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01UhhZMBTviDQxZvwnyP89fo
2026-10-15 23:17:39 -04:00
jyvikoandClaude Opus 5.5 5cee94f947 geometry: check bodies for short edges, small and sliver faces, near faces
Co-Authored-By: Claude Opus 5.5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01UhhZMBTviDQxZvwnyP89fo
2026-10-15 23:17:39 -04:00
jyvikoandClaude Opus 5.5 06c4a8d73d mesh: projection divisions from the mean edge length of each class, thin-layer tests (#418)
Co-Authored-By: Claude Opus 5.5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01UhhZMBTviDQxZvwnyP89fo
2026-10-15 23:09:50 -04:00
jyvikoandClaude Opus 5.5 f9a0282acc engine: results.export.vtu writes a solved step for ParaView
Static, frequency (per mode), nonlinear and explicit (per frame, with a
.pvd collection) and heat results; fluid steps are refused. Wedges keep
the model's node order: VTK 9's wedge has the same orientation.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01UhhZMBTviDQxZvwnyP89fo
2026-10-15 22:55:12 -04:00
jyvikoandClaude Opus 5.5 439dfc678f io: write VTK XML unstructured grids and PVD collections
Co-Authored-By: Claude Opus 5.5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01UhhZMBTviDQxZvwnyP89fo
2026-10-15 22:55:12 -04:00
jyvikoandClaude Opus 5.5 68016f69f7 engine: the crank half y > 0 divides where its mirror does (#283)
The kernel failure is reported as such since #381; the failure itself came
from split_by_plane's oversized boxes, which #384 replaced with body-sized
ones. The regression test now requires the cut (x = 110, 148, reversed
normal, the diagonal plane) from commands, with the cells' volumes adding up.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01UhhZMBTviDQxZvwnyP89fo
2026-10-15 22:45:27 -04:00
jyvikoandClaude Opus 5.5 92d49debec mesh: a screw hole's ring takes in the fillet of its rounded corner; frames centred on the hole (#402)
The projection layout gave every fillet a blend layer along the sides it runs between, so a
screw hole close to a rounded corner sat inside the layer and the plan fell back to frame cuts
and swept cells, which fan into the hole. A corner fillet that lies inside the square from the
hole to the two sides is now taken in by the hole's O-grid ring: the frame reaches both sides,
its outer corner projects onto the middle of the fillet, and no layer is needed. An O-grid's
frame is centred on its hole (a near side is the frame, the far side as far), and the plan
reports the layout's frames and drops the frame-cut notes when it does not cut.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01UhhZMBTviDQxZvwnyP89fo
2026-10-15 22:43:02 -04:00
jyvikoandClaude Opus 5.5 1d71a9f8af engine: mesh.export.stl writes the outer surface or a set's faces
Binary by default, ASCII on request; in the Mesh tab's Verify panel.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01UhhZMBTviDQxZvwnyP89fo
2026-10-15 22:34:02 -04:00
jyvikoandClaude Opus 5.5 87710a83ab io: write element faces as binary and ASCII STL
Model::skin_faces gives the mesh's outer skin: the exterior faces of
the solids and the top side of every shell.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01UhhZMBTviDQxZvwnyP89fo
2026-10-15 22:34:02 -04:00
jyvikoandClaude Opus 5.5 eecdcb5b96 mesh: projection divisions follow the curvature of curved targets, max_arc_angle (#418, #402)
Co-Authored-By: Claude Opus 5.5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01UhhZMBTviDQxZvwnyP89fo
2026-10-15 21:53:38 -04:00
jyvikoandClaude Opus 5.5 464417d84d mesh: test that a plane is trimmed to its face (#418)
Co-Authored-By: Claude Opus 5.5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01UhhZMBTviDQxZvwnyP89fo
2026-10-15 21:53:38 -04:00
jyvikoandClaude Opus 5.5 c107ea8105 mesh: a point of a plane past its face's triangles is off the face (#418)
project_trimmed accepted the analytic projection within a fifth of the nearest
triangle's size; a plane face's triangles can span the whole face, so nodes in a
3 mm fillet landed on the untrimmed box planes (mesh volume = the unfilleted box).

Co-Authored-By: Claude Opus 5.5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01UhhZMBTviDQxZvwnyP89fo
2026-10-15 21:53:38 -04:00
jyvikoandClaude Opus 5.5 390ddcd6cc cli, mcp: snapshot --section and --field; headless MCP screenshots on the GPU
--section x|y|z[=VALUE] hides the elements on the camera's side of a plane
(at the mesh's middle by default) so the element faces inside show;
--field contours a nodal field of the solved step (results.contour). The
MCP server's headless screenshot draws with the viewport's pipeline on the
shared device and its reply, like snapshot's, names the renderer.

Refs #422

Co-Authored-By: Claude Opus 5.5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01UhhZMBTviDQxZvwnyP89fo
2026-10-15 20:50:40 -04:00
jyvikoandClaude Opus 5.5 c9163e98ad gpu: captures draw name labels; a shared capturer and a PNG with the CPU as last tier
render::draw_labels draws a scene's labels over finished pixels in the CPU
rasterizer's font. capture::shared opens the process's device once by the
FIELDCRAFT_GPU policy; capture::png draws on it or on the CPU and reports
which (Renderer).

Refs #422

Co-Authored-By: Claude Opus 5.5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01UhhZMBTviDQxZvwnyP89fo
2026-10-15 20:50:40 -04:00
jyvikoandClaude Opus 5.5 fee978c7e4 cli: snapshot draws a script's model to a PNG with no window
fieldcraft-cli snapshot script.json --out shot.png [--view] [--size WxH]
draws the engine's framed scene (engine::view::frame, shared with the CPU
render_png) with the viewport's GPU pipelines offscreen: hardware GPU, then
a software one, then the CPU rasterizer (FIELDCRAFT_GPU=auto|hardware|
software|cpu). CI installs lavapipe so the GPU path runs there.

Refs #422

Co-Authored-By: Claude Opus 5.5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01UhhZMBTviDQxZvwnyP89fo
2026-10-15 20:19:00 -04:00
jyvikoandClaude Opus 5.5 248e74ca9e gpu: the viewport's pipelines move to a crate of their own (fieldcraft-gpu)
ui-egui keeps only the egui_wgpu paint callback; the shaders, batching and
pipelines are fieldcraft-gpu's view module, so an offscreen picture can draw
with the window's pipelines.

Refs #422

Co-Authored-By: Claude Opus 5.5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01UhhZMBTviDQxZvwnyP89fo
2026-10-15 20:19:00 -04:00
jyvikoandClaude Opus 5.5 575ae10dbf mesh: tests pin projection smoothing's edge ratio and regular grids (#418)
Co-Authored-By: Claude Opus 5.5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01UhhZMBTviDQxZvwnyP89fo
2026-10-15 19:39:01 -04:00
jyvikoandClaude Opus 5.5 58d3b351ff mesh: projection smoothing keeps a result that holds the grid's quality (#418)
Co-Authored-By: Claude Opus 5.5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01UhhZMBTviDQxZvwnyP89fo
2026-10-15 19:39:01 -04:00
jyvikoandClaude Opus 5.5 5306450413 mesh: projection smoothing guards edge ratio and never leaves the grid worse (#418)
Co-Authored-By: Claude Opus 5.5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01UhhZMBTviDQxZvwnyP89fo
2026-10-15 19:39:01 -04:00
jyvikoandClaude Opus 5.5 d29334a7a7 mesh: mesh.plan.apply builds rings and fillet/chamfer blend layers as one projected block layout (#402)
Co-Authored-By: Claude Opus 5.5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01UhhZMBTviDQxZvwnyP89fo
2026-10-15 18:59:02 -04:00
jyvikoandClaude Opus 5.5 361ac2e7b3 ui: an icon for Extrude to Surface (mesh.hex.extrude)
develop CI failed every_catalogue_entry_has_an_icon_and_every_icon_an_entry since #414.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01UhhZMBTviDQxZvwnyP89fo
2026-10-15 17:39:22 -04:00
jyvikoandClaude Opus 5.5 febd40fadc mesh: split a projection block through its whole sheet; name twisted elements' block junction (#399)
Topology::split cuts a block at given fractions and every block chained to it
through parallel edges, orienting the fractions through the chain, so the
topology stays conforming. A certified-invalid element is reported with its
block, cell, centre and the block vertex and blocks meeting there; the mesh is
never emitted.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01UhhZMBTviDQxZvwnyP89fo
2026-10-15 16:57:05 -04:00
jyvikoandClaude Opus 5.5 4dadaa50aa ci: docs/releasing.md: release jobs run in parallel; only the draft waits for verify
Co-Authored-By: Claude Opus 5.5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01UhhZMBTviDQxZvwnyP89fo
2026-10-15 16:52:48 -04:00