3
$\begingroup$

I'm going to write a script that adds Surface Deform Modifier to multiple objects in batches and binds it to the target object.

I succeeded in adding a Modifier to all selected objects and setting a target object, but failed to bind. Currently, my script runs Bind operation only for the active object.

How can I fix my script?

import bpy

obs             = bpy.context.selected_objects
modifier_type   = 'SURFACE_DEFORM'
modifier_target = bpy.data.objects['Plane']

for ob in obs :
    ob.modifiers.new(name=modifier_type,type=modifier_type)
    ob.modifiers[modifier_type].target=modifier_target
    bpy.ops.object.surfacedeform_bind(modifier=modifier_type)
$\endgroup$

2 Answers 2

3
$\begingroup$

Override the context.

Another option other than setting the active object is to send an alternative (overridden) context to the operator.

Have used normal blender practice of using the active object to be the target, and add and bind modifier to other mesh objects selected.

Have named the modifier "Foo" to emphasize the use of the reference and not rely on the modifier having the name suggested. Relying on it having name given is a common way to have blender scripts not work as expected because of the naming convention requiring a unique name, that only the first can have.

import bpy

context = bpy.context
target = context.active_object
obs = [o for o in context.selected_objects
        if o.type == 'MESH'
        and o is not target]
        
for ob in obs:
    mod = ob.modifiers.new("Foo", 'SURFACE_DEFORM')
    mod.target = target
    bpy.ops.object.surfacedeform_bind(
        {"object" : ob},
        modifier=mod.name
        )

From Blender 3.2+ temp_override method is introduced. Which looks like this:

for ob in obs:
    mod = ob.modifiers.new("Foo", 'SURFACE_DEFORM')
    mod.target = target
    with bpy.context.temp_override(object=obj):
    bpy.ops.object.surfacedeform_bind(
        modifier=mod.name
        )

Finally In as much as aligning equals signs is "nicey nicey" and nostalgic for anyone who remembers COBOL, blender recommends the usage of PEP8 for formatting code. If your addon makes the repo it will be cleaned away by autopep8

$\endgroup$
2
  • 1
    $\begingroup$ remember me to never again answer Python questions, except if you tell me you're gone for hollidays or something! ; ) $\endgroup$
    – lemon
    Commented Sep 6, 2020 at 9:03
  • 1
    $\begingroup$ @lemon. Timing wise had started answer before yours popped up, got lost in the COBOL link. Fortunately there was a point of difference. $\endgroup$
    – batFINGER
    Commented Sep 6, 2020 at 9:10
4
$\begingroup$

Set the object active (and preferably, use the new modifier name instead of a constant name).

import bpy

obs             = bpy.context.selected_objects
modifier_type   = 'SURFACE_DEFORM'
modifier_target = bpy.data.objects['Plane']

for ob in obs :
    # Set the object active
    bpy.context.view_layer.objects.active = ob
    modifier = ob.modifiers.new(name=modifier_type,type=modifier_type)
    modifier.target = modifier_target
    bpy.ops.object.surfacedeform_bind(modifier=modifier.name)
$\endgroup$

You must log in to answer this question.

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