3
$\begingroup$

The thing is I am trying to toggle on/off multiple snapping options ( like enable snapping ,enable align rotation to target , enable scale ,enable rotation) with a single button created in my cistom panel.

I have already created an custom operator class with all the snapping option mentioned above set to True and asigned it to an new button in the panel class.

It enables all the snapping options at once but I am unable to toggle them back off.

import bpy

class SimpleOperator(bpy.types.Operator):
    
    bl_idname = "object.simple_operator"
    bl_label = "Simple Object Operator"
    

    @classmethod
    def poll(cls, context):
        return context.active_object is not None

    def execute(self, context):
            bpy.context.scene.tool_settings.use_snap = True      
            bpy.context.scene.tool_settings.snap_elements = {'FACE'}
            bpy.context.scene.tool_settings.use_snap_scale = True
            bpy.context.scene.tool_settings.use_snap_translate = True
            bpy.context.scene.tool_settings.use_snap_align_rotation = True
            bpy.context.scene.tool_settings.use_snap_rotate = True
            
            

class MyTools(bpy.types.Panel):
    bl_label = "My Tools"
    bl_idname = "VIEW_3D_PT_MyTools"
    bl_space_type = "VIEW_3D"
    bl_region_type = "UI" 
    bl_category = "My Tools"
        
    
    
    def draw(self, context):
        layout = self.layout
        
        
        row = layout.row()
        row.operator(SimpleOperator.bl_idname, text = "Multi_Snap" , icon = 'SNAP_OFF')
        


def register():
    bpy.utils.register_class(SimpleOperator)
    bpy.utils.register_class(MyTools)
    
    


def unregister():
    bpy.utils.unregister_class(SimpleOperator)
    bpy.utils.unregister_class(Mytools)
    


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

1 Answer 1

2
$\begingroup$

You're setting all values to True so there isn't any toggling going on.

I have 3 remarks :

  • Operators should return a set indicating their state at the end of execution. For simple operators it should be {"FINISHED"}.
  • Operators' execute method take context as an argument, it's better to use it rather than bpy.context that doesn't let you override the operator.
  • To toggle a setting, you can invert its boolean value with not.
class SimpleOperator(bpy.types.Operator):
    bl_idname = "object.simple_operator"
    bl_label = "Simple Object Operator"

    @classmethod
    def poll(cls, context):
        return context.active_object is not None

    def execute(self, context):
        tool_settings = context.scene.tool_settings
        tool_settings.use_snap = True      
        tool_settings.snap_elements = {'FACE'}

        toggle = not tool_settings.use_snap_scale
        tool_settings.use_snap_scale = toggle
        tool_settings.use_snap_translate = toggle
        tool_settings.use_snap_align_rotation = toggle
        tool_settings.use_snap_rotate = toggle
        return {"FINISHED"}
$\endgroup$
1
  • 1
    $\begingroup$ Thanks a lot man. It worked perfectly. $\endgroup$
    – VBlaZE
    Apr 29, 2022 at 11:53

You must log in to answer this question.

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