1
$\begingroup$

I want to write a script that turns on (preferably on / off) the view of the specified modifier on an object in the collection and finally introduce it to the UI, but it doesn't work. Is there a solution?

import bpy
class cvo1(bpy.types.Operator):
    """Tooltip"""
    bl_idname = "object.cvo1_operator"
    bl_label = "off"

def draw(self, context):
    for obj in bpy.data.collections['Solidify.001'].all_objects:
        obj.select_set(True)
        for ob in bpy.context.selected_objects:
            bpy.context.view_layer.objects.active = ob
        for mod in [m for m in ob.modifiers if m.type == 'SOLIDIFY']:
            bpy.context.object.modifiers["Solidify.001"].show_viewport = True
            bpy.context.object.modifiers["Solidify.001"].show_render = True
            bpy.ops.object.select_all(action='DESELECT')
            return{'FINISHED'} 
    
def register():
    bpy.utils.register_class(cvo1)


def unregister():
    bpy.utils.unregister_class(cvo1)


if __name__ == "__main__":
    register()

This code below works fine.

import bpy



for obj in bpy.data.collections['Solidify.001'].all_objects:
    obj.select_set(True)
    for ob in bpy.context.selected_objects:
        bpy.context.view_layer.objects.active = ob
    for mod in [m for m in ob.modifiers if m.type == 'SOLIDIFY']:
        bpy.context.object.modifiers["Solidify.001"].show_viewport = True
        bpy.context.object.modifiers["Solidify.001"].show_render = True
        bpy.ops.object.select_all(action='DESELECT')
$\endgroup$
3
  • $\begingroup$ Hello ! To be sure, you want to disable all solidify modifiers on all mesh objects in the collection named 'Solidify.001' ? $\endgroup$
    – Gorgious
    Jul 25, 2021 at 18:26
  • $\begingroup$ that's right. Disables all solidify modifiers for all mesh objects in the collection named "Solidify.001". $\endgroup$
    – mml
    Jul 26, 2021 at 3:04
  • 3
    $\begingroup$ AFAICT the draw method above, should instead be an execute method of the operator. IMO work from context, eg context.collection , see no reason here to select objects or set active. Never use foo.bar["key"] unless you are certain that key exists. (will simply throw a key error if "key" does not exist) .. in above suggest that mod is is a solidify modifier on an obj in the collection, hence would use mod.foo = 3. In as much as "code above works fine" following the loops obj -> ob -> bpy.context.object is pretty confusing, most of which appear unnecessary. $\endgroup$
    – batFINGER
    Jul 26, 2021 at 9:35

1 Answer 1

2
$\begingroup$

Began writing things in comment but I figured it would be too long to make sense. You don't have to use operators to do such task. The logic goes :

  • For each object in collection
  • For each modifier in each object
  • IF modifier is Solidify
  • Toggle viewport and render visibility.

In python code, using list comprehension :

for attr in ("show_viewport", "show_render"):
    [[setattr(mod, attr, not getattr(mod, attr))
         for mod in ob.modifiers 
         if mod.type == 'SOLIDIFY'] 
            for ob in context.collection.all_objects]

Or in a more "classical" way:

for attr in ("show_viewport", "show_render"):
    for ob in context.collection.all_objects:
        for mod in ob.modifiers:
            if mod.type != 'SOLIDIFY':
                continue
            setattr(mod, attr, not getattr(mod, attr))

Your script then becomes :

import bpy

class cvo1(bpy.types.Operator):
    bl_idname = "object.cvo1_operator"
    bl_label = "off"

    def execute(self, context):
        for attr in ("show_viewport", "show_render"):
            for ob in context.collection.all_objects:
                for mod in ob.modifiers:
                    if mod.name == "Solidify.001":
                        continue
                    setattr(mod, attr, not getattr(mod, attr))
        return {'FINISHED'} 
    
def register():
    bpy.utils.register_class(cvo1)


def unregister():
    bpy.utils.unregister_class(cvo1)


if __name__ == "__main__":
    register()
$\endgroup$
5
  • $\begingroup$ Thank you for your reply! I tried using the code provided, but it didn't work ... sorry ... What I'm looking for is to turn off only the modifier named "Solidify.001" in the "Solidify" modifier. For example, The expression in the animation line art uses the Solidify.001 modifier. When outputting to FBX, the modifier gets in the way. So I wanted to write a script that "turns it off easily". $\endgroup$
    – mml
    Jul 26, 2021 at 21:08
  • $\begingroup$ !Image $\endgroup$
    – mml
    Jul 26, 2021 at 21:10
  • $\begingroup$ @mml edited the script part, let me know if it works. I change the line if mod.type == 'SOLIDIFY' to if mod.name == "Solidify.001" (be careful the name is case sensitive) $\endgroup$
    – Gorgious
    Jul 27, 2021 at 6:27
  • $\begingroup$ i.imgur.com/4vq5yMJ.jpg thank you! The script worked! (I was able to execute it via UI) However, it wasn't just my purpose, "Solidify.001", to turn it on and off. The script you created is "modifiers other than" Solidify.001 "turn on and off". $\endgroup$
    – mml
    Jul 27, 2021 at 8:46
  • $\begingroup$ thank you! By changing "if mod.name ==" Solidify.001 ":" to "if mod.name! =" Solidify.001 ":" ", the goal was achieved! $\endgroup$
    – mml
    Jul 27, 2021 at 9:00

You must log in to answer this question.

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