lithop 0.2.0 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (60) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +7 -0
  3. data/Cargo.lock +284 -0
  4. data/Cargo.toml +6 -0
  5. data/README.md +25 -7
  6. data/RELEASING.md +24 -6
  7. data/docs/README.md +3 -1
  8. data/docs/artifacts.md +9 -2
  9. data/docs/bambu-studio.md +5 -1
  10. data/docs/command.md +25 -2
  11. data/docs/config.md +1 -1
  12. data/docs/getting-started.md +8 -5
  13. data/docs/images/cmyw-lithophane-preview.png +0 -0
  14. data/docs/local-ui.md +114 -0
  15. data/docs/tiling.md +4 -2
  16. data/docs/troubleshooting.md +10 -0
  17. data/ext/lithop_native/Cargo.toml +17 -0
  18. data/ext/lithop_native/build.rs +4 -0
  19. data/ext/lithop_native/extconf.rb +6 -0
  20. data/ext/lithop_native/src/column_mesh.rs +388 -0
  21. data/ext/lithop_native/src/lib.rs +37 -0
  22. data/ext/lithop_native/src/mesh.rs +187 -0
  23. data/ext/lithop_native/src/palette.rs +67 -0
  24. data/ext/lithop_native/src/xml.rs +134 -0
  25. data/lib/lithop/calibration/export.rb +2 -2
  26. data/lib/lithop/cli/options.rb +13 -0
  27. data/lib/lithop/cli.rb +28 -0
  28. data/lib/lithop/export/generation.rb +30 -17
  29. data/lib/lithop/export/job.rb +2 -2
  30. data/lib/lithop/export/metadata.rb +8 -3
  31. data/lib/lithop/export/previews.rb +25 -1
  32. data/lib/lithop/formats/three_mf/mesh.rb +72 -3
  33. data/lib/lithop/formats/three_mf/model_writer.rb +19 -16
  34. data/lib/lithop/formats/three_mf/part_writer.rb +37 -0
  35. data/lib/lithop/formats/three_mf.rb +1 -1
  36. data/lib/lithop/image/pipeline.rb +50 -11
  37. data/lib/lithop/image/svg_loader.rb +5 -5
  38. data/lib/lithop/job_execution.rb +132 -4
  39. data/lib/lithop/mesh/column_geometry.rb +8 -0
  40. data/lib/lithop/mesh/column_topology.rb +2 -0
  41. data/lib/lithop/model/material_model.rb +17 -5
  42. data/lib/lithop/model/palette.rb +21 -3
  43. data/lib/lithop/native.rb +39 -0
  44. data/lib/lithop/tiling.rb +3 -2
  45. data/lib/lithop/version.rb +1 -1
  46. data/lib/lithop/web/app.rb +513 -0
  47. data/lib/lithop/web/bambu_studio_launcher.rb +82 -0
  48. data/lib/lithop/web/job_launcher.rb +214 -0
  49. data/lib/lithop/web/job_store.rb +390 -0
  50. data/lib/lithop/web/preview_store.rb +182 -0
  51. data/lib/lithop/web/public/app.css +319 -0
  52. data/lib/lithop/web/public/app.js +1847 -0
  53. data/lib/lithop/web/server.rb +21 -0
  54. data/lib/lithop/web/settings_form.rb +64 -0
  55. data/lib/lithop/web/settings_library.rb +154 -0
  56. data/lib/lithop/web/views/index.erb +364 -0
  57. data/lib/lithop/web/worker.rb +27 -0
  58. data/lib/lithop.rb +1 -0
  59. data/sig/lithop.rbs +25 -0
  60. metadata +84 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 724832daeb852eb0910033dd04b596f4d5f0f74535804e0577c20312b499ebe9
4
- data.tar.gz: 0a75bcd7986e64d707736b67f49f6e5301819043cddccdd63fb09569541d6aa9
3
+ metadata.gz: 6d976da7f11815d7bb666e57fc4fa9f3154b535f1482814974804c642c988d11
4
+ data.tar.gz: cbb54acb9074271d1813398f98b6e2353eb8fa545ccb8f4ac256c73fdebde0b5
5
5
  SHA512:
6
- metadata.gz: 719b4231386b719eacade124d17fb26c020d546ee526244bd285df6f78bf6c1905c4c1f62dd4b3d5853e57fb93f930b6c83e9c0bce47fee76d1fd49f4d320abc
7
- data.tar.gz: 16d8f9c4ce8cd42fa152e0e4a1dc6d98b40cd8d615fdb871b0e54f9ac2a96c96184f57ae906d227dd994bc2f5b215259c70f89f113a112744214f5b7f27d427b
6
+ metadata.gz: 24c42f6590c20ff0dd02c301569b4935559f160be4f79361f252e10fb027beedd7692a4ed2f1689753bbe23321c1b646a59e4e2d6f4e6c29f9e5b8da1e8ca3f3
7
+ data.tar.gz: 2c0e65025d88cb73e3266ed1b2d7325aa0c0ebdc845ac819e31ae40d38b24bab79a5e7557a3c1ab78470690638f04bcbb058cf7a9fc1fbc09b221fc2773799c6
data/CHANGELOG.md CHANGED
@@ -1,5 +1,12 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.3.0 - 2026-10-20
4
+
5
+ - Adds a loopback-only Sinatra/ERB/Puma UI with responsive Create, Jobs, and Presets panes, faster immediate JPEG/PNG/SVG input previews, reusable settings, drafts, and engine-rendered result views.
6
+ - Adds persistent job progress and cancellation, indexed searchable history, result comparison, ZIP downloads, safe bulk deletion, direct opening of completed 3MF artifacts in Bambu Studio on macOS, and bounded preview caching with browser timing diagnostics.
7
+ - Adds a Rust extension for CMY recipe selection, CMY mesh generation, 3MF vertex indexing, and XML output; the standard chart benchmark median improves from 36.800 seconds to 13.946 seconds while retaining the Ruby comparison path.
8
+ - Packages the UI and Rust sources in the source gem, adds `lithop doctor`, and verifies macOS/Ruby 4.0 builds, installed-gem native loading, Chromium/WebKit workflows, and Bambu Studio loading of unsplit and split 3MF outputs.
9
+
3
10
  ## 0.2.0 - 2026-10-16
