Skip to content

Faster alternative to mesh.from_pydata() #70

Description

@BradyAJohnston

If we manually add vertices & set attributes, we can be much faster than the default .from_pydata() that Blender uses.

These benchmarks are just operating on the verts, but the same approach for adding edges and faces can be taken.

Benchmark below:

import bpy
import numpy as np

n = int(1e5)
data = np.random.rand(n * 3).astype(np.float32).reshape(n, 3)


def from_pydata():
    mesh = bpy.data.meshes.new("mesh")
    mesh.from_pydata(data, [], [])


def vertices_foreach_set():
    mesh = bpy.data.meshes.new("mesh")
    mesh.vertices.add(n)
    mesh.vertices.foreach_set("co", data.ravel())


def attributes_foreach_set():
    mesh = bpy.data.meshes.new("mesh")
    mesh.vertices.add(n)
    mesh.attributes["position"].data.foreach_set("vector", data.ravel())


def test_from_pydata(benchmark):
    result = benchmark(from_pydata)


def test_vertices_foreach_set(benchmark):
    result = benchmark(vertices_foreach_set)


def test_attributes_foreach_set(benchmark):
    result = benchmark(attributes_foreach_set)

A total of 350x faster to manually allocate verts and then operate on their position attribute:

Image

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions