lithop 0.1.0 → 0.2.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 (44) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +7 -0
  3. data/README.md +9 -3
  4. data/RELEASING.md +3 -3
  5. data/docs/README.md +1 -0
  6. data/docs/artifacts.md +19 -2
  7. data/docs/bambu-studio.md +2 -0
  8. data/docs/color-model.md +2 -0
  9. data/docs/command.md +23 -5
  10. data/docs/config.md +30 -3
  11. data/docs/getting-started.md +5 -3
  12. data/docs/tiling.md +132 -0
  13. data/docs/troubleshooting.md +12 -0
  14. data/lib/lithop/calibration/export.rb +21 -8
  15. data/lib/lithop/cli/calibration.rb +3 -1
  16. data/lib/lithop/cli/image_options.rb +41 -2
  17. data/lib/lithop/cli.rb +8 -1
  18. data/lib/lithop/export/color_metadata.rb +55 -0
  19. data/lib/lithop/export/generation.rb +117 -20
  20. data/lib/lithop/export/job.rb +30 -16
  21. data/lib/lithop/export/metadata.rb +48 -3
  22. data/lib/lithop/export/planning.rb +97 -0
  23. data/lib/lithop/export/print_readme.rb +22 -4
  24. data/lib/lithop/export/result.rb +26 -4
  25. data/lib/lithop/formats/three_mf/bambu_metadata.rb +111 -24
  26. data/lib/lithop/formats/three_mf/model_writer.rb +245 -23
  27. data/lib/lithop/formats/three_mf/part_writer.rb +14 -6
  28. data/lib/lithop/formats/three_mf.rb +8 -5
  29. data/lib/lithop/image/pipeline.rb +17 -0
  30. data/lib/lithop/job_directory.rb +41 -0
  31. data/lib/lithop/job_execution.rb +250 -0
  32. data/lib/lithop/layer_structure.rb +11 -0
  33. data/lib/lithop/mesh/box_geometry.rb +41 -0
  34. data/lib/lithop/mesh/column_geometry.rb +2 -2
  35. data/lib/lithop/mesh/geometry.rb +21 -13
  36. data/lib/lithop/model/layer_region_model.rb +24 -0
  37. data/lib/lithop/reference_three_mf.rb +17 -1
  38. data/lib/lithop/settings.rb +116 -1
  39. data/lib/lithop/settings_file.rb +10 -4
  40. data/lib/lithop/tiling.rb +126 -0
  41. data/lib/lithop/version.rb +1 -1
  42. data/lib/lithop.rb +4 -0
  43. data/sig/lithop.rbs +77 -2
  44. metadata +6 -1
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 13a626692e6ae5bd67e88bb4f81e0cf8ae8ad6fb220e5cdb4822a582eaec6dd7
4
- data.tar.gz: 1497a224597acc9416aa67961969aeeb868981581af93cff6fb7e0bada32d781
3
+ metadata.gz: 724832daeb852eb0910033dd04b596f4d5f0f74535804e0577c20312b499ebe9
4
+ data.tar.gz: 0a75bcd7986e64d707736b67f49f6e5301819043cddccdd63fb09569541d6aa9
5
5
  SHA512:
6
- metadata.gz: 879e0cc070dfd33464e12504d5409b2b98df8ff1f576e716c818968875cab637a9f315ddf41bd021c391e3c88e222ebc3eddb29dcbbecf002531b9b80068a743
7
- data.tar.gz: 3ce5b71121d43b5c58ffb9bee086cf59e36ab1550554a007742ffc76852a2350b2e3dc49ec14596f4bc4caa4022efb1a53b752103eddfb18084d60a1ca454b31
6
+ metadata.gz: 719b4231386b719eacade124d17fb26c020d546ee526244bd285df6f78bf6c1905c4c1f62dd4b3d5853e57fb93f930b6c83e9c0bce47fee76d1fd49f4d320abc
7
+ data.tar.gz: 16d8f9c4ce8cd42fa152e0e4a1dc6d98b40cd8d615fdb871b0e54f9ac2a96c96184f57ae906d227dd994bc2f5b215259c70f89f113a112744214f5b7f27d427b
data/CHANGELOG.md CHANGED
@@ -1,5 +1,12 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.2.0 - 2026-10-16
4
+
5
+ - Adds exact-count CMYW 3MF tiling, plus optional four-plate output for three Base White-backed CMYW color regions and Top White.
6
+ - Aligns the CLI help and source-checkout settings with the 140 × 104 mm standard profile.
7
+ - Adds reproducible sRGB brightness, contrast, and saturation adjustments to JSON settings and the CLI.
8
+ - Records conversion progress and final status, supports cancellation and stale temporary-data recovery, and limits each project to one active conversion.
9
+
3
10
  ## 0.1.0 - 2026-10-12
4
11
 
5
12
  - 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/README.md CHANGED
@@ -30,15 +30,15 @@ Before printing, inspect every layer and confirm the Cyan, Magenta, Yellow, and
30
30
 
31
31
  ## Install
32
32
 
33
- To install the 0.1.0 release from RubyGems, install libvips and the matching Lithop version:
33
+ To install the 0.2.0 release from RubyGems, install libvips and the matching Lithop version:
34
34
 
35
35
  ```sh
36
36
  brew install vips
37
- gem install lithop -v 0.1.0
37
+ gem install lithop -v 0.2.0
38
38
  lithop --version
39
39
  ```
40
40
 
