1
$\begingroup$

I'm working on a script that assembles assets from various blend files using the bpy.data.libraries.load context.

I'm trying to load an object that has various Vertex Weight modifiers, including Proximity to another object.

I have to process the Vertex Weight values after the libraries.load call, but, in this case, I find all values set to 1.0.

If I use the UI to append the same object, and then run the same script, I get my proper Vertex Weight values.

I have the impression that modifiers are not "ready" (evaluated yet) after the libraries.load call.

Is there any way to instruct Blender to properly setup the modifiers after a call to libraries.load?

$\endgroup$

1 Answer 1

1
$\begingroup$

The modifiers are evaluated by the Depsgraph.

AFAIK, the Python API only provides access to the Depsgraph of visible objects.

After the load, the objects must be added to the bpy.context.scene, in a way that makes them visible.

Then, their modifiers are properly evaluated when accessed in Python.

I've been testing with the following script.

import bpy

# Load the asset

blendPath = r"C:\temp\plane_vertex_proximity_modifier.blend"
with bpy.data.libraries.load(blendPath, link=False, relative=True) as (data_from, data_to):

    data_to.objects = data_from.objects[:]

# Put the objects loaded in a *visible* collection
# visible is IMPORTANT, so that modifiers are evaluated

my_collection = bpy.data.collections.new('__assets__')
bpy.context.scene.collection.children.link(my_collection)
layer_collection = bpy.context.view_layer.layer_collection.children[my_collection.name]
layer_collection.exclude = False
for obj in data_to.objects:
    my_collection.objects.link(obj)

# Query vertex group values

obj = bpy.context.scene.objects['Plane']

depsgraph = bpy.context.evaluated_depsgraph_get()
eo = obj.evaluated_get(depsgraph)
mesh = eo.to_mesh(preserve_all_data_layers=True, depsgraph=depsgraph)

vg = eo.vertex_groups['dist']
vg_index = vg.index

class NoGroup:
    weight = 0.0

v_weights = [ 0.0 ] * len(mesh.vertices)
for v in mesh.vertices:
    group = NoGroup
    # IMPORTANT(nll) v.groups can be in any order, or incomplete...
    for g in v.groups:
        if g.group == vg_index:
            group = g
            break
    v_weights[v.index] = group.weight

# values are '1.0' if modifiers are not evaluated
# values are '0.2828...' if modifiers are ok
print("v_weight", v_weights)

# After the evaluation, we can exclude the layer collection

layer_collection.exclude = True
$\endgroup$

You must log in to answer this question.

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