PyBevy is in an early and experimental stage. The API is incomplete, subject to breaking changes without notice, and you should expect bugs. Many features are still under development.
NumPy Point Cloud
Create a custom mesh from a NumPy array to render a point cloud.
Introduction
This advanced recipe shows how to integrate pybevy with numpy, a popular
Python library for numerical computing. We will generate a large number of points
using numpy and then render them efficiently as a "point cloud" using a custom mesh.
# You will need to install numpy: pip install numpy
import numpy as np
from pybevy.prelude import *Generating Points with NumPy
We'll create a function to generate points on the surface of a sphere.
This is a classic algorithm that uses numpy for fast, vectorized operations.
The function will return a numpy array of shape (N, 3).
def generate_sphere_points(num_points: int) -> np.ndarray:
indices = np.arange(0, num_points, dtype=float) + 0.5
phi = np.arccos(1 - 2 * indices / num_points)
theta = np.pi * (1 + 5**0.5) * indices
x, y, z = np.cos(theta) * np.sin(phi), np.sin(theta) * np.sin(phi), np.cos(phi)
return np.stack([x, y, z], axis=-1) * 5.0 # Scale the sphereThe Setup System
This is where the magic happens.
- We call our
numpyfunction to get the point data. - We create a new
Meshasset. - We set the mesh's vertex positions using the
numpyarray. - Crucially, we set the
primitive_topologytoPointList. This tells the GPU to render each vertex as a single point, rather than trying to connect them into triangles.
def setup(
commands: Commands,
meshes: ResMut[Assets[Mesh]],
materials: ResMut[Assets[StandardMaterial]],
):
# Generate 50,000 points using NumPy
points = generate_sphere_points(50000)
# Create a new Bevy mesh
point_cloud_mesh = Mesh()
# Set the vertex positions from the NumPy array
point_cloud_mesh.set_attribute(Mesh.ATTRIBUTE_POSITION, points)
# Set the topology to PointList
point_cloud_mesh.primitive_topology = PrimitiveTopology.PointList
# Spawn the point cloud entity
commands.spawn(
Mesh3d(meshes.add(point_cloud_mesh)),
MeshMaterial3d(materials.add(StandardMaterial(
base_color=Color.srgb(0.9, 0.2, 0.3),
unlit=True, # Unlit makes points visible without a light source
))),
)
# Spawn a camera
commands.spawn(
Camera3d(),
Transform.from_xyz(0.0, 0.0, 15.0).looking_at(Vec3.ZERO, Vec3.Y),
)Running the App
This will render a sphere made of thousands of individual points. This technique is very efficient for visualizing large datasets, simulations, or creating particle effects.
@entrypoint
def main(app: App) -> App:
return app.add_plugins(DefaultPlugins).add_systems(Startup, setup)
if __name__ == "__main__":
main().run()