Quick Start¶
This guide gets external partners from a clean machine to a running NovaPhy demo as quickly as possible, then points to the rest of the documentation for deeper integration.
Prerequisites¶
- Conda (Miniconda or Anaconda)
- vcpkg installed
- C++20 compiler
- MSVC 2022 (Windows)
- GCC 11+ (Linux)
- Clang 14+ (Linux / macOS)
- (Optional, for IPC) CUDA >= 12.4
- (Optional, for VBD CUDA backend) CUDA toolkit + NVCC
- (Optional, for SPH CUDA backend) CUDA toolkit + NVCC
Setup¶
# Create conda environment
conda env create -f environment.yml
conda activate novaphy
# Make your vcpkg toolchain visible to CMake
export CMAKE_TOOLCHAIN_FILE="/path/to/vcpkg/scripts/buildsystems/vcpkg.cmake"
# Windows PowerShell:
# $env:CMAKE_TOOLCHAIN_FILE="C:/path/to/vcpkg/scripts/buildsystems/vcpkg.cmake"
# Install NovaPhy
pip install -e .
# (Optional) Install with IPC support
git submodule update --init --recursive
CMAKE_ARGS="--preset=ipc" pip install -e .
# (Optional) VBD with CUDA backend
CMAKE_ARGS="-DNOVAPHY_WITH_VBD_CUDA=ON -DCMAKE_CUDA_COMPILER=/path/to/nvcc" pip install -e .
# (Optional) Enable SPH CUDA backend
CMAKE_ARGS="-DNOVAPHY_WITH_SPH_CUDA=ON -DCMAKE_CUDA_COMPILER=/path/to/nvcc" pip install -e .
See Build from Source for full details, compiler compatibility tables, and troubleshooting.
Verify¶
import novaphy
print(novaphy.version()) # 0.4.0
print(novaphy.has_ipc()) # True if built with IPC
print(novaphy.has_sph_cuda()) # True if built with SPH CUDA backend
Run a Demo¶
Demos live under python/demos/ and use Polyscope
for visualization (pip install polyscope).
# Rigid body demos (pick the solver backend with --solver)
python python/demos/demo_pyramid_ball.py --solver semi_implicit
python python/demos/demo_pyramid_ball.py --solver featherstone
python python/demos/demo_pyramid_ball.py --solver xpbd
# Articulated multibody demos
python python/demos/multibody_demo/demo_newtons_cradle_pendulum.py
python python/demos/multibody_demo/demo_rope.py
# Fluid demos
python python/demos/demo_dam_break.py
python python/demos/demo_ball_in_water.py
python python/demos/demo_sph_fluid.py
# IPC demo (requires IPC build)
python python/demos/demo_ipc_stack.py
# VBD / AVBD demos
python python/demos/demo_vbd_contacts_gui.py
python python/demos/demo_vbd_joint_gui.py
python python/demos/demo_vbd_spring_gui.py
The full demo list with screenshots and matching solver backends is in Demos.
What NovaPhy Looks Like in Code¶
NovaPhy uses Newton's solver-primary API: build a Model, construct a solver
with that model, and call
solver.step(state_in, state_out, control, contacts, dt) directly. There is
no World wrapper.
import numpy as np
import novaphy
# 1. Build the scene
builder = novaphy.ModelBuilder()
builder.add_ground_plane(y=0.0)
half_extents = np.array([0.5, 0.5, 0.5], dtype=np.float32)
body = novaphy.RigidBody.from_box(1.0, half_extents)
idx = builder.add_body(
body,
novaphy.Transform.from_translation(np.array([0.0, 5.0, 0.0], dtype=np.float32)),
)
builder.add_shape(novaphy.CollisionShape.make_box(half_extents, idx))
# 2. Finalize and create a solver + runtime buffers
model = builder.finalize()
solver = novaphy.solvers.SolverSemiImplicit(model)
state = model.state()
control = model.control()
collision_pipeline = novaphy.CollisionPipeline(model)
contacts = collision_pipeline.contacts()
# 3. Step the simulation
for step in range(600):
# Aliased state == in-place. Pass distinct buffers for checkpointed rollouts.
collision_pipeline.collide(state, contacts)
solver.step(state, state, control, contacts, 1.0 / 120.0)
if step % 120 == 0:
pos = state.transforms[idx].position
print(f"t={step/120:.1f}s y={pos[1]:.3f}")
Newton-aligned explicit collide + step chain¶
Newton separates broadphase / narrowphase from the constraint solve. Call
collision_pipeline.collide before solver.step so the solver has contacts to consume:
for step in range(600):
collision_pipeline.collide(state, contacts) # broadphase + narrowphase
solver.step(state, state, control, contacts, 1.0 / 120.0)
collision_pipeline.collide(state, contacts) matches Newton's collision-on-model
contract. If you skip the explicit call, rigid solvers run without rigid
contact constraints for that step.
Public Python Surface¶
import novaphy is the primary entry point. The partner-facing public API is
the set of names exported from novaphy.__all__, plus solver classes and
configuration objects under novaphy.solvers.
| Area | Public entry points |
|---|---|
| Version and feature checks | novaphy.version(), novaphy.has_ipc(), novaphy.has_sph_cuda() |
| Scene construction | ModelBuilder, Model, RigidBody, CollisionShape, ShapeConfig, ShapeType, ShapeFlags, Transform, SpatialTransform, Mesh, AABB, Site |
| Collision | CollisionPipeline, CollisionFilterPair, BroadPhaseMode, BroadPhasePair, SweepAndPrune |
| Runtime buffers | SimState, Control, Contacts |
| Solvers | novaphy.solvers.SolverSemiImplicit, SolverFeatherstone, SolverXPBD, SolverPBF, SolverSPH, SolverIPC, SolverMPM, SolverLBM, plus settings/config objects |
| Articulated bodies | Joint, JointType, JointDofConfig, Axis, axis_to_vec3, forward_kinematics, inverse_dynamics, mass_matrix_crba, forward_dynamics, forward_link_velocities, eval_fk |
| Fluids | FluidBlockDef, generate_fluid_block, SPHKernels, SpatialHashGrid, ParticleState, SPHState, BoundaryParticle, sample_model_boundaries, apply_particle_coupling_contacts, apply_particle_contact_reactions |
| Robot and scene I/O | UrdfParser, UrdfImportOptions, OpenUsdImporter, SceneBuilderEngine, SimulationExporter, FeatureCompletenessChecker, ModelBuilder.add_mjcf, ModelBuilder.add_mjcf_string |
| Observations and control helpers | novaphy.sensors, novaphy.actuators |
| Math, profiling, and utilities | skew, spatial_*, deg2rad, rad2deg, compute_inertia_mesh, batch_transform_vertices, Device, PerformanceMonitor, is_scaffold, scaffold_reason |
The full per-symbol reference lives in Python API Reference.
Integration Notes¶
When embedding NovaPhy into a partner application:
- NovaPhy uses SI units (meters, kilograms, seconds) unless an API states otherwise.
- Numeric data is float32-first. Prefer
np.float32for positions, velocities, forces, and geometry data crossing the boundary. Modelis immutable scene topology and can be shared across rollouts. Each environment instance allocates its ownSimState,Control, and collision-sizedContactsvia aCollisionPipelinebound to the sameModel.-
Guard optional CUDA features with feature checks before constructing CUDA-backed solvers:
-
novaphy.VBDWorldand, in IPC-enabled builds,novaphy.IPCWorldare legacy backend containers. New integration code should prefer the solver-primary APIs (novaphy.solvers.SolverIPCfor IPC; aSolverVBDwrapper is in flight for VBD).
Fluid Simulation¶
Run a Position Based Fluids dam break with the Newton-aligned solver chain:
import numpy as np
import novaphy
builder = novaphy.ModelBuilder()
builder.add_ground_plane(y=0.0)
fluid_block = novaphy.FluidBlockDef()
fluid_block.lower = np.array([0.0, 0.0, 0.0])
fluid_block.upper = np.array([1.0, 1.0, 1.0])
fluid_block.particle_spacing = 0.05
positions = novaphy.generate_fluid_block(fluid_block)
mass = fluid_block.rest_density * fluid_block.particle_spacing ** 3
radius = fluid_block.particle_spacing * 0.5
builder.add_particles(
positions,
[fluid_block.initial_velocity] * len(positions),
[mass] * len(positions),
[radius] * len(positions),
)
model = builder.finalize()
pbf_config = novaphy.solvers.PBFConfig()
pbf_config.kernel_radius = 4.0 * 0.05
pbf_config.solver_iterations = 4
# SolverPBF (fluid) chained with SolverSemiImplicit (rigid) gives full
# Akinci two-way coupling through the shared Contacts aggregate.
pbf_solver = novaphy.solvers.SolverPBF(model, pbf_config)
rigid_solver = novaphy.solvers.SolverSemiImplicit(model)
state = model.state()
pbf_solver.initialize_state(state)
control = model.control()
collision_pipeline = novaphy.CollisionPipeline(model)
contacts = collision_pipeline.contacts()
dt = 1.0 / 120.0
for _ in range(500):
collision_pipeline.collide(state, contacts)
pbf_solver.step(state, state, None, contacts, dt)
collision_pipeline.collide(state, contacts)
rigid_solver.step(state, state, control, contacts, dt)
Visualization¶
NovaPhy uses Polyscope for 3D visualization. Most demos include built-in visualization:
# Install polyscope
pip install polyscope
# Run a visual demo
python python/demos/demo_pyramid_ball.py
python python/demos/demo_dam_break.py
python python/demos/vbd/demo_vbd_rigid.py --scene pyramid --headless 120
Next Steps¶
- Architecture Guide — Understand NovaPhy's design
- Build from Source — Detailed build options and troubleshooting
- Migration: world.step → solver.step — Upgrade an older codebase
- Demos — Explore all available demos
- API Reference — Full Python API documentation