41
- The version command must print `0.1.0`.
41
+ The version command must print `0.2.0`.
42
42
 
43
43
  To work from a source checkout instead:
44
44
 
@@ -69,6 +69,12 @@ bundle exec lithop path/to/image.jpeg
69
69
 
70
70
  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
71
 
72
+ 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
+
74
+ 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
+
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.
77
+
72
78
  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
79
 
74
80
  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.
data/RELEASING.md CHANGED
@@ -49,15 +49,15 @@ Alternatively, configure a RubyGems.org trusted publisher for this repository an
49
49
  bundle exec rake release
50
50
  ```
51
51
 
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:
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:
53
53
 
54
54
  ```sh
55
- gh release create v0.1.0 lithop-0.1.0.gem --verify-tag --generate-notes
55
+ gh release create v0.2.0 --verify-tag --generate-notes
56
56
  ```
57
57
 
58
58
  Finally, install the published version in a clean environment and verify the CLI:
59
59
 
60
60
  ```sh
61
- gem install lithop -v 0.1.0
61
+ gem install lithop -v 0.2.0
62
62
  lithop --version
63
63
  ```
data/docs/README.md CHANGED
@@ -23,6 +23,7 @@ Lithopは、JPEG、PNG、SVGからCMYW材料のカラーLithophane(リトフ
23
23
  ## 仕様を調べる
24
24
 
25
25
  - [生成物と記録](artifacts.md) — ジョブ、全成果物、プレビュー、`settings.json`、`manifest.json`
26
+ - [3MFタイル分割とZ分割](tiling.md) — 指定枚数のXY分割、組み立て座標、4プレートのZ分割
26
27
  - [生成オプションと設定ファイル](config.md) — 設定の優先順位、入力JSON、既定値、検証規則
27
28
  - [コマンドリファレンス](command.md) — 構文、全オプション、終了ステータス
28
29
  - [CMYWの色モデルと積層構造](color-model.md) — 材料、減法混色、White厚み、3MF構造
data/docs/artifacts.md CHANGED
@@ -6,7 +6,11 @@ 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`として記録し、未完成ジョブを公開しません。失敗はエラーのクラスとメッセージを`failed`状態へ記録します。どちらも実行自身が作成した一時領域を回収し、入力画像、別の実行の所有情報がない一時領域、使用中の一時領域、完了済みジョブを削除しません。プロセスが強制終了して回収できなかった所有情報付き一時領域は、所有PIDの終了を確認したうえで次の変換開始時に削除し、残っていた実行状態を`failed`の`recovered`工程へ変更します。
10
14
 
11
15
  ## 通常ジョブのファイル
12
16
 
@@ -28,6 +32,8 @@ Lithopは生成中のファイルを一時ディレクトリへ書き、すべ
28
32
 
29
33
  標準ジョブは単一プレートと非一様レイヤー情報を持つ`lithop.3mf`を出力します。未使用のCyan、Magenta、Yellowは3MFのメッシュから省略されるため、材料部品は1〜4個です。Whiteは必ず含まれます。`cmyk_white.stl`は比較用で、CMYWの材料分離情報を持ちません。
30
34
 
35
+ XYタイルとZ分割のファイル構成、座標、`tile-layout.svg`、マニフェスト記録、4プレート構成は[3MFタイル分割とZ分割](tiling.md)を参照してください。
36
+
31
37
  ## プレビューの座標と値
32
38
 
33
39
  全プレビューの1画素は3MFの1セルに対応し、左上がモデルの`+Y`側です。材料マスクは黒が0層で、明るいほど層数が多く、4材料で同じ明度尺度を使います。
@@ -55,12 +61,21 @@ Lithopは生成中のファイルを一時ディレクトリへ書き、すべ
55
61
  "crop_position_x": 0.5,
56
62
  "crop_position_y": 0.5,
57
63
  "crop_scale": 1.0,
64
+ "brightness": 0.0,
65
+ "contrast": 0.0,
66
+ "saturation": 0.0,
58
67
  "minimum_thickness": 1.0,
59
68
  "maximum_thickness": 2.14689422,
60
69
  "pixel_size": 0.22,
61
70
  "color_pixel_size": null,
62
71
  "grid_columns": null,
63
72
  "grid_rows": null,
73
+ "tile_count": 1,
74
+ "tile_layout": "auto",
75
+ "tile_rows": null,
76
+ "tile_columns": null,
77
+ "separate_z_parts": false,
78
+ "color_region_parts": 3,
64
79
  "first_layer_height": 0.1,
65
80
  "layer_height": 0.1,
66
81
  "base_white_layers": 2,
@@ -78,12 +93,14 @@ Lithopは生成中のファイルを一時ディレクトリへ書き、すべ
78
93
  "effective_color_pixel_size": 0.22,
79
94
  "effective_minimum_thickness": 1.0,
80
95
  "effective_maximum_thickness": 2.14689422,
96
+ "resolved_tile_rows": 1,
97
+ "resolved_tile_columns": 1,
81
98
  "columns": 637,
82
99
  "rows": 473,
83
100
  "pixel_size_x": 0.21978021978021978,
84
101
  "pixel_size_y": 0.21987315010570824,
85
102
  "schema_version": 1,
86
- "generator_version": "0.1.0",
103
+ "generator_version": "0.2.0",
87
104
  "input_path": "/absolute/path/to/image.png",
88
105
  "input_settings_path": "/absolute/path/to/config/settings.json",
