lithop 0.1.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 (76) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +14 -0
  3. data/Cargo.lock +284 -0
  4. data/Cargo.toml +6 -0
  5. data/README.md +31 -7
  6. data/RELEASING.md +24 -6
  7. data/docs/README.md +4 -1
  8. data/docs/artifacts.md +26 -2
  9. data/docs/bambu-studio.md +7 -1
  10. data/docs/color-model.md +2 -0
  11. data/docs/command.md +48 -7
  12. data/docs/config.md +31 -4
  13. data/docs/getting-started.md +10 -5
  14. data/docs/images/cmyw-lithophane-preview.png +0 -0
  15. data/docs/local-ui.md +114 -0
  16. data/docs/tiling.md +134 -0
  17. data/docs/troubleshooting.md +22 -0
  18. data/ext/lithop_native/Cargo.toml +17 -0
  19. data/ext/lithop_native/build.rs +4 -0
  20. data/ext/lithop_native/extconf.rb +6 -0
  21. data/ext/lithop_native/src/column_mesh.rs +388 -0
  22. data/ext/lithop_native/src/lib.rs +37 -0
  23. data/ext/lithop_native/src/mesh.rs +187 -0
  24. data/ext/lithop_native/src/palette.rs +67 -0
  25. data/ext/lithop_native/src/xml.rs +134 -0
  26. data/lib/lithop/calibration/export.rb +21 -8
  27. data/lib/lithop/cli/calibration.rb +3 -1
  28. data/lib/lithop/cli/image_options.rb +41 -2
  29. data/lib/lithop/cli/options.rb +13 -0
  30. data/lib/lithop/cli.rb +36 -1
  31. data/lib/lithop/export/color_metadata.rb +55 -0
  32. data/lib/lithop/export/generation.rb +131 -21
  33. data/lib/lithop/export/job.rb +30 -16
  34. data/lib/lithop/export/metadata.rb +54 -4
  35. data/lib/lithop/export/planning.rb +97 -0
  36. data/lib/lithop/export/previews.rb +25 -1
  37. data/lib/lithop/export/print_readme.rb +22 -4
  38. data/lib/lithop/export/result.rb +26 -4
  39. data/lib/lithop/formats/three_mf/bambu_metadata.rb +111 -24
  40. data/lib/lithop/formats/three_mf/mesh.rb +72 -3
  41. data/lib/lithop/formats/three_mf/model_writer.rb +249 -24
  42. data/lib/lithop/formats/three_mf/part_writer.rb +51 -6
  43. data/lib/lithop/formats/three_mf.rb +9 -6
  44. data/lib/lithop/image/pipeline.rb +66 -10
  45. data/lib/lithop/image/svg_loader.rb +5 -5
  46. data/lib/lithop/job_directory.rb +41 -0
  47. data/lib/lithop/job_execution.rb +378 -0
  48. data/lib/lithop/layer_structure.rb +11 -0
  49. data/lib/lithop/mesh/box_geometry.rb +41 -0
  50. data/lib/lithop/mesh/column_geometry.rb +10 -2
  51. data/lib/lithop/mesh/column_topology.rb +2 -0
  52. data/lib/lithop/mesh/geometry.rb +21 -13
  53. data/lib/lithop/model/layer_region_model.rb +24 -0
  54. data/lib/lithop/model/material_model.rb +17 -5
  55. data/lib/lithop/model/palette.rb +21 -3
  56. data/lib/lithop/native.rb +39 -0
  57. data/lib/lithop/reference_three_mf.rb +17 -1
  58. data/lib/lithop/settings.rb +116 -1
  59. data/lib/lithop/settings_file.rb +10 -4
  60. data/lib/lithop/tiling.rb +127 -0
  61. data/lib/lithop/version.rb +1 -1
  62. data/lib/lithop/web/app.rb +513 -0
  63. data/lib/lithop/web/bambu_studio_launcher.rb +82 -0
  64. data/lib/lithop/web/job_launcher.rb +214 -0
  65. data/lib/lithop/web/job_store.rb +390 -0
  66. data/lib/lithop/web/preview_store.rb +182 -0
  67. data/lib/lithop/web/public/app.css +319 -0
  68. data/lib/lithop/web/public/app.js +1847 -0
  69. data/lib/lithop/web/server.rb +21 -0
  70. data/lib/lithop/web/settings_form.rb +64 -0
  71. data/lib/lithop/web/settings_library.rb +154 -0
  72. data/lib/lithop/web/views/index.erb +364 -0
  73. data/lib/lithop/web/worker.rb +27 -0
  74. data/lib/lithop.rb +5 -0
  75. data/sig/lithop.rbs +102 -2
  76. metadata +89 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 13a626692e6ae5bd67e88bb4f81e0cf8ae8ad6fb220e5cdb4822a582eaec6dd7
