made scripts pass the pep8 test (though not fully pep8 yet)
[blender.git] / release / scripts / ui / properties_object_constraint.py
1 # This software is distributable under the terms of the GNU
2 # General Public License (GPL) v2, the text of which can be found at
3 # http://www.gnu.org/copyleft/gpl.html. Installing, importing or otherwise
4 # using this module constitutes acceptance of the terms of this License.
5
6 # <pep8 compliant>
7 import bpy
8
9
10 class ConstraintButtonsPanel(bpy.types.Panel):
11     bl_space_type = 'PROPERTIES'
12     bl_region_type = 'WINDOW'
13     bl_context = "constraint"
14
15     def draw_constraint(self, context, con):
16         layout = self.layout
17
18         box = layout.template_constraint(con)
19
20         if box:
21             # match enum type to our functions, avoids a lookup table.
22             getattr(self, con.type)(context, box, con)
23
24             # show/key buttons here are most likely obsolete now, with
25             # keyframing functionality being part of every button
26             if con.type not in ('RIGID_BODY_JOINT', 'NULL'):
27                 box.itemR(con, "influence")
28
29     def space_template(self, layout, con, target=True, owner=True):
30         if target or owner:
31             row = layout.row()
32
33             row.itemL(text="Convert:")
34
35             if target:
36                 row.itemR(con, "target_space", text="")
37
38             if target and owner:
39                 row.itemL(icon='ICON_ARROW_LEFTRIGHT')
40
41             if owner:
42                 row.itemR(con, "owner_space", text="")
43
44     def target_template(self, layout, con, subtargets=True):
45         layout.itemR(con, "target") # XXX limiting settings for only 'curves' or some type of object
46
47         if con.target and subtargets:
48             if con.target.type == 'ARMATURE':
49                 layout.item_pointerR(con, "subtarget", con.target.data, "bones", text="Bone")
50
51                 if con.type == 'COPY_LOCATION':
52                     row = layout.row()
53                     row.itemL(text="Head/Tail:")
54                     row.itemR(con, "head_tail", text="")
55             elif con.target.type in ('MESH', 'LATTICE'):
56                 layout.item_pointerR(con, "subtarget", con.target, "vertex_groups", text="Vertex Group")
57
58     def ik_template(self, layout, con):
59         # only used for iTaSC
60         layout.itemR(con, "pole_target")
61
62         if con.pole_target and con.pole_target.type == 'ARMATURE':
63             layout.item_pointerR(con, "pole_subtarget", con.pole_target.data, "bones", text="Bone")
64
65         if con.pole_target:
66             row = layout.row()
67             row.itemL()
68             row.itemR(con, "pole_angle")
69
70         split = layout.split(percentage=0.33)
71         col = split.column()
72         col.itemR(con, "tail")
73         col.itemR(con, "stretch")
74
75         col = split.column()
76         col.itemR(con, "chain_length")
77         col.itemR(con, "targetless")
78
79     def CHILD_OF(self, context, layout, con):
80         self.target_template(layout, con)
81
82         split = layout.split()
83
84         col = split.column()
85         col.itemL(text="Location:")
86         col.itemR(con, "locationx", text="X")
87         col.itemR(con, "locationy", text="Y")
88         col.itemR(con, "locationz", text="Z")
89
90         col = split.column()
91         col.itemL(text="Rotation:")
92         col.itemR(con, "rotationx", text="X")
93         col.itemR(con, "rotationy", text="Y")
94         col.itemR(con, "rotationz", text="Z")
95
96         col = split.column()
97         col.itemL(text="Scale:")
98         col.itemR(con, "sizex", text="X")
99         col.itemR(con, "sizey", text="Y")
100         col.itemR(con, "sizez", text="Z")
101
102         row = layout.row()
103         row.itemO("constraint.childof_set_inverse")
104         row.itemO("constraint.childof_clear_inverse")
105
106     def TRACK_TO(self, context, layout, con):
107         self.target_template(layout, con)
108
109         row = layout.row()
110         row.itemL(text="To:")
111         row.itemR(con, "track", expand=True)
112
113         row = layout.row()
114         #row.itemR(con, "up", text="Up", expand=True) # XXX: up and expand don't play nice together
115         row.itemR(con, "up", text="Up")
116         row.itemR(con, "target_z")
117
118         self.space_template(layout, con)
119
120     def IK(self, context, layout, con):
121         if context.object.pose.ik_solver == "ITASC":
122             layout.itemR(con, "ik_type")
123             getattr(self, "IK_" + con.ik_type)(context, layout, con)
124         else:
125             # Legacy IK constraint
126             self.target_template(layout, con)
127             layout.itemR(con, "pole_target")
128
129             if con.pole_target and con.pole_target.type == 'ARMATURE':
130                 layout.item_pointerR(con, "pole_subtarget", con.pole_target.data, "bones", text="Bone")
131
132             if con.pole_target:
133                 row = layout.row()
134                 row.itemL()
135                 row.itemR(con, "pole_angle")
136
137             split = layout.split()
138             col = split.column()
139             col.itemR(con, "tail")
140             col.itemR(con, "stretch")
141
142             col = split.column()
143             col.itemR(con, "iterations")
144             col.itemR(con, "chain_length")
145
146             split = layout.split()
147             col = split.column()
148             col.itemL()
149             col.itemR(con, "targetless")
150             col.itemR(con, "rotation")
151
152             col = split.column()
153             col.itemL(text="Weight:")
154             col.itemR(con, "weight", text="Position", slider=True)
155             sub = col.column()
156             sub.active = con.rotation
157             sub.itemR(con, "orient_weight", text="Rotation", slider=True)
158
159     def IK_COPY_POSE(self, context, layout, con):
160         self.target_template(layout, con)
161         self.ik_template(layout, con)
162
163         row = layout.row()
164         row.itemL(text="Axis Ref:")
165         row.itemR(con, "axis_reference", expand=True)
166         split = layout.split(percentage=0.33)
167         split.row().itemR(con, "position")
168         row = split.row()
169         row.itemR(con, "weight", text="Weight", slider=True)
170         row.active = con.position
171         split = layout.split(percentage=0.33)
172         row = split.row()
173         row.itemL(text="Lock:")
174         row = split.row()
175         row.itemR(con, "pos_lock_x", text="X")
176         row.itemR(con, "pos_lock_y", text="Y")
177         row.itemR(con, "pos_lock_z", text="Z")
178         split.active = con.position
179
180         split = layout.split(percentage=0.33)
181         split.row().itemR(con, "rotation")
182         row = split.row()
183         row.itemR(con, "orient_weight", text="Weight", slider=True)
184         row.active = con.rotation
185         split = layout.split(percentage=0.33)
186         row = split.row()
187         row.itemL(text="Lock:")
188         row = split.row()
189         row.itemR(con, "rot_lock_x", text="X")
190         row.itemR(con, "rot_lock_y", text="Y")
191         row.itemR(con, "rot_lock_z", text="Z")
192         split.active = con.rotation
193
194     def IK_DISTANCE(self, context, layout, con):
195         self.target_template(layout, con)
196         self.ik_template(layout, con)
197
198         layout.itemR(con, "limit_mode")
199         row = layout.row()
200         row.itemR(con, "weight", text="Weight", slider=True)
201         row.itemR(con, "distance", text="Distance", slider=True)
202
203     def FOLLOW_PATH(self, context, layout, con):
204         self.target_template(layout, con)
205
206         split = layout.split()
207
208         col = split.column()
209         col.itemR(con, "use_curve_follow")
210         col.itemR(con, "use_curve_radius")
211
212         col = split.column()
213         col.itemR(con, "use_fixed_position")
214         if con.use_fixed_position:
215             col.itemR(con, "offset_factor", text="Offset")
216         else:
217             col.itemR(con, "offset")
218
219         row = layout.row()
220         row.itemL(text="Forward:")
221         row.itemR(con, "forward", expand=True)
222
223         row = layout.row()
224         row.itemR(con, "up", text="Up")
225         row.itemL()
226
227     def LIMIT_ROTATION(self, context, layout, con):
228
229         split = layout.split()
230
231         col = split.column()
232         col.itemR(con, "use_limit_x")
233         sub = col.column()
234         sub.active = con.use_limit_x
235         sub.itemR(con, "minimum_x", text="Min")
236         sub.itemR(con, "maximum_x", text="Max")
237
238         col = split.column()
239         col.itemR(con, "use_limit_y")
240         sub = col.column()
241         sub.active = con.use_limit_y
242         sub.itemR(con, "minimum_y", text="Min")
243         sub.itemR(con, "maximum_y", text="Max")
244
245         col = split.column()
246         col.itemR(con, "use_limit_z")
247         sub = col.column()
248         sub.active = con.use_limit_z
249         sub.itemR(con, "minimum_z", text="Min")
250         sub.itemR(con, "maximum_z", text="Max")
251
252         row = layout.row()
253         row.itemR(con, "limit_transform")
254         row.itemL()
255
256         row = layout.row()
257         row.itemL(text="Convert:")
258         row.itemR(con, "owner_space", text="")
259
260     def LIMIT_LOCATION(self, context, layout, con):
261         split = layout.split()
262
263         col = split.column()
264         col.itemR(con, "use_minimum_x")
265         sub = col.column()
266         sub.active = con.use_minimum_x
267         sub.itemR(con, "minimum_x", text="")
268         col.itemR(con, "use_maximum_x")
269         sub = col.column()
270         sub.active = con.use_maximum_x
271         sub.itemR(con, "maximum_x", text="")
272
273         col = split.column()
274         col.itemR(con, "use_minimum_y")
275         sub = col.column()
276         sub.active = con.use_minimum_y
277         sub.itemR(con, "minimum_y", text="")
278         col.itemR(con, "use_maximum_y")
279         sub = col.column()
280         sub.active = con.use_maximum_y
281         sub.itemR(con, "maximum_y", text="")
282
283         col = split.column()
284         col.itemR(con, "use_minimum_z")
285         sub = col.column()
286         sub.active = con.use_minimum_z
287         sub.itemR(con, "minimum_z", text="")
288         col.itemR(con, "use_maximum_z")
289         sub = col.column()
290         sub.active = con.use_maximum_z
291         sub.itemR(con, "maximum_z", text="")
292
293         row = layout.row()
294         row.itemR(con, "limit_transform")
295         row.itemL()
296
297         row = layout.row()
298         row.itemL(text="Convert:")
299         row.itemR(con, "owner_space", text="")
300
301     def LIMIT_SCALE(self, context, layout, con):
302         split = layout.split()
303
304         col = split.column()
305         col.itemR(con, "use_minimum_x")
306         sub = col.column()
307         sub.active = con.use_minimum_x
308         sub.itemR(con, "minimum_x", text="")
309         col.itemR(con, "use_maximum_x")
310         sub = col.column()
311         sub.active = con.use_maximum_x
312         sub.itemR(con, "maximum_x", text="")
313
314         col = split.column()
315         col.itemR(con, "use_minimum_y")
316         sub = col.column()
317         sub.active = con.use_minimum_y
318         sub.itemR(con, "minimum_y", text="")
319         col.itemR(con, "use_maximum_y")
320         sub = col.column()
321         sub.active = con.use_maximum_y
322         sub.itemR(con, "maximum_y", text="")
323
324         col = split.column()
325         col.itemR(con, "use_minimum_z")
326         sub = col.column()
327         sub.active = con.use_minimum_z
328         sub.itemR(con, "minimum_z", text="")
329         col.itemR(con, "use_maximum_z")
330         sub = col.column()
331         sub.active = con.use_maximum_z
332         sub.itemR(con, "maximum_z", text="")
333
334         row = layout.row()
335         row.itemR(con, "limit_transform")
336         row.itemL()
337
338         row = layout.row()
339         row.itemL(text="Convert:")
340         row.itemR(con, "owner_space", text="")
341
342     def COPY_ROTATION(self, context, layout, con):
343         self.target_template(layout, con)
344
345         split = layout.split()
346
347         col = split.column()
348         col.itemR(con, "rotate_like_x", text="X")
349         sub = col.column()
350         sub.active = con.rotate_like_x
351         sub.itemR(con, "invert_x", text="Invert")
352
353         col = split.column()
354         col.itemR(con, "rotate_like_y", text="Y")
355         sub = col.column()
356         sub.active = con.rotate_like_y
357         sub.itemR(con, "invert_y", text="Invert")
358
359         col = split.column()
360         col.itemR(con, "rotate_like_z", text="Z")
361         sub = col.column()
362         sub.active = con.rotate_like_z
363         sub.itemR(con, "invert_z", text="Invert")
364
365         layout.itemR(con, "offset")
366
367         self.space_template(layout, con)
368
369     def COPY_LOCATION(self, context, layout, con):
370         self.target_template(layout, con)
371
372         split = layout.split()
373
374         col = split.column()
375         col.itemR(con, "locate_like_x", text="X")
376         sub = col.column()
377         sub.active = con.locate_like_x
378         sub.itemR(con, "invert_x", text="Invert")
379
380         col = split.column()
381         col.itemR(con, "locate_like_y", text="Y")
382         sub = col.column()
383         sub.active = con.locate_like_y
384         sub.itemR(con, "invert_y", text="Invert")
385
386         col = split.column()
387         col.itemR(con, "locate_like_z", text="Z")
388         sub = col.column()
389         sub.active = con.locate_like_z
390         sub.itemR(con, "invert_z", text="Invert")
391
392         layout.itemR(con, "offset")
393
394         self.space_template(layout, con)
395
396     def COPY_SCALE(self, context, layout, con):
397         self.target_template(layout, con)
398
399         row = layout.row(align=True)
400         row.itemR(con, "size_like_x", text="X")
401         row.itemR(con, "size_like_y", text="Y")
402         row.itemR(con, "size_like_z", text="Z")
403
404         layout.itemR(con, "offset")
405
406         self.space_template(layout, con)
407
408     #def SCRIPT(self, context, layout, con):
409
410     def ACTION(self, context, layout, con):
411         self.target_template(layout, con)
412
413         layout.itemR(con, "action")
414         layout.itemR(con, "transform_channel")
415
416         split = layout.split()
417
418         col = split.column(align=True)
419         col.itemR(con, "start_frame", text="Start")
420         col.itemR(con, "end_frame", text="End")
421
422         col = split.column(align=True)
423         col.itemR(con, "minimum", text="Min")
424         col.itemR(con, "maximum", text="Max")
425
426         row = layout.row()
427         row.itemL(text="Convert:")
428         row.itemR(con, "owner_space", text="")
429
430     def LOCKED_TRACK(self, context, layout, con):
431         self.target_template(layout, con)
432
433         row = layout.row()
434         row.itemL(text="To:")
435         row.itemR(con, "track", expand=True)
436
437         row = layout.row()
438         row.itemL(text="Lock:")
439         row.itemR(con, "locked", expand=True)
440
441     def LIMIT_DISTANCE(self, context, layout, con):
442         self.target_template(layout, con)
443
444         col = layout.column(align=True)
445         col.itemR(con, "distance")
446         col.itemO("constraint.limitdistance_reset")
447
448         row = layout.row()
449         row.itemL(text="Clamp Region:")
450         row.itemR(con, "limit_mode", text="")
451
452     def STRETCH_TO(self, context, layout, con):
453         self.target_template(layout, con)
454
455         row = layout.row()
456         row.itemR(con, "original_length", text="Rest Length")
457         row.itemO("constraint.stretchto_reset", text="Reset")
458
459         col = layout.column()
460         col.itemR(con, "bulge", text="Volume Variation")
461
462         row = layout.row()
463         row.itemL(text="Volume:")
464         row.itemR(con, "volume", expand=True)
465         row.itemL(text="Plane:")
466         row.itemR(con, "keep_axis", expand=True)
467
468     def FLOOR(self, context, layout, con):
469         self.target_template(layout, con)
470
471         row = layout.row()
472         row.itemR(con, "sticky")
473         row.itemR(con, "use_rotation")
474
475         layout.itemR(con, "offset")
476
477         row = layout.row()
478         row.itemL(text="Min/Max:")
479         row.itemR(con, "floor_location", expand=True)
480
481     def RIGID_BODY_JOINT(self, context, layout, con):
482         self.target_template(layout, con)
483
484         layout.itemR(con, "pivot_type")
485         layout.itemR(con, "child")
486
487         row = layout.row()
488         row.itemR(con, "disable_linked_collision", text="No Collision")
489         row.itemR(con, "draw_pivot", text="Display Pivot")
490
491         split = layout.split()
492
493         col = split.column(align=True)
494         col.itemL(text="Pivot:")
495         col.itemR(con, "pivot_x", text="X")
496         col.itemR(con, "pivot_y", text="Y")
497         col.itemR(con, "pivot_z", text="Z")
498
499         col = split.column(align=True)
500         col.itemL(text="Axis:")
501         col.itemR(con, "axis_x", text="X")
502         col.itemR(con, "axis_y", text="Y")
503         col.itemR(con, "axis_z", text="Z")
504
505         #Missing: Limit arrays (not wrapped in RNA yet)
506
507     def CLAMP_TO(self, context, layout, con):
508         self.target_template(layout, con)
509
510         row = layout.row()
511         row.itemL(text="Main Axis:")
512         row.itemR(con, "main_axis", expand=True)
513
514         row = layout.row()
515         row.itemR(con, "cyclic")
516
517     def TRANSFORM(self, context, layout, con):
518         self.target_template(layout, con)
519
520         layout.itemR(con, "extrapolate_motion", text="Extrapolate")
521
522         split = layout.split()
523
524         col = split.column()
525         col.itemL(text="Source:")
526         col.row().itemR(con, "map_from", expand=True)
527
528         sub = col.row(align=True)
529         sub.itemL(text="X:")
530         sub.itemR(con, "from_min_x", text="")
531         sub.itemR(con, "from_max_x", text="")
532
533         sub = col.row(align=True)
534         sub.itemL(text="Y:")
535         sub.itemR(con, "from_min_y", text="")
536         sub.itemR(con, "from_max_y", text="")
537
538         sub = col.row(align=True)
539         sub.itemL(text="Z:")
540         sub.itemR(con, "from_min_z", text="")
541         sub.itemR(con, "from_max_z", text="")
542
543         split = layout.split()
544
545         col = split.column()
546         col.itemL(text="Destination:")
547         col.row().itemR(con, "map_to", expand=True)
548
549         sub = col.row(align=True)
550         sub.itemR(con, "map_to_x_from", text="")
551         sub.itemR(con, "to_min_x", text="")
552         sub.itemR(con, "to_max_x", text="")
553
554         sub = col.row(align=True)
555         sub.itemR(con, "map_to_y_from", text="")
556         sub.itemR(con, "to_min_y", text="")
557         sub.itemR(con, "to_max_y", text="")
558
559         sub = col.row(align=True)
560         sub.itemR(con, "map_to_z_from", text="")
561         sub.itemR(con, "to_min_z", text="")
562         sub.itemR(con, "to_max_z", text="")
563
564         self.space_template(layout, con)
565
566     def SHRINKWRAP(self, context, layout, con):
567         self.target_template(layout, con)
568
569         layout.itemR(con, "distance")
570         layout.itemR(con, "shrinkwrap_type")
571
572         if con.shrinkwrap_type == 'PROJECT':
573             row = layout.row(align=True)
574             row.itemR(con, "axis_x")
575             row.itemR(con, "axis_y")
576             row.itemR(con, "axis_z")
577
578     def DAMPED_TRACK(self, context, layout, con):
579         self.target_template(layout, con)
580
581         row = layout.row()
582         row.itemL(text="To:")
583         row.itemR(con, "track", expand=True)
584
585
586 class OBJECT_PT_constraints(ConstraintButtonsPanel):
587     bl_label = "Constraints"
588     bl_context = "constraint"
589
590     def poll(self, context):
591         return (context.object)
592
593     def draw(self, context):
594         layout = self.layout
595         ob = context.object
596
597         row = layout.row()
598         row.item_menu_enumO("object.constraint_add", "type")
599         row.itemL()
600
601         for con in ob.constraints:
602             self.draw_constraint(context, con)
603
604
605 class BONE_PT_inverse_kinematics(ConstraintButtonsPanel):
606     bl_label = "Inverse Kinematics"
607     bl_default_closed = True
608     bl_context = "bone_constraint"
609
610     def poll(self, context):
611         ob = context.object
612         bone = context.bone
613
614         if ob and bone:
615             pchan = ob.pose.pose_channels[bone.name]
616             return pchan.has_ik
617
618         return False
619
620     def draw(self, context):
621         layout = self.layout
622
623         ob = context.object
624         bone = context.bone
625         pchan = ob.pose.pose_channels[bone.name]
626
627         row = layout.row()
628         row.itemR(ob.pose, "ik_solver")
629
630         split = layout.split(percentage=0.25)
631         split.itemR(pchan, "ik_dof_x", text="X")
632         row = split.row()
633         row.itemR(pchan, "ik_stiffness_x", text="Stiffness", slider=True)
634         row.active = pchan.ik_dof_x
635
636         split = layout.split(percentage=0.25)
637         row = split.row()
638         row.itemR(pchan, "ik_limit_x", text="Limit")
639         row.active = pchan.ik_dof_x
640         row = split.row(align=True)
641         row.itemR(pchan, "ik_min_x", text="")
642         row.itemR(pchan, "ik_max_x", text="")
643         row.active = pchan.ik_dof_x and pchan.ik_limit_x
644
645         split = layout.split(percentage=0.25)
646         split.itemR(pchan, "ik_dof_y", text="Y")
647         row = split.row()
648         row.itemR(pchan, "ik_stiffness_y", text="Stiffness", slider=True)
649         row.active = pchan.ik_dof_y
650
651         split = layout.split(percentage=0.25)
652         row = split.row()
653         row.itemR(pchan, "ik_limit_y", text="Limit")
654         row.active = pchan.ik_dof_y
655         row = split.row(align=True)
656         row.itemR(pchan, "ik_min_y", text="")
657         row.itemR(pchan, "ik_max_y", text="")
658         row.active = pchan.ik_dof_y and pchan.ik_limit_y
659
660         split = layout.split(percentage=0.25)
661         split.itemR(pchan, "ik_dof_z", text="Z")
662         row = split.row()
663         row.itemR(pchan, "ik_stiffness_z", text="Stiffness", slider=True)
664         row.active = pchan.ik_dof_z
665
666         split = layout.split(percentage=0.25)
667         row = split.row()
668         row.itemR(pchan, "ik_limit_z", text="Limit")
669         row.active = pchan.ik_dof_z
670         row = split.row(align=True)
671         row.itemR(pchan, "ik_min_z", text="")
672         row.itemR(pchan, "ik_max_z", text="")
673         row.active = pchan.ik_dof_z and pchan.ik_limit_z
674         split = layout.split()
675         split.itemR(pchan, "ik_stretch", text="Stretch", slider=True)
676         split.itemL()
677
678         if ob.pose.ik_solver == "ITASC":
679             row = layout.row()
680             row.itemR(pchan, "ik_rot_control", text="Control Rotation")
681             row.itemR(pchan, "ik_rot_weight", text="Weight", slider=True)
682             # not supported yet
683             #row = layout.row()
684             #row.itemR(pchan, "ik_lin_control", text="Joint Size")
685             #row.itemR(pchan, "ik_lin_weight", text="Weight", slider=True)
686
687
688 class BONE_PT_iksolver_itasc(ConstraintButtonsPanel):
689     bl_label = "iTaSC parameters"
690     bl_default_closed = True
691     bl_context = "bone_constraint"
692
693     def poll(self, context):
694         ob = context.object
695         bone = context.bone
696
697         if ob and bone:
698             pchan = ob.pose.pose_channels[bone.name]
699             return pchan.has_ik and ob.pose.ik_solver == "ITASC" and ob.pose.ik_param
700
701         return False
702
703     def draw(self, context):
704         layout = self.layout
705
706         ob = context.object
707         itasc = ob.pose.ik_param
708
709         layout.itemR(itasc, "mode", expand=True)
710         simulation = itasc.mode == "SIMULATION"
711         if simulation:
712             layout.itemL(text="Reiteration:")
713             layout.itemR(itasc, "reiteration", expand=True)
714
715         flow = layout.column_flow()
716         flow.itemR(itasc, "precision", text="Prec")
717         flow.itemR(itasc, "num_iter", text="Iter")
718         flow.active = not simulation or itasc.reiteration != "NEVER"
719
720         if simulation:
721             layout.itemR(itasc, "auto_step")
722             row = layout.row()
723             if itasc.auto_step:
724                 row.itemR(itasc, "min_step", text="Min")
725                 row.itemR(itasc, "max_step", text="Max")
726             else:
727                 row.itemR(itasc, "num_step")
728
729         layout.itemR(itasc, "solver")
730         if simulation:
731             layout.itemR(itasc, "feedback")
732             layout.itemR(itasc, "max_velocity")
733         if itasc.solver == "DLS":
734             row = layout.row()
735             row.itemR(itasc, "dampmax", text="Damp", slider=True)
736             row.itemR(itasc, "dampeps", text="Eps", slider=True)
737
738
739 class BONE_PT_constraints(ConstraintButtonsPanel):
740     bl_label = "Constraints"
741     bl_context = "bone_constraint"
742
743     def poll(self, context):
744         ob = context.object
745         return (ob and ob.type == 'ARMATURE' and context.bone)
746
747     def draw(self, context):
748         layout = self.layout
749
750         ob = context.object
751         pchan = ob.pose.pose_channels[context.bone.name]
752
753         row = layout.row()
754         row.item_menu_enumO("pose.constraint_add", "type")
755         row.itemL()
756
757         for con in pchan.constraints:
758             self.draw_constraint(context, con)
759
760 bpy.types.register(OBJECT_PT_constraints)
761 bpy.types.register(BONE_PT_iksolver_itasc)
762 bpy.types.register(BONE_PT_inverse_kinematics)
763 bpy.types.register(BONE_PT_constraints)