Commit Graph

22 Commits

Author SHA1 Message Date
bflatastic 6c4b549669 Say why when the app cannot start or has to close
A Windows release build has no console, so when the GPU could not be
set up or the app panicked, the window never showed or vanished without
a word. Such errors now also go to errors.log beside the settings and,
on the main thread, to a message box that names the log file.

Fixes #106.
2026-11-02 13:52:12 +07:00
bflatastic 1fc73bc87d Merge remote-tracking branch 'origin/main' into HEAD
# Conflicts:
#	apps/texturecraft-cli/tests/cli.rs
2026-11-02 12:33:55 +07:00
BFlat fc26ad4477 Merge pull request #58 from kk376/fix/49-multigpu-adapter-selection
feat(app): support multi-GPU selection and discrete adapter preference (#49)
2026-11-02 12:33:34 +07:00
bflatastic 5f890e584e Web: ask to save before replacing the project or closing the tab
The browser build threw unsaved changes away on New project, Open,
Close, Open sample project or a dropped file, and when the tab closed.
They now wait on the desktop's Save / Don't save / Cancel dialog (Save
downloads the project), and closing or reloading the tab with unsaved
changes makes the browser ask first.
2026-11-02 09:32:25 +07:00
BFlat f6b66a2580 Merge pull request #87 from storytold/cli/sample-bake-size-note
CLI: say that new --sample bakes its mesh maps at up to 1024 px
2026-11-02 06:31:08 +07:00
bflatastic f47638d782 CLI: say that new --sample bakes its mesh maps at up to 1024 px
The baked maps are most of a sample project's size, so a 2048 sample is
as large as a 1024 one; the usage and the control protocol now say so.

Fixes #66.
2026-11-02 05:42:55 +07:00
bflatastic c4353cc8d0 CLI: --automation-read-root / --automation-write-root for mcp and serve
The spelling the other crafting apps use; the same as --read-root /
--write-root.

Fixes #57.
2026-11-02 05:41:00 +07:00
test-bit-sys f0242058f2 cli: support builtin:<id> in info command (#63) 2026-11-01 23:06:43 +01:00
bflatastic 96b179ccfc Start window: new, open or a recent project at launch
The app opens on the sample project, which left no obvious place to pick a
project. A start window now offers New project, Open, the recent projects and
Continue with the sample project, with Show at startup (also Settings >
Interface > Start window). It opens at launch in the desktop and web apps, but
not when a file is given on the command line or the app runs with --control.

Labels translated into the other nine UI languages; a UI test covers New
project, Continue and the startup setting.
2026-11-02 04:15:55 +07:00
Kushagra Kumar fbacf65c68 fix(app): refine adapter selection error handling and priority ordering (#49) 2026-11-02 02:09:01 +05:30
Kushagra Kumar c89a9870e1 feat(app): support multi-GPU selection and discrete adapter preference (#49) 2026-11-02 01:59:03 +05:30
Agapenordev 836e3f251b Control server: close on malformed JSON before auth
A malformed first line got a "bad JSON" reply but kept the connection open until
the auth deadline, unlike `texturecraft-cli serve` and the documented
one-attempt rule. It now closes the connection while unauthenticated; after
auth a malformed line still only gets the error reply. Adds a regression test
and doc comments on the touched functions.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-01 20:42:06 +01:00
Agapenordev 5a065c1e15 Control channel: harden the token file and the app's control server
The desktop app wrote its control token to <temp>/texturecraft-control-<port>.token with
default permissions (world-readable in a shared /tmp), from a hash-based generator, and
compared it non-constant-time with no connection limit. Any local user could read the token
and drive the app, whose command.run takes host paths.

- Token files are created new (remove, then O_EXCL) with mode 0600, so a planted file or
  symlink can neither keep its permissions nor redirect the write; one that cannot be
  replaced disables the server with a hint to set TEXTURECRAFT_CONTROL_TOKEN.
- Clients only read a token file that is a regular file owned by them with no group or
  other permissions, opened without following symlinks or blocking on a FIFO.
- The app's control server uses the shared security module: OS-random 256-bit token,
  constant-time compare, validated and trimmed env token, bounded lines and at most 16
  connections.
- Connections must authenticate within 10 s (AuthDeadline) and get one attempt.
- The app and `serve --port` bind before writing the token file, so a server whose port is
  busy no longer replaces the running server's token.

Regression tests cover owner-only files over an existing open file, symlink and FIFO
handling, the auth deadline, the connection limit and the app's token checks.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-01 20:16:37 +01:00
bflatastic 4a259e7270 New README showcase renders: a storm lantern and a rangefinder camera
Replace the crate and material-ball renders in Made in TextureCraft with two
original props, modelled procedurally and textured with TextureCraft's own
materials, masks and mesh-map generators, path traced at 2048 samples.

texturecraft-cli render gains --camera <name> to look through a camera saved
in the project (camera.add), so a render can use an art-directed framing
(distance, target, field of view) rather than only yaw and pitch.
2026-11-02 01:08:59 +07:00
bflatastic bdac5a22d2 Custom title bar: app icon, menus and window buttons in one strip
The top menu strip is now the window's title bar wherever the app draws the
frame (crates/ui-egui/src/titlebar.rs), using craft-window for the decision
and for the draggable empty area:

- Windows: no OS frame. App icon at the very left, the menus, empty space
  that moves the window (double-click maximizes), the mode label, then
  minimize, maximize/restore and close (46 pt wide, crisp pixel-snapped
  glyphs, close turns red on hover, dimmed while inactive). Invisible edge
  and corner zones resize the window. A per-frame guard ported from
  VectorCraft keeps the undecorated window borderless and a maximized one
  clear of the taskbar (winsafe, no unsafe), and the taskbar gets the big
  app icon.
- macOS: the traffic lights over the strip (full-size content view, hidden
  title), centred on it with eframe's traffic-light API, the app icon after
  their inset, and AppKit's movable flag synced by craft-window.
- Linux and the BSDs: craft-window's probe decides; where the compositor
  leaves the frame to the app (GNOME) the strip draws the buttons in the
  desktop's button layout.
- Wherever the system draws the frame (and on the web) the strip stays the
  menu bar, with the app icon at its left. No line under the strip.

TEXTURECRAFT_TITLEBAR=app|system overrides the decision. Settings ›
Interface › System title bar (applies on restart) brings the OS frame back;
it is read from the saved settings before the window opens and is settable
over the control channel as prefs.system_title_bar. ui.inspect reports
titleBar. New strings are translated in every language, and the offscreen
snapshots render the app-drawn and macOS variants.
2026-11-01 19:46:06 +07:00
bflatastic 9eb200863b Meshes with files beside them: .gltf buffers and images, loose USD layer textures
A .gltf whose buffers or images are separate files, and a loose USD layer whose
UsdPreviewSurface textures sit next to it, now open, reimport and bake as high polys with
those files, and projects keep them: `self_contained_mesh` folds a .gltf's files in as data
URIs and packages a loose layer with its textures as a .usdz, so the stored mesh imports
from its bytes alone. Only files inside the mesh's folder are read (no absolute paths, URLs
or `..` above it); missing ones are named in the log.

- formats: `self_contained_mesh`, `read_mesh_file` and `MeshFile`; `import_mesh` uses them;
  the glTF reader no longer reads the disk itself; USD texture lookups go through one
  `Assets` source (usdz package or loose files)
- engine: file.open, file.new, file.reimportMesh, bake.highPoly.add and bake.cage.set read
  meshes this way; a failed reimport no longer leaves the session pointing at the new file
- automation: mesh_import / mesh.import read the files under the same workspace rules
- CLI `info` reports a .gltf with external buffers

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-23 13:16:59 +07:00
bflatastic 5c33d2005f Modern theme matching VectorCraft: brightness levels, accent colours, rounded cards
Four brightness levels (Medium dark by default) and seven accent colours (Copper, from the app
icon, by default) in Settings › Interface, saved in the UI preferences and settable over the
control channel. Panels, dock groups and bars are rounded cards; tabs are pills, buttons flat and
rounded, popups shadowed; spacing follows VectorCraft. The 3D and 2D views keep a neutral studio
grey with overlay colours that stay readable on it. Widget colours come from craft-ui.

Also: `ui.resize` sets the window size for recordings and screenshots, and TEXTURECRAFT_NO_PREFS
keeps scripted runs off the user's saved layout and settings.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-16 16:58:47 +07:00
bflatastic 1e88b9041f Smooth 8K strokes, decal handles, displacement, refraction, release readiness
- Strokes pre-blend their commit while painting and recompose committed tiles at low
  priority: the 8K stroke-end frame drops from 30-42 ms to 12-19 ms
- Texture set resize runs in the background (8K: 3 s to 0.5 s, UV padding map from island
  borders only)
- Decal move/scale/rotate handles; FBX and USD high-poly textures for the color map;
  viewport displacement from the height channel; screen-space refraction of the scene
- CI pinned to Rust 1.96.0; FreeBSD VM sized for hosted runners; release builds embed
  craft-fonts; file associations for FBX, COLLADA, USD and Alembic on every platform
- README, release checklist, NOTICE and attribution brought up to date

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-16 13:25:10 +07:00
bflatastic 55387bf0fd GPU baking, Alembic, templates, translations and 8K responsiveness
- Baking: per-map ray settings (AO, thickness, bent normals), GPU ray-traced baking with CPU
  fallback (~12x), color map from textured glTF high polys
- Files: Alembic (Ogawa) and FBX 6 import, per-tile UDIM resolution, converting a set to UV
  tiles, project templates, preserving painted strokes on mesh reimport
- UI: translations (French, German, Spanish, Portuguese, Italian, Japanese, Chinese, Korean)
  with a live language picker and CJK fonts, closed panels reopen where they were, viewport
  texture resolution setting, frame-budgeted scene sync for 8K sets
- Web: loading screen, WebGL2 notice, app-captured shortcuts, touch navigation

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-16 11:23:28 +07:00
bflatastic 81d3f5c14c GPU path tracing, depth of field, cameras, glass, filters and decals
- Rendering mode traces on the GPU (compute shaders, ~25x the CPU tracer) with CPU fallback;
  CLI/MCP render --samples uses the GPU unless --cpu
- Depth of field in the viewport and the path tracer; multiple cameras with glTF import;
  transmission/IOR, coat normal and screen-space subsurface blur; exact 8-bit normal decode
- Filter library (18 filters incl. warp, color balance, gradient map, posterize, MatFinish)
  with a Filters shelf tab; geometry decals; clone from the current layer; anchors inside a
  content stack; instances across texture-set resolutions; drag saved smart materials

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-16 09:06:22 +07:00
bflatastic bdbb52c9b6 UDIM tiles, USD import/export, coat/sheen/anisotropy/subsurface shading
- UV tiles: auto-detected UDIM texture sets as one atlas per set, padding kept inside tiles,
  one file per tile with the $udim export token, builtin:udim_plane
- USD: usda/usdc/usdz import (Crate reader with LZ4) and export with UsdPreviewSurface
- Shader lobes: clear coat, sheen, anisotropy and subsurface scattering channels in the
  viewport and the path tracer; car paint, velvet, brushed steel, skin and wax materials;
  glTF clearcoat/sheen export
- Color swatch popups no longer stay open

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-15 19:45:14 +07:00
bflatastic ec859420d5 TextureCraft: clean-room 3D texture painting in pure Rust
An open-source, clean-room implementation of a Substance 3D Painter-style texturing
workflow, written in pure Rust with egui and wgpu.

- Layer stack with 32 blend modes, masks, generators, content effects and anchor points
- Painting, projection, smudge, clone, path, lasso fill, particle brush and quick mask
- 43 procedural materials, 17 smart materials and 10 smart masks
- Mesh map baking with high-poly, cage and match-by-name support
- PBR viewport with HDR environments, TAA and a path-traced Rendering mode
- glTF, FBX, COLLADA, OBJ, PLY and STL import; texture export presets; OBJ and GLB export
- Dockable Painter-style UI, shortcut editor, web build, MCP server and CLI

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-15 01:33:13 +07:00