# vertex positional difference alternative using numpy

I have a function looking at a difference in vertex positions, and storing that difference on a third mesh -

def mesh_difference(A, B, difference):
# Get the objects from the collection using their names
object_A = bpy.data.objects[A]
object_B = bpy.data.objects[B]
object_difference = bpy.data.objects[difference]

# Get the meshes from the objects
mesh_A = object_A.data
mesh_B = object_B.data
mesh_difference = object_difference.data

# Get the vertices of each mesh
verts_A = mesh_A.vertices
verts_B = mesh_B.vertices
verts_difference = mesh_difference.vertices

# Loop through the vertices and calculate the difference in position
for i in range(len(verts_A)):
vert_A = verts_A[i]
vert_B = verts_B[i]
vert_difference = verts_difference[i]

# Check if the positions of the vertices are different between mesh_A and mesh_B
if vert_A.co != vert_B.co:
# Calculate the difference in position
diff_x = vert_A.co.x - vert_B.co.x
diff_y = vert_A.co.y - vert_B.co.y
diff_z = vert_A.co.z - vert_B.co.z

# Move the vertex on mesh_difference by the absolute difference in position
vert_difference.co.x += diff_x
vert_difference.co.y += diff_y
vert_difference.co.z += diff_z


While this is working fine, I'd like to explore other options that may be faster or more memory efficient, since for large meshes this is getting a but to slow/heavy. I started looking into numpy, but I'm doing something wrong I think since the function isn't doing anything -

import bpy
import numpy as np

def mesh_difference(object_A_name, object_B_name, object_difference_name):
# Get the objects from the collection using their names
object_A = bpy.data.objects[object_A_name]
object_B = bpy.data.objects[object_B_name]
object_difference = bpy.data.objects[object_difference_name]

# Get the meshes from the objects
mesh_A = object_A.data
mesh_B = object_B.data
mesh_difference = object_difference.data

# Get the vertices of each mesh as numpy arrays
verts_A = np.array([vert.co for vert in mesh_A.vertices])
verts_B = np.array([vert.co for vert in mesh_B.vertices])
verts_difference = np.array([vert.co for vert in mesh_difference.vertices])

# Calculate the difference in position
verts_difference -= verts_A - verts_B


Any ideas as of why the numpy function isn't working, or if there are more efficient alternatives to the first option?

A solution using a slightly modified version of a suggestiong from below -

import bpy, numpy as np
from bpy import context as C, data as D

def mesh_difference(A, B, difference):
ob1 = D.objects[A]
ob2 = D.objects[B]
ob3 = D.objects[difference]

verts1 = ob1.data.vertices
verts2 = ob2.data.vertices
verts3 = ob3.data.vertices

arr1 = np.empty(len(verts1)*3, dtype=float)
arr2 = np.empty(len(verts2)*3, dtype=float)
arr3 = np.empty(len(verts2)*3, dtype=float)

verts1.foreach_get('co', arr1)
verts2.foreach_get('co', arr2)
verts3.foreach_get('co', arr3)
verts3.foreach_set('co', arr3-(arr2 - arr1))
ob3.data.update()

mesh_difference('A', 'B', 'Cube')


Quite a bit faster -

Time taken: 0.5296132564544678 seconds

Time taken: 0.0469057559967041 seconds

• the power of foreach_get Commented Jan 19, 2023 at 2:45

import bpy, numpy as np
from bpy import context as C, data as D

def mesh_difference(A, B, difference):
ob1 = D.objects[A]
ob2 = D.objects[B]
ob3 = D.objects[difference]

verts1 = ob1.data.vertices
verts2 = ob2.data.vertices
verts3 = ob3.data.vertices

arr1 = np.empty(len(verts1)*3, dtype=float)
arr2 = np.empty(len(verts2)*3, dtype=float)

verts1.foreach_get('co', arr1)
verts2.foreach_get('co', arr2)
verts3.foreach_set('co', arr2 - arr1)
ob3.data.update()

mesh_difference('Cube', 'Cube.001', 'Cube.002')

• brilliant! that was the right idea, thank you. I slightly modified it add the deltas to subtract the differences from an existing array (I'll use it for shapekey correctives, so I'd need it to be relative to the existing positions of the 'difference' mesh), but this is what I was looking for. Commented Jan 19, 2023 at 1:39
• foreach_get() sounds like a loop, but internally .. is it just slamming chunks of memory around? .. only if you happen to know,, Commented Jan 19, 2023 at 12:03
• @RobinBetts I don't know. You're not getting an access to the original data, you get a copy, so it seems it is a loop that copies the data. Commented Jan 19, 2023 at 12:45
• memcpy() ? probably not.... Commented Jan 19, 2023 at 14:09
• @RobinBetts memcpy still will be implemented as a loop, though understandably it can be implemented more efficiently than just a boring loop written by a Blender dev. Commented Jan 19, 2023 at 14:30