6702b745c1e9fb858c8fafd8446c7725d474b538
[blender.git] / source / blender / src / buttons_object.c
1 /**
2  * $Id: 
3  *
4  * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License
8  * as published by the Free Software Foundation; either version 2
9  * of the License, or (at your option) any later version. The Blender
10  * Foundation also sells licenses for use in proprietary software under
11  * the Blender License.  See http://www.blender.org/BL/ for information
12  * about this.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program; if not, write to the Free Software Foundation,
21  * Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
22  *
23  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
24  * All rights reserved.
25  *
26  * The Original Code is: all of this file.
27  *
28  * Contributor(s): none yet.
29  *
30  * ***** END GPL/BL DUAL LICENSE BLOCK *****
31  */
32
33 #include <time.h>
34 #include <math.h>
35 #include <stdlib.h>
36 #include <string.h>
37
38 #ifdef HAVE_CONFIG_H
39 #include <config.h>
40 #endif
41
42 #ifdef WIN32
43 #include "BLI_winstuff.h"
44 #endif
45
46 #include "MEM_guardedalloc.h"
47 #include "DNA_screen_types.h"
48 #include "DNA_space_types.h"
49 #include "DNA_scene_types.h"
50
51 #include "BKE_global.h"
52 #include "BKE_main.h"
53 #include "BKE_library.h"
54
55 #include "BLI_blenlib.h"
56 #include "BLI_arithb.h"
57
58 #include "BSE_filesel.h"
59
60 #include "BIF_gl.h"
61 #include "BIF_graphics.h"
62 #include "BIF_keyval.h"
63 #include "BIF_mainqueue.h"
64 #include "BIF_resources.h"
65 #include "BIF_screen.h"
66 #include "BIF_mywindow.h"
67 #include "BIF_space.h"
68 #include "BIF_glutil.h"
69 #include "BIF_interface.h"
70 #include "BIF_toolbox.h"
71 #include "BIF_editmesh.h"
72 #include "BDR_editcurve.h"
73 #include "BDR_editface.h"
74 #include "BDR_drawobject.h"
75 #include "BIF_butspace.h"
76
77 #include "mydevice.h"
78 #include "blendef.h"
79
80 /* -----includes for this file specific----- */
81
82
83 #include "DNA_action_types.h"
84 #include "DNA_armature_types.h"
85 #include "DNA_camera_types.h"
86 #include "DNA_constraint_types.h"
87 #include "DNA_curve_types.h"
88 #include "DNA_effect_types.h"
89 #include "DNA_group_types.h"
90 #include "DNA_ika_types.h"
91 #include "DNA_image_types.h"
92 #include "DNA_key_types.h"
93 #include "DNA_lamp_types.h"
94 #include "DNA_lattice_types.h"
95 #include "DNA_material_types.h"
96 #include "DNA_meta_types.h"
97 #include "DNA_mesh_types.h"
98 #include "DNA_object_types.h"
99 #include "DNA_radio_types.h"
100 #include "DNA_screen_types.h"
101 #include "DNA_sound_types.h"
102 #include "DNA_texture_types.h"
103 #include "DNA_userdef_types.h"
104 #include "DNA_vfont_types.h"
105 #include "DNA_view3d_types.h"
106 #include "DNA_world_types.h"
107
108 #include "BKE_anim.h"
109 #include "BKE_armature.h"
110 #include "BKE_constraint.h"
111 #include "BKE_curve.h"
112 #include "BKE_displist.h"
113 #include "BKE_effect.h"
114 #include "BKE_font.h"
115 #include "BKE_ika.h"
116 #include "BKE_image.h"
117 #include "BKE_ipo.h"
118 #include "BKE_lattice.h"
119 #include "BKE_material.h"
120 #include "BKE_mball.h"
121 #include "BKE_mesh.h"
122 #include "BKE_object.h"
123 #include "BKE_sound.h"
124 #include "BKE_texture.h"
125 #include "BKE_utildefines.h"
126
127 #include "BIF_editconstraint.h"
128 #include "BSE_editipo.h"
129 #include "BDR_editobject.h"
130
131 #include "butspace.h" // own module
132
133 static float prspeed=0.0;
134 float prlen=0.0;
135
136
137
138 /* ********************* CONSTRAINT ***************************** */
139
140 static void add_influence_key_to_constraint_func (void *arg1v, void *unused)
141 {
142         bConstraint *con = arg1v;
143         add_influence_key_to_constraint(con);
144 }
145 static void activate_constraint_ipo_func (void *arg1v, void *unused)
146 {
147
148         bConstraint *con = arg1v;
149         bConstraintChannel *chan;
150         ListBase *conbase;
151
152         get_constraint_client(NULL, NULL, NULL);
153
154         conbase = get_constraint_client_channels(1);
155
156         if (!conbase)
157                 return;
158
159         /* See if this list already has an appropriate channel */
160         chan = find_constraint_channel(conbase, con->name);
161
162         if (!chan){
163                 /* Add a new constraint channel */
164                 chan = add_new_constraint_channel(con->name);
165                 BLI_addtail(conbase, chan);
166         }
167
168         /* Ensure there is an ipo to display */
169         if (!chan->ipo){
170                 chan->ipo = add_ipo(con->name, IPO_CO);
171         }
172
173         /* Make this the active channel */
174         OBACT->activecon = chan;
175
176         allqueue(REDRAWIPO, 0);
177         allqueue(REDRAWNLA, 0);
178 }
179
180 static void del_constraint_func (void *arg1v, void *arg2v)
181 {
182         bConstraint *con= arg1v;
183         Object *ob;
184
185         ListBase *lb= arg2v;
186         
187         ob=OBACT;
188         
189         if (ob->activecon && !strcmp(ob->activecon->name, con->name))
190                 ob->activecon = NULL;
191
192         free_constraint_data (con);
193
194         BLI_freelinkN(lb, con);
195
196         allqueue(REDRAWBUTSOBJECT, 0);
197         allqueue(REDRAWIPO, 0); 
198
199 }
200
201 static void verify_constraint_name_func (void *data, void *data2_unused)
202 {
203         ListBase *conlist;
204         bConstraint *con;
205         char ownerstr[64];
206         short type;
207         
208         con = (bConstraint*) data;
209         if (!con)
210                 return;
211         
212         conlist = get_constraint_client(ownerstr, &type, NULL);
213         unique_constraint_name (con, conlist);
214 }
215
216 static void constraint_changed_func (void *data, void *data2_unused)
217 {
218         bConstraint *con = (bConstraint*) data;
219
220         if (con->type == con->otype)
221                 return;
222
223         free_constraint_data (con);
224         con->data = new_constraint_data(con->type);
225
226 }
227
228 static void move_constraint_func (void *datav, void *data2_unused)
229 {
230         bConstraint *constraint_to_move= datav;
231         int val;
232         ListBase *conlist;
233         char ownerstr[64];
234         short   type;
235         bConstraint *curCon, *con, *neighbour;
236         
237         val= pupmenu("Move up%x1|Move down %x2");
238         
239         con = constraint_to_move;
240
241         if(val>0) {
242                 conlist = get_constraint_client(ownerstr, &type, NULL);
243                 for (curCon = conlist->first; curCon; curCon = curCon->next){
244                         if (curCon == con){
245                                 /* Move up */
246                                 if (val == 1 && con->prev){
247                                         neighbour = con->prev;
248                                         BLI_remlink(conlist, neighbour);
249                                         BLI_insertlink(conlist, con, neighbour);
250                                 }
251                                 /* Move down */
252                                 else if (val == 2 && con->next){
253                                         neighbour = con->next;
254                                         BLI_remlink (conlist, con);
255                                         BLI_insertlink(conlist, neighbour, con);
256                                 }
257                                 break;
258                         }
259                 }
260         }
261 }
262
263 static void get_constraint_typestring (char *str, bConstraint *con)
264 {
265         switch (con->type){
266         case CONSTRAINT_TYPE_CHILDOF:
267                 strcpy (str, "Child Of");
268                 return;
269         case CONSTRAINT_TYPE_NULL:
270                 strcpy (str, "Null");
271                 return;
272         case CONSTRAINT_TYPE_TRACKTO:
273                 strcpy (str, "Track To");
274                 return;
275         case CONSTRAINT_TYPE_KINEMATIC:
276                 strcpy (str, "IK Solver");
277                 return;
278         case CONSTRAINT_TYPE_ROTLIKE:
279                 strcpy (str, "Copy Rotation");
280                 return;
281         case CONSTRAINT_TYPE_LOCLIKE:
282                 strcpy (str, "Copy Location");
283                 return;
284         case CONSTRAINT_TYPE_ACTION:
285                 strcpy (str, "Action");
286                 return;
287         case CONSTRAINT_TYPE_LOCKTRACK:
288                 strcpy (str, "Locked Track");
289                 return;
290         case CONSTRAINT_TYPE_FOLLOWPATH:
291                 strcpy (str, "Follow Path");
292                 return;
293         default:
294                 strcpy (str, "Unknown");
295                 return;
296         }
297 }
298
299 static int get_constraint_col(bConstraint *con)
300 {
301         switch (con->type) {
302         case CONSTRAINT_TYPE_NULL:
303                 return TH_BUT_NEUTRAL;
304         case CONSTRAINT_TYPE_KINEMATIC:
305                 return TH_BUT_SETTING2;
306         case CONSTRAINT_TYPE_TRACKTO:
307                 return TH_BUT_SETTING;
308         case CONSTRAINT_TYPE_ROTLIKE:
309                 return TH_BUT_SETTING1;
310         case CONSTRAINT_TYPE_LOCLIKE:
311                 return TH_BUT_POPUP;
312         case CONSTRAINT_TYPE_ACTION:
313                 return TH_BUT_ACTION;
314         case CONSTRAINT_TYPE_LOCKTRACK:
315                 return TH_BUT_SETTING;
316         case CONSTRAINT_TYPE_FOLLOWPATH:
317                 return TH_BUT_SETTING2;
318         default:
319                 return TH_REDALERT;
320         }
321 }
322
323 static void draw_constraint (uiBlock *block, ListBase *list, bConstraint *con, short *xco, short *yco, short type)
324 {
325         uiBut *but;
326         char typestr[64];
327         short height, width = 265;
328         int curCol;
329
330         get_constraint_typestring (typestr, con);
331
332         curCol = get_constraint_col(con);
333
334         /* Draw constraint header */
335         uiBlockSetEmboss(block, UI_EMBOSSN);
336         
337         uiDefIconButS(block, ICONTOG|BIT|CONSTRAINT_EXPAND_BIT, B_CONSTRAINT_REDRAW, ICON_DISCLOSURE_TRI_RIGHT, *xco-10, *yco, 20, 20, &con->flag, 0.0, 0.0, 0.0, 0.0, "Collapse/Expand Constraint");
338
339         if (con->flag & CONSTRAINT_EXPAND) {
340                 
341                 if (con->flag & CONSTRAINT_DISABLE) {
342                         BIF_ThemeColor(TH_REDALERT);
343                         uiBlockSetCol(block, TH_REDALERT);
344                 }
345                 else
346                         BIF_ThemeColor(curCol);
347
348                 /*if (type==TARGET_BONE)
349                         but = uiDefButC(block, MENU, B_CONSTRAINT_TEST, "Bone Constraint%t|Track To%x2|IK Solver%x3|Copy Rotation%x8|Copy Location%x9|Action%x12|Null%x0", *xco+20, *yco, 100, 20, &con->type, 0.0, 0.0, 0.0, 0.0, "Constraint type"); 
350                 else
351                         but = uiDefButC(block, MENU, B_CONSTRAINT_TEST, "Object Constraint%t|Track To%x2|Copy Rotation%x8|Copy Location%x9|Null%x0", *xco+20, *yco, 100, 20, &con->type, 0.0, 0.0, 0.0, 0.0, "Constraint type"); 
352                 */
353                 uiBlockSetEmboss(block, UI_EMBOSSX);
354                 
355                 /* rounded header */
356                 BIF_ThemeColorShade(curCol, -20);
357                 uiSetRoundBox(3);
358                 uiRoundBox((float)*xco+4, (float)*yco-18, (float)*xco+width+30, (float)*yco+6, 5.0);
359
360                 but = uiDefBut(block, LABEL, B_CONSTRAINT_TEST, typestr, *xco+10, *yco-1, 100, 19, NULL, 0.0, 0.0, 0.0, 0.0, ""); 
361
362                 uiButSetFunc(but, constraint_changed_func, con, NULL);
363                 con->otype = con->type;
364                 
365                 but = uiDefBut(block, TEX, B_CONSTRAINT_REDRAW, "", *xco+120, *yco-1, 135, 19, con->name, 0.0, 32.0, 0.0, 0.0, "Constraint name"); 
366                 uiButSetFunc(but, verify_constraint_name_func, con, NULL);
367         }       
368         else{
369                 uiBlockSetEmboss(block, UI_EMBOSSN);
370
371                 if (con->flag & CONSTRAINT_DISABLE) {
372                         uiBlockSetCol(block, TH_REDALERT);
373                         BIF_ThemeColor(TH_REDALERT);
374                 }
375                 else
376                         BIF_ThemeColor(curCol);
377                         
378                 /* coloured rectangle to hold constraint controls */
379                 if (con->type!=CONSTRAINT_TYPE_NULL) glRects(*xco+3, *yco-36, *xco+width+30, *yco-15);
380         
381                 /* rounded header */
382                 BIF_ThemeColorShade(curCol, -20);
383                 uiSetRoundBox(3);
384                 uiRoundBox((float)*xco+4, (float)*yco-15, (float)*xco+width+30, (float)*yco+6, 5.0);
385                 
386                 but = uiDefBut(block, LABEL, B_CONSTRAINT_TEST, typestr, *xco+10, *yco-1, 100, 19, NULL, 0.0, 0.0, 0.0, 0.0, ""); 
387                 uiButSetFunc(but, move_constraint_func, con, NULL);
388                 
389                 but = uiDefBut(block, LABEL, B_CONSTRAINT_TEST, con->name, *xco+120, *yco-1, 135, 19, NULL, 0.0, 0.0, 0.0, 0.0, ""); 
390                 uiButSetFunc(but, move_constraint_func, con, NULL);
391         }
392
393         uiBlockSetCol(block, TH_AUTO);  
394         
395         uiBlockSetEmboss(block, UI_EMBOSSN);
396         
397         but = uiDefIconBut(block, BUT, B_CONSTRAINT_REDRAW, ICON_X, *xco+262, *yco, 19, 19, list, 0.0, 0.0, 0.0, 0.0, "Delete constraint");
398         uiButSetFunc(but, del_constraint_func, con, list);
399
400         uiBlockSetEmboss(block, UI_EMBOSSX);
401
402
403         /* Draw constraint data*/
404         if (!(con->flag & CONSTRAINT_EXPAND)) {
405                 (*yco)-=21;
406         }
407         else {
408                 switch (con->type){
409                 case CONSTRAINT_TYPE_ACTION:
410                         {
411                                 bActionConstraint *data = con->data;
412                                 bArmature *arm;
413
414                                 height = 86;
415                                 
416                                 BIF_ThemeColor(curCol);
417                                 glRects(*xco+3, *yco-height-39, *xco+width+30, *yco-18);
418
419                                 uiDefBut(block, LABEL, B_CONSTRAINT_TEST, "Target:", *xco+65, *yco-24, 50, 18, NULL, 0.0, 0.0, 0.0, 0.0, ""); 
420
421                                 /* Draw target parameters */
422                                 uiBlockBeginAlign(block);
423                                 uiDefIDPoinBut(block, test_obpoin_but, B_CONSTRAINT_CHANGETARGET, "OB:", *xco+120, *yco-24, 135, 18, &data->tar, "Target Object"); 
424
425                                 arm = get_armature(data->tar);
426                                 if (arm){
427                                         but=uiDefBut(block, TEX, B_CONSTRAINT_CHANGETARGET, "BO:", *xco+120, *yco-42,135,18, &data->subtarget, 0, 24, 0, 0, "Subtarget Bone");
428                                 }
429                                 else
430                                         strcpy (data->subtarget, "");
431                                 uiBlockEndAlign(block);
432
433                                 /* Draw action button */
434                                 uiDefIDPoinBut(block, test_actionpoin_but, B_CONSTRAINT_CHANGETARGET, "AC:", *xco+((width/2)-117), *yco-64, 78, 18, &data->act, "Action containing the keyed motion for this bone"); 
435                                 uiDefButI(block, MENU, B_CONSTRAINT_REDRAW, "Key on%t|X Rot%x0|Y Rot%x1|Z Rot%x2", *xco+((width/2)-117), *yco-84, 78, 18, &data->type, 0, 24, 0, 0, "Specify which transformation channel from the target is used to key the action");
436
437                                 uiBlockBeginAlign(block);
438                                 uiDefButS(block, NUM, B_CONSTRAINT_CHANGETARGET, "Start:", *xco+((width/2)-36), *yco-64, 78, 18, &data->start, 1, 18000, 0.0, 0.0, "Starting frame of the keyed motion"); 
439                                 uiDefButS(block, NUM, B_CONSTRAINT_CHANGETARGET, "End:", *xco+((width/2)-36), *yco-84, 78, 18, &data->end, 1, 18000, 0.0, 0.0, "Ending frame of the keyed motion"); 
440                                 uiBlockEndAlign(block);
441                                 
442                                 uiBlockBeginAlign(block);
443                                 uiDefButF(block, NUM, B_CONSTRAINT_REDRAW, "Min:", *xco+((width/2)+45), *yco-64, 78, 18, &data->min, -180, 180, 0, 0, "Minimum value for target channel range");
444                                 uiDefButF(block, NUM, B_CONSTRAINT_REDRAW, "Max:", *xco+((width/2)+45), *yco-84, 78, 18, &data->max, -180, 180, 0, 0, "Maximum value for target channel range");
445                                 uiBlockEndAlign(block);
446                         }
447                         break;
448                 case CONSTRAINT_TYPE_LOCLIKE:
449                         {
450                                 bLocateLikeConstraint *data = con->data;
451                                 bArmature *arm;
452                                 height = 66;
453                                 
454                                 BIF_ThemeColor(curCol);
455                                 glRects(*xco+3, *yco-height-39, *xco+width+30, *yco-18);
456
457                                 uiDefBut(block, LABEL, B_CONSTRAINT_TEST, "Target:", *xco+65, *yco-24, 50, 18, NULL, 0.0, 0.0, 0.0, 0.0, ""); 
458
459                                 /* Draw target parameters */
460                                 uiBlockBeginAlign(block);
461                                 uiDefIDPoinBut(block, test_obpoin_but, B_CONSTRAINT_CHANGETARGET, "OB:", *xco+120, *yco-24, 135, 18, &data->tar, "Target Object"); 
462
463                                 arm = get_armature(data->tar);
464                                 if (arm){
465                                         but=uiDefBut(block, TEX, B_CONSTRAINT_CHANGETARGET, "BO:", *xco+120, *yco-42,135,18, &data->subtarget, 0, 24, 0, 0, "Subtarget Bone");
466                                 }
467                                 else
468                                         strcpy (data->subtarget, "");
469                                 uiBlockEndAlign(block);
470                                 
471                                 /* Draw XYZ toggles */
472                                 uiBlockBeginAlign(block);
473                                 but=uiDefButI(block, TOG|BIT|0, B_CONSTRAINT_TEST, "X", *xco+((width/2)-48), *yco-64, 32, 18, &data->flag, 0, 24, 0, 0, "Copy X component");
474                                 but=uiDefButI(block, TOG|BIT|1, B_CONSTRAINT_TEST, "Y", *xco+((width/2)-16), *yco-64, 32, 18, &data->flag, 0, 24, 0, 0, "Copy Y component");
475                                 but=uiDefButI(block, TOG|BIT|2, B_CONSTRAINT_TEST, "Z", *xco+((width/2)+16), *yco-64, 32, 18, &data->flag, 0, 24, 0, 0, "Copy Z component");
476                                 uiBlockEndAlign(block);
477                         }
478                         break;
479                 case CONSTRAINT_TYPE_ROTLIKE:
480                         {
481                                 bRotateLikeConstraint *data = con->data;
482                                 bArmature *arm;
483                                 height = 46;
484
485                                 BIF_ThemeColor(curCol);
486                                 glRects(*xco+3, *yco-height-39, *xco+width+30, *yco-18);
487                                 
488                                 uiDefBut(block, LABEL, B_CONSTRAINT_TEST, "Target:", *xco+65, *yco-24, 50, 18, NULL, 0.0, 0.0, 0.0, 0.0, ""); 
489
490                                 /* Draw target parameters */
491                                 uiBlockBeginAlign(block);
492                                 uiDefIDPoinBut(block, test_obpoin_but, B_CONSTRAINT_CHANGETARGET, "OB:", *xco+120, *yco-24, 135, 18, &data->tar, "Target Object"); 
493
494                                 arm = get_armature(data->tar);
495                                 if (arm){
496                                         but=uiDefBut(block, TEX, B_CONSTRAINT_CHANGETARGET, "BO:", *xco+120, *yco-42,135,18, &data->subtarget, 0, 24, 0, 0, "Subtarget Bone");
497                                 }
498                                 else
499                                         strcpy (data->subtarget, "");
500                                 uiBlockEndAlign(block);
501                         }
502                         break;
503                 case CONSTRAINT_TYPE_KINEMATIC:
504                         {
505                                 bKinematicConstraint *data = con->data;
506                                 bArmature *arm;
507                                 
508                                 height = 66;
509                                 
510                                 BIF_ThemeColor(curCol);
511                                 glRects(*xco+3, *yco-height-39, *xco+width+30, *yco-18);
512                                 
513                                 uiDefBut(block, LABEL, B_CONSTRAINT_TEST, "Target:", *xco+65, *yco-24, 50, 18, NULL, 0.0, 0.0, 0.0, 0.0, ""); 
514
515                                 /* Draw target parameters */
516                                 uiBlockBeginAlign(block);
517                                 uiDefIDPoinBut(block, test_obpoin_but, B_CONSTRAINT_CHANGETARGET, "OB:", *xco+120, *yco-24, 135, 18, &data->tar, "Target Object"); 
518
519                                 arm = get_armature(data->tar);
520                                 if (arm){
521                                         but=uiDefBut(block, TEX, B_CONSTRAINT_CHANGETARGET, "BO:", *xco+120, *yco-42,135,18, &data->subtarget, 0, 24, 0, 0, "Subtarget Bone");
522                                 }
523                                 else
524                                         strcpy (data->subtarget, "");
525                                 uiBlockEndAlign(block);
526         
527                                 uiDefButF(block, NUM, B_CONSTRAINT_REDRAW, "Tolerance:", *xco+((width/2)-117), *yco-64, 120, 18, &data->tolerance, 0.0001, 1.0, 0.0, 0.0, "Maximum distance to target after solving"); 
528                                 uiDefButI(block, NUM, B_CONSTRAINT_REDRAW, "Iterations:", *xco+((width/2)+3), *yco-64, 120, 18, &data->iterations, 1, 10000, 0.0, 0.0, "Maximum number of solving iterations"); 
529                                 
530                         }
531                         break;
532                 case CONSTRAINT_TYPE_TRACKTO:
533                         {
534                                 bTrackToConstraint *data = con->data;
535                                 bArmature *arm;
536
537                                 height = 66;
538                                 
539                                 BIF_ThemeColor(curCol);
540                                 glRects(*xco+3, *yco-height-39, *xco+width+30, *yco-18);
541                                 
542                                 uiDefBut(block, LABEL, B_CONSTRAINT_TEST, "Target:", *xco+65, *yco-24, 50, 18, NULL, 0.0, 0.0, 0.0, 0.0, ""); 
543
544                                 /* Draw target parameters */
545                                 uiBlockBeginAlign(block);
546                                 uiDefIDPoinBut(block, test_obpoin_but, B_CONSTRAINT_CHANGETARGET, "OB:", *xco+120, *yco-24, 135, 18, &data->tar, "Target Object"); 
547
548                                 arm = get_armature(data->tar);
549                                 if (arm){
550                                         but=uiDefBut(block, TEX, B_CONSTRAINT_CHANGETARGET, "BO:", *xco+120, *yco-42,135,18, &data->subtarget, 0, 24, 0, 0, "Subtarget Bone");
551                                 }
552                                 else
553                                         strcpy (data->subtarget, "");
554                                 uiBlockEndAlign(block);
555
556                                 uiBlockBeginAlign(block);
557                                 uiDefBut(block, LABEL, B_CONSTRAINT_TEST, "To:", *xco+12, *yco-64, 25, 18, NULL, 0.0, 0.0, 0.0, 0.0, ""); 
558                                 
559                                 uiDefButI(block, ROW,B_CONSTRAINT_REDRAW,"X",   *xco+39, *yco-64,17,18, &data->reserved1, 12.0, 0.0, 0, 0, "The axis that points to the target object");
560                                 uiDefButI(block, ROW,B_CONSTRAINT_REDRAW,"Y",   *xco+56, *yco-64,17,18, &data->reserved1, 12.0, 1.0, 0, 0, "The axis that points to the target object");
561                                 uiDefButI(block, ROW,B_CONSTRAINT_REDRAW,"Z",   *xco+73, *yco-64,17,18, &data->reserved1, 12.0, 2.0, 0, 0, "The axis that points to the target object");
562                                 uiDefButI(block, ROW,B_CONSTRAINT_REDRAW,"-X",  *xco+90, *yco-64,24,18, &data->reserved1, 12.0, 3.0, 0, 0, "The axis that points to the target object");
563                                 uiDefButI(block, ROW,B_CONSTRAINT_REDRAW,"-Y",  *xco+114, *yco-64,24,18, &data->reserved1, 12.0, 4.0, 0, 0, "The axis that points to the target object");
564                                 uiDefButI(block, ROW,B_CONSTRAINT_REDRAW,"-Z",  *xco+138, *yco-64,24,18, &data->reserved1, 12.0, 5.0, 0, 0, "The axis that points to the target object");
565                                 uiBlockEndAlign(block);
566                                 
567                                 uiBlockBeginAlign(block);
568                                 uiDefBut(block, LABEL, B_CONSTRAINT_TEST, "Up:", *xco+174, *yco-64, 30, 18, NULL, 0.0, 0.0, 0.0, 0.0, "");
569                                 
570                                 uiDefButI(block, ROW,B_CONSTRAINT_REDRAW,"X",   *xco+204, *yco-64,17,18, &data->reserved2, 13.0, 0.0, 0, 0, "The axis that points upward");
571                                 uiDefButI(block, ROW,B_CONSTRAINT_REDRAW,"Y",   *xco+221, *yco-64,17,18, &data->reserved2, 13.0, 1.0, 0, 0, "The axis that points upward");
572                                 uiDefButI(block, ROW,B_CONSTRAINT_REDRAW,"Z",   *xco+238, *yco-64,17,18, &data->reserved2, 13.0, 2.0, 0, 0, "The axis that points upward");
573                                 uiBlockEndAlign(block);
574                         }
575                         break;
576                 case CONSTRAINT_TYPE_LOCKTRACK:
577                         {
578                                 bLockTrackConstraint *data = con->data;
579                                 bArmature *arm;
580                                 height = 66;
581                                 
582                                 BIF_ThemeColor(curCol);
583                                 glRects(*xco+3, *yco-height-39, *xco+width+30, *yco-18);
584
585                                 uiDefBut(block, LABEL, B_CONSTRAINT_TEST, "Target:", *xco+65, *yco-24, 50, 18, NULL, 0.0, 0.0, 0.0, 0.0, ""); 
586
587                                 /* Draw target parameters */
588                                 uiBlockBeginAlign(block);
589                                 uiDefIDPoinBut(block, test_obpoin_but, B_CONSTRAINT_CHANGETARGET, "OB:", *xco+120, *yco-24, 135, 18, &data->tar, "Target Object"); 
590
591                                 arm = get_armature(data->tar);
592                                 if (arm){
593                                         but=uiDefBut(block, TEX, B_CONSTRAINT_CHANGETARGET, "BO:", *xco+120, *yco-42,135,18, &data->subtarget, 0, 24, 0, 0, "Subtarget Bone");
594                                 }
595                                 else
596                                         strcpy (data->subtarget, "");
597                                 uiBlockEndAlign(block);
598                                 
599                                 uiBlockBeginAlign(block);
600                                 uiDefBut(block, LABEL, B_CONSTRAINT_TEST, "To:", *xco+12, *yco-64, 25, 18, NULL, 0.0, 0.0, 0.0, 0.0, ""); 
601                                 
602                                 uiDefButI(block, ROW,B_CONSTRAINT_REDRAW,"X",   *xco+39, *yco-64,17,18, &data->trackflag, 12.0, 0.0, 0, 0, "The axis that points to the target object");
603                                 uiDefButI(block, ROW,B_CONSTRAINT_REDRAW,"Y",   *xco+56, *yco-64,17,18, &data->trackflag, 12.0, 1.0, 0, 0, "The axis that points to the target object");
604                                 uiDefButI(block, ROW,B_CONSTRAINT_REDRAW,"Z",   *xco+73, *yco-64,17,18, &data->trackflag, 12.0, 2.0, 0, 0, "The axis that points to the target object");
605                                 uiDefButI(block, ROW,B_CONSTRAINT_REDRAW,"-X",  *xco+90, *yco-64,24,18, &data->trackflag, 12.0, 3.0, 0, 0, "The axis that points to the target object");
606                                 uiDefButI(block, ROW,B_CONSTRAINT_REDRAW,"-Y",  *xco+114, *yco-64,24,18, &data->trackflag, 12.0, 4.0, 0, 0, "The axis that points to the target object");
607                                 uiDefButI(block, ROW,B_CONSTRAINT_REDRAW,"-Z",  *xco+138, *yco-64,24,18, &data->trackflag, 12.0, 5.0, 0, 0, "The axis that points to the target object");
608                                 uiBlockEndAlign(block);
609                                 
610                                 uiBlockBeginAlign(block);
611                                 uiDefBut(block, LABEL, B_CONSTRAINT_TEST, "Lock:", *xco+166, *yco-64, 38, 18, NULL, 0.0, 0.0, 0.0, 0.0, "");
612                                 
613                                 uiDefButI(block, ROW,B_CONSTRAINT_REDRAW,"X",   *xco+204, *yco-64,17,18, &data->lockflag, 13.0, 0.0, 0, 0, "The axis that is locked");
614                                 uiDefButI(block, ROW,B_CONSTRAINT_REDRAW,"Y",   *xco+221, *yco-64,17,18, &data->lockflag, 13.0, 1.0, 0, 0, "The axis that is locked");
615                                 uiDefButI(block, ROW,B_CONSTRAINT_REDRAW,"Z",   *xco+238, *yco-64,17,18, &data->lockflag, 13.0, 2.0, 0, 0, "The axis that is locked");
616                                 uiBlockEndAlign(block);
617                         }
618                         break;
619                 case CONSTRAINT_TYPE_FOLLOWPATH:
620                         {
621                                 bFollowPathConstraint *data = con->data;
622
623                                 height = 66;
624                                 
625                                 BIF_ThemeColor(curCol);
626                                 glRects(*xco+3, *yco-height-39, *xco+width+30, *yco-18);
627                                 
628                                 uiDefBut(block, LABEL, B_CONSTRAINT_TEST, "Target:", *xco+65, *yco-24, 50, 18, NULL, 0.0, 0.0, 0.0, 0.0, ""); 
629
630                                 /* Draw target parameters */
631                                 uiDefIDPoinBut(block, test_obpoin_but, B_CONSTRAINT_CHANGETARGET, "OB:", *xco+120, *yco-24, 135, 18, &data->tar, "Target Object"); 
632                                 
633                                 /* Draw Curve Follow toggle */
634                                 but=uiDefButI(block, TOG|BIT|0, B_CONSTRAINT_TEST, "CurveFollow", *xco+39, *yco-44, 100, 18, &data->followflag, 0, 24, 0, 0, "Object will follow the heading and banking of the curve");
635
636                                 /* Draw Offset number button */
637                                 uiDefButF(block, NUM, B_CONSTRAINT_REDRAW, "Offset:", *xco+155, *yco-44, 100, 18, &data->offset, -9000, 9000, 100.0, 0.0, "Offset from the position corresponding to the time frame"); 
638
639                                 uiBlockBeginAlign(block);
640                                 uiDefBut(block, LABEL, B_CONSTRAINT_TEST, "Fw:", *xco+12, *yco-64, 27, 18, NULL, 0.0, 0.0, 0.0, 0.0, ""); 
641                                 
642                                 uiDefButI(block, ROW,B_CONSTRAINT_REDRAW,"X",   *xco+39, *yco-64,17,18, &data->trackflag, 12.0, 0.0, 0, 0, "The axis that points forward along the path");
643                                 uiDefButI(block, ROW,B_CONSTRAINT_REDRAW,"Y",   *xco+56, *yco-64,17,18, &data->trackflag, 12.0, 1.0, 0, 0, "The axis that points forward along the path");
644                                 uiDefButI(block, ROW,B_CONSTRAINT_REDRAW,"Z",   *xco+73, *yco-64,17,18, &data->trackflag, 12.0, 2.0, 0, 0, "The axis that points forward along the path");
645                                 uiDefButI(block, ROW,B_CONSTRAINT_REDRAW,"-X",  *xco+90, *yco-64,24,18, &data->trackflag, 12.0, 3.0, 0, 0, "The axis that points forward along the path");
646                                 uiDefButI(block, ROW,B_CONSTRAINT_REDRAW,"-Y",  *xco+114, *yco-64,24,18, &data->trackflag, 12.0, 4.0, 0, 0, "The axis that points forward along the path");
647                                 uiDefButI(block, ROW,B_CONSTRAINT_REDRAW,"-Z",  *xco+138, *yco-64,24,18, &data->trackflag, 12.0, 5.0, 0, 0, "The axis that points forward along the path");
648                                 uiBlockEndAlign(block);
649                                 
650                                 uiBlockBeginAlign(block);
651                                 uiDefBut(block, LABEL, B_CONSTRAINT_TEST, "Up:", *xco+174, *yco-64, 30, 18, NULL, 0.0, 0.0, 0.0, 0.0, "");
652                                 
653                                 uiDefButI(block, ROW,B_CONSTRAINT_REDRAW,"X",   *xco+204, *yco-64,17,18, &data->upflag, 13.0, 0.0, 0, 0, "The axis that points upward");
654                                 uiDefButI(block, ROW,B_CONSTRAINT_REDRAW,"Y",   *xco+221, *yco-64,17,18, &data->upflag, 13.0, 1.0, 0, 0, "The axis that points upward");
655                                 uiDefButI(block, ROW,B_CONSTRAINT_REDRAW,"Z",   *xco+238, *yco-64,17,18, &data->upflag, 13.0, 2.0, 0, 0, "The axis that points upward");
656                                 uiBlockEndAlign(block);
657                         }
658                         break;
659                 case CONSTRAINT_TYPE_NULL:
660                         {
661                                 height = 17;
662                                 
663                                 BIF_ThemeColor(curCol);
664                                 glRects(*xco+3, *yco-height-17, *xco+width+30, *yco-18);
665                                 
666                         }
667                         break;
668                 default:
669                         height = 0;
670                         break;
671                 }
672
673                 (*yco)-=(24+height);
674         }
675
676         if (con->type!=CONSTRAINT_TYPE_NULL) {
677                 uiDefButF(block, NUMSLI, B_CONSTRAINT_REDRAW, "Influence ", *xco+15, *yco, 199, 19, &(con->enforce), 0.0, 1.0, 0.0, 0.0, "Amount of influence this constraint will have on the final solution");
678                 but = uiDefBut(block, BUT, B_CONSTRAINT_REDRAW, "Edit", *xco+214, *yco, 41, 19, 0, 0.0, 1.0, 0.0, 0.0, "Show this constraint's ipo in the object's Ipo window");
679                 /* If this is on an object, add the constraint to the object */
680                 uiButSetFunc (but, activate_constraint_ipo_func, con, NULL);
681                 /* If this is on a bone, add the constraint to the action (if any) */
682                 //but = uiDefBut(block, BUT, B_CONSTRAINT_REDRAW, "Key", *xco+227, *yco, 41, 20, 0, 0.0, 1.0, 0.0, 0.0, "Add an influence keyframe to the constraint");
683                 /* Add a keyframe to the influence IPO */
684                 //uiButSetFunc (but, add_influence_key_to_constraint_func, con, NULL);
685                 (*yco)-=24;
686         } else {
687                 (*yco)-=3;
688         }
689         
690 }
691
692 static uiBlock *add_constraintmenu(void *arg_unused)
693 {
694         uiBlock *block;
695         
696         ListBase *conlist;
697         char ownerstr[64];
698         short type;
699         short yco= 0;
700         
701         conlist = get_constraint_client(ownerstr, &type, NULL);
702         
703         block= uiNewBlock(&curarea->uiblocks, "add_constraintmenu", UI_EMBOSSP, UI_HELV, curarea->win);
704
705         uiDefBut(block, BUTM, B_CONSTRAINT_ADD_LOCLIKE,"Copy Location",         0, yco-=20, 160, 19, NULL, 0.0, 0.0, 1, 0, "");
706         uiDefBut(block, BUTM, B_CONSTRAINT_ADD_ROTLIKE,"Copy Rotation",         0, yco-=20, 160, 19, NULL, 0.0, 0.0, 1, 0, "");
707         
708         uiDefBut(block, SEPR, 0, "",                                    0, yco-=6, 120, 6, NULL, 0.0, 0.0, 0, 0, "");
709         
710         uiDefBut(block, BUTM, B_CONSTRAINT_ADD_TRACKTO,"Track To",              0, yco-=20, 160, 19, NULL, 0.0, 0.0, 1, 0, "");
711         uiDefBut(block, BUTM, B_CONSTRAINT_ADD_LOCKTRACK,"Locked Track",                0, yco-=20, 160, 19, NULL, 0.0, 0.0, 1, 0, "");
712         uiDefBut(block, BUTM, B_CONSTRAINT_ADD_FOLLOWPATH,"Follow Path",                0, yco-=20, 160, 19, NULL, 0.0, 0.0, 1, 0, "");
713         
714         if (type==TARGET_BONE) {
715         
716                 uiDefBut(block, SEPR, 0, "",                                    0, yco-=6, 120, 6, NULL, 0.0, 0.0, 0, 0, "");
717                 
718                 uiDefBut(block, BUTM, B_CONSTRAINT_ADD_KINEMATIC,"IK Solver",           0, yco-=20, 160, 19, NULL, 0.0, 0.0, 1, 0, "");
719                 uiDefBut(block, BUTM, B_CONSTRAINT_ADD_ACTION,"Action",         0, yco-=20, 160, 19, NULL, 0.0, 0.0, 1, 0, "");
720                 
721         }
722         
723         uiDefBut(block, SEPR, 0, "",                                    0, yco-=6, 120, 6, NULL, 0.0, 0.0, 0, 0, "");
724         
725         uiDefBut(block, BUTM, B_CONSTRAINT_ADD_NULL,"Null",             0, yco-=20, 160, 19, NULL, 0.0, 0.0, 1, 0, "");
726         
727         uiTextBoundsBlock(block, 50);
728         uiBlockSetDirection(block, UI_DOWN);
729                 
730         return block;
731 }
732
733 void do_constraintbuts(unsigned short event)
734 {
735         switch(event) {
736         case B_CONSTRAINT_CHANGENAME:
737                 break;
738         case B_CONSTRAINT_TEST:
739                 test_scene_constraints();
740                 allqueue (REDRAWVIEW3D, 0);
741                 allqueue (REDRAWBUTSOBJECT, 0);
742                 break;
743         case B_CONSTRAINT_REDRAW:
744                 test_scene_constraints();
745                 allqueue (REDRAWVIEW3D, 0);
746                 allqueue (REDRAWBUTSOBJECT, 0);
747                 break;
748         case B_CONSTRAINT_CHANGETARGET:
749                 test_scene_constraints();
750                 allqueue (REDRAWVIEW3D, 0);
751                 allqueue (REDRAWBUTSOBJECT, 0);
752                 break;
753         case B_CONSTRAINT_CHANGETYPE:
754                 test_scene_constraints();
755                 allqueue (REDRAWVIEW3D, 0);
756                 allqueue (REDRAWBUTSOBJECT, 0);
757                 break;
758         case B_CONSTRAINT_ADD_NULL:
759                 {
760                         bConstraint *con;
761                         
762                         con = add_new_constraint(CONSTRAINT_TYPE_NULL);
763                         add_constraint_to_client(con);
764
765                         test_scene_constraints();
766                         allqueue (REDRAWVIEW3D, 0);
767                         allqueue (REDRAWBUTSOBJECT, 0);
768                 }
769                 break;
770         case B_CONSTRAINT_ADD_KINEMATIC:
771                 {
772                         bConstraint *con;
773                         
774                         con = add_new_constraint(CONSTRAINT_TYPE_KINEMATIC);
775                         add_constraint_to_client(con);
776
777                         test_scene_constraints();
778                         allqueue (REDRAWVIEW3D, 0);
779                         allqueue (REDRAWBUTSOBJECT, 0);
780                 }
781                 break;
782         case B_CONSTRAINT_ADD_TRACKTO:
783                 {
784                         bConstraint *con;
785
786                         con = add_new_constraint(CONSTRAINT_TYPE_TRACKTO);
787                         add_constraint_to_client(con);
788
789                         test_scene_constraints();
790                         allqueue (REDRAWVIEW3D, 0);
791                         allqueue (REDRAWBUTSOBJECT, 0);
792                 }
793                 break;
794         case B_CONSTRAINT_ADD_ROTLIKE:
795                 {
796                         bConstraint *con;
797
798                         con = add_new_constraint(CONSTRAINT_TYPE_ROTLIKE);
799                         add_constraint_to_client(con);
800
801                         test_scene_constraints();
802                         allqueue (REDRAWVIEW3D, 0);
803                         allqueue (REDRAWBUTSOBJECT, 0);
804                 }
805                 break;
806         case B_CONSTRAINT_ADD_LOCLIKE:
807                 {
808                         bConstraint *con;
809
810                         con = add_new_constraint(CONSTRAINT_TYPE_LOCLIKE);
811                         add_constraint_to_client(con);
812
813                         test_scene_constraints();
814                         allqueue (REDRAWVIEW3D, 0);
815                         allqueue (REDRAWBUTSOBJECT, 0);
816                 }
817                 break;
818         case B_CONSTRAINT_ADD_ACTION:
819                 {
820                         bConstraint *con;
821
822                         con = add_new_constraint(CONSTRAINT_TYPE_ACTION);
823                         add_constraint_to_client(con);
824
825                         test_scene_constraints();
826                         allqueue (REDRAWVIEW3D, 0);
827                         allqueue (REDRAWBUTSOBJECT, 0);
828                 }
829                 break;
830         case B_CONSTRAINT_ADD_LOCKTRACK:
831                 {
832                         bConstraint *con;
833
834                         con = add_new_constraint(CONSTRAINT_TYPE_LOCKTRACK);
835                         add_constraint_to_client(con);
836
837                         test_scene_constraints();
838                         allqueue (REDRAWVIEW3D, 0);
839                         allqueue (REDRAWBUTSOBJECT, 0);
840                 }
841                 break;
842         case B_CONSTRAINT_ADD_FOLLOWPATH:
843                 {
844                         bConstraint *con;
845
846                         con = add_new_constraint(CONSTRAINT_TYPE_FOLLOWPATH);
847                         add_constraint_to_client(con);
848
849                         test_scene_constraints();
850                         allqueue (REDRAWVIEW3D, 0);
851                         allqueue (REDRAWBUTSOBJECT, 0);
852                 }
853                 break;
854         case B_CONSTRAINT_DEL:
855                 test_scene_constraints();
856                 allqueue (REDRAWVIEW3D, 0);
857                 allqueue (REDRAWBUTSOBJECT, 0);
858                 break;
859         default:
860                 break;
861         }
862
863         clear_object_constraint_status(OBACT);
864         make_displists_by_armature (OBACT);
865 }
866
867 static void object_panel_constraint(void)
868 {
869         uiBlock *block;
870         ListBase *conlist;
871         bConstraint *curcon;
872         short xco, yco, type;
873         char ownerstr[64];
874         
875         block= uiNewBlock(&curarea->uiblocks, "object_panel_constraint", UI_EMBOSS, UI_HELV, curarea->win);
876         if(uiNewPanel(curarea, block, "Constraints", "Object", 640, 0, 318, 204)==0) return;
877
878         /* this is a variable height panel, newpanel doesnt force new size on existing panels */
879         /* so first we make it default height */
880         uiNewPanelHeight(block, 204);
881
882         conlist = get_constraint_client(ownerstr, &type, NULL);
883         
884         if (conlist) {
885                  
886                 uiDefBlockBut(block, add_constraintmenu, NULL, "Add Constraint|>> ", 0, 190, 130, 20, "Add a new constraint");
887                 
888                 /* print active object or bone */
889                 {
890                         short type;
891                         void *data=NULL;
892                         char str[64];
893                         
894                         str[0]= 0;
895                         get_constraint_client(NULL, &type, &data);
896                         if (data && type==TARGET_BONE){
897                                 sprintf(str, "To Bone: %s", ((Bone*)data)->name);
898                         }
899                         else if(OBACT) {
900                                 Object *ob= OBACT;
901                                 sprintf(str, "To Object: %s", ob->id.name+2);
902                         }
903                         uiDefBut(block, LABEL, 1, str,  150, 190, 150, 20, NULL, 0.0, 0.0, 0, 0, "Displays Active Object or Bone name");
904                 }
905                 
906                 /* Go through the list of constraints and draw them */
907                 xco = 10;
908                 yco = 160;
909                 // local panel coords
910                 uiPanelPush(block);
911                 
912                 for (curcon = conlist->first; curcon; curcon=curcon->next) {
913                         /* Draw default constraint header */                    
914                         draw_constraint(block, conlist, curcon, &xco, &yco, type);      
915                 }
916                 
917                 uiPanelPop(block);
918                 
919                 if(yco < 0) uiNewPanelHeight(block, 204-yco);
920                 
921         }
922 }
923
924 void object_panel_draw(Object *ob)
925 {
926         uiBlock *block;
927         int xco, a, dx, dy;
928         
929         block= uiNewBlock(&curarea->uiblocks, "object_panel_draw", UI_EMBOSS, UI_HELV, curarea->win);
930         if(uiNewPanel(curarea, block, "Draw", "Object", 320, 0, 318, 204)==0) return;
931
932         /* LAYERS */
933         xco= 151;
934         dx= 32;
935         dy= 30;
936
937         uiBlockBeginAlign(block);
938         for(a=0; a<5; a++)
939                 uiDefButI(block, TOG|BIT|(a), B_OBLAY+a, "",    (short)(xco+a*(dx/2)), 180, (short)(dx/2), (short)(dy/2), &(BASACT->lay), 0, 0, 0, 0, "");
940         for(a=0; a<5; a++)
941                 uiDefButI(block, TOG|BIT|(a+10), B_OBLAY+a+10, "",      (short)(xco+a*(dx/2)), 165, (short)(dx/2), (short)(dy/2), &(BASACT->lay), 0, 0, 0, 0, "");
942                 
943         xco+= 5;
944         uiBlockBeginAlign(block);
945         for(a=5; a<10; a++)
946                 uiDefButI(block, TOG|BIT|(a), B_OBLAY+a, "",    (short)(xco+a*(dx/2)), 180, (short)(dx/2), (short)(dy/2), &(BASACT->lay), 0, 0, 0, 0, "");
947         for(a=5; a<10; a++)
948                 uiDefButI(block, TOG|BIT|(a+10), B_OBLAY+a+10, "",      (short)(xco+a*(dx/2)), 165, (short)(dx/2), (short)(dy/2), &(BASACT->lay), 0, 0, 0, 0, "");
949
950         uiBlockEndAlign(block);
951
952         uiDefBut(block, LABEL, 0, "Drawtype",                                           28,200,100,18, 0, 0, 0, 0, 0, "");
953         uiDefButC(block, MENU, REDRAWVIEW3D, "Drawtype%t|Bounds %x1|Wire %x2|Solid %x3|Shaded %x4",     
954                                                                                                                                 28,180,100,18, &ob->dt, 0, 0, 0, 0, "Sets the drawing type of the active object");
955         uiDefBut(block, LABEL, 0, "Draw Extra",                                         28,160,100,18, 0, 0, 0, 0, 0, "");
956         uiBlockBeginAlign(block);
957         uiDefButC(block, TOG|BIT|0, REDRAWVIEW3D, "Bounds",             28, 140, 100, 18, &ob->dtx, 0, 0, 0, 0, "Displays the active object's bounds");
958         uiDefButS(block, MENU, REDRAWVIEW3D, "Boundary Display%t|Box%x0|Sphere%x1|Cylinder%x2|Cone%x3|Polyheder%x4",
959                                                                                                                         28, 120, 100, 18, &ob->boundtype, 0, 0, 0, 0, "Selects the boundary display type");
960         uiDefButBitC(block, TOG, OB_DRAWWIRE, REDRAWVIEW3D, "Wire",             28, 100, 100, 18, &ob->dtx, 0, 0, 0, 0, "Displays the active object's wireframe in shaded drawing modes");
961         uiDefButBitC(block, TOG, OB_AXIS, REDRAWVIEW3D, "Axis",         28, 80, 100, 18, &ob->dtx, 0, 0, 0, 0, "Displays the active object's centre and axis");
962         uiDefButBitC(block, TOG, OB_TEXSPACE, REDRAWVIEW3D, "TexSpace", 28, 60, 100, 18, &ob->dtx, 0, 0, 0, 0, "Displays the active object's texture space");
963         uiDefButBitC(block, TOG, OB_DRAWNAME, REDRAWVIEW3D, "Name",             28, 40, 100, 18, &ob->dtx, 0, 0, 0, 0, "Displays the active object's name");
964         
965         
966 }
967
968
969
970
971 void do_object_panels(unsigned short event)
972 {
973         Object *ob;
974         Base *base;
975         Effect *eff, *effn;
976         int type;
977         
978         ob= OBACT;
979
980         switch(event) {
981                 
982         case B_RECALCPATH:
983                 calc_curvepath(OBACT);
984                 allqueue(REDRAWVIEW3D, 0);
985                 break;
986         case B_AUTOTIMEOFS:
987                 auto_timeoffs();
988                 break;
989         case B_FRAMEMAP:
990                 G.scene->r.framelen= G.scene->r.framapto;
991                 G.scene->r.framelen/= G.scene->r.images;
992                 break;
993         case B_NEWEFFECT:
994                 if(ob) {
995                         if (BLI_countlist(&ob->effect)==MAX_EFFECT)
996                                 error("Unable to add: effect limit reached");
997                         else
998                                 copy_act_effect(ob);
999                 }
1000                 allqueue(REDRAWBUTSOBJECT, 0);
1001                 break;
1002         case B_DELEFFECT:
1003                 if(ob==0 || ob->type!=OB_MESH) break;
1004                 eff= ob->effect.first;
1005                 while(eff) {
1006                         effn= eff->next;
1007                         if(eff->flag & SELECT) {
1008                                 BLI_remlink(&ob->effect, eff);
1009                                 free_effect(eff);
1010                                 break;
1011                         }
1012                         eff= effn;
1013                 }
1014                 allqueue(REDRAWBUTSOBJECT, 0);
1015                 allqueue(REDRAWVIEW3D, 0);
1016                 break;
1017         case B_NEXTEFFECT:
1018                 if(ob==0 || ob->type!=OB_MESH) break;
1019                 eff= ob->effect.first;
1020                 while(eff) {
1021                         if(eff->flag & SELECT) {
1022                                 if(eff->next) {
1023                                         eff->flag &= ~SELECT;
1024                                         eff->next->flag |= SELECT;
1025                                 }
1026                                 break;
1027                         }
1028                         eff= eff->next;
1029                 }
1030                 allqueue(REDRAWBUTSOBJECT, 0);
1031                 break;
1032         case B_PREVEFFECT:
1033                 if(ob==0 || ob->type!=OB_MESH) break;
1034                 eff= ob->effect.first;
1035                 while(eff) {
1036                         if(eff->flag & SELECT) {
1037                                 if(eff->prev) {
1038                                         eff->flag &= ~SELECT;
1039                                         eff->prev->flag |= SELECT;
1040                                 }
1041                                 break;
1042                         }
1043                         eff= eff->next;
1044                 }
1045                 allqueue(REDRAWBUTSOBJECT, 0);
1046                 break;
1047         case B_CHANGEEFFECT:
1048                 if(ob==0 || ob->type!=OB_MESH) break;
1049                 eff= ob->effect.first;
1050                 while(eff) {
1051                         if(eff->flag & SELECT) {
1052                                 if(eff->type!=eff->buttype) {
1053                                         BLI_remlink(&ob->effect, eff);
1054                                         type= eff->buttype;
1055                                         free_effect(eff);
1056                                         eff= add_effect(type);
1057                                         BLI_addtail(&ob->effect, eff);
1058                                 }
1059                                 break;
1060                         }
1061                         eff= eff->next;
1062                 }
1063                 allqueue(REDRAWBUTSOBJECT, 0);
1064                 allqueue(REDRAWVIEW3D, 0);
1065                 break;
1066         case B_CALCEFFECT:
1067                 if(ob==0 || ob->type!=OB_MESH) break;
1068                 eff= ob->effect.first;
1069                 while(eff) {
1070                         if(eff->flag & SELECT) {
1071                                 if(eff->type==EFF_PARTICLE) build_particle_system(ob);
1072                                 else if(eff->type==EFF_WAVE) object_wave(ob);
1073                         }
1074                         eff= eff->next;
1075                 }
1076                 allqueue(REDRAWVIEW3D, 0);
1077                 allqueue(REDRAWBUTSOBJECT, 0);
1078                 break;
1079         case B_RECALCAL:
1080                 base= FIRSTBASE;
1081                 while(base) {
1082                         if(base->lay & G.vd->lay) {
1083                                 ob= base->object;
1084                                 eff= ob->effect.first;
1085                                 while(eff) {
1086                                         if(eff->flag & SELECT) {
1087                                                 if(eff->type==EFF_PARTICLE) build_particle_system(ob);
1088                                         }
1089                                         eff= eff->next;
1090                                 }
1091                         }
1092                         base= base->next;
1093                 }
1094                 allqueue(REDRAWVIEW3D, 0);
1095                 break;
1096         case B_PRINTSPEED:
1097                 ob= OBACT;
1098                 if(ob) {
1099                         float vec[3];
1100                         CFRA++;
1101                         do_ob_ipo(ob);
1102                         where_is_object(ob);
1103                         VECCOPY(vec, ob->obmat[3]);
1104                         CFRA--;
1105                         do_ob_ipo(ob);
1106                         where_is_object(ob);
1107                         VecSubf(vec, vec, ob->obmat[3]);
1108                         prspeed= Normalise(vec);
1109                         scrarea_queue_winredraw(curarea);
1110                 }
1111                 break;
1112         case B_PRINTLEN:
1113                 ob= OBACT;
1114                 if(ob && ob->type==OB_CURVE) {
1115                         Curve *cu=ob->data;
1116                         
1117                         if(cu->path) prlen= cu->path->totdist; else prlen= -1.0;
1118                         scrarea_queue_winredraw(curarea);
1119                 } 
1120                 break;
1121         case B_RELKEY:
1122                 allspace(REMAKEIPO, 0);
1123                 allqueue(REDRAWBUTSOBJECT, 0);
1124                 allqueue(REDRAWIPO, 0);
1125                 break;
1126                 
1127         default:
1128                 if(event>=B_SELEFFECT && event<B_SELEFFECT+MAX_EFFECT) {
1129                         ob= OBACT;
1130                         if(ob) {
1131                                 int a=B_SELEFFECT;
1132                                 
1133                                 eff= ob->effect.first;
1134                                 while(eff) {
1135                                         if(event==a) eff->flag |= SELECT;
1136                                         else eff->flag &= ~SELECT;
1137                                         
1138                                         a++;
1139                                         eff= eff->next;
1140                                 }
1141                                 allqueue(REDRAWBUTSOBJECT, 0);
1142                         }
1143                 }
1144         }
1145
1146 }
1147
1148 void object_panel_effects(Object *ob)
1149 {
1150         Effect *eff;
1151         uiBlock *block;
1152         int a;
1153         short x, y;
1154         
1155         block= uiNewBlock(&curarea->uiblocks, "object_panel_effects", UI_EMBOSS, UI_HELV, curarea->win);
1156         uiNewPanelTabbed("Constraints", "Object");
1157         if(uiNewPanel(curarea, block, "Effects", "Object", 640, 0, 418, 204)==0) return;
1158
1159         /* EFFECTS */
1160         
1161         if (ob->type == OB_MESH) {
1162                 uiBlockBeginAlign(block);
1163                 uiDefBut(block, BUT, B_NEWEFFECT, "NEW Effect", 550,187,124,27, 0, 0, 0, 0, 0, "Create a new effect");
1164                 uiDefBut(block, BUT, B_DELEFFECT, "Delete", 676,187,62,27, 0, 0, 0, 0, 0, "Delete the effect");
1165                 uiBlockEndAlign(block);
1166         }
1167
1168         /* select effs */
1169         eff= ob->effect.first;
1170         a= 0;
1171         while(eff) {
1172                 
1173                 x= 15 * a + 550;
1174                 y= 172; // - 12*( abs(a/10) ) ;
1175                 uiDefButS(block, TOG|BIT|0, B_SELEFFECT+a, "", x, y, 15, 12, &eff->flag, 0, 0, 0, 0, "");
1176                 
1177                 a++;
1178                 if(a==MAX_EFFECT) break;
1179                 eff= eff->next;
1180         }
1181         
1182         eff= ob->effect.first;
1183         while(eff) {
1184                 if(eff->flag & SELECT) break;
1185                 eff= eff->next;
1186         }
1187         
1188         if(eff) {
1189                 uiDefButS(block, MENU, B_CHANGEEFFECT, "Build %x0|Particles %x1|Wave %x2", 895,187,107,27, &eff->buttype, 0, 0, 0, 0, "Start building the effect");
1190                 
1191                 if(eff->type==EFF_BUILD) {
1192                         BuildEff *bld;
1193                         
1194                         bld= (BuildEff *)eff;
1195                         
1196                         uiDefButF(block, NUM, 0, "Len:",                        649,138,95,21, &bld->len, 1.0, 9000.0, 100, 0, "Specify the total time the building requires");
1197                         uiDefButF(block, NUM, 0, "Sfra:",                       746,138,94,22, &bld->sfra, 1.0, 9000.0, 100, 0, "Specify the startframe of the effect");
1198                 }
1199                 else if(eff->type==EFF_WAVE) {
1200                         WaveEff *wav;
1201                         
1202                         wav= (WaveEff *)eff;
1203                         uiBlockBeginAlign(block);
1204                         uiDefButS(block, TOG|BIT|1, B_CALCEFFECT, "X",          782,135,54,23, &wav->flag, 0, 0, 0, 0, "Enable X axis");
1205                         uiDefButS(block, TOG|BIT|2, B_CALCEFFECT, "Y",          840,135,47,23, &wav->flag, 0, 0, 0, 0, "Enable Y axis");
1206                         uiDefButS(block, TOG|BIT|3, B_CALCEFFECT, "Cycl",       890,135,111,23, &wav->flag, 0, 0, 0, 0, "Enable cyclic wave efefct");
1207                         uiBlockBeginAlign(block);
1208                         uiDefButF(block, NUM, B_CALCEFFECT, "Sta x:",           550,135,113,24, &wav->startx, -100.0, 100.0, 100, 0, "Starting position for the X axis");
1209                         uiDefButF(block, NUM, B_CALCEFFECT, "Sta y:",           665,135,104,24, &wav->starty, -100.0, 100.0, 100, 0, "Starting position for the Y axis");
1210                         uiBlockBeginAlign(block);
1211                         uiDefButF(block, NUMSLI, B_CALCEFFECT, "Speed:",        550,100,216,20, &wav->speed, -2.0, 2.0, 0, 0, "Specify the wave speed");
1212                         uiDefButF(block, NUMSLI, B_CALCEFFECT, "Heigth:",       550,80,216,20, &wav->height, -2.0, 2.0, 0, 0, "Specify the amplitude of the wave");
1213                         uiDefButF(block, NUMSLI, B_CALCEFFECT, "Width:",        550,60,216,20, &wav->width, 0.0, 5.0, 0, 0, "Specify the width of the wave");
1214                         uiDefButF(block, NUMSLI, B_CALCEFFECT, "Narrow:",       550,40,216,20, &wav->narrow, 0.0, 10.0, 0, 0, "Specify how narrow the wave follows");
1215                         uiBlockBeginAlign(block);
1216                         uiDefButF(block, NUM, B_CALCEFFECT, "Time sta:",        780,100,219,20, &wav->timeoffs, -1000.0, 1000.0, 100, 0, "Specify startingframe of the wave");
1217
1218                         uiDefButF(block, NUM, B_CALCEFFECT, "Lifetime:",        780,80,219,20, &wav->lifetime,  -1000.0, 1000.0, 100, 0, "Specify the lifespan of the wave");
1219                         uiDefButF(block, NUM, B_CALCEFFECT, "Damptime:",        780,60,219,20, &wav->damp,  -1000.0, 1000.0, 100, 0, "Specify the dampingtime of the wave");
1220                         uiBlockEndAlign(block);
1221                 }
1222                 else if(eff->type==EFF_PARTICLE) {
1223                         PartEff *paf;
1224                         
1225                         paf= (PartEff *)eff;
1226                         
1227                         uiDefBut(block, BUT, B_RECALCAL, "RecalcAll", 741,187,67,27, 0, 0, 0, 0, 0, "Update the particle system");
1228                         uiDefButS(block, TOG|BIT|2, B_CALCEFFECT, "Static",     825,187,67,27, &paf->flag, 0, 0, 0, 0, "Make static particles");
1229                         
1230                         uiBlockBeginAlign(block);
1231                         uiDefButI(block, NUM, B_CALCEFFECT, "Tot:",                     550,146,91,20, &paf->totpart, 1.0, 100000.0, 0, 0, "Set the total number of particles");
1232                         if(paf->flag & PAF_STATIC) {
1233                                 uiDefButS(block, NUM, REDRAWVIEW3D, "Step:",    644,146,84+97,20, &paf->staticstep, 1.0, 100.0, 10, 0, "");
1234                         }
1235                         else {
1236                                 uiDefButF(block, NUM, B_CALCEFFECT, "Sta:",             644,146,84,20, &paf->sta, -250.0, 9000.0, 100, 0, "Specify the startframe");
1237                                 uiDefButF(block, NUM, B_CALCEFFECT, "End:",             731,146,97,20, &paf->end, 1.0, 9000.0, 100, 0, "Specify the endframe");
1238                         }
1239                         uiDefButF(block, NUM, B_CALCEFFECT, "Life:",            831,146,88,20, &paf->lifetime, 1.0, 9000.0, 100, 0, "Specify the life span of the particles");
1240                         uiDefButI(block, NUM, B_CALCEFFECT, "Keys:",            922,146,80,20, &paf->totkey, 1.0, 32.0, 0, 0, "Specify the number of key positions");
1241                         
1242                         uiDefButS(block, NUM, B_REDR,           "CurMul:",              550,124,91,20, &paf->curmult, 0.0, 3.0, 0, 0, "Multiply the particles");
1243                         uiDefButS(block, NUM, B_CALCEFFECT, "Mat:",                     644,124,84,20, paf->mat+paf->curmult, 1.0, 8.0, 0, 0, "Specify the material used for the particles");
1244                         uiDefButF(block, NUM, B_CALCEFFECT, "Mult:",            730,124,98,20, paf->mult+paf->curmult, 0.0, 1.0, 10, 0, "Probability \"dying\" particle spawns a new one.");
1245                         uiDefButF(block, NUM, B_CALCEFFECT, "Life:",            831,124,89,20, paf->life+paf->curmult, 1.0, 600.0, 100, 0, "Specify the lifespan of the next generation particles");
1246                         uiDefButS(block, NUM, B_CALCEFFECT, "Child:",           922,124,80,20, paf->child+paf->curmult, 1.0, 600.0, 100, 0, "Specify the number of children of a particle that multiply itself");
1247                         
1248                         uiBlockBeginAlign(block);
1249                         uiDefButF(block, NUM, B_CALCEFFECT, "Randlife:",        550,96,96,20, &paf->randlife, 0.0, 2.0, 10, 0, "Give the particlelife a random variation");
1250                         uiDefButI(block, NUM, B_CALCEFFECT, "Seed:",            652,96,80,20, &paf->seed, 0.0, 255.0, 0, 0, "Set an offset in the random table");
1251
1252                         uiDefButS(block, TOG|BIT|3, B_CALCEFFECT, "Face",               735,96,46,20, &paf->flag, 0, 0, 0, 0, "Emit particles also from faces");
1253                         uiDefButS(block, TOG|BIT|1, B_CALCEFFECT, "Bspline",    782,96,54,20, &paf->flag, 0, 0, 0, 0, "Use B spline formula for particle interpolation");
1254                         uiDefButS(block, TOG, REDRAWVIEW3D, "Vect",                             837,96,45,20, &paf->stype, 0, 0, 0, 0, "Give the particles a rotation direction");
1255                         uiDefButF(block, NUM, B_DIFF,                   "VectSize",             885,96,116,20, &paf->vectsize, 0.0, 1.0, 10, 0, "Set the speed for Vect");      
1256
1257                         uiBlockBeginAlign(block);
1258                         uiBlockSetCol(block, TH_BUT_SETTING2);
1259                         uiDefButF(block, NUM, B_CALCEFFECT, "Norm:",            550,67,96,20, &paf->normfac, -2.0, 2.0, 10, 0, "Let the mesh give the particle a starting speed");
1260                         uiDefButF(block, NUM, B_CALCEFFECT, "Ob:",              649,67,86,20, &paf->obfac, -1.0, 1.0, 10, 0, "Let the object give the particle a starting speed");
1261                         uiDefButF(block, NUM, B_CALCEFFECT, "Rand:",            738,67,86,20, &paf->randfac, 0.0, 2.0, 10, 0, "Give the startingspeed a random variation");
1262                         uiDefButF(block, NUM, B_CALCEFFECT, "Tex:",             826,67,85,20, &paf->texfac, 0.0, 2.0, 10, 0, "Let the texture give the particle a starting speed");
1263                         uiDefButF(block, NUM, B_CALCEFFECT, "Damp:",            913,67,89,20, &paf->damp, 0.0, 1.0, 10, 0, "Specify the damping factor");
1264                         uiBlockSetCol(block, TH_AUTO);
1265                         
1266                         uiBlockBeginAlign(block);
1267                         uiDefButF(block, NUM, B_CALCEFFECT, "X:",               550,31,72,20, paf->force, -1.0, 1.0, 1, 0, "Specify the X axis of a continues force");
1268                         uiDefButF(block, NUM, B_CALCEFFECT, "Y:",               624,31,78,20, paf->force+1,-1.0, 1.0, 1, 0, "Specify the Y axis of a continues force");
1269                         uiDefBut(block, LABEL, 0, "Force:",                             550,9,72,20, 0, 1.0, 0, 0, 0, "");
1270                         uiDefButF(block, NUM, B_CALCEFFECT, "Z:",               623,9,79,20, paf->force+2, -1.0, 1.0, 1, 0, "Specify the Z axis of a continues force");
1271
1272                         uiBlockBeginAlign(block);
1273                         uiDefButF(block, NUM, B_CALCEFFECT, "X:",               722,31,74,20, paf->defvec, -1.0, 1.0, 1, 0, "Specify the X axis of a force, determined by the texture");
1274                         uiDefButF(block, NUM, B_CALCEFFECT, "Y:",               798,31,74,20, paf->defvec+1,-1.0, 1.0, 1, 0, "Specify the Y axis of a force, determined by the texture");
1275                         uiDefBut(block, LABEL, 0, "Texture:",                   722,9,74,20, 0, 1.0, 0, 0, 0, "");
1276                         uiDefButF(block, NUM, B_CALCEFFECT, "Z:",               797,9,75,20, paf->defvec+2, -1.0, 1.0, 1, 0, "Specify the Z axis of a force, determined by the texture");
1277                         uiBlockEndAlign(block);
1278
1279                         uiDefButS(block, ROW, B_CALCEFFECT, "Int",              875,9,32,43, &paf->texmap, 14.0, 0.0, 0, 0, "Use texture intensity as a factor for texture force");
1280
1281                         uiBlockBeginAlign(block);
1282                         uiDefButS(block, ROW, B_CALCEFFECT, "RGB",              911,31,45,20, &paf->texmap, 14.0, 1.0, 0, 0, "Use RGB values as a factor for particle speed");
1283                         uiDefButS(block, ROW, B_CALCEFFECT, "Grad",             958,31,44,20, &paf->texmap, 14.0, 2.0, 0, 0, "Use texture gradient as a factor for particle speed");
1284                         uiDefButF(block, NUM, B_CALCEFFECT, "Nabla:",           911,9,91,20, &paf->nabla, 0.0001, 1.0, 1, 0, "Specify the dimension of the area for gradient calculation");
1285
1286                 }
1287         }
1288 }
1289
1290 static void object_panel_anim(Object *ob)
1291 {
1292         uiBlock *block;
1293         char str[32];
1294         
1295         block= uiNewBlock(&curarea->uiblocks, "object_panel_anim", UI_EMBOSS, UI_HELV, curarea->win);
1296         if(uiNewPanel(curarea, block, "Anim settings", "Object", 0, 0, 318, 204)==0) return;
1297         
1298         uiBlockBeginAlign(block);
1299         uiDefButC(block, ROW,REDRAWVIEW3D,"TrackX",     27,190,58,19, &ob->trackflag, 12.0, 0.0, 0, 0, "Specify the axis that points to another object");
1300         uiDefButC(block, ROW,REDRAWVIEW3D,"Y",          85,190,19,19, &ob->trackflag, 12.0, 1.0, 0, 0, "Specify the axis that points to another object");
1301         uiDefButC(block, ROW,REDRAWVIEW3D,"Z",          104,190,19,19, &ob->trackflag, 12.0, 2.0, 0, 0, "Specify the axis that points to another object");
1302         uiDefButC(block, ROW,REDRAWVIEW3D,"-X",         124,190,24,19, &ob->trackflag, 12.0, 3.0, 0, 0, "Specify the axis that points to another object");
1303         uiDefButC(block, ROW,REDRAWVIEW3D,"-Y",         150,190,24,19, &ob->trackflag, 12.0, 4.0, 0, 0, "Specify the axis that points to another object");
1304         uiDefButC(block, ROW,REDRAWVIEW3D,"-Z",         177,190,24,19, &ob->trackflag, 12.0, 5.0, 0, 0, "Specify the axis that points to another object");
1305         uiBlockBeginAlign(block);
1306         uiDefButC(block, ROW,REDRAWVIEW3D,"UpX",        226,190,45,19, &ob->upflag, 13.0, 0.0, 0, 0, "Specify the axis that points up");
1307         uiDefButC(block, ROW,REDRAWVIEW3D,"Y",          274,190,20,19, &ob->upflag, 13.0, 1.0, 0, 0, "Specify the axis that points up");
1308         uiDefButC(block, ROW,REDRAWVIEW3D,"Z",          297,190,19,19, &ob->upflag, 13.0, 2.0, 0, 0, "Specify the axis that points up");
1309         uiBlockBeginAlign(block);
1310         uiDefButC(block, TOG|BIT|0, REDRAWVIEW3D, "Draw Key",           25,160,70,19, &ob->ipoflag, 0, 0, 0, 0, "Draw object as key position");
1311         uiDefButC(block, TOG|BIT|1, REDRAWVIEW3D, "Draw Key Sel",       97,160,81,19, &ob->ipoflag, 0, 0, 0, 0, "Limit the drawing of object keys");
1312         uiDefButC(block, TOG|BIT|7, REDRAWVIEW3D, "Powertrack",         180,160,78,19, &ob->transflag, 0, 0, 0, 0, "Switch objects rotation off");
1313         uiDefButS(block, TOG|BIT|4, 0, "SlowPar",                                       261,160,56,19, &ob->partype, 0, 0, 0, 0, "Create a delay in the parent relationship");
1314         uiBlockBeginAlign(block);
1315         uiDefButC(block, TOG|BIT|3, REDRAWVIEW3D, "DupliFrames",        24,128,88,19, &ob->transflag, 0, 0, 0, 0, "Make copy of object for every frame");
1316         uiDefButC(block, TOG|BIT|4, REDRAWVIEW3D, "DupliVerts",         114,128,82,19, &ob->transflag, 0, 0, 0, 0, "Duplicate child objects on all vertices");
1317         uiDefButC(block, TOG|BIT|5, REDRAWVIEW3D, "Rot",                200,128,31,19, &ob->transflag, 0, 0, 0, 0, "Rotate dupli according to facenormal");
1318         uiDefButC(block, TOG|BIT|6, REDRAWVIEW3D, "No Speed",   234,128,82,19, &ob->transflag, 0, 0, 0, 0, "Set dupliframes to still, regardless of frame");
1319         uiBlockBeginAlign(block);
1320         uiDefButS(block, NUM, REDRAWVIEW3D, "DupSta:",          24,105,141,19, &ob->dupsta, 1.0, 17999.0, 0, 0, "Specify startframe for Dupliframes");
1321         uiDefButS(block, NUM, REDRAWVIEW3D, "DupOn:",           169,105,146,19, &ob->dupon, 1.0, 1500.0, 0, 0, "");
1322         uiDefButS(block, NUM, REDRAWVIEW3D, "DupEnd",           24,82,140,19, &ob->dupend, 1.0, 18000.0, 0, 0, "Specify endframe for Dupliframes");
1323         uiDefButS(block, NUM, REDRAWVIEW3D, "DupOff",           169,82,145,19, &ob->dupoff, 0.0, 1500.0, 0, 0, "");
1324         uiBlockBeginAlign(block);
1325         uiDefButC(block, TOG|BIT|2, REDRAWALL, "Offs Ob",                       23,51,56,20, &ob->ipoflag, 0, 0, 0, 0, "Let the timeoffset work on its own objectipo");
1326         uiDefButC(block, TOG|BIT|6, REDRAWALL, "Offs Par",                      82,51,56,20 , &ob->ipoflag, 0, 0, 0, 0, "Let the timeoffset work on the parent");
1327         uiDefButC(block, TOG|BIT|7, REDRAWALL, "Offs Particle",         141,51,103,20, &ob->ipoflag, 0, 0, 0, 0, "Let the timeoffset work on the particle effect");
1328         
1329         uiBlockBeginAlign(block);
1330         uiDefButF(block, NUM, REDRAWALL, "TimeOffset:",                 23,17,114,30, &ob->sf, -9000.0, 9000.0, 100, 0, "Specify an offset in frames");
1331         uiDefBut(block, BUT, B_AUTOTIMEOFS, "Automatic Time",   139,17,104,31, 0, 0, 0, 0, 0, "Generate automatic timeoffset values for all selected frames");
1332         uiDefBut(block, BUT, B_PRINTSPEED,      "PrSpeed",                      246,17,67,31, 0, 0, 0, 0, 0, "Print objectspeed");
1333         uiBlockEndAlign(block);
1334         
1335         sprintf(str, "%.4f", prspeed);
1336         uiDefBut(block, LABEL, 0, str,                                                  247,40,63,31, 0, 1.0, 0, 0, 0, "");
1337         
1338 }
1339
1340 void object_panels()
1341 {
1342         Object *ob;
1343
1344         /* check context here */
1345         ob= OBACT;
1346         if(ob) {
1347                 if(ob->id.lib) uiSetButLock(1, "Can't edit library data");
1348
1349                 object_panel_anim(ob);
1350                 object_panel_draw(ob);
1351                 object_panel_constraint();
1352                 if(ob->type==OB_MESH) object_panel_effects(ob);
1353                 
1354                 uiClearButLock();
1355         }
1356 }
1357