diff options
author | Daniel Salazar <zanqdo@gmail.com> | 2011-05-19 12:42:47 +0400 |
---|---|---|
committer | Daniel Salazar <zanqdo@gmail.com> | 2011-05-19 12:42:47 +0400 |
commit | 8a9d2b32b9d4ecffc8027027d207c580a142a918 (patch) | |
tree | cf9276e26e0413625e3eb3c4ad9198a536453d2e /paint_palette.py | |
parent | 759656622d79948190fe3a7af46f394f29033496 (diff) |
Moving Paint Palettes to addons. Has been a good help here!
http://wiki.blender.org/index.php/Extensions:2.5/Py/Scripts/Paint/Palettes
Diffstat (limited to 'paint_palette.py')
-rw-r--r-- | paint_palette.py | 699 |
1 files changed, 699 insertions, 0 deletions
diff --git a/paint_palette.py b/paint_palette.py new file mode 100644 index 00000000..a8cc6299 --- /dev/null +++ b/paint_palette.py @@ -0,0 +1,699 @@ +# paint_palette.py (c) 2011 Dany Lebel (Axon_D) +# +# ***** BEGIN GPL LICENSE BLOCK ***** +# +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software Foundation, +# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +# +# ***** END GPL LICENCE BLOCK ***** + + +bl_info = { + "name": "Paint Palettes", + "author": "Dany Lebel (Axon D)", + "version": (0,8,1), + "blender": (2, 5, 7), + "api": 36722, + "location": "Image Editor and 3D View > Any Paint mode > Color Palette or Weight Palette panel", + "description": "Palettes for color and weight paint modes", + "warning": "beta", + "wiki_url": "http://wiki.blender.org/index.php/Extensions:2.5/Py/Scripts/Paint/Palettes", + "tracker_url": "http://projects.blender.org/tracker/index.php?func=detail&aid=25908", + "category": "Other"} + +""" +This addon brings palettes to the paint modes. + + * Color Palette for Image Painting, Texture Paint and Vertex Paint modes. + * Weight Palette for the Weight Paint mode. + +Set a number of colors (or weights according to the mode) and then associate it +with the brush by using the button under the color. +""" + +import bpy +from bpy.props import * + + +class AddPresetBase(): + '''Base preset class, only for subclassing + subclasses must define + - preset_values + - preset_subdir ''' + # bl_idname = "script.preset_base_add" + # bl_label = "Add a Python Preset" + bl_options = {'REGISTER'} # only because invoke_props_popup requires. + + name = bpy.props.StringProperty(name="Name", + description="Name of the preset, used to make the path name", + maxlen=64, default="") + remove_active = bpy.props.BoolProperty(default=False, options={'HIDDEN'}) + + @staticmethod + def as_filename(name): # could reuse for other presets + for char in " !@#$%^&*(){}:\";'[]<>,.\\/?": + name = name.replace(char, '_') + return name.lower().strip() + + def execute(self, context): + import os + + if hasattr(self, "pre_cb"): + self.pre_cb(context) + + preset_menu_class = getattr(bpy.types, self.preset_menu) + + if not self.remove_active: + + if not self.name: + return {'FINISHED'} + + filename = self.as_filename(self.name) + + target_path = bpy.utils.user_resource('SCRIPTS', + os.path.join("presets", self.preset_subdir), create=True) + + if not target_path: + self.report({'WARNING'}, "Failed to create presets path") + return {'CANCELLED'} + + filepath = os.path.join(target_path, filename) + ".py" + + if hasattr(self, "add"): + self.add(context, filepath) + else: + file_preset = open(filepath, 'w') + file_preset.write("import bpy\n") + + if hasattr(self, "preset_defines"): + for rna_path in self.preset_defines: + exec(rna_path) + file_preset.write("%s\n" % rna_path) + file_preset.write("\n") + + + for rna_path in self.preset_values: + value = eval(rna_path) + # convert thin wrapped sequences to simple lists to repr() + try: + value = value[:] + except: + pass + + file_preset.write("%s = %r\n" % (rna_path, value)) + file_preset.write("\ +ci = bpy.context.window_manager.palette_props.current_color_index\n\ +palette_props = bpy.context.window_manager.palette_props\n\ +image_paint = bpy.context.tool_settings.image_paint\n\ +vertex_paint = bpy.context.tool_settings.vertex_paint\n\ +if ci == 0:\n\ + image_paint.brush.color = palette_props.color_0\n\ + vertex_paint.brush.color = palette_props.color_0\n\ +elif ci == 1:\n\ + image_paint.brush.color = palette_props.color_1\n\ + vertex_paint.brush.color = palette_props.color_1\n\ +elif ci == 2:\n\ + image_paint.brush.color = palette_props.color_2\n\ + vertex_paint.brush.color = palette_props.color_2\n\ +elif ci == 3:\n\ + image_paint.brush.color = palette_props.color_3\n\ + vertex_paint.brush.color = palette_props.color_3\n\ +elif ci == 4:\n\ + image_paint.brush.color = palette_props.color_4\n\ + vertex_paint.brush.color = palette_props.color_4\n\ +elif ci == 5:\n\ + image_paint.brush.color = palette_props.color_5\n\ + vertex_paint.brush.color = palette_props.color_5\n\ +elif ci == 6:\n\ + image_paint.brush.color = palette_props.color_6\n\ + vertex_paint.brush.color = palette_props.color_6\n\ +elif ci == 7:\n\ + image_paint.brush.color = palette_props.color_7\n\ + vertex_paint.brush.color = palette_props.color_7\n\ +elif ci == 8:\n\ + image_paint.brush.color = palette_props.color_8\n\ + vertex_paint.brush.color = palette_props.color_8") + + file_preset.close() + + preset_menu_class.bl_label = bpy.path.display_name(filename) + + else: + preset_active = preset_menu_class.bl_label + + # fairly sloppy but convenient. + filepath = bpy.utils.preset_find(preset_active, self.preset_subdir) + + if not filepath: + filepath = bpy.utils.preset_find(preset_active, + self.preset_subdir, display_name=True) + + if not filepath: + return {'CANCELLED'} + + if hasattr(self, "remove"): + self.remove(context, filepath) + else: + try: + os.remove(filepath) + except: + import traceback + traceback.print_exc() + + # XXX, stupid! + preset_menu_class.bl_label = "Presets" + + if hasattr(self, "post_cb"): + self.post_cb(context) + + return {'FINISHED'} + + def check(self, context): + self.name = self.as_filename(self.name) + + def invoke(self, context, event): + if not self.remove_active: + wm = context.window_manager + return wm.invoke_props_dialog(self) + else: + return self.execute(context) + +class ExecutePalettePreset(bpy.types.Operator): + ''' Executes a preset ''' + bl_idname = "script.execute_preset" + bl_label = "Execute a Python Preset" + + filepath = bpy.props.StringProperty(name="Path", + description="Path of the Python file to execute", + maxlen=512, default="") + menu_idname = bpy.props.StringProperty(name="Menu ID Name", + description="ID name of the menu this was called from", default="") + + def execute(self, context): + from os.path import basename + filepath = self.filepath + + # change the menu title to the most recently chosen option + preset_class = getattr(bpy.types, self.menu_idname) + preset_class.bl_label = bpy.path.display_name(basename(filepath)) + + # execute the preset using script.python_file_run + bpy.ops.script.python_file_run(filepath=filepath) + return {'FINISHED'} + + +class PALETTE_MT_palette_presets(bpy.types.Menu): + bl_label = "Palette Presets" + preset_subdir = "palette" + preset_operator = "script.execute_preset" + draw = bpy.types.Menu.draw_preset + + +class AddPresetPalette(AddPresetBase, bpy.types.Operator): + '''Add a Palette Preset''' + bl_idname = "palette.preset_add" + bl_label = "Add Palette Preset" + preset_menu = "PALETTE_MT_palette_presets" + + preset_defines = [ + "window_manager = bpy.context.window_manager" + ] + + preset_values = [ + "window_manager.palette_props.color_0", + "window_manager.palette_props.color_1", + "window_manager.palette_props.color_2", + "window_manager.palette_props.color_3", + "window_manager.palette_props.color_4", + "window_manager.palette_props.color_5", + "window_manager.palette_props.color_6", + "window_manager.palette_props.color_7", + "window_manager.palette_props.color_8", + + ] + + preset_subdir = "palette" + + +class BrushButtonsPanel(): + bl_space_type = 'IMAGE_EDITOR' + bl_region_type = 'UI' + + @classmethod + def poll(cls, context): + sima = context.space_data + toolsettings = context.tool_settings.image_paint + return sima.show_paint and toolsettings.brush + +class IMAGE_OT_select_color(bpy.types.Operator): + bl_label = "" + bl_description = "Select this color" + bl_idname = "paint.select_color" + + + color_index = IntProperty() + + def invoke(self, context, event): + palette_props = bpy.context.window_manager.palette_props + palette_props.current_color_index = self.color_index + + if self.color_index == 0: + color = palette_props.color_0 + elif self.color_index == 1: + color = palette_props.color_1 + elif self.color_index == 2: + color = palette_props.color_2 + elif self.color_index == 3: + color = palette_props.color_3 + elif self.color_index == 4: + color = palette_props.color_4 + elif self.color_index == 5: + color = palette_props.color_5 + elif self.color_index == 6: + color = palette_props.color_6 + elif self.color_index == 7: + color = palette_props.color_7 + elif self.color_index == 8: + color = palette_props.color_8 + elif self.color_index == 9: + color = palette_props.color_9 + + bpy.context.tool_settings.image_paint.brush.color = color + bpy.context.tool_settings.vertex_paint.brush.color = color + return {"FINISHED"} + + + + +def color_palette_draw(self, context): + palette_props = bpy.context.window_manager.palette_props + + + layout = self.layout + + row = layout.row(align=True) + row.menu("PALETTE_MT_palette_presets", text=bpy.types.PALETTE_MT_palette_presets.bl_label) + row.operator("palette.preset_add", text="", icon="ZOOMIN") + row.operator("palette.preset_add", text="", icon="ZOOMOUT").remove_active = True + + + if context.vertex_paint_object: + brush = context.tool_settings.vertex_paint.brush + elif context.image_paint_object: + brush = context.tool_settings.image_paint.brush + elif context.space_data.use_image_paint: + brush = context.tool_settings.image_paint.brush + + + for i in range(0, 9): + if not i % 3: + row = layout.row() + + + + if i == palette_props.current_color_index: + + if i == 0: + palette_props.color_0 = brush.color[:] + elif i == 1: + palette_props.color_1 = brush.color[:] + elif i == 2: + palette_props.color_2 = brush.color[:] + elif i == 3: + palette_props.color_3 = brush.color[:] + elif i == 4: + palette_props.color_4 = brush.color[:] + elif i == 5: + palette_props.color_5 = brush.color[:] + elif i == 6: + palette_props.color_6 = brush.color[:] + elif i == 7: + palette_props.color_7 = brush.color[:] + elif i == 8: + palette_props.color_8 = brush.color[:] + col = row.column() + col.prop(brush, "color", text="") + col.operator("paint.select_color", + icon="COLOR", emboss=False).color_index = i + + else : + col = row.column(align=True) + col.prop(palette_props, "color_%d" % i) + col.operator("paint.select_color" + ).color_index = i + + + +class IMAGE_PT_color_palette(BrushButtonsPanel, bpy.types.Panel): + bl_label = "Color Palette" + bl_options = {'DEFAULT_CLOSED'} + + def draw(self, context): + color_palette_draw(self, context) + + +class PaintPanel(): + bl_space_type = 'VIEW_3D' + bl_region_type = 'TOOLS' + + @staticmethod + def paint_settings(context): + ts = context.tool_settings + + if context.vertex_paint_object: + return ts.vertex_paint + elif context.weight_paint_object: + return ts.weight_paint + elif context.texture_paint_object: + return ts.image_paint + return None + + +class VIEW3D_PT_color_palette(PaintPanel, bpy.types.Panel): + bl_label = "Color Palette" + bl_options = {'DEFAULT_CLOSED'} + + @classmethod + def poll(cls, context): + return (context.image_paint_object or context.vertex_paint_object) + + def draw(self, context): + color_palette_draw(self, context) + + +class VIEW3D_OT_select_weight(bpy.types.Operator): + bl_label = "" + bl_description = "Select this weight" + bl_idname = "paint.select_weight" + + weight_index = IntProperty() + + def invoke(self, context, event): + palette_props = bpy.context.window_manager.palette_props + palette_props.current_weight_index = self.weight_index + + if self.weight_index == 0: + weight = palette_props.weight_0 + elif self.weight_index == 1: + weight = palette_props.weight_1 + elif self.weight_index == 2: + weight = palette_props.weight_2 + elif self.weight_index == 3: + weight = palette_props.weight_3 + elif self.weight_index == 4: + weight = palette_props.weight_4 + elif self.weight_index == 5: + weight = palette_props.weight_5 + elif self.weight_index == 6: + weight = palette_props.weight_6 + elif self.weight_index == 7: + weight = palette_props.weight_7 + elif self.weight_index == 8: + weight = palette_props.weight_8 + elif self.weight_index == 9: + weight = palette_props.weight_9 + elif self.weight_index == 10: + weight = palette_props.weight_10 + + bpy.context.tool_settings.vertex_group_weight = weight + return {"FINISHED"} + + +class VIEW3D_OT_reset_weight_palette(bpy.types.Operator): + bl_label = "" + bl_idname = "paint.reset_weight_palette" + + def execute(self, context): + palette_props = context.window_manager.palette_props + + + if palette_props.current_weight_index == 0: + print("coucou!") + context.tool_settings.vertex_group_weight = 0.0 + palette_props.weight_0 = 0.0 + + palette_props.weight_1 = 0.1 + if palette_props.current_weight_index == 1: + context.tool_settings.vertex_group_weight = 0.1 + + if palette_props.current_weight_index == 2: + context.tool_settings.vertex_group_weight = 0.25 + palette_props.weight_2 = 0.25 + + if palette_props.current_weight_index == 3: + context.tool_settings.vertex_group_weight = 0.3333 + palette_props.weight_3 = 0.3333 + + if palette_props.current_weight_index == 4: + context.tool_settings.vertex_group_weight = 0.4 + palette_props.weight_4 = 0.4 + + if palette_props.current_weight_index == 5: + context.tool_settings.vertex_group_weight = 0.5 + palette_props.weight_5 = 0.5 + + if palette_props.current_weight_index == 6: + context.tool_settings.vertex_group_weight = 0.6 + palette_props.weight_6 = 0.6 + + if palette_props.current_weight_index == 7: + context.tool_settings.vertex_group_weight = 0.6666 + palette_props.weight_7 = 0.6666 + + if palette_props.current_weight_index == 8: + context.tool_settings.vertex_group_weight = 0.75 + palette_props.weight_8 = 0.75 + + if palette_props.current_weight_index == 9: + context.tool_settings.vertex_group_weight = 0.9 + palette_props.weight_9 = 0.9 + + if palette_props.current_weight_index == 10: + context.tool_settings.vertex_group_weight = 1.0 + palette_props.weight_10 = 1.0 + return {"FINISHED"} + +class VIEW3D_PT_weight_palette(PaintPanel, bpy.types.Panel): + bl_label = "Weight Palette" + bl_options = {'DEFAULT_CLOSED'} + + @classmethod + def poll(cls, context): + return context.weight_paint_object + + def draw(self, context): + palette_props = bpy.context.window_manager.palette_props + vertex_group_weight = bpy.context.tool_settings.vertex_group_weight + + + + layout = self.layout + + box = layout.box() + + row = box.row() + if palette_props.current_weight_index == 0: + palette_props.weight_0 = vertex_group_weight + row.operator("paint.select_weight", text="%.2f" % palette_props.weight_0, + emboss=False).weight_index = 0 + else : + row.operator("paint.select_weight", text="%.2f" % palette_props.weight_0, + emboss=True).weight_index = 0 + + row = box.row(align=True) + if palette_props.current_weight_index == 1: + palette_props.weight_1 = vertex_group_weight + row.operator("paint.select_weight", text="%.2f" % palette_props.weight_1, + emboss=False).weight_index = 1 + else : + row.operator("paint.select_weight", text="%.2f" % palette_props.weight_1, + emboss=True).weight_index = 1 + + if palette_props.current_weight_index == 2: + palette_props.weight_2 = vertex_group_weight + row.operator("paint.select_weight", text="%.2f" % palette_props.weight_2, + emboss=False).weight_index = 2 + else : + row.operator("paint.select_weight", text="%.2f" % palette_props.weight_2, + emboss=True).weight_index = 2 + + if palette_props.current_weight_index == 3: + palette_props.weight_3 = vertex_group_weight + row.operator("paint.select_weight", text="%.2f" % palette_props.weight_3, + emboss=False).weight_index = 3 + else : + row.operator("paint.select_weight", text="%.2f" % palette_props.weight_3, + emboss=True).weight_index = 3 + + row = box.row(align=True) + + if palette_props.current_weight_index == 4: + palette_props.weight_4 = vertex_group_weight + row.operator("paint.select_weight", text="%.2f" % palette_props.weight_4, + emboss=False).weight_index = 4 + else : + row.operator("paint.select_weight", text="%.2f" % palette_props.weight_4, + emboss=True).weight_index = 4 + + if palette_props.current_weight_index == 5: + palette_props.weight_5 = vertex_group_weight + row.operator("paint.select_weight", text="%.2f" % palette_props.weight_5, + emboss=False).weight_index = 5 + else : + row.operator("paint.select_weight", text="%.2f" % palette_props.weight_5, + emboss=True).weight_index = 5 + + if palette_props.current_weight_index == 6: + palette_props.weight_6 = vertex_group_weight + row.operator("paint.select_weight", text="%.2f" % palette_props.weight_6, + emboss=False).weight_index = 6 + else : + row.operator("paint.select_weight", text="%.2f" % palette_props.weight_6, + emboss=True).weight_index = 6 + + row = box.row(align=True) + + if palette_props.current_weight_index == 7: + palette_props.weight_7 = vertex_group_weight + row.operator("paint.select_weight", text="%.2f" % palette_props.weight_7, + emboss=False).weight_index = 7 + else : + row.operator("paint.select_weight", text="%.2f" % palette_props.weight_7, + emboss=True).weight_index = 7 + + if palette_props.current_weight_index == 8: + palette_props.weight_8 = vertex_group_weight + row.operator("paint.select_weight", text="%.2f" % palette_props.weight_8, + emboss=False).weight_index = 8 + else : + row.operator("paint.select_weight", text="%.2f" % palette_props.weight_8, + emboss=True).weight_index = 8 + + if palette_props.current_weight_index == 9: + palette_props.weight_9 = vertex_group_weight + row.operator("paint.select_weight", text="%.2f" % palette_props.weight_9, + emboss=False).weight_index = 9 + else : + row.operator("paint.select_weight", text="%.2f" % palette_props.weight_9, + emboss=True).weight_index = 9 + + row = box.row() + + if palette_props.current_weight_index == 10: + palette_props.weight_10 = vertex_group_weight + row.operator("paint.select_weight", text="%.2f" % palette_props.weight_10, + emboss=False).weight_index = 10 + else : + row.operator("paint.select_weight", text="%.2f" % palette_props.weight_10, + emboss=True).weight_index = 10 + + row = layout.row() + row.operator("paint.reset_weight_palette", text="Reset") + + +def register(): + + class Colors(bpy.types.PropertyGroup): + """Class for colors CollectionProperty""" + color = bpy.props.FloatVectorProperty( + name="", description="", default=(0.8, 0.8, 0.8), min=0, max=1, + step=1, precision=3, subtype='COLOR_GAMMA', size=3) + + + class PaletteProps(bpy.types.PropertyGroup): + current_color_index = IntProperty( + name="Current Color Index", description="", default=0, min=-1) + + current_weight_index = IntProperty( + name="Current Color Index", description="", default=10, min=-1) + + # Collection of colors + colors = bpy.props.CollectionProperty(type=Colors) + + color_0 = bpy.props.FloatVectorProperty( + name="", description="", default=(0.8, 0.8, 0.8), min=0, max=1, + step=1, precision=3, subtype='COLOR_GAMMA', size=3) + color_1 = bpy.props.FloatVectorProperty( + name="", description="", default=(0.8, 0.8, 0.8), min=0, max=1, + step=1, precision=3, subtype='COLOR_GAMMA', size=3) + color_2 = bpy.props.FloatVectorProperty( + name="", description="", default=(0.8, 0.8, 0.8), min=0, max=1, + step=1, precision=3, subtype='COLOR_GAMMA', size=3) + color_3 = bpy.props.FloatVectorProperty( + name="", description="", default=(0.8, 0.8, 0.8), min=0, max=1, + step=1, precision=3, subtype='COLOR_GAMMA', size=3) + color_4 = bpy.props.FloatVectorProperty( + name="", description="", default=(0.8, 0.8, 0.8), min=0, max=1, + step=1, precision=3, subtype='COLOR_GAMMA', size=3) + color_5 = bpy.props.FloatVectorProperty( + name="", description="", default=(0.8, 0.8, 0.8), min=0, max=1, + step=1, precision=3, subtype='COLOR_GAMMA', size=3) + color_6 = bpy.props.FloatVectorProperty( + name="", description="", default=(0.8, 0.8, 0.8), min=0, max=1, + step=1, precision=3, subtype='COLOR_GAMMA', size=3) + color_7 = bpy.props.FloatVectorProperty( + name="", description="", default=(0.8, 0.8, 0.8), min=0, max=1, + step=1, precision=3, subtype='COLOR_GAMMA', size=3) + color_8 = bpy.props.FloatVectorProperty( + name="", description="", default=(0.8, 0.8, 0.8), min=0, max=1, + step=1, precision=3, subtype='COLOR_GAMMA', size=3) + + + weight_0 = bpy.props.FloatProperty( + default=0.0, min=0.0, max=1.0, precision=3) + weight_1 = bpy.props.FloatProperty( + default=0.1, min=0.0, max=1.0, precision=3) + weight_2 = bpy.props.FloatProperty( + default=0.25, min=0.0, max=1.0, precision=3) + weight_3 = bpy.props.FloatProperty( + default=0.333, min=0.0, max=1.0, precision=3) + weight_4 = bpy.props.FloatProperty( + default=0.4, min=0.0, max=1.0, precision=3) + weight_5 = bpy.props.FloatProperty( + default=0.5, min=0.0, max=1.0, precision=3) + weight_6 = bpy.props.FloatProperty( + default=0.6, min=0.0, max=1.0, precision=3) + weight_7 = bpy.props.FloatProperty( + default=0.6666, min=0.0, max=1.0, precision=3) + weight_8 = bpy.props.FloatProperty( + default=0.75, min=0.0, max=1.0, precision=3) + weight_9 = bpy.props.FloatProperty( + default=0.9, min=0.0, max=1.0, precision=3) + weight_10 = bpy.props.FloatProperty( + default=1.0, min=0.0, max=1.0, precision=3) + pass + + + + + + bpy.utils.register_module(__name__) + + bpy.types.WindowManager.palette_props = PointerProperty( + type=PaletteProps, name="Palette Props", description="") + + + for i in range(0, 256): + colors = bpy.context.window_manager.palette_props.colors.add() + + pass + + +def unregister(): + pass + + +if __name__ == "__main__": + register() |