Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 6 additions & 3 deletions docs/api/workflows.rst
Original file line number Diff line number Diff line change
Expand Up @@ -107,16 +107,19 @@ VTK to USD

.. code-block:: python

import pyvista as pv
from physiotwin4d import WorkflowConvertVTKToUSD

input_meshes = [pv.read("heart_000.vtp"), pv.read("heart_001.vtp")]
workflow = WorkflowConvertVTKToUSD(
vtk_files=["heart_000.vtp", "heart_001.vtp"],
output_usd="heart.usd",
input_meshes=input_meshes,
usd_project_name="heart",
output_directory="./output",
appearance="anatomy",
anatomy_type="heart",
)

output_path = workflow.run()
output_path = workflow.process()

Statistical Shape Modeling
==========================
Expand Down
7 changes: 4 additions & 3 deletions docs/architecture.rst
Original file line number Diff line number Diff line change
Expand Up @@ -84,9 +84,10 @@ Primary Workflows
reference.

``WorkflowConvertVTKToUSD``
Converts VTK files to animated USD scenes through the supported workflow
wrapper. The lower-level :mod:`physiotwin4d.vtk_to_usd` package exposes
advanced file conversion primitives.
Converts in-memory PyVista/VTK meshes to static or animated USD scenes
through the supported workflow wrapper. The lower-level
:mod:`physiotwin4d.vtk_to_usd` package exposes advanced file conversion
primitives.

AI Surrogate Workflows (PhysicsNeMo)
=====================================
Expand Down
34 changes: 20 additions & 14 deletions docs/cli_scripts/byod_tutorials.rst
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,7 @@ selects its default reference frame internally.
segmentation_method=pt4d.SegmentChestTotalSegmentator(),
output_directory="./results",
project_name="heart_animated",
times_per_second=30.0,
frames_per_second=30.0,
)
workflow.process()

Expand Down Expand Up @@ -179,24 +179,27 @@ Pass a single ``.vtp`` file. Use ``--appearance`` to control material style and

.. code-block:: python

import pyvista as pv
import physiotwin4d as pt4d

workflow = pt4d.WorkflowConvertVTKToUSD(
vtk_files=["heart.vtp"],
output_usd="heart.usd",
input_meshes=[pv.read("heart.vtp")],
usd_project_name="heart",
output_directory=".",
appearance="anatomy",
anatomy_type="heart",
)
workflow.run()
workflow.process()

4D - Mesh Time Series
~~~~~~~~~~~~~~~~~~~~~

Pass per-frame VTK files. The default workflow treats multiple files as a time
series when their names match ``.t<index>.vtk``, ``.t<index>.vtp``, or
``.t<index>.vtu``. The VTK-to-USD CLI supports ``--fps`` to control playback
rate. For scalar colormaps, combine ``--primvar``, ``--cmap``, and
``--intensity-range``.
Pass per-frame VTK files in time order; the workflow treats them as an
ordered time series by list order (no filename pattern required). Pass
``--static-merge`` instead when the files are unrelated static meshes to
merge into one scene rather than animation frames. The VTK-to-USD CLI
supports ``--fps`` to control playback rate. For scalar colormaps, combine
``--primvar``, ``--cmap``, and ``--intensity-range``.

**CLI:**

Expand All @@ -220,18 +223,21 @@ rate. For scalar colormaps, combine ``--primvar``, ``--cmap``, and

.. code-block:: python

import pyvista as pv
import physiotwin4d as pt4d

input_meshes = [pv.read(f) for f in ("stress.t0.vtk", "stress.t1.vtk", "stress.t2.vtk")]
workflow = pt4d.WorkflowConvertVTKToUSD(
vtk_files=["stress.t0.vtk", "stress.t1.vtk", "stress.t2.vtk"],
output_usd="stress_animation.usd",
times_per_second=30,
input_meshes=input_meshes,
usd_project_name="stress_animation",
output_directory=".",
frames_per_second=30,
appearance="colormap",
colormap_primvar="vtk_point_stress_c0",
colormap_name="viridis",
colormap_intensity_range=(0, 500),
)
workflow.run()
workflow.process()

**Lower-level in-memory conversion with ConvertVTKToUSD:**

Expand All @@ -249,7 +255,7 @@ lower-level :class:`physiotwin4d.ConvertVTKToUSD` class directly:
converter = pt4d.ConvertVTKToUSD(
data_basename="HeartAnimation",
input_polydata=meshes,
times_per_second=30,
frames_per_second=30,
)
converter.convert("output.usd")

Expand Down
14 changes: 5 additions & 9 deletions docs/cli_scripts/download_data.rst
Original file line number Diff line number Diff line change
Expand Up @@ -28,18 +28,14 @@ Supported Datasets
Basic Usage
===========

Download the default dataset into the default location:
Download a dataset into its default location:

.. code-block:: bash

physiotwin4d-download-data
physiotwin4d-download-data Slicer-Heart-CT

This is equivalent to:

.. code-block:: bash

physiotwin4d-download-data Slicer-Heart-CT \
--directory data/Slicer-Heart-CT
Running the command with no arguments prints usage/help instead of
downloading anything.

Options
=======
Expand All @@ -50,7 +46,7 @@ Options

``data_name``
Dataset to download. One of ``Slicer-Heart-CT``, ``KCL-Heart-Model``, or
``CHOP-Valve4D``.
``CHOP-Valve4D``. Required — omitting it prints help and exits.

``--directory``
Directory where the dataset is stored. Defaults to ``data/<data_name>``.
Expand Down
11 changes: 7 additions & 4 deletions docs/cli_scripts/vtk_to_usd.rst
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,9 @@ VTK to USD Conversion
=====================

The ``physiotwin4d-convert-vtk-to-usd`` command converts VTK, VTP, or VTU
mesh files to USD for Omniverse visualization. Multiple input files are treated
as a time series.
mesh files to USD for Omniverse visualization. Multiple input files are
treated as an ordered time series by default; pass ``--static-merge`` to
instead merge unrelated static meshes into one scene with no time samples.

Basic Usage
===========
Expand Down Expand Up @@ -70,8 +71,10 @@ one mesh, or ``--by-cell-type`` to split by cell type.
Python API
==========

Use :class:`physiotwin4d.WorkflowConvertVTKToUSD` for the workflow API and
:class:`physiotwin4d.ConvertVTKToUSD` for direct in-memory conversion.
Use :class:`physiotwin4d.WorkflowConvertVTKToUSD` for the workflow API
(splitting and appearance built in) and :class:`physiotwin4d.ConvertVTKToUSD`
for lower-level control (e.g. anatomical label splitting via ``mask_ids``).
Both take in-memory PyVista/VTK meshes.

Related Pages
=============
Expand Down
2 changes: 1 addition & 1 deletion docs/developer/usd_generation.rst
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ Time Series
data_basename='Heart',
vtk_files=['heart_t0.vtp', 'heart_t1.vtp', 'heart_t2.vtp'],
time_codes=[0.0, 1.0, 2.0],
times_per_second=24.0,
frames_per_second=24.0,
).convert('animated_heart.usd')

In-Memory Meshes
Expand Down
20 changes: 12 additions & 8 deletions docs/tutorials.rst
Original file line number Diff line number Diff line change
Expand Up @@ -346,24 +346,28 @@ Preview
Output (placeholder — a real capture lands in a follow-up PR)

Inner API usage
The supported workflow wrapper converts one or more VTK files into an
animated, materially-painted USD stage:
The supported workflow wrapper converts one or more in-memory PyVista/VTK
meshes into an animated, materially-painted USD stage:

.. code-block:: python

import pyvista as pv

mesh = pv.read(str(vtk_file))
workflow = WorkflowConvertVTKToUSD(
vtk_files=[vtk_file],
output_usd=output_usd,
input_meshes=[mesh],
usd_project_name="surfaces",
output_directory=output_dir,
appearance="anatomy",
anatomy_type="heart",
separate_by_connectivity=True,
)
usd_file = workflow.run()
usd_file = workflow.process()

For callers who need more control than the workflow wrapper offers (e.g.
converting in-memory PyVista/VTK objects instead of files, or applying a
colormap), use :class:`physiotwin4d.ConvertVTKToUSD` directly — it is the
supported public entry point for VTK-to-USD conversion.
applying a colormap or per-label anatomical splitting), use
:class:`physiotwin4d.ConvertVTKToUSD` directly — it is the supported
public entry point for VTK-to-USD conversion.

Run
.. code-block:: bash
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@

# Conversion parameters
separate_by = "connectivity" # Essential for alterra vtk file
times_per_second = 60.0
frames_per_second = 60.0
solid_color = (0.5, 0.5, 0.5)