89
106
  "calibration_profile_id": null,
data/docs/bambu-studio.md CHANGED
@@ -24,6 +24,8 @@ 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
 
29
31
  1. `cmyk_white.stl`ではなく`lithop.3mf`をモデルとして読み込む。
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
  ## 材料別メッシュの関係
data/docs/command.md CHANGED
@@ -19,8 +19,14 @@ Usage: lithop IMAGE [options]
19
19
  | オプション | 型 | 既定値 | 説明 |
20
20
  | --- | --- | ---: | --- |
21
21
  | `--layout-profile NAME` | String | `standard` | 標準構造を選ぶ。現在は`standard`のみ |
22
- | `--width MM` | Float | `130` | 完成幅をmm単位で指定する |
23
- | `--height MM` | Float | `100` | 完成高さをmm単位で指定する |
22
+ | `--width MM` | Float | `140.0` | 完成幅をmm単位で指定する |
23
+ | `--height MM` | Float | `104.0` | 完成高さをmm単位で指定する |
24
+ | `--tile-count COUNT` | Integer | `1` | 出力する3MFタイルの総数を指定する |
25
+ | `--tile-layout MODE` | String | `auto` | `auto`、`columns`、`rows`、`grid`から配置を選ぶ |
26
+ | `--tile-rows COUNT` | Integer | なし | `grid`配置の行数を指定する |
27
+ | `--tile-columns COUNT` | Integer | なし | `grid`配置の列数を指定する |
28
+ | `--separate-z-parts` | — | 無効 | 下地White、CMYW色領域、上部Whiteを別プレートにする |
29
+ | `--color-region-parts COUNT` | Integer | `3` | CMYW色領域のZ方向の分割数を指定する |
24
30
  | `--margin-top MM` | Float | `0` | 上側のWhite余白をmm単位で指定する |
25
31
  | `--margin-right MM` | Float | `0` | 右側のWhite余白をmm単位で指定する |
26
32
  | `--margin-bottom MM` | Float | `0` | 下側のWhite余白をmm単位で指定する |
@@ -29,6 +35,9 @@ Usage: lithop IMAGE [options]
29
35
  | `--crop-position-x FRACTION` | Float | `0.5` | 横方向の配置を左`0`から右`1`で指定する |
30
36
  | `--crop-position-y FRACTION` | Float | `0.5` | 縦方向の配置を上`0`から下`1`で指定する |
31
37
  | `--crop-scale FRACTION` | Float | `1.0` | `0`より大きく`1`以下の切り出し倍率を指定する |
38
+ | `--brightness PERCENT` | Float | `0` | sRGB明るさを`-100`〜`100`で補正する |
39
+ | `--contrast PERCENT` | Float | `0` | sRGBコントラストを`-100`〜`100`で補正する |
40
+ | `--saturation PERCENT` | Float | `0` | sRGB彩度を`-100`〜`100`で補正する |
32
41
  | `--min-thickness MM` | Float | `1.0` | 要求最小厚さをmm単位で指定する |
33
42
  | `--max-thickness MM` | Float | `2.14689422` | 要求最大厚さをmm単位で指定する |
34
43
  | `--pixel-size MM` | Float | `0.22` | XYセル寸法をmm単位で指定する |
@@ -67,6 +76,8 @@ SVGをPNGへ書き出さずに生成します。
67
76
  lithop image.svg --width 20 --height 15 --pixel-size 0.5
68
77
  ```
69
78
 
79
+ タイル分割とZ分割のコマンド例、配置、成果物は[3MFタイル分割とZ分割](tiling.md)を参照してください。
80
+
70
81
  完成寸法を変えず、上下1 mm、左右2 mmのWhite余白を設けます。
71
82
 
72
83
  ```sh
@@ -85,6 +96,12 @@ lithop image.png --crop-position-x 1 --crop-scale 0.8 --pixel-size 0.25 --color-
85
96
  lithop image.png --image-fit contain
86
97
  ```
87
98
 
99
+ 明るさを10%上げ、コントラストを15%、彩度を20%強めます。指定値は出力の`settings.json`へ保存され、同じCLIまたは入力設定JSONで再現できます。
100
+
101
+ ```sh
102
+ lithop image.png --brightness 10 --contrast 15 --saturation 20
103
+ ```
104
+
88
105
  別のプロジェクトと入力設定を使います。
89
106
 
90
107
  ```sh
@@ -99,17 +116,18 @@ lithop image.png --calibration-profile build/<calibration-job-id>/calibration-pr
99
116
 
100
117
  ### 出力
101
118
 
102
- 書き出し前にWhite参照STL、CMYW 3MF、材料別3MFの三角形数を表示します。成功時は確定した三角形数、ジョブディレクトリの絶対パス、ファイル一覧を表示します。
119
+ 画像処理、White高さ、材料モデル、メッシュ計画、3MF、プレビュー、メタデータの進捗を百分率で表示します。書き出し前にWhite参照STL、CMYW 3MF、材料別3MFの三角形数を表示し、成功時は確定した三角形数、ジョブディレクトリの絶対パス、ファイル一覧を表示します。
103
120
 
104
121
  ```text
105
122
  Estimated ... STL and ... CMYW 3MF triangles before writing
106
123
  CMYW by material: cyan=..., magenta=..., yellow=..., white=...
124
+ Progress ...%: ...
107
125
  Generated ... STL and ... CMYW 3MF triangles
108
126
  in /absolute/path/to/build/<job_id>
109
127
  ...
110
128
  ```
