Sample: Directly filling a GeomVertexData instance using NumPy arrays

Today I tried to fill a GeomVertexData directly, and above all FAST, using a numpy array. Using a GeomVertexWriter requires me to iterate over my data (medium sized pointclouds), which is very slow in python.

Instead I directly filled the buffer using the following. For this, I created a “custom” vertexDataFormat, so there are two GeomVertexArrays that I can fill separately later on.

import panda3d.core as core
import numpy as np

# Create the vertex array data format
positionColFormat = core.GeomVertexArrayFormat(
    "vertex",
    3,
    core.Geom.NT_float32,
    core.Geom.C_point
)
colorColFormat = core.GeomVertexArrayFormat(
    "color",
    4,
    core.Geom.NT_uint8,
    core.Geom.C_color
)

# Create the overall format that contains the arrays
vertexDataFormat = core.GeomVertexFormat()
vertexDataFormat.addArray(positionColFormat)
vertexDataFormat.addArray(colorColFormat)
vertexDataFormat = core.GeomVertexFormat.registerFormat(vertexDataFormat) #important!

vertexData = core.GeomVertexData(
    "Pointcloud",
    vertexDataFormat,
    core.Geom.UH_static
)

# Assuming you have created some numpy array somewhere else...
positions = np.array(...)  # shape: (n,3)
colors = np.array(...)     # shape: (n,4)

arrayHandle0: core.GeomVertexArrayData = vertexData.modifyArray(0)
arrayHandle1: core.GeomVertexArrayData = vertexData.modifyArray(1)

# Make sure the data is copied using the right type
arrayHandle0.modifyHandle().copyDataFrom(positions.astype(np.float32))
arrayHandle1.modifyHandle().copyDataFrom(colors.astype(np.uint8))

# go on with the creation of a Geom in your scene ...

I was struggeling to find a good example for this, so I hope this will help some of you.