# %%
Expand Down Expand Up @@ -153,7 +153,7 @@
vtk_files=alterra_files,
extract_surface=True,
separate_by=separate_by,
times_per_second=times_per_second,
frames_per_second=frames_per_second,
solid_color=solid_color,
time_codes=alterra_times,
)
Expand Down
32 changes: 15 additions & 17 deletions experiments/Convert_VTK_To_USD/convert_chop_heart_vtk_to_usd.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
# %%
from pathlib import Path

import pyvista as pv

from physiotwin4d.workflow_convert_vtk_to_usd import WorkflowConvertVTKToUSD

Expand All @@ -25,33 +26,30 @@

output_dir.mkdir(parents=True, exist_ok=True)

all_files = []
all_meshes = []
for vtkname, usdname in zip(vtknames, usdnames):
out_usd = Path.absolute(output_dir / f"RVOT28-Dias-{usdname}.usd")
if out_usd.exists():
out_usd.unlink()
mesh = pv.read(str(input_dir / f"{vtkname}.vtk"))
all_meshes.append(mesh)

in_name = input_dir / f"{vtkname}.vtk"
all_files.append(in_name)

converter = WorkflowConvertVTKToUSD(
vtk_files=[in_name],
output_usd=out_usd,
workflow = WorkflowConvertVTKToUSD(
input_meshes=[mesh],
usd_project_name=f"RVOT28-Dias-{usdname}",
output_directory=output_dir,
separate_by_connectivity=False,
separate_by_cell_type=False,
mesh_name=f"RVOT28Dias_{usdname}",
appearance="anatomy",
anatomy_type="heart",
)
converter.run()
workflow.process()

converter = WorkflowConvertVTKToUSD(
vtk_files=all_files,
output_usd=Path.absolute(output_dir / Path("RVOT28-Dias-WholeHeart.usd")),
workflow = WorkflowConvertVTKToUSD(
input_meshes=all_meshes,
usd_project_name="RVOT28-Dias-WholeHeart",
output_directory=output_dir,
separate_by_connectivity=False,
separate_by_cell_type=False,
mesh_name="RVOT28Dias_WholeHeart",
static_merge=True,
appearance="anatomy",
anatomy_type="heart",
)
converter.run()
workflow.process()
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@

# Conversion parameters
separate_by = "connectivity" # Essential for tpv25 vtk file
times_per_second = 60.0
frames_per_second = 60.0
solid_color = (0.5, 0.5, 0.5)

# %%
Expand Down Expand Up @@ -150,7 +150,7 @@
vtk_files=tpv25_files,
extract_surface=True,
separate_by=separate_by,
times_per_second=times_per_second,
frames_per_second=frames_per_second,
solid_color=solid_color,
time_codes=tpv25_times,
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ def convert_contours(base_name, output_dir, project_name, compute_normals=False)
polydata = [pv.read(f) for f in files]

# For cardiac gated CT data with 21 time points (0-20), each frame = 1 second
# so we use times_per_second=1.0 instead of the default 24.0.
# so we use frames_per_second=1.0 instead of the default 24.0.
# Forwarding `seg` groups labels by anatomy type under
# /World/{project_name}/{type}/{label_name}.
converter = ConvertVTKToUSD(
Expand All @@ -72,7 +72,7 @@ def convert_contours(base_name, output_dir, project_name, compute_normals=False)
all_mask_ids,
segmenter=seg,
compute_normals=compute_normals,
times_per_second=1.0,
frames_per_second=1.0,
)
stage = converter.convert(
os.path.join(output_dir, f"{project_name}.{base_name}.usd"),
Expand Down
4 changes: 2 additions & 2 deletions src/physiotwin4d/cli/convert_image_to_usd.py
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ def main() -> int:
"--fps",
type=float,
default=24.0,
dest="times_per_second",
dest="frames_per_second",
help="Frames per second for animated USD time series (default: 24)",
)

Expand Down Expand Up @@ -159,7 +159,7 @@ def main() -> int:
output_directory=args.output_dir,
segmentation_method=segmentation_method,
registration_method=registration_method,
times_per_second=args.times_per_second,
frames_per_second=args.frames_per_second,
)
except Exception as e:
print(f"Error initializing workflow: {e}")
Expand Down
Loading
Loading