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