-
Campbell Barton authored
- remove unused imports - remove/comment unused vars - fix for some bugs with unused vars being used
Campbell Barton authored- remove unused imports - remove/comment unused vars - fix for some bugs with unused vars being used
paint_palette.py 25.19 KiB
# 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,2),
"blender": (2, 5, 7),
"api": 36826,
"location": "Image Editor and 3D View > Any Paint mode > Color Palette or Weight Palette panel",
"description": "Palettes for color and weight paint modes",
"warning": "",
"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": "Paint"}
"""
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):
bpy.context.window_manager.palette_props.colors.add()
pass
def unregister():
bpy.utils.unregister_module(__name__)
pass
if __name__ == "__main__":
register()