2
$\begingroup$

I would like to code multiple functions (operations?) to a single button that is on a Display panel within the 3D viewport, and which will have toggle functionality. This is what I have so far. I'd like that when the button is pressed it adds a Subsurf modifier (with both Render & Viewport Subdivisions set to 2), and shade_smooth turned on for the selected object. When the button is pressed again the subsurf is deleted and the shade_smooth is turned off (shade_flat). As it stands now when the button is pressed again it just adds another Subsurf. I might also like to assign a hotkey to it. Any thoughts? Working with Blender 2.83.3

row = layout.row()
row.operator("object.modifier_add", text= "Subsurf", icon = "MOD_SUBSURF").type="SUBSURF" 

Here's a larger portion of the script:

class CustomPanel(bpy.types.Panel):
    """A Custom Panel in the Properties Toolbar"""
    bl_label = "V3"
    bl_space_type = 'VIEW_3D'
    bl_region_type = 'TOOLS'


    def draw(self, context):
        layout = self.layout

        obj = context.object

        row = layout.row()
        row.prop(bpy.context.space_data.overlay, 'show_cursor', text = "3D cursor", toggle = True)
        row = layout.row()
        row.operator("object.modifier_add", text= "Subsurf", icon = "MOD_SUBSURF").type="SUBSURF" 

def register():
    bpy.utils.register_class(CustomPanel)


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

if __name__ == "__main__":
    register()
```
$\endgroup$
2
$\begingroup$

You have to create custom Operator class and register it. Inside the operator you have to check if the object has the modifier or not. If it is not then add or else remove it. Then replace the YourOperator.bl_idname with "object.modifier_add".

Added shade smooth and flat toggle. For shortcut you can click on the button and "add shortcut". Note: Your Operator.bl_idname have to give blender some idea of what group the shortcut should be added to. Otherwise the "add shortcut" button won't appear.

import bpy

class SubsurfOperator(bpy.types.Operator):
    bl_idname = "object.toggle_subsurf"
    bl_label = "Toggle Subsurf"
    bl_options = {'REGISTER', 'UNDO'}

    def execute(self, context):
        mods = bpy.context.object.modifiers
        mod_type = 'SUBSURF'
        mod_name = None
        for mod in mods:
            if mod.type == mod_type:
                mod_name = mod.name
                break
        if mod_name != None:
            bpy.ops.object.modifier_remove(modifier=mod_name)
            bpy.ops.object.shade_flat()
        else:
            bpy.ops.object.modifier_add(type=mod_type)
            bpy.ops.object.shade_smooth()

        return {'FINISHED'}


class CustomPanel(bpy.types.Panel):
    """A Custom Panel in the Properties Toolbar"""
    bl_label = "V3"
    bl_space_type = 'VIEW_3D'
    bl_region_type = 'TOOLS'


    def draw(self, context):
        layout = self.layout

        obj = context.object

        row = layout.row()

        # here is your operator

        row.operator(SubsurfOperator.bl_idname, text= SubsurfOperator.bl_label, icon = "MOD_SUBSURF")

        row.prop(bpy.context.space_data.overlay, 'show_cursor', text = "3D cursor", toggle = True)
        row = layout.row()
        row.operator("object.modifier_add", text= "Subsurf", icon = "MOD_SUBSURF").type="SUBSURF" 

# requires to register classes
from bpy.utils import register_class, unregister_class

# Class list to register
_classes = [
    SubsurfOperator,
    CustomPanel
]

def register():
    for cls in _classes:
        register_class(cls)

def unregister():
    for cls in _classes:
        unregister_class(cls)

if __name__ == "__main__":
    register()
|improve this answer|||||
$\endgroup$
  • $\begingroup$ Thank you. I'm unable to get it to work however. My above code is just part of a larger bit of code, with a CustomPanel class which I have indeed registered. There are several row.operators in order to make several buttons. The above code is just what I had for one of the buttons. How would I incorporate your code into the pre-existing script? Here's a more clear example of what I have for the class: class CustomPanel(bpy.types.Panel): """A Custom Panel in the Properties Toolbar""" bl_label = "V3" bl_space_type = 'VIEW_3D' bl_region_type = 'TOOLS' $\endgroup$ – Increality Mar 27 at 23:02
  • $\begingroup$ And for that class I have a draw: def draw(self, context): layout = self.layout obj = context.object row = layout.row() row.prop(bpy.context.space_data.overlay, 'show_cursor', text = "3D cursor", toggle = True) row = layout.row() row.operator("object.modifier_add", text= "Subsurf", icon = "MOD_SUBSURF").type="SUBSURF" $\endgroup$ – Increality Mar 27 at 23:05
  • 1
    $\begingroup$ @ Increality I've edited my answer. $\endgroup$ – Jayanta Roy Mar 28 at 16:20
  • 1
    $\begingroup$ You can update the Viewport setting in Subdivision Subsurface with: bpy.data.objects["Cube"].modifiers["Subdivision"].levels = 2 $\endgroup$ – Natetronn Mar 30 at 19:58

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.