4 class ConstraintButtonsPanel(bpy.types.Panel):
5 __space_type__ = "BUTTONS_WINDOW"
6 __region_type__ = "WINDOW"
7 __context__ = "constraint"
9 def draw_constraint(self, con):
11 box = layout.template_constraint(con)
14 if con.type == "CHILD_OF":
15 self.child_of(box, con)
16 elif con.type == "TRACK_TO":
17 self.track_to(box, con)
18 elif con.type == "IK":
20 elif con.type == "FOLLOW_PATH":
21 self.follow_path(box, con)
22 elif con.type == "LIMIT_ROTATION":
23 self.limit_rotation(box, con)
24 elif con.type == "LIMIT_LOCATION":
25 self.limit_location(box, con)
26 elif con.type == "LIMIT_SCALE":
27 self.limit_scale(box, con)
28 elif con.type == "COPY_ROTATION":
29 self.copy_rotation(box, con)
30 elif con.type == "COPY_LOCATION":
31 self.copy_location(box, con)
32 elif con.type == "COPY_SCALE":
33 self.copy_scale(box, con)
34 #elif con.type == "SCRIPT":
35 # self.script(box, con)
36 elif con.type == "ACTION":
38 elif con.type == "LOCKED_TRACK":
39 self.locked_track(box, con)
40 elif con.type == "LIMIT_DISTANCE":
41 self.limit_distance(box, con)
42 elif con.type == "STRETCH_TO":
43 self.stretch_to(box, con)
44 elif con.type == "FLOOR":
46 elif con.type == "RIGID_BODY_JOINT":
47 self.rigid_body(box, con)
48 elif con.type == "CLAMP_TO":
49 self.clamp_to(box, con)
50 elif con.type == "TRANSFORM":
51 self.transform(box, con)
52 elif con.type == "SHRINKWRAP":
53 self.shrinkwrap(box, con)
55 # show/key buttons here are most likely obsolete now, with
56 # keyframing functionality being part of every button
57 if con.type not in ("RIGID_BODY_JOINT", "NULL"):
58 box.itemR(con, "influence")
60 def space_template(self, layout, con, target=True, owner=True):
64 row.itemL(text="Convert:")
67 row.itemR(con, "target_space", text="")
70 row.itemL(icon="ICON_ARROW_LEFTRIGHT")
73 row.itemR(con, "owner_space", text="")
75 def target_template(self, layout, con, subtargets=True):
76 layout.itemR(con, "target") # XXX limiting settings for only 'curves' or some type of object
78 if con.target and subtargets:
79 if con.target.type == "ARMATURE":
80 layout.item_pointerR(con, "subtarget", con.target.data, "bones", text="Bone")
82 if con.type == 'COPY_LOCATION':
84 row.itemL(text="Head/Tail:")
85 row.itemR(con, "head_tail", text="")
86 elif con.target.type in ("MESH", "LATTICE"):
87 layout.item_pointerR(con, "subtarget", con.target, "vertex_groups", text="Vertex Group")
89 def child_of(self, layout, con):
90 self.target_template(layout, con)
92 split = layout.split()
95 sub.itemL(text="Location:")
96 sub.itemR(con, "locationx", text="X")
97 sub.itemR(con, "locationy", text="Y")
98 sub.itemR(con, "locationz", text="Z")
101 sub.itemL(text="Rotation:")
102 sub.itemR(con, "rotationx", text="X")
103 sub.itemR(con, "rotationy", text="Y")
104 sub.itemR(con, "rotationz", text="Z")
107 sub.itemL(text="Scale:")
108 sub.itemR(con, "sizex", text="X")
109 sub.itemR(con, "sizey", text="Y")
110 sub.itemR(con, "sizez", text="Z")
114 row.itemL(text="SET OFFSET")
115 row.itemL(text="CLEAR OFFSET")
117 def track_to(self, layout, con):
118 self.target_template(layout, con)
121 row.itemL(text="To:")
122 row.itemR(con, "track", expand=True)
125 row.itemR(con, "up", text="Up")
126 row.itemR(con, "target_z")
128 self.space_template(layout, con)
130 def ik(self, layout, con):
131 self.target_template(layout, con)
133 layout.itemR(con, "pole_target")
134 layout.itemR(con, "pole_subtarget")
136 col = layout.column_flow()
137 col.itemR(con, "iterations")
138 col.itemR(con, "pole_angle")
139 col.itemR(con, "weight")
140 col.itemR(con, "orient_weight")
141 col.itemR(con, "chain_length")
143 col = layout.column_flow()
144 col.itemR(con, "tail")
145 col.itemR(con, "rotation")
146 col.itemR(con, "targetless")
147 col.itemR(con, "stretch")
149 def follow_path(self, layout, con):
150 self.target_template(layout, con)
153 row.itemR(con, "curve_follow")
154 row.itemR(con, "offset")
157 row.itemL(text="Forward:")
158 row.itemR(con, "forward", expand=True)
161 row.itemR(con, "up", text="Up")
164 def limit_rotation(self, layout, con):
166 split = layout.split()
169 col.itemR(con, "use_limit_x")
170 colsub = col.column()
171 colsub.active = con.use_limit_x
172 colsub.itemR(con, "minimum_x", text="Min")
173 colsub.itemR(con, "maximum_x", text="Max")
176 col.itemR(con, "use_limit_y")
177 colsub = col.column()
178 colsub.active = con.use_limit_y
179 colsub.itemR(con, "minimum_y", text="Min")
180 colsub.itemR(con, "maximum_y", text="Max")
183 col.itemR(con, "use_limit_z")
184 colsub = col.column()
185 colsub.active = con.use_limit_z
186 colsub.itemR(con, "minimum_z", text="Min")
187 colsub.itemR(con, "maximum_z", text="Max")
190 row.itemR(con, "limit_transform")
194 row.itemL(text="Convert:")
195 row.itemR(con, "owner_space", text="")
197 def limit_location(self, layout, con):
198 split = layout.split()
201 col.itemR(con, "use_minimum_x")
202 colsub = col.column()
203 colsub.active = con.use_minimum_x
204 colsub.itemR(con, "minimum_x", text="")
205 col.itemR(con, "use_maximum_x")
206 colsub = col.column()
207 colsub.active = con.use_maximum_x
208 colsub.itemR(con, "maximum_x", text="")
211 col.itemR(con, "use_minimum_y")
212 colsub = col.column()
213 colsub.active = con.use_minimum_y
214 colsub.itemR(con, "minimum_y", text="")
215 col.itemR(con, "use_maximum_y")
216 colsub = col.column()
217 colsub.active = con.use_maximum_y
218 colsub.itemR(con, "maximum_y", text="")
221 col.itemR(con, "use_minimum_z")
222 colsub = col.column()
223 colsub.active = con.use_minimum_z
224 colsub.itemR(con, "minimum_z", text="")
225 col.itemR(con, "use_maximum_z")
226 colsub = col.column()
227 colsub.active = con.use_maximum_z
228 colsub.itemR(con, "maximum_z", text="")
231 row.itemR(con, "limit_transform")
235 row.itemL(text="Convert:")
236 row.itemR(con, "owner_space", text="")
238 def limit_scale(self, layout, con):
239 split = layout.split()
242 col.itemR(con, "use_minimum_x")
243 colsub = col.column()
244 colsub.active = con.use_minimum_x
245 colsub.itemR(con, "minimum_x", text="")
246 col.itemR(con, "use_maximum_x")
247 colsub = col.column()
248 colsub.active = con.use_maximum_x
249 colsub.itemR(con, "maximum_x", text="")
252 col.itemR(con, "use_minimum_y")
253 colsub = col.column()
254 colsub.active = con.use_minimum_y
255 colsub.itemR(con, "minimum_y", text="")
256 col.itemR(con, "use_maximum_y")
257 colsub = col.column()
258 colsub.active = con.use_maximum_y
259 colsub.itemR(con, "maximum_y", text="")
262 col.itemR(con, "use_minimum_z")
263 colsub = col.column()
264 colsub.active = con.use_minimum_z
265 colsub.itemR(con, "minimum_z", text="")
266 col.itemR(con, "use_maximum_z")
267 colsub = col.column()
268 colsub.active = con.use_maximum_z
269 colsub.itemR(con, "maximum_z", text="")
272 row.itemR(con, "limit_transform")
276 row.itemL(text="Convert:")
277 row.itemR(con, "owner_space", text="")
279 def copy_rotation(self, layout, con):
280 self.target_template(layout, con)
282 split = layout.split()
285 col.itemR(con, "rotate_like_x", text="X")
286 colsub = col.column()
287 colsub.active = con.rotate_like_x
288 colsub.itemR(con, "invert_x", text="Invert")
291 col.itemR(con, "rotate_like_y", text="Y")
292 colsub = col.column()
293 colsub.active = con.rotate_like_y
294 colsub.itemR(con, "invert_y", text="Invert")
297 col.itemR(con, "rotate_like_z", text="Z")
298 colsub = col.column()
299 colsub.active = con.rotate_like_z
300 colsub.itemR(con, "invert_z", text="Invert")
302 layout.itemR(con, "offset")
304 self.space_template(layout, con)
306 def copy_location(self, layout, con):
307 self.target_template(layout, con)
309 split = layout.split()
312 col.itemR(con, "locate_like_x", text="X")
313 colsub = col.column()
314 colsub.active = con.locate_like_x
315 colsub.itemR(con, "invert_x", text="Invert")
318 col.itemR(con, "locate_like_y", text="Y")
319 colsub = col.column()
320 colsub.active = con.locate_like_y
321 colsub.itemR(con, "invert_y", text="Invert")
324 col.itemR(con, "locate_like_z", text="Z")
325 colsub = col.column()
326 colsub.active = con.locate_like_z
327 colsub.itemR(con, "invert_z", text="Invert")
329 layout.itemR(con, "offset")
331 self.space_template(layout, con)
333 def copy_scale(self, layout, con):
334 self.target_template(layout, con)
336 row = layout.row(align=True)
337 row.itemR(con, "size_like_x", text="X")
338 row.itemR(con, "size_like_y", text="Y")
339 row.itemR(con, "size_like_z", text="Z")
341 layout.itemR(con, "offset")
343 self.space_template(layout, con)
345 #def script(self, layout, con):
347 def action(self, layout, con):
348 self.target_template(layout, con)
350 layout.itemR(con, "action")
351 layout.itemR(con, "transform_channel")
353 split = layout.split()
355 col = split.column(align=True)
356 col.itemR(con, "start_frame", text="Start")
357 col.itemR(con, "end_frame", text="End")
359 col = split.column(align=True)
360 col.itemR(con, "minimum", text="Min")
361 col.itemR(con, "maximum", text="Max")
364 row.itemL(text="Convert:")
365 row.itemR(con, "owner_space", text="")
367 def locked_track(self, layout, con):
368 self.target_template(layout, con)
371 row.itemL(text="To:")
372 row.itemR(con, "track", expand=True)
375 row.itemL(text="Lock:")
376 row.itemR(con, "locked", expand=True)
378 def limit_distance(self, layout, con):
379 self.target_template(layout, con)
381 layout.itemR(con, "distance")
384 row.itemL(text="Clamp Region:")
385 row.itemR(con, "limit_mode", text="")
386 #Missing: Recalculate Button
388 def stretch_to(self, layout, con):
389 self.target_template(layout, con)
392 row.itemR(con, "original_length", text="Rest Length")
393 row.itemR(con, "bulge", text="Volume Variation")
396 row.itemL(text="Volume:")
397 row.itemR(con, "volume", expand=True)
398 row.itemL(text="Plane:")
399 row.itemR(con, "keep_axis", expand=True)
400 #Missing: Recalculate Button
402 def floor(self, layout, con):
403 self.target_template(layout, con)
406 row.itemR(con, "sticky")
407 row.itemR(con, "use_rotation")
409 layout.itemR(con, "offset")
412 row.itemL(text="Min/Max:")
413 row.itemR(con, "floor_location", expand=True)
415 def rigid_body(self, layout, con):
416 self.target_template(layout, con)
418 layout.itemR(con, "pivot_type")
419 layout.itemR(con, "child")
422 row.itemR(con, "disable_linked_collision", text="No Collision")
423 row.itemR(con, "draw_pivot")
425 split = layout.split()
428 col.itemR(con, "pivot_x")
429 col.itemR(con, "pivot_y")
430 col.itemR(con, "pivot_z")
433 col.itemR(con, "axis_x")
434 col.itemR(con, "axis_y")
435 col.itemR(con, "axis_z")
437 #Missing: Limit arrays (not wrapped in RNA yet)
439 def clamp_to(self, layout, con):
440 self.target_template(layout, con)
443 row.itemL(text="Main Axis:")
444 row.itemR(con, "main_axis", expand=True)
447 row.itemR(con, "cyclic")
449 def transform(self, layout, con):
450 self.target_template(layout, con)
452 layout.itemR(con, "extrapolate_motion", text="Extrapolate")
454 split = layout.split()
457 col.itemL(text="Source:")
458 col.row().itemR(con, "map_from", expand=True)
460 sub = col.row(align=True)
462 sub.itemR(con, "from_min_x", text="")
463 sub.itemR(con, "from_max_x", text="")
465 sub = col.row(align=True)
467 sub.itemR(con, "from_min_y", text="")
468 sub.itemR(con, "from_max_y", text="")
470 sub = col.row(align=True)
472 sub.itemR(con, "from_min_z", text="")
473 sub.itemR(con, "from_max_z", text="")
475 split = layout.split()
478 col.itemL(text="Destination:")
479 col.row().itemR(con, "map_to", expand=True)
481 sub = col.row(align=True)
482 sub.itemR(con, "map_to_x_from", text="")
483 sub.itemR(con, "to_min_x", text="")
484 sub.itemR(con, "to_max_x", text="")
486 sub = col.row(align=True)
487 sub.itemR(con, "map_to_y_from", text="")
488 sub.itemR(con, "to_min_y", text="")
489 sub.itemR(con, "to_max_y", text="")
491 sub = col.row(align=True)
492 sub.itemR(con, "map_to_z_from", text="")
493 sub.itemR(con, "to_min_z", text="")
494 sub.itemR(con, "to_max_z", text="")
496 self.space_template(layout, con)
498 def shrinkwrap (self, layout, con):
499 self.target_template(layout, con)
501 layout.itemR(con, "distance")
502 layout.itemR(con, "shrinkwrap_type")
504 if con.shrinkwrap_type == "PROJECT":
505 row = layout.row(align=True)
506 row.itemR(con, "axis_x")
507 row.itemR(con, "axis_y")
508 row.itemR(con, "axis_z")
510 class OBJECT_PT_constraints(ConstraintButtonsPanel):
511 __idname__ = "OBJECT_PT_constraints"
512 __label__ = "Constraints"
513 __context__ = "constraint"
515 def poll(self, context):
516 return (context.object != None)
518 def draw(self, context):
523 row.item_menu_enumO("OBJECT_OT_constraint_add", "type")
526 for con in ob.constraints:
527 self.draw_constraint(con)
529 class BONE_PT_constraints(ConstraintButtonsPanel):
530 __idname__ = "BONE_PT_constraints"
531 __label__ = "Bone Constraints"
534 def poll(self, context):
536 return (ob and ob.type == "ARMATURE" and context.bone)
538 def draw(self, context):
540 pchan = ob.pose.pose_channels[context.bone.name]
544 row.item_menu_enumO("OBJECT_OT_constraint_add", "type")
547 for con in pchan.constraints:
548 self.draw_constraint(con)
550 bpy.types.register(OBJECT_PT_constraints)
551 bpy.types.register(BONE_PT_constraints)