dazpy 2.7.2__tar.gz → 2.9.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {dazpy-2.7.2/dazpy.egg-info → dazpy-2.9.0}/PKG-INFO +189 -9
- dazpy-2.7.2/PKG-INFO → dazpy-2.9.0/README.md +186 -23
- {dazpy-2.7.2 → dazpy-2.9.0}/dazpy/__init__.py +62 -3
- {dazpy-2.7.2 → dazpy-2.9.0}/dazpy/_camera.py +46 -0
- {dazpy-2.7.2 → dazpy-2.9.0}/dazpy/_client.py +189 -34
- dazpy-2.9.0/dazpy/_client_aio.py +411 -0
- {dazpy-2.7.2 → dazpy-2.9.0}/dazpy/_light.py +2 -2
- {dazpy-2.7.2 → dazpy-2.9.0}/dazpy/_node.py +99 -1
- {dazpy-2.7.2 → dazpy-2.9.0}/dazpy/_property.py +26 -11
- {dazpy-2.7.2 → dazpy-2.9.0}/dazpy/_render.py +375 -6
- {dazpy-2.7.2 → dazpy-2.9.0}/dazpy/_render_api.py +23 -4
- dazpy-2.9.0/dazpy/_render_api_aio.py +150 -0
- dazpy-2.9.0/dazpy/_shot_geometry.py +81 -0
- {dazpy-2.7.2 → dazpy-2.9.0}/dazpy/_skeleton.py +27 -0
- dazpy-2.9.0/dazpy/aio.py +20 -0
- dazpy-2.9.0/dazpy/cinematics.py +423 -0
- {dazpy-2.7.2 → dazpy-2.9.0}/dazpy/exceptions.py +39 -0
- dazpy-2.9.0/dazpy/lighting.py +227 -0
- dazpy-2.9.0/dazpy/materials.py +270 -0
- {dazpy-2.7.2 → dazpy-2.9.0}/dazpy/math3.py +167 -0
- dazpy-2.9.0/dazpy/poses.py +88 -0
- dazpy-2.7.2/README.md → dazpy-2.9.0/dazpy.egg-info/PKG-INFO +203 -8
- {dazpy-2.7.2 → dazpy-2.9.0}/dazpy.egg-info/SOURCES.txt +20 -0
- {dazpy-2.7.2 → dazpy-2.9.0}/dazpy.egg-info/requires.txt +3 -0
- {dazpy-2.7.2 → dazpy-2.9.0}/pyproject.toml +4 -1
- {dazpy-2.7.2 → dazpy-2.9.0}/tests/test_api.py +38 -0
- {dazpy-2.7.2 → dazpy-2.9.0}/tests/test_comfyui_client.py +38 -2
- {dazpy-2.7.2 → dazpy-2.9.0}/tests/test_comfyui_enhance_integration.py +7 -1
- {dazpy-2.7.2 → dazpy-2.9.0}/tests/test_dazpy.py +2012 -40
- dazpy-2.9.0/tests/test_dazpy_aio.py +338 -0
- {dazpy-2.7.2 → dazpy-2.9.0}/tests/test_file_watcher.py +2 -1
- dazpy-2.9.0/tests/test_math3.py +183 -0
- dazpy-2.9.0/tests/test_render_api.py +77 -0
- dazpy-2.9.0/tests/test_sprite_matrix_canvas_convert.py +110 -0
- dazpy-2.9.0/tests/test_sprite_matrix_integration.py +134 -0
- dazpy-2.9.0/tests/test_sprite_matrix_paths.py +86 -0
- dazpy-2.9.0/tests/test_sprite_matrix_presets.py +86 -0
- dazpy-2.9.0/tests/test_sprite_matrix_render_shot.py +80 -0
- dazpy-2.9.0/tests/test_sprite_matrix_render_util.py +73 -0
- dazpy-2.9.0/tests/test_sprite_matrix_schema.py +234 -0
- dazpy-2.9.0/tests/test_sprite_matrix_stylize_stage.py +121 -0
- dazpy-2.9.0/tests/test_sprite_matrix_workflow_builder.py +383 -0
- {dazpy-2.7.2 → dazpy-2.9.0}/tests/test_workflow_builder.py +7 -1
- {dazpy-2.7.2 → dazpy-2.9.0}/dazpy/_animation.py +0 -0
- {dazpy-2.7.2 → dazpy-2.9.0}/dazpy/_batch.py +0 -0
- {dazpy-2.7.2 → dazpy-2.9.0}/dazpy/_bone.py +0 -0
- {dazpy-2.7.2 → dazpy-2.9.0}/dazpy/_dforce.py +0 -0
- {dazpy-2.7.2 → dazpy-2.9.0}/dazpy/_element.py +0 -0
- {dazpy-2.7.2 → dazpy-2.9.0}/dazpy/_geometry.py +0 -0
- {dazpy-2.7.2 → dazpy-2.9.0}/dazpy/_interaction.py +0 -0
- {dazpy-2.7.2 → dazpy-2.9.0}/dazpy/_material.py +0 -0
- {dazpy-2.7.2 → dazpy-2.9.0}/dazpy/_modifier.py +0 -0
- {dazpy-2.7.2 → dazpy-2.9.0}/dazpy/_morph.py +0 -0
- {dazpy-2.7.2 → dazpy-2.9.0}/dazpy/_polling.py +0 -0
- {dazpy-2.7.2 → dazpy-2.9.0}/dazpy/_pose.py +0 -0
- {dazpy-2.7.2 → dazpy-2.9.0}/dazpy/_result.py +0 -0
- {dazpy-2.7.2 → dazpy-2.9.0}/dazpy/_scene.py +0 -0
- {dazpy-2.7.2 → dazpy-2.9.0}/dazpy/_scene_events.py +0 -0
- {dazpy-2.7.2 → dazpy-2.9.0}/dazpy/_scene_state.py +0 -0
- {dazpy-2.7.2 → dazpy-2.9.0}/dazpy/_script_builder.py +0 -0
- {dazpy-2.7.2 → dazpy-2.9.0}/dazpy/_timeline.py +0 -0
- {dazpy-2.7.2 → dazpy-2.9.0}/dazpy/_undo.py +0 -0
- {dazpy-2.7.2 → dazpy-2.9.0}/dazpy/_viewport.py +0 -0
- {dazpy-2.7.2 → dazpy-2.9.0}/dazpy/py.typed +0 -0
- {dazpy-2.7.2 → dazpy-2.9.0}/dazpy.egg-info/dependency_links.txt +0 -0
- {dazpy-2.7.2 → dazpy-2.9.0}/dazpy.egg-info/top_level.txt +0 -0
- {dazpy-2.7.2 → dazpy-2.9.0}/setup.cfg +0 -0
- {dazpy-2.7.2 → dazpy-2.9.0}/tests/test_dazpy_integration.py +0 -0
- {dazpy-2.7.2 → dazpy-2.9.0}/tests/test_dsp_runner.py +0 -0
- {dazpy-2.7.2 → dazpy-2.9.0}/tests/test_performance.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: dazpy
|
|
3
|
-
Version: 2.
|
|
3
|
+
Version: 2.9.0
|
|
4
4
|
Summary: Python SDK for the DAZ Studio Script Server
|
|
5
5
|
License: MIT
|
|
6
6
|
Project-URL: Homepage, https://github.com/bluemoonfoundry/daz-script-server
|
|
@@ -12,10 +12,12 @@ Requires-Dist: requests>=2.28
|
|
|
12
12
|
Provides-Extra: docs
|
|
13
13
|
Requires-Dist: sphinx>=7.0; extra == "docs"
|
|
14
14
|
Requires-Dist: sphinx-rtd-theme>=2.0; extra == "docs"
|
|
15
|
+
Provides-Extra: aio
|
|
16
|
+
Requires-Dist: httpx>=0.24; extra == "aio"
|
|
15
17
|
|
|
16
18
|
# DazScript Server
|
|
17
19
|
|
|
18
|
-
**Version 2.
|
|
20
|
+
**Version 2.9.0** | DAZ Studio 4.5+ | DAZ Studio 6.25+ | Windows & macOS
|
|
19
21
|
|
|
20
22
|
[](https://bluemoonfoundry.github.io/daz-script-server/)
|
|
21
23
|
[](https://bluemoonfoundry.github.io/daz-script-server/api-reference/)
|
|
@@ -83,6 +85,8 @@ print(response.json())
|
|
|
83
85
|
### Getting Started
|
|
84
86
|
- [Quick Start](#-quick-start)
|
|
85
87
|
- [Why This Exists](#why-this-exists)
|
|
88
|
+
- [What's New in v2.9.0](#whats-new-in-v290)
|
|
89
|
+
- [What's New in v2.8.0](#whats-new-in-v280)
|
|
86
90
|
- [What's New in v2.7.2](#whats-new-in-v272)
|
|
87
91
|
- [What's New in v2.7.1](#whats-new-in-v271)
|
|
88
92
|
- [What's New in v2.7.0](#whats-new-in-v270)
|
|
@@ -169,6 +173,177 @@ DAZ Studio is powerful for 3D content creation, but automation is limited to man
|
|
|
169
173
|
|
|
170
174
|
---
|
|
171
175
|
|
|
176
|
+
## What's New in v2.9.0
|
|
177
|
+
|
|
178
|
+
### 🎬 dazpy.cinematics — camera shot builders
|
|
179
|
+
|
|
180
|
+
`dazpy.cinematics` packages common camera choreography on top of
|
|
181
|
+
`DazCamera`/`DazScene`: `apply_static_shot()` places/aims/configures a
|
|
182
|
+
camera in one call; `apply_orbit_camera()` sweeps a camera around a target
|
|
183
|
+
across a frame range; `apply_frame_subject()` frames a subject at a named
|
|
184
|
+
shot distance (`close_up` / `medium` / `full_body`); and
|
|
185
|
+
`apply_animated_shot()` writes real, interpolated DAZ Studio keyframes at a
|
|
186
|
+
sequence of waypoints instead of baking a value on every frame.
|
|
187
|
+
|
|
188
|
+
```python
|
|
189
|
+
from dazpy.cinematics import OrbitCamera, apply_orbit_camera
|
|
190
|
+
|
|
191
|
+
apply_orbit_camera(scene, OrbitCamera(target=figure, radius=250, frame_start=0, frame_end=90))
|
|
192
|
+
```
|
|
193
|
+
|
|
194
|
+
### 💡 dazpy.lighting — three-point rigs and HDRI environments
|
|
195
|
+
|
|
196
|
+
`apply_three_point_light_setup()` creates and places a key/fill/rim light
|
|
197
|
+
rig around a target in one call, via angle/distance placement or explicit
|
|
198
|
+
world-space positions per light. `apply_hdri_environment()` applies
|
|
199
|
+
image-based dome lighting — map, intensity, rotation, dome/scene mode,
|
|
200
|
+
visibility, and IBL resolution — validating the image path up front and
|
|
201
|
+
verifying a post-apply readback so a silent failure never passes as success.
|
|
202
|
+
|
|
203
|
+
### 🧍 dazpy.poses — apply_pose, reset_transforms, zero_figure
|
|
204
|
+
|
|
205
|
+
Common pose operations without hand-assembling a `DazPose`:
|
|
206
|
+
`apply_pose()` applies a pose object or a JSON file path directly to a
|
|
207
|
+
skeleton; `reset_transforms()` zeroes a node's local position/rotation and
|
|
208
|
+
resets scale to 1.0; `zero_figure()` drives every bone rotation and morph
|
|
209
|
+
to zero while leaving the figure's root transform untouched by default.
|
|
210
|
+
|
|
211
|
+
### 📐 dazpy.math3.AxisRemap — coordinate-space conversion
|
|
212
|
+
|
|
213
|
+
A generic signed-axis-permutation converter for `Vec3`/`Quat`/
|
|
214
|
+
`BoundingBox` between coordinate conventions, with a ready-made
|
|
215
|
+
`Y_UP_TO_Z_UP` preset for moving data from DAZ Studio (Y-up) into
|
|
216
|
+
Blender/glTF-style Z-up pipelines.
|
|
217
|
+
|
|
218
|
+
```python
|
|
219
|
+
from dazpy.math3 import Y_UP_TO_Z_UP
|
|
220
|
+
|
|
221
|
+
blender_pos = Y_UP_TO_Z_UP.apply_vec3(daz_pos)
|
|
222
|
+
```
|
|
223
|
+
|
|
224
|
+
### 🦴 DazSkeleton.bone_rotations_quat()
|
|
225
|
+
|
|
226
|
+
Returns local-space quaternion rotations for every bone in one HTTP
|
|
227
|
+
round-trip — the composable counterpart to `bone_rotations()` for callers
|
|
228
|
+
feeding the result into another rotation (e.g. `AxisRemap.apply_quat()`),
|
|
229
|
+
sidestepping the per-bone Euler rotation-order tracking that would
|
|
230
|
+
otherwise be required.
|
|
231
|
+
|
|
232
|
+
### 🎞️ Frame-level progress streaming for animation renders
|
|
233
|
+
|
|
234
|
+
The `GET /render/:id/progress` SSE stream now emits a progress event at
|
|
235
|
+
each frame boundary during an animation render, instead of only start/
|
|
236
|
+
terminal events — the DAZ SDK exposes no per-percent render progress
|
|
237
|
+
signal, so this frame-level marker is the most granular progress available.
|
|
238
|
+
|
|
239
|
+
### ⚡ Async client — `dazpy.aio.AsyncDazClient`
|
|
240
|
+
|
|
241
|
+
Async frameworks (FastAPI, FastMCP, ComfyUI custom nodes, asyncio/Temporal
|
|
242
|
+
workflows) previously had to wrap every `DazClient` call in
|
|
243
|
+
`asyncio.to_thread()` or hand-roll an `httpx.AsyncClient` wrapper.
|
|
244
|
+
`dazpy.aio.AsyncDazClient` mirrors `DazClient`'s full method surface —
|
|
245
|
+
`execute`, `execute_file`, async submit/status/result/list/cancel, render
|
|
246
|
+
submit/batch/animation, USD export, and server-health endpoints — as
|
|
247
|
+
native `async def` methods backed by `httpx.AsyncClient`, including the
|
|
248
|
+
same `retry_on_busy`/`max_wait` backoff semantics (via `asyncio.sleep`
|
|
249
|
+
instead of blocking `time.sleep`).
|
|
250
|
+
|
|
251
|
+
```python
|
|
252
|
+
from dazpy.aio import AsyncDazClient
|
|
253
|
+
|
|
254
|
+
async def main():
|
|
255
|
+
async with AsyncDazClient() as client:
|
|
256
|
+
result = await client.execute("1 + 1;")
|
|
257
|
+
print(result.value)
|
|
258
|
+
```
|
|
259
|
+
|
|
260
|
+
Requires the optional `httpx` dependency: `pip install dazpy[aio]`.
|
|
261
|
+
|
|
262
|
+
### `DazClient` connection pooling + `close()`
|
|
263
|
+
|
|
264
|
+
`DazClient` now issues requests through a pooled `requests.Session` instead
|
|
265
|
+
of a fresh connection per call, and supports `close()` / use as a context
|
|
266
|
+
manager (`with DazClient() as client:`) for symmetry with the new async
|
|
267
|
+
client's connection lifecycle.
|
|
268
|
+
|
|
269
|
+
### Truthful Iray/Viewport render-engine selector
|
|
270
|
+
|
|
271
|
+
`DazRenderSettings.render_engine_state()` now reads the effective
|
|
272
|
+
`DzRenderOptions.renderType` value and the active renderer class/name as separate
|
|
273
|
+
facts. Its schema-1 record includes the raw enum value/name, normalized
|
|
274
|
+
`verified_iray` / `verified_non_iray` / `unavailable` status, and field-level
|
|
275
|
+
live-readback provenance. A retained `NVIDIA Iray` active-renderer name never
|
|
276
|
+
overrides a Viewport/OpenGL `renderType`.
|
|
277
|
+
|
|
278
|
+
`DazRenderSettings.set_render_engine("iray" | "viewport")` is an explicit
|
|
279
|
+
persistent setter. It selects the registered `DzIrayRenderer` plus `Software` for
|
|
280
|
+
Iray, or `ScreenShot` for Viewport, calls `applyChanges()`, and returns only after
|
|
281
|
+
exact readback. Missing renderers, mutation/apply faults, malformed replies, and
|
|
282
|
+
readback disagreement raise `RenderError`; unknown engine names raise `ValueError`
|
|
283
|
+
before dispatch.
|
|
284
|
+
|
|
285
|
+
```python
|
|
286
|
+
settings = DazRenderSettings(client)
|
|
287
|
+
before = settings.render_engine_state()
|
|
288
|
+
change = settings.set_render_engine("iray")
|
|
289
|
+
assert change["readback"]["status"] == "verified_iray"
|
|
290
|
+
```
|
|
291
|
+
|
|
292
|
+
The `engine` field on `/render`, `/render/batch`, and `/render/animation` also
|
|
293
|
+
accepts `viewport` and uses the same fail-closed mutation/readback rules. These
|
|
294
|
+
operations intentionally persist the requested engine. DAZ documents `ScreenShot`
|
|
295
|
+
and `HardwareAssisted` as Viewport/OpenGL operations and `Software` as the active
|
|
296
|
+
software-renderer operation in the
|
|
297
|
+
[DzRenderOptions reference](https://docs.daz3d.com/public/software/dazstudio/4/referenceguide/scripting/api_reference/object_index/renderoptions_dz);
|
|
298
|
+
renderer lookup and activation are documented by
|
|
299
|
+
[DzRenderMgr](https://docs.daz3d.com/public/software/dazstudio/4/referenceguide/scripting/api_reference/object_index/rendermgr_dz).
|
|
300
|
+
|
|
301
|
+
---
|
|
302
|
+
|
|
303
|
+
## What's New in v2.8.0
|
|
304
|
+
|
|
305
|
+
### 🚦 Fail Fast When DAZ Studio Is Busy — `503 STUDIO_BUSY`
|
|
306
|
+
|
|
307
|
+
DAZ Studio's Qt main thread is single-threaded: if a user loads a scene,
|
|
308
|
+
saves, clears the scene, or renders through the DAZ Studio UI while the
|
|
309
|
+
server is also being driven remotely, requests that need the main thread
|
|
310
|
+
used to block indefinitely with no signal to the caller. `/execute`,
|
|
311
|
+
`/scripts/:id/execute`, the async-enqueue endpoints, and the render-submit
|
|
312
|
+
endpoints now check DAZ Studio's busy state first and return `503` with
|
|
313
|
+
`error_code: "STUDIO_BUSY"` (plus a `Retry-After` header) immediately
|
|
314
|
+
instead of hanging.
|
|
315
|
+
|
|
316
|
+
`dazpy` surfaces this as a new exception hierarchy — `DazBusyError`, with
|
|
317
|
+
`StudioBusyError` (503) and `ConcurrencyLimitError` (429) subclasses, each
|
|
318
|
+
carrying `reason` and `retry_after`. This also fixes a pre-existing bug
|
|
319
|
+
where `429 CONCURRENT_LIMIT_EXCEEDED` responses were misreported as
|
|
320
|
+
`ScriptRuntimeError`, as if the script itself had failed.
|
|
321
|
+
|
|
322
|
+
```python
|
|
323
|
+
from dazpy import DazClient
|
|
324
|
+
from dazpy.exceptions import DazBusyError
|
|
325
|
+
|
|
326
|
+
client = DazClient()
|
|
327
|
+
try:
|
|
328
|
+
result = client.execute("1+1;")
|
|
329
|
+
except DazBusyError as e:
|
|
330
|
+
print(f"DAZ Studio is busy: {e.reason} — retry after {e.retry_after}s")
|
|
331
|
+
```
|
|
332
|
+
|
|
333
|
+
Opt in to automatic retry with backoff instead of handling the exception
|
|
334
|
+
yourself:
|
|
335
|
+
|
|
336
|
+
```python
|
|
337
|
+
result = client.execute("1+1;", retry_on_busy=True, max_wait=30.0)
|
|
338
|
+
```
|
|
339
|
+
|
|
340
|
+
`retry_on_busy`/`max_wait` are available on `execute`, `execute_file`,
|
|
341
|
+
`execute_async_submit`, `render_submit`, `render_batch_submit`, and
|
|
342
|
+
`render_animation_submit`. Retry is opt-in and off by default — callers
|
|
343
|
+
(and any LLM driving them) stay informed rather than silently blocked.
|
|
344
|
+
|
|
345
|
+
---
|
|
346
|
+
|
|
172
347
|
## What's New in v2.7.2
|
|
173
348
|
|
|
174
349
|
No functional changes to `dazpy`'s behavior. `2.7.1`'s version bump missed
|
|
@@ -273,7 +448,7 @@ change. For dirty scenes it serialises via `Scene.saveScene()` and restores
|
|
|
273
448
|
the original filename immediately. The `method` field in the response tells
|
|
274
449
|
you which strategy was used.
|
|
275
450
|
|
|
276
|
-
See `
|
|
451
|
+
See [`fundamentals/scene_save_copy`](https://github.com/bluemoonfoundry/daz-script-server-examples/tree/main/fundamentals/scene_save_copy) in the examples repo for a complete example
|
|
277
452
|
with `--compare` and `--dry-run` options.
|
|
278
453
|
|
|
279
454
|
---
|
|
@@ -325,7 +500,7 @@ snapshot = scene.scene_snapshot()
|
|
|
325
500
|
profiles = build_rig_profiles_from_snapshot(snapshot)
|
|
326
501
|
```
|
|
327
502
|
|
|
328
|
-
**Body measurement accuracy improvements** in `
|
|
503
|
+
**Body measurement accuracy improvements** in [`geometry/body_measurements`](https://github.com/bluemoonfoundry/daz-script-server-examples/tree/main/geometry/body_measurements):
|
|
329
504
|
|
|
330
505
|
- Slices now use centroid-weighted torso loop selection to filter arm cross-sections, correcting a ~70 cm overestimate on A-pose figures.
|
|
331
506
|
- The heuristic fallback for unlabelled figures (e.g. a character named
|
|
@@ -505,11 +680,14 @@ print(anim.frame_range()) # (start, end)
|
|
|
505
680
|
anim.bake_pose_to_keyframes(start=0, end=60)
|
|
506
681
|
```
|
|
507
682
|
|
|
508
|
-
### 📐 math3 — Vec3, Quat, BoundingBox
|
|
683
|
+
### 📐 math3 — Vec3, Quat, BoundingBox, AxisRemap
|
|
509
684
|
|
|
510
685
|
New module **`dazpy.math3`** provides lightweight value types returned throughout
|
|
511
686
|
the SDK: `Vec3` (positions, translations), `Quat` (rotations), and `BoundingBox`
|
|
512
687
|
(geometry bounds). All support arithmetic operators and round-trip through JSON.
|
|
688
|
+
`AxisRemap` converts `Vec3`/`Quat`/`BoundingBox` values between axis conventions
|
|
689
|
+
via signed-axis permutations (e.g. the built-in `Y_UP_TO_Z_UP` preset for
|
|
690
|
+
converting DAZ Studio's Y-up scene data to Z-up tools like Blender).
|
|
513
691
|
|
|
514
692
|
### 🌐 Posed Vertex Export & USD Scene Export
|
|
515
693
|
|
|
@@ -517,7 +695,7 @@ the SDK: `Vec3` (positions, translations), `Quat` (rotations), and `BoundingBox`
|
|
|
517
695
|
positions with skinning and morphs already applied — enabling downstream export
|
|
518
696
|
pipelines to read the final mesh without re-solving the rig.
|
|
519
697
|
|
|
520
|
-
New example
|
|
698
|
+
New example **[`export/scene_to_usd`](https://github.com/bluemoonfoundry/daz-script-server-examples/tree/main/export/scene_to_usd)** uses this to export a full live
|
|
521
699
|
DAZ Studio scene to Pixar USD: posed meshes, cameras, lights, PBR materials, and
|
|
522
700
|
strand-based hair as `UsdGeom.BasisCurves`. Pass `--morphs` to write blend
|
|
523
701
|
shapes as `UsdSkel` targets.
|
|
@@ -555,8 +733,8 @@ Studio instance) now ship in the repo root.
|
|
|
555
733
|
|
|
556
734
|
### 📖 Docs & Ergonomics
|
|
557
735
|
|
|
558
|
-
- API reference pages for `DazPose`, `DazAnimation`, `Vec3`, `Quat`, and `
|
|
559
|
-
- Every script in
|
|
736
|
+
- API reference pages for `DazPose`, `DazAnimation`, `Vec3`, `Quat`, `BoundingBox`, and `AxisRemap`
|
|
737
|
+
- Every script in [daz-script-server-examples](https://github.com/bluemoonfoundry/daz-script-server-examples) has an `if __name__ == "__main__":` guard and
|
|
560
738
|
argparse `--help`, making all examples safe to import and self-documenting
|
|
561
739
|
|
|
562
740
|
---
|
|
@@ -620,6 +798,8 @@ Long-running operations (renders, exports, batch jobs) no longer need to block t
|
|
|
620
798
|
|
|
621
799
|
**TTL:** Completed, failed, and cancelled requests are automatically purged after 1 hour (cleanup timer fires every 5 minutes).
|
|
622
800
|
|
|
801
|
+
**Stale running requests:** If a request has been `running` for more than 30 minutes without completing — e.g. a render blocked behind a DAZ Studio modal dialog — it's automatically marked `failed` so polling clients aren't left waiting forever. The underlying DAZ Studio operation may still be stuck; check the DAZ Studio window directly if this happens.
|
|
802
|
+
|
|
623
803
|
---
|
|
624
804
|
|
|
625
805
|
## What's New in v1.2.0
|
|
@@ -667,7 +847,7 @@ automation code without authoring DazScript by hand.
|
|
|
667
847
|
Download the `.whl` file from the [latest release](https://github.com/bluemoonfoundry/daz-script-server/releases/latest) and install it:
|
|
668
848
|
|
|
669
849
|
```bash
|
|
670
|
-
pip install dazpy-2.
|
|
850
|
+
pip install dazpy-2.9.0-py3-none-any.whl
|
|
671
851
|
```
|
|
672
852
|
|
|
673
853
|
Or install directly from the repo for development:
|
|
@@ -1,21 +1,6 @@
|
|
|
1
|
-
Metadata-Version: 2.4
|
|
2
|
-
Name: dazpy
|
|
3
|
-
Version: 2.7.2
|
|
4
|
-
Summary: Python SDK for the DAZ Studio Script Server
|
|
5
|
-
License: MIT
|
|
6
|
-
Project-URL: Homepage, https://github.com/bluemoonfoundry/daz-script-server
|
|
7
|
-
Project-URL: Repository, https://github.com/bluemoonfoundry/daz-script-server
|
|
8
|
-
Project-URL: Bug Tracker, https://github.com/bluemoonfoundry/daz-script-server/issues
|
|
9
|
-
Requires-Python: >=3.10
|
|
10
|
-
Description-Content-Type: text/markdown
|
|
11
|
-
Requires-Dist: requests>=2.28
|
|
12
|
-
Provides-Extra: docs
|
|
13
|
-
Requires-Dist: sphinx>=7.0; extra == "docs"
|
|
14
|
-
Requires-Dist: sphinx-rtd-theme>=2.0; extra == "docs"
|
|
15
|
-
|
|
16
1
|
# DazScript Server
|
|
17
2
|
|
|
18
|
-
**Version 2.
|
|
3
|
+
**Version 2.9.0** | DAZ Studio 4.5+ | DAZ Studio 6.25+ | Windows & macOS
|
|
19
4
|
|
|
20
5
|
[](https://bluemoonfoundry.github.io/daz-script-server/)
|
|
21
6
|
[](https://bluemoonfoundry.github.io/daz-script-server/api-reference/)
|
|
@@ -83,6 +68,8 @@ print(response.json())
|
|
|
83
68
|
### Getting Started
|
|
84
69
|
- [Quick Start](#-quick-start)
|
|
85
70
|
- [Why This Exists](#why-this-exists)
|
|
71
|
+
- [What's New in v2.9.0](#whats-new-in-v290)
|
|
72
|
+
- [What's New in v2.8.0](#whats-new-in-v280)
|
|
86
73
|
- [What's New in v2.7.2](#whats-new-in-v272)
|
|
87
74
|
- [What's New in v2.7.1](#whats-new-in-v271)
|
|
88
75
|
- [What's New in v2.7.0](#whats-new-in-v270)
|
|
@@ -169,6 +156,177 @@ DAZ Studio is powerful for 3D content creation, but automation is limited to man
|
|
|
169
156
|
|
|
170
157
|
---
|
|
171
158
|
|
|
159
|
+
## What's New in v2.9.0
|
|
160
|
+
|
|
161
|
+
### 🎬 dazpy.cinematics — camera shot builders
|
|
162
|
+
|
|
163
|
+
`dazpy.cinematics` packages common camera choreography on top of
|
|
164
|
+
`DazCamera`/`DazScene`: `apply_static_shot()` places/aims/configures a
|
|
165
|
+
camera in one call; `apply_orbit_camera()` sweeps a camera around a target
|
|
166
|
+
across a frame range; `apply_frame_subject()` frames a subject at a named
|
|
167
|
+
shot distance (`close_up` / `medium` / `full_body`); and
|
|
168
|
+
`apply_animated_shot()` writes real, interpolated DAZ Studio keyframes at a
|
|
169
|
+
sequence of waypoints instead of baking a value on every frame.
|
|
170
|
+
|
|
171
|
+
```python
|
|
172
|
+
from dazpy.cinematics import OrbitCamera, apply_orbit_camera
|
|
173
|
+
|
|
174
|
+
apply_orbit_camera(scene, OrbitCamera(target=figure, radius=250, frame_start=0, frame_end=90))
|
|
175
|
+
```
|
|
176
|
+
|
|
177
|
+
### 💡 dazpy.lighting — three-point rigs and HDRI environments
|
|
178
|
+
|
|
179
|
+
`apply_three_point_light_setup()` creates and places a key/fill/rim light
|
|
180
|
+
rig around a target in one call, via angle/distance placement or explicit
|
|
181
|
+
world-space positions per light. `apply_hdri_environment()` applies
|
|
182
|
+
image-based dome lighting — map, intensity, rotation, dome/scene mode,
|
|
183
|
+
visibility, and IBL resolution — validating the image path up front and
|
|
184
|
+
verifying a post-apply readback so a silent failure never passes as success.
|
|
185
|
+
|
|
186
|
+
### 🧍 dazpy.poses — apply_pose, reset_transforms, zero_figure
|
|
187
|
+
|
|
188
|
+
Common pose operations without hand-assembling a `DazPose`:
|
|
189
|
+
`apply_pose()` applies a pose object or a JSON file path directly to a
|
|
190
|
+
skeleton; `reset_transforms()` zeroes a node's local position/rotation and
|
|
191
|
+
resets scale to 1.0; `zero_figure()` drives every bone rotation and morph
|
|
192
|
+
to zero while leaving the figure's root transform untouched by default.
|
|
193
|
+
|
|
194
|
+
### 📐 dazpy.math3.AxisRemap — coordinate-space conversion
|
|
195
|
+
|
|
196
|
+
A generic signed-axis-permutation converter for `Vec3`/`Quat`/
|
|
197
|
+
`BoundingBox` between coordinate conventions, with a ready-made
|
|
198
|
+
`Y_UP_TO_Z_UP` preset for moving data from DAZ Studio (Y-up) into
|
|
199
|
+
Blender/glTF-style Z-up pipelines.
|
|
200
|
+
|
|
201
|
+
```python
|
|
202
|
+
from dazpy.math3 import Y_UP_TO_Z_UP
|
|
203
|
+
|
|
204
|
+
blender_pos = Y_UP_TO_Z_UP.apply_vec3(daz_pos)
|
|
205
|
+
```
|
|
206
|
+
|
|
207
|
+
### 🦴 DazSkeleton.bone_rotations_quat()
|
|
208
|
+
|
|
209
|
+
Returns local-space quaternion rotations for every bone in one HTTP
|
|
210
|
+
round-trip — the composable counterpart to `bone_rotations()` for callers
|
|
211
|
+
feeding the result into another rotation (e.g. `AxisRemap.apply_quat()`),
|
|
212
|
+
sidestepping the per-bone Euler rotation-order tracking that would
|
|
213
|
+
otherwise be required.
|
|
214
|
+
|
|
215
|
+
### 🎞️ Frame-level progress streaming for animation renders
|
|
216
|
+
|
|
217
|
+
The `GET /render/:id/progress` SSE stream now emits a progress event at
|
|
218
|
+
each frame boundary during an animation render, instead of only start/
|
|
219
|
+
terminal events — the DAZ SDK exposes no per-percent render progress
|
|
220
|
+
signal, so this frame-level marker is the most granular progress available.
|
|
221
|
+
|
|
222
|
+
### ⚡ Async client — `dazpy.aio.AsyncDazClient`
|
|
223
|
+
|
|
224
|
+
Async frameworks (FastAPI, FastMCP, ComfyUI custom nodes, asyncio/Temporal
|
|
225
|
+
workflows) previously had to wrap every `DazClient` call in
|
|
226
|
+
`asyncio.to_thread()` or hand-roll an `httpx.AsyncClient` wrapper.
|
|
227
|
+
`dazpy.aio.AsyncDazClient` mirrors `DazClient`'s full method surface —
|
|
228
|
+
`execute`, `execute_file`, async submit/status/result/list/cancel, render
|
|
229
|
+
submit/batch/animation, USD export, and server-health endpoints — as
|
|
230
|
+
native `async def` methods backed by `httpx.AsyncClient`, including the
|
|
231
|
+
same `retry_on_busy`/`max_wait` backoff semantics (via `asyncio.sleep`
|
|
232
|
+
instead of blocking `time.sleep`).
|
|
233
|
+
|
|
234
|
+
```python
|
|
235
|
+
from dazpy.aio import AsyncDazClient
|
|
236
|
+
|
|
237
|
+
async def main():
|
|
238
|
+
async with AsyncDazClient() as client:
|
|
239
|
+
result = await client.execute("1 + 1;")
|
|
240
|
+
print(result.value)
|
|
241
|
+
```
|
|
242
|
+
|
|
243
|
+
Requires the optional `httpx` dependency: `pip install dazpy[aio]`.
|
|
244
|
+
|
|
245
|
+
### `DazClient` connection pooling + `close()`
|
|
246
|
+
|
|
247
|
+
`DazClient` now issues requests through a pooled `requests.Session` instead
|
|
248
|
+
of a fresh connection per call, and supports `close()` / use as a context
|
|
249
|
+
manager (`with DazClient() as client:`) for symmetry with the new async
|
|
250
|
+
client's connection lifecycle.
|
|
251
|
+
|
|
252
|
+
### Truthful Iray/Viewport render-engine selector
|
|
253
|
+
|
|
254
|
+
`DazRenderSettings.render_engine_state()` now reads the effective
|
|
255
|
+
`DzRenderOptions.renderType` value and the active renderer class/name as separate
|
|
256
|
+
facts. Its schema-1 record includes the raw enum value/name, normalized
|
|
257
|
+
`verified_iray` / `verified_non_iray` / `unavailable` status, and field-level
|
|
258
|
+
live-readback provenance. A retained `NVIDIA Iray` active-renderer name never
|
|
259
|
+
overrides a Viewport/OpenGL `renderType`.
|
|
260
|
+
|
|
261
|
+
`DazRenderSettings.set_render_engine("iray" | "viewport")` is an explicit
|
|
262
|
+
persistent setter. It selects the registered `DzIrayRenderer` plus `Software` for
|
|
263
|
+
Iray, or `ScreenShot` for Viewport, calls `applyChanges()`, and returns only after
|
|
264
|
+
exact readback. Missing renderers, mutation/apply faults, malformed replies, and
|
|
265
|
+
readback disagreement raise `RenderError`; unknown engine names raise `ValueError`
|
|
266
|
+
before dispatch.
|
|
267
|
+
|
|
268
|
+
```python
|
|
269
|
+
settings = DazRenderSettings(client)
|
|
270
|
+
before = settings.render_engine_state()
|
|
271
|
+
change = settings.set_render_engine("iray")
|
|
272
|
+
assert change["readback"]["status"] == "verified_iray"
|
|
273
|
+
```
|
|
274
|
+
|
|
275
|
+
The `engine` field on `/render`, `/render/batch`, and `/render/animation` also
|
|
276
|
+
accepts `viewport` and uses the same fail-closed mutation/readback rules. These
|
|
277
|
+
operations intentionally persist the requested engine. DAZ documents `ScreenShot`
|
|
278
|
+
and `HardwareAssisted` as Viewport/OpenGL operations and `Software` as the active
|
|
279
|
+
software-renderer operation in the
|
|
280
|
+
[DzRenderOptions reference](https://docs.daz3d.com/public/software/dazstudio/4/referenceguide/scripting/api_reference/object_index/renderoptions_dz);
|
|
281
|
+
renderer lookup and activation are documented by
|
|
282
|
+
[DzRenderMgr](https://docs.daz3d.com/public/software/dazstudio/4/referenceguide/scripting/api_reference/object_index/rendermgr_dz).
|
|
283
|
+
|
|
284
|
+
---
|
|
285
|
+
|
|
286
|
+
## What's New in v2.8.0
|
|
287
|
+
|
|
288
|
+
### 🚦 Fail Fast When DAZ Studio Is Busy — `503 STUDIO_BUSY`
|
|
289
|
+
|
|
290
|
+
DAZ Studio's Qt main thread is single-threaded: if a user loads a scene,
|
|
291
|
+
saves, clears the scene, or renders through the DAZ Studio UI while the
|
|
292
|
+
server is also being driven remotely, requests that need the main thread
|
|
293
|
+
used to block indefinitely with no signal to the caller. `/execute`,
|
|
294
|
+
`/scripts/:id/execute`, the async-enqueue endpoints, and the render-submit
|
|
295
|
+
endpoints now check DAZ Studio's busy state first and return `503` with
|
|
296
|
+
`error_code: "STUDIO_BUSY"` (plus a `Retry-After` header) immediately
|
|
297
|
+
instead of hanging.
|
|
298
|
+
|
|
299
|
+
`dazpy` surfaces this as a new exception hierarchy — `DazBusyError`, with
|
|
300
|
+
`StudioBusyError` (503) and `ConcurrencyLimitError` (429) subclasses, each
|
|
301
|
+
carrying `reason` and `retry_after`. This also fixes a pre-existing bug
|
|
302
|
+
where `429 CONCURRENT_LIMIT_EXCEEDED` responses were misreported as
|
|
303
|
+
`ScriptRuntimeError`, as if the script itself had failed.
|
|
304
|
+
|
|
305
|
+
```python
|
|
306
|
+
from dazpy import DazClient
|
|
307
|
+
from dazpy.exceptions import DazBusyError
|
|
308
|
+
|
|
309
|
+
client = DazClient()
|
|
310
|
+
try:
|
|
311
|
+
result = client.execute("1+1;")
|
|
312
|
+
except DazBusyError as e:
|
|
313
|
+
print(f"DAZ Studio is busy: {e.reason} — retry after {e.retry_after}s")
|
|
314
|
+
```
|
|
315
|
+
|
|
316
|
+
Opt in to automatic retry with backoff instead of handling the exception
|
|
317
|
+
yourself:
|
|
318
|
+
|
|
319
|
+
```python
|
|
320
|
+
result = client.execute("1+1;", retry_on_busy=True, max_wait=30.0)
|
|
321
|
+
```
|
|
322
|
+
|
|
323
|
+
`retry_on_busy`/`max_wait` are available on `execute`, `execute_file`,
|
|
324
|
+
`execute_async_submit`, `render_submit`, `render_batch_submit`, and
|
|
325
|
+
`render_animation_submit`. Retry is opt-in and off by default — callers
|
|
326
|
+
(and any LLM driving them) stay informed rather than silently blocked.
|
|
327
|
+
|
|
328
|
+
---
|
|
329
|
+
|
|
172
330
|
## What's New in v2.7.2
|
|
173
331
|
|
|
174
332
|
No functional changes to `dazpy`'s behavior. `2.7.1`'s version bump missed
|
|
@@ -273,7 +431,7 @@ change. For dirty scenes it serialises via `Scene.saveScene()` and restores
|
|
|
273
431
|
the original filename immediately. The `method` field in the response tells
|
|
274
432
|
you which strategy was used.
|
|
275
433
|
|
|
276
|
-
See `
|
|
434
|
+
See [`fundamentals/scene_save_copy`](https://github.com/bluemoonfoundry/daz-script-server-examples/tree/main/fundamentals/scene_save_copy) in the examples repo for a complete example
|
|
277
435
|
with `--compare` and `--dry-run` options.
|
|
278
436
|
|
|
279
437
|
---
|
|
@@ -325,7 +483,7 @@ snapshot = scene.scene_snapshot()
|
|
|
325
483
|
profiles = build_rig_profiles_from_snapshot(snapshot)
|
|
326
484
|
```
|
|
327
485
|
|
|
328
|
-
**Body measurement accuracy improvements** in `
|
|
486
|
+
**Body measurement accuracy improvements** in [`geometry/body_measurements`](https://github.com/bluemoonfoundry/daz-script-server-examples/tree/main/geometry/body_measurements):
|
|
329
487
|
|
|
330
488
|
- Slices now use centroid-weighted torso loop selection to filter arm cross-sections, correcting a ~70 cm overestimate on A-pose figures.
|
|
331
489
|
- The heuristic fallback for unlabelled figures (e.g. a character named
|
|
@@ -505,11 +663,14 @@ print(anim.frame_range()) # (start, end)
|
|
|
505
663
|
anim.bake_pose_to_keyframes(start=0, end=60)
|
|
506
664
|
```
|
|
507
665
|
|
|
508
|
-
### 📐 math3 — Vec3, Quat, BoundingBox
|
|
666
|
+
### 📐 math3 — Vec3, Quat, BoundingBox, AxisRemap
|
|
509
667
|
|
|
510
668
|
New module **`dazpy.math3`** provides lightweight value types returned throughout
|
|
511
669
|
the SDK: `Vec3` (positions, translations), `Quat` (rotations), and `BoundingBox`
|
|
512
670
|
(geometry bounds). All support arithmetic operators and round-trip through JSON.
|
|
671
|
+
`AxisRemap` converts `Vec3`/`Quat`/`BoundingBox` values between axis conventions
|
|
672
|
+
via signed-axis permutations (e.g. the built-in `Y_UP_TO_Z_UP` preset for
|
|
673
|
+
converting DAZ Studio's Y-up scene data to Z-up tools like Blender).
|
|
513
674
|
|
|
514
675
|
### 🌐 Posed Vertex Export & USD Scene Export
|
|
515
676
|
|
|
@@ -517,7 +678,7 @@ the SDK: `Vec3` (positions, translations), `Quat` (rotations), and `BoundingBox`
|
|
|
517
678
|
positions with skinning and morphs already applied — enabling downstream export
|
|
518
679
|
pipelines to read the final mesh without re-solving the rig.
|
|
519
680
|
|
|
520
|
-
New example
|
|
681
|
+
New example **[`export/scene_to_usd`](https://github.com/bluemoonfoundry/daz-script-server-examples/tree/main/export/scene_to_usd)** uses this to export a full live
|
|
521
682
|
DAZ Studio scene to Pixar USD: posed meshes, cameras, lights, PBR materials, and
|
|
522
683
|
strand-based hair as `UsdGeom.BasisCurves`. Pass `--morphs` to write blend
|
|
523
684
|
shapes as `UsdSkel` targets.
|
|
@@ -555,8 +716,8 @@ Studio instance) now ship in the repo root.
|
|
|
555
716
|
|
|
556
717
|
### 📖 Docs & Ergonomics
|
|
557
718
|
|
|
558
|
-
- API reference pages for `DazPose`, `DazAnimation`, `Vec3`, `Quat`, and `
|
|
559
|
-
- Every script in
|
|
719
|
+
- API reference pages for `DazPose`, `DazAnimation`, `Vec3`, `Quat`, `BoundingBox`, and `AxisRemap`
|
|
720
|
+
- Every script in [daz-script-server-examples](https://github.com/bluemoonfoundry/daz-script-server-examples) has an `if __name__ == "__main__":` guard and
|
|
560
721
|
argparse `--help`, making all examples safe to import and self-documenting
|
|
561
722
|
|
|
562
723
|
---
|
|
@@ -620,6 +781,8 @@ Long-running operations (renders, exports, batch jobs) no longer need to block t
|
|
|
620
781
|
|
|
621
782
|
**TTL:** Completed, failed, and cancelled requests are automatically purged after 1 hour (cleanup timer fires every 5 minutes).
|
|
622
783
|
|
|
784
|
+
**Stale running requests:** If a request has been `running` for more than 30 minutes without completing — e.g. a render blocked behind a DAZ Studio modal dialog — it's automatically marked `failed` so polling clients aren't left waiting forever. The underlying DAZ Studio operation may still be stuck; check the DAZ Studio window directly if this happens.
|
|
785
|
+
|
|
623
786
|
---
|
|
624
787
|
|
|
625
788
|
## What's New in v1.2.0
|
|
@@ -667,7 +830,7 @@ automation code without authoring DazScript by hand.
|
|
|
667
830
|
Download the `.whl` file from the [latest release](https://github.com/bluemoonfoundry/daz-script-server/releases/latest) and install it:
|
|
668
831
|
|
|
669
832
|
```bash
|
|
670
|
-
pip install dazpy-2.
|
|
833
|
+
pip install dazpy-2.9.0-py3-none-any.whl
|
|
671
834
|
```
|
|
672
835
|
|
|
673
836
|
Or install directly from the repo for development:
|
|
@@ -13,7 +13,7 @@ Typical usage::
|
|
|
13
13
|
figure.find_bone("r_forearm").set_local_rotation(0, 0, 45)
|
|
14
14
|
"""
|
|
15
15
|
|
|
16
|
-
__version__ = "2.
|
|
16
|
+
__version__ = "2.9.0"
|
|
17
17
|
|
|
18
18
|
from ._client import DazClient
|
|
19
19
|
from ._scene import DazScene
|
|
@@ -76,7 +76,37 @@ from ._undo import UndoGroup
|
|
|
76
76
|
from ._pose import DazPose
|
|
77
77
|
from ._scene_state import DazSceneState
|
|
78
78
|
from ._animation import DazAnimation
|
|
79
|
-
from .math3 import Vec3, Quat, BoundingBox
|
|
79
|
+
from .math3 import Vec3, Quat, BoundingBox, AxisRemap, Y_UP_TO_Z_UP
|
|
80
|
+
from .lighting import (
|
|
81
|
+
LightSpec,
|
|
82
|
+
ThreePointLightSetup,
|
|
83
|
+
ThreePointLightRig,
|
|
84
|
+
apply_three_point_light_setup,
|
|
85
|
+
HDRIEnvironment,
|
|
86
|
+
apply_hdri_environment,
|
|
87
|
+
set_light_color,
|
|
88
|
+
)
|
|
89
|
+
from .poses import apply_pose, reset_transforms, zero_figure
|
|
90
|
+
from .materials import (
|
|
91
|
+
IrayMaterial,
|
|
92
|
+
TextureMap,
|
|
93
|
+
SurfaceProperty,
|
|
94
|
+
apply_iray_material,
|
|
95
|
+
apply_texture_map,
|
|
96
|
+
get_surface_property,
|
|
97
|
+
set_surface_property,
|
|
98
|
+
)
|
|
99
|
+
from .cinematics import (
|
|
100
|
+
CinematicStaticShot,
|
|
101
|
+
OrbitCamera,
|
|
102
|
+
FrameSubject,
|
|
103
|
+
CameraKeyframe,
|
|
104
|
+
CinematicAnimatedShot,
|
|
105
|
+
apply_static_shot,
|
|
106
|
+
apply_orbit_camera,
|
|
107
|
+
apply_frame_subject,
|
|
108
|
+
apply_animated_shot,
|
|
109
|
+
)
|
|
80
110
|
from ._result import ExecutionResult
|
|
81
111
|
from ._polling import execute_long
|
|
82
112
|
from ._render_api import (
|
|
@@ -87,7 +117,7 @@ from ._render_api import (
|
|
|
87
117
|
render,
|
|
88
118
|
render_variants,
|
|
89
119
|
)
|
|
90
|
-
from .exceptions import RenderError
|
|
120
|
+
from .exceptions import RenderError, MaterialError
|
|
91
121
|
from ._scene_events import SceneEvent, watch_scene_events, wait_for_scene_event
|
|
92
122
|
from . import exceptions
|
|
93
123
|
|
|
@@ -158,6 +188,34 @@ __all__ = [
|
|
|
158
188
|
"Vec3",
|
|
159
189
|
"Quat",
|
|
160
190
|
"BoundingBox",
|
|
191
|
+
"AxisRemap",
|
|
192
|
+
"Y_UP_TO_Z_UP",
|
|
193
|
+
"LightSpec",
|
|
194
|
+
"ThreePointLightSetup",
|
|
195
|
+
"ThreePointLightRig",
|
|
196
|
+
"apply_three_point_light_setup",
|
|
197
|
+
"HDRIEnvironment",
|
|
198
|
+
"apply_hdri_environment",
|
|
199
|
+
"set_light_color",
|
|
200
|
+
"apply_pose",
|
|
201
|
+
"reset_transforms",
|
|
202
|
+
"zero_figure",
|
|
203
|
+
"IrayMaterial",
|
|
204
|
+
"TextureMap",
|
|
205
|
+
"SurfaceProperty",
|
|
206
|
+
"apply_iray_material",
|
|
207
|
+
"apply_texture_map",
|
|
208
|
+
"get_surface_property",
|
|
209
|
+
"set_surface_property",
|
|
210
|
+
"CinematicStaticShot",
|
|
211
|
+
"OrbitCamera",
|
|
212
|
+
"FrameSubject",
|
|
213
|
+
"CameraKeyframe",
|
|
214
|
+
"CinematicAnimatedShot",
|
|
215
|
+
"apply_static_shot",
|
|
216
|
+
"apply_orbit_camera",
|
|
217
|
+
"apply_frame_subject",
|
|
218
|
+
"apply_animated_shot",
|
|
161
219
|
"ExecutionResult",
|
|
162
220
|
"execute_long",
|
|
163
221
|
"FigureMorphs",
|
|
@@ -165,6 +223,7 @@ __all__ = [
|
|
|
165
223
|
"RenderBase",
|
|
166
224
|
"RenderResult",
|
|
167
225
|
"RenderError",
|
|
226
|
+
"MaterialError",
|
|
168
227
|
"render",
|
|
169
228
|
"render_variants",
|
|
170
229
|
"SceneEvent",
|