Low-Level vtk_to_usd Subpackage

physiomotion4d.vtk_to_usd is a stable low-level API for advanced external users. Inside this repository (experiments, workflows, CLIs, tutorials, tests), use ConvertVTKToUSD from VTK to USD Conversion instead of importing this subpackage directly.

This subpackage exposes the readers, data containers, coordinate helpers, and USD primitive writers that back ConvertVTKToUSD. The public symbols are documented in their defining submodules below; __init__ re-exports them for convenience.

File Facade

Public low-level file conversion facade for vtk_to_usd.

physiomotion4d.vtk_to_usd.converter.convert_vtk_file(vtk_file, output_usd_file, *, data_basename=None, mesh_name='Mesh', extract_surface=True, settings=None, material=None)[source]

Convert one VTK file to one USD stage.

This is the stable low-level facade for advanced users who want the file-based vtk_to_usd conversion layer directly. In-repository workflows, experiments, and CLIs should use physiomotion4d.ConvertVTKToUSD instead.

Parameters:
  • vtk_file (Union[str, Path]) – Input VTK file path (.vtk, .vtp, or .vtu).

  • output_usd_file (Union[str, Path]) – Output USD file path.

  • data_basename (Optional[str]) – Root prim name under /World. Defaults to the input stem.

  • mesh_name (str) – Mesh prim name under /World/{data_basename}.

  • extract_surface (bool) – If True, extract surfaces from volumetric VTK datasets.

  • settings (Optional[ConversionSettings]) – Optional conversion settings. Defaults to ConversionSettings().

  • material (Optional[MaterialData]) – Optional material. Defaults to settings.default_color.

Return type:

Stage

Returns:

Created USD stage.

Data Structures

Data structures for VTK to USD conversion.

Based on OmniConnectData from ParaViewConnector but simplified for file-based conversion.

class physiomotion4d.vtk_to_usd.data_structures.DataType(value)[source]

Bases: Enum

Data type enumeration for generic arrays.

UCHAR = 'uchar'
CHAR = 'char'
USHORT = 'ushort'
SHORT = 'short'
UINT = 'uint'
INT = 'int'
ULONG = 'ulong'
LONG = 'long'
FLOAT = 'float'
DOUBLE = 'double'
class physiomotion4d.vtk_to_usd.data_structures.GenericArray(name, data, num_components, data_type, interpolation='vertex')[source]

Bases: object

Generic data array that can be converted to USD primvar.

Represents a named array of data with a specific type and number of components. Mimics OmniConnectGenericArray from ParaViewConnector.

name: str
data: ndarray[tuple[Any, ...], dtype[_ScalarT]]
num_components: int
data_type: DataType
interpolation: str = 'vertex'
__post_init__()[source]

Validate and normalize data shape.

Handles three cases: 1. 1D array with num_components=1: kept as-is (scalar) 2. 1D array with num_components>1: reshaped to 2D if length is divisible 3. 2D array: validated that shape[1] matches num_components

Return type:

None

__init__(name, data, num_components, data_type, interpolation='vertex')
class physiomotion4d.vtk_to_usd.data_structures.MaterialData(name='default_material', diffuse_color=(0.8, 0.8, 0.8), specular_color=(0.0, 0.0, 0.0), emissive_color=(0.0, 0.0, 0.0), opacity=1.0, roughness=0.5, metallic=0.0, ior=1.5, use_vertex_colors=False)[source]

Bases: object

Material properties for USD conversion.

Mimics OmniConnectMaterialData from ParaViewConnector.

name: str = 'default_material'
diffuse_color: tuple[float, float, float] = (0.8, 0.8, 0.8)
specular_color: tuple[float, float, float] = (0.0, 0.0, 0.0)
emissive_color: tuple[float, float, float] = (0.0, 0.0, 0.0)
opacity: float = 1.0
roughness: float = 0.5
metallic: float = 0.0
ior: float = 1.5
use_vertex_colors: bool = False
__init__(name='default_material', diffuse_color=(0.8, 0.8, 0.8), specular_color=(0.0, 0.0, 0.0), emissive_color=(0.0, 0.0, 0.0), opacity=1.0, roughness=0.5, metallic=0.0, ior=1.5, use_vertex_colors=False)
class physiomotion4d.vtk_to_usd.data_structures.MeshData(points, face_vertex_counts, face_vertex_indices, normals=None, uvs=None, colors=None, generic_arrays=<factory>, material_id='default_material')[source]

