Merge of itasc branch. Project files, scons and cmake should be working. Makefile...
[blender.git] / release / ui / buttons_data_bone.py
1
2 import bpy
3  
4 class BoneButtonsPanel(bpy.types.Panel):
5         __space_type__ = 'PROPERTIES'
6         __region_type__ = 'WINDOW'
7         __context__ = "bone"
8         
9         def poll(self, context):
10                 return (context.bone or context.edit_bone)
11
12 class BONE_PT_context_bone(BoneButtonsPanel):
13         __show_header__ = False
14
15         def draw(self, context):
16                 layout = self.layout
17                 
18                 bone = context.bone
19                 if not bone:
20                         bone = context.edit_bone
21                 
22                 row = layout.row()
23                 row.itemL(text="", icon='ICON_BONE_DATA')
24                 row.itemR(bone, "name", text="")
25
26 class BONE_PT_transform(BoneButtonsPanel):
27         __label__ = "Transform"
28
29         def draw(self, context):
30                 layout = self.layout
31                 
32                 ob = context.object
33                 bone = context.bone
34                 if not bone:
35                         bone = context.edit_bone
36
37                         row = layout.row()
38                         row.column().itemR(bone, "head")
39                         row.column().itemR(bone, "tail")
40
41                         col = row.column()
42                         sub = col.column(align=True)
43                         sub.itemL(text="Roll:")
44                         sub.itemR(bone, "roll", text="")
45                         sub.itemL()
46                         sub.itemR(bone, "locked")
47
48                 else:
49                         pchan = ob.pose.pose_channels[context.bone.name]
50
51                         layout.itemR(pchan, "rotation_mode")
52
53                         row = layout.row()
54                         col = row.column()
55                         col.itemR(pchan, "location")
56                         col.active = not (bone.parent and bone.connected)
57
58                         col = row.column()
59                         if pchan.rotation_mode == 'QUATERNION':
60                                 col.itemR(pchan, "rotation", text="Rotation")
61                         elif pchan.rotation_mode == 'AXIS_ANGLE':
62                                 col.itemL(text="Rotation")
63                                 col.itemR(pchan, "rotation_angle", text="Angle")
64                                 col.itemR(pchan, "rotation_axis", text="Axis")
65                         else:
66                                 col.itemR(pchan, "euler_rotation", text="Rotation")
67
68                         row.column().itemR(pchan, "scale")
69
70                         if pchan.rotation_mode == 'QUATERNION':
71                                 col = layout.column(align=True)
72                                 col.itemL(text="Euler:")
73                                 col.row().itemR(pchan, "euler_rotation", text="")
74                                 
75 class BONE_PT_transform_locks(BoneButtonsPanel):
76         __label__ = "Transform Locks"
77         __default_closed__ = True
78         
79         def poll(self, context):
80                 return context.bone
81         
82         def draw(self, context):
83                 layout = self.layout
84                 
85                 ob = context.object
86                 bone = context.bone
87                 pchan = ob.pose.pose_channels[context.bone.name]
88                 
89                 row = layout.row()
90                 col = row.column()
91                 col.itemR(pchan, "lock_location")
92                 col.active = not (bone.parent and bone.connected)
93                 
94                 col = row.column()
95                 if pchan.rotation_mode in ('QUATERNION', 'AXIS_ANGLE'):
96                         col.itemR(pchan, "lock_rotations_4d", text="Lock Rotation")
97                         if pchan.lock_rotations_4d:
98                                 col.itemR(pchan, "lock_rotation_w", text="W")
99                         col.itemR(pchan, "lock_rotation", text="")
100                 else:
101                         col.itemR(pchan, "lock_rotation", text="Rotation")
102                 
103                 row.column().itemR(pchan, "lock_scale")
104
105 class BONE_PT_bone(BoneButtonsPanel):
106         __label__ = "Bone"
107
108         def draw(self, context):
109                 layout = self.layout
110                 
111                 ob = context.object
112                 bone = context.bone
113                 arm = context.armature
114                 
115                 if not bone:
116                         bone = context.edit_bone
117                         pchan = None
118                 else:
119                         pchan = ob.pose.pose_channels[context.bone.name]
120
121                 split = layout.split()
122
123                 col = split.column()
124                 col.itemL(text="Parent:")
125                 if context.bone:
126                         col.itemR(bone, "parent", text="")
127                 else:
128                         col.item_pointerR(bone, "parent", arm, "edit_bones", text="")
129                 
130                 row = col.row()
131                 row.active = bone.parent != None
132                 row.itemR(bone, "connected")
133                 
134                 col.itemL(text="Layers:")
135                 col.itemR(bone, "layer", text="")
136                 
137                 col = split.column()
138                 col.itemL(text="Inherit:")
139                 col.itemR(bone, "hinge", text="Rotation")
140                 col.itemR(bone, "inherit_scale", text="Scale")
141                 col.itemL(text="Display:")
142                 col.itemR(bone, "draw_wire", text="Wireframe")
143                 col.itemR(bone, "hidden", text="Hide")
144                 
145                 if ob and pchan:
146                         split = layout.split()
147                         
148                         col = split.column()
149                         col.itemL(text="Bone Group:")
150                         col.item_pointerR(pchan, "bone_group", ob.pose, "bone_groups", text="")
151                         
152                         col = split.column()
153                         col.itemL(text="Custom Shape:")
154                         col.itemR(pchan, "custom_shape", text="")
155
156 class BONE_PT_inverse_kinematics(BoneButtonsPanel):
157         __label__ = "Inverse Kinematics"
158         __default_closed__ = True
159         
160         def poll(self, context):
161                 ob = context.object
162                 bone = context.bone
163
164                 if ob and context.bone:
165                         pchan = ob.pose.pose_channels[context.bone.name]
166                         return pchan.has_ik
167                 
168                 return False
169
170         def draw(self, context):
171                 layout = self.layout
172                 
173                 ob = context.object
174                 bone = context.bone
175                 pchan = ob.pose.pose_channels[context.bone.name]
176
177                 row = layout.row()
178                 row.itemR(ob.pose, "ik_solver")
179
180                 split = layout.split(percentage=0.25)
181                 split.itemR(pchan, "ik_dof_x", text="X")
182                 row = split.row()
183                 row.itemR(pchan, "ik_stiffness_x", text="Stiffness", slider=True)
184                 row.active = pchan.ik_dof_x
185
186                 split = layout.split(percentage=0.25)
187                 row = split.row()
188                 row.itemR(pchan, "ik_limit_x", text="Limit")
189                 row.active = pchan.ik_dof_x
190                 row = split.row(align=True)
191                 row.itemR(pchan, "ik_min_x", text="")
192                 row.itemR(pchan, "ik_max_x", text="")
193                 row.active = pchan.ik_dof_x and pchan.ik_limit_x
194
195                 split = layout.split(percentage=0.25)
196                 split.itemR(pchan, "ik_dof_y", text="Y")
197                 row = split.row()
198                 row.itemR(pchan, "ik_stiffness_y", text="Stiffness", slider=True)
199                 row.active = pchan.ik_dof_y
200
201                 split = layout.split(percentage=0.25)
202                 row = split.row()
203                 row.itemR(pchan, "ik_limit_y", text="Limit")
204                 row.active = pchan.ik_dof_y
205                 row = split.row(align=True)
206                 row.itemR(pchan, "ik_min_y", text="")
207                 row.itemR(pchan, "ik_max_y", text="")
208                 row.active = pchan.ik_dof_y and pchan.ik_limit_y
209
210                 split = layout.split(percentage=0.25)
211                 split.itemR(pchan, "ik_dof_z", text="Z")
212                 row = split.row()
213                 row.itemR(pchan, "ik_stiffness_z", text="Stiffness", slider=True)
214                 row.active = pchan.ik_dof_z
215
216                 split = layout.split(percentage=0.25)
217                 row = split.row()
218                 row.itemR(pchan, "ik_limit_z", text="Limit")
219                 row.active = pchan.ik_dof_z
220                 row = split.row(align=True)
221                 row.itemR(pchan, "ik_min_z", text="")
222                 row.itemR(pchan, "ik_max_z", text="")
223                 row.active = pchan.ik_dof_z and pchan.ik_limit_z
224                 split = layout.split()
225                 split.itemR(pchan, "ik_stretch", text="Stretch", slider=True)
226                 split.itemL()
227
228                 if ob.pose.ik_solver == "ITASC":
229                         layout.itemL(text="Joint constraint:")
230                         split = layout.split(percentage=0.3)
231                         row = split.row()
232                         row.itemR(pchan, "ik_rot_control", text="Rotation")
233                         row = split.row()
234                         row.itemR(pchan, "ik_rot_weight", text="Weight", slider=True)
235                         row.active = pchan.ik_rot_control
236                         # not supported yet
237                         #split = layout.split(percentage=0.3)
238                         #row = split.row()
239                         #row.itemR(pchan, "ik_lin_control", text="Size")
240                         #row = split.row()
241                         #row.itemR(pchan, "ik_lin_weight", text="Weight", slider=True)
242                         #row.active = pchan.ik_lin_control
243                         
244
245 class BONE_PT_deform(BoneButtonsPanel):
246         __label__ = "Deform"
247         __default_closed__ = True
248
249         def draw_header(self, context):
250                 bone = context.bone
251                 
252                 if not bone:
253                         bone = context.edit_bone
254                         
255                 self.layout.itemR(bone, "deform", text="")
256
257         def draw(self, context):
258                 layout = self.layout
259                 
260                 bone = context.bone
261                 
262                 if not bone:
263                         bone = context.edit_bone
264         
265                 layout.active = bone.deform
266                         
267                 split = layout.split()
268
269                 col = split.column()
270                 col.itemL(text="Envelope:")
271                 
272                 sub = col.column(align=True)
273                 sub.itemR(bone, "envelope_distance", text="Distance")
274                 sub.itemR(bone, "envelope_weight", text="Weight")
275                 col.itemR(bone, "multiply_vertexgroup_with_envelope", text="Multiply")
276
277                 sub = col.column(align=True)
278                 sub.itemL(text="Radius:")
279                 sub.itemR(bone, "head_radius", text="Head")
280                 sub.itemR(bone, "tail_radius", text="Tail")
281
282                 col = split.column()
283                 col.itemL(text="Curved Bones:")
284                 
285                 sub = col.column(align=True)
286                 sub.itemR(bone, "bbone_segments", text="Segments")
287                 sub.itemR(bone, "bbone_in", text="Ease In")
288                 sub.itemR(bone, "bbone_out", text="Ease Out")
289                 
290                 col.itemL(text="Offset:")
291                 col.itemR(bone, "cyclic_offset")
292
293 class BONE_PT_iksolver_itasc(BoneButtonsPanel):
294         __idname__ = "BONE_PT_iksolver_itasc"
295         __label__ = "iTaSC parameters"
296         __default_closed__ = True
297         
298         def poll(self, context):
299                 ob = context.object
300                 bone = context.bone
301
302                 if ob and context.bone:
303                         pchan = ob.pose.pose_channels[context.bone.name]
304                         return pchan.has_ik and ob.pose.ik_solver == "ITASC" and ob.pose.ik_param
305                 
306                 return False
307
308         def draw(self, context):
309                 layout = self.layout
310                 ob = context.object
311                 itasc = ob.pose.ik_param
312
313                 layout.row().itemR(itasc, "simulation")
314                 if itasc.simulation:
315                         split = layout.split()
316                         row = split.row()
317                         row.itemR(itasc, "reiteration")
318                         row = split.row()
319                         if itasc.reiteration:
320                                 itasc.initial_reiteration = True
321                         row.itemR(itasc, "initial_reiteration")
322                         row.active = not itasc.reiteration
323                 
324                 flow = layout.column_flow()
325                 flow.itemR(itasc, "precision")
326                 flow.itemR(itasc, "num_iter")
327                 flow.active = not itasc.simulation or itasc.initial_reiteration or itasc.reiteration
328
329                 if itasc.simulation:            
330                         layout.itemR(itasc, "auto_step")
331                         row = layout.row()
332                         if itasc.auto_step:
333                                 row.itemR(itasc, "min_step")
334                                 row.itemR(itasc, "max_step")
335                         else:
336                                 row.itemR(itasc, "num_step")
337                         
338                 layout.itemR(itasc, "solver")
339                 if itasc.simulation:
340                         layout.itemR(itasc, "feedback")
341                         layout.itemR(itasc, "max_velocity")
342                 if itasc.solver == "DLS":
343                         row = layout.row()
344                         row.itemR(itasc, "dampmax")
345                         row.itemR(itasc, "dampeps")
346
347 bpy.types.register(BONE_PT_context_bone)
348 bpy.types.register(BONE_PT_transform)
349 bpy.types.register(BONE_PT_transform_locks)
350 bpy.types.register(BONE_PT_bone)
351 bpy.types.register(BONE_PT_deform)
352 bpy.types.register(BONE_PT_inverse_kinematics)
353 bpy.types.register(BONE_PT_iksolver_itasc)