passages: floor profile by nearest centreline + metric distance outside voids (L114, v222) - WIP
Floor ribs are present in L109/L112/L113 rock tunnels too: the floor height comes from the nearest segment, so it jumps (up to 5.9-7.3 cm) where the nearest segment switches. v222 reduces them; faint ribs remain. Quiet-machine timing (load 0.64): near-ready 9-17% slower than L109 (FI W12 0.95 -> 1.10 s); candidate totals ~5x L109. Fast tier FAIL: 2 SW wall-shell probes of 31,381 read host air. Walk/grade audits pass; Clang/GCC deterministic; UE builds. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016dhxM43dnWvUu2B5Ph1iG1
This commit is contained in:
1 parent
36d954cf2f
commit
5e875ae504
45 files changed
+3081
-53
No files matched your search
@@ -0,0 +1,252 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Copy verified L113 wall views and capture L113/L114 rock floors plus L114 walls."""
|
||||
from __future__ import annotations
|
||||
|
||||
import hashlib
|
||||
import importlib.util
|
||||
import json
|
||||
import math
|
||||
import re
|
||||
import shutil
|
||||
import subprocess
|
||||
import sys
|
||||
from pathlib import Path
|
||||
|
||||
ROOT = Path(__file__).resolve().parents[4]
|
||||
RESEARCH = Path(__file__).resolve().parent
|
||||
CAPTURES = RESEARCH / "captures"
|
||||
SAVED = ROOT / "Saved/Linux/l114/captures"
|
||||
L113_RESEARCH = ROOT / "Standalone/Research/WorldAssemblerM3/Linux113"
|
||||
L113_SAVED = ROOT / "Saved/Linux/l113"
|
||||
L114_SAVED = ROOT / "Saved/Linux/l114"
|
||||
sys.dont_write_bytecode = True
|
||||
SPEC = importlib.util.spec_from_file_location(
|
||||
"l113_capture_helpers", L113_RESEARCH / "RunL113Captures.py")
|
||||
if SPEC is None or SPEC.loader is None:
|
||||
raise SystemExit("cannot load the verified L113 capture helpers")
|
||||
HELPERS = importlib.util.module_from_spec(SPEC)
|
||||
SPEC.loader.exec_module(HELPERS)
|
||||
HELPERS.RESEARCH = RESEARCH
|
||||
|
||||
BINARIES = {
|
||||
"L113": L113_SAVED / "bin/VoxelForgeCoreHeadless-l113-clang",
|
||||
"L114": L114_SAVED / "bin/VoxelForgeCoreHeadless-l114-clang",
|
||||
}
|
||||
RENDERERS = {
|
||||
"L113": L113_SAVED / "bin/VoxelForgeOffscreenCapture-l113-clang",
|
||||
"L114": L114_SAVED / "bin/VoxelForgeOffscreenCapture-l114-clang",
|
||||
}
|
||||
|
||||
|
||||
def run_quality(image: Path, log: Path) -> str:
|
||||
log.parent.mkdir(parents=True, exist_ok=True)
|
||||
command = ["taskset", "-c", "0-11", "prlimit", "--as=6442450944", "--",
|
||||
"timeout", "1740s", "python3", "-B",
|
||||
str(ROOT / "Standalone/Tools/verify/capture_quality.py"), str(image)]
|
||||
with log.open("w", encoding="utf-8") as stream:
|
||||
result = subprocess.run(command, cwd=ROOT, stdout=stream,
|
||||
stderr=subprocess.STDOUT, check=False, timeout=1740)
|
||||
output = log.read_text(encoding="utf-8", errors="replace")
|
||||
# L113 already admitted low-contrast views when geometry covered at least
|
||||
# 0.1% of pixels; use the same visibility rule for its copied references.
|
||||
# The caller still rejects decode failures because they have no metrics.
|
||||
if result.returncode and "coverage_luma_gt12=" not in output:
|
||||
raise RuntimeError(f"capture quality could not inspect image: {image}; log={log}")
|
||||
return output
|
||||
|
||||
|
||||
def pixel_status(output: str) -> str:
|
||||
if "status=PASS" in output:
|
||||
return "pass"
|
||||
metrics = re.search(r"coverage_luma_gt12=([\d.]+)", output)
|
||||
if metrics and float(metrics.group(1)) >= 0.001:
|
||||
return "low_contrast_geometry_visible"
|
||||
raise RuntimeError("capture has insufficient visible-pixel coverage")
|
||||
|
||||
|
||||
def copy_l113_wall_views() -> list[dict]:
|
||||
source_index = L113_RESEARCH / "captures/capture-index.json"
|
||||
if not source_index.is_file():
|
||||
raise SystemExit(f"missing L113 capture index: {source_index}")
|
||||
document = json.loads(source_index.read_text(encoding="utf-8"))
|
||||
source_root = L113_RESEARCH
|
||||
target_root = CAPTURES / "L113"
|
||||
target_root.mkdir(parents=True, exist_ok=True)
|
||||
rows = []
|
||||
for source_row in document.get("captures", []):
|
||||
if source_row.get("variant") != "after" or source_row.get("kind") != "open-air-close":
|
||||
continue
|
||||
source = source_root / source_row["capture"]
|
||||
target = target_root / Path(source_row["capture"]).name
|
||||
shutil.copy2(source, target)
|
||||
source_hash = hashlib.sha256(source.read_bytes()).hexdigest()
|
||||
target_hash = hashlib.sha256(target.read_bytes()).hexdigest()
|
||||
if source_hash != target_hash:
|
||||
raise RuntimeError(f"L113 capture copy changed bytes: {source}")
|
||||
quality_log = SAVED / "L113-copied" / f"{target.stem}-quality.log"
|
||||
quality = run_quality(target, quality_log)
|
||||
row = dict(source_row)
|
||||
row.update({"variant": "L113", "capture": str(target.relative_to(RESEARCH)),
|
||||
"source_capture": str(source.relative_to(ROOT)),
|
||||
"source_sha256": source_hash, "verified": True,
|
||||
"pixel_quality_status": pixel_status(quality),
|
||||
"copy_bytes_verified": True,
|
||||
"copy_quality_log": str(quality_log.relative_to(ROOT))})
|
||||
if (row.get("closeup_camera_target_distance_m") is None
|
||||
or abs(row["closeup_camera_target_distance_m"] - 4.0) > 0.02
|
||||
or row.get("closeup_target_surface_distance_m", 99.0) > 5.0
|
||||
or row.get("closeup_wall_normal_alignment", -1.0) < 0.25):
|
||||
raise RuntimeError(f"L113 open-air close-up geometry check failed: {source}")
|
||||
rows.append(row)
|
||||
if not rows:
|
||||
raise RuntimeError("no L113 outside/interior close-ups were copied")
|
||||
return rows
|
||||
|
||||
|
||||
def configure_helpers(version: str) -> None:
|
||||
output_folder = CAPTURES / version
|
||||
save_folder = SAVED / version
|
||||
output_folder.mkdir(parents=True, exist_ok=True)
|
||||
save_folder.mkdir(parents=True, exist_ok=True)
|
||||
HELPERS.CAPTURES = output_folder
|
||||
HELPERS.SAVED = save_folder
|
||||
HELPERS.BINARIES = {"after": BINARIES[version]}
|
||||
HELPERS.RENDERERS = {"after": RENDERERS[version]}
|
||||
HELPERS.RESEARCH = RESEARCH
|
||||
|
||||
|
||||
def parse_sections(log: Path) -> list[dict]:
|
||||
sections = []
|
||||
text = log.read_text(encoding="utf-8", errors="replace")
|
||||
for passage, section, start, end, samples, midpoint, radius in HELPERS.SECTION.findall(text):
|
||||
sections.append({"passage": passage, "section": int(section),
|
||||
"start_m": float(start), "end_m": float(end),
|
||||
"samples": int(samples), "midpoint": HELPERS.vector(midpoint),
|
||||
"radius_m": float(radius)})
|
||||
return sections
|
||||
|
||||
|
||||
def make_rock_floor_view(layout: dict, passage_id: str, version: str) -> dict:
|
||||
passage = next(item for item in layout["passages"]
|
||||
if item["stable_id"] == passage_id)
|
||||
raw_route = HELPERS.smooth_route(layout, passage)
|
||||
route, body_depth = HELPERS.derived_smooth_route(raw_route, passage, layout)
|
||||
lengths, prefix = HELPERS.route_lengths(route)
|
||||
station = prefix[-1] * 0.5
|
||||
center, radius = HELPERS.at_distance(route, lengths, prefix, station)
|
||||
floor_depth = min(body_depth, max(0.0, radius - 0.23))
|
||||
planned_floor = (center[0], center[1], center[2] - floor_depth)
|
||||
tangent = HELPERS.tangent_at(route, lengths, prefix, station)
|
||||
grade_deg = math.degrees(math.atan2(abs(tangent[2]),
|
||||
math.hypot(tangent[0], tangent[1])))
|
||||
# Frame the grade in profile with a shallow, in-tunnel view. The close
|
||||
# overhead angle hid the floor in a nearly uniform patch of rock.
|
||||
camera = tuple(planned_floor[axis] - 2.5 * tangent[axis]
|
||||
+ (1.25 if axis == 2 else 0.0) for axis in range(3))
|
||||
yaw, pitch = HELPERS.angles(camera, planned_floor)
|
||||
safe_id = HELPERS.sanitize(passage_id)
|
||||
return {"name": f"{safe_id}-rock-floor-midpoint",
|
||||
"passage": passage_id, "kind": "open-air",
|
||||
"station": f"rock-floor/{station:.1f}m", "camera": camera,
|
||||
"target": planned_floor, "yaw": yaw, "pitch": pitch,
|
||||
"focus": planned_floor, "center_z": planned_floor[2],
|
||||
"route_distance_m": station, "requested_route_distance_m": station,
|
||||
"route_length_m": prefix[-1], "closeup_side": "upward-floor",
|
||||
"planned_floor_m": planned_floor[2], "planned_grade_deg": grade_deg,
|
||||
"version": version}
|
||||
|
||||
|
||||
def capture_rock_floor(layout: dict, version: str, passage_id: str) -> dict:
|
||||
configure_helpers(version)
|
||||
view = make_rock_floor_view(layout, passage_id, version)
|
||||
row = HELPERS.capture("after", view, layout)
|
||||
scene = ROOT / row["scene"]
|
||||
floor_anchor = HELPERS.nearest_surface_anchor(scene, view["target"], margin_m=5.0,
|
||||
preferred_normal=(0.0, 0.0, 1.0), minimum_alignment=0.85)
|
||||
floor_normal_alignment = HELPERS.dot(floor_anchor["normal"], (0.0, 0.0, 1.0))
|
||||
camera_to_floor = math.dist(row["camera_actual_m"], floor_anchor["position_m"])
|
||||
camera_to_target = math.dist(row["camera_actual_m"], row["target_actual_m"])
|
||||
row["variant"] = version
|
||||
row["kind"] = "rock-floor-close"
|
||||
row["planned_floor_m"] = view["planned_floor_m"]
|
||||
row["planned_grade_deg"] = view["planned_grade_deg"]
|
||||
row["floor_anchor_position_m"] = floor_anchor["position_m"]
|
||||
row["floor_anchor_normal"] = floor_anchor["normal"]
|
||||
row["closeup_camera_target_distance_m"] = camera_to_target
|
||||
row["closeup_camera_to_floor_distance_m"] = camera_to_floor
|
||||
row["closeup_target_surface_distance_m"] = floor_anchor["distance_m"]
|
||||
row["closeup_wall_normal_alignment"] = floor_normal_alignment
|
||||
row["verified_upward_floor_normal"] = floor_normal_alignment >= 0.85
|
||||
if (not row["verified"]
|
||||
or not 2.0 <= camera_to_floor <= 3.2
|
||||
or row["closeup_target_surface_distance_m"] > 0.25
|
||||
or not row["verified_upward_floor_normal"]
|
||||
or row["planned_grade_deg"] < 2.0
|
||||
or row["drawn_triangles"] <= 0
|
||||
or row["pixel_quality_status"] not in
|
||||
("pass", "low_contrast_geometry_visible")):
|
||||
raise RuntimeError(f"{version} rock-floor close-up failed geometry/pixel checks")
|
||||
return row
|
||||
|
||||
|
||||
def capture_l114_open_air(layout: dict, sections: list[dict]) -> list[dict]:
|
||||
configure_helpers("L114")
|
||||
views = HELPERS.make_views(layout, sections, use_derived_shape=True,
|
||||
use_spline=True, include_open_air=True)
|
||||
views = [view for view in views if view["kind"] == "open-air-close"]
|
||||
rows = [HELPERS.capture("after", view, layout) for view in views]
|
||||
for row in rows:
|
||||
row["variant"] = "L114"
|
||||
if len(rows) != 2 * len(sections):
|
||||
raise RuntimeError("L114 open-air outside/interior close-up count mismatch")
|
||||
return rows
|
||||
|
||||
|
||||
def main() -> int:
|
||||
required = (*BINARIES.values(), *RENDERERS.values(),
|
||||
L113_SAVED / "audit-layout-candidate.json",
|
||||
L114_SAVED / "audit-layout-candidate.json",
|
||||
L114_SAVED / "audit-owner-clang.log")
|
||||
if any(not path.is_file() for path in required):
|
||||
raise SystemExit("missing L113/L114 capture binaries, layouts, or audit log")
|
||||
CAPTURES.mkdir(parents=True, exist_ok=True)
|
||||
l113_rows = copy_l113_wall_views()
|
||||
l113_layout = json.loads((L113_SAVED / "audit-layout-candidate.json").read_text())
|
||||
l114_layout = json.loads((L114_SAVED / "audit-layout-candidate.json").read_text())
|
||||
l114_sections = parse_sections(L114_SAVED / "audit-owner-clang.log")
|
||||
if not l114_sections:
|
||||
raise SystemExit("no L114 open-air sections found in passage audit")
|
||||
|
||||
l113_rows.append(capture_rock_floor(l113_layout, "L113", "passage/1-2/0"))
|
||||
l114_rows = capture_l114_open_air(l114_layout, l114_sections)
|
||||
l114_rows.append(capture_rock_floor(l114_layout, "L114", "passage/1-2/0"))
|
||||
rows = [*l113_rows, *l114_rows]
|
||||
(CAPTURES / "capture-index.json").write_text(
|
||||
json.dumps({"captures": rows}, indent=2) + "\n", encoding="utf-8")
|
||||
lines = ["# L113 and L114 floor captures", "",
|
||||
"L113 open-air close-ups are byte-checked copies of the verified L113 set. "
|
||||
"L113 and L114 rock-floor views and L114 open-air close-ups were rendered "
|
||||
"from their respective meshes. Each image passed the pixel check. Rock-floor "
|
||||
"anchors require an upward normal alignment of at least 0.85, a floor offset "
|
||||
"of at most 0.25 m, and a camera distance between 2.0 and 3.2 m.", ""]
|
||||
for version in ("L113", "L114"):
|
||||
lines.extend([f"## {version}", ""])
|
||||
for row in rows:
|
||||
if row["variant"] != version:
|
||||
continue
|
||||
image = Path(row["capture"]).name
|
||||
lines.append(f"- [{row['station']}]({row['capture']}) — {row['kind']}; "
|
||||
f"{row.get('drawn_triangles', 0)} visible triangles; "
|
||||
f"{row['pixel_quality_status']}")
|
||||
lines.append("")
|
||||
(CAPTURES / "INDEX.md").write_text("\n".join(lines), encoding="utf-8")
|
||||
floor_rows = [row for row in rows if row["kind"] == "rock-floor-close"]
|
||||
if len(floor_rows) != 2 or not all(row["verified_upward_floor_normal"] for row in floor_rows):
|
||||
raise RuntimeError("L113/L114 rock-floor capture verification failed")
|
||||
print(f"[L114CaptureSummary] captures={len(rows)} L113={len(l113_rows)} "
|
||||
f"L114={len(l114_rows)} rock_floor_verified={len(floor_rows)}", flush=True)
|
||||
return 0
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
raise SystemExit(main())
|
||||
Reference in new issue
Block a user