mirror of
https://github.com/ConsistentlyInconsistentYT/Pixeltovoxelprojector.git
synced 2025-11-19 06:46:38 +00:00
Create blenderrestarteraftercrashing.py
Rip Princess Diana
This commit is contained in:
parent
63e1bc211d
commit
011722ac4e
1 changed files with 93 additions and 0 deletions
93
blenderrestarteraftercrashing.py
Normal file
93
blenderrestarteraftercrashing.py
Normal file
|
|
@ -0,0 +1,93 @@
|
|||
#!/usr/bin/env python3
|
||||
"""
|
||||
Watch-dog that restarts Blender until every entry in metadata.json
|
||||
is "rendered": true. Now hardened against path-quoting issues and
|
||||
third-party add-ons crashing on start-up.
|
||||
"""
|
||||
|
||||
import json, os, subprocess, sys, tempfile, time
|
||||
from pathlib import Path
|
||||
import textwrap, json as _json # for safe string literal
|
||||
|
||||
# ─────────────────────────── USER SETTINGS ────────────────────────────
|
||||
BLENDER_EXE = r"C:\Program Files\Blender Foundation\Blender 3.6\blender.exe"
|
||||
BLEND_FILE = r"C:\Users\youruser\Desktop\birdge.blend"
|
||||
JOB_SCRIPT = r"C:\Users\youruser\Desktop\birdge.py"
|
||||
|
||||
OUTPUT_DIR = r"C:\Users\Rhoady\Desktop\pet projects\relcams40"
|
||||
META_PATH = Path(OUTPUT_DIR) / "metadata.json"
|
||||
|
||||
CRASH_SLEEP = 5.0 # seconds between retries
|
||||
# ───────────────────────────────────────────────────────────────────────
|
||||
|
||||
# ----------------------------------------------------------------------
|
||||
def all_frames_done(meta_file: Path) -> bool:
|
||||
if not meta_file.exists():
|
||||
return False
|
||||
with meta_file.open("r") as fh:
|
||||
return all(m.get("rendered") for m in json.load(fh))
|
||||
|
||||
# ----------------------------------------------------------------------
|
||||
def make_wrapper() -> Path:
|
||||
wrapper = Path(tempfile.gettempdir()) / "run_render_job_once.py"
|
||||
|
||||
safe_job = _json.dumps(JOB_SCRIPT) # proper quoting
|
||||
safe_json = _json.dumps(str(META_PATH)) # ← new
|
||||
|
||||
wrapper.write_text(textwrap.dedent(f"""
|
||||
import importlib.util, types, pathlib, sys, os
|
||||
|
||||
# ---- import the render job script ----------------------------------
|
||||
job_path = pathlib.Path({safe_job})
|
||||
spec = importlib.util.spec_from_file_location("job", job_path)
|
||||
if spec and spec.loader:
|
||||
job = importlib.util.module_from_spec(spec)
|
||||
spec.loader.exec_module(job)
|
||||
else: # very old Python fallback
|
||||
job = types.ModuleType("job")
|
||||
exec(job_path.read_text(), job.__dict__)
|
||||
sys.modules["job"] = job
|
||||
|
||||
# ---- pick fresh vs. resume ----------------------------------------
|
||||
meta_path = pathlib.Path({safe_json})
|
||||
job.NEW_PHOTOS = not meta_path.exists() # True on first run only
|
||||
print(f"[WRAPPER] NEW_PHOTOS = {{job.NEW_PHOTOS}}")
|
||||
|
||||
job.main()
|
||||
"""))
|
||||
|
||||
return wrapper
|
||||
|
||||
# ----------------------------------------------------------------------
|
||||
def launch_blender(wrapper: Path) -> int:
|
||||
cmd = [
|
||||
BLENDER_EXE,
|
||||
"--factory-startup", # <-- disables all add-ons
|
||||
"-b", BLEND_FILE,
|
||||
"--python", str(wrapper)
|
||||
]
|
||||
return subprocess.run(cmd).returncode
|
||||
|
||||
# ----------------------------------------------------------------------
|
||||
def main():
|
||||
print("▶ Blender render watchdog started.")
|
||||
wrapper = make_wrapper()
|
||||
|
||||
while True:
|
||||
if all_frames_done(META_PATH):
|
||||
print("✓ All frames already rendered – nothing to do. Exiting.")
|
||||
return
|
||||
|
||||
print("→ Launching Blender …")
|
||||
rc = launch_blender(wrapper)
|
||||
|
||||
if rc == 0 and all_frames_done(META_PATH):
|
||||
print("✓ Job completed on this pass. Exiting.")
|
||||
return
|
||||
|
||||
print(f"⚠ Blender exited (code {rc}). Will retry in {CRASH_SLEEP}s …")
|
||||
time.sleep(CRASH_SLEEP)
|
||||
|
||||
# ----------------------------------------------------------------------
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
Loading…
Add table
Add a link
Reference in a new issue