Source code for dazpy._render

from __future__ import annotations

import json

from ._client import DazClient
from ._script_builder import ScriptBuilder

# Access path: App.getRenderMgr() → DzRenderMgr
# Render options: mgr.getRenderOptions() → DzRenderOptions
# imageSize is a QSize value type — read via .width/.height, write back by
# calling setWidth/setHeight on the copy then reassigning opts.imageSize.


[docs] class DazRenderSettings: def __init__(self, client: DazClient | None = None): self._client = client or DazClient() def _render_mgr(self) -> str: return "App.getRenderMgr()"
[docs] def is_available(self) -> bool: """Return True if the render manager is accessible.""" script = ScriptBuilder.iife(f""" var mgr = {self._render_mgr()}; return (mgr !== null && mgr !== undefined); """) result = self._client.execute(script).value return bool(result)
[docs] def is_rendering(self) -> bool: """Return True if a render is currently in progress.""" script = ScriptBuilder.iife(f""" var mgr = {self._render_mgr()}; if (!mgr) return false; return mgr.isRendering(); """) return bool(self._client.execute(script).value)
@property def resolution(self) -> dict | None: """Return the render image size as {{width, height}}.""" script = ScriptBuilder.iife(f""" var mgr = {self._render_mgr()}; if (!mgr) return null; var opts = mgr.getRenderOptions(); var sz = opts.imageSize; return {{width: sz.width, height: sz.height}}; """) return self._client.execute(script).value
[docs] def set_resolution(self, width: int, height: int) -> None: """Set the render image size in pixels.""" w, h = int(width), int(height) # QSize is exposed as a constructor in DazScript; plain object literals # are not coerced, so new QSize(w, h) is required. script = ScriptBuilder.iife(f""" var mgr = {self._render_mgr()}; if (!mgr) return; var opts = mgr.getRenderOptions(); opts.imageSize = new QSize({w}, {h}); opts.applyChanges(); """) self._client.execute(script)
@property def output_path(self) -> str | None: """Return the filename set for rendered images.""" script = ScriptBuilder.iife(f""" var mgr = {self._render_mgr()}; if (!mgr) return null; return mgr.getRenderOptions().renderImgFilename; """) return self._client.execute(script).value @output_path.setter def output_path(self, path: str) -> None: script = ScriptBuilder.iife(f""" var mgr = {self._render_mgr()}; if (!mgr) return; var opts = mgr.getRenderOptions(); opts.renderImgFilename = {json.dumps(path)}; opts.applyChanges(); """) self._client.execute(script) @property def gamma(self) -> float | None: """Return the gamma correction value.""" script = ScriptBuilder.iife(f""" var mgr = {self._render_mgr()}; if (!mgr) return null; var opts = mgr.getRenderOptions(); return opts.gamma; """) return self._client.execute(script).value @gamma.setter def gamma(self, value: float) -> None: script = ScriptBuilder.iife(f""" var mgr = {self._render_mgr()}; if (!mgr) return; var opts = mgr.getRenderOptions(); opts.gamma = {float(value)}; opts.applyChanges(); """) self._client.execute(script) @property def double_sided(self) -> bool | None: """Return whether polygons are rendered as double-sided.""" script = ScriptBuilder.iife(f""" var mgr = {self._render_mgr()}; if (!mgr) return null; return mgr.getRenderOptions().doubleSided; """) result = self._client.execute(script).value return None if result is None else bool(result) @double_sided.setter def double_sided(self, value: bool) -> None: js_bool = "true" if value else "false" script = ScriptBuilder.iife(f""" var mgr = {self._render_mgr()}; if (!mgr) return; var opts = mgr.getRenderOptions(); opts.doubleSided = {js_bool}; opts.applyChanges(); """) self._client.execute(script)
[docs] def render(self, camera_name: str | None = None) -> bool: """Render the scene to :attr:`output_path`. DAZ Studio's ``doRender()`` only writes to disk when ``renderImgToId`` is set to ``DzRenderOptions.DirectToFile`` and the camera is applied to both the render options and the active viewport before the call. Args: camera_name: Internal name of the camera node to render from. When omitted the active viewport camera is used. Returns: ``True`` if the render completed without error. """ if camera_name is not None: cam_expr = f"Scene.findCamera({json.dumps(camera_name)})" else: cam_expr = ( "MainWindow.getViewportMgr().getActiveViewport()" ".get3DViewport().getCamera()" ) script = ScriptBuilder.iife(f""" var mgr = {self._render_mgr()}; if (!mgr) return false; var cam = {cam_expr}; if (!cam) return false; var opts = mgr.getRenderOptions(); opts.camera = cam; opts.renderImgToId = DzRenderOptions.DirectToFile; var vp = MainWindow.getViewportMgr().getActiveViewport().get3DViewport(); var prevCam = vp ? vp.getCamera() : null; if (vp) vp.setCamera(cam); var err = mgr.doRender(opts); if (vp && prevCam) vp.setCamera(prevCam); return (err === 0 || err === true); """) return bool(self._client.execute(script).value)
[docs] def render_and_wait( self, poll_interval: float = 1.0, timeout: float = 600.0 ) -> bool: """Alias for :meth:`render` kept for backwards compatibility. ``doRender()`` is synchronous in DAZ Studio so no polling is required. """ return self.render()
[docs] def has_render(self) -> bool: """Return True if there is a completed render available to save.""" script = ScriptBuilder.iife(f""" var mgr = {self._render_mgr()}; if (!mgr) return false; return mgr.hasRender(); """) return bool(self._client.execute(script).value)