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()