1
$\begingroup$

I am at developing a little addon to have tab buttons in the header of the 3d view to switch between the modes.

When you have a normal object, then the mode dropdown box goes from object mode to texture paint. When you add a particle system to the object, then we have one more point: Particle edit. And this is what gives me a hard time. I cannot find the needed info to define if a particle system is added. Means that i have to display the particle edit button now too.

if obj.type == 'PARTICLES': does not throw an error, but doesn't work neither. My particle button is missing. Particles does not seem to be an object type at all. And when i simply add the particles button to the object part of the code, then the console throws an error when no particle system is attached.

What is the condition to detect if a particle system is at our object now?

The script uses external icons. So here is the complete bundle of the current state with script and icons in case you want to test it, 23 kb: http://www.reinerstilesets.de/ext/blender/particleproblem.zip

The trouble part starts at line 59

import bpy
import os
import bpy.utils.previews

# Dummyclass
class VIEW3D_MT_not_available(bpy.types.Operator):  
    """This functionality is not available in the current state"""      # blender will use this as a tooltip for menu items and buttons.
    bl_idname = "data.not_available"        # unique identifier for buttons and menu items to reference.
    bl_label = "Not Available"         # display name in the interface.
    #bl_options = {'REGISTER', 'UNDO'}  # enable undo for the operator.

    def execute(self, context):
        # Nothing gets executed here. It's a dummy class to define empty buttons.
        return {'FINISHED'}

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

    obj = context.active_object
    row = layout.row(align=True)
    global custom_icons
    # Something in the viewport. buttons active   
    if obj is not None:

        mode = obj.mode

        if obj.type == 'MESH':

            if mode == 'OBJECT':
                row.operator("object.mode_set", text="", icon_value = custom_icons["icon_objectmode_active"].icon_id).mode = 'OBJECT'
            else: 
                row.operator("object.mode_set", text="", icon = 'OBJECT_DATAMODE').mode = 'OBJECT'

            if mode == 'EDIT':
                row.operator("object.mode_set", text="", icon_value = custom_icons["icon_editmode_active"].icon_id).mode = 'EDIT'
            else:
                row.operator("object.mode_set", text="", icon = 'EDITMODE_HLT').mode = 'EDIT'

            if mode == 'SCULPT':
                row.operator("object.mode_set", text="", icon_value = custom_icons["icon_sculptmode_active"].icon_id).mode = 'SCULPT'
            else:
                row.operator("object.mode_set", text="", icon = 'SCULPTMODE_HLT').mode = 'SCULPT'

            if mode == 'VERTEX_PAINT':
                row.operator("object.mode_set", text="", icon_value = custom_icons["icon_vpaintmode_active"].icon_id).mode = 'VERTEX_PAINT'
            else:
                row.operator("object.mode_set", text="", icon = 'VPAINT_HLT').mode = 'VERTEX_PAINT'

            if mode == 'WEIGHT_PAINT':
                row.operator("object.mode_set", text="", icon_value = custom_icons["icon_wpaintmode_active"].icon_id).mode = 'WEIGHT_PAINT'
            else:
                row.operator("object.mode_set", text="", icon = 'WPAINT_HLT').mode = 'WEIGHT_PAINT'

            if mode == 'TEXTURE_PAINT':
                row.operator("object.mode_set", text="", icon_value = custom_icons["icon_tpaintmode_active"].icon_id).mode = 'TEXTURE_PAINT'
            else:
                row.operator("object.mode_set", text="", icon = 'TPAINT_HLT').mode = 'TEXTURE_PAINT'

            ######################### The Trouble maker #############################

            if mode == 'PARTICLE_EDIT':
                row.operator("object.mode_set", text="", icon_value = custom_icons["icon_particle_active"].icon_id).mode = 'PARTICLE_EDIT'
            else:
                row.operator("object.mode_set", text="", icon = 'PARTICLEMODE').mode = 'PARTICLE_EDIT'

            ##########################################################################

            row.operator("data.not_available", text="", icon_value = custom_icons["icon_not_available"].icon_id)            

        if obj.type == 'ARMATURE':
            if mode == 'OBJECT':
                row.operator("object.mode_set", text="", icon_value = custom_icons["icon_objectmode_active"].icon_id).mode = 'OBJECT'
            else: 
                row.operator("object.mode_set", text="", icon = 'OBJECT_DATAMODE').mode = 'OBJECT'

            if mode == 'EDIT':
                row.operator("object.mode_set", text="", icon_value = custom_icons["icon_editmode_active"].icon_id).mode = 'EDIT'
            else:
                row.operator("object.mode_set", text="", icon = 'EDITMODE_HLT').mode = 'EDIT'

            row.operator("data.not_available", text="", icon_value = custom_icons["icon_not_available"].icon_id)
            row.operator("data.not_available", text="", icon_value = custom_icons["icon_not_available"].icon_id)
            row.operator("data.not_available", text="", icon_value = custom_icons["icon_not_available"].icon_id)
            row.operator("data.not_available", text="", icon_value = custom_icons["icon_not_available"].icon_id)
            row.operator("data.not_available", text="", icon_value = custom_icons["icon_not_available"].icon_id)

            if mode == 'POSE':
                row.operator("object.mode_set", text="", icon_value = custom_icons["icon_pose_active"].icon_id).mode = 'POSE'
            else:
                row.operator("object.mode_set", text="", icon = 'POSE_HLT').mode = 'POSE'

        if obj.type in ['CURVE', 'SURFACE','META', 'FONT', 'LATTICE']:

            if mode == 'OBJECT':
                row.operator("object.mode_set", text="", icon_value = custom_icons["icon_objectmode_active"].icon_id).mode = 'OBJECT'
            else: 
                row.operator("object.mode_set", text="", icon = 'OBJECT_DATAMODE').mode = 'OBJECT'

            if mode == 'EDIT':
                row.operator("object.mode_set", text="", icon_value = custom_icons["icon_editmode_active"].icon_id).mode = 'EDIT'
            else:
                row.operator("object.mode_set", text="", icon = 'EDITMODE_HLT').mode = 'EDIT'

            row.operator("data.not_available", text="", icon_value = custom_icons["icon_not_available"].icon_id)
            row.operator("data.not_available", text="", icon_value = custom_icons["icon_not_available"].icon_id)
            row.operator("data.not_available", text="", icon_value = custom_icons["icon_not_available"].icon_id)
            row.operator("data.not_available", text="", icon_value = custom_icons["icon_not_available"].icon_id)
            row.operator("data.not_available", text="", icon_value = custom_icons["icon_not_available"].icon_id)
            row.operator("data.not_available", text="", icon_value = custom_icons["icon_not_available"].icon_id)

        if obj.type in ['EMPTY', 'LAMP','CAMERA', 'EFFECTOR', 'SPEAKER']:   

            if mode == 'OBJECT':
                row.operator("object.mode_set", text="", icon_value = custom_icons["icon_objectmode_active"].icon_id).mode = 'OBJECT'
            else: 
                row.operator("object.mode_set", text="", icon = 'OBJECT_DATAMODE').mode = 'OBJECT'

            row.operator("data.not_available", text="", icon_value = custom_icons["icon_not_available"].icon_id)
            row.operator("data.not_available", text="", icon_value = custom_icons["icon_not_available"].icon_id)
            row.operator("data.not_available", text="", icon_value = custom_icons["icon_not_available"].icon_id)
            row.operator("data.not_available", text="", icon_value = custom_icons["icon_not_available"].icon_id)
            row.operator("data.not_available", text="", icon_value = custom_icons["icon_not_available"].icon_id)
            row.operator("data.not_available", text="", icon_value = custom_icons["icon_not_available"].icon_id)      

        obj.data.update() 

    # Nothing in the viewport or nothing is selected. Buttons inactive
    else:
        row.operator("object.mode_set", text="", icon = 'OBJECT_DATAMODE')
        row.operator("object.mode_set", text="", icon = 'EDITMODE_HLT')
        row.operator("object.mode_set", text="", icon = 'SCULPTMODE_HLT')
        row.operator("object.mode_set", text="", icon = 'VPAINT_HLT')
        row.operator("object.mode_set", text="", icon = 'WPAINT_HLT')
        row.operator("object.mode_set", text="", icon = 'TPAINT_HLT')
        row.operator("object.mode_set", text="", icon = 'PARTICLEMODE')
        row.operator("object.mode_set", text="", icon = 'POSE_HLT')



# global variable to store icons in
custom_icons = None

def register():

    bpy.utils.register_class(VIEW3D_MT_not_available)
    bpy.types.VIEW3D_HT_header.prepend(addon_button) # Here we add our button in front of the View 3D header. 
     #To add it at the end use append instead of prepend.

    # Our external Icons
    global custom_icons
    custom_icons = bpy.utils.previews.new()
    script_path = bpy.context.space_data.text.filepath
    icons_dir = os.path.join(os.path.dirname(script_path), "icons")
    custom_icons.load("icon_not_available", os.path.join(icons_dir, "NOT_AVAILABLE.png"), 'IMAGE')
    custom_icons.load("icon_objectmode_active", os.path.join(icons_dir, "OBJECTMODE__ACTIVE.png"), 'IMAGE')
    custom_icons.load("icon_editmode_active", os.path.join(icons_dir, "EDITMODE__ACTIVE.png"), 'IMAGE')
    custom_icons.load("icon_sculptmode_active", os.path.join(icons_dir, "SCULPTMODE_ACTIVE.png"), 'IMAGE')
    custom_icons.load("icon_vpaintmode_active", os.path.join(icons_dir, "VPAINT_ACTIVE.png"), 'IMAGE')
    custom_icons.load("icon_wpaintmode_active", os.path.join(icons_dir, "WPAINT_ACTIVE.png"), 'IMAGE')
    custom_icons.load("icon_tpaintmode_active", os.path.join(icons_dir, "TPAINT_ACTIVE.png"), 'IMAGE')
    custom_icons.load("icon_particle_active", os.path.join(icons_dir, "PARTICLE_ACTIVE.png"), 'IMAGE')
    custom_icons.load("icon_pose_active", os.path.join(icons_dir, "POSE_ACTIVE.png"), 'IMAGE')


def unregister():
    global custom_icons
    bpy.utils.previews.remove(custom_icons)
    bpy.utils.unregister_class(VIEW3D_MT_not_available)

# This allows you to run the script directly from blenders text editor
# to test the addon without having to install it.

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

Check if the object has a Particle System attached. Something like

import bpy

obj = bpy.data.objects['Plane']

if obj.modifiers:
    print(obj.modifiers)
    if 'PARTICLE_SYSTEM' in [m.type for m in obj.modifiers]:
        print('yeah, particle system found')

You may have never noticed that when you add a particle system, you also add a particle system Modifier. And, unless you've added a Particle System, the Particle Edit mode is unavailable.

$\endgroup$
  • $\begingroup$ Many thanks, this was the hint that i was looking for. Let's have a look if i can turn this into working code for my addon :) $\endgroup$ – Tiles Oct 6 '16 at 7:03
  • $\begingroup$ I had to change obj = bpy.data.objects['Plane'] into object = bpy.context.object . And now it works like charm. Many thanks :) $\endgroup$ – Tiles Oct 6 '16 at 7:29

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.