1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
|
# SPDX-License-Identifier: GPL-2.0-or-later
# <pep8 compliant>
import bpy
import math
from itertools import count, repeat
from mathutils import Vector, Matrix
from ....utils.naming import make_derived_name
from ....utils.widgets_basic import create_cube_widget
from ....utils.misc import LazyRef
from ....base_rig import stage
from ..skin_parents import ControlBoneParentArmature
from ..skin_rigs import BaseSkinRig
class Rig(BaseSkinRig):
"""
This rig transforms its child nodes' locations, but keeps
their rotation and scale stable. This demonstrates implementing
a basic parent controller rig.
"""
def find_org_bones(self, bone):
return bone.name
def initialize(self):
super().initialize()
self.make_control = self.params.make_control
# Choose the parent bone for the child nodes
if self.make_control:
self.input_ref = LazyRef(self.bones.ctrl, 'master')
else:
self.input_ref = self.base_bone
# Retrieve the orientation of the control
matrix = self.get_bone(self.base_bone).bone.matrix_local
self.transform_orientation = matrix.to_quaternion()
####################################################
# Control Nodes
def build_control_node_parent(self, node, parent_bone):
# Parent nodes to the control bone, but isolate rotation and scale
return ControlBoneParentArmature(
self, node, bones=[self.input_ref],
orientation=self.transform_orientation,
copy_scale=LazyRef(self.bones.mch, 'template'),
copy_rotation=LazyRef(self.bones.mch, 'template'),
)
def get_child_chain_parent(self, rig, parent_bone):
# Forward child chain parenting to the next rig, so that
# only control nodes are affected by this one.
return self.get_child_chain_parent_next(rig)
####################################################
# BONES
#
# ctrl:
# master
# Master control
# mch:
# template
# Bone used to lock rotation and scale of child nodes.
#
####################################################
####################################################
# Master control
@stage.generate_bones
def make_master_control(self):
if self.make_control:
self.bones.ctrl.master = self.copy_bone(
self.bones.org, make_derived_name(self.bones.org, 'ctrl'), parent=True)
@stage.configure_bones
def configure_master_control(self):
if self.make_control:
self.copy_bone_properties(self.bones.org, self.bones.ctrl.master)
@stage.generate_widgets
def make_master_control_widget(self):
if self.make_control:
create_cube_widget(self.obj, self.bones.ctrl.master)
####################################################
# Template MCH
@stage.generate_bones
def make_mch_template_bone(self):
self.bones.mch.template = self.copy_bone(
self.bones.org, make_derived_name(self.bones.org, 'mch', '_orient'), parent=True)
@stage.parent_bones
def parent_mch_template_bone(self):
self.set_bone_parent(self.bones.mch.template, self.get_child_chain_parent_next(self))
####################################################
# ORG bone
@stage.rig_bones
def rig_org_bone(self):
pass
####################################################
# SETTINGS
@classmethod
def add_parameters(self, params):
params.make_control = bpy.props.BoolProperty(
name="Control",
default=True,
description="Create a control bone for the copy"
)
@classmethod
def parameters_ui(self, layout, params):
layout.prop(params, "make_control", text="Generate Control")
def create_sample(obj):
from rigify.rigs.basic.super_copy import create_sample as inner
obj.pose.bones[inner(obj)["Bone"]].rigify_type = 'skin.transform.basic'
|