lithop 0.2.0 → 0.4.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 +34 -13
  6. data/RELEASING.md +24 -6
  7. data/docs/README.md +6 -3
  8. data/docs/artifacts.md +35 -16
  9. data/docs/bambu-studio.md +17 -11
  10. data/docs/calibration.md +4 -4
  11. data/docs/color-model.md +20 -18
  12. data/docs/command.md +53 -14
  13. data/docs/config.md +43 -31
  14. data/docs/getting-started.md +17 -8
  15. data/docs/images/cmyw-lithophane-preview.png +0 -0
  16. data/docs/local-ui.md +117 -0
  17. data/docs/tiling.md +20 -19
  18. data/docs/troubleshooting.md +12 -2
  19. data/ext/lithop_native/Cargo.toml +17 -0
  20. data/ext/lithop_native/build.rs +4 -0
  21. data/ext/lithop_native/extconf.rb +6 -0
  22. data/ext/lithop_native/src/column_mesh.rs +388 -0
  23. data/ext/lithop_native/src/lib.rs +37 -0
  24. data/ext/lithop_native/src/mesh.rs +187 -0
  25. data/ext/lithop_native/src/palette.rs +67 -0
  26. data/ext/lithop_native/src/xml.rs +134 -0
  27. data/lib/lithop/calibration/export.rb +2 -2
  28. data/lib/lithop/calibration/target.rb +5 -5
  29. data/lib/lithop/cli/image_adjustment_options.rb +33 -0
  30. data/lib/lithop/cli/image_options.rb +5 -18
  31. data/lib/lithop/cli/options.rb +17 -4
  32. data/lib/lithop/cli.rb +28 -0
  33. data/lib/lithop/export/color_metadata.rb +46 -23
  34. data/lib/lithop/export/generation.rb +38 -27
  35. data/lib/lithop/export/job.rb +2 -2
  36. data/lib/lithop/export/metadata.rb +8 -3
  37. data/lib/lithop/export/planning.rb +82 -45
  38. data/lib/lithop/export/previews.rb +25 -1
  39. data/lib/lithop/export/print_readme.rb +20 -4
  40. data/lib/lithop/formats/three_mf/bambu_metadata.rb +11 -8
  41. data/lib/lithop/formats/three_mf/mesh.rb +72 -3
  42. data/lib/lithop/formats/three_mf/model_writer.rb +21 -21
  43. data/lib/lithop/formats/three_mf/part_writer.rb +37 -0
  44. data/lib/lithop/formats/three_mf.rb +1 -1
  45. data/lib/lithop/image/pipeline.rb +84 -31
  46. data/lib/lithop/image/svg_loader.rb +16 -7
  47. data/lib/lithop/job_execution.rb +132 -4
  48. data/lib/lithop/layer_structure.rb +0 -9
  49. data/lib/lithop/mesh/column_geometry.rb +8 -0
  50. data/lib/lithop/mesh/column_topology.rb +2 -0
  51. data/lib/lithop/model/filament_profile.rb +3 -3
  52. data/lib/lithop/model/material_display_map.rb +2 -1
  53. data/lib/lithop/model/material_model.rb +17 -5
  54. data/lib/lithop/model/palette.rb +21 -3
  55. data/lib/lithop/model/z_region_model.rb +44 -0
  56. data/lib/lithop/native.rb +39 -0
  57. data/lib/lithop/settings.rb +147 -15
  58. data/lib/lithop/settings_file.rb +1 -0
  59. data/lib/lithop/tiling.rb +3 -2
  60. data/lib/lithop/version.rb +1 -1
  61. data/lib/lithop/web/app.rb +517 -0
  62. data/lib/lithop/web/bambu_studio_launcher.rb +82 -0
  63. data/lib/lithop/web/job_launcher.rb +214 -0
  64. data/lib/lithop/web/job_store.rb +390 -0
  65. data/lib/lithop/web/preview_store.rb +182 -0
  66. data/lib/lithop/web/public/app.css +330 -0
  67. data/lib/lithop/web/public/app.js +1949 -0
  68. data/lib/lithop/web/server.rb +21 -0
  69. data/lib/lithop/web/settings_form.rb +67 -0
  70. data/lib/lithop/web/settings_library.rb +154 -0
  71. data/lib/lithop/web/views/index.erb +418 -0
  72. data/lib/lithop/web/worker.rb +27 -0
  73. data/lib/lithop.rb +3 -1
  74. data/sig/lithop.rbs +41 -0
  75. metadata +86 -3
  76. data/lib/lithop/model/layer_region_model.rb +0 -24
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 724832daeb852eb0910033dd04b596f4d5f0f74535804e0577c20312b499ebe9
4
- data.tar.gz: 0a75bcd7986e64d707736b67f49f6e5301819043cddccdd63fb09569541d6aa9
3
+ metadata.gz: 167c581e6f5dbf12a3aff1fe0c0d9ad8bdd3b7da94a88553e4e170f9c6b30566
4
+ data.tar.gz: 516366ae988c3c59be4316d900f3eca7bdbd37099753feb4ee2b78e311d02056
5
5
  SHA512:
6
- metadata.gz: 719b4231386b719eacade124d17fb26c020d546ee526244bd285df6f78bf6c1905c4c1f62dd4b3d5853e57fb93f930b6c83e9c0bce47fee76d1fd49f4d320abc
7
- data.tar.gz: 16d8f9c4ce8cd42fa152e0e4a1dc6d98b40cd8d615fdb871b0e54f9ac2a96c96184f57ae906d227dd994bc2f5b215259c70f89f113a112744214f5b7f27d427b
6
+ metadata.gz: f1f60f8b051d8dc885acef8f7d0dd135bcce5bc27c43c977b27b74d6377df4ad8c47f2f2bedbf98d39c50b59451b5b3cd713d69b3d13f910bd5984560853826a
7
+ data.tar.gz: d5fbdd4805690c0935b8196dc6980fa643f803e5bd30b509dfe60d4eebccc92312fbd0a34c19568a4d420b7889d4cc0c42e41af56718822fac503380a3df30d1
data/CHANGELOG.md CHANGED
@@ -1,5 +1,19 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.4.0 - 2026-10-30
4
+
5
+ - Changes Z separation to 1–3 contiguous plates with a 0.10 mm first-layer Base White support on each; three-plate output uses eight 0.08 mm CMYW layers, equal source slices, a CMY-free third plate, and only one 0.08 mm Top White layer at the brightest thickness.
6
+ - Adds print color controls for all six CMY stacking orders with YMC as the default, optional Cyan or Magenta mixing into Yellow, and opt-in pale-color suppression.
7
+ - Moves Create, Jobs, and Presets into a GitHub-style top navigation, places the conversion action beside image selection, organizes settings into responsive panes, and adds bulk selection and deletion for recent jobs.
8
+ - Sets the standard maximum thickness to the printable 1.94 mm boundary with 0.01 mm UI increments and updates generated models, calibration stages, documentation, and artifact contracts accordingly.
9
+
10
+ ## 0.3.0 - 2026-10-20
11
+
12
+ - 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.
13
+ - 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.
14
+ - 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.
15
+ - 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.
16
+
3
17
  ## 0.2.0 - 2026-10-16
4
18
 
5
19
  - 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.4.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. By default, it turns a JPEG, PNG, or validated self-contained SVG image into a single-plate multipart CMYW 3MF and a White reference STL; optional XY tiling and Z-separated plates are also available. The source image is processed without uploading it or copying it into the completed 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
 
@@ -13,32 +17,35 @@ The standard profile uses:
13
17
  | Model size | 140 × 104 mm |
14
18
  | Thickness grid | 637 × 473 cells, approximately 0.22 mm per cell |
15
19
  | Nozzle | 0.2 mm |
16
- | White base | Two 0.1 mm layers |
17
- | Color region | Seven 0.1 mm CMYW layers in `Cyan -> Magenta -> Yellow -> White` order |
18
- | Upper White | Continuous height field from 1.0 to 2.14689422 mm, sliced at 0.04 mm |
20
+ | White base | One 0.10 mm first layer |
21
+ | Color region | Seven 0.08 mm CMYW layers; default `Yellow -> Magenta -> Cyan -> White` order |
22
+ | Upper White | Continuous White from 0.66 mm, sliced at 0.08 mm; one layer at the 0.74 mm brightest thickness |
19
23
  | Extruders | Cyan=1, Magenta=2, Yellow=3, White=4 |
20
24
 
21
- Bambu Studio restores the generated single `lithophane` plate and its White/Cyan/Magenta/Yellow assignments. The bundled fine-line target has been printed successfully with the current 0.2 mm, seven-layer standard. The current 140 × 104 mm color chart has been sliced and inspected in Bambu Studio, but it has not been physically printed with the 0.2 mm standard; its 120 recipes and eight White thickness stages have not been measured numerically. Colorimetric accuracy is not guaranteed.
25
+ Bambu Studio restores the generated single `lithophane` plate and its White/Cyan/Magenta/Yellow assignments. The bundled fine-line target and 140 × 104 mm color chart have been physically printed with the current 0.2 mm, seven-layer standard. LED transmission was visually checked on the chart and showed stronger transmission at Y100; the recipes and White thickness stages have not been measured numerically. Colorimetric accuracy is not guaranteed.
22
26
 
23
27
  Before printing, inspect every layer and confirm the Cyan, Magenta, Yellow, and White assignments. Do not move, align, scale, or merge individual material parts. Lithop does not slice models, send print jobs, or control a printer or AMS.
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.4.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.4.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.4.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,7 +68,15 @@ 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
 
64
- The standard command generates the 140 × 104 × 2.14689422 mm, 0.2 mm-nozzle layout:
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 keeps Create, Jobs, and Presets in a persistent top navigation. The Create view places the conversion action next to drag-and-drop image selection and provides section navigation for grouped settings; the Presets view separates saved-setting selection from save and management operations. Responsive panes, an engine-rendered input preview, persistent job progress and cancellation, side-by-side result views, and per-job artifact management remain available. 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
+
79
+ The standard command generates the 140 × 104 × 1.94 mm, 0.2 mm-nozzle layout:
65
80
 
66
81
  ```sh
67
82
  bundle exec lithop path/to/image.jpeg
@@ -71,9 +86,11 @@ It writes `lithop.3mf` with a single `lithophane` plate and White/Cyan/Magenta/Y
71
86
 
72
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`.
73
88
 
89
+ Use `--yellow-mix-color cyan|magenta` with `--yellow-mix-percent 0..100` to replace that percentage of Yellow coverage before the nearest layered recipe is selected. The default is 0%, so existing output is unchanged. Seven-layer output quantizes the requested ratio to whole layers.
90
+
74
91
  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.
75
92
 
76
- 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.
93
+ Add `--separate-z-parts` to slice the CMYW model into 1–3 contiguous Bambu Studio plates. Every plate receives Base White support beneath its source Z slice so Cyan and Yellow regions remain connected after printing. Z separation uses eight 0.08 mm CMY/W color layers. `--color-region-parts 3` uses equal source ranges beginning at 0.10, 0.42, and 0.74 mm. The second plate ends with the color region, while the third contains no CMY. To prevent its brightest area from becoming a fragile two-layer sheet, Z plate 3 uses three Base White layers (0.26 mm) plus at least one 0.08 mm Top White layer. Its printed minimum is 0.34 mm, and the assembled range is 1.18–2.30 mm. See [3MF tiling and Z separation](docs/tiling.md).
77
94
 
78
95
  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.
79
96
 
@@ -100,16 +117,20 @@ The command-line options can override individual profile values. Use `--color-pi
100
117
  ## Other commands
101
118
 
102
119
  - `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).
120
+ - `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).
121
+ - `lithop doctor` reports whether the Rust acceleration extension is loaded, enabled, and version-matched.
103
122
  - `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.
123
+ - `lithop --help`, `lithop calibrate --help`, `lithop ui --help`, and `lithop clean --help` show the current command syntax.
105
124
 
106
125
  ## Documentation
107
126
 
108
127
  - [Documentation index and verification status](docs/README.md)
109
128
  - [Installation and basic use](docs/getting-started.md)
129
+ - [Local browser UI](docs/local-ui.md)
110
130
  - [Bambu Studio verification and printing](docs/bambu-studio.md)
111
131
  - [Options and settings](docs/config.md)
112
132
  - [Artifacts and generation records](docs/artifacts.md)
133
+ - [3MF tiling and Z separation](docs/tiling.md)
113
134
  - [CMYW color model and layer structure](docs/color-model.md)
114
135
  - [Optional measured calibration](docs/calibration.md)