Bases: object

Mesh geometry data for USD conversion.

Mimics OmniConnectMeshData from ParaViewConnector.

points: ndarray[tuple[Any, ...], dtype[_ScalarT]]
face_vertex_counts: ndarray[tuple[Any, ...], dtype[_ScalarT]]
face_vertex_indices: ndarray[tuple[Any, ...], dtype[_ScalarT]]
normals: ndarray[tuple[Any, ...], dtype[_ScalarT]] | None = None
uvs: ndarray[tuple[Any, ...], dtype[_ScalarT]] | None = None
colors: ndarray[tuple[Any, ...], dtype[_ScalarT]] | None = None
generic_arrays: list[GenericArray]
material_id: str = 'default_material'
__post_init__()[source]

Validate mesh data.

Return type:

None

__init__(points, face_vertex_counts, face_vertex_indices, normals=None, uvs=None, colors=None, generic_arrays=<factory>, material_id='default_material')
class physiomotion4d.vtk_to_usd.data_structures.VolumeData(image_data, spacing=(1.0, 1.0, 1.0), origin=(0.0, 0.0, 0.0), scalar_range=None, generic_arrays=<factory>)[source]

Bases: object

Volume data for USD conversion.

Mimics OmniConnectVolumeData from ParaViewConnector.

image_data: ndarray[tuple[Any, ...], dtype[_ScalarT]]
spacing: tuple[float, float, float] = (1.0, 1.0, 1.0)
origin: tuple[float, float, float] = (0.0, 0.0, 0.0)
scalar_range: tuple[float, float] | None = None
generic_arrays: list[GenericArray]
__init__(image_data, spacing=(1.0, 1.0, 1.0), origin=(0.0, 0.0, 0.0), scalar_range=None, generic_arrays=<factory>)
class physiomotion4d.vtk_to_usd.data_structures.TimeStepData(time_code, meshes=<factory>, volumes=<factory>, materials=<factory>)[source]

Bases: object

Data for a single time step.

time_code: float
meshes: dict[str, MeshData]
volumes: dict[str, VolumeData]
materials: dict[str, MaterialData]
__init__(time_code, meshes=<factory>, volumes=<factory>, materials=<factory>)
class physiomotion4d.vtk_to_usd.data_structures.ConversionSettings(output_binary=False, meters_per_unit=1.0, up_axis='Y', triangulate_meshes=True, compute_normals=True, preserve_point_arrays=True, preserve_cell_arrays=True, separate_objects_by_cell_type=False, separate_objects_by_connectivity=False, use_preview_surface=True, default_color=(0.8, 0.8, 0.8), times_per_second=24.0, use_time_samples=True, point_array_prefix='vtk_point_', cell_array_prefix='vtk_cell_')[source]

Bases: object

Settings for VTK to USD conversion.

output_binary: bool = False
meters_per_unit: float = 1.0
up_axis: str = 'Y'
triangulate_meshes: bool = True
compute_normals: bool = True
preserve_point_arrays: bool = True
preserve_cell_arrays: bool = True
separate_objects_by_cell_type: bool = False
separate_objects_by_connectivity: bool = False
use_preview_surface: bool = True
default_color: tuple[float, float, float] = (0.8, 0.8, 0.8)
times_per_second: float = 24.0
use_time_samples: bool = True
point_array_prefix: str = 'vtk_point_'
cell_array_prefix: str = 'vtk_cell_'
__post_init__()[source]

Validate that at most one of the split options is enabled.

Return type:

None

__init__(output_binary=False, meters_per_unit=1.0, up_axis='Y', triangulate_meshes=True, compute_normals=True, preserve_point_arrays=True, preserve_cell_arrays=True, separate_objects_by_cell_type=False, separate_objects_by_connectivity=False, use_preview_surface=True, default_color=(0.8, 0.8, 0.8), times_per_second=24.0, use_time_samples=True, point_array_prefix='vtk_point_', cell_array_prefix='vtk_cell_')

VTK Readers

VTK file readers for various VTK formats (VTK, VTP, VTU).

Reads VTK files and extracts geometry, topology, and data arrays.

