import sys
import wx
import os
import json
import inspect
from pathlib import Path
from .render_frame import RenderFrame
# Path to persistent state file in user home directory
STATE_FILE = Path.home() / ".pyvcad_render_state.json"
def _get_caller_id():
"""Identify the script invoking the render function."""
try:
# Step back through stack: 0=here, 1=renderWrapper, 2=caller
# We look for the first frame outside of this module
for frame_info in inspect.stack():
filename = frame_info.filename
# Ignore calls from within the library itself
if "pyvcad_rendering" in filename:
continue
return os.path.abspath(filename)
except Exception:
pass
return "unknown"
[docs]
def render(vcad_object, materials=None):
caller_id = _get_caller_id()
# Load state
state = {}
if STATE_FILE.exists():
try:
with open(STATE_FILE, 'r') as f:
state = json.load(f)
except Exception:
state = {} # Corrupt file, reset
last_caller = state.get("last_caller", None)
settings_to_use = {}
# If the caller matches the last run, reuse settings
if last_caller == caller_id and "last_settings" in state:
settings_to_use = state["last_settings"]
else:
# New design context -> reset settings (empty dict uses defaults in RenderFrame)
settings_to_use = {}
# Update state with new caller immediately so if they crash/close, we track it
state["last_caller"] = caller_id
# Clear old settings in file to avoid confusion
state["last_settings"] = {}
try:
with open(STATE_FILE, 'w') as f:
json.dump(state, f, indent=4)
except:
pass
app = wx.App(False)
# Pass state file path so Frame can save on close
app.frame = RenderFrame(vcad_object, state_file=str(STATE_FILE), initial_settings=settings_to_use, materials=materials)
app.MainLoop()
[docs]
def Render(vcad_object, materials=None):
render(vcad_object, materials)
[docs]
def render_image(vcad_object, filepath, settings=None, width=1920, height=1080, materials=None):
# settings can include scale_bar_palette: "auto" or a named palette override.
from .headless_renderer import HeadlessRenderer
renderer = HeadlessRenderer(width=width, height=height)
renderer.render_and_save(vcad_object, filepath, settings=settings, materials=materials)
[docs]
def Render_Image(vcad_object, filepath, settings=None, width=1920, height=1080, materials=None):
render_image(vcad_object, filepath, settings, width, height, materials=materials)
[docs]
def render_turntable_animation(vcad_object, output_dir, duration=3.0, fps=30, distance_multiplier=1.5, elevation_angle_deg=30.0, settings=None, width=1920, height=1080, output_format="gif", keep_frames=False, materials=None):
# settings can include scale_bar_palette: "auto" or a named palette override.
from .headless_renderer import HeadlessRenderer
renderer = HeadlessRenderer(width=width, height=height)
renderer.render_turntable_animation(vcad_object, output_dir, duration=duration, fps=fps, distance_multiplier=distance_multiplier, elevation_angle_deg=elevation_angle_deg, settings=settings, output_format=output_format, keep_frames=keep_frames, materials=materials)
[docs]
def Render_Turntable_Animation(vcad_object, output_dir, duration=3.0, fps=30, distance_multiplier=1.5, elevation_angle_deg=30.0, settings=None, width=1920, height=1080, output_format="gif", keep_frames=False, materials=None):
render_turntable_animation(vcad_object, output_dir, duration, fps, distance_multiplier, elevation_angle_deg, settings, width, height, output_format, keep_frames, materials=materials)
[docs]
def render_sweep_animation(vcad_object, output_dir, axis="z", duration=3.0, fps=30, loop=False, pause_seconds=0.5, settings=None, width=1920, height=1080, output_format="gif", keep_frames=False, materials=None):
from .headless_renderer import HeadlessRenderer
renderer = HeadlessRenderer(width=width, height=height)
renderer.render_sweep_animation(vcad_object, output_dir, axis=axis, duration=duration, fps=fps, loop=loop, pause_seconds=pause_seconds, settings=settings, output_format=output_format, keep_frames=keep_frames, materials=materials)
[docs]
def Render_Sweep_Animation(vcad_object, output_dir, axis="z", duration=3.0, fps=30, loop=False, pause_seconds=0.5, settings=None, width=1920, height=1080, output_format="gif", keep_frames=False, materials=None):
render_sweep_animation(vcad_object, output_dir, axis, duration, fps, loop, pause_seconds, settings, width, height, output_format, keep_frames, materials=materials)
__all__ = ["render", "Render", "render_image", "Render_Image", "render_turntable_animation", "Render_Turntable_Animation", "render_sweep_animation", "Render_Sweep_Animation"]