# Cinema 4D Render Takes Automation

> Rendered all 1,988 Cinema 4D takes overnight, unattended, with no operator waking up to babysit it.
>
> https://pravda.systems/work/c4d-render-takes-automation · 2026-06-13

**Problem.** Rendering 1,988 Cinema 4D takes across two GPUs meant a human had to babysit the machine all night: track finished frames, restart crashes, convert raw files before the disk filled.

**Solution.** A Python supervisor runs both GPU workers, tracks every frame, converts finished renders to delivery format, and restarts itself on any crash, started by one batch file.

**Outcome.** All 1,988 takes reached final format unattended. The system recovered from crashes and disk pressure on its own, and nobody had to wake up.

## Key metrics

- **1,988** Takes rendered unattended — Distinct Cinema 4D takes tracked to completion across two GPUs, all reaching final delivery format _(verified: takes.csv row count: 1989 lines minus 1 header = 1988 data rows. All rows show Status=rendered)_
- **684** Lines of Python — The entire supervisor, render, tracking, and conversion logic, built in 2 days across 9 scripts _(verified: stats.json loc_by_ext_top .py for c4d_render_takes_automation, confirmed by manual line count of all 9 .py files in Scripts/)_
- **N CPU cores** Converter threads — EXR-to-TGA conversion runs one thread per CPU core to keep up with both GPUs _(verified: convert_exr_to_tga.py line 47)_
- **25 s** Progress check interval — How often the system reconciles real output files against the CSV to catch missing frames _(verified: update_render_status_csv.py main_loop line 133: wait.wait_for_update('update csv', 25). wait_for_update sleeps 1 second per iteration, so argument 25 = 25 seconds)_
- **3** Crash retries before reboot — The pipeline restarts itself on each GPU crash, then reboots the machine after 3 to clear GPU memory leaks _(verified: render_workflow_manager.py line 80: if flags_count > 2: restart_computer())_

## Outcome

**All 1,988 Cinema 4D takes reached final delivery format overnight, with zero human intervention.**

The system tracked every take to a `rendered` state across two GPUs, rendering **73,100 frames** in total. It recovered from crashes and disk pressure on its own. The operator never woke up to fix anything.

## The problem

**Without automation, a person had to babysit the render machine all night.**

The job held 1,988 distinct takes, each a unique combination of character state, animation phase, color variant, and frame range. Rendering them across two GPUs (Redshift renderer) meant the job would run for many hours unattended.

The manual alternative was slow and error-prone: check which takes had completed, note missing frames, restart Cinema 4D's command-line renderer on the correct take, watch for crashes, convert finished EXR sequences before the disk filled, repeat. A single overnight session would require multiple interruptions to stay on track.

## What it does

**One batch file launches a five-process pipeline that runs the whole render unattended.**

Two render workers (one per GPU) pull their queue from a shared CSV and drive Cinema 4D's command-line renderer. Each worker reads its assigned rows, invokes `Commandline.exe` with the correct Redshift GPU assignment, streams render output to detect failures mid-frame, and writes per-take timing stats back to disk. A status updater scans output files every **25 seconds** to track exact frame-level progress. A converter turns finished raw frames into compressed delivery files and reclaims disk. A supervisor watches all of it and restarts on failure.

Configuration (file paths, GPU IDs, restart intervals, monitor resolution) lives in a single `config.ini`, so the pipeline adapts to a new Cinema 4D project by editing one file.

## How it stays unattended

**Crash recovery, disk watchdog, and self-restart let the run finish without anyone present.**

When a render crashes, the failing process writes an error flag file to disk. The supervisor polls for these flags, clears them, increments a counter, and restarts the full pipeline. After **3 failures it reboots the machine** to clear GPU memory leaks accumulated across long runs. A disk-space watchdog in the converter switches to a continuous emergency loop and forces EXR deletion before storage fills. Because both GPUs work from different filtered rows of the same CSV, there is no locking contention between them.

## Why it's reliable

**Progress is measured against real output files, not process exit codes.**

The status updater reconciles the CSV against frames that actually exist on disk every 25 seconds, catching partial renders and frames that vanished after being marked done. It also detects regressions (a take previously promoted to `rendered` that has since lost frames) and returns it to the queue. A rolling average of real frame-render durations drives a live ETA shown in the terminal progress monitor. Parallel EXR-to-TGA conversion uses all available CPU cores via `ThreadPoolExecutor`, keeping pace with two simultaneous GPU streams. The result: a render the machine finishes itself, **delivered in a 2-day build of 684 lines of Python**.

## Features

- **Dual-GPU work distribution** — Both GPUs render in parallel from separate rows of one shared CSV, so neither blocks the other and no locking is needed.
- **Frame-level completion tracking** — Progress is measured against the frames that actually exist on disk, catching partial renders and frames that vanished after being marked done.
- **Crash-resilient supervisor** — A failed render drops an error flag that the supervisor detects, then restarts the whole pipeline and reboots the machine after three failures.
- **Disk-pressure converter** — When free space drops below the threshold, the converter switches to a continuous loop and clears finished raw frames before the drive fills.

## Architecture

Five Python processes coordinated by a supervisor. Shared state lives in a CSV file. Error signaling uses flag files on disk. All processes are launched as separate Windows console windows from a single `.bat` entry point.

- **render_workflow_manager.py** — Top-level supervisor: launches all processes, polls for error flags, restarts on crash, triggers reboot on timeout
- **command_line_render_controller.py** — Per-GPU render worker: reads CSV queue, invokes C4D Commandline.exe, monitors output stream for failures, writes timing stats
- **update_render_status_csv.py** — State reconciler: scans output directories, computes missing frame ranges, updates CSV status every 25 seconds
- **convert_exr_to_tga.py** — Format converter: parallel EXR-to-TGA conversion with ICC profile, disk-space watchdog, deletes source EXR after conversion
- **render_progress_monitor.py** — Terminal UI: reads CSV and timing stats, renders color progress bar with estimated completion time
- **takes.csv** — Shared state machine: one row per take, tracks name, needed frames, current status, remaining frames

## Tech

- **Languages:** Python
- **Frameworks:** pandas, psutil, concurrent.futures
- **Infrastructure:** Cinema 4D 2024 Commandline.exe, Redshift GPU renderer, ImageMagick (magick CLI), Windows Task Scheduler (manual launch via .bat)

## Skills demonstrated

- unattended overnight automation
- self-healing systems that recover from crashes
- multi-process orchestration and supervision
- tracking work against real results, not assumptions
- parallel file processing across all CPU cores
- render pipeline automation (Cinema 4D + Redshift)
- automatic disk-space management
- portable, config-driven design
- Windows process control
