Python API Reference#
High-level Python API for the ovphysx library.
Stream-Ordered Execution Model#
All operations in this API are stream-ordered, meaning they execute in submission order as if on a single queue. This provides sequential consistency:
Operations appear to complete in submission order
Writes from operation N are visible to operation N+1
You don’t need explicit synchronization between dependent operations
Independent operations may execute concurrently internally for performance
Example (no explicit waits needed between dependent operations):
physx.attach_ovstage(stage, read_ordinal=initial_ordinal)
# After the application authors later ovstage edits:
physx.update_from_ovstage(from_ordinal, to_ordinal)
physx.step(dt) # Sees the drained stage edits
binding = physx.create_tensor_binding(
"/World/Cube", tensor_type=TensorType.RIGID_BODY_POSE
) # Sees step results
binding.read(output) # Reads current state
Use wait_op() when:
Before accessing results outside the stream (e.g., reading data on CPU/GPU)
To ensure operations complete before program exit
For explicit synchronization points in your application
Thread Safety#
PhysX instances share the underlying omni.physx runtime. Serialize simulation, stage mutation, and binding creation across instances.
A single instance is NOT thread-safe. Use external synchronization if calling from multiple threads.
ctypes releases the GIL during native calls, so concurrent
step()andTensorBinding.read()/write()from different threads is a data race. See the developer guide threading section for the recommended pattern.
Core Classes#
- class ovphysx.api.PhysX(
- config: PhysXConfig | None = None,
- ignore_version_mismatch: bool = False,
- active_cuda_gpus: str | None = None,
Bases:
objectHigh-level wrapper around the C API using ctypes.
- attach_ovstage(stage, read_ordinal: int = 1) None#
Attach an ovstage Stage as the orchestration data surface.
Attach performs the initial scene parse at
read_ordinal. After the producer authors later ovstage edits, callupdate_from_ovstage()with only those subsequent ordinals. Tensor bindings remain available as a perf escape hatch.- Parameters:
stage – An
ovstage.Stageor a rawovstage_instance_t*handle.read_ordinal – Caller-owned sealed ovstage ordinal the initial scene parse reads at. The application owns ordinal advancement; defaults to 1 (read from the first sealed ordinal).
- Preconditions:
Instance must be valid.
Not already attached to a Stage.
- Lifetime:
stagemust outlive the attachment because ovphysx captures and dereferences its native pointer until detach. This wrapper holds a reference tostagefor the duration of the attachment, so a Stage created inline (attach_ovstage(ovstage.Stage(...))) stays alive; the reference is dropped bydetach_ovstage()andrelease().
- Errors:
Raises
RuntimeErrorif already attached,stageis null, or the runtime attach fails. Instance remains unattached on failure.
- clone(
- source_path: str,
- target_paths: list[str],
- parent_transforms: list[tuple[float, float, float, float, float, float, float]] | None = None,
- env_ids: list[int] | None = None,
Clone a prim hierarchy to create multiple runtime physics copies.
Creates physics-optimized clones in the runtime representation for high-performance simulation, backed by the PhysX SDK replicator so cloned articulations are real articulations. The source prim must exist in the loaded stage and have physics properties. Replication executes inline. The returned operation index is already complete, so subsequent operations see the clone immediately and
wait_op()returns immediately.This is the clone entrypoint for both standalone callers and callers that populate the scene through an ovstage Stage attached via
attach_ovstage(). Replication runs in the internal representation only (USD untouched).Cross-environment collision filtering can optionally use PhysX environment ids, controlled by the
/ovphysx/clone/useEnvIdssetting (default: on). When enabled and the scene runs GPU dynamics + GPU broadphase, each cloned environment gets a distinct environment id so copies in different environments do not collide. The source environment is included: its bodies are created holding environment id 0 (assigned as the attach parses them; clones get 1..N), so co-located clones (parent_transforms=None) are collision-isolated from the source as well. Like all carbonite settings it is per-process (shared by every ovphysx instance in the process), so set it consistently before attaching.When one logical environment is assembled from SEVERAL clone calls (e.g. an IsaacLab ClonePlan cloning one source row at a time: first
/env0/Robotto every environment, then/env0/Object), passenv_idsso objects that share an environment share an environment id – withenv_ids=Noneeach call numbers its copies afresh, so/env1/Robotand/env1/Objectcloned by different calls would land on different ids and never collide with each other:env_ids = [0, 1] # same ids in every call -> same logical environments physx.clone("/env0/Robot", ["/env1/Robot", "/env2/Robot"], transforms_r, env_ids) physx.clone("/env0/Object", ["/env1/Object", "/env2/Object"], transforms_o, env_ids)
- Parameters:
source_path – USD path of the source prim hierarchy to clone (e.g., “/World/env0”)
target_paths – List of USD paths for the cloned hierarchies (e.g., [“/World/env1”, “/World/env2”])
parent_transforms – Optional list of (px, py, pz, qx, qy, qz, qw) transforms giving the world pose of each copy’s parent. Position followed by quaternion rotation (imaginary-first, matching tensor API convention). Identity rotation = (0, 0, 0, 1). Must have the same length as target_paths. Each cloned body keeps its pose relative to the source’s parent, so a copy’s world pose is transform * inverse(source_parent) * source_body – for a source authored at the origin this places each body exactly at the transform. Pass None to co-locate every copy on the source.
env_ids – Optional logical environment id per target (list of int, same length as target_paths, each 0 <= id < 0x00FFFFFF – PhysX supports at most 1<<24 environments and the runtime id is env_ids[i] + 1). Stable across calls: the same id always maps to the same runtime environment, so clones from different calls that share an id collide with each other and stay isolated from every other environment (engages under GPU dynamics + GPU broadphase, like all env-id filtering). Pass None for automatic per-call numbering (each call’s copies get fresh ids past every previous call’s).
- Returns:
op_index (can be used with wait_op() for explicit synchronization)
- Raises:
ValueError – If source_path is empty, target_paths is empty, or any target path matches source path
RuntimeError – If cloning fails, if no ovstage is attached, if target_paths contains duplicate or overlapping entries, or if clone() is called after the first
step(),step_sync(), orstep_n_sync(). The after-step rejection applies in CPU and GPU mode. GPU warmup is also rejected; hard CPU mode treatswarmup_gpu()as a no-op.
- Preconditions:
An ovstage source is attached and source_path exists.
target_paths are unique, disjoint, and do not already contain physics.
No
step()/step_sync()/step_n_sync()has run since the lastreset_stage()orattach_ovstage()call, in either CPU or GPU mode – violating this raisesRuntimeError. (Note:update_from_ovstage()does not reset this – only a freshattach_ovstage()orreset_stage()does.)warmup_gpu()has not been called since the same reset points, but this precondition is currently GPU-only – see above.
- Side effects:
Creates live PhysX objects keyed by the target paths. No USD or runtime-stage prims are authored.
- Ownership/Lifetime:
Clones remain valid until reset_stage().
- Threading:
Do not call concurrently on the same instance without external sync.
- Errors:
Raises ValueError for invalid inputs.
Raises RuntimeError on internal failure, including duplicate-target and after-step/after-warmup ordering violations.
- create_contact_binding(
- sensor_patterns: list[str],
- filter_patterns: list[str] | None = None,
- filters_per_sensor: int = 0,
- max_contact_data_count: int = 0,
Create a contact binding for reading aggregate and detailed contact tensors.
Returns DLPack-compatible tensors of net forces
[S, 3]or force matrices[S, F, 3]. Detailed contact and friction data are exposed as flat[C, ...]buffers plus[S, F]count/start-index tensors viaContactBinding.read_contact_data()andContactBinding.read_friction_data().A sensor is a set of rigid body prims matched by a USD prim path pattern. A filter is a second set of bodies whose contacts with each sensor you want to measure. No extra USD schema is needed beyond the rigid bodies themselves.
The binding must be created before the first simulation step whose contacts you want to observe. Call
read_net_forces()orread_force_matrix()afterPhysxSDK.step(). Before the first step, both return all-zeros tensors.- Result tensor shapes after step:
net forces:
[S, 3]where S = matched sensor countforce matrix:
[S, F, 3]where F = matched filter count per sensordetailed data: flat
[C, 1]or[C, 3]buffers indexed bycountsandstart_indiceswith shape[S, F]
Use
ContactBinding.sensor_pathsandContactBinding.filter_pathsto map rows and columns back to resolved USD prim paths.Example:
cb = sdk.create_contact_binding( sensor_patterns=["/World/robot_0/ee"], filter_patterns=["/World/obstacles/box"], filters_per_sensor=1, max_contact_data_count=256, ) # After sdk.step(): forces = torch.zeros(cb.sensor_count, 3, device="cuda") cb.read_net_forces(forces)
- Parameters:
sensor_patterns – USD prim path patterns for sensor bodies.
filter_patterns – Flat list of USD prim path patterns for filters. Total length must equal
len(sensor_patterns) * filters_per_sensor. PassNonewithfilters_per_sensor=0to get contacts with all bodies.filters_per_sensor – Number of filter patterns per sensor (same for all sensors).
max_contact_data_count – Max raw contact pairs to track in the native backend; also caps the detailed contact/friction flat-buffer reads. Detailed reads require this value and
filters_per_sensorto be positive.
- create_sdf_view(
- pattern: str,
- max_query_points: int,
Create an SDF shape view for evaluating signed distance fields.
Requires a GPU instance; CPU SDF evaluation is not yet implemented.
- Parameters:
pattern – USD glob pattern matching SDF collision shapes.
max_query_points – Number of query points per shape per call. Query tensors passed to
SdfView.evaluatemust have Q equal to this.
- Returns:
SdfView with count == number of matched shapes.
Example:
sdf = physx.create_sdf_view("/World/Mesh*", max_query_points=64) # Query/output tensors must be on the CUDA device (SDF eval is GPU-only). pts = torch.zeros((sdf.count, 64, 3), dtype=torch.float32, device="cuda") out = torch.zeros((sdf.count, 64, 4), dtype=torch.float32, device="cuda") sdf.evaluate(pts, out) sdf.destroy()
- create_tensor_binding(
- pattern: str = None,
- prim_paths: list[str] = None,
- tensor_type: int = TensorType.RIGID_BODY_POSE,
- *,
- raise_if_empty: bool = False,
Create tensor binding for bulk physics data access (synchronous).
A tensor binding connects USD prims (by pattern or explicit paths) to a tensor type, enabling efficient bulk read/write of physics data.
- Parameters:
pattern – USD path glob pattern (e.g., “/World/robot*”, “/World/env[N]/robot”). Mutually exclusive with
prim_paths.prim_paths – Explicit list of prim paths. Mutually exclusive with
pattern.tensor_type – Tensor type enum value (
TensorType.*).raise_if_empty – If
True, raiseValueErrorwhen the binding matches zero prims. The default keeps empty bindings valid; prefer it for optional or broad queries and checkbinding.count.
- Returns:
TensorBinding object for reading/writing tensor data.
- Raises:
ValueError – If neither
patternnorprim_pathsis provided, both are, orraise_if_emptyis true and no prims match.RuntimeError – If binding creation fails.
Examples:
# Read all robot poses by pattern. Optional broad queries can be empty. with sdk.create_tensor_binding( "/World/robot*", tensor_type=TensorType.RIGID_BODY_POSE ) as binding: if binding.count: poses = np.zeros(binding.shape, dtype=np.dtype(str(binding.dtype))) binding.read(poses) # Set joint position targets for specific articulations binding = physx.create_tensor_binding( prim_paths=["/World/env1/robot", "/World/env2/robot"], tensor_type=TensorType.ARTICULATION_DOF_POSITION_TARGET, ) targets = np.zeros(binding.shape, dtype=np.dtype(str(binding.dtype))) binding.write(targets) binding.destroy()
- Preconditions:
Exactly one of
patternorprim_pathsmust be provided.A USD stage is loaded.
- Side effects:
Allocates native binding resources.
- Ownership/Lifetime:
Returned TensorBinding owns native resources until
destroy().Use
binding.shapeandbinding.dtype(orbinding.spec) to allocate compatible buffers; most tensor types are float32, but some types such asRIGID_BODY_DISABLE_SIMULATIONare not.The binding is tied to the current stage topology. Reuse it across steps, but do not keep it across
reset_stage(), removing USD data that contains bound objects, or replacing/reparsing the stage so bound objects are destroyed and recreated. Destroy cached bindings before those lifecycle operations when practical; if a stale binding survives, only destroy it. Create replacements after the operation completes.
- Diagnostics:
Pattern bindings can intentionally match zero prims, so expected TensorAPI no-match diagnostics are quieted on the simulation view used to create that binding.
Explicit
prim_pathskeep the default error-level no-match diagnostics for typo detection. To detect partial misses programmatically, compare the requestedprim_pathswith the resolvedbinding.prim_pathsreturned after creation.
- Threading:
Do not create bindings concurrently with stage mutation.
- Errors:
Raises
ValueErrorfor invalid arguments.Raises
RuntimeErroron creation failure.
- detach_ovstage() None#
Detach the currently-attached ovstage Stage.
Idempotent — calling on an unattached instance is a no-op success. Clears registered interests and output-buffer registrations, so a subsequent
attach_ovstage()to a different Stage starts clean. After detach, stage-dependent calls such asupdate_from_ovstage()andstep()fail until a Stage is attached again. Detach invalidates the stage’s tensor, contact, and SDF views. Do not read, write, or evaluate existing bindings or SDF views; destroy them and create replacements after callingattach_ovstage()and realizing a stage again.- Errors:
Raises
RuntimeErroron internal failures.
- get_config_bool(key: int) bool#
Get a boolean config value.
- Parameters:
key – Boolean config key (e.g.,
ovphysx.ConfigBool.DISABLE_CONTACT_PROCESSING).- Returns:
Current boolean value.
- get_config_float(key: int) float#
Get a float config value.
- Parameters:
key – Float config key.
- Returns:
Current float value.
- get_config_int32(key: int) int#
Get an int32 config value.
- Parameters:
key – Int32 config key (e.g.,
ovphysx.ConfigInt32.NUM_THREADS).- Returns:
Current int32 value.
- get_config_string(key: int) str | None#
Get a string config value.
- Parameters:
key – String config key from
ovphysx.ConfigString.- Returns:
Current string value, or None if not found.
- get_contact_report(
- include_friction_anchors: bool = False,
- copy: bool = False,
Get per-contact-point event data for the current simulation step.
Use this for custom contact sensors, collision debugging, or per-point force analysis. For aggregate force tensors (net forces or force matrices between sensor/filter body sets), use
create_contact_binding()instead.Warning
With the default
copy=False, the returnedheaders,points, andanchorsare zero-copy ctypes views into internal C buffers that are valid only until the nextstep()orstep_sync()call. After the next step the buffers may be reallocated or reused; accessing the views is undefined behavior (silent data corruption or segfault). Python cannot detect this dangling state.Pass
copy=Trueto get Python-owned lists of dicts that are safe to retain across simulation steps. This is the recommended mode for RL training loops or any code that holds contact data beyond a single step.- Parameters:
include_friction_anchors – If True, also return friction anchor data (position and impulse at each friction anchor point).
copy – If True, return Python-owned
list[dict]for each section (safe to hold across steps). If False (default), return zero-copy ctypes array views (faster but valid only until the nextstep()/step_sync()).
- Returns a dict with:
headers: contact event headers describing each contact pair (actors, colliders, event type). Whencopy=False, a ctypes array ofContactEventHeader; whencopy=True, alist[dict]with the same field names. Length isnum_headers.num_headers(int): Number of contact event headers.points: per-contact-point data (position, normal, impulse, separation). Whencopy=False, a ctypes array ofContactPoint; whencopy=True, alist[dict]. Length isnum_points.num_points(int): Number of contact point entries.anchors(only ifinclude_friction_anchors=True): friction anchor data. Whencopy=False, a ctypes array ofFrictionAnchor; whencopy=True, alist[dict]. Length isnum_anchors.num_anchors(int, only ifinclude_friction_anchors=True): Number of friction anchors.
Example (safe across steps,
copy=True):report = physx.get_contact_report(copy=True) physx.step_sync(dt) # next step — report still valid for h in report["headers"]: print(h["actor0"], h["numContactData"]) for p in report["points"]: print(p["position"], p["normal"], p["impulse"])
Example (zero-copy,
copy=False):report = physx.get_contact_report() for i in range(report["num_headers"]): h = report["headers"][i] print(h.actor0, h.numContactData) # Do NOT call step() before finishing access to report.
Prims must have
PhysxContactReportAPIapplied in the USD stage for contacts to be reported.- Raises:
RuntimeError – If the call fails.
- get_object_type(prim_path: str) int#
Classify a USD prim by TensorAPI object type.
Unresolved paths return INVALID. Raises RuntimeError for invalid input (empty path, embedded NUL byte) or if no stage is attached.
- Returns:
One of RIGID_BODY, ARTICULATION, ARTICULATION_LINK, ARTICULATION_ROOT_LINK, ARTICULATION_JOINT, or INVALID.
- Return type:
- property handle: int#
The raw
ovphysx_handle_tfor this instance (read-only).Use this when passing the handle to C/C++ code that calls the ovphysx C API directly.
- Raises:
RuntimeError – If the instance has been released.
- overlap(
- geometry_type: SceneQueryGeometryType,
- mode: SceneQueryMode = SceneQueryMode.ALL,
- **kwargs,
Test geometry overlap against objects in the scene.
For overlap queries, location fields (normal, position, distance, face_index, material) are zeroed – only object identity is populated.
Return the opaque pointer to the shared ovstage path dictionary backing a query.
This is NOT an ovphysx-private dictionary: it is the process-shared ovstage dictionary the attached Stage uses, the same one that interned the query’s tokens / prim lists, so a group’s
attributetoken /prim_listhandle resolve through anovstage.PathDictionary(stage)as well. Returns 0 if unavailable.
- raycast(
- origin: tuple | list,
- direction: tuple | list,
- distance: float,
- mode: SceneQueryMode = SceneQueryMode.CLOSEST,
- both_sides: bool = False,
Cast a ray and return hits.
- Parameters:
origin – Ray origin [x, y, z].
direction – Normalized ray direction [x, y, z].
distance – Maximum ray length (>= 0).
mode –
SceneQueryMode(CLOSEST, ANY, or ALL).both_sides – If True, test both sides of mesh triangles.
- Returns:
List of hit dicts. Each dict contains
collision,rigid_body,proto_index,normal,position,distance,face_index,material. For ANY mode, hit fields are zeroed.
- read(
- object_type: SimObjectType,
- attribute_names: list[str],
- scope: ObjectScope = ObjectScope.ALL,
Read physics output (ADR-0007) for one simulated type as column groups.
Mirrors the ovstage read idiom: open a query over
object_typeinscope, read the namedattribute_names(e.g.["position", "orientation"]), and return a context-managedReadResultwhosegroupsis oneReadGroupper typed column. The read is ovstage-native — attach an ovstage Stage first.Use it as a context manager: the query + read session stay open for the
withblock so each group’s internedprim_list/attributehandles are valid — feed them straight into the ovstage write path (stage.query_from_path_list(group.prim_list)) for a no-repack write-back. Grouptensorsare NumPy copies, safe to keep past the block.This is the physics → app direction. To avoid physics consuming its own output, write the data back into ovstage at ordinals that are never passed to
update_from_ovstage(). See the ovstage Integration guide for the ordinal-coupling principle.- Parameters:
object_type – Simulated type to read (
SimObjectType).attribute_names – Semantic attribute names to read.
scope –
ALLorACTIVE(active is single-frame).
- Returns:
A
ReadResultcontext manager.result.groupsis empty if no objects matched.- Raises:
RuntimeError – on a native error (e.g. no ovstage attached).
- read_tokens(
- object_type: SimObjectType,
- attribute_tokens: list[int],
- scope: ObjectScope = ObjectScope.ALL,
Token form of
read().Identical to
read()but the attributes are given as interned attribute tokens (e.g. those fromfetch_query_result()) instead of strings, so a token can be fed straight back in with no token→string→name round-trip. Both forms build the sameovx_string_or_token_tarray under the hood.- Parameters:
object_type – Simulated type to read (
SimObjectType).attribute_tokens – Interned attribute tokens to read.
scope –
ALLorACTIVE(active is single-frame).
- Returns:
A
ReadResultcontext manager (seeread()).- Raises:
RuntimeError – on a native error (e.g. no ovstage attached).
- release() None#
Release PhysX instance.
- Preconditions:
Instance is valid and not in use by other threads.
- Side effects:
Releases native resources and unregisters the instance.
- Ownership/Lifetime:
All tensor bindings and contact bindings created by this instance are automatically released.
The instance becomes unusable after release.
- Threading:
Do not call concurrently with other operations on this instance.
- Errors:
Errors during cleanup are suppressed for robustness.
- reset_stage() int#
Reset stage to empty (async).
- Returns:
op_index (can be used with wait_op() for explicit synchronization)
Example
# Simple usage (stream-ordered) physx.reset_stage() physx.wait_all()
- Preconditions:
Instance must be valid.
- Side effects:
Clears the runtime stage.
Detaches any attached ovstage Stage (the C runtime calls detach_ovstage internally). Callers must re-attach with attach_ovstage() before any further update_from_ovstage().
- Ownership/Lifetime:
All TensorBinding, ContactBinding, and SdfView objects for the previous stage become invalid. Destroy cached bindings and SDF views before reset when practical; if a stale handle survives, only destroy it. Create replacement bindings and SDF views after the reset completes.
- Threading:
Do not call concurrently on the same instance without external sync.
- Errors:
Raises RuntimeError on failure.
- set_config(
- entry: ovphysx._bindings.ovphysx_config_entry_t,
Set a typed global config entry at runtime (process-global).
Prefer the typed setters (
set_config_bool(),set_config_int32(),set_config_float()) for a cleaner API.- Parameters:
entry – Typed config entry (
ovphysx_config_entry_t).
- set_config_bool(key: int, value: bool) None#
Set a boolean config value at runtime (process-global).
- Parameters:
key – Boolean config key (e.g.,
ConfigBool.DISABLE_CONTACT_PROCESSING).value – Boolean value.
- set_config_float(key: int, value: float) None#
Set a float config value at runtime (process-global).
- Parameters:
key – Float config key.
value – Float value.
- set_config_int32(key: int, value: int) None#
Set an int32 config value at runtime (process-global).
- Parameters:
key – Int32 config key (e.g.,
ConfigInt32.NUM_THREADS).value – Int32 value.
- static set_cpu_mode(cpu_only: bool) None#
Force process-wide CPU-only mode.
Call before the first PhysX instance is ever created to guarantee that CUDA is never touched. The call requires no active instances. Once set to True successfully, the mode cannot be reversed for this process.
When True: no CUDA driver is touched; all PhysX scenes use CPU dynamics regardless of their USD physxScene:enableGPUDynamics settings.
- Raises:
RuntimeError – If any PhysX instances are currently active, or if attempting to set False after True has been applied (CPU-only mode is sticky as soon as enabling it succeeds).
- step(dt: float) int#
Initiate physics step (async, returns op_index).
Simulation time is tracked internally; each step advances it by
dt.- Parameters:
dt – Delta time for this step [s].
- Returns:
op_index (can be used with wait_op() for explicit synchronization)
Examples
# Simple usage (stream-ordered) physx.step(0.016) binding.read(output) # Automatically waits for step
# Explicit wait (if accessing results outside stream) op = physx.step(0.016) physx.wait_op(op) # Ensure step completes before external GPU work
- Preconditions:
A USD stage is loaded if physics content is expected.
- Side effects:
Advances simulation time and mutates physics state.
- Ownership/Lifetime:
Returned op_index is single-use and must be waited once if needed.
- Threading:
Do not call concurrently on the same instance without external sync.
- Errors:
Raises RuntimeError on failure to enqueue.
- step_n_sync(n: int, dt: float) None#
Run N steps in a single C call, saving (N-1) ctypes round-trips.
Equivalent to calling
step_sync(dt)n times, but with only one Python-to-C transition. Simulation time is tracked internally and advanced byn * dt.- Parameters:
n – Number of steps to run (must be >= 1).
dt – Duration of each step [s].
- Raises:
RuntimeError – If any step fails.
- step_sync(dt: float) None#
Step simulation and wait for completion in a single call.
Faster than
step()+wait_op()for performance-critical applications like RL training that always wait immediately. Simulation time is tracked internally and advanced bydt.- Parameters:
dt – Delta time [s] for this step.
- Raises:
RuntimeError – If the step or wait fails.
- sweep(
- geometry_type: SceneQueryGeometryType,
- direction: tuple | list,
- distance: float,
- mode: SceneQueryMode = SceneQueryMode.CLOSEST,
- both_sides: bool = False,
- **kwargs,
Sweep a geometry shape along a direction and return hits.
- Parameters:
geometry_type –
SceneQueryGeometryType.direction – Normalized sweep direction [x, y, z].
distance – Maximum sweep distance (>= 0).
mode –
SceneQueryMode.both_sides – If True, test both sides of mesh triangles.
**kwargs –
Geometry parameters:
SPHERE:
radius,positionBOX:
half_extent,position,rotation(xyzw quaternion)SHAPE:
prim_path(USD prim path string)
- Returns:
List of hit dicts (same format as
raycast()).
- update_articulations_kinematic() None#
Update articulation link poses from current joint positions.
This performs a synchronous articulation forward-kinematics update without running a normal simulation step, collision detection, or contact generation. Call it after writing articulation DOF positions and before reading articulation link pose tensors when fresh link poses are needed in the same frame.
In GPU mode, the first kinematic update after loading USD may perform the same automatic DirectGPU warmup step used by tensor reads/writes.
- Raises:
RuntimeError – If the update fails.
- update_from_ovstage(from_ordinal: int, to_ordinal: int) None#
Apply committed ovstage edits over the closed range
[from_ordinal, to_ordinal].The application that writes to ovstage owns the ordinal range and calls this after sealing the writes.
population.apply_usd_changes()waits for population work but does not seal its ordinal; completestage.advance_write_floor(ordinal).wait()before this call. ovphysx forwards the range (as ovstage’s ownovstage_ordinal_range_t) to the runtime ovstage change feed and applies the resulting deltas to the simulation.The initial
read_ordinalwas already parsed byattach_ovstage(). Normal incremental updates pass only later ordinals; including the initial ordinal replays the initial scene changes rather than only the new delta.
- wait_all(timeout_ns: int | None = None) None#
Wait for all pending operations (convenience wrapper for wait_op(ALL)).
- Parameters:
timeout_ns – Timeout in nanoseconds (None = infinite, 0 = poll)
- Preconditions:
Instance must be valid.
- Side effects:
Consumes each completed or failed operation reached before success or timeout.
- Threading:
Serialize all calls on the same instance externally.
- Errors:
Raises RuntimeError on failure.
Raises TimeoutError if timeout expired (e.g., when polling with timeout_ns=0 and operations are not ready).
- wait_op(op_index: int, timeout_ns: int | None = None) None#
Wait for operation(s) to complete.
- Parameters:
op_index – Operation index to wait for, or OP_INDEX_ALL for all ops
timeout_ns – Timeout in nanoseconds (None = infinite, 0 = poll)
- Raises:
RuntimeError – If an operation failed or op_index is invalid or already consumed.
TimeoutError – If timeout expired (e.g., when polling with timeout_ns=0 and the operation is not ready)
- Preconditions:
op_index must be valid and not previously consumed.
- Side effects:
Consumes each completed or failed operation reached up to op_index.
An operation still pending when the wait times out is not consumed.
An index completed by internal stream synchronization may be acknowledged once; that acknowledgement consumes it.
- Ownership/Lifetime:
Wait-result storage is released internally.
Error strings are borrowed and remain valid until the next API call on the same thread.
- Threading:
Serialize calls on one PhysX instance externally.
Do not wait on the same op_index from multiple threads.
Examples:
# Blocking wait (default) physx.wait_op(op_index) # Non-blocking poll try: physx.wait_op(op_index, timeout_ns=0) except TimeoutError: pass # operation not yet complete
- warmup_gpu() None#
Explicitly initialize GPU buffers (synchronous).
In GPU mode, PhysX DirectGPU buffers need one simulation step to initialize. This is normally done automatically on the first tensor read (auto-warmup).
Call this function explicitly if you want to: - Control exactly when the warmup latency occurs - Avoid a latency spike on the first tensor read - Verify GPU initialization succeeded before starting your main loop
This function is idempotent - calling it multiple times has no effect after the first successful call. In CPU mode, this is a no-op.
- Raises:
RuntimeError – If GPU warmup fails.
- Preconditions:
Instance is configured for GPU mode.
- Side effects:
Advances simulation by a minimal timestep on first call.
- Ownership/Lifetime:
No ownership changes; affects current stage state.
- Threading:
Do not call concurrently with other operations on this instance.
- class ovphysx.api.TensorBinding(
- sdk,
- handle: int,
- tensor_type: int,
- ndim: int,
- shape: tuple,
- dtype: DLDataType | None = None,
Bases:
objectTensor binding for bulk physics data access via DLPack.
A tensor binding connects a USD prim pattern to a tensor type, enabling efficient bulk read/write of physics data (poses, velocities, joint positions, etc.). The
shape,ndim, anddtypemetadata come fromovphysx_get_tensor_binding_spec(). Use them to allocate compatible buffers instead of assuming every tensor type isfloat32.This is a synchronous API - operations complete before returning. Bindings are tied to the currently realized physics objects. Reuse them across simulation steps, but do not keep them across reset_stage(), removing USD data that contains bound objects, or replacing/reparsing the stage so bound objects are destroyed and recreated. Destroy cached bindings before those lifecycle operations when practical; if a stale binding survives, only destroy it. Create replacement bindings after the operation completes.
Usage patterns:
Context manager (auto-cleanup):
with sdk.create_tensor_binding("/World/robot*", tensor_type=TensorType.RIGID_BODY_POSE) as binding: poses = np.zeros(binding.shape, dtype=np.dtype(str(binding.dtype))) binding.read(poses) poses[:, 2] += 0.1 # raise z position binding.write(poses) # Auto-destroyed here
Manual (explicit cleanup):
binding = sdk.create_tensor_binding("/World/robot*", tensor_type=TensorType.RIGID_BODY_POSE) poses = np.zeros(binding.shape, dtype=np.dtype(str(binding.dtype))) binding.read(poses) binding.destroy()
- property body_count: int#
Number of links.
- property body_names: list[str]#
List of body/link names.
- property count: int#
Get number of entities (first dimension of shape).
- destroy() None#
Release binding resources.
Safe to call multiple times. Called automatically on garbage collection or when exiting a context manager.
- Preconditions:
Binding must not be in use by other threads.
- Side effects:
Releases native resources and invalidates the binding.
- Ownership/Lifetime:
After destruction, the binding cannot be used.
- Threading:
Serialized per binding via an internal lock.
- Errors:
RuntimeError if destruction fails.
- property dof_count: int#
Number of degrees of freedom (DOFs). 0 if not an articulation binding.
- property dof_names: list[str]#
List of DOF names (one per DOF).
- property dtype: DLDataType#
Get the required DLPack dtype for tensors passed to this binding.
Most bindings use
float32. Index bindings (deformable element indices) useint32; bool bindings (DISABLE_SIMULATION) useuint8. Seedtype_namefor a compact string form.
- property dtype_name: str#
Get the required tensor dtype as a short string such as
float32,int32, oruint8.
- property fixed_tendon_count: int#
Number of fixed tendons per articulation (0 if none).
Use to decide whether to allocate buffers for fixed tendon property tensors (types 80-85) and to skip tendon code paths when T=0.
- property handle: int#
Get the binding handle.
- property is_fixed_base: bool#
Whether the articulation has a fixed base.
- property joint_count: int#
Number of joints per articulation.
- property joint_names: list[str]#
List of joint names.
- property ndim: int#
Get the number of dimensions reported by
ovphysx_get_tensor_binding_spec().
- property prim_paths: list[str]#
Resolved USD prim paths in tensor row order.
Rigid-body bindings return one path per rigid-body tensor row. Articulation bindings return one root prim path per articulation row. For per-articulation link names, use
body_names.
- read(tensor) None#
Read simulation data into a user-provided tensor (synchronous).
The tensor must have matching shape and dtype (
shapeanddtype). Can be a NumPy array, PyTorch tensor, or any object with __dlpack__ protocol.When called repeatedly with the same buffer object, an internal cache skips DLPack acquisition and attribute chain lookups, giving near-raw-C-call overhead. The numpy writeable guard is preserved on the fast path. Callers that want this fast path should reuse the same tensor object with unchanged backing storage across calls. Calling
numpy.ndarray.resize()ortorch.Tensor.resize_()between calls is safe (a staleness guard detects the pointer change and rebuilds the cache) but defeats the purpose of caching.- Parameters:
tensor – DLPack-compatible tensor with pre-allocated storage matching self.shape. Must use
self.dtype. CPU/CUDA device mismatches are staged when CUDA is available; cross-GPU mismatches and CUDA tensors in process-wide CPU-only mode are rejected.
- Preconditions:
This binding is not destroyed.
tensor has matching shape and dtype and uses a supported device.
- Side effects:
Blocks until data is available and writes into the provided tensor.
- Ownership/Lifetime:
Caller owns tensor storage and must keep it alive for the duration of the call.
Do not mutate the tensor’s backing storage (
resize(),set_(), etc.) between cached calls. For numpy and torch tensors, a staleness guard detects common mutations and falls back to the slow path; other types rely on the caller honouring this contract.
- Threading:
Serialized per binding via an internal lock.
- Errors:
RuntimeError if read fails (shape mismatch, device mismatch, etc.).
- property shape: tuple#
Get tensor shape as tuple reported by
ovphysx_get_tensor_binding_spec().- Returns:
Tensor dimensions for this binding. Scalar-property bindings use
(N,). Flat state tensors use(N, C). Articulation and deformable mesh tensors use(N, L, C).
- sleep(indices=None) None#
Force rigid bodies in this binding to sleep.
Mirrors PhysX SDK
PxRigidDynamic::putToSleep. Symmetric counterpart towake_up(). Bodies that haveRIGID_BODY_DISABLE_SIMULATIONset are silently skipped.Only valid on a rigid-body binding. Articulation bindings raise.
- Parameters:
indices – Optional int32 DLPack-compatible tensor of indices into this binding. If None, every body in the binding is put to sleep.
- Errors:
RuntimeError if the binding is destroyed, is not a rigid-body binding, has been invalidated by a stage change, or the engine call fails.
- property spatial_tendon_count: int#
Number of spatial tendons per articulation (0 if none).
Use to decide whether to allocate buffers for spatial tendon property tensors (types 90-93) and to skip tendon code paths when T=0.
- property spec: TensorBindingSpec#
Get a Python-owned tensor spec snapshot for this binding.
- property tensor_type: int#
Get the tensor type enum value.
- wake_up(indices=None) None#
Wake rigid bodies in this binding.
Mirrors PhysX SDK
PxRigidDynamic::wakeUp. Bodies that still haveRIGID_BODY_DISABLE_SIMULATIONset are silently skipped (the engine refuses to wake disabled actors).Typical pair: clear the disable flag on an actor (re-add it to simulation in a sleep state) and then call this so the actor is active for the next
step().Only valid on a rigid-body binding. Articulation bindings raise.
- Parameters:
indices – Optional int32 DLPack-compatible tensor of indices into this binding. If None, every body in the binding is woken.
- Errors:
RuntimeError if the binding is destroyed, is not a rigid-body binding, has been invalidated by a stage change, or the engine wake call fails.
- write(tensor, indices=None, mask=None) None#
Write data from a user-provided tensor into the simulation (synchronous).
The tensor must have matching shape and dtype (
shapeanddtype). Can be a NumPy array, PyTorch tensor, or any object with __dlpack__ protocol.When called repeatedly with the same buffer object and no indices/mask, an internal cache skips DLPack acquisition and attribute chain lookups, giving near-raw-C-call overhead. Callers that want this fast path should reuse the same tensor object with unchanged backing storage across calls; see
read()for the full contract.- Parameters:
tensor – DLPack-compatible tensor with data to write, shape matching self.shape. Must use
self.dtype. CPU/CUDA device mismatches are staged when CUDA is available; cross-GPU mismatches and CUDA tensors in process-wide CPU-only mode are rejected.indices – Optional int32 tensor of indices for partial update. If provided, only the rows at the given indices are written. The tensor argument must still be full shape [N, …] matching the binding spec; only the selected rows are applied. Shape of indices: [K] where K <= N.
mask –
Optional bool/uint8 tensor for masked update. If provided, only elements where mask[i] != 0 are written. Shape: [N] matching the binding’s first dimension. When mask is provided, tensor must be full shape [N, …]. If both mask and indices are provided, mask takes precedence and indices are ignored (with a warning).
Note: there is no corresponding
read(..., mask=...); reads always return the full [N,…] tensor and callers can index the result themselves. This write-only mask design matches other RL physics APIs such as Newton’s selectionAPI, where masks selectively apply actions but observations are always returned in full.
- Preconditions:
This binding is not destroyed.
tensor matches shape and dtype and uses a supported device.
indices (if provided) is int32 and within bounds.
mask (if provided) is bool/uint8 with shape [N] on a supported device.
- Side effects:
Updates simulation state for the bound entities.
- Ownership/Lifetime:
Caller owns tensor/indices/mask storage and must keep it alive for the call.
- Threading:
Serialized per binding via an internal lock.
- Errors:
RuntimeError if write fails (shape mismatch, device mismatch, etc.).
- class ovphysx.api.ContactBinding(
- sdk,
- handle: int,
- sensor_count: int,
- filter_count: int,
- max_contact_data_count: int,
Bases:
objectContact tensor binding backed by IRigidContactView.
Do not instantiate directly. Use
PhysxSDK.create_contact_binding()to obtain an instance. Thesensor_pathsandfilter_pathsproperties expose the row/column metadata for the returned tensors.- destroy() None#
Release contact binding resources.
Safe to call multiple times. Captures strong references to the SDK and library before the C call to guard against GC ordering issues (Python may collect self._sdk before self if both go out of scope together).
- property filter_count: int#
Number of filter bodies per sensor (0 when no filters specified).
- property filter_paths: list[list[str]]#
Resolved filter USD prim paths in contact tensor column order.
The outer list is indexed by sensor row and the inner list by filter column. Each inner list is empty for unfiltered contact bindings (i.e. when
filter_count == 0).- Returns:
Nested list of shape [sensor_count][filter_count].
- Return type:
list[list[str]]
- get_other_actor_paths_from_ids(ids_array) list[str]#
Resolve actor IDs from
read_raw_contact_data()to USD prim paths.ids_arrayis a 1D int64/uint64 array (numpy / warp / torch with DLPack support) holding actor IDs. IDs that cannot be resolved yield empty strings. Path strings are copied into Python – the caller can keep them across subsequent ovphysx calls.- Returns:
USD prim paths in the same order as the input IDs.
- Return type:
list[str]
- property max_contact_data_count: int#
Flat-buffer capacity for detailed contact and friction reads.
- read_contact_data(
- contact_forces,
- positions,
- normals,
- separations,
- counts,
- start_indices,
Read detailed contact data into flat buffers.
Expected shapes are
[C, 1]forcontact_forcesandseparations,[C, 3]forpositionsandnormals, and[sensor_count, filter_count]forcountsandstart_indices.Cismax_contact_data_count; bothCandfilter_countmust be positive. Count and start-index tensors may be int32 or uint32.
- read_force_matrix(output) None#
Read contact force matrix into output. Expected shape: [sensor_count, filter_count, 3].
The dt for impulse-to-force conversion is taken automatically from the last
PhysxSDK.step()call.
- read_friction_data(
- friction_forces,
- friction_points,
- counts,
- start_indices,
Read detailed friction data into flat buffers.
Expected shapes are
[C, 3]forfriction_forcesandfriction_points, and[sensor_count, filter_count]forcountsandstart_indices.Cismax_contact_data_countand must be positive;filter_countmust also be positive. Count and start-index tensors may be int32 or uint32. Friction entries are per-anchor; sum each flat slice to build a pair-level[sensor_count, filter_count, 3]force tensor.
- read_net_forces(output) None#
Read net contact forces into output. Expected shape: [sensor_count, 3].
The dt for impulse-to-force conversion is taken automatically from the last
PhysxSDK.step()call.
- read_raw_contact_data(
- contact_forces,
- positions,
- normals,
- separations,
- counts,
- start_indices,
- other_actor_ids,
Read raw (unfiltered) contact data into flat buffers.
Filter-less variant of
read_contact_data()— returns every contact involving each sensor regardless of which other actor it collided with, plus a per-contactother_actor_idslookup for identifying the contacting body viaget_other_actor_paths_from_ids().Expected shapes are
[C, 1]forcontact_forcesandseparations,[C, 3]forpositionsandnormals,[sensor_count]forcountsandstart_indices, and[C]forother_actor_ids.Cismax_contact_data_countand must be positive; no filter dimension is required. Count and start-index tensors may be int32 or uint32;other_actor_idsmust be int64 or uint64.
- property sensor_count: int#
Number of sensor bodies matched.
- property sensor_paths: list[str]#
Resolved sensor USD prim paths in contact tensor row order.
- Returns:
One path per sensor row, in the same order as the contact data tensors.
- Return type:
list[str]
Schema Path Registration#
- ovphysx.register_schema_paths() None#
Register ovphysx’s namespaced USD schema/plugin paths before native bootstrap.
Call this before any USD stage open or schema-registry access when ovphysx shares a process with another USD-aware subsystem such as ovrtx. Standalone ovphysx applications do not need to call it because native startup registers the same ovphysx path automatically.
Always idempotent: re-reads the live env (Python and native views), merges, dedupes, and writes back only if the merged value differs. Safe to call repeatedly and after callers pop
OV_PXR_PLUGINPATH_2511fromos.environto force re-registration.- Raises:
RuntimeError – If no existing ovphysx
plugins/usddirectory can be found.
Logging#
- ovphysx.api.set_log_level(level: int) None#
Set the global log level threshold.
Messages below this level are suppressed for all outputs (console and registered callbacks). Callable at any time, including before instance creation.
- Parameters:
level – Log level threshold (LogLevel.VERBOSE through LogLevel.NONE). Default: LogLevel.WARNING.
- Raises:
ValueError – If level is out of range. No state change is applied.
- ovphysx.api.get_log_level() int#
Get the current global log level threshold.
- Returns:
The current log level (int matching ovphysx_log_level_t constants).
- ovphysx.api.enable_default_log_output(enable: bool = True) None#
Enable or disable Carbonite’s built-in console log output.
By default, Carbonite logs to the console. When custom callbacks are registered (or
enable_python_logging()is active), both the built-in console output and the callbacks receive messages, which may cause duplicate output.Call with
Falseto suppress the built-in console output while keeping callbacks active. Call withTrueto re-enable it.This is independent of callback registration and the global log level.
- Parameters:
enable –
Trueto enable (default),Falseto disable.
- ovphysx.api.enable_python_logging(logger_name: str = 'ovphysx') None#
Route native log messages to Python’s logging module.
Registers a C-level callback that forwards every message (at or above the global log level) to
logging.getLogger(logger_name)at the corresponding Python log level.Call
disable_python_logging()to stop forwarding.- Parameters:
logger_name – Name of the Python logger to route to (default: “ovphysx”).
- ovphysx.api.disable_python_logging() None#
Stop routing native log messages to Python’s logging module.
If
enable_python_logging()was not called, this is a no-op.
Configuration#
Typed config for ovphysx.
Provides PhysXConfig, a dataclass whose fields map 1:1 to the
C typed config enums in ovphysx_types.h. Only non-None fields are
applied; the rest keep their Carbonite/PhysX defaults.
Usage:
from ovphysx import PhysX, PhysXConfig
physx = PhysX(config=PhysXConfig(
disable_contact_processing=True,
num_threads=4,
carbonite_overrides={"/physics/updateToUsd": False},
))
- class ovphysx.config.PhysXConfig(
- disable_contact_processing: bool | None = None,
- collision_cone_custom_geometry: bool | None = None,
- collision_cylinder_custom_geometry: bool | None = None,
- num_threads: int | None = None,
- scene_multi_gpu_mode: int | None = None,
- omnipvd_output_enabled: bool | None = None,
- omnipvd_ovd_recording_directory: str | None = None,
- cooked_collider_cache_dir: str | None = None,
- carbonite_overrides: dict[str, bool | int | float | str] | None = None,
Bases:
objectTyped configuration for ovphysx.
All fields default to
None(= use Carbonite/PhysX default). Only non-None fields are applied.Example:
from ovphysx import PhysX, PhysXConfig physx = PhysX(config=PhysXConfig( disable_contact_processing=True, num_threads=4, carbonite_overrides={"/physics/updateToUsd": False}, ))
- carbonite_overrides: dict[str, bool | int | float | str] | None = None#
- collision_cone_custom_geometry: bool | None = None#
- collision_cylinder_custom_geometry: bool | None = None#
- cooked_collider_cache_dir: str | None = None#
Directory for the local cooked-collider (UJITSO) cache. Provide this to persist cooked colliders across runs and reuse them on the next launch; if left None, ovphysx does not choose a location and cooking runs without cross-run persistence.
- disable_contact_processing: bool | None = None#
- num_threads: int | None = None#
- omnipvd_output_enabled: bool | None = None#
Must be set before instance creation
- omnipvd_ovd_recording_directory: str | None = None#
Must be set before instance creation
- scene_multi_gpu_mode: int | None = None#
0=disabled, 1=all GPUs, 2=skip first GPU
Types and Enums#
Pure-Python type definitions for ovphysx.
This module contains IntEnum definitions that mirror the C enums in ovphysx/include/ovphysx/ovphysx_types.h. It has zero native dependencies (no ctypes, no shared library loading, no USD) and is safe to import in any Python process regardless of USD version or native library state.
Keeping this module dependency-free is intentional: downstream consumers like IsaacLab can import TensorType without triggering ovphysx’s native bootstrap or USD version checks.
Naming convention: strip the OVPHYSX_TENSOR_ prefix and scalar dtype suffix
(_F32 or _S32) from the C enum name. This keeps names unambiguous
(ARTICULATION_ vs RIGID_BODY_) and makes the _bindings.py aliases
mechanically verifiable.
- class ovphysx.types.ApiStatus(
- value,
- names=<not given>,
- *values,
- module=None,
- qualname=None,
- type=None,
- start=1,
- boundary=None,
Bases:
IntEnumReturn codes from the ovphysx C API. Mirrors ovphysx_api_status_t.
- BUFFER_TOO_SMALL = 6#
- DEVICE_MISMATCH = 7#
- END_OF_ITERATION = 9#
- ERROR = 1#
- GPU_NOT_AVAILABLE = 8#
- INVALID_ARGUMENT = 4#
- NOT_FOUND = 5#
- NOT_IMPLEMENTED = 3#
- SUCCESS = 0#
- TIMEOUT = 2#
- class ovphysx.types.BindingPrimMode(
- value,
- names=<not given>,
- *values,
- module=None,
- qualname=None,
- type=None,
- start=1,
- boundary=None,
Bases:
IntEnumPrim selection mode for tensor bindings.
Unlike the other enums in this module, BindingPrimMode does not have a named typedef in ovphysx_types.h – the values come from the internal implementation. It is not covered by test_types_sync.py.
- CREATE_NEW = 2#
- EXISTING_ONLY = 0#
- MUST_EXIST = 1#
- class ovphysx.types.ConfigBool(
- value,
- names=<not given>,
- *values,
- module=None,
- qualname=None,
- type=None,
- start=1,
- boundary=None,
Bases:
IntEnumBoolean config keys. Mirrors ovphysx_config_bool_t.
- COLLISION_CONE_CUSTOM_GEOMETRY = 1#
- COLLISION_CYLINDER_CUSTOM_GEOMETRY = 2#
- DISABLE_CONTACT_PROCESSING = 0#
- OMNIPVD_OUTPUT_ENABLED = 3#
- class ovphysx.types.ConfigFloat(
- value,
- names=<not given>,
- *values,
- module=None,
- qualname=None,
- type=None,
- start=1,
- boundary=None,
Bases:
IntEnumFloat config keys (reserved). Mirrors ovphysx_config_float_t.
- class ovphysx.types.ConfigInt32(
- value,
- names=<not given>,
- *values,
- module=None,
- qualname=None,
- type=None,
- start=1,
- boundary=None,
Bases:
IntEnumInt32 config keys. Mirrors ovphysx_config_int32_t.
- NUM_THREADS = 0#
- SCENE_MULTI_GPU_MODE = 1#
- class ovphysx.types.ConfigString(
- value,
- names=<not given>,
- *values,
- module=None,
- qualname=None,
- type=None,
- start=1,
- boundary=None,
Bases:
IntEnumString config keys. Mirrors ovphysx_config_string_t.
- OMNIPVD_OVD_RECORDING_DIRECTORY = 0#
- class ovphysx.types.LogLevel(
- value,
- names=<not given>,
- *values,
- module=None,
- qualname=None,
- type=None,
- start=1,
- boundary=None,
Bases:
IntEnumLog level for ovphysx output. Mirrors ovphysx_log_level_t.
- ERROR = 3#
- INFO = 1#
- NONE = 4#
- VERBOSE = 0#
- WARNING = 2#
- class ovphysx.types.ObjectScope(
- value,
- names=<not given>,
- *values,
- module=None,
- qualname=None,
- type=None,
- start=1,
- boundary=None,
Bases:
IntEnumOutput query scope. Mirrors ovphysx_object_scope_t.
ACTIVE is single-frame (the active set is recomputed each step); ALL is stable until a structural change.
- ACTIVE = 1#
- ALL = 0#
- class ovphysx.types.ObjectType(
- value,
- names=<not given>,
- *values,
- module=None,
- qualname=None,
- type=None,
- start=1,
- boundary=None,
Bases:
IntEnumTensorAPI object classification. Mirrors ovphysx_object_type_t.
- ARTICULATION = 2#
- ARTICULATION_JOINT = 5#
- ARTICULATION_LINK = 3#
- ARTICULATION_ROOT_LINK = 4#
- INVALID = 0#
- RIGID_BODY = 1#
- class ovphysx.types.SceneQueryGeometryType(
- value,
- names=<not given>,
- *values,
- module=None,
- qualname=None,
- type=None,
- start=1,
- boundary=None,
Bases:
IntEnumGeometry type for sweep/overlap queries. Mirrors ovphysx_scene_query_geometry_type_t.
- BOX = 1#
- SHAPE = 2#
- SPHERE = 0#
- class ovphysx.types.SceneQueryMode(
- value,
- names=<not given>,
- *values,
- module=None,
- qualname=None,
- type=None,
- start=1,
- boundary=None,
Bases:
IntEnumScene query hit mode. Mirrors ovphysx_scene_query_mode_t.
- ALL = 2#
- ANY = 1#
- CLOSEST = 0#
- class ovphysx.types.SimObjectType(
- value,
- names=<not given>,
- *values,
- module=None,
- qualname=None,
- type=None,
- start=1,
- boundary=None,
Bases:
IntEnumSimulated object type for the physics output read. Mirrors ovphysx_sim_object_type_t.
- ARTICULATION_JOINT = 2#
- ARTICULATION_LINK = 1#
- DEFORMABLE_SURFACE = 5#
- DEFORMABLE_VOLUME = 4#
- PARTICLE_SET = 6#
- RIGID_BODY = 0#
- VEHICLE_WHEEL = 3#
- class ovphysx.types.TensorType(
- value,
- names=<not given>,
- *values,
- module=None,
- qualname=None,
- type=None,
- start=1,
- boundary=None,
Bases:
IntEnumTensor type identifiers for TensorBindingsAPI.
Values match ovphysx_tensor_type_t in ovphysx_types.h. IntEnum members compare equal to plain ints, so they pass directly to the C API without conversion.
- ARTICULATION_BODY_COM_POSE = 61#
- ARTICULATION_BODY_INERTIA = 62#
- ARTICULATION_BODY_INV_INERTIA = 64#
- ARTICULATION_BODY_INV_MASS = 63#
- ARTICULATION_BODY_MASS = 60#
- ARTICULATION_CENTROIDAL_MOMENTUM = 14#
- ARTICULATION_CONTACT_OFFSET = 111#
- ARTICULATION_CORIOLIS_AND_CENTRIFUGAL_FORCE = 72#
- ARTICULATION_DOF_ACTUATION_FORCE = 34#
- ARTICULATION_DOF_ARMATURE = 40#
- ARTICULATION_DOF_DAMPING = 36#
- ARTICULATION_DOF_DRIVE_MODEL = 42#
- ARTICULATION_DOF_FRICTION_PROPERTIES = 41#
- ARTICULATION_DOF_LIMIT = 37#
- ARTICULATION_DOF_MAX_FORCE = 39#
- ARTICULATION_DOF_MAX_VELOCITY = 38#
- ARTICULATION_DOF_POSITION = 30#
- ARTICULATION_DOF_POSITION_TARGET = 32#
- ARTICULATION_DOF_PROJECTED_JOINT_FORCE = 75#
- ARTICULATION_DOF_STIFFNESS = 35#
- ARTICULATION_DOF_VELOCITY = 31#
- ARTICULATION_DOF_VELOCITY_TARGET = 33#
- ARTICULATION_FIXED_TENDON_DAMPING = 81#
- ARTICULATION_FIXED_TENDON_LIMIT = 83#
- ARTICULATION_FIXED_TENDON_LIMIT_STIFFNESS = 82#
- ARTICULATION_FIXED_TENDON_OFFSET = 85#
- ARTICULATION_FIXED_TENDON_REST_LENGTH = 84#
- ARTICULATION_FIXED_TENDON_STIFFNESS = 80#
- ARTICULATION_GRAVITY_FORCE = 73#
- ARTICULATION_JACOBIAN = 70#
- ARTICULATION_LINK_ACCELERATION = 22#
- ARTICULATION_LINK_INCOMING_JOINT_FORCE = 74#
- ARTICULATION_LINK_POSE = 20#
- ARTICULATION_LINK_VELOCITY = 21#
- ARTICULATION_LINK_WRENCH = 52#
- ARTICULATION_MASS_CENTER_LOCAL = 13#
- ARTICULATION_MASS_CENTER_WORLD = 12#
- ARTICULATION_MASS_MATRIX = 71#
- ARTICULATION_REST_OFFSET = 112#
- ARTICULATION_ROOT_POSE = 10#
- ARTICULATION_ROOT_VELOCITY = 11#
- ARTICULATION_SHAPE_FRICTION_AND_RESTITUTION = 110#
- ARTICULATION_SPATIAL_TENDON_DAMPING = 91#
- ARTICULATION_SPATIAL_TENDON_LIMIT_STIFFNESS = 92#
- ARTICULATION_SPATIAL_TENDON_OFFSET = 93#
- ARTICULATION_SPATIAL_TENDON_STIFFNESS = 90#
- DEFORMABLE_COLLISION_ELEMENT_INDICES = 125#
- DEFORMABLE_MATERIAL_BENDING_DAMPING = 136#
- DEFORMABLE_MATERIAL_BENDING_STIFFNESS = 134#
- DEFORMABLE_MATERIAL_DYNAMIC_FRICTION = 130#
- DEFORMABLE_MATERIAL_ELASTICITY_DAMPING = 133#
- DEFORMABLE_MATERIAL_POISSONS_RATIO = 132#
- DEFORMABLE_MATERIAL_THICKNESS = 135#
- DEFORMABLE_MATERIAL_YOUNGS_MODULUS = 131#
- DEFORMABLE_REST_NODAL_POSITION = 123#
- DEFORMABLE_SIM_ELEMENT_INDICES = 124#
- DEFORMABLE_SIM_KINEMATIC_TARGET = 122#
- DEFORMABLE_SIM_NODAL_POSITION = 120#
- DEFORMABLE_SIM_NODAL_VELOCITY = 121#
- INVALID = 0#
- RIGID_BODY_ACCELERATION = 6#
- RIGID_BODY_COM_POSE = 5#
- RIGID_BODY_CONTACT_OFFSET = 101#
- RIGID_BODY_DISABLE_SIMULATION = 9#
- RIGID_BODY_FORCE = 50#
- RIGID_BODY_INERTIA = 4#
- RIGID_BODY_INV_INERTIA = 8#
- RIGID_BODY_INV_MASS = 7#
- RIGID_BODY_MASS = 3#
- RIGID_BODY_POSE = 1#
- RIGID_BODY_REST_OFFSET = 102#
- RIGID_BODY_SHAPE_FRICTION_AND_RESTITUTION = 100#
- RIGID_BODY_VELOCITY = 2#
- RIGID_BODY_WRENCH = 51#
- SURFACE_DEFORMABLE_REST_POSITION = 143#
- SURFACE_DEFORMABLE_SIM_ELEMENT_INDICES = 144#
- SURFACE_DEFORMABLE_SIM_POSITION = 140#
- SURFACE_DEFORMABLE_SIM_VELOCITY = 141#
DLPack Tensor Structures#
DLPack tensor structures for zero-copy data interchange.
This module provides ctypes wrappers for the vendored DLPack C header, enabling efficient data sharing between the C library and Python without copying.
NOTE: This file is NOT copied from another repo. It is a hand-written Python/ctypes mirror of the C structs defined in ovphysx/dlpack/dlpack.h (which itself is the upstream header from https://github.com/dmlc/dlpack). When the vendored C header is updated, this file must be updated to match.
- class ovphysx.dlpack.DLDataType#
Bases:
StructureDescriptor of data type for elements of DLTensor.
- TYPE_MAP = {'bfloat16': (4, 16, 1), 'float16': (2, 16, 1), 'float32': (2, 32, 1), 'float32x4': (2, 32, 4), 'float64': (2, 64, 1), 'int16': (0, 16, 1), 'int32': (0, 32, 1), 'int64': (0, 64, 1), 'int8': (0, 8, 1), 'uint16': (1, 16, 1), 'uint32': (1, 32, 1), 'uint64': (1, 64, 1), 'uint8': (1, 8, 1), 'uint8x4': (1, 8, 4)}#
- bits#
Structure/Union member
- code#
Structure/Union member
- lanes#
Structure/Union member
- class ovphysx.dlpack.DLDataTypeCode#
Bases:
c_ubyteAn integer that encodes the category of DLTensor elements’ data type.
- kDLBfloat = 4#
- kDLBool = 6#
- kDLComplex = 5#
- kDLFloat = 2#
- kDLFloat4_e2m1fn = 17#
- kDLFloat6_e2m3fn = 15#
- kDLFloat6_e3m2fn = 16#
- kDLFloat8_e3m4 = 7#
- kDLFloat8_e4m3 = 8#
- kDLFloat8_e4m3b11fnuz = 9#
- kDLFloat8_e4m3fn = 10#
- kDLFloat8_e4m3fnuz = 11#
- kDLFloat8_e5m2 = 12#
- kDLFloat8_e5m2fnuz = 13#
- kDLFloat8_e8m0fnu = 14#
- kDLInt = 0#
- kDLOpaqueHandle = 3#
- kDLUInt = 1#
- class ovphysx.dlpack.DLDevice#
Bases:
StructureRepresents the device where DLTensor memory is allocated.
- device_id#
Structure/Union member
- device_type#
Structure/Union member
- class ovphysx.dlpack.DLDeviceType#
Bases:
c_longThe enum that encodes the type of the device where DLTensor memory is allocated.
- kDLCPU = 1#
- kDLCUDA = 2#
- kDLCUDAHost = 3#
- kDLCUDAManaged = 13#
- kDLExtDev = 12#
- kDLHexagon = 16#
- kDLMAIA = 17#
- kDLMetal = 8#
- kDLOneAPI = 14#
- kDLOpenCL = 4#
- kDLROCM = 10#
- kDLROCMHost = 11#
- kDLTrn = 18#
- kDLVPI = 9#
- kDLVulkan = 7#
- kDLWebGPU = 15#
- class ovphysx.dlpack.DLManagedTensor#
Bases:
StructureC structure for managed DLPack tensor.
- deleter#
Structure/Union member
- dl_tensor#
Structure/Union member
- manager_ctx#
Structure/Union member
- class ovphysx.dlpack.DLTensor#
Bases:
StructurePlain C Tensor object, does not manage memory.
- byte_offset#
Structure/Union member
- data#
Structure/Union member
- device#
Structure/Union member
- dtype#
Structure/Union member
- ndim#
Structure/Union member
- shape#
Structure/Union member
- strides#
Structure/Union member
- class ovphysx.dlpack.ManagedDLTensor(
- dl_tensor: DLTensor,
- manager_ctx: Any,
- deleter_callback: Callable | None = None,
Bases:
objectManaged DLPack tensor wrapper (CPU-only).
- property data: int#
Data pointer address.
- property device#
Device info.
- property dtype#
Data type descriptor.
- property ndim: int#
Number of dimensions.
- property shape: tuple[int, ...]#
Shape as Python tuple.
- to_bytes() bytes#
Get pixel data as bytes (creates copy).
Contact Report Structures#
ctypes mirrors of the C ABI structs returned by
ovphysx.api.PhysX.get_contact_report(); see the C API Reference
for full field semantics.
Contact report ctypes structures.
These ctypes.Structure mirrors of the C ABI structs returned by
ovphysx_get_contact_report() are used to access per-step contact data
in Python without copying. Field layouts must stay in sync with the C definitions
in ovphysx/include/ovphysx/ovphysx_types.h.
The module has no native-library dependencies and is safe to import in any Python process; the structures are populated by ctypes against pointers returned from the C API.
- class ovphysx.contact_types.ContactEventHeader#
Bases:
StructureContact event header. Mirrors
ovphysx_contact_event_header_t.- actor0#
Structure/Union member
- actor1#
Structure/Union member
- collider0#
Structure/Union member
- collider1#
Structure/Union member
- contactDataOffset#
Structure/Union member
- frictionAnchorsDataOffset#
Structure/Union member
- numContactData#
Structure/Union member
- numfrictionAnchorsData#
Structure/Union member
- protoIndex0#
Structure/Union member
- protoIndex1#
Structure/Union member
- stageId#
Structure/Union member
- type#
Structure/Union member
- class ovphysx.contact_types.ContactPoint#
Bases:
StructurePer-contact-point data. Mirrors
ovphysx_contact_point_t.- faceIndex0#
Structure/Union member
- faceIndex1#
Structure/Union member
- impulse#
Structure/Union member
- material0#
Structure/Union member
- material1#
Structure/Union member
- normal#
Structure/Union member
- position#
Structure/Union member
- separation#
Structure/Union member
Constants#
- ovphysx.OP_INDEX_ALL#
Sentinel value (
0xFFFFFFFFFFFFFFFF) passed towait_op()to wait for all outstanding operations. Equivalent toOVPHYSX_OP_INDEX_ALLin the C API.