Skip to content

Release 0.3.0

Pre-release
Pre-release

Choose a tag to compare

@ignaci ignaci released this 18 May 17:34

Added

  • Upgrade skill to migrate an existing codebase from 0.2.0 to 0.3.0. Ask your agent to "upgrade from 0.2 to 0.3".
  • New root-stage loading API. In C, ovrtx_open_usd_from_file() and ovrtx_open_usd_from_string() replace the active root layer, while ovrtx_add_usd_reference_from_file() and ovrtx_add_usd_reference_from_string() add removable referenced content below a caller-provided prefix path so multiple layers can be composed under separate prims. Exposed in Python as Renderer.open_usd() / open_usd_from_string() / add_usd_reference() / add_usd_reference_from_string() and their _async variants.
  • ovrtx_register_schema_paths() for publishing ovrtx USD schema/plugin paths before any shared OpenUSD runtime is initialized. Python exposes register_schema_paths() and auto-registers on import ovrtx unless OVRTX_SKIP_SCHEMA_AUTO_REGISTER=1 is set.
  • Stage query API for discovering prims and their attribute schemas. In C, ovrtx_query_prims() / ovrtx_fetch_query_results() / ovrtx_release_query_results() return prims grouped by shared attribute schema, with AND/OR/NOT filters on prim type and attribute presence. The returned prim_list_handle plugs directly into subsequent read/write bindings. Exposed in Python as Renderer.query_prims() / query_prims_async().
  • Stage attribute read API. In C, ovrtx_read_attribute() / ovrtx_fetch_read_result() / ovrtx_release_read_result() enqueue stream-ordered reads of scalar or array attributes and optionally write into a caller-provided ovrtx_read_dest_t tensor (including GPU/CUDA destinations). Exposed in Python as Renderer.read_attribute() / read_array_attribute() and their _async variants.
  • Expanded attribute write and mapping APIs. Python writes now accept CPU or GPU DLPack-compatible tensors directly, support synchronous or asynchronous data access with CUDA stream/event synchronization, and can use persistent AttributeBinding handles or direct Renderer.map_attribute() / AttributeMapping.unmap_async() workflows for repeated updates and caller-managed lifetimes.
  • ovrtx_get_path_dictionary() to obtain the renderer's path dictionary for converting between tokens/path handles and strings, and for pre-resolving filter names for repeated queries.
  • Lidar and radar sensor support, including composite PointCloud render variables with named tensors for channels such as coordinates, intensity, velocity, radar cross section, flags, and counts; see the new C/Python lidar and radar sensor examples.
  • Viewport picking and selection outline support. Applications can enqueue RenderProduct-space pick rectangles with ovrtx_enqueue_pick_query() / Renderer.enqueue_pick_query_async(), read the synthetic pick-hit render var, resolve picked prim paths through the path dictionary, and draw selection outlines by writing selection outline group attributes. The C API also adds ovrtx_set_selection_group_styles(), ovrtx_set_selection_outline_group(), and ovrtx_set_pickable(); Python adds SelectionGroupStyle, SelectionFillMode, and Renderer.set_selection_group_styles(). The Vulkan interop example now demonstrates click picking, marquee selection with a Vulkan overlay rectangle, selected-prim path printing, and styled ovrtx selection outlines with translucent fill.
  • New renderer configuration controls: OVRTX_CONFIG_SELECTION_OUTLINE_ENABLED, OVRTX_CONFIG_SELECTION_OUTLINE_WIDTH, OVRTX_CONFIG_SELECTION_FILL_MODE, OVRTX_CONFIG_ENABLE_GEOMETRY_STREAMING, OVRTX_CONFIG_ENABLE_GEOMETRY_STREAMING_LOD, and experimental OVRTX_CONFIG_ENABLE_SPG, plus matching C helper functions and RendererConfig fields. ovrtx_config.h also includes typed config-entry constructors such as ovrtx_config_entry_bool(), ovrtx_config_entry_string(), ovrtx_config_entry_int(), and ovrtx_config_entry_binary_package_root_path().
  • Windows ovrtx binaries are now Authenticode-signed so Windows deployments can verify the publisher and avoid unsigned-binary trust warnings.
  • ovrtx packages can connect to DDCS servers through the renderer-plugin version of GRPCDataStore, enabling DDCS-backed workflows such as IsaacLab and Windows deployments.
  • New attribute semantics for query results: OVRTX_SEMANTIC_TOKEN_ID, OVRTX_SEMANTIC_PATH_ID, and OVRTX_SEMANTIC_TAG (name-only tag attributes with no data).
  • Python: Renderer.update_from_usd_time_async() to schedule a stage-time update asynchronously, Operation.query_status() for polling operation progress, and AttributeMapping.unmap_async() for asynchronous attribute-map commits.
  • Python public surface expanded in ovrtx.__init__: AttributeFilterMode, FilterKind, BindingFlag, EventStatus, SelectionFillMode, SelectionGroupStyle, AttributeInfo, AttributeBinding, AttributeMapping, FrameOutput, ProductOutput, RenderProductSetOutputs, RenderVarOutput, RenderVarParam, RenderVarTensor, Operation, OperationCounter, OperationStatus, PendingFetch, MappedRenderVar, and ManagedDLTensor.
  • New examples: C Material Editor, C/Python status queries, Python tiled rendering, Python semantic segmentation, and C/Python lidar and radar sensor examples.
  • Expanded documentation and skills for camera RenderVars, render modes, render settings, sensor configuration, render output interpretation, lidar/radar point clouds, semantic labels, material binding, viewport picking/selection, stage queries, attribute reads, and status queries.