4
11
 
5
12
  - Adds exact-count CMYW 3MF tiling, plus optional four-plate output for three Base White-backed CMYW color regions and Top White.
data/Cargo.lock ADDED
@@ -0,0 +1,284 @@
1
+ # This file is automatically @generated by Cargo.
2
+ # It is not intended for manual editing.
3
+ version = 4
4
+
5
+ [[package]]
6
+ name = "aho-corasick"
7
+ version = "1.1.5"
8
+ source = "registry+https://github.com/rust-lang/crates.io-index"
9
+ checksum = "c982642fa9e8606056828ee9a8505737230110bb1099153c79efe865c59d12ba"
10
+ dependencies = [
11
+ "memchr",
12
+ ]
13
+
14
+ [[package]]
15
+ name = "bindgen"
16
+ version = "0.72.1"
17
+ source = "registry+https://github.com/rust-lang/crates.io-index"
18
+ checksum = "993776b509cfb49c750f11b8f07a46fa23e0a1386ffc01fb1e7d343efc387895"
19
+ dependencies = [
20
+ "bitflags",
21
+ "cexpr",
22
+ "clang-sys",
23
+ "itertools",
24
+ "proc-macro2",
25
+ "quote",
26
+ "regex",
27
+ "rustc-hash",
28
+ "shlex",
29
+ "syn",
30
+ ]
31
+
32
+ [[package]]
33
+ name = "bitflags"
34
+ version = "2.13.2"
35
+ source = "registry+https://github.com/rust-lang/crates.io-index"
36
+ checksum = "3ded4057c258ba199e2d26386d3af3780957ecaee6c4ef4041c6b4b8b97c0b06"
37
+
38
+ [[package]]
39
+ name = "cexpr"
40
+ version = "0.6.0"
41
+ source = "registry+https://github.com/rust-lang/crates.io-index"
42
+ checksum = "6fac387a98bb7c37292057cffc56d62ecb629900026402633ae9160df93a8766"
43
+ dependencies = [
44
+ "nom",
45
+ ]
46
+
47
+ [[package]]
48
+ name = "cfg-if"
49
+ version = "1.0.5"
50
+ source = "registry+https://github.com/rust-lang/crates.io-index"
51
+ checksum = "4e7648175b45a9a48536d676f68d918270699102aa8dab5496df06904c914600"
52
+
53
+ [[package]]
54
+ name = "clang-sys"
55
+ version = "1.9.1"
56
+ source = "registry+https://github.com/rust-lang/crates.io-index"
57
+ checksum = "157a8ba7b480713b56f4c09fd13fc3e0a22a5dfab8097ba61cbc5feef950788a"
58
+ dependencies = [
59
+ "glob",
60
+ "libc",
61
+ "libloading",
62
+ ]
63
+
64
+ [[package]]
65
+ name = "either"
66
+ version = "1.19.0"
67
+ source = "registry+https://github.com/rust-lang/crates.io-index"
68
+ checksum = "0e9c71c2167ca323c882b99918929403426e2373ea17242ff5653e0d5e1058be"
69
+
70
+ [[package]]
71
+ name = "glob"
72
+ version = "0.3.4"
73
+ source = "registry+https://github.com/rust-lang/crates.io-index"
74
+ checksum = "e4eba85ea1d0a966a983acd07deee566e67395d2d96b6fb39e62b5a833f1eb0b"
75
+
76
+ [[package]]
77
+ name = "itertools"
78
+ version = "0.13.0"
79
+ source = "registry+https://github.com/rust-lang/crates.io-index"
80
+ checksum = "413ee7dfc52ee1a4949ceeb7dbc8a33f2d6c088194d9f922fb8318faf1f01186"
81
+ dependencies = [
82
+ "either",
83
+ ]
84
+
85
+ [[package]]
86
+ name = "lazy_static"
87
+ version = "1.5.1"
88
+ source = "registry+https://github.com/rust-lang/crates.io-index"
89
+ checksum = "20870f649af7073d53e38067b2a84312175d56ea15217e1b15bc83506ec50afb"
90
+
91
+ [[package]]
92
+ name = "libc"
93
+ version = "0.2.191"
94
+ source = "registry+https://github.com/rust-lang/crates.io-index"
95
+ checksum = "65cd87c9a6d60536580b316ad985726104730a5151c99845f2490428ef91240a"
96
+
97
+ [[package]]
98
+ name = "libloading"
99
+ version = "0.8.9"
100
+ source = "registry+https://github.com/rust-lang/crates.io-index"
101
+ checksum = "d7c4b02199fee7c5d21a5ae7d8cfa79a6ef5bb2fc834d6e9058e89c825efdc55"
102
+ dependencies = [
103
+ "cfg-if",
104
+ "windows-link",
105
+ ]
106
+
107
+ [[package]]
108
+ name = "lithop_native"
109
+ version = "0.3.0"
110
+ dependencies = [
111
+ "libc",
112
+ "magnus",
113
+ "rb-sys",
114
+ "rb-sys-env",
115
+ ]
116
+
117
+ [[package]]
118
+ name = "magnus"
119
+ version = "0.8.4"
120
+ source = "registry+https://github.com/rust-lang/crates.io-index"
121
+ checksum = "e76237a607e1dea288dd0ef0c6c8f49037df2152d14bb52b3542c46522d9e6fc"
122
+ dependencies = [
123
+ "magnus-macros",
124
+ "rb-sys",
125
+ "rb-sys-env",
126
+ "seq-macro",
127
+ ]
128
+
129
+ [[package]]
130
+ name = "magnus-macros"
131
+ version = "0.8.0"
132
+ source = "registry+https://github.com/rust-lang/crates.io-index"
133
+ checksum = "47607461fd8e1513cb4f2076c197d8092d921a1ea75bd08af97398f593751892"
134
+ dependencies = [
135
+ "proc-macro2",
136
+ "quote",
137
+ "syn",
138
+ ]
139
+
140
+ [[package]]
141
+ name = "memchr"
142
+ version = "2.8.3"
143
+ source = "registry+https://github.com/rust-lang/crates.io-index"
144
+ checksum = "cf8baf1c55e62ffcace7a9f06f4bd9cd3f0c4beb022d3b367256b91b87513d98"
145
+
146
+ [[package]]
147
+ name = "minimal-lexical"
148
+ version = "0.2.1"
149
+ source = "registry+https://github.com/rust-lang/crates.io-index"
150
+ checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a"
151
+
152
+ [[package]]
153
+ name = "nom"
154
+ version = "7.1.3"
155
+ source = "registry+https://github.com/rust-lang/crates.io-index"
156
+ checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a"
157
+ dependencies = [
158
+ "memchr",
159
+ "minimal-lexical",
160
+ ]
161
+
162
+ [[package]]
163
+ name = "proc-macro2"
164
+ version = "1.0.107"
165
+ source = "registry+https://github.com/rust-lang/crates.io-index"
166
+ checksum = "985e7ec9bb745e6ce6535b544d84d6cd6f7ad8bd711c398938ae983b91a766d9"
167
+ dependencies = [
168
+ "unicode-ident",
169
+ ]
170
+
171
+ [[package]]
172
+ name = "quote"
173
+ version = "1.0.47"
174
+ source = "registry+https://github.com/rust-lang/crates.io-index"
175
+ checksum = "1fbf4db142a473a8d80c26bbf18454ed458bf8d26c8219c331daecfdbd079001"
176
+ dependencies = [
177
+ "proc-macro2",
178
+ ]
179
+
180
+ [[package]]
181
+ name = "rb-sys"
182
+ version = "0.9.130"
183
+ source = "registry+https://github.com/rust-lang/crates.io-index"
184
+ checksum = "02faf625bb10ba893e3ae620f19c9fb1b5f8fcae0fe4eb86bb3f2230fad75edb"
185
+ dependencies = [
186
+ "rb-sys-build",
187
+ ]
188
+
189
+ [[package]]
190
+ name = "rb-sys-build"
191
+ version = "0.9.130"
192
+ source = "registry+https://github.com/rust-lang/crates.io-index"
193
+ checksum = "05be6f9c86fe5482808162826f6c047d093b3670582296c770de1d94f8066694"
194
+ dependencies = [
195
+ "bindgen",
196
+ "lazy_static",
197
+ "proc-macro2",
198
+ "quote",
199
+ "regex",
200
+ "shell-words",
201
+ "syn",
202
+ ]
203
+
204
+ [[package]]
205
+ name = "rb-sys-env"
206
+ version = "0.2.3"
207
+ source = "registry+https://github.com/rust-lang/crates.io-index"
208
+ checksum = "cca7ad6a7e21e72151d56fe2495a259b5670e204c3adac41ee7ef676ea08117a"
209
+
210
+ [[package]]
211
+ name = "regex"
212
+ version = "1.13.1"
213
+ source = "registry+https://github.com/rust-lang/crates.io-index"
214
+ checksum = "f020237b6c8eed93db2e2cb53c00c60a8e1bc73da7d073199a1180401450218d"
215
+ dependencies = [
216
+ "aho-corasick",
217
+ "memchr",
218
+ "regex-automata",
219
+ "regex-syntax",
220
+ ]
221
+
222
+ [[package]]
223
+ name = "regex-automata"
224
+ version = "0.4.18"
225
+ source = "registry+https://github.com/rust-lang/crates.io-index"
226
+ checksum = "ad8553b9b26413251cbf30e620595c7a41b3887f03da04579c0e6b0d6a06b4b2"
227
+ dependencies = [
228
+ "aho-corasick",
229
+ "memchr",
230
+ "regex-syntax",
231
+ ]
232
+
233
+ [[package]]
234
+ name = "regex-syntax"
235
+ version = "0.8.11"
236
+ source = "registry+https://github.com/rust-lang/crates.io-index"
237
+ checksum = "d6f6ff9a378485b298a5286656da665ba74413d36db0979633275d2e708145d4"
238
+
239
+ [[package]]
240
+ name = "rustc-hash"
241
+ version = "2.1.3"
242
+ source = "registry+https://github.com/rust-lang/crates.io-index"
243
+ checksum = "6b1e7f9a428571be2dc5bc0505c13fb6bf936822b894ec87abf8a08a4e51742d"
244
+
245
+ [[package]]
246
+ name = "seq-macro"
247
+ version = "0.3.6"
248
+ source = "registry+https://github.com/rust-lang/crates.io-index"
249
+ checksum = "1bc711410fbe7399f390ca1c3b60ad0f53f80e95c5eb935e52268a0e2cd49acc"
250
+
251
+ [[package]]
252
+ name = "shell-words"
253
+ version = "1.1.1"
254
+ source = "registry+https://github.com/rust-lang/crates.io-index"
255
+ checksum = "dc6fe69c597f9c37bfeeeeeb33da3530379845f10be461a66d16d03eca2ded77"
256
+
257
+ [[package]]
258
+ name = "shlex"
259
+ version = "1.3.0"
260
+ source = "registry+https://github.com/rust-lang/crates.io-index"
261
+ checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64"
262
+
263
+ [[package]]
264
+ name = "syn"
265
+ version = "2.0.119"
266
+ source = "registry+https://github.com/rust-lang/crates.io-index"
267
+ checksum = "872831b642d1a07999a962a351ed35b955ea2cfc8f3862091e2a240a84f17297"
268
+ dependencies = [
269
+ "proc-macro2",
270
+ "quote",
271
+ "unicode-ident",
272
+ ]
273
+
274
+ [[package]]
275
+ name = "unicode-ident"
276
+ version = "1.0.27"
277
+ source = "registry+https://github.com/rust-lang/crates.io-index"
278
+ checksum = "a2c754d6c33795a1c324727428e5a7dedb5b06195f9890bdbcba760d3e246563"
279
+
280
+ [[package]]
281
+ name = "windows-link"
282
+ version = "0.2.1"
283
+ source = "registry+https://github.com/rust-lang/crates.io-index"
284
+ checksum = "f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5"
data/Cargo.toml ADDED
@@ -0,0 +1,6 @@
1
+ [workspace]
2
+ members = ["ext/lithop_native"]
3
+ resolver = "2"
4
+
5
+ [profile.release]
6
+ debug = true
data/README.md CHANGED
@@ -2,7 +2,11 @@
2
2
 
