175 lines
7.9 KiB
Python
175 lines
7.9 KiB
Python
import json
|
|
import os
|
|
import subprocess
|
|
import shutil
|
|
from pathlib import Path
|
|
import argparse
|
|
|
|
def update_robot_json(robot_json_file, camera_position, camera_target, default_position, width, height, fstop):
|
|
"""Aktualisiert die cameraPosition und defaultPosition in der robot.json-Datei."""
|
|
try:
|
|
with open(robot_json_file, 'r') as f:
|
|
data = json.load(f)
|
|
|
|
data['renderingInfo']['cameraPosition'] = camera_position
|
|
data['renderingInfo']['cameraTarget'] = camera_target
|
|
data['renderingInfo']['width'] = width
|
|
data['renderingInfo']['height'] = height
|
|
data['renderingInfo']['dofFStop'] = fstop
|
|
data['defaultPosition'] = default_position
|
|
|
|
with open(robot_json_file, 'w') as f:
|
|
json.dump(data, f, indent=2)
|
|
except FileNotFoundError:
|
|
print(f"Fehler: Datei {robot_json_file} nicht gefunden.")
|
|
return False
|
|
except json.JSONDecodeError:
|
|
print(f"Fehler: JSON-Datei {robot_json_file} ist ungültig.")
|
|
return False
|
|
return True
|
|
|
|
def run_blender(blender_executable, script_path, log_level):
|
|
"""Führt Blender mit dem angegebenen Skript aus."""
|
|
try:
|
|
command = [
|
|
blender_executable,
|
|
"-b",
|
|
"--python",
|
|
script_path,
|
|
"--log-level",
|
|
str(log_level)
|
|
]
|
|
subprocess.run(command, check=True, capture_output=True, text=True)
|
|
return True
|
|
except subprocess.CalledProcessError as e:
|
|
print(f"Blender-Skript fehlgeschlagen:\n{e.stderr}")
|
|
return False
|
|
|
|
def copy_and_rename_file(source_file, destination_dir, new_filename):
|
|
"""Kopiert die erstellte Bilddatei in den Zielordner und benennt sie um."""
|
|
destination_path = os.path.join(destination_dir, new_filename)
|
|
try:
|
|
shutil.copy2(source_file, destination_path) # copy2 behält Metadaten
|
|
return True
|
|
except FileNotFoundError:
|
|
print(f"Fehler: Quelldatei {source_file} nicht gefunden.")
|
|
return False
|
|
except Exception as e:
|
|
print(f"Fehler beim Kopieren/Umbenennen der Datei: {e}")
|
|
return False
|
|
|
|
def main():
|
|
USER_HOME = Path.home()
|
|
ROBOT_JSON_FILE = str(USER_HOME / "SynologyDrive" / "2026-AppServer-AppRobot" / "appRobotRendering" / "data" / "robot" / "robot.json")
|
|
OUTPUT_DIR = str(USER_HOME / "SynologyDrive" / "2026-AppServer-AppRobot" / "appRobotRendering" / "data" / "simulation" / "debug" )
|
|
BLENDER_EXE = str("C:/Program Files/Blender Foundation/Blender 4.5/blender.exe")
|
|
RENDER_PY= str(USER_HOME /"SynologyDrive" / "2026-AppServer-AppRobot" / "appRobotRendering"/ "setup"/"generateSets"/"render_robot.py")
|
|
RENDER_PNG=str(USER_HOME /"SynologyDrive" / "2026-AppServer-AppRobot" / "appRobotRendering"/"data"/"simulation"/"debug"/"render.png")
|
|
OUTPUT_SET = str(USER_HOME / "SynologyDrive" / "2026-AppServer-AppRobot" / "appRobotRendering" / "data" / "simulation" )
|
|
|
|
parser = argparse.ArgumentParser(description="Automatisiert die Roboter-Rendering-Pipeline.")
|
|
parser.add_argument("robot_json", nargs="?",
|
|
default=ROBOT_JSON_FILE, help="Pfad zur robot.json-Datei.")
|
|
parser.add_argument("blender_executable",nargs="?",
|
|
default=BLENDER_EXE, help="Pfad zur Blender-Executable.")
|
|
parser.add_argument("render_script",
|
|
default=RENDER_PY,
|
|
help="Pfad zum render_robot.py-Skript.",nargs="?")
|
|
parser.add_argument("render_png",nargs="?",
|
|
default=RENDER_PNG,help="script erzeugte png")
|
|
parser.add_argument("output_dir", nargs="?",
|
|
default=OUTPUT_DIR, help="Zielordner für die gerenderten Blender Bilder.")
|
|
parser.add_argument("output_set", nargs="?",
|
|
default=OUTPUT_SET, help="Zielordner in dem die Sets abgelegt werden")
|
|
parser.add_argument("--log_level", type=int, default=2, help="Log-Level für Blender (Standard: 2).")
|
|
args = parser.parse_args()
|
|
|
|
# Kamerapositions-Dictionary
|
|
camera_positions = {
|
|
"a": [-300, -800, 800],
|
|
"b": [300, -900, 1200],
|
|
"c": [300, -900, 400],
|
|
"d": [700, -800, 400],
|
|
"e": [1200, -900, 400],
|
|
"f": [500, -300, 1400],
|
|
"g": [-200, 200, 1400],
|
|
}
|
|
camera_targets = {
|
|
"a": [210, -100, 180],
|
|
"b": [310, -80, 180],
|
|
"c": [210, -100, 150],
|
|
"d": [210, -100, 150],
|
|
"e": [210, -100, 50],
|
|
"f": [200, -200, 180],
|
|
"g": [200, -200, 180],
|
|
}
|
|
|
|
|
|
# Robot-Pose-Dictionary
|
|
robot_poses = {
|
|
#"4": {"x": 70, "y": 50,"z": -70,"a": 120,"b": 50,"c": 30,"e": 20},
|
|
#"5": {"x": 180,"y": 86,"z": -120,"a": -60,"b": 22,"c": 91,"e": 10},
|
|
#"6": {"x": 80, "y": 20, "z": 80, "a": -120, "b": 23, "c": 9, "e": 3},
|
|
#"7": {"x": 30, "y": -2, "z": 95, "a": 20, "b": 23, "c": 9, "e": 9},
|
|
#"8": {"x": 50, "y": -2, "z": 95, "a": 20, "b": 60, "c": 9, "e": 3},
|
|
#"9": {"x": 60, "y": -2, "z": 95, "a": 200, "b": 60, "c": 9, "e": 8},
|
|
#"9a": {"x": 60, "y": -2, "z": 95, "a": 200, "b": 60, "c": 9, "e": 8},
|
|
"9b": {"x": 60, "y": -2, "z": 95, "a": 200, "b": 60, "c": 9, "e": 8},
|
|
#"10": {"x": 120, "y": 60, "z": -110, "a": 20, "b": 30, "c": 180, "e": 4},
|
|
#"11": {"x": 50, "y": 4, "z": 176, "a": 20, "b": 60, "c": 9, "e": 5},
|
|
#"12": {"x": 50, "y": 0, "z": 178, "a": 210, "b": 80, "c": 90, "e": 6},
|
|
}
|
|
|
|
renderingInfos = {
|
|
"4": {"width":1280, "height":720, "dofFStop":11},
|
|
"5": {"width":1280, "height":720, "dofFStop":11},
|
|
"6": {"width":1280, "height":720, "dofFStop":11},
|
|
"7": {"width":1280, "height":720, "dofFStop":11},
|
|
"8": {"width":1280, "height":720, "dofFStop":11},
|
|
"9": {"width":1280, "height":720, "dofFStop":11},
|
|
"9a": {"width":1440, "height":1080, "dofFStop":11},
|
|
"9b": {"width":4896, "height":3264, "dofFStop":5.6},
|
|
"10": {"width":1280, "height":720, "dofFStop":11},
|
|
"11": {"width":1280, "height":720, "dofFStop":11},
|
|
"12": {"width":1280, "height":720, "dofFStop":11},
|
|
}
|
|
|
|
for pose_name, default_position in robot_poses.items():
|
|
new_folder = Path(args.output_set) / f"Scene{pose_name}"
|
|
os.makedirs(new_folder, exist_ok=True)
|
|
|
|
renderingInfo = renderingInfos[pose_name]
|
|
print(renderingInfo)
|
|
|
|
pose_file = new_folder / "pose.json"
|
|
pose_data = {"name": pose_name,"position": default_position, "camera_positions": camera_positions}
|
|
with open(pose_file, "w") as f:
|
|
json.dump(pose_data, f, indent=2)
|
|
|
|
for frame_name, camera_position in camera_positions.items():
|
|
|
|
camera_target = camera_targets[frame_name]
|
|
|
|
# 1. JSON aktualisieren
|
|
if not update_robot_json(args.robot_json, camera_position, camera_target, default_position, renderingInfo["width"], renderingInfo["height"], renderingInfo["dofFStop"]):
|
|
continue # Gehe zum nächsten Schleifendurchlauf
|
|
|
|
# 2. Blender-Skript ausführen
|
|
if not run_blender(args.blender_executable, args.render_script, args.log_level):
|
|
continue # Gehe zum nächsten Schleifendurchlauf
|
|
|
|
# 3. Datei kopieren und umbenennen
|
|
new_filename = f"render_{frame_name}.png"
|
|
if not copy_and_rename_file(args.render_png, new_folder, new_filename):
|
|
continue # Gehe zum nächsten Schleifendurchlauf
|
|
|
|
if not copy_and_rename_file(args.render_png.replace(".png",".npz"), new_folder, new_filename.replace(".png",".npz")):
|
|
continue # Gehe zum nächsten Schleifendurchlauf
|
|
|
|
if not copy_and_rename_file(args.render_png.replace("render.png","markers.json"), new_folder, new_filename.replace(".png",".json")):
|
|
continue # Gehe zum nächsten Schleifendurchlauf
|
|
|
|
print(f"Rendering für Frame {frame_name}, Scene {pose_name} erfolgreich abgeschlossen.")
|
|
|
|
if __name__ == "__main__":
|
|
main() |