3
$\begingroup$

What would be the most effective way to track changes in the user mesh-data's? I would like to receive a notification signal if a user mesh data has changed.

I see a few (fast) approaches possible:

  • on depsgraph handler: Keeping track of all meshes vertex-count
  • on depsgraph handler: Keeping track of all meshes bounding-boxes
  • via msgbus: Overseeing if a user is entering edit/sculpt mode, on which mesh

But:

  • Keeping track of BB & vertcount wouldn't work if the user is simply moving a vertex within the BB area
  • Overseeing edit/sculpt mode could create false positives if the user is just toggling edit mode on/off

Did I miss something obvious? We could gather bmesh information, but I'm afraid this method would be much too slow.

Context: creating a live bridge between blender and a game engine. Extra points if the solutions can also detect changes in mesh attributes

$\endgroup$

2 Answers 2

1
$\begingroup$

There is another approach i did not knew about, much more generic!

  • on depsgraph handler: Overviewing depsgraph.updates with upd.is_updated_geometry

A mix of this and a custom mesh hash method would be ideal

$\endgroup$
0
$\begingroup$

We could use numpy and foreach_get to get an accurate hash. look fast enough? might be too slow, with such method, it is crucial that the hash calculation is done on key moments

import bpy
import numpy as np
from bpy.app.handlers import persistent
from collections import defaultdict

mesh_vertices_hashes = defaultdict(int)

def mesh_hash(obj):
    vertex_count = len(obj.data.vertices)
    vertices_np = np.empty(vertex_count * 3, dtype=np.float32)
    obj.data.vertices.foreach_get("co", vertices_np)
    h = hash(vertices_np.tobytes())
    print(h)
    return h

@persistent
def base_mesh_modified_notifier(scene):
    global mesh_vertices_hashes

    for obj in scene.objects:
        if obj.type == 'MESH':
            current_hash = mesh_hash(obj)

            if obj.name not in mesh_vertices_hashes:
                mesh_vertices_hashes[obj.name] = current_hash
            elif mesh_vertices_hashes[obj.name] != current_hash:
                print(f"Base mesh of {obj.name} has been modified.")
                mesh_vertices_hashes[obj.name] = current_hash


bpy.app.handlers.depsgraph_update_post.append(base_mesh_modified_notifier)
$\endgroup$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .