diff --git a/tooling/planet-gen/batch.py b/tooling/planet-gen/batch.py index 9d7ebd3c7..21360ac7e 100644 --- a/tooling/planet-gen/batch.py +++ b/tooling/planet-gen/batch.py @@ -186,18 +186,14 @@ def _scaffold_system(system_dir: Path, overrides: dict) -> list: # Generate # ───────────────────────────────────────────────────────────────────────────── -def _atomic_save_img(img, target: Path): - """Write image to .tmp, then rename. Prevents corrupt files on crash.""" - tmp = target.with_name(target.name + ".tmp") - img.save(str(tmp), format="PNG") - tmp.rename(target) +def _save_img(img, target: Path): + """Write image directly — resume logic handles incomplete outputs.""" + img.save(str(target), format="PNG") -def _atomic_save(data, target: Path, save_fn): - """Write data to .tmp, then rename. Prevents corrupt files on crash.""" - tmp = target.with_name(target.name + ".tmp") - save_fn(data, str(tmp)) - tmp.rename(target) +def _save(data, target: Path, save_fn): + """Write data directly — resume logic handles incomplete outputs.""" + save_fn(data, str(target)) def _is_complete(body_dir: Path, is_gas: bool) -> bool: @@ -242,21 +238,15 @@ def _generate_body_from_dir(body_dir: Path, hmap_w: int, hmap_h: int, # Heightmap — atomic write if not is_gas: - import render_heightmap as rh - rh.OUT_W = hmap_w - rh.OUT_H = hmap_h - rh.UI_SCALE = hmap_w / 1024 - rh.RENDER_MODE = "cartographic" - rh.BIOME_RGB = rh._build_biome_rgb("cartographic") - rh.OCEAN_DEEP, rh.OCEAN_MID, rh.OCEAN_SHALLOW = rh._ocean_arrays("cartographic") - - hmap_img = render_heightmap(bd, terrain, chrome=False) - _atomic_save_img(hmap_img, body_dir / "heightmap.png") + hmap_img = render_heightmap(bd, terrain, + out_w=hmap_w, out_h=hmap_h, + chrome=False) + _save_img(hmap_img, body_dir / "heightmap.png") # Globe — atomic write from planet_renderer import render_globe globe_img = render_globe(bd, terrain, size=globe_size) - _atomic_save_img(globe_img, body_dir / "globe.png") + _save_img(globe_img, body_dir / "globe.png") # Terrain data — atomic write if not is_gas: @@ -266,17 +256,12 @@ def _generate_body_from_dir(body_dir: Path, hmap_w: int, hmap_h: int, if key in terrain: save_dict[key] = terrain[key] save_dict["sea_level"] = np.array([terrain["sea_level"]]) - # npz: numpy appends .npz to the path, so write directly - # (atomic rename doesn't work cleanly with numpy's extension handling) - npz_path = body_dir / "terrain.npz" - npz_tmp = body_dir / "terrain_tmp" - np.savez_compressed(str(npz_tmp), **save_dict) - Path(str(npz_tmp) + ".npz").rename(npz_path) + np.savez_compressed(str(body_dir / "terrain.npz"), **save_dict) - # Markers — atomic write + # Markers from generate import _build_markers markers = _build_markers(bd, terrain) - _atomic_save(markers, body_dir / "markers.json", + _save(markers, body_dir / "markers.json", lambda m, p: Path(p).write_text(json.dumps(m, indent=2))) elapsed = time.time() - t0 @@ -303,7 +288,7 @@ def main(): help="Validate body definitions without generating") parser.add_argument("--verify-determinism", type=int, metavar="N", default=0, help="Run N random bodies twice and verify identical output") - parser.add_argument("--heightmap-size", default="4096x2048") + parser.add_argument("--heightmap-size", default="1024x512") parser.add_argument("--globe-size", type=int, default=512) args = parser.parse_args() diff --git a/tooling/planet-gen/generate.py b/tooling/planet-gen/generate.py index a618143ef..9605b55ef 100644 --- a/tooling/planet-gen/generate.py +++ b/tooling/planet-gen/generate.py @@ -151,21 +151,17 @@ def _generate_body(body_def: dict, hmap_w: int, hmap_h: int, # ── 2. Render heightmap ────────────────────────────────────────────── t_hmap = t_sim if not is_gas: - import render_heightmap as rh - rh.OUT_W = hmap_w - rh.OUT_H = hmap_h - rh.UI_SCALE = hmap_w / 1024 - rh.RENDER_MODE = render_mode - rh.BIOME_RGB = rh._build_biome_rgb(render_mode) - rh.OCEAN_DEEP, rh.OCEAN_MID, rh.OCEAN_SHALLOW = rh._ocean_arrays(render_mode) - # Clean heightmap (no title/legend) - hmap_img = render_heightmap(body_def, terrain, chrome=False) + hmap_img = render_heightmap(body_def, terrain, + out_w=hmap_w, out_h=hmap_h, + render_mode=render_mode, chrome=False) hmap_img.save(os.path.join(body_dir, "heightmap.png")) # Chrome version for review (optional — saved to /tmp, not shipped) if chrome: - hmap_chrome = render_heightmap(body_def, terrain, chrome=True) + hmap_chrome = render_heightmap(body_def, terrain, + out_w=hmap_w, out_h=hmap_h, + render_mode=render_mode, chrome=True) chrome_path = f"/tmp/{body_id}_heightmap_chrome.png" hmap_chrome.save(chrome_path) print(f" chrome: {chrome_path}") @@ -223,7 +219,7 @@ def main(): help="Root output directory (bodies get subdirs)") # Rendering - parser.add_argument("--heightmap-size", default="4096x2048", + parser.add_argument("--heightmap-size", default="1024x512", help="Heightmap output resolution (WxH)") parser.add_argument("--globe-size", type=int, default=512, help="Globe output resolution (square, locked at 512)") diff --git a/tooling/planet-gen/render_heightmap.py b/tooling/planet-gen/render_heightmap.py index 8b60933b2..05de78101 100644 --- a/tooling/planet-gen/render_heightmap.py +++ b/tooling/planet-gen/render_heightmap.py @@ -52,8 +52,8 @@ from biome_config import ( # Output resolution # --------------------------------------------------------------------------- -OUT_W = 4096 -OUT_H = 2048 +OUT_W = 1024 +OUT_H = 512 UI_SCALE = OUT_W / 1024 # 4.0 — all pixel sizes scale with this # --------------------------------------------------------------------------- @@ -390,13 +390,13 @@ def render_heightmap(body_def: dict, render_mode: str = "cartographic", chrome: bool = True) -> Image.Image: """ - Render a 4096×2048 annotated equirectangular heightmap PNG. + Render an annotated equirectangular heightmap PNG. Parameters ---------- body_def : dict — body definition from body_definition_parser terrain : dict — terrain dict from planet_simulation.simulate() - out_w, out_h — output resolution (default 4096×2048) + out_w, out_h — output resolution (default 1024×512) Returns -------