Newer
Older
Alexander Gavrilov
committed
#====================== 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 LICENSE BLOCK ========================
# <pep8 compliant>
import bpy
ORG_LAYER = [n == 31 for n in range(0, 32)] # Armature layer that original bones should be moved to.
MCH_LAYER = [n == 30 for n in range(0, 32)] # Armature layer that mechanism bones should be moved to.
DEF_LAYER = [n == 29 for n in range(0, 32)] # Armature layer that deformation bones should be moved to.
ROOT_LAYER = [n == 28 for n in range(0, 32)] # Armature layer that root bone should be moved to.
Alexander Gavrilov
committed
def get_layers(layers):
""" Does its best to extract a set of layers from any data thrown at it.
"""
if type(layers) == int:
return [x == layers for x in range(0, 32)]
elif type(layers) == str:
s = layers.split(",")
l = []
for i in s:
try:
l += [int(float(i))]
except ValueError:
pass
return [x in l for x in range(0, 32)]
elif type(layers) == tuple or type(layers) == list:
return [x in layers for x in range(0, 32)]
else:
try:
list(layers)
except TypeError:
pass
else:
return [x in layers for x in range(0, 32)]
def set_bone_layers(bone, layers, combine=False):
if combine:
bone.layers = [ a or b for a, b in zip(bone.layers, layers) ]
else:
bone.layers = layers
Alexander Gavrilov
committed
#=============================================
# UI utilities
#=============================================
class ControlLayersOption:
def __init__(self, name, toggle_name=None, toggle_default=True, description="Set of control layers"):
self.name = name
self.toggle_default = toggle_default
self.description = description
self.toggle_option = self.name+'_layers_extra'
self.layers_option = self.name+'_layers'
Alexander Gavrilov
committed
self.toggle_name = toggle_name if toggle_name else "Assign " + self.name.title() + " Layers"
Alexander Gavrilov
committed
def get(self, params):
if getattr(params, self.toggle_option):
return list(getattr(params, self.layers_option))
else:
return None
def assign(self, params, bone_set, bone_list, combine=False):
Alexander Gavrilov
committed
layers = self.get(params)
if isinstance(bone_set, bpy.types.Object):
bone_set = bone_set.data.bones
Alexander Gavrilov
committed
if layers:
for name in bone_list:
bone = bone_set[name]
if isinstance(bone, bpy.types.PoseBone):
bone = bone.bone
set_bone_layers(bone, layers, combine)
def assign_rig(self, rig, bone_list, combine=False, priority=None):
layers = self.get(rig.params)
bone_set = rig.obj.data.bones
if layers:
for name in bone_list:
set_bone_layers(bone_set[name], layers, combine)
if priority is not None:
rig.generator.set_layer_group_priority(name, layers, priority)
Alexander Gavrilov
committed
def add_parameters(self, params):
prop_toggle = bpy.props.BoolProperty(
name=self.toggle_name,
default=self.toggle_default,
description=""
)
setattr(params, self.toggle_option, prop_toggle)
prop_layers = bpy.props.BoolVectorProperty(
size=32,
description=self.description,
subtype='LAYER',
Alexander Gavrilov
committed
default=tuple([i == 1 for i in range(0, 32)])
)
setattr(params, self.layers_option, prop_layers)
def parameters_ui(self, layout, params):
Alexander Gavrilov
committed
box = layout.box()
box.prop(params, self.toggle_option)
Alexander Gavrilov
committed
Alexander Gavrilov
committed
active = getattr(params, self.toggle_option)
if not active:
return
row = box.row(align=True)
row.prop(params, self.layers_option, text="")
Alexander Gavrilov
committed
ControlLayersOption.FK = ControlLayersOption('fk', description="Layers for the FK controls to be on")
ControlLayersOption.TWEAK = ControlLayersOption('tweak', description="Layers for the tweak controls to be on")