class physiomotion4d.vtk_to_usd.vtk_reader.VTKReader[source]

Bases: object

Base class for VTK file readers.

class physiomotion4d.vtk_to_usd.vtk_reader.PolyDataReader[source]

Bases: VTKReader

Reader for VTK PolyData files (.vtp).

static read(filename)[source]

Read a VTP file and return MeshData.

Parameters:

filename (str | Path) – Path to .vtp file

Returns:

Extracted mesh data

Return type:

MeshData

class physiomotion4d.vtk_to_usd.vtk_reader.LegacyVTKReader[source]

Bases: VTKReader

Reader for legacy VTK files (.vtk).

Handles all legacy VTK dataset types: - POLYDATA - UNSTRUCTURED_GRID - STRUCTURED_GRID - STRUCTURED_POINTS - RECTILINEAR_GRID

static read(filename, extract_surface=True)[source]

Read a legacy VTK file and return MeshData.

Parameters:
  • filename (str | Path) – Path to .vtk file

  • extract_surface (bool) – If True, extract surface from volumetric data

Returns:

Extracted mesh data

Return type:

MeshData

class physiomotion4d.vtk_to_usd.vtk_reader.UnstructuredGridReader[source]

Bases: VTKReader

Reader for VTK UnstructuredGrid files (.vtu).

static read(filename, extract_surface=True)[source]

Read a VTU file and return MeshData.

Parameters:
  • filename (str | Path) – Path to .vtu file

  • extract_surface (bool) – If True, extract surface as PolyData

Returns:

Extracted mesh data

Return type:

MeshData

physiomotion4d.vtk_to_usd.vtk_reader.read_vtk_file(filename, extract_surface=True)[source]

Auto-detect VTK file format and read appropriately.

Parameters:
  • filename (str | Path) – Path to VTK file (.vtk, .vtp, or .vtu)

  • extract_surface (bool) – For .vtu and .vtk files, whether to extract surface from volumetric data

Returns:

Extracted mesh data

Return type:

MeshData

Raises:

ValueError – If file format is not supported

physiomotion4d.vtk_to_usd.vtk_reader.validate_time_series_topology(mesh_data_sequence, filenames=None)[source]

Validate topology consistency across a time series of meshes.

Checks for: - Changes in number of points/cells over time - Inconsistent primvar sizes

Parameters:
  • mesh_data_sequence (list[MeshData]) – List of MeshData objects

  • filenames (list[str | Path] | None) – Optional list of filenames for better error messages

Returns:

Validation report with warnings and statistics

Return type:

dict

USD Mesh Conversion

USD Mesh converter for creating UsdGeomMesh from MeshData.

Handles geometry, normals, colors, primvars, and time-varying attributes.

class physiomotion4d.vtk_to_usd.usd_mesh_converter.UsdMeshConverter(stage, settings, material_mgr)[source]

Bases: object

Converts MeshData to UsdGeomMesh with full feature support.

Handles: - Geometry (points, faces, normals) - Vertex colors and display color primvars - Generic data arrays as primvars - Time-varying attributes - Material binding

__init__(stage, settings, material_mgr)[source]

Initialize mesh converter.

Parameters:
create_mesh(mesh_data, mesh_path, time_code=None, bind_material=True)[source]

Create a UsdGeomMesh from MeshData.

Parameters:
  • mesh_data (MeshData) – Mesh data to convert

  • mesh_path (str) – USD path for the mesh

  • time_code (Optional[float]) – Optional time code for time-varying data

  • bind_material (bool) – Whether to create and bind material

Returns:

Created USD mesh

Return type:

UsdGeom.Mesh

create_time_varying_mesh(mesh_data_sequence, mesh_path, time_codes, bind_material=True)[source]

Create a mesh with time-varying attributes.

Assumes constant topology (same number of points/faces).

Parameters:
  • mesh_data_sequence (list[MeshData]) – List of MeshData for each time step

  • mesh_path (str) – USD path for the mesh

  • time_codes (list[float]) – List of time codes

  • bind_material (bool) – Whether to create and bind material

Returns:

Created USD mesh with time samples

Return type:

UsdGeom.Mesh

Material Manager

Material management for USD export.

Creates and manages UsdPreviewSurface materials for mesh rendering.

