initial version of random angle strokes
This commit is contained in:
@@ -4,6 +4,7 @@ from __future__ import annotations
|
||||
|
||||
import argparse
|
||||
import json
|
||||
import math
|
||||
import os
|
||||
import shutil
|
||||
import subprocess
|
||||
@@ -177,6 +178,8 @@ def _run_blender_script(script: str, blend: Path, extra_args: list[str]) -> int:
|
||||
str(blender),
|
||||
"-b",
|
||||
str(blend),
|
||||
"--python-exit-code",
|
||||
"1",
|
||||
"-P",
|
||||
str(script_path),
|
||||
"--",
|
||||
@@ -467,6 +470,77 @@ def cmd_texture(revision_dir: Path, args: argparse.Namespace) -> int:
|
||||
return 0
|
||||
|
||||
|
||||
def cmd_binary_preview(revision_dir: Path, args: argparse.Namespace) -> int:
|
||||
"""Convert existing colour textures to a bounded binary camera-footprint trial."""
|
||||
root = repo_root(revision_dir)
|
||||
paths = RevisionPaths.from_revision_dir(revision_dir)
|
||||
errors = validate_revision_metadata(paths)
|
||||
if errors:
|
||||
for message in errors:
|
||||
print(f"ERROR: {message}", file=sys.stderr)
|
||||
return 1
|
||||
|
||||
if not math.isfinite(args.camera_width_fraction) or args.camera_width_fraction <= 0:
|
||||
print("ERROR: --camera-width-fraction must be finite and positive", file=sys.stderr)
|
||||
return 2
|
||||
texture_dir = resolve_texture_output_dir(root, paths, None)
|
||||
job_name = "_texture_views_job.json" if args.views else "_texture_job.json"
|
||||
job_path = (args.source_job or texture_dir / job_name).resolve()
|
||||
if not job_path.is_file():
|
||||
print(f"ERROR: colour texture job missing: {job_path}", file=sys.stderr)
|
||||
return 3
|
||||
try:
|
||||
job = json.loads(job_path.read_text(encoding="utf-8"))
|
||||
expected_schema = (
|
||||
"orisys-sensor-design/texture-job-multiview-v1"
|
||||
if args.views else "orisys-sensor-design/texture-job-v3"
|
||||
)
|
||||
if job.get("schema") != expected_schema:
|
||||
raise ValueError(f"expected {expected_schema}, got {job.get('schema')!r}")
|
||||
if Path(job["revision_dir"]).resolve() != paths.root.resolve():
|
||||
raise ValueError("source job belongs to a different revision")
|
||||
if Path(job["source_blend"]).resolve() != paths.source_blend.resolve():
|
||||
raise ValueError("source job was built from a different Blender scene")
|
||||
entries = job["pairs" if args.views else "outputs"]
|
||||
source_ids = [str(entry["id" if args.views else "uv_map"]) for entry in entries]
|
||||
if (not source_ids or len(source_ids) != len(set(source_ids))
|
||||
or any(not source_id or not all(
|
||||
char.isalnum() or char in "_-" for char in source_id
|
||||
) for source_id in source_ids)):
|
||||
raise ValueError("source job needs distinct, filename-safe output IDs")
|
||||
except (OSError, ValueError, KeyError, TypeError) as exc:
|
||||
print(f"ERROR: invalid colour texture job {job_path}: {exc}", file=sys.stderr)
|
||||
return 2
|
||||
|
||||
output_dir = (args.output_dir or job_path.parent / "binary-preview").resolve()
|
||||
targets = [output_dir / f"{source_id}_camera_compensated_width.png"
|
||||
for source_id in source_ids]
|
||||
if any(path.exists() for path in targets):
|
||||
print("ERROR: binary preview target already exists; choose a fresh --output-dir",
|
||||
file=sys.stderr)
|
||||
return 2
|
||||
code = _run_blender_script(
|
||||
"binary_pattern_from_color.py", paths.source_blend,
|
||||
["--job", str(job_path), "--output-dir", str(output_dir),
|
||||
"--modes", "camera_compensated_width",
|
||||
"--camera-width-fraction", str(args.camera_width_fraction)],
|
||||
)
|
||||
if code != 0:
|
||||
return code
|
||||
missing = [path for path in targets if not path.is_file() or path.stat().st_size == 0]
|
||||
if missing:
|
||||
for path in missing:
|
||||
print(f"ERROR: binary preview missing or empty: {path}", file=sys.stderr)
|
||||
return 3
|
||||
if console.get_level() == console.QUIET:
|
||||
console.artifact_paths(targets)
|
||||
else:
|
||||
console.report(f"OK: {len(targets)} binary preview PNG(s) in {output_dir}")
|
||||
for path in targets:
|
||||
console.report(f" {path}")
|
||||
return 0
|
||||
|
||||
|
||||
def cmd_texture_views(revision_dir: Path, args: argparse.Namespace) -> int:
|
||||
"""Generate one owned texture per production view.
|
||||
|
||||
@@ -1357,7 +1431,6 @@ def _run_track_stage(
|
||||
|
||||
def cmd_deform(revision_dir: Path, args: argparse.Namespace) -> int:
|
||||
"""Deform the sensing surface through the declared x/y/z sweep."""
|
||||
root = repo_root(revision_dir)
|
||||
paths = RevisionPaths.from_revision_dir(revision_dir)
|
||||
errors = validate_revision_metadata(paths)
|
||||
if errors:
|
||||
@@ -1374,7 +1447,6 @@ def cmd_deform(revision_dir: Path, args: argparse.Namespace) -> int:
|
||||
|
||||
def cmd_render(revision_dir: Path, args: argparse.Namespace) -> int:
|
||||
"""Render what the sensor camera sees for every deformed frame."""
|
||||
root = repo_root(revision_dir)
|
||||
paths = RevisionPaths.from_revision_dir(revision_dir)
|
||||
errors = validate_revision_metadata(paths)
|
||||
if errors:
|
||||
@@ -1392,7 +1464,6 @@ def cmd_render(revision_dir: Path, args: argparse.Namespace) -> int:
|
||||
|
||||
def cmd_track(revision_dir: Path, args: argparse.Namespace) -> int:
|
||||
"""Estimate DIS optical flow against the zero-displacement reference."""
|
||||
root = repo_root(revision_dir)
|
||||
paths = RevisionPaths.from_revision_dir(revision_dir)
|
||||
errors = validate_revision_metadata(paths)
|
||||
if errors:
|
||||
@@ -1426,7 +1497,6 @@ def cmd_track(revision_dir: Path, args: argparse.Namespace) -> int:
|
||||
|
||||
def cmd_sensitivity(revision_dir: Path, args: argparse.Namespace) -> int:
|
||||
"""Run the probe bench end to end and write the sensitivity report."""
|
||||
root = repo_root(revision_dir)
|
||||
paths = RevisionPaths.from_revision_dir(revision_dir)
|
||||
errors = validate_revision_metadata(paths)
|
||||
if errors:
|
||||
@@ -1490,7 +1560,6 @@ def cmd_sensitivity(revision_dir: Path, args: argparse.Namespace) -> int:
|
||||
|
||||
def cmd_optimise(revision_dir: Path, args: argparse.Namespace) -> int:
|
||||
"""Search patch-pattern parameters for the best measured sensitivity."""
|
||||
root = repo_root(revision_dir)
|
||||
paths = RevisionPaths.from_revision_dir(revision_dir)
|
||||
errors = validate_revision_metadata(paths)
|
||||
if errors:
|
||||
@@ -1740,7 +1809,6 @@ def _compare_stage_runner(paths, args):
|
||||
|
||||
def cmd_compare(revision_dir: Path, args: argparse.Namespace) -> int:
|
||||
"""Run one pattern under several estimator settings and plot the comparison."""
|
||||
root = repo_root(revision_dir)
|
||||
paths = RevisionPaths.from_revision_dir(revision_dir)
|
||||
errors = validate_revision_metadata(paths)
|
||||
if errors:
|
||||
@@ -2112,6 +2180,28 @@ def main(argv: list[str] | None = None) -> None:
|
||||
),
|
||||
)
|
||||
|
||||
binary_p = sub.add_parser(
|
||||
"binary-preview",
|
||||
help="Make bounded black/white PNG trials from existing colour textures",
|
||||
)
|
||||
binary_p.add_argument("revision_dir", type=Path)
|
||||
binary_p.add_argument(
|
||||
"--views", action="store_true",
|
||||
help="Read the texture-views job instead of the single-UV texture job",
|
||||
)
|
||||
binary_p.add_argument(
|
||||
"--source-job", type=Path, default=None,
|
||||
help="Existing colour texture job (default: revision build/textures job)",
|
||||
)
|
||||
binary_p.add_argument(
|
||||
"--output-dir", type=Path, default=None,
|
||||
help="Fresh output directory (default: binary-preview beside the colour job)",
|
||||
)
|
||||
binary_p.add_argument(
|
||||
"--camera-width-fraction", type=float, default=0.5,
|
||||
help="Stroke width / projected camera-cell span (default: 0.5; width 0.11–0.28 mm)",
|
||||
)
|
||||
|
||||
manifest_p = sub.add_parser("manifest", help="Write release manifest with file hashes")
|
||||
manifest_p.add_argument("revision_dir", type=Path)
|
||||
manifest_p.add_argument(
|
||||
@@ -2505,6 +2595,8 @@ def main(argv: list[str] | None = None) -> None:
|
||||
code = cmd_texture(args.revision_dir, args)
|
||||
elif args.command == "texture-views":
|
||||
code = cmd_texture_views(args.revision_dir, args)
|
||||
elif args.command == "binary-preview":
|
||||
code = cmd_binary_preview(args.revision_dir, args)
|
||||
elif args.command == "inspect":
|
||||
code = cmd_inspect(args.revision_dir, args)
|
||||
elif args.command == "preview":
|
||||
|
||||
Reference in New Issue
Block a user