I wrote a simple render engine addon to test this.
import bpy
import bgl
import blf
import numpy as np
bl_info = {
"name": "Test Render Engnie",
"author": "ihsieh",
"version": (1, 0, 0),
"blender": (3, 0, 0),
"location": "Info Header, render engine menu",
"description": "My Test RE",
"warning": "",
"category": "Render"}
class MyMesh:
def __init__(self, name):
self.name = name
self.points = []
def update(self, mesh):
nvertices = len(mesh.vertices)
P = np.zeros(nvertices*3, dtype=np.float32)
mesh.vertices.foreach_get('co', P)
P = np.reshape(P, (nvertices, 3))
self.points = P.tolist()
class TestRenderEngine(bpy.types.RenderEngine):
bl_idname = 'TEST_RENDER'
bl_label = "TestRenderEngine"
bl_use_preview = False
bl_use_save_buffers = True
bl_use_shading_nodes = True
bl_use_eevee_viewport = True
bl_use_postprocess = True
def __init__(self):
self.scene_data = None
def __del__(self):
pass
def render(self, depsgraph):
pass
def view_update(self, context, depsgraph):
region = context.region
view3d = context.space_data
scene = depsgraph.scene
objects_updated = list()
if not self.scene_data:
# First time initialization
self.scene_data = dict()
# Loop over all datablocks used in the scene.
for datablock in depsgraph.ids:
if not isinstance(datablock, bpy.types.Mesh):
continue
my_mesh = MyMesh(datablock.name)
self.scene_data[datablock.original] = my_mesh
# Loop over all instances
for instance in depsgraph.object_instances:
ob = instance.object
if ob.type != 'MESH':
continue
datablock = ob.data
if datablock.original not in self.scene_data:
# this datablock didn't get exported in the loop above
my_mesh = MyMesh(datablock.name)
self.scene_data[datablock.original] = my_mesh
else:
my_mesh = self.scene_data[datablock.original]
my_mesh.update(datablock)
else:
objects_updated = list()
# Test which datablocks changed
for update in depsgraph.updates:
if isinstance(update.id, bpy.types.Object):
print("Datablock updated: %s" % update.id.name)
objects_updated.append(update.id.original)
# Loop over all object instances, see which instances changed.
if depsgraph.id_type_updated('OBJECT'):
for instance in depsgraph.object_instances:
ob = instance.object
if ob.type != 'MESH':
continue
if instance.is_instance:
if instance.instance_object.original not in objects_updated:
print("\tInstance object not updated: %s" % ob.name)
continue
elif ob.original not in objects_updated:
print("\tObject not updated: %s" % ob.name)
continue
datablock = ob.data
if datablock.original not in self.scene_data:
print("\tNot in objects_updated: %s" % datablock.name)
continue
my_mesh = self.scene_data[datablock.original]
print("\tUpdating datablock: %s" % datablock.name)
my_mesh.update(datablock)
def view_draw(self, context, depsgraph):
pass
classes = [
TestRenderEngine,
]
def register():
for cls in classes:
bpy.utils.register_class(cls)
def unregister():
for cls in classes:
try:
bpy.utils.unregister_class(cls)
except RuntimeError:
pass
Using the scene file attached (the forum doesn’t to allow for uploads of .blend file, so I name it .txt), how do I know if the cubes that the BezierCircle has instanced have been updated? Ex: open the scene, start a viewport render, select Cube and press Tab to go to edit mode. The depsgraph.updates loop let’s me know that BezierCurve object has updated, but I need to reference its data from our scene_data dictionary.
geonodes_instancing_test_re.txt (811.0 KB)