So I need an operator (for creating a DECIMATE modifier in the selected object) that runs every time that the value input is changed and uses that value (for the Ratio of the modifier).

For now I've this alternative. The problem is that when the value is changed nothing happens until the operator button is clicked (see code below).

enter image description here

So basically I would like an interface in which just the value is shown and if its changed then the operator runs, changinge of the value of the decimate modifier.

enter image description here

import bpy
from bpy.props import (BoolProperty,
from bpy.types import (Panel,
class MyProperties(bpy.types.PropertyGroup):
    my_float : bpy.props.FloatProperty (name = "Decimate Radio", soft_min = 0, soft_max= 1)

class ADDONNAME_PT_main_panel(bpy.types.Panel):
    bl_label= "Add-On"
    bl_idname = "PT_TestPanel"
    bl_space_type = 'VIEW_3D'
    bl_region_type= 'UI'
    bl_category= 'Add-On'
    def draw(self,context):
        layout = self.layout
        scene= context.scene
        mytool= scene.my_tool
        for obj in bpy.context.selected_objects:
               i =i+1
        if i==1 :
            row= layout.row()

class ADDONNAME_OT_my_op_3(bpy.types.Operator):
    bl_label = "Operator"
    bl_idname = "addonname.myop_operator_3"
    def execute(self, context):
        scene = context.scene
        mytool= scene.my_tool
        obj_1 = bpy.context.selected_objects[0]
        mod = obj_1.modifiers.new("Decimate", 'DECIMATE')



        return {'FINISHED'}

classes = [ ADDONNAME_PT_main_panel, ADDONNAME_OT_my_op_3, MyProperties]
def register():
    from bpy.utils import register_class
    for cls in classes:

    bpy.types.Scene.my_tool = PointerProperty(type=MyProperties)

def unregister():
    from bpy.utils import unregister_class
    for cls in reversed(classes):
    del bpy.types.Scene.my_tool

if __name__ == "__main__":

1 Answer 1


You can use an Application Handler.

import bpy
from bpy.app.handlers import persistent

def decimate_addon_handler(scene):
    for o in scene.objects:
        if o.type=='MESH':
            if "Decimate" in o.modifiers:
                 o.modifiers["Decimate"].ratio = scene.my_tool.my_float


It runs every time something is changed in the scene, so that will become an issue quite fast especially when updating decimate modifier for all objects in the scene. Be sure to check for conditions that you really need it in so it only runs when needed. For example you probably want to run it only when the value changes so you should probably think of a way to track if the value changes.

  • $\begingroup$ That's a direct improvement to my view3d draw callback technique, you can take a look how I use a "global" variable to keep track if the value of interest changed. $\endgroup$ Sep 19, 2022 at 17:15

You must log in to answer this question.

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