生成无重叠的 0.2 mm Xynova 笔画图案
在打印页毫米坐标中筛选候选笔画,更新双 UV 产物。38 项测试通过;SVG 检查无交叠。
This commit is contained in:
@@ -598,7 +598,7 @@ def cmd_stroke_texture(revision_dir: Path, args: argparse.Namespace) -> int:
|
||||
"source_blend": {"path": str(paths.source_blend),
|
||||
"sha256": sha256_file(paths.source_blend)},
|
||||
# The v1 keys stay for compatibility; `resolved` carries what the block and the flag
|
||||
# overrides actually produced, because with ten knobs the flags alone no longer
|
||||
# overrides actually produced, because the flags alone no longer
|
||||
# describe the run. The design.yaml and params hashes pin the tuning either way.
|
||||
"settings": {
|
||||
"mode": STROKE_MODE,
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
The stroke generator is one mode, ``camera_compensated_width``: each source colour of the colour
|
||||
artwork is one cell, and the mark inside it is a capsule whose width is scaled from that cell's
|
||||
footprint on the print page — so a cell the projection stretches gets a proportionally larger
|
||||
mark — then clamped. That gives ten live knobs, and this module owns their names, defaults and
|
||||
mark — then clamped. This module owns the live knobs, their defaults and
|
||||
ranges on the host side.
|
||||
|
||||
Why the keys are exactly these
|
||||
@@ -45,12 +45,14 @@ STROKE_DEFAULTS: dict[str, Any] = {
|
||||
"length_ratio": 2.4,
|
||||
"coverage_cap": 0.45,
|
||||
"neighbourhood_mm": 0.5,
|
||||
"clearance_mm": 0.0,
|
||||
"candidate_count": 1,
|
||||
}
|
||||
|
||||
STROKE_KEYS = frozenset(STROKE_DEFAULTS)
|
||||
|
||||
#: Integer-valued keys, validated as ints so a fractional seed cannot reach the palette lookup.
|
||||
STROKE_INT_KEYS = frozenset({"seed", "min_cell_pixels"})
|
||||
STROKE_INT_KEYS = frozenset({"seed", "min_cell_pixels", "candidate_count"})
|
||||
|
||||
STROKE_PARAMS_FILENAME = "_stroke_pattern_params.json"
|
||||
|
||||
@@ -93,6 +95,10 @@ def validate_stroke_block(block: Any) -> list[str]:
|
||||
|
||||
if "min_cell_pixels" in block and block["min_cell_pixels"] < 1:
|
||||
errors.append(f"{where}.min_cell_pixels: must be >= 1 (got {block['min_cell_pixels']!r})")
|
||||
if "candidate_count" in block and block["candidate_count"] < 1:
|
||||
errors.append(f"{where}.candidate_count: must be >= 1 (got {block['candidate_count']!r})")
|
||||
if "clearance_mm" in block and block["clearance_mm"] < 0:
|
||||
errors.append(f"{where}.clearance_mm: must be >= 0 (got {block['clearance_mm']!r})")
|
||||
if "jitter_fraction" in block and not 0.0 <= block["jitter_fraction"] <= 1.0:
|
||||
errors.append(
|
||||
f"{where}.jitter_fraction: must be within [0, 1] (got {block['jitter_fraction']!r})"
|
||||
|
||||
Reference in New Issue
Block a user