5ee6aba1f0589000b515172738e450af37deeeae
[blender.git] / release / ui / buttons_object_constraint.py
1
2 import bpy
3
4 class ConstraintButtonsPanel(bpy.types.Panel):
5         __space_type__ = "BUTTONS_WINDOW"
6         __region_type__ = "WINDOW"
7         __context__ = "constraint"
8
9         def draw_constraint(self, con):
10                 layout = self.layout
11                 
12                 box = layout.template_constraint(con)
13
14                 if box:
15                         # match enum type to our functions, avoids a lookup table.
16                         getattr(self, con.type)(box, con)
17         
18                         # show/key buttons here are most likely obsolete now, with
19                         # keyframing functionality being part of every button
20                         if con.type not in ('RIGID_BODY_JOINT', 'NULL'):
21                                 box.itemR(con, "influence")
22         
23         def space_template(self, layout, con, target=True, owner=True):
24                 if target or owner:
25                         row = layout.row()
26
27                         row.itemL(text="Convert:")
28
29                         if target:
30                                 row.itemR(con, "target_space", text="")
31
32                         if target and owner:
33                                 row.itemL(icon='ICON_ARROW_LEFTRIGHT')
34
35                         if owner:
36                                 row.itemR(con, "owner_space", text="")
37                         
38         def target_template(self, layout, con, subtargets=True):
39                 layout.itemR(con, "target") # XXX limiting settings for only 'curves' or some type of object
40                 
41                 if con.target and subtargets:
42                         if con.target.type == "ARMATURE":
43                                 layout.item_pointerR(con, "subtarget", con.target.data, "bones", text="Bone")
44                                 
45                                 if con.type == 'COPY_LOCATION':
46                                         row = layout.row()
47                                         row.itemL(text="Head/Tail:")
48                                         row.itemR(con, "head_tail", text="")
49                         elif con.target.type in ('MESH', 'LATTICE'):
50                                 layout.item_pointerR(con, "subtarget", con.target, "vertex_groups", text="Vertex Group")
51         
52         def CHILD_OF(self, layout, con):
53                 self.target_template(layout, con)
54
55                 split = layout.split()
56                 
57                 col = split.column()
58                 col.itemL(text="Location:")
59                 col.itemR(con, "locationx", text="X")
60                 col.itemR(con, "locationy", text="Y")
61                 col.itemR(con, "locationz", text="Z")
62                 
63                 col = split.column()
64                 col.itemL(text="Rotation:")
65                 col.itemR(con, "rotationx", text="X")
66                 col.itemR(con, "rotationy", text="Y")
67                 col.itemR(con, "rotationz", text="Z")
68                 
69                 col = split.column()
70                 col.itemL(text="Scale:")
71                 col.itemR(con, "sizex", text="X")
72                 col.itemR(con, "sizey", text="Y")
73                 col.itemR(con, "sizez", text="Z")
74                 
75                 row = layout.row()
76                 row.itemO("constraint.childof_set_inverse")
77                 row.itemO("constraint.childof_clear_inverse")
78                 
79         def TRACK_TO(self, layout, con):
80                 self.target_template(layout, con)
81                 
82                 row = layout.row()
83                 row.itemL(text="To:")
84                 row.itemR(con, "track", expand=True)
85                 
86                 row = layout.row()
87                 #row.itemR(con, "up", text="Up", expand=True) # XXX: up and expand don't play nice together
88                 row.itemR(con, "up", text="Up")
89                 row.itemR(con, "target_z")
90                 
91                 self.space_template(layout, con)
92                 
93         def IK(self, layout, con):
94                 self.target_template(layout, con)
95                 
96                 layout.itemR(con, "pole_target")
97         
98                 if con.pole_target and con.pole_target.type == 'ARMATURE':
99                         layout.item_pointerR(con, "pole_subtarget", con.pole_target.data, "bones", text="Bone")
100                 
101                 split = layout.split()
102         
103                 col = split.column()
104                 col.itemR(con, "iterations")
105                 col.itemR(con, "chain_length")
106                 sub = col.column()
107                 sub.active = con.pole_target
108                 sub.itemR(con, "pole_angle")
109                 col.itemL(text="Weight:")
110                 col.itemR(con, "weight", text="Position", slider=True)
111                 sub = col.column()
112                 sub.active = con.rotation
113                 sub.itemR(con, "orient_weight", text="Rotation", slider=True)
114                 
115                 col = split.column()
116                 col.itemR(con, "tail")
117                 col.itemR(con, "rotation")
118                 col.itemR(con, "targetless")
119                 col.itemR(con, "stretch")
120                 
121         def FOLLOW_PATH(self, layout, con):
122                 self.target_template(layout, con)
123                 
124                 row = layout.row()
125                 row.itemR(con, "curve_follow")
126                 row.itemR(con, "offset")
127                 
128                 row = layout.row()
129                 row.itemL(text="Forward:")
130                 row.itemR(con, "forward", expand=True)
131                 
132                 row = layout.row()
133                 row.itemR(con, "up", text="Up")
134                 row.itemL()
135                 
136         def LIMIT_ROTATION(self, layout, con):
137                 
138                 split = layout.split()
139                 
140                 col = split.column()
141                 col.itemR(con, "use_limit_x")
142                 sub = col.column()
143                 sub.active = con.use_limit_x
144                 sub.itemR(con, "minimum_x", text="Min")
145                 sub.itemR(con, "maximum_x", text="Max")
146                 
147                 col = split.column()
148                 col.itemR(con, "use_limit_y")
149                 sub = col.column()
150                 sub.active = con.use_limit_y
151                 sub.itemR(con, "minimum_y", text="Min")
152                 sub.itemR(con, "maximum_y", text="Max")
153                 
154                 col = split.column()
155                 col.itemR(con, "use_limit_z")
156                 sub = col.column()
157                 sub.active = con.use_limit_z
158                 sub.itemR(con, "minimum_z", text="Min")
159                 sub.itemR(con, "maximum_z", text="Max")
160                 
161                 row = layout.row()
162                 row.itemR(con, "limit_transform")
163                 row.itemL()
164                 
165                 row = layout.row()
166                 row.itemL(text="Convert:")
167                 row.itemR(con, "owner_space", text="")
168                 
169         def LIMIT_LOCATION(self, layout, con):
170                 split = layout.split()
171                 
172                 col = split.column()
173                 col.itemR(con, "use_minimum_x")
174                 sub = col.column()
175                 sub.active = con.use_minimum_x
176                 sub.itemR(con, "minimum_x", text="")
177                 col.itemR(con, "use_maximum_x")
178                 sub = col.column()
179                 sub.active = con.use_maximum_x
180                 sub.itemR(con, "maximum_x", text="")
181                 
182                 col = split.column()
183                 col.itemR(con, "use_minimum_y")
184                 sub = col.column()
185                 sub.active = con.use_minimum_y
186                 sub.itemR(con, "minimum_y", text="")
187                 col.itemR(con, "use_maximum_y")
188                 sub = col.column()
189                 sub.active = con.use_maximum_y
190                 sub.itemR(con, "maximum_y", text="")
191                 
192                 col = split.column()
193                 col.itemR(con, "use_minimum_z")
194                 sub = col.column()
195                 sub.active = con.use_minimum_z
196                 sub.itemR(con, "minimum_z", text="")
197                 col.itemR(con, "use_maximum_z")
198                 sub = col.column()
199                 sub.active = con.use_maximum_z
200                 sub.itemR(con, "maximum_z", text="")
201         
202                 row = layout.row()
203                 row.itemR(con, "limit_transform")
204                 row.itemL()
205                 
206                 row = layout.row()
207                 row.itemL(text="Convert:")
208                 row.itemR(con, "owner_space", text="")
209                 
210         def LIMIT_SCALE(self, layout, con):
211                 split = layout.split()
212
213                 col = split.column()
214                 col.itemR(con, "use_minimum_x")
215                 sub = col.column()
216                 sub.active = con.use_minimum_x
217                 sub.itemR(con, "minimum_x", text="")
218                 col.itemR(con, "use_maximum_x")
219                 sub = col.column()
220                 sub.active = con.use_maximum_x
221                 sub.itemR(con, "maximum_x", text="")
222                 
223                 col = split.column()
224                 col.itemR(con, "use_minimum_y")
225                 sub = col.column()
226                 sub.active = con.use_minimum_y
227                 sub.itemR(con, "minimum_y", text="")
228                 col.itemR(con, "use_maximum_y")
229                 sub = col.column()
230                 sub.active = con.use_maximum_y
231                 sub.itemR(con, "maximum_y", text="")
232                 
233                 col = split.column()
234                 col.itemR(con, "use_minimum_z")
235                 sub = col.column()
236                 sub.active = con.use_minimum_z
237                 sub.itemR(con, "minimum_z", text="")
238                 col.itemR(con, "use_maximum_z")
239                 sub = col.column()
240                 sub.active = con.use_maximum_z
241                 sub.itemR(con, "maximum_z", text="")
242                 
243                 row = layout.row()
244                 row.itemR(con, "limit_transform")
245                 row.itemL()
246                 
247                 row = layout.row()
248                 row.itemL(text="Convert:")
249                 row.itemR(con, "owner_space", text="")
250         
251         def COPY_ROTATION(self, layout, con):
252                 self.target_template(layout, con)
253                 
254                 split = layout.split()
255                 
256                 col = split.column()
257                 col.itemR(con, "rotate_like_x", text="X")
258                 sub = col.column()
259                 sub.active = con.rotate_like_x
260                 sub.itemR(con, "invert_x", text="Invert")
261                 
262                 col = split.column()
263                 col.itemR(con, "rotate_like_y", text="Y")
264                 sub = col.column()
265                 sub.active = con.rotate_like_y
266                 sub.itemR(con, "invert_y", text="Invert")
267                 
268                 col = split.column()
269                 col.itemR(con, "rotate_like_z", text="Z")
270                 sub = col.column()
271                 sub.active = con.rotate_like_z
272                 sub.itemR(con, "invert_z", text="Invert")
273
274                 layout.itemR(con, "offset")
275                 
276                 self.space_template(layout, con)
277                 
278         def COPY_LOCATION(self, layout, con):
279                 self.target_template(layout, con)
280                 
281                 split = layout.split()
282                 
283                 col = split.column()
284                 col.itemR(con, "locate_like_x", text="X")
285                 sub = col.column()
286                 sub.active = con.locate_like_x
287                 sub.itemR(con, "invert_x", text="Invert")
288                 
289                 col = split.column()
290                 col.itemR(con, "locate_like_y", text="Y")
291                 sub = col.column()
292                 sub.active = con.locate_like_y
293                 sub.itemR(con, "invert_y", text="Invert")
294                 
295                 col = split.column()
296                 col.itemR(con, "locate_like_z", text="Z")
297                 sub = col.column()
298                 sub.active = con.locate_like_z
299                 sub.itemR(con, "invert_z", text="Invert")
300
301                 layout.itemR(con, "offset")
302                         
303                 self.space_template(layout, con)
304                 
305         def COPY_SCALE(self, layout, con):
306                 self.target_template(layout, con)
307                 
308                 row = layout.row(align=True)
309                 row.itemR(con, "size_like_x", text="X")
310                 row.itemR(con, "size_like_y", text="Y")
311                 row.itemR(con, "size_like_z", text="Z")
312
313                 layout.itemR(con, "offset")
314                 
315                 self.space_template(layout, con)
316                 
317         #def SCRIPT(self, layout, con):
318         
319         def ACTION(self, layout, con):
320                 self.target_template(layout, con)
321                 
322                 layout.itemR(con, "action")
323                 layout.itemR(con, "transform_channel")
324
325                 split = layout.split()
326         
327                 col = split.column(align=True)
328                 col.itemR(con, "start_frame", text="Start")
329                 col.itemR(con, "end_frame", text="End")
330                 
331                 col = split.column(align=True)
332                 col.itemR(con, "minimum", text="Min")
333                 col.itemR(con, "maximum", text="Max")
334                 
335                 row = layout.row()
336                 row.itemL(text="Convert:")
337                 row.itemR(con, "owner_space", text="")
338         
339         def LOCKED_TRACK(self, layout, con):
340                 self.target_template(layout, con)
341                 
342                 row = layout.row()
343                 row.itemL(text="To:")
344                 row.itemR(con, "track", expand=True)
345                 
346                 row = layout.row()
347                 row.itemL(text="Lock:")
348                 row.itemR(con, "locked", expand=True)
349                 
350         def LIMIT_DISTANCE(self, layout, con):
351                 self.target_template(layout, con)
352                 
353                 col = layout.column(align=True);
354                 col.itemR(con, "distance")
355                 col.itemO("constraint.limitdistance_reset")
356                 
357                 row = layout.row()
358                 row.itemL(text="Clamp Region:")
359                 row.itemR(con, "limit_mode", text="")
360                 
361         def STRETCH_TO(self, layout, con):
362                 self.target_template(layout, con)
363                 
364                 col = layout.column(align=True)
365                 col.itemR(con, "original_length", text="Rest Length")
366                 col.itemO("constraint.stretchto_reset")
367                 
368                 col = layout.column()
369                 col.itemR(con, "bulge", text="Volume Variation")
370                 
371                 row = layout.row()
372                 row.itemL(text="Volume:")
373                 row.itemR(con, "volume", expand=True)
374                 row.itemL(text="Plane:")
375                 row.itemR(con, "keep_axis", expand=True)
376                 
377         def FLOOR(self, layout, con):
378                 self.target_template(layout, con)
379                 
380                 row = layout.row()
381                 row.itemR(con, "sticky")
382                 row.itemR(con, "use_rotation")
383                 
384                 layout.itemR(con, "offset")
385                 
386                 row = layout.row()
387                 row.itemL(text="Min/Max:")
388                 row.itemR(con, "floor_location", expand=True)
389                 
390         def RIGID_BODY_JOINT(self, layout, con):
391                 self.target_template(layout, con)
392                 
393                 layout.itemR(con, "pivot_type")
394                 layout.itemR(con, "child")
395                 
396                 row = layout.row()
397                 row.itemR(con, "disable_linked_collision", text="No Collision")
398                 row.itemR(con, "draw_pivot")
399                 
400                 split = layout.split()
401                 
402                 col = split.column()
403                 col.itemR(con, "pivot_x")
404                 col.itemR(con, "pivot_y")
405                 col.itemR(con, "pivot_z")
406                 
407                 col = split.column()
408                 col.itemR(con, "axis_x")
409                 col.itemR(con, "axis_y")
410                 col.itemR(con, "axis_z")
411                 
412                 #Missing: Limit arrays (not wrapped in RNA yet) 
413         
414         def CLAMP_TO(self, layout, con):
415                 self.target_template(layout, con)
416                 
417                 row = layout.row()
418                 row.itemL(text="Main Axis:")
419                 row.itemR(con, "main_axis", expand=True)
420                 
421                 row = layout.row()
422                 row.itemR(con, "cyclic")
423                 
424         def TRANSFORM(self, layout, con):
425                 self.target_template(layout, con)
426                 
427                 layout.itemR(con, "extrapolate_motion", text="Extrapolate")
428                 
429                 split = layout.split()
430                 
431                 col = split.column()
432                 col.itemL(text="Source:")
433                 col.row().itemR(con, "map_from", expand=True)
434                 
435                 sub = col.row(align=True)
436                 sub.itemL(text="X:")
437                 sub.itemR(con, "from_min_x", text="")
438                 sub.itemR(con, "from_max_x", text="")
439                 
440                 sub = col.row(align=True)
441                 sub.itemL(text="Y:")
442                 sub.itemR(con, "from_min_y", text="")
443                 sub.itemR(con, "from_max_y", text="")
444                 
445                 sub = col.row(align=True)
446                 sub.itemL(text="Z:")
447                 sub.itemR(con, "from_min_z", text="")
448                 sub.itemR(con, "from_max_z", text="")
449                 
450                 split = layout.split()
451                 
452                 col = split.column()
453                 col.itemL(text="Destination:")
454                 col.row().itemR(con, "map_to", expand=True)
455
456                 sub = col.row(align=True)
457                 sub.itemR(con, "map_to_x_from", text="")
458                 sub.itemR(con, "to_min_x", text="")
459                 sub.itemR(con, "to_max_x", text="")
460                 
461                 sub = col.row(align=True)
462                 sub.itemR(con, "map_to_y_from", text="")
463                 sub.itemR(con, "to_min_y", text="")
464                 sub.itemR(con, "to_max_y", text="")
465                 
466                 sub = col.row(align=True)
467                 sub.itemR(con, "map_to_z_from", text="")
468                 sub.itemR(con, "to_min_z", text="")
469                 sub.itemR(con, "to_max_z", text="")
470                 
471                 self.space_template(layout, con)
472                 
473         def SHRINKWRAP (self, layout, con):
474                 self.target_template(layout, con)
475                 
476                 layout.itemR(con, "distance")
477                 layout.itemR(con, "shrinkwrap_type")
478                 
479                 if con.shrinkwrap_type == "PROJECT":
480                         row = layout.row(align=True)
481                         row.itemR(con, "axis_x")
482                         row.itemR(con, "axis_y")
483                         row.itemR(con, "axis_z")
484                 
485 class OBJECT_PT_constraints(ConstraintButtonsPanel):
486         __label__ = "Constraints"
487         __context__ = "constraint"
488
489         def poll(self, context):
490                 return (context.object)
491                 
492         def draw(self, context):
493                 layout = self.layout
494                 ob = context.object
495
496                 row = layout.row()
497                 row.item_menu_enumO("object.constraint_add", "type")
498                 row.itemL();
499
500                 for con in ob.constraints:
501                         self.draw_constraint(con)
502
503 class BONE_PT_constraints(ConstraintButtonsPanel):
504         __label__ = "Constraints"
505         __context__ = "bone"
506
507         def poll(self, context):
508                 ob = context.object
509                 return (ob and ob.type == 'ARMATURE' and context.bone)
510                 
511         def draw(self, context):
512                 layout = self.layout
513                 
514                 ob = context.object
515                 pchan = ob.pose.pose_channels[context.bone.name]
516
517                 row = layout.row()
518                 row.item_menu_enumO("pose.constraint_add", "type")
519                 row.itemL();
520
521                 for con in pchan.constraints:
522                         self.draw_constraint(con)
523
524 bpy.types.register(OBJECT_PT_constraints)
525 bpy.types.register(BONE_PT_constraints)