1
$\begingroup$

I want to update an object's mesh (only vertices and edges, plus screw modifier) at every new frame via frame_change_pre. This is my code:

import bpy
import numpy as np

def get_mirror_vertices_dummy(frame):
    zpos = np.array([0., 1.]);
    rpos = np.array([0., np.sin(frame/10.)]);
    return zpos, rpos, [], [];

def create_mirror_mesh(mesh, frame):
    # mesh arrays
    verts = [];
    edges = [];

    zpos, rpos, zneg, rneg = get_mirror_vertices_dummy(frame);

    # calculate vertices
    for vertexID in range(0,zpos.size):
        x = rpos[vertexID];
        y = 0.;
        z = zpos[vertexID];

        vert = (x,y,z);
        print(vert);
        verts.append(vert);

    # fill edges
    for vertexID in range(0,zpos.size-1):
        edge = (vertexID, vertexID+1);
        print(edge);
        edges.append(edge);

    # create mesh from data calculated above
    mesh.from_pydata(verts, edges, []);
    mesh.update();

def add_mirror():
    # create mesh and object
    mesh = bpy.data.meshes.new("mirror");
    mesh.update();
    object = bpy.data.objects.new("mirror", mesh);
    # set mesh location
    object.location = bpy.context.scene.cursor.location;
    bpy.context.scene.collection.objects.link(object);

    # add screw modifier
    object.select_set(state=True)
    bpy.context.view_layer.objects.active = object;
    bpy.ops.object.modifier_add(type='SCREW');

def mirror_update(frame):
    # if object does not yet exist, create it
    if not 'mirror' in bpy.data.objects:
        add_mirror();
    # delete old mesh first
    mesh = bpy.data.meshes['mirror'];
    #bpy.data.meshes.remove(mesh);
    create_mirror_mesh(mesh, frame);

def mirror_update_handler(scene):
    frame = scene.frame_current;
    mirror_update(frame);

bpy.app.handlers.frame_change_pre.append(mirror_update_handler);

When I run it in Blender (v2.82.7) in a fresh, empty scene, the first time I jump to a new frame, the object gets created and the mesh is also appearing. However, when jumping to another frame, I get the error

Error: Array length mismatch (expected 12, got 6)
Traceback (most recent call last):
  File "/Text", line 61, in mirror_update_handler
  File "/Text", line 57, in mirror_update
  File "/Text", line 33, in create_mirror_mesh
  File "/snap/blender/37/2.82/scripts/modules/bpy_types.py", line 469, in from_pydata
    self.vertices.foreach_set("co", tuple(chain.from_iterable(vertices)))
RuntimeError: internal error setting the array

I tried to remove the mesh before calculating the new vertices by un-commenting the line

bpy.data.meshes.remove(mesh);

in the function mirror_update. When I run this and jump to a new frame, the mesh is deleted and I get the error:

Error: Array length mismatch (expected 18, got 6)
Traceback (most recent call last):
  File "/Text", line 61, in mirror_update_handler
  File "/Text", line 57, in mirror_update
  File "/Text", line 33, in create_mirror_mesh
  File "/snap/blender/37/2.82/scripts/modules/bpy_types.py", line 469, in from_pydata
    self.vertices.foreach_set("co", tuple(chain.from_iterable(vertices)))
RuntimeError: internal error setting the array
(0.0, 0.0, 0.0)
(0.3894183423086505, 0.0, 1.0)
(0, 1)
Traceback (most recent call last):
  File "/Text", line 61, in mirror_update_handler
  File "/Text", line 57, in mirror_update
  File "/Text", line 33, in create_mirror_mesh
ReferenceError: StructRNA of type Mesh has been removed

The strange thing is: when I now comment-in again this line and run it afterwards, it works exactly as expected.

Can someone spot what I am doing wrong here?

$\endgroup$
1
$\begingroup$

I got it working by replacing bpy.data.meshes.remove(mesh); with mesh.clear_geometry();.

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.