4
- data.tar.gz: 1497a224597acc9416aa67961969aeeb868981581af93cff6fb7e0bada32d781
3
+ metadata.gz: 6d976da7f11815d7bb666e57fc4fa9f3154b535f1482814974804c642c988d11
4
+ data.tar.gz: cbb54acb9074271d1813398f98b6e2353eb8fa545ccb8f4ac256c73fdebde0b5
5
5
  SHA512:
6
- metadata.gz: 879e0cc070dfd33464e12504d5409b2b98df8ff1f576e716c818968875cab637a9f315ddf41bd021c391e3c88e222ebc3eddb29dcbbecf002531b9b80068a743
7
- data.tar.gz: 3ce5b71121d43b5c58ffb9bee086cf59e36ab1550554a007742ffc76852a2350b2e3dc49ec14596f4bc4caa4022efb1a53b752103eddfb18084d60a1ca454b31
6
+ metadata.gz: 24c42f6590c20ff0dd02c301569b4935559f160be4f79361f252e10fb027beedd7692a4ed2f1689753bbe23321c1b646a59e4e2d6f4e6c29f9e5b8da1e8ca3f3
7
+ data.tar.gz: 2c0e65025d88cb73e3266ed1b2d7325aa0c0ebdc845ac819e31ae40d38b24bab79a5e7557a3c1ab78470690638f04bcbb058cf7a9fc1fbc09b221fc2773799c6
data/CHANGELOG.md CHANGED
@@ -1,5 +1,19 @@
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
+
10
+ ## 0.2.0 - 2026-10-16
11
+
12
+ - Adds exact-count CMYW 3MF tiling, plus optional four-plate output for three Base White-backed CMYW color regions and Top White.
13
+ - Aligns the CLI help and source-checkout settings with the 140 × 104 mm standard profile.
14
+ - Adds reproducible sRGB brightness, contrast, and saturation adjustments to JSON settings and the CLI.
15
+ - Records conversion progress and final status, supports cancellation and stale temporary-data recovery, and limits each project to one active conversion.
16
+
3
17
  ## 0.1.0 - 2026-10-12
4
18
 
5
19
  - Converts JPEG, PNG, and validated self-contained SVG files up to 15 MB into a White reference STL and a single-plate multipart CMYW 3MF.
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.1.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.1.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.1.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
@@ -69,6 +84,12 @@ bundle exec lithop path/to/image.jpeg
69
84
 
70
85
  It writes `lithop.3mf` with a single `lithophane` plate and White/Cyan/Magenta/Yellow extruders. Its layer preview and physical print still require manual verification.
71
86
 
87
+ Use `--brightness`, `--contrast`, and `--saturation` with percentages from `-100` to `100` to adjust the shared sRGB input before White thickness and CMYW recipes are sampled. The resolved values are recorded in each job's `settings.json`.
88
+
89
+ Use `--tile-count N` with `--tile-layout auto`, `columns`, `rows`, or `grid` to emit exactly N local-origin 3MF tiles. Tiled jobs include assembled offsets and bounds in `manifest.json` plus a physical-size `tile-layout.svg` placement guide.
90
+
91
+ Add `--separate-z-parts` to place three closed CMYW color-region bands and Top White on four Bambu Studio plates inside every generated 3MF. Each color-region plate includes its own Base White carrier, and every plate is translated to start at Z=0 for independent printing; `manifest.json` retains the original assembly order and Z bounds.
92
+
72
93
  The command reports estimated and final triangle counts and creates a new `build/<job_id>/` directory. Completed jobs are never overwritten. Inspect `preview.png`, `transmission.png`, `thickness.png`, and the four material masks, then import `lithop.3mf` into Bambu Studio as a model. The 3MF contains geometry, fixed extruder numbers, and layer-height metadata. It does not select a printer, physical build plate, AMS slot, or complete slicing preset.
73
94
 
74
95
  The bundled color chart at standard settings produces 2,660,706 CMYW 3MF triangles, below the default 5,000,000-triangle limit. Runtime and memory depend on the image and machine; use a smaller model and a coarser cell size for initial checks.
@@ -94,13 +115,16 @@ The command-line options can override individual profile values. Use `--color-pi
94
115
  ## Other commands
95
116
 
96
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.
97
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.
98
- - `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.
99
122
 
100
123
  ## Documentation
101
124
 
102
125
  - [Documentation index and verification status](docs/README.md)
103
126
  - [Installation and basic use](docs/getting-started.md)