class physiomotion4d.vtk_to_usd.material_manager.MaterialManager(stage, materials_scope_path='/World/Looks')[source]

Bases: object

Manages creation and binding of USD materials.

Creates UsdPreviewSurface materials based on MaterialData specifications. Handles material caching to avoid duplicate creation.

__init__(stage, materials_scope_path='/World/Looks')[source]

Initialize material manager.

Parameters:
  • stage (Stage) – USD stage

  • materials_scope_path (str) – Path where materials will be created

create_material(mat_data, time_code=None)[source]

Create a UsdPreviewSurface material.

Parameters:
  • mat_data (MaterialData) – Material data specification

  • time_code (Optional[float]) – Optional time code for time-varying materials

Returns:

Created material

Return type:

UsdShade.Material

bind_material(geom_prim, material)[source]

Bind a material to a geometry prim.

Parameters:
  • geom_prim (Gprim) – Geometry prim (Mesh, Points, etc.)

  • material (Material) – Material to bind

Return type:

None

get_or_create_material(mat_data, time_code=None)[source]

Get existing material from cache or create new one.

Parameters:
  • mat_data (MaterialData) – Material data specification

  • time_code (Optional[float]) – Optional time code for time-varying materials

Returns:

Material (cached or newly created)

Return type:

UsdShade.Material

create_default_material(name='default', color=(0.8, 0.8, 0.8))[source]

Create a simple default material.

Parameters:
Returns:

Created default material

Return type:

UsdShade.Material

Mesh Utilities

Mesh utilities for VTK to USD conversion.

Includes splitting meshes by cell type (face vertex count) or by connectivity for separate USD prims.

physiomotion4d.vtk_to_usd.mesh_utils.cell_type_name_for_vertex_count(count)[source]

Return a readable name for a cell type given its vertex count.

Return type:

str

physiomotion4d.vtk_to_usd.mesh_utils.split_mesh_data_by_cell_type(mesh_data, mesh_name)[source]

Split MeshData into one mesh per distinct face vertex count (cell type).

Each part is named as mesh_name plus the cell type (e.g. MeshName_Triangle, MeshName_Quad).

Parameters:
  • mesh_data (MeshData) – Single mesh that may contain mixed cell types.

  • mesh_name (str) – Name of the source mesh; used as prefix in returned base_name.

Return type:

list[tuple[MeshData, str]]

Returns:

List of (MeshData, base_name) for each cell type present. base_name is mesh_name + “_” + cell type name (e.g. “MeshName_Triangle”, “MeshName_Quad”).

physiomotion4d.vtk_to_usd.mesh_utils.split_mesh_data_by_connectivity(mesh_data, mesh_name)[source]

Split MeshData into one mesh per connected component.

A connected component is a maximal set of cells that share vertices (directly or transitively). Components are named mesh_name_object1, mesh_name_object2, etc.

Parameters:
  • mesh_data (MeshData) – Single mesh that may contain multiple disconnected parts.

  • mesh_name (str) – Name of the source mesh; used as prefix in returned base_name.

Return type:

list[tuple[MeshData, str]]

Returns:

List of (MeshData, base_name) for each component. base_name is mesh_name + “_objectN” (e.g. “MeshName_object1”, “MeshName_object2”, …).

USD Coordinate and Primvar Helpers

USD utility functions for VTK to USD conversion.

Provides helper functions for coordinate conversion, primvar creation, and USD type mapping.

physiomotion4d.vtk_to_usd.usd_utils.ras_to_usd(point)[source]

Convert RAS (Right-Anterior-Superior) coordinates to USD’s right-handed Y-up system.

VTK/Medical imaging typically uses RAS coordinate system: - R (Right): X-axis points to patient’s right - A (Anterior): Y-axis points to patient’s front - S (Superior): Z-axis points to patient’s head

USD uses right-handed Y-up: - X: right - Y: up - Z: back (toward camera)

Conversion: USD(x, y, z) = RAS(x, z, -y) * 0.001 (mm → m)

Parameters:

point (ndarray[tuple[Any, ...], dtype[TypeVar(_ScalarT, bound= generic)]] | tuple | list) – Point in RAS coordinates [x, y, z] in millimeters

Returns:

Point in USD coordinates in meters

Return type:

Gf.Vec3f

physiomotion4d.vtk_to_usd.usd_utils.ras_points_to_usd(points)[source]