115
136
  - [Command reference](docs/command.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.4.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.4.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.4.0
62
80
  lithop --version
63
81
  ```
data/docs/README.md CHANGED
@@ -1,10 +1,11 @@
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です。既定では単一プレートの3MFを生成し、必要に応じてXYタイル分割とZプレート分割を利用できます。画像を外部へ送信せず、入力画像自体を完了済みジョブへコピーしません。
4
4
 
5
5
  ## 安全と現在の検証範囲
6
6
 
7
- - 標準は0.2 mmノズル、White下地2層、CMYW色領域7層、連続高のWhite上面を使います。
7
+ - 標準は0.2 mmノズル、White下地1層0.10 mm、0.08 mmのCMYW色領域7層、0.08 mmの連続高White上面を使います。
8
+ - Z分割時は各プレートの第1層をBase White 0.10 mm、CMYW色領域8層とTop Whiteを0.08 mm積層ピッチにします。3分割時のZプレート3はBase White 3層とTop White 1層以上で、最薄部をWhite合計4層・0.34 mmにします。
8
9
  - Bambu Studioで単一プレートとWhite/Cyan/Magenta/Yellowの割り当て復元を確認済みです。0.2 mmノズルで実機印刷済みなのは細線評価片です。現行140 × 104 mmカラーチャートはBambu Studioで形状を確認済みですが、実機印刷は未実施です。
9
10
  - 現行カラーチャートの120レシピとWhite厚み8段階は数値測色していません。
10
11
  - 数値測色は必須にしておらず、入力画像やプレビューとの測色的一致は保証しません。
@@ -14,6 +15,7 @@ Lithopは、JPEG、PNG、SVGからCMYW材料のカラーLithophane(リトフ
14
15
  ## 初めて使う
15
16
 
16
17
  - [導入と基本操作](getting-started.md) — インストール、小型モデルの生成、最初に見る成果物
18
+ - [ローカルブラウザUI](local-ui.md) — 画像選択、設定、プレビュー、進捗・中止、成果物表示
17
19
 
18
20
  ## 印刷・校正する
19
21
 
@@ -23,7 +25,7 @@ Lithopは、JPEG、PNG、SVGからCMYW材料のカラーLithophane(リトフ
23
25
  ## 仕様を調べる
24
26
 
25
27
  - [生成物と記録](artifacts.md) — ジョブ、全成果物、プレビュー、`settings.json`、`manifest.json`
26
- - [3MFタイル分割とZ分割](tiling.md) — 指定枚数のXY分割、組み立て座標、4プレートのZ分割
28
+ - [3MFタイル分割とZ分割](tiling.md) — 指定枚数のXY分割、組み立て座標、強度調整したBase White付きの連続Z分割
27
29
  - [生成オプションと設定ファイル](config.md) — 設定の優先順位、入力JSON、既定値、検証規則
28
30
  - [コマンドリファレンス](command.md) — 構文、全オプション、終了ステータス
29
31
  - [CMYWの色モデルと積層構造](color-model.md) — 材料、減法混色、White厚み、3MF構造
@@ -37,6 +39,7 @@ CLIの現在の構文は、次のコマンドでも確認できます。
37
39
  ```sh
38
40
  lithop --help
39
41
  lithop calibrate --help
42
+ lithop ui --help
40
43
  lithop clean --help
41
44
  ```
42
45
 
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` | セル単位の厚さマップ |
@@ -32,7 +37,9 @@ Lithopは生成中のファイルを一時ディレクトリへ書き、すべ
32
37
 
33
38
  標準ジョブは単一プレートと非一様レイヤー情報を持つ`lithop.3mf`を出力します。未使用のCyan、Magenta、Yellowは3MFのメッシュから省略されるため、材料部品は1〜4個です。Whiteは必ず含まれます。`cmyk_white.stl`は比較用で、CMYWの材料分離情報を持ちません。
34
39
 
35
- XYタイルとZ分割のファイル構成、座標、`tile-layout.svg`、マニフェスト記録、4プレート構成は[3MFタイル分割とZ分割](tiling.md)を参照してください。
40
+ XYタイルとZ分割のファイル構成、座標、`tile-layout.svg`、マニフェスト記録、Base White第1層0.10 mm、以降0.08 mmピッチ、3分割時のZプレート3がWhite合計4層・最小0.34 mmという構成は[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`で対応を記録します。
36
43
 
37
44
  ## プレビューの座標と値
38
45
 
@@ -46,7 +53,7 @@ XYタイルとZ分割のファイル構成、座標、`tile-layout.svg`、マニ
46
53
 
47
54
  ## 出力される settings.json
48
55
 
49
- `settings.json`は入力用設定ファイルではなく、そのジョブで確定した値の記録です。代表的な構造は次のとおりです。
56
+ `settings.json`は入力用設定ファイルではなく、そのジョブで確定した値の記録です。次の例は`separate_z_parts: false`の非分割設定です。Z分割時は`color_layer_count: 8`、`first_layer_height: 0.1`、`layer_height: 0.08`、`top_layer_height: 0.08`となり、3分割時のZプレート3はWhite合計4層・最小0.34 mmになります。プレート別のBase White層数と厚みは`manifest.json`へ記録します。代表的な構造は次のとおりです。
50
57
 
51
58
  ```json
52
59
  {
@@ -64,8 +71,11 @@ XYタイルとZ分割のファイル構成、座標、`tile-layout.svg`、マニ
64
71
  "brightness": 0.0,
65
72
  "contrast": 0.0,
66
73
  "saturation": 0.0,
67
- "minimum_thickness": 1.0,
68
- "maximum_thickness": 2.14689422,
74
+ "suppress_pale_colors": false,
75
+ "yellow_mix_color": "cyan",
76
+ "yellow_mix_percent": 0.0,
77
+ "minimum_thickness": 0.74,
78
+ "maximum_thickness": 1.94,
69
79
  "pixel_size": 0.22,
70
80
  "color_pixel_size": null,
71
81
  "grid_columns": null,
@@ -77,22 +87,31 @@ XYタイルとZ分割のファイル構成、座標、`tile-layout.svg`、マニ
77
87
  "separate_z_parts": false,
78
88
  "color_region_parts": 3,
79
89
  "first_layer_height": 0.1,
80
- "layer_height": 0.1,
81
- "base_white_layers": 2,
82
- "top_layer_height": 0.04,
83
- "top_white_start": 1.0,
84
- "minimum_top_white_layers": 0,
85
- "exact_maximum_thickness": true,
90
+ "layer_height": 0.08,
91
+ "base_white_layers": 1,
92
+ "top_layer_height": 0.08,
93
+ "top_white_start": null,
94
+ "minimum_top_white_layers": 1,
95
+ "exact_maximum_thickness": false,
86
96
  "nozzle_diameter": 0.2,
87
97
  "color_model": "cmy",
88
98
  "color_layer_count": 7,
89
- "pigment_order": ["cyan", "magenta", "yellow"],
99
+ "pigment_order": ["yellow", "magenta", "cyan"],
90
100
  "bambu_project": true,
91
101
  "maximum_input_pixels": 20000000,
92
102
  "maximum_triangles": 5000000,
93
103
  "effective_color_pixel_size": 0.22,
94
- "effective_minimum_thickness": 1.0,
95
- "effective_maximum_thickness": 2.14689422,
104
+ "effective_minimum_thickness": 0.74,
105
+ "effective_maximum_thickness": 1.94,
106
+ "minimum_z_part_thickness": 0.32,
107
+ "z_part_base_white_layers": 1,
108
+ "z_part_base_white_thickness": 0.1,
109
+ "z_part_minimum_build_thickness": 0.1,
110
+ "resolved_z_part_count": 3,
111
+ "z_separated_minimum_thickness": 0.96,
112
+ "z_separated_output_minimum_thickness": 0.94,
113
+ "z_separated_output_maximum_thickness": 2.14,
114
+ "z_separated_source_end": 1.06,
96
115
  "resolved_tile_rows": 1,
97
116
  "resolved_tile_columns": 1,
98
117
  "columns": 637,
@@ -100,7 +119,7 @@ XYタイルとZ分割のファイル構成、座標、`tile-layout.svg`、マニ
100
119
  "pixel_size_x": 0.21978021978021978,
101
120
  "pixel_size_y": 0.21987315010570824,
102
121
  "schema_version": 1,
103
- "generator_version": "0.2.0",
122
+ "generator_version": "0.4.0",
104
123
  "input_path": "/absolute/path/to/image.png",
105
124
  "input_settings_path": "/absolute/path/to/config/settings.json",
106
125
  "calibration_profile_id": null,
@@ -134,6 +153,6 @@ XYタイルとZ分割のファイル構成、座標、`tile-layout.svg`、マニ
134
153
 
135
154
  ## ローカルパスと共有時の注意
136
155
 
137
- 入力画像自体はジョブへコピーされません。ただし、`settings.json`の`input_path`、`input_settings_path`、`calibration_profile_path`にはローカルのディレクトリ名やファイル名が含まれます。Issueや第三者へ共有する前に機密情報がないか確認してください。
156
+ 入力画像自体は完了済みジョブへコピーされません。ただし、`settings.json`の`input_path`、`input_settings_path`、`calibration_profile_path`にはローカルのディレクトリ名やファイル名が含まれます。Issueや第三者へ共有する前に機密情報がないか確認してください。
138
157
 
139
158
  `manifest.json`には入力画像のSHA-256が含まれます。公開してよい識別情報か判断してから共有してください。