mesh_tools/mesh_relax: pass in smooth factor
[blender-addons.git] / rigify / base_rig.py
blobb7a5d08c038d2e8bce6fff736493775c42bc4179
1 #====================== BEGIN GPL LICENSE BLOCK ======================
3 # This program is free software; you can redistribute it and/or
4 # modify it under the terms of the GNU General Public License
5 # as published by the Free Software Foundation; either version 2
6 # of the License, or (at your option) any later version.
8 # This program is distributed in the hope that it will be useful,
9 # but WITHOUT ANY WARRANTY; without even the implied warranty of
10 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 # GNU General Public License for more details.
13 # You should have received a copy of the GNU General Public License
14 # along with this program; if not, write to the Free Software Foundation,
15 # Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17 #======================= END GPL LICENSE BLOCK ========================
19 # <pep8 compliant>
21 import bpy
22 import sys
23 import traceback
25 from .utils.errors import RaiseErrorMixin
26 from .utils.bones import BoneDict, BoneUtilityMixin
27 from .utils.mechanism import MechanismUtilityMixin
28 from .utils.metaclass import BaseStagedClass
30 # Only export certain symbols via 'from base_rig import *'
31 __all__ = ['BaseRig', 'stage']
33 #=============================================
34 # Base Rig
35 #=============================================
37 class GenerateCallbackHost(BaseStagedClass, define_stages=True):
38 """
39 Standard set of callback methods to redefine.
40 Shared between BaseRig and GeneratorPlugin.
42 These callbacks are called in this order; every one is
43 called for all rigs before proceeding to the next stage.
45 Switching modes is not allowed in rigs for performance
46 reasons. Place code in the appropriate callbacks to use
47 the mode set by the main engine.
49 After each callback, all other methods decorated with
50 @stage.<method_name> are called, for instance:
52 def generate_bones(self):
53 print('first')
55 @stage.generate_bones
56 def foo(self):
57 print('second')
59 Will print 'first', then 'second'. Multiple methods in the
60 same stage are called in the order they are first defined;
61 in case of inheritance, the class bodies are scanned in
62 reverse MRO order. E.g.:
64 class Base(...):
65 @stage.generate_bones
66 def first(self):...
68 @stage.generate_bones
69 def second(self):...
71 class Derived(Base):
72 @stage.generate_bones
73 def third(self):...
75 # Was first defined in Base so still first:
76 @stage.generate_bones
77 def first(self):...
79 @stage.generate_bones
80 def fourth(self):...
82 Multiple inheritance can make this ordering confusing, so it
83 is best to avoid it.
85 When overriding such methods in a subclass the appropriate
86 decorator should be repeated for code clarity reasons;
87 a warning is printed if this is not done.
88 """
89 def initialize(self):
90 """
91 Initialize processing after all rig classes are constructed.
92 Called in Object mode. May not change the armature.
93 """
94 pass
96 def prepare_bones(self):
97 """
98 Prepare ORG bones for generation, e.g. align them.
99 Called in Edit mode. May not add bones.
101 pass
103 def generate_bones(self):
105 Create all bones.
106 Called in Edit mode.
108 pass
110 def parent_bones(self):
112 Parent all bones and set other edit mode properties.
113 Called in Edit mode. May not add bones.
115 pass
117 def configure_bones(self):
119 Configure bone properties, e.g. transform locks, layers etc.
120 Called in Object mode. May not do Edit mode operations.
122 pass
124 def apply_bones(self):
126 Can be used to apply some constraints to rest pose, and for final parenting.
127 Called in Edit mode. May not add bones.
129 pass
131 def rig_bones(self):
133 Create and configure all constraints, drivers etc.
134 Called in Object mode. May not do Edit mode operations.
136 pass
138 def generate_widgets(self):
140 Create all widget objects.
141 Called in Object mode. May not do Edit mode operations.
143 pass
145 def finalize(self):
147 Finishing touches to the construction of the rig.
148 Called in Object mode. May not do Edit mode operations.
150 pass
153 class BaseRig(GenerateCallbackHost, RaiseErrorMixin, BoneUtilityMixin, MechanismUtilityMixin):
155 Base class for all rigs.
157 The main weak areas in the legacy Rigify rig class structure
158 was that there were no provisions for intelligent interactions
159 between rigs, and all processing was done via one generate
160 method, necessitating frequent expensive mode switches.
162 This structure fixes those problems by providing a mandatory
163 base class that hold documented connections between rigs, bones,
164 and the common generator object. The generation process is also
165 split into multiple stages.
167 def __init__(self, generator, pose_bone):
168 self.generator = generator
170 self.obj = generator.obj
171 self.script = generator.script
172 self.base_bone = pose_bone.name
173 self.params = pose_bone.rigify_parameters
175 # Collection of bone names for use in implementing the rig
176 self.bones = BoneDict(
177 # ORG bone names
178 org = self.find_org_bones(pose_bone),
179 # Control bone names
180 ctrl = BoneDict(),
181 # MCH bone names
182 mch = BoneDict(),
183 # DEF bone names
184 deform = BoneDict(),
187 # Data useful for complex rig interaction:
188 # Parent-child links between rigs.
189 self.rigify_parent = None
190 self.rigify_children = []
191 # ORG bones directly owned by the rig.
192 self.rigify_org_bones = set(self.bones.flatten('org'))
193 # Children of bones owned by the rig.
194 self.rigify_child_bones = set()
195 # Bones created by the rig (mapped to original names)
196 self.rigify_new_bones = dict()
198 def register_new_bone(self, new_name, old_name=None):
199 """Registers this rig as the owner of this new bone."""
200 self.rigify_new_bones[new_name] = old_name
201 self.generator.bone_owners[new_name] = self
203 ###########################################################
204 # Bone ownership
206 def find_org_bones(self, pose_bone):
208 Select bones directly owned by the rig. Returning the
209 same bone from multiple rigs is an error.
211 May return a single name, a list, or a BoneDict.
213 Called in Object mode, may not change the armature.
215 return [pose_bone.name]
217 ###########################################################
218 # Parameters and UI
220 @classmethod
221 def add_parameters(cls, params):
223 This method add more parameters to params
224 :param params: rigify_parameters of a pose_bone
225 :return:
227 pass
229 @classmethod
230 def parameters_ui(cls, layout, params):
232 This method draws the UI of the rigify_parameters defined on the pose_bone
233 :param layout:
234 :param params:
235 :return:
237 layout.label(text="No options")
239 @classmethod
240 def on_parameter_update(cls, context, pose_bone, params, param_name):
242 A callback invoked whenever a parameter value is changed by the user.
246 #=============================================
247 # Rig Utility
248 #=============================================
251 class RigUtility(BoneUtilityMixin, MechanismUtilityMixin):
252 """Base class for utility classes that generate part of a rig."""
253 def __init__(self, owner):
254 self.owner = owner
255 self.obj = owner.obj
257 def register_new_bone(self, new_name, old_name=None):
258 self.owner.register_new_bone(new_name, old_name)
261 class RigComponent(GenerateCallbackHost, RigUtility):
262 """Base class for utility classes that generate part of a rig using callbacks."""
263 def __init__(self, owner):
264 super().__init__(owner)
266 self.owner.rigify_sub_objects = objects = self.owner.rigify_sub_objects or []
268 objects.append(self)
271 #=============================================
272 # Rig Stage Decorators
273 #=============================================
275 class stage:
276 pass
278 # Generate @stage.<...> decorators for all valid stages
279 for name, decorator in GenerateCallbackHost.make_stage_decorators():
280 setattr(stage, name, decorator)