Changed

  • Root-stage composition is now explicit: open_usd* owns the single active root layer and replaces any previous root, while add_usd_reference* is only for additive, removable references under an already-open root stage.
  • ovrtx_wait_op() now returns only the op ids that produced errors plus the lowest still-pending op id, instead of an inline list of error strings and all active op ids. Error strings are retrieved per-id via ovrtx_get_last_op_error() and are transient thread-local data invalidated by the next ovrtx_wait_op() on the same thread. The separate ovrtx_release_errors cleanup step is no longer needed.
  • Logging callbacks are now process-global instead of renderer-scoped. ovrtx_set_log_callback() no longer takes a renderer, ovrtx_log_callback_t no longer receives an op id, timestamps are wall-clock seconds, severity values now mirror carb log levels (INFO=-1, WARNING=0, ERROR=1, FATAL=2), and ovrtx_flush_op_log() is replaced by ovrtx_flush_log(). The channel_filter string now accepts comma-separated <channel_prefix>=<level> rules with longest-prefix matching and RUST_LOG-style level names.
  • ovrtx_query_extension() is documented as internal-only and unsupported for public API compatibility guarantees.
  • Documentation clarified: ovx_string_t consumers should prefer the explicit length field over relying on the null terminator, and strings returned from ovrtx_get_last_error() should be copied or consumed before the next API call on the same thread.
  • Render-variable outputs are now multi-tensor capable. The C struct ovrtx_rendered_output_t is replaced by ovrtx_render_var_output_t, exposing named tensors[] and params[] arrays and a single cuda_sync field; the corresponding handle types and ovrtx_map_rendered_output / ovrtx_unmap_rendered_output are renamed to ovrtx_render_var_output_*. C consumers must recompile and migrate field accesses. Python MappedRenderVar exposes tensors via dict access (rv["name"]) or DLPack on the mapping itself for single-tensor render variables; the legacy MappedRenderVar.tensor accessor still works for single-tensor render variables but emits DeprecationWarning and will be removed. See the refreshed docs/sensors/configuration.rst, the reading-render-output skill, and examples/{c,python}/minimal for the new usage.
  • Image RenderVar tensors now use channel-last shapes such as [height, width, channels] with scalar DLPack lanes.
  • Python MappedRenderVar mappings now have a consumer-owned lifetime: the underlying buffer stays valid as long as any DLPack-derived array, RenderVarTensor, or RenderVarParam view holds a reference, even after unmap() or context-manager exit. ManagedDLTensor.numpy() is a zero-copy view; use .copy() while the mapping is live when an independent array is needed. See the MappedRenderVar docstring and the reading-render-output skill for the full contract.
  • Python Renderer.step_async() now follows the standard two-phase async lifecycle: it returns Operation[PendingFetch[RenderProductSetOutputs]]; call wait() to wait for rendering and fetch() to retrieve outputs. Synchronous Renderer.step() still waits and fetches for callers.
  • RendererConfig.keep_system_alive now defaults to enabled in the native layer, reducing teardown/recreate churn for multi-renderer lifecycles.
  • Multi-GPU RenderProducts without authored deviceIds are now auto-assigned to GPU devices at RenderProduct creation time when multiple devices are active.
  • Tiled rendering workloads with many RenderProducts or cameras now spend less CPU time updating per-view tile parameters.
  • GPU transform mode now supports per-tick TLAS updates during multi-tick steps, improving dynamic-scene behavior when GPU transform propagation is enabled.
  • License text was updated to the current NVIDIA Software License Agreement and Product Specific Terms for NVIDIA AI Products.