Convert array of RAS points (mm) to USD coordinates (m).

Applies axis swap RAS → Y-up and scales millimeters to meters (* 0.001).

Parameters:

points (ndarray[tuple[Any, ...], dtype[TypeVar(_ScalarT, bound= generic)]]) – Array of points with shape (N, 3) in millimeters

Returns:

Points in USD Y-up coordinates in meters

Return type:

Vt.Vec3fArray

physiomotion4d.vtk_to_usd.usd_utils.ras_normals_to_usd(normals)[source]

Convert array of RAS normals to USD Y-up coordinates.

Applies only the axis swap — normals are unit direction vectors and must not be scaled by the mm→m factor.

Parameters:

normals (ndarray[tuple[Any, ...], dtype[TypeVar(_ScalarT, bound= generic)]]) – Array of normals with shape (N, 3)

Returns:

Normals in USD Y-up coordinates (unit length preserved)

Return type:

Vt.Vec3fArray

physiomotion4d.vtk_to_usd.usd_utils.numpy_to_vt_array(array, data_type)[source]

Convert numpy array to appropriate VtArray type.

Parameters:
Return type:

Any

Returns:

Appropriate VtArray based on data_type and array shape

physiomotion4d.vtk_to_usd.usd_utils.get_sdf_value_type(data_type, num_components)[source]

Get appropriate SDF value type for primvar creation.

Parameters:
  • data_type (DataType) – Data type

  • num_components (int) – Number of components (1, 2, 3, or 4)

Returns:

Appropriate USD type

Return type:

Sdf.ValueTypeName

physiomotion4d.vtk_to_usd.usd_utils.sanitize_primvar_name(name)[source]

Sanitize a name to be USD-compliant.

USD attribute names must: - Start with a letter or underscore - Contain only letters, numbers, and underscores - Not contain dots, spaces, or special characters

Parameters:

name (str) – Original name

Returns:

Sanitized name safe for USD

Return type:

str

physiomotion4d.vtk_to_usd.usd_utils.create_primvar(geom, array, array_name_prefix='', time_code=None)[source]

Create a USD primvar from a GenericArray.

Parameters:
  • geom (UsdGeom.Gprim) – USD geometry prim (Mesh, Points, etc.)

  • array (GenericArray) – GenericArray containing data

  • array_name_prefix (str) – Prefix for primvar name (e.g., "vtk_point_")

  • time_code (float | None) – Optional time code for time-varying data

Returns:

Created primvar, or None if validation failed

Return type:

UsdGeom.Primvar

physiomotion4d.vtk_to_usd.usd_utils.triangulate_face(face_counts, face_indices)[source]

Triangulate polygonal faces using fan triangulation.

Parameters:
Returns:

  • tri_counts: int32 array, all entries equal to 3.

  • tri_indices: int32 flat array of triangle vertex indices.

  • source_face_index_per_triangle: int32 array mapping each output triangle back to its source face in face_counts. Length matches tri_counts. Use this to expand uniform (per-face) primvar data to match the triangulated face count: new_data = old_data[mapping].

Return type:

(tri_counts, tri_indices, source_face_index_per_triangle)

physiomotion4d.vtk_to_usd.usd_utils.compute_mesh_extent(points)[source]

Compute bounding box extent for a mesh.

Parameters:

points (Vec3fArray) – Array of points

Returns:

Extent as [min_point, max_point]

Return type:

Vt.Vec3fArray

physiomotion4d.vtk_to_usd.usd_utils.add_framing_camera(stage, *, parent_path='/World', name='Camera', bounds_min=None, bounds_max=None, focal_length_mm=50.0, horizontal_aperture_mm=36.0, distance_factor=3.0)[source]

Define a USD camera that frames stage geometry with tight clipping planes.

Adds a UsdGeom.Camera prim at {parent_path}/{name} positioned along +Z to view the supplied (or stage-computed) bounding box. Sets a tight clippingRange so users can zoom close in Omniverse Kit and other USD viewers without geometry vanishing at the near plane.

Bounds must be expressed in stage coordinates (post axis-swap and unit scaling). For time-varying stages, bounds are sampled at the start time code.