111
129
 
112
- 一時出力、完了済みジョブ、各ファイルは[生成物と記録](artifacts.md)を参照してください。
130
+ 通常生成と校正生成を合わせて、同じプロジェクトで同時に実行できる変換は1件です。`Ctrl-C`で中止したジョブは`cancelled`になり、一時出力を回収して成果物ディレクトリを公開しません。状態、一時出力、完了済みジョブ、各ファイルは[生成物と記録](artifacts.md)を参照してください。
113
131
 
114
132
  ## 校正片を生成する
115
133
 
@@ -138,7 +156,7 @@ Usage: lithop calibrate [options]
138
156
  lithop calibrate
139
157
  ```
140
158
 
141
- 固定レイアウトのため、画像用の`width`、`height`、`margin_*`、画像配置、`pixel_size`、`color_pixel_size`、`maximum_input_pixels`は使いません。生成物は[校正ジョブのファイル](artifacts.md#校正ジョブのファイル)、測定方法は[色校正](calibration.md)を参照してください。
159
+ 固定レイアウトで入力画像を使わないため、画像用の`width`、`height`、`margin_*`、画像配置、明るさ・コントラスト・彩度、`pixel_size`、`color_pixel_size`、`maximum_input_pixels`は使いません。生成物は[校正ジョブのファイル](artifacts.md#校正ジョブのファイル)、測定方法は[色校正](calibration.md)を参照してください。
142
160
 
143
161
  ## 生成物を削除する
144
162
 
data/docs/config.md CHANGED
@@ -30,12 +30,21 @@
30
30
  "crop_position_x": 0.5,
31
31
  "crop_position_y": 0.5,
32
32
  "crop_scale": 1.0,
33
+ "brightness": 0.0,
34
+ "contrast": 0.0,
35
+ "saturation": 0.0,
33
36
  "minimum_thickness": 1.0,
34
37
  "maximum_thickness": 2.14689422,
35
38
  "pixel_size": 0.5,
36
39
  "color_pixel_size": null,
37
40
  "grid_columns": null,
38
41
  "grid_rows": null,
42
+ "tile_count": 1,
43
+ "tile_layout": "auto",
44
+ "tile_rows": null,
45
+ "tile_columns": null,
46
+ "separate_z_parts": false,
47
+ "color_region_parts": 3,
39
48
  "first_layer_height": 0.1,
40
49
  "layer_height": 0.1,
41
50
  "base_white_layers": 2,
@@ -84,12 +93,21 @@ lithop image.png --config presets/fine.json
84
93
  | `crop_position_x` | `--crop-position-x FRACTION` | `0.5` | 左`0`から右`1`までの横位置 |
85
94
  | `crop_position_y` | `--crop-position-y FRACTION` | `0.5` | 上`0`から下`1`までの縦位置 |
86
95
  | `crop_scale` | `--crop-scale FRACTION` | `1.0` | 切り出し矩形または収容画像の倍率 |
96
+ | `brightness` | `--brightness PERCENT` | `0.0` | sRGB明るさ補正。`-100`〜`100` |
97
+ | `contrast` | `--contrast PERCENT` | `0.0` | sRGBコントラスト補正。`-100`〜`100` |
98
+ | `saturation` | `--saturation PERCENT` | `0.0` | sRGB彩度補正。`-100`〜`100` |
87
99
  | `minimum_thickness` | `--min-thickness MM` | `1.0` | 要求最小厚さmm |
88
100
  | `maximum_thickness` | `--max-thickness MM` | `2.14689422` | 要求最大厚さmm |
89
101
  | `pixel_size` | `--pixel-size MM` | `0.22` | XYセル寸法mm |
90
102
  | `color_pixel_size` | `--color-pixel-size MM` | `null` | `pixel_size`以上のCMYW色セル寸法。`null`は同じ寸法 |
91
- | `grid_columns` | なし | `591` | fit格子の列数。寸法または`pixel_size`指定時は未指定扱い |
92
- | `grid_rows` | なし | `455` | fit格子の行数。寸法または`pixel_size`指定時は未指定扱い |
103
+ | `grid_columns` | なし | `637` | fit格子の列数。寸法または`pixel_size`指定時は未指定扱い |
104
+ | `grid_rows` | なし | `473` | fit格子の行数。寸法または`pixel_size`指定時は未指定扱い |
105
+ | `tile_count` | `--tile-count COUNT` | `1` | 出力する3MFタイルの総数 |
106
+ | `tile_layout` | `--tile-layout MODE` | `auto` | `auto`、`columns`、`rows`、`grid` |
107
+ | `tile_rows` | `--tile-rows COUNT` | `null` | `grid`配置の行数 |
108
+ | `tile_columns` | `--tile-columns COUNT` | `null` | `grid`配置の列数 |
109
+ | `separate_z_parts` | `--separate-z-parts` | `false` | 下地White、CMYW色領域、上部WhiteをZ方向の別プレートにする |
110
+ | `color_region_parts` | `--color-region-parts COUNT` | `3` | Z分離時のCMYW色領域の分割数 |
93
111
  | `first_layer_height` | `--first-layer-height MM` | `0.1` | 下地Whiteの層高mm |
94
112
  | `layer_height` | `--layer-height MM` | `0.1` | CMYW色領域の積層ピッチmm |
95
113
  | `base_white_layers` | なし | `2` | 色領域より下のWhite層数 |
@@ -123,8 +141,12 @@ SVGでは、通常の厚さ格子と`color_pixel_size`を指定した色格子
123
141
 
124
142
  `image_fit=cover`は出力領域を満たして余分を切り出し、`contain`は画像全体を収めて残りをWhiteにします。`crop_position_x`と`crop_position_y`は、`cover`では切り出す位置、`contain`では画像を置く位置です。`crop_scale`を`1`より小さくすると、`cover`では拡大して狭い範囲を切り出し、`contain`では画像を縮小してWhite領域を増やします。
125
143
 
144
+ `brightness`、`contrast`、`saturation`はJPEG、PNG、SVGをsRGBへ正規化した後、格子へサンプリングする前にこの順で適用します。単位は百分率で、`0`は無補正です。明るさはRGB値へ加算し、コントラストは50%グレーを中心に、彩度はRec.601輝度を中心に調整します。`-100`はそれぞれ黒方向、コントラストなし、無彩色となり、`100`は既定量の2倍です。範囲外の値はクリップされます。同じ補正済み画像をWhite厚さとCMYW色選択で共有します。
145
+
126
146
  `color_pixel_size`を指定すると、White厚さは`pixel_size`の格子で保ったまま、各色セル内の厚さセルが同じCMYWレシピを使います。色セルはモデル原点から独立して区切り、端には部分セルを残します。未指定時は従来どおり厚さと色が同じ格子です。
127
147
 
148
+ タイル配置の選択、座標、Z分割のプレート構成、併用時の成果物は[3MFタイル分割とZ分割](tiling.md)を参照してください。
149
+
128
150
  標準では`null`を推奨します。140 × 104 mmの細線評価では、0.4 mm以上の色セルは色境界の段差と3MF三角形数を増やし、処理時間を短縮しませんでした。細線を含まない入力で個別にプレビューとBambu Studioのレイヤー表示を確認できる場合だけ、より大きい値を使用してください。
129
151
 
130
152
  ## 出力先
@@ -149,9 +171,14 @@ lithop images/page.png --project-dir output/book
149
171
  - 幅、高さ、厚さ、XYセル寸法、レイヤー高さが正の有限値ではない
150
172
  - `layout_profile`が`standard`ではない
151
173
  - `grid_columns`と`grid_rows`が同時に指定されていない、または正の整数ではない
174
+ - `tile_count`が1以上の整数ではない、配置名が不明、`grid`の行数 × 列数が総数と一致しない
175
+ - 行数または列数がXYセル数を超え、幅または高さが0セルになるタイルがある
176
+ - `separate_z_parts`が真偽値ではない、または`color_region_parts`が1〜`color_layer_count`の整数ではない
177
+ - Z分離時に上部Whiteの最小厚さが0になる
152
178
  - `color_pixel_size`が`null`でも`pixel_size`以上の正の有限値でもない
153
179
  - `image_fit`が`cover`または`contain`ではない
154
180
  - クロップ位置が0〜1の範囲外、または`crop_scale`が0より大きく1以下ではない
181
+ - 明るさ、コントラスト、彩度が`-100`〜`100`の有限値ではない
155
182
  - 要求最小厚さが要求最大厚さを超える
156
183
  - ノズル径が0.2または0.4ではない
157
184
  - 色モデルが`cmy`ではない
@@ -180,7 +207,7 @@ effective: 1.0–2.14689422 mm
180
207
 
181
208
  ## 校正片に使う設定
182
209
 
183
- `lithop calibrate`は、厚さ、ノズル、レイヤー高さ、色モデル、色領域の層数、顔料順、三角形数上限を設定から読みます。固定レイアウトのため、`width`、`height`、`margin_*`、画像配置、`pixel_size`、`color_pixel_size`、`maximum_input_pixels`は使いません。
210
+ `lithop calibrate`は、厚さ、ノズル、レイヤー高さ、色モデル、色領域の層数、顔料順、三角形数上限を設定から読みます。固定レイアウトで入力画像を使わないため、`width`、`height`、`margin_*`、画像配置、明るさ・コントラスト・彩度、`pixel_size`、`color_pixel_size`、`maximum_input_pixels`は使いません。
184
211
 
185
212
  現在の校正片は7層・`cyan,magenta,yellow`順と、White厚みを8段階取れる範囲を要求します。通常生成で使う`--calibration-profile`は入力設定キーではなくCLIオプションです。詳しくは[色校正](calibration.md)を参照してください。
186
213
 
@@ -13,15 +13,15 @@ Lithopは、画像からカラーLithophane(リトファン)の3MFとWhite
13
13
 
14
14
  ## インストール
15
15
 
16
- 公開版0.1.0を使う場合は、libvipsとバージョンを指定したLithopをインストールします。
16
+ 公開版0.2.0を使う場合は、libvipsとバージョンを指定したLithopをインストールします。
17
17
 
18
18
  ```sh
