Files
solidcraft-upstream/assets
83c31d77c4 surface.boundary: surfaces through boundary curves and curve networks (#763) (#2129)
* feat(geom): surfaces through curve networks, and spline spaces to build them

Adds spline_space (clamped B-spline spaces, Hermite interpolation, exact
embedding by Bézier degree elevation and knot insertion, a monotone cubic
for reparameterising) and network (loft, Coons and Gordon surfaces through
curves in one or two directions, with G1/G2 cross-boundary conditions
against a neighbouring face). Part of #763.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* feat(kernel): boundary surfaces from sketch curves, 3D curves and edges

kernel::boundary_network turns sketch chains, 3D sketch polylines and edge chains
into network curves, gives G1 frames of the faces along open edges
(EdgeFaces), builds the B-spline face (sides split at chain vertices so a
join shares the body's edges) and joins it into a surface body by stitching.
G2 is refused for now (not supported yet). Part of #763.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* fix(kernel): second derivatives of B-spline surfaces in the vendored truck-geometry

BSplineSurface::uuder and vvder multiplied the second differences by p
instead of p·(p − 1), as BSplineCurve::der2 does, so every surface of
degree p ≥ 3 (NURBS too, through its homogeneous surface) reported
1/(p − 1) of its second derivative: a cubic surface's curvature read as
half. This is why a G2 boundary surface on a cylinder measured half the
curvature it carries (#763). New tests hold both to finite differences
for degrees 2 to 5.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LGeCa5jWWdroMWvXxN3LLM

* feat(kernel): G2 boundary surfaces against a body's face

The network always carried the face's curvature across a G2 edge; the
refusal came from measuring it with truck's halved surface second
derivatives (fixed in the previous commit). EdgeFaces now reads the
face's second fundamental form from the exact second derivatives
instead of differencing the normal. A new test holds the curvature
across a cylinder's edge to the cylinder's within 0.1%, also with a
sheared far curve; G3 is refused (a network holds up to G2).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LGeCa5jWWdroMWvXxN3LLM

* test(kernel): a boundary patch with straight corners measures its own area

A stadium's arcs meet its lines at 180°, so the Coons patch is singular
at its corners. From such a corner the reference mesher's boundary walk
ran onto the B-spline's extrapolation past its domain (a planar spline
passes through every point of its plane there), and the face measured
289 mm² for its 158.5 (#763). The vendored mesher's bounded projection
(nearest_projection, #2043) keeps the walk on the domain; this holds it
there, by the faces, the measuring mesh and the display mesh. The
display path (#1653) was never affected.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LGeCa5jWWdroMWvXxN3LLM

* feat(geom,kernel): three-sided boundary surfaces (one side collapsed to a point)

A network curve may be a PointCurve: the apex where the two sides beside
it meet. The curves through it cross it at the point itself, its row of
the net collapses there, and the kernel's face leaves that side out of
its loop (three edges, one vertex at the apex). One point per patch, as
a side; refused elsewhere, when it moves, or with a continuity
condition. Tests: a triangle and a quarter disc filled flat with their
analytic areas (40 mm², 25π), by geom and by the kernel's faces and
meshes.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LGeCa5jWWdroMWvXxN3LLM

* feat(doc): boundary surfaces through curve networks and loops of three or four

FeatureKind::SurfaceNetwork saves a network as `u` and `v` curves, each
a sketch chain (planar or 3D), a chain of a body's edges with an
optional G1/G2 continuity, or a point (the apex of a three-sided
patch), and an `operation` that can join the surface into the body of
its edges. A SurfaceBoundary of three or four sketch curves, refused
until now, builds as the flat Coons patch of its loop (three collapse
the side opposite the first curve). The format change is one pending
file; feature-walk goldens record the new variant's sketches, bodies
and points.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LGeCa5jWWdroMWvXxN3LLM

* feat(engine): surface.boundary through loops of three or four and curve networks

The command keeps its loop form (two to four curves of one sketch; three
and four now build the flat patch of the loop, crown refused there) and
gains a network form: `u` and `v`, each curve a sketch curve id, a
{sketch?, curves} chain (planar or 3D), a {body, edges, continuity?}
edge chain (g1/g2 with the face beside it) or a {point} for a
three-sided patch, with `operation` new or join. Edits may move between
the two forms (timeline.redefine accepts the command now that it has a
dialog).

Tests: analytic areas of loop patches and of a hyperbolic paraboloid
bounded by four 3D lines (every mesh vertex on z = xy/10), a loft
across two sketches, G1 and G2 measured across a cylinder's edge with
inspect.continuity (angle < 0.1°; curvature jump 1e-16 with G2 against
0.027 with G1), 26 hostile networks refused without panicking, and u/v
added to hostile_params_never_panic.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LGeCa5jWWdroMWvXxN3LLM

* feat(ui): Boundary Surface dialog

Curves and Cross curves take sketch curves and edges (picks that meet
end to end in one sketch or body are one chain); Continuity and
Operation (New Body or Join). Two to four sketch curves of one sketch
with nothing across are the loop patch; anything else is a network.
Edit Feature brings either back (per-side orders, crown and stations
the dialog does not show are kept). Strings in en, ja and zh.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LGeCa5jWWdroMWvXxN3LLM

* docs: ROADMAP M8 and the bridge patch's notes for boundary networks (#763)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LGeCa5jWWdroMWvXxN3LLM

* test(oracle): a boundary surface through a loop, thickened (#763)

Case 83: four sketch curves (a square's three sides and a half circle
for its top) make one boundary surface, thickened 2 mm; analytic values
from tools/oracle-analytic/cases_surfaces.py (V = 2A, area 2A + 2P,
centroid by moments). Recipes gain boundary_surface, thicken and remove.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LGeCa5jWWdroMWvXxN3LLM

* refactor: boundary surfaces, review cleanups

Project onto the face once per derivative evaluation (the frame is
passed to natural() and reused by scale()), keep each track's
finite-difference step instead of rescanning its table, export the
kernel's edge-pick and chain caps and the default station count for
the engine, doc and dialog to share, map TooLarge spline errors to
KernelError::TooLarge, reuse the engine's operation parser, and skip
the dialog's sketch lookup when the picks are no loop.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LGeCa5jWWdroMWvXxN3LLM

---------

Co-authored-by: jyviko <2501648+jyviko@users.noreply.github.com>
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Co-authored-by: bherbruck <brennen.herbruck@gmail.com>
2026-10-17 21:47:38 -04:00
..

Application resources

assets/ is the design resource home for SolidCraft. ATTRIBUTION.md is the file inventory and provenance record. Keep one editable master per resource and place shipped derivatives in exports/.

assets/
  icons/
    app/
      shared/source/                 # original Rust mark and executable ICO encoder
      macos/source/SolidCraft.icon/   # approved Composer project and linked SVGs
      macos/exports/                 # paired Assets.car and icon.icns
      windows/exports/               # executable DIB ICO and installer PNG ICO
      linux/exports/hicolor/         # Linux/FreeBSD package images, 16–512 px
    ui/design/svg/                   # authoritative original UI icon masters
    ui/design/tools/                 # authoring bases, checks and included review app
    ui/source/                       # Rust viewport glyphs, markers and navigation
  branding/web/source/og.png          # shared social preview card
  styles/ui/palettes.rs               # light/dark defaults
  styles/web/loading.css             # web loading/canvas styles
  appearances/library.rs             # built-in visual presets
  materials/library.rs               # physical defaults and colours
  shaders/viewport.wgsl               # original viewport shader
  fonts/{liberation-sans,biz-udp-gothic}/ # unmodified fonts and OFL licences
  locales/{en,de,ja,ko}.json          # shared offline catalogs
  platforms/{macos,linux,windows}/    # bundle, freedesktop and WiX templates
  archive/icons/macos-v1/
    source/icon.vectorcraft          # earlier editable work, retained
                                     # redundant historical exports are retired

Editing and regeneration

UI artwork identifies the drawing masters and their consumers. Read the mandatory UI style guide before editing an icon. Edit SVG geometry and its command/UI assignments together; inspect both themes and small sizes. Temporary media and generated reports belong in ignored target/. Palettes and model presets are also editable Rust data.

The current macOS master is icons/app/macos/source/SolidCraft.icon/, including its linked SVG layers and appearance settings. The earlier VectorCraft document is preserved in the archive. No other native design projects were available for the current UI set or preview card. Keep any future .vectorcraft, .ai or other native work and linked inputs under that resource's source/work/, with an attribution row; retain the editable document alongside its exports.

Regenerate all exports of the shared Windows/Linux/FreeBSD mark together:

cargo xtask app-icons

For macOS, use Xcode with Icon Composer support:

mkdir -p target/resources/macos-icon
xcrun actool assets/icons/app/macos/source/SolidCraft.icon \
  --compile target/resources/macos-icon --platform macosx \
  --minimum-deployment-target 11.0 --app-icon SolidCraft \
  --output-partial-info-plist target/resources/macos-icon/icon-info.plist \
  --output-format human-readable-text
cp target/resources/macos-icon/Assets.car assets/icons/app/macos/exports/Assets.car
cp target/resources/macos-icon/SolidCraft.icns assets/icons/app/macos/exports/icon.icns

Review and commit source changes and required exports together. Temporary renders, tool caches and package staging belong under ignored target/ or dist/. Normal builds use the committed exports and require no design applications. The CLI still supports arbitrary PNG/ICO exports with solidcraft-cli icon.

Platform bindings

Platform Resources and output paths
macOS Composer master and paired exports; bundle installs Assets.car and SolidCraft.icns
Windows executable solidcraft-executable.ico: original DIB/mask representations at 16/24/32/48/64/128/256 px
Windows installer solidcraft.ico: PNG representations at 16/20/24/32/40/48/64/128/256 px; SOLIDCRAFT_ICONS override retained
Linux, Nix, deb/rpm, tar, Flatpak, Snap Copy canonical hicolor images; icon name stays ai.storyteller.solidcraft
AppImage Uses the Linux 256 px image and .DirIcon alias
FreeBSD Shares Linux hicolor images and freedesktop metadata
Web HTML/Trunk and manifest.webmanifest stay in apps/solidcraft-web/; copies Japanese font/licence to fonts/, uses the collected CSS, and copies the Linux 32/256/512 px images to icons/ for the favicon and installed app
Docs and link previews xtask book copies the shared card to the existing /solidcraft/og.png public path

Code and provenance

Resources remain compiled by their owning layer through existing APIs: ui-egui::icons::paint and Tokens at L5, model presets in L2 doc, and sketch fonts at L1. State, projection, interaction, commands and GPU bindings stay in their current modules. Embedded data uses CARGO_MANIFEST_DIR; application code needs no runtime resource registry or repository lookup.

cargo xtask assets requires an exact attribution row for every collected file except Markdown documentation, and continues checking file assets elsewhere in the repository. This includes native work, Rust masters, catalogs, shaders and platform templates. Packaging selects explicit current files and fails when required inputs are absent. Archived artwork has no production consumers.

Dependency-owned egui fonts and vendored renderer shaders stay with their libraries; their licences remain in THIRD-PARTY-LICENSES.txt and ATTRIBUTION.md. System fonts, optional packs, user fonts/canvases/decals/materials and native OS controls retain external ownership. Root licence/notice texts stay canonical.