Parameters:
  • stage (Usd.Stage) – The USD stage. Must already contain geometry when bounds are not supplied; world bounds are then computed from the stage.

  • parent_path (str) – Parent prim path. Defaults to "/World".

  • name (str) – Camera prim name. Defaults to "Camera".

  • bounds_min (tuple[float, float, float] | None) – Optional min corner (x, y, z) in stage coordinates.

  • bounds_max (tuple[float, float, float] | None) – Optional max corner (x, y, z) in stage coordinates.

  • focal_length_mm (float) – Camera focal length. USD camera lens parameters are always in millimeters regardless of metersPerUnit.

  • horizontal_aperture_mm (float) – Camera horizontal aperture in millimeters.

  • distance_factor (float) – Camera distance from bbox center as a multiple of the bounding-box diagonal. 3.0 gives generous framing.

Return type:

UsdGeom.Camera | None

Returns:

The created Camera prim, or None if no valid bounds could be found.

Primvar Derivations

Derived primvar computations for VTK-to-USD conversion.

This module hosts a small registry of functions that compute new scalar or vector primvars from existing ones, so that downstream colormap workflows can visualize physically meaningful quantities (von Mises stress, principal invariants, trace, magnitudes, etc.) without depending on the raw tensor representation.

Adding a new derivation

  1. Write a function derive_<name>(array: GenericArray) -> list[GenericArray]. It inspects array (name, num_components, interpolation, data) and returns zero or more derived GenericArray objects. Returning an empty list means “this derivation does not apply.”

  2. Append the function to PRIMVAR_DERIVATIONS below.

The conversion pipeline calls derive_primvars to apply every registered function to every existing primvar; the results are appended to the mesh’s generic_arrays list.

Naming convention

Use <source_name>_<DerivedName> (capitalized derived suffix). Capital letters sort before lowercase in ASCII, so stress_VonMises is selected over stress_c0 by USDTools.pick_color_primvar’s alphabetical tiebreak.

physiomotion4d.vtk_to_usd.primvar_derivations.compute_von_mises_stress(stress_tensor)[source]

Compute scalar von Mises stress from a row-major 9-component tensor.

The input tensor layout is:

[s_xx, s_xy, s_xz, s_yx, s_yy, s_yz, s_zx, s_zy, s_zz]

Off-diagonal pairs are averaged to symmetrize, which is a no-op for an already-symmetric Cauchy stress tensor.

Formula:

sigma_VM = sqrt(0.5 * [(sxx-syy)^2 + (syy-szz)^2 + (szz-sxx)^2]
                + 3.0 * (sxy^2 + syz^2 + szx^2))
Parameters:

stress_tensor (ndarray[tuple[Any, ...], dtype[TypeVar(_ScalarT, bound= generic)]]) – Array of shape (N, 9) or a flat length N * 9.

Return type:

ndarray[tuple[Any, ...], dtype[TypeVar(_ScalarT, bound= generic)]]

Returns:

Float32 array of shape (N,) with per-element von Mises stress.

physiomotion4d.vtk_to_usd.primvar_derivations.PrimvarDerivation

Signature for a primvar-derivation function.

A derivation inspects one source GenericArray and returns zero or more newly-computed GenericArray objects. Return [] when the derivation does not apply to the source array.

alias of Callable[[GenericArray], list[GenericArray]]

physiomotion4d.vtk_to_usd.primvar_derivations.derive_von_mises_from_stress(array)[source]

Derive a scalar VonMises primvar from any 9-component stress tensor.

Matches any source array whose name contains "stress" (case-insensitive) and has 9 components.

Return type:

list[GenericArray]

physiomotion4d.vtk_to_usd.primvar_derivations.PRIMVAR_DERIVATIONS: list[Callable[[GenericArray], list[GenericArray]]] = [<function derive_von_mises_from_stress>]

Ordered list of derivations applied to every input primvar.

Append a function to extend the pipeline. External callers may also mutate this list (e.g. to register project-specific derivations at import time), but keep in mind the list is module-global.

physiomotion4d.vtk_to_usd.primvar_derivations.derive_primvars(arrays)[source]

Apply every registered derivation to every array in arrays.

Parameters:

arrays (list[GenericArray]) – Source primvars. Not modified.

Return type:

list[GenericArray]

Returns:

The newly-derived primvars only (does not include the originals). Callers typically extend their source list with the result.

See Also