19
19
  brew install vips
20
- gem install lithop -v 0.1.0
20
+ gem install lithop -v 0.2.0
21
21
  lithop --version
22
22
  ```
23
23
 
24
- `lithop --version`が`0.1.0`を表示することを確認します。
24
+ `lithop --version`が`0.2.0`を表示することを確認します。
25
25
 
26
26
  ソースチェックアウトから実行する場合は、代わりに次を実行します。
27
27
 
@@ -87,6 +87,8 @@ SVGは正の`width`・`height`(単位なし、`px`、`mm`、`in`)または`v
87
87
 
88
88
  確認後、`lithop.3mf`をBambu Studioへモデルとして読み込みます。材料部品を個別に移動、整列、拡大縮小、結合しないでください。
89
89
 
90
+ タイル分割またはZ分割を使う場合は、[3MFタイル分割とZ分割](tiling.md)に従って各3MF、組み立て位置、Bambu Studioのプレートを確認してください。
91
+
90
92
  ## 生成物を削除する
91
93
 
92
94
  `lithop clean`は、選択したプロジェクトの`build/`全体を完全に削除します。個別ジョブの削除ではなく、元に戻せません。実行前に対象パスを確認してください。
data/docs/tiling.md ADDED
@@ -0,0 +1,132 @@
1
+ # 3MFタイル分割とZ分割
2
+
3
+ Lithopは、1枚では印刷できない大きさのリトファンを、指定枚数のCMYW 3MFへXY方向に分割できます。分割後も、完成時の幅・高さ、White厚み、CMYWレシピ、画像の向きは変わりません。必要なら各タイルを、CMYW色領域と上部Whiteの4プレートにZ方向へ分けられます。
4
+
5
+ このページでは、タイルの数と配置、出力座標、Bambu Studioで確認する対象を定義します。材料、積層構造、Z境界は[CMYWの色モデルと積層構造](color-model.md)、入力値の全一覧は[生成オプションと設定ファイル](config.md)を参照してください。
6
+
7
+ ## 使い分け
8
+
9
+ | 目的 | 設定 | 出力 |
10
+ | --- | --- | --- |
11
+ | 通常の1枚出力 | 既定値 | `lithop.3mf`を1つ。Bambu Studioでは1プレート |
12
+ | XY方向の分割 | `tile_count: 2`以上 | `tiles/tile_rNN_cNN.3mf`を指定枚数。各ファイルは1プレート |
13
+ | Z方向の分割 | `separate_z_parts: true` | 各3MFに、3つの`Color region`と`Top White`の4プレート |
14
+ | XYとZの併用 | 両方を指定 | タイルごとに4プレートを持つ3MF |
15
+
16
+ `cmyk_white.stl`、`preview.png`、`transmission.png`、`thickness.png`、材料マスクは、常に分割前の完成全体を表します。XY分割時だけカラー3MFは`tiles/`へ出力され、ルートに`lithop.3mf`は作りません。
17
+
18
+ ## XY方向のタイル分割
19
+
20
+ `--tile-count`で出力する3MFの総数を指定します。既定値は`1`です。
21
+
22
+ 4枚を自動的に、できるだけ正方形に近い行列へ配置します。
23
+
24
+ ```sh
25
+ lithop image.svg --tile-count 4 --tile-layout auto
26
+ ```
27
+
28
+ 横1行に6枚、または3行1列に並べる場合は、それぞれ次を使います。
29
+
30
+ ```sh
31
+ lithop image.svg --tile-count 6 --tile-layout columns
32
+ lithop image.svg --tile-count 3 --tile-layout rows
33
+ ```
34
+
35
+ 2行3列を明示する場合は、次のように行と列を指定します。
36
+
37
+ ```sh
38
+ lithop image.svg --tile-count 6 --tile-layout grid --tile-rows 2 --tile-columns 3
39
+ ```
40
+
41
+ | `tile_layout` | 行列の決め方 |
42
+ | --- | --- |
43
+ | `auto` | 指定枚数になる因数の組から、実寸法で最も正方形に近いタイルを選ぶ。同点では列数が多い配置を選ぶ |
44
+ | `columns` | 1行 × `tile_count`列 |
45
+ | `rows` | `tile_count`行 × 1列 |
46
+ | `grid` | `tile_rows` × `tile_columns`。積は必ず`tile_count`と一致させる |
47
+
48
+ JSON設定ファイルでは次のように指定します。
49
+
50
+ ```json
51
+ {
52
+ "layout_profile": "standard",
53
+ "tile_count": 6,
54
+ "tile_layout": "grid",
55
+ "tile_rows": 2,
56
+ "tile_columns": 3
57
+ }
58
+ ```
59
+
60
+ ### 分割の契約
61
+
62
+ 画像全体のWhite厚みとCMYW材料配置を先に決めてから、既存のXYセル境界で切り出します。分割境界が色セルを横切らないため、隣接タイルを組み立てた結果は、分割しない場合と同じ色・厚みになります。タイルごとに新しい外枠、重なり、隙間、位置合わせ用のダボは追加しません。
63
+
64
+ 各タイルはローカルXY座標へ移動し、左下を`(0, 0)`、底面を`Z=0`にします。回転・拡縮は行いません。タイルIDは鑑賞面から見た左上を`tile_r01_c01`とし、左から右、次に上から下の順です。`tile_rNN_cNN.3mf`の`NN`はこの行列番号です。
65
+
66
+ 幅または高さのセル数が行数・列数で割り切れない場合でも、セルを切りません。そのため、タイル寸法には最大1セルの差が生じます。各タイルには少なくとも1つのXYセルが必要で、行数または列数がセル数を超える設定はエラーになります。
67
+
68
+ ### 成果物と組み立て位置
69
+
70
+ タイルジョブは`tile-layout.svg`を追加します。これは完成寸法と同じ物理サイズの配置図で、各タイルIDと幅・高さを示します。`manifest.json`には次の情報を保存します。
71
+
72
+ - `tile_layout`: 要求した配置、解決後の行数・列数、IDの順序、ローカル原点、画像上端の向き
73
+ - `tiles`: 各タイルのID、3MFファイル名、行・列、完成全体での`offset_mm`、`bounds_mm`、寸法、材料、三角形数
74
+
75
+ 複数のタイルを1つの完成物として配置する場合は、各3MFの材料部品を動かさず、対応する`offset_mm`を使ってタイル全体を配置します。`tile-layout.svg`と`manifest.json`は、その配置を復元するための正本です。
76
+
77
+ ## Z方向の4プレート分割
78
+
79
+ `--separate-z-parts`を指定すると、各3MFのZ方向を複数のBambu Studioプレートへ分けます。
80
+
81
+ ```sh
82
+ lithop image.svg --separate-z-parts
83
+ ```
84
+
85
+ 標準の7層CMYW色領域と既定の`--color-region-parts 3`では、Bambu Studioで次の4プレートを開きます。
86
+
87
+ | プレート | 元のZ範囲 | 内容 |
88
+ | --- | --- | --- |
89
+ | `Color region 1` | 0.2–0.5 mm | 3層のCMYW色領域と0.0–0.2 mmのBase Whiteキャリア |
90
+ | `Color region 2` | 0.5–0.7 mm | 2層のCMYW色領域とBase Whiteキャリア |
91
+ | `Color region 3` | 0.7–0.9 mm | 2層のCMYW色領域とBase Whiteキャリア |
92
+ | `Top White` | 0.9 mm–可変上面 | 色領域より上のWhite |
93
+
94
+ 各プレートは単独印刷できるよう、出力3MFでは底面が`Z=0`になります。Base Whiteだけのプレートは作りません。Base Whiteキャリアは各`Color region`に含まれ、使用されるCyan、Magenta、Yellowの閉じた部品と同じ領域を支えます。未使用の顔料部品は省略されますが、Extruder番号はCyan=1、Magenta=2、Yellow=3、White=4のままです。
95
+
96
+ `color_region_parts`は1から色層数まで指定できます。既定の3は7層を3・2・2層に分けます。値を変えると領域数と各領域のZ境界が変わるため、印刷前に生成ジョブの`manifest.json`にある`color_model.z_part_separation.plates`を確認してください。この記録には、元のZ境界、各プレートでの印刷厚み、積層順、部品名が入ります。
97
+
98
+ 分離したZ部品を印刷後に組み立てる場合は、`Color region 1`から`Top White`まで、マニフェストの積層順どおりに同じXY位置で重ねます。各プレート内の部品を移動、整列、拡大縮小、結合してはいけません。
99
+
100
+ ## XY分割とZ分割を併用する
101
+
102
+ 次の例は、完成全体を横2枚へ分け、各タイルを4プレートにします。
103
+
104
+ ```sh
105
+ lithop image.svg --tile-count 2 --tile-layout columns --separate-z-parts
106
+ ```
107
+
108
+ 出力は次の構造になります。
109
+
110
+ ```text
111
+ build/<job_id>/
112
+ ├── cmyk_white.stl
113
+ ├── tile-layout.svg
114
+ ├── tiles/
115
+ │ ├── tile_r01_c01.3mf # Color region 1–3、Top Whiteの4プレート
116
+ │ └── tile_r01_c02.3mf # Color region 1–3、Top Whiteの4プレート
117
+ ├── manifest.json
118
+ ├── settings.json
119
+ └── preview.png ほか
120
+ ```
121
+
122
+ タイルのXY組み立て情報とZ方向の積層情報は別の契約です。XY方向は各タイルの`offset_mm`、Z方向は各タイルの`color_model.z_part_separation.plates`を使います。Bambu Studioへ読み込んだ後は、同一タイル内の材料部品を移動、整列、拡大縮小、結合しないでください。
123
+
124
+ ## 印刷前の確認
125
+
126
+ 1. `preview.png`、`thickness.png`、4枚の材料マスクで、分割前の色・厚みが意図どおりか確認する。
127
+ 2. XY分割時は`tile-layout.svg`と`manifest.json`で、枚数、ID、完成全体での位置、タイル寸法を確認する。
128
+ 3. 各タイル3MFをBambu Studioで開き、Cyan=1、Magenta=2、Yellow=3、White=4の材料割り当てを確認する。
129
+ 4. Z分割時は4プレートと各`Color region`・`Top White`の部品を確認し、`manifest.json`のZ境界と積層順に合わせる。
130
+ 5. すべてのレイヤーを確認してからスライスする。Lithopはスライス、造形可否の判定、印刷開始を行わない。
131
+
132
+ 分割した実機での継ぎ目の位置ずれ、色差、光漏れはまだ評価対象です。小さい入力と少数タイルで、Bambu Studioのレイヤープレビューを確認してから完成寸法へ進めてください。
@@ -35,6 +35,8 @@ bundle exec lithop --version
35
35
 
36
36
  **最初の確認:** `cmyk_white.stl`ではなく`lithop.3mf`を開き、一つの親オブジェクトの下に材料部品があるか確認します。
37
37
 
38
+ 分割ジョブでは`lithop.3mf`の代わりに`tiles/tile_rNN_cNN.3mf`を開きます。各ファイル内の材料部品は同じローカル座標を共有し、全体の位置は`tile-layout.svg`と`manifest.json`で確認します。
39
+
38
40
  **原因候補:** White参照STLを開いた、部品を結合・修復・自動整列した、材料割り当てを変更した可能性があります。未使用顔料の省略は正常です。
39
41
 
40
42
  **対処:** 3MFを読み直し、部品を動かさず、Cyan=1、Magenta=2、Yellow=3、White=4を確認します。省略された番号は詰めません。
@@ -95,6 +97,16 @@ bundle exec lithop image.png --width 20 --height 15 --pixel-size 0.5
95
97
 
96
98
  **関連:** [生成物を削除する](command.md#生成物を削除する)
97
99
 
100
+ ## `another conversion is already running`と表示される
101
+
102
+ **最初の確認:** 同じプロジェクトを指定した別の`lithop`または`lithop calibrate`が実行中か確認します。
103
+
104
+ **原因候補:** プロジェクト単位の同時変換数は1です。通常生成と校正生成は同じ排他ロックを使います。
105
+
106
+ **対処:** 実行中の変換が完了または中止してから再実行します。プロセスが異常終了した場合もOSが排他ロックを解放し、次回の変換が所有情報付き一時データを回収します。`.lithop.lock`ファイルの存在だけでは実行中を意味しないため、手動で削除する必要はありません。
107
+
108
+ **関連:** [ジョブディレクトリ](artifacts.md#ジョブディレクトリ)
109
+
98
110
  ## 不具合を報告する
99
111
 
100
112
  **最初の確認:** 入力画像、ローカルパス、ハッシュを公開してよいか判断します。公開できない画像は添付しないでください。
@@ -10,34 +10,47 @@ module Lithop
10
10
  class Export
11
11
  Result = Data.define(:job_id, :path, :files, :triangle_count, :patch_count)
12
12
 
13
- def initialize(settings:, project_dir:, clock: Time, random: SecureRandom)
13
+ def initialize(
14
+ settings:, project_dir:, job_progress: nil, clock: Time, random: SecureRandom, job_id: nil
15
+ )
14
16
  @settings = settings
15
17
  @project_dir = File.expand_path(project_dir)
16
18
  @clock = clock
17
19
  @random = random
20
+ @job_progress = job_progress
21
+ @job_id = job_id
18
22
  end
19
23
 
20
24
  def call
21
- job_id = "#{@clock.now.utc.strftime("%Y%m%dT%H%M%SZ")}-#{@random.hex(4)}-calibration"
22
- destination, generated = JobDirectory.new(project_dir: @project_dir, job_id:).call do |directory|
23
- generate(directory, job_id)
25
+ job_id = @job_id || "#{@clock.now.utc.strftime("%Y%m%dT%H%M%SZ")}-#{@random.hex(4)}-calibration"
26
+ execution = JobExecution.new(
27
+ project_dir: @project_dir, job_id:, progress: @job_progress, clock: @clock
28
+ )
29
+ execution.call do |job|
30
+ destination, generated = JobDirectory.new(project_dir: @project_dir, job_id:).call do |directory|
31
+ generate(directory, job_id, job)
32
+ end
33
+ job.progress(phase: :publishing, percent: 99, message: "Calibration artifacts published")
34
+ Result.new(job_id:, path: destination, files: generated.fetch(:files),
35
+ triangle_count: generated.fetch(:triangle_count), patch_count: generated.fetch(:patch_count))
24
36
  end
25
- Result.new(job_id:, path: destination, files: generated.fetch(:files),
26
- triangle_count: generated.fetch(:triangle_count), patch_count: generated.fetch(:patch_count))
27
37
  end
28
38
 
29
39
  private
30
40
 
31
- def generate(directory, job_id)
41
+ def generate(directory, job_id, job)
42
+ job.progress(phase: :calibration_planning, percent: 10, message: "Planning calibration target")
32
43
  target = Target.new(settings: @settings)
44
+ job.progress(phase: :three_mf_write, percent: 35, message: "Writing calibration 3MF")
33
45
  result = write_three_mf(File.join(directory, "calibration.3mf"), target)
46
+ job.progress(phase: :supporting_files, percent: 80, message: "Writing calibration files")
34
47
  TargetSVG.write(File.join(directory, "calibration.svg"), target)
35
48
  profile = Profile.template(profile_id: job_id, settings: @settings, target:)
36
49
  profile.write(File.join(directory, "calibration-profile.json"))
37
50
  write_manifest(directory, job_id, target, result)
38
51
  write_readme(directory, target)
39
52
  {
40
- files: Dir.children(directory).sort,
53
+ files: Dir.children(directory).reject { |name| name == JobDirectory::OWNER_FILE }.sort,
41
54
  triangle_count: result.triangle_count,
42
55
  patch_count: target.patches.length
43
56
  }
@@ -17,7 +17,9 @@ module Lithop
17
17
  raise OptionParser::InvalidArgument, arguments.join(" ") unless arguments.empty?
18
18
 
19
19
  project_dir, settings, = load_settings(options, keys: CALIBRATION_SETTING_KEYS)
20
- result = Calibration::Export.new(settings:, project_dir:).call
20
+ result = Calibration::Export.new(
21
+ settings:, project_dir:, job_progress: method(:report_job_progress)
22
+ ).call
21
23
  @out.puts "Generated #{result.patch_count} calibration patches and #{result.triangle_count} 3MF triangles"
22
24
  @out.puts "in #{result.path}"
23
25
  result.files.each { |file| @out.puts " #{file}" }