3
3
  Create backlit color lithophanes locally.
4
4
 
5
- Lithop is a command-line CMYW color lithophane generator. It turns a JPEG, PNG, or validated self-contained SVG image into a single-plate multipart CMYW 3MF and a White reference STL without uploading, modifying, or copying the source image into the output job.
5
+ Lithop is a local CMYW color lithophane generator with a CLI and browser UI. It turns a JPEG, PNG, or validated self-contained SVG image into a single-plate multipart CMYW 3MF and a White reference STL without uploading the source image or copying it into the output job.
6
+
7
+ ![CMYW lithophane color-chart preview generated by Lithop](docs/images/cmyw-lithophane-preview.png)
8
+
9
+ *CMYW lithophane preview generated from the bundled color chart. This is the pre-print preview, not a photograph of a physical print.*
6
10
 
7
11
  ## Status and safety
8
12
 
@@ -24,21 +28,24 @@ Before printing, inspect every layer and confirm the Cyan, Magenta, Yellow, and
24
28
 
25
29
  ## Requirements
26
30
 
27
- - macOS and Ruby 4.0 or later
31
+ - macOS, Ruby 4.0 or later, and Rust. CI verifies macOS with Ruby 4.0; the current measured build is Apple silicon.
28
32
  - libvips with JPEG, PNG, SVG (librsvg), and ICC profile support
29
33
  - For physical printing: Bambu Studio, an AMS-capable printer, and the required PLA Basic Cyan, Magenta, Yellow, and White filaments
30
34
 
31
35
  ## Install
32
36
 
33
- To install the 0.2.0 release from RubyGems, install libvips and the matching Lithop version:
37
+ To install Lithop 0.3.0 from RubyGems, install libvips, Rust for the native palette extension, and the matching Lithop version:
34
38
 
35
39
  ```sh
36
- brew install vips
37
- gem install lithop -v 0.2.0
40
+ brew install vips rust
41
+ gem install lithop -v 0.3.0
38
42
  lithop --version
43
+ lithop doctor
39
44
  ```
40
45
 
41
- The version command must print `0.2.0`.
46
+ The version command must print `0.3.0`.
47
+ The doctor command reports `"backend": "rust"` and the loaded native-extension version. Set
48
+ `LITHOP_DISABLE_NATIVE=1` only when comparing the Ruby fallback.
42
49
 
43
50
  To work from a source checkout instead:
44
51
 
@@ -61,6 +68,14 @@ From a source checkout, use the bundled sample and a coarse cell size for a fast
61
68
  bundle exec lithop examples/cmy-fine-line.svg --width 20 --height 15 --pixel-size 0.5
62
69
  ```
63
70
 
71
+ To use the local browser UI, start its loopback-only server and open the displayed URL:
72
+
73
+ ```sh
74
+ lithop ui
75
+ ```
76
+
77
+ The UI separates creation, jobs, and reusable presets into responsive panes, with drag-and-drop image selection, grouped settings, an engine-rendered input preview, persistent job progress and cancellation, side-by-side result views, and per-job artifact management. Sinatra, ERB, Puma, CSS, and JavaScript are included in the gem, so the workflow remains local and works offline after installation. Playwright is used only for source-checkout browser tests. See [local browser UI](docs/local-ui.md).
78
+
64
79
  The standard command generates the 140 × 104 × 2.14689422 mm, 0.2 mm-nozzle layout:
65
80
 
66
81
  ```sh