127
+ - [Local browser UI](docs/local-ui.md)
104
128
  - [Bambu Studio verification and printing](docs/bambu-studio.md)
105
129
  - [Options and settings](docs/config.md)
106
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.1.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.1.0 lithop-0.1.0.gem --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.1.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
 
@@ -23,6 +24,7 @@ Lithopは、JPEG、PNG、SVGからCMYW材料のカラーLithophane(リトフ
23
24
  ## 仕様を調べる
24
25
 
25
26
  - [生成物と記録](artifacts.md) — ジョブ、全成果物、プレビュー、`settings.json`、`manifest.json`
27
+ - [3MFタイル分割とZ分割](tiling.md) — 指定枚数のXY分割、組み立て座標、4プレートのZ分割
26
28
  - [生成オプションと設定ファイル](config.md) — 設定の優先順位、入力JSON、既定値、検証規則
27
29
  - [コマンドリファレンス](command.md) — 構文、全オプション、終了ステータス
28
30
  - [CMYWの色モデルと積層構造](color-model.md) — 材料、減法混色、White厚み、3MF構造
@@ -36,6 +38,7 @@ CLIの現在の構文は、次のコマンドでも確認できます。
36
38
  ```sh
37
39
  lithop --help
38
40
  lithop calibrate --help
41
+ lithop ui --help
39
42
  lithop clean --help
40
43
  ```
41
44
 
data/docs/artifacts.md CHANGED
@@ -6,7 +6,15 @@ Lithopは生成中のファイルを一時ディレクトリへ書き、すべ
6
6
 
7
7
  通常生成は`build/<job_id>/`、校正片生成は`build/<job_id>-calibration/`へ保存します。ジョブIDはUTC時刻とランダム値から作られます。
8
8
 
9
- 生成中は`build/.tmp-<job_id>/`を排他的に取得します。失敗または中断した実行は自分が作成した一時領域だけを回収し、入力画像、別の実行の一時領域、完了済みジョブを削除しません。完了済みジョブと同じIDは上書きしません。
9
+ 生成中は`build/.tmp-<job_id>/`へ書き込みます。通常生成と校正生成はプロジェクトごとの`build/.lithop.lock`を共有し、同時変換数を1に制限します。変換中に別の変換を開始した場合は待機せず、`another conversion is already running`で失敗します。完了済みジョブと同じIDは上書きしません。
10
+
11
+ 状態は`build/.jobs/<job_id>.json`へ原子的に保存します。`state`は`queued`、`running`、中止要求を受けた`cancelling`、終了状態の`completed`/`failed`/`cancelled`です。`phase`、0〜100の`percent`、メッセージ、開始・更新・終了日時を持ち、完了時だけ`output_path`と`files`を記録します。CLIにも主要工程の進捗を表示します。
12
+
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起動時に回収します。
10
18
 
11
19
  ## 通常ジョブのファイル
12
20
 
@@ -14,6 +22,7 @@ Lithopは生成中のファイルを一時ディレクトリへ書き、すべ
14
22
  | --- | --- |
15
23
  | `lithop.3mf` | 使用するCyan、Magenta、Yellow、Whiteの材料別メッシュを持つカラー用モデル |
16
24
  | `cmyk_white.stl` | 厚さマップから作るWhite単色の参照リトファン |
25
+ | `corrected-input.png` | 配置、クロップ、色調整、White余白を適用し、変換時の格子でサンプリングしたRGB入力 |
17
26
  | `preview.png` | 公称レシピ色に相対的な厚さの明暗を重ねた確認用画像 |
18
27
  | `transmission.png` | White厚さによる相対透過明度 |
19
28
  | `thickness.png` | セル単位の厚さマップ |
@@ -28,6 +37,10 @@ Lithopは生成中のファイルを一時ディレクトリへ書き、すべ
28
37
 
29
38
  標準ジョブは単一プレートと非一様レイヤー情報を持つ`lithop.3mf`を出力します。未使用のCyan、Magenta、Yellowは3MFのメッシュから省略されるため、材料部品は1〜4個です。Whiteは必ず含まれます。`cmyk_white.stl`は比較用で、CMYWの材料分離情報を持ちません。
30
39
 
40
+ XYタイルとZ分割のファイル構成、座標、`tile-layout.svg`、マニフェスト記録、4プレート構成は[3MFタイル分割とZ分割](tiling.md)を参照してください。
41
+
42
+ XY分割時は各`tiles/tile_rNN_cNN.3mf`に対応する`tiles/tile_rNN_cNN-preview.png`を追加します。画像の1画素はそのタイルの1セルで、分割3MFと同じ範囲を表します。`manifest.json`の各`tiles`要素は`file`と`preview_file`で対応を記録します。
43
+
31
44
  ## プレビューの座標と値
32
45
 
33
46
  全プレビューの1画素は3MFの1セルに対応し、左上がモデルの`+Y`側です。材料マスクは黒が0層で、明るいほど層数が多く、4材料で同じ明度尺度を使います。
@@ -55,12 +68,21 @@ Lithopは生成中のファイルを一時ディレクトリへ書き、すべ
55
68
  "crop_position_x": 0.5,
56
69
  "crop_position_y": 0.5,
57
70
  "crop_scale": 1.0,
71
+ "brightness": 0.0,
72
+ "contrast": 0.0,
73
+ "saturation": 0.0,
58
74
  "minimum_thickness": 1.0,
59
75
  "maximum_thickness": 2.14689422,
60
76
  "pixel_size": 0.22,
61
77
  "color_pixel_size": null,
62
78
  "grid_columns": null,
63
79
  "grid_rows": null,
80
+ "tile_count": 1,
81
+ "tile_layout": "auto",
82
+ "tile_rows": null,
83
+ "tile_columns": null,
84
+ "separate_z_parts": false,
85
+ "color_region_parts": 3,
64
86
  "first_layer_height": 0.1,
65
87
  "layer_height": 0.1,
66
88
  "base_white_layers": 2,
@@ -78,12 +100,14 @@ Lithopは生成中のファイルを一時ディレクトリへ書き、すべ
78
100
  "effective_color_pixel_size": 0.22,
79
101
  "effective_minimum_thickness": 1.0,
80
102
  "effective_maximum_thickness": 2.14689422,
103
+ "resolved_tile_rows": 1,
104
+ "resolved_tile_columns": 1,
81
105
  "columns": 637,
82
106
  "rows": 473,
83
107
  "pixel_size_x": 0.21978021978021978,
84
108
  "pixel_size_y": 0.21987315010570824,
85
109
  "schema_version": 1,
86
- "generator_version": "0.1.0",
110
+ "generator_version": "0.3.0",
87
111
  "input_path": "/absolute/path/to/image.png",
88
112
  "input_settings_path": "/absolute/path/to/config/settings.json",
89
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
 
@@ -24,8 +24,14 @@ bundle exec lithop examples/cmy-fine-line.svg --width 20 --height 15 --pixel-siz
24
24
 
25
25
  表示された`build/<job_id>/`で、`preview.png`、`PRINT_README.md`、`settings.json`、`manifest.json`を確認してから`lithop.3mf`を開きます。自分のジョブIDと印刷条件は`manifest.json`に記録されています。
26
26
 
27
+ タイルまたはZ分割ジョブを開く場合は、[3MFタイル分割とZ分割](tiling.md)に従い、対象3MF、組み立て座標、4プレート、材料割り当てを確認します。
28
+
27
29
  ## 3MFを読み込む
28
30
 
31
+ macOSで`lithop ui`を使用している場合は、完了ジョブの「成果物 → モデル」にある「Bambu Studioで開く」から対象3MFを渡せます。XY分割ジョブは、分割モデルカードまたは成果物一覧でタイルを1つずつ選びます。画面に成功と表示されても、OSへ起動要求を渡した段階です。Bambu Studioでファイル名、プレート数、材料、寸法を確認してから次へ進んでください。Bambu Studioで既存プロジェクトを開いていると別の3MFが表示されない場合があるため、その場合は現在の作業を確認してから3MFを保存して開きます。
32
+
33
+ ボタンが表示されない環境や起動できない場合は、同じ行の「3MFを保存」を使い、Bambu Studioからファイルを開きます。未保存プロジェクトの確認ダイアログが表示された場合は、現在の編集内容を確認してから操作してください。
34
+
29
35
  1. `cmyk_white.stl`ではなく`lithop.3mf`をモデルとして読み込む。
30
36
  2. 一つの親オブジェクトの下に、使用材料の部品が同じ位置で組み立てられていることを確認する。
31
37
  3. 部品を個別に移動、整列、拡大縮小、結合しない。
data/docs/color-model.md CHANGED
@@ -77,6 +77,8 @@ Z=0 / バックライト側
77
77
  | CMYW色領域 | 7 | 0.20–0.90 mm |
78
78
  | 上部White | 可変 | 0.90–2.14689422 mm |
79
79
 
80
+ `--separate-z-parts`で出力する4プレート、Base Whiteキャリア、元のZ境界、積層順は[3MFタイル分割とZ分割](tiling.md)を参照してください。
81
+
80
82
  標準の最小厚さは1.0 mm、最大厚さは2.14689422 mmです。
81
83
 
82
84
  ## 材料別メッシュの関係