0
$\begingroup$

I am trying to watch changes in the depsgraph so that ever time I assign a material to a mesh, all its sibling meshes (those that share a parent) are assigned the same color.

The way I do that is in the script below.

However, when I update a material one of these things happen (randomly as far as I can tell):

  • the material gets updated on the mesh and all its siblings, and Blender crashes with the next update
  • the material changes on the mesh and all its siblings, but into a black non-reflective material (I havent't checked if the material name is correct, and it just doesn't render)
  • Blender crashes immediately
import bpy
import time

from bpy.app.handlers import persistent
from inspect import currentframe, getframeinfo, stack

mats = dict()
for obj in bpy.data.objects:
    mats[obj.name] = obj.material_slots[0].material if obj.material_slots else None

def lprint(*args):
    frameinfo = getframeinfo(stack()[1][0])
    print(frameinfo.filename, frameinfo.lineno, *args)

def depsgraph_handler_post(scene, depsgraph):

    updates =  [ u for u in depsgraph.updates if u.is_updated_shading and type(u.id).__name__ == "Object" ]

    siblings = []
    mat = None

    bpy.app.handlers.depsgraph_update_post.remove(depsgraph_handler_post)
    bpy.app.handlers.depsgraph_update_pre.remove(depsgraph_handler_pre)
    
    for update in updates:
        try:
            obj = update.id
            mat = obj.material_slots[0].material
            lprint("Post", type(obj).__name__, obj.name, mats[obj.name].name, mat.name)
            mats[obj.name] = mat if obj.material_slots else None
            parent = obj.parent
            siblings = [ o.name for o in bpy.data.objects if o.parent and o.parent.name == parent.name and not o.name == obj.name ]
        except Exception as err:
            lprint("Post", err)

        for name in siblings:
            print(name)
            obj = bpy.data.objects[name]
            if len(obj.material_slots) == 0:
                obj.data.materials.append(mat)
            else:
                obj.material_slots[0].material = mat

    bpy.app.handlers.depsgraph_update_post.append(depsgraph_handler_post)
    bpy.app.handlers.depsgraph_update_pre.append(depsgraph_handler_pre)
    scene.render.use_lock_interface = False
    


def depsgraph_handler_pre(scene):
    scene.render.use_lock_interface = True

bpy.app.handlers.depsgraph_update_post.append(depsgraph_handler_post)
bpy.app.handlers.depsgraph_update_pre.append(depsgraph_handler_pre)

I have managed to work around the problem in a semi-satisfactory way, but I would like to know what's going on here.

$\endgroup$

0

You must log in to answer this question.

Browse other questions tagged .