Fixed

  • Fixed Python DLPack/render-var/attribute mapping lifetime issues, including AttributeBinding.write() after unbind(), empty prim_paths=[] writes, leaked or locked attribute mappings outside a context manager, abandoned async step handles, double-unmap on exceptions, failed DLTensor construction after a successful C map, and renderer teardown with active mappings or bindings.
  • Fixed Python import/library discovery failures caused by inaccessible Windows PATH entries such as WindowsApps.
  • Fixed ovrtx schema/plugin discovery when running from non-Kit executables, from Python, or in processes that also load another USD-based subsystem, including the missing OmniPlaybackAPI schema warning when loading materials.
  • ovrtx now vendors OpenUSD libraries that are namespaced to avoid symbol collisions. OpenUSD and usd-core can now be used in the same process as ovrtx without issue.
  • Fixed logging callback flush/lost-wakeup races and applied init-time log file/log level settings when the first renderer is created.
  • Fixed multi-GPU picking readback device mismatches and related selection-outline ordering issues.
  • Fixed CUDA interop failures including BAR1/NVML permission handling and Vulkan sparse-buffer corruption cases.
  • Fixed a Windows rendering issue where every other frame could be black during repeated transform-update rendering.
  • Fixed dataWindowNDC on RenderProduct prims so mapped output tensors reflect the cropped output size instead of always returning the full authored resolution.
  • Fixed texture-processing failures for invalid texture inputs that could emit TextureProcessor : Failed to process texture ... errors.
  • Fixed crashes or incorrect updates around time-sampled visibility, GPU point updates, and stage loading regressions.
  • Fixed package/deploy issues including missing shader cache content, missing CMake config files, and recursive dependency updates for nested Python examples.

Removed

  • OVRTX_CONFIG_OUTPUT_PARTIAL_FRAMES and the corresponding ovrtx_config_entry_output_partial_frames() helper. Partial-frame output is now controlled per render product via the USD attribute bool omni:sensor:Core:accumulateOutputs on the camera prim (defaults to false, i.e. partial frames are emitted every step — the same as the old default). Setting it to true suppresses partial frames for that sensor and only emits a frame once the exposure has been fully accumulated.
  • ovrtx_add_usd() and ovrtx_usd_input_t. Use ovrtx_open_usd_from_file() / ovrtx_open_usd_from_string() for root-stage loading and ovrtx_add_usd_reference_from_file() / ovrtx_add_usd_reference_from_string() for additive references.
  • Python: Renderer.add_usd(), Renderer.add_usd_layer(), and their async variants. Use open_usd* for root-stage loading and add_usd_reference* for additive references.
  • Python: the RendererResult export. Renderer.step_async() returns Operation[PendingFetch[RenderProductSetOutputs]].

Security

  • Updated OpenSSL to 3.5.6 for use-after-free and heap-buffer-overflow fixes, updated PerfSDK to remove bundled Python 3.10.5 CVE exposure, and refreshed USD, GLib/GStreamer, and Python dependency pins for security fixes.

Limitations

  • Viewport picking currently only works for RenderProducts running on CUDA-visible GPU 0. On multi-GPU systems, author uint[] deviceIds = [0] on RenderProducts that are used for picking. deviceIds is an allow-list of indices into CUDA_VISIBLE_DEVICES; ovrtx may choose any CUDA-visible GPU from the list.
  • On Linux systems with no display, repeatedly creating and destroying renderers may result in a crash with the stack trace pointing into libEGL.so when shared graphics resources are torn down between renderers. This can happen if keep_system_alive is configured to false, or if ovrtx_initialize() is not called before the multi-renderer lifecycle. In the implicit-initialization pattern (when ovrtx_initialize() is not called), the keep_system_alive config setting is effectively ignored. Avoid this by both configuring keep_system_alive to true (RendererConfig(keep_system_alive=True) in Python, ovrtx_config_entry_keep_system_alive(true) in C) and calling ovrtx_initialize() before creating renderers. If this is not possible, or the crash persists, a further workaround is to set the environment variable VK_LOADER_DISABLE_DYNAMIC_LIBRARY_UNLOADING=1.
  • When ovrtx is used together with ovPhysX in the same process, ovrtx must be initialized first. In Python, this means import ovrtx must come before import ovphysx. In C/C++, call ovrtx_initialize() before initializing ovPhysX.

Python Wheels