@@ -100,13 +115,16 @@ The command-line options can override individual profile values. Use `--color-pi
100
115
  ## Other commands
101
116
 
102
117
  - `lithop calibrate` creates a 140 × 104 mm calibration SVG and matching printable 3MF with all 120 seven-layer recipes, eight White thickness stages, and a measurement-profile template. A completed measured profile can select both color recipes and the physical White height used by the 3MF, STL, previews, thickness map, and material masks. See [color calibration](docs/calibration.md).
118
+ - `lithop ui` starts the local browser UI on `127.0.0.1:4567`; on macOS, completed 3MF artifacts can be handed directly to Bambu Studio from the Jobs view. See [local browser UI](docs/local-ui.md).
119
+ - `lithop doctor` reports whether the Rust acceleration extension is loaded, enabled, and version-matched.
103
120
  - `lithop clean` permanently removes the selected project's complete `build/` directory, not one job. See the [command reference](docs/command.md#生成物を削除する) before using it.
104
- - `lithop --help`, `lithop calibrate --help`, and `lithop clean --help` show the current command syntax.
121
+ - `lithop --help`, `lithop calibrate --help`, `lithop ui --help`, and `lithop clean --help` show the current command syntax.
105
122
 
106
123
  ## Documentation
107
124
 
108
125
  - [Documentation index and verification status](docs/README.md)
109
126
  - [Installation and basic use](docs/getting-started.md)
127
+ - [Local browser UI](docs/local-ui.md)
110
128
  - [Bambu Studio verification and printing](docs/bambu-studio.md)
111
129
  - [Options and settings](docs/config.md)
112
130
  - [Artifacts and generation records](docs/artifacts.md)
data/RELEASING.md CHANGED
@@ -2,20 +2,38 @@
2
2
 
3
3
  This checklist prepares and publishes one immutable gem version. Run every command from the repository root.
4
4
 
5
+ Confirm that Ruby 4.0, Rust, Cargo, and libvips are available before installing dependencies:
6
+
7
+ ```sh
8
+ ruby --version
9
+ rustc --version
10
+ cargo --version
11
+ bundle exec ruby -rvips -e 'puts Vips.version_string'
12
+ ```
13
+
5
14
  ## 1. Prepare the version
6
15
 
7
16
  1. Update `Lithop::VERSION` in `lib/lithop/version.rb`.
8
17
  2. Add or update the matching version and release date in `CHANGELOG.md`. Keep the changelog concise; add an `Unreleased` section only when subsequent changes need one.
9
18
  3. Confirm the README installation and usage examples match the release.
10
19
  4. Manually open the external links in `README.md` and `docs/`; automated tests intentionally validate only local links and anchors.
11
- 5. Commit all intended files and verify that `git status --short` is empty.
12
- 6. Run the non-publishing release check:
20
+ 5. Confirm that `LICENSE` and `lithop.gemspec` identify Lithop as MIT. Review newly bundled code, images, fonts, and binaries for third-party terms. The current source gem does not bundle its Ruby dependencies, Playwright, libvips, or Rust crate sources, so it does not need a separate `THIRD_PARTY_NOTICES` file. Re-run this review before vendoring dependencies or publishing a precompiled native gem, and include the required license and notice texts when applicable.
21
+ 6. Commit all intended files and verify that `git status --short` is empty.
22
+ 7. When the local UI changed, run the Chromium and WebKit browser suite with the development-only Node.js 22 toolchain:
23
+
24
+ ```sh
25
+ npm install
26
+ npx playwright install chromium webkit
27
+ npm run test:browser
28
+ ```
29
+
30
+ 8. Run the non-publishing release check:
13
31
 
14
32
  ```sh
15
33
  bundle exec rake release:check
16
34
  ```
17
35
 
18
- The check runs the specs, RuboCop, and RBS validation; builds the gem; checks its version, metadata, runtime dependency, and packaged documentation; installs it into a temporary isolated gem directory; and executes the installed `lithop --version` command.
36
+ The check compiles the Rust extension, runs the Rust and Ruby specs, RuboCop, and RBS validation; builds the gem; checks its version, metadata, runtime dependency, and packaged documentation; installs it into a temporary isolated gem directory; and executes the installed `lithop --version` command.
19
37
 
20
38
  ## 2. Prepare publishing services
21
39
 
@@ -49,15 +67,15 @@ Alternatively, configure a RubyGems.org trusted publisher for this repository an
49
67
  bundle exec rake release
50
68
  ```
51
69
 
52
- After the tag exists on GitHub, create a GitHub Release and attach the exact gem that passed validation. Replace `0.2.0` for later versions:
70
+ After the tag exists on GitHub, create a GitHub Release and attach the exact gem that passed validation. Replace `0.3.0` for later versions:
53
71
 
54
72
  ```sh
55
- gh release create v0.2.0 --verify-tag --generate-notes
73
+ gh release create v0.3.0 --verify-tag --generate-notes
56
74
  ```
57
75
 
58
76
  Finally, install the published version in a clean environment and verify the CLI:
59
77
 
60
78
  ```sh
61
- gem install lithop -v 0.2.0
79
+ gem install lithop -v 0.3.0
62
80
  lithop --version
63
81
  ```
data/docs/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # Lithopドキュメント
2
2
 
3
- Lithopは、JPEG、PNG、SVGからCMYW材料のカラーLithophane(リトファン)3MFと、White参照STLを生成するローカルCLIです。画像を外部へ送信せず、入力画像自体を生成ジョブへコピーしません。
3
+ Lithopは、JPEG、PNG、SVGからCMYW材料のカラーLithophane(リトファン)3MFと、White参照STLを生成するローカルCLI/ブラウザUIです。画像を外部へ送信せず、入力画像自体を生成ジョブへコピーしません。
4
4
 
5
5
  ## 安全と現在の検証範囲
6
6
 
@@ -14,6 +14,7 @@ Lithopは、JPEG、PNG、SVGからCMYW材料のカラーLithophane(リトフ
14
14
  ## 初めて使う
15
15
 
16
16
  - [導入と基本操作](getting-started.md) — インストール、小型モデルの生成、最初に見る成果物
17
+ - [ローカルブラウザUI](local-ui.md) — 画像選択、設定、プレビュー、進捗・中止、成果物表示
17
18
 
18
19
  ## 印刷・校正する
19
20
 
@@ -37,6 +38,7 @@ CLIの現在の構文は、次のコマンドでも確認できます。
37
38
  ```sh
38
39
  lithop --help
39
40
  lithop calibrate --help
41
+ lithop ui --help
40
42
  lithop clean --help
41
43
  ```
42
44
 
data/docs/artifacts.md CHANGED
@@ -10,7 +10,11 @@ Lithopは生成中のファイルを一時ディレクトリへ書き、すべ
10
10
 
11
11
  状態は`build/.jobs/<job_id>.json`へ原子的に保存します。`state`は`queued`、`running`、中止要求を受けた`cancelling`、終了状態の`completed`/`failed`/`cancelled`です。`phase`、0〜100の`percent`、メッセージ、開始・更新・終了日時を持ち、完了時だけ`output_path`と`files`を記録します。CLIにも主要工程の進捗を表示します。
12
12
 
13
- `Ctrl-C`などの割り込みと`JobExecution.request_cancel`による中止要求は`cancelled`として記録し、未完成ジョブを公開しません。失敗はエラーのクラスとメッセージを`failed`状態へ記録します。どちらも実行自身が作成した一時領域を回収し、入力画像、別の実行の所有情報がない一時領域、使用中の一時領域、完了済みジョブを削除しません。プロセスが強制終了して回収できなかった所有情報付き一時領域は、所有PIDの終了を確認したうえで次の変換開始時に削除し、残っていた実行状態を`failed`の`recovered`工程へ変更します。
13
+ `Ctrl-C`などの割り込みと`JobExecution.request_cancel`による中止要求は`cancelled`として記録し、未完成ジョブを公開しません。成果物の原子的な公開が確定した後に中止要求が届いた場合は、出力との整合を保つため`completed`として記録します。失敗はエラーのクラスとメッセージを`failed`状態へ記録します。どちらも実行自身が作成した一時領域を回収し、入力画像、別の実行の所有情報がない一時領域、使用中の一時領域、完了済みジョブを削除しません。プロセスが強制終了して回収できなかった所有情報付き一時領域は、所有PIDの終了を確認したうえで次の変換開始時に削除し、残っていた実行状態を`failed`の`recovered`工程へ変更します。
14
+
15
+ ローカルUIでは終了状態のジョブを個別または複数選択で削除できます。対象は`build/<job_id>/`、`build/.jobs/<job_id>.json`、同名のログと中止要求、終了済みの`build/.web/<job_id>/`だけです。実行中のジョブ、シンボリックリンク、状態に記録された出力先がジョブIDと一致しないものは削除を拒否します。
16
+
17
+ ローカルUIの「全3MFをZIP」と「全成果物をZIP」は、状態JSONの`files`に成果物として記録されたファイルだけを元の相対パスで格納します。対象一覧と容量の確認まではZIPを生成しません。生成した`build/.downloads/*.zip`は応答終了時に削除し、異常終了で残った場合は次のUI起動時に回収します。
14
18
 
15
19
  ## 通常ジョブのファイル
16
20
 
@@ -18,6 +22,7 @@ Lithopは生成中のファイルを一時ディレクトリへ書き、すべ
18
22
  | --- | --- |
19
23
  | `lithop.3mf` | 使用するCyan、Magenta、Yellow、Whiteの材料別メッシュを持つカラー用モデル |
20
24
  | `cmyk_white.stl` | 厚さマップから作るWhite単色の参照リトファン |
25
+ | `corrected-input.png` | 配置、クロップ、色調整、White余白を適用し、変換時の格子でサンプリングしたRGB入力 |
21
26
  | `preview.png` | 公称レシピ色に相対的な厚さの明暗を重ねた確認用画像 |
22
27
  | `transmission.png` | White厚さによる相対透過明度 |
23
28
  | `thickness.png` | セル単位の厚さマップ |
@@ -34,6 +39,8 @@ Lithopは生成中のファイルを一時ディレクトリへ書き、すべ
34
39
 
35
40
  XYタイルとZ分割のファイル構成、座標、`tile-layout.svg`、マニフェスト記録、4プレート構成は[3MFタイル分割とZ分割](tiling.md)を参照してください。
36
41
 
42
+ XY分割時は各`tiles/tile_rNN_cNN.3mf`に対応する`tiles/tile_rNN_cNN-preview.png`を追加します。画像の1画素はそのタイルの1セルで、分割3MFと同じ範囲を表します。`manifest.json`の各`tiles`要素は`file`と`preview_file`で対応を記録します。
43
+
37
44
  ## プレビューの座標と値
38
45
 
39
46
  全プレビューの1画素は3MFの1セルに対応し、左上がモデルの`+Y`側です。材料マスクは黒が0層で、明るいほど層数が多く、4材料で同じ明度尺度を使います。
@@ -100,7 +107,7 @@ XYタイルとZ分割のファイル構成、座標、`tile-layout.svg`、マニ
100
107
  "pixel_size_x": 0.21978021978021978,
101
108
  "pixel_size_y": 0.21987315010570824,
102
109
  "schema_version": 1,
103
- "generator_version": "0.2.0",
110
+ "generator_version": "0.3.0",
104
111
  "input_path": "/absolute/path/to/image.png",
105
112
  "input_settings_path": "/absolute/path/to/config/settings.json",
106
113
  "calibration_profile_id": null,
data/docs/bambu-studio.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # Bambu Studioでの確認と印刷
2
2
 
3
- 標準の`lithop.3mf`は、単一`lithophane`プレート、CMYW割り当て、上部Whiteのレイヤー範囲を持ちます。単一プレートとWhite/Cyan/Magenta/Yellow割り当ての復元はBambu Studioで確認済みです。G-code、温度、速度、AMS実スロット、機種固有の開始・終了コードを含まないため、その他の印刷条件はBambu Studio側で確認します。
3
+ 標準の`lithop.3mf`は、単一`lithophane`プレート、CMYW割り当て、上部Whiteのレイヤー範囲を持ちます。単一プレートとWhite/Cyan/Magenta/Yellow割り当ての復元に加え、分割なし・分割ありの3MFが正常に開くことをBambu Studioで確認済みです。G-code、温度、速度、AMS実スロット、機種固有の開始・終了コードを含まないため、その他の印刷条件はBambu Studio側で確認します。
4
4
 
5
5
  標準構造は0.2 mmノズル、White下地2層、7層の`Cyan -> Magenta -> Yellow -> White`、連続高のWhite上面を使います。以下の確認をすべて終えるまで印刷を開始しないでください。
6
6
 
@@ -28,6 +28,10 @@ bundle exec lithop examples/cmy-fine-line.svg --width 20 --height 15 --pixel-siz
28
28
 
29
29
  ## 3MFを読み込む
30
30
 
31
+ macOSで`lithop ui`を使用している場合は、完了ジョブの「成果物 → モデル」にある「Bambu Studioで開く」から対象3MFを渡せます。XY分割ジョブは、分割モデルカードまたは成果物一覧でタイルを1つずつ選びます。画面に成功と表示されても、OSへ起動要求を渡した段階です。Bambu Studioでファイル名、プレート数、材料、寸法を確認してから次へ進んでください。Bambu Studioで既存プロジェクトを開いていると別の3MFが表示されない場合があるため、その場合は現在の作業を確認してから3MFを保存して開きます。
32
+
33
+ ボタンが表示されない環境や起動できない場合は、同じ行の「3MFを保存」を使い、Bambu Studioからファイルを開きます。未保存プロジェクトの確認ダイアログが表示された場合は、現在の編集内容を確認してから操作してください。
34
+
31
35
  1. `cmyk_white.stl`ではなく`lithop.3mf`をモデルとして読み込む。
32
36
  2. 一つの親オブジェクトの下に、使用材料の部品が同じ位置で組み立てられていることを確認する。
33
37
  3. 部品を個別に移動、整列、拡大縮小、結合しない。
data/docs/command.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # コマンドリファレンス
2
2
 
3
- このページはCLI構文とオプションの正本です。実行中の版では`lithop --help`、`lithop calibrate --help`、`lithop clean --help`でも確認できます。ソースチェックアウトでは、例の`lithop`を`bundle exec lithop`に読み替えてください。
3
+ このページはCLI構文とオプションの正本です。実行中の版では`lithop --help`、`lithop calibrate --help`、`lithop ui --help`、`lithop clean --help`でも確認できます。`lithop doctor`はRust拡張の状態をJSONで表示します。ソースチェックアウトでは、例の`lithop`を`bundle exec lithop`に読み替えてください。
4
4
 
5
5
  ## 画像からリトファンを生成する
6
6
 
@@ -158,6 +158,27 @@ lithop calibrate
158
158
 
159
159
  固定レイアウトで入力画像を使わないため、画像用の`width`、`height`、`margin_*`、画像配置、明るさ・コントラスト・彩度、`pixel_size`、`color_pixel_size`、`maximum_input_pixels`は使いません。生成物は[校正ジョブのファイル](artifacts.md#校正ジョブのファイル)、測定方法は[色校正](calibration.md)を参照してください。
160
160
 
161
+ ## ローカルUIを起動する
162
+
163
+ 画像選択、主要設定、プレビュー、進捗・中止、成果物表示を行うブラウザUIを`127.0.0.1`で起動します。
164
+
165
+ ```text
166
+ Usage: lithop ui [--project-dir DIR] [--port PORT]
167
+ ```
168
+
169
+ | オプション | 型 | 既定値 | 説明 |
170
+ | --- | --- | ---: | --- |
171
+ | `--project-dir DIR` | Path | 現在のディレクトリ | 設定を読み、`build/`を作るプロジェクトを選ぶ |
172
+ | `--port PORT` | Integer | `4567` | ローカルUIのポートを1〜65535で指定する |
173
+ | `-v`, `--version` | — | — | バージョンを表示して終了する |
174
+ | `-h`, `--help` | — | — | ヘルプを表示して終了する |
175
+
176
+ ```sh
177
+ lithop ui
178
+ ```
179
+
180
+ 表示された`http://127.0.0.1:4567`をブラウザで開きます。詳細は[ローカルブラウザUI](local-ui.md)を参照してください。
181
+
161
182
  ## 生成物を削除する
162
183
 
163
184
  ### 構文
@@ -181,13 +202,15 @@ lithop clean --project-dir /path/to/project
181
202
 
182
203
  `build/`がなければ正常終了します。ファイルシステムのルート、`build`自体がシンボリックリンク、または`build`がディレクトリではない場合は削除を拒否します。
183
204
 
184
- ## バージョンとヘルプを表示する
205
+ ## バージョン、診断、ヘルプを表示する
185
206
 
186
207
  | コマンド | 内容 |
187
208
  | --- | --- |
188
209
  | `lithop --version` | バージョンを表示する。短縮形は`lithop -v` |
210
+ | `lithop doctor` | Rustバックエンドのロード・有効状態、拡張とLithopのバージョン、Ruby、実行プラットフォームをJSONで表示する |
189
211
  | `lithop --help` | 通常生成の構文とオプションを表示する |
190
212
  | `lithop calibrate --help` | 校正片生成の構文とオプションを表示する |
213
+ | `lithop ui --help` | ローカルUIの起動オプションを表示する |
191
214
  | `lithop clean --help` | 削除コマンドの構文とオプションを表示する |
192
215
 
193
216
  ## 終了ステータスとエラー
data/docs/config.md CHANGED
@@ -225,4 +225,4 @@ effective: 1.0–2.14689422 mm
225
225
 
226
226
  ## 情報表示オプション
227
227
 
228
- `--help`と`--version`の対応は[バージョンとヘルプを表示する](command.md#バージョンとヘルプを表示する)を参照してください。
228
+ `--help`、`--version`、`doctor`の対応は[バージョン、診断、ヘルプを表示する](command.md#バージョン診断ヘルプを表示する)を参照してください。
@@ -4,8 +4,9 @@ Lithopは、画像からカラーLithophane(リトファン)の3MFとWhite
4
4
 
5
5
  ## 準備
6
6
 
7
- - macOS
7
+ - macOS(CIはmacOS/Ruby 4.0、現在の実測環境はApple silicon)
8
8
  - Ruby 4.0以上
9
+ - CMYWレシピ選択用ネイティブ拡張をビルドするRust
9
10
  - JPEG、PNG、SVG(librsvg)、ICCプロファイルを扱えるlibvips
10
11
  - 印刷する場合はBambu Studio、AMS対応プリンタ、必要なCMYWフィラメント
11
12
 
@@ -13,15 +14,17 @@ Lithopは、画像からカラーLithophane(リトファン)の3MFとWhite
13
14
 
14
15
  ## インストール
15
16
 
16
- 公開版0.2.0を使う場合は、libvipsとバージョンを指定したLithopをインストールします。
17
+ 0.3.0を使う場合は、libvips、Rust、バージョンを指定したLithopをインストールします。
17
18
 
18
19
  ```sh
19
- brew install vips
20
- gem install lithop -v 0.2.0
20
+ brew install vips rust
21
+ gem install lithop -v 0.3.0
21
22
  lithop --version
23
+ lithop doctor
22
24
  ```
23
25
 
24
- `lithop --version`が`0.2.0`を表示することを確認します。
26
+ `lithop --version`が`0.3.0`を表示することを確認します。
27
+ `lithop doctor`では`backend`が`rust`、`extension_version`がLithopと同じバージョンであることを確認します。
25
28
 
26
29
  ソースチェックアウトから実行する場合は、代わりに次を実行します。
27
30