abb211818600ae9a02492707caab9ab305b7835a
[blender-staging.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 float hspeed=0.1, prspeed=0.0, prlen=0.0;
134
135
136
137 /* ********************* CONSTRAINT ***************************** */
138
139 static void activate_constraint_ipo_func (void *arg1v, void *unused)
140 {
141
142         bConstraint *con = arg1v;
143         bConstraintChannel *chan;
144         ListBase *conbase;
145
146         get_constraint_client(NULL, NULL, NULL);
147
148         conbase = get_constraint_client_channels(1);
149
150         if (!conbase)
151                 return;
152
153         /* See if this list already has an appropriate channel */
154         chan = find_constraint_channel(conbase, con->name);
155
156         if (!chan){
157                 /* Add a new constraint channel */
158                 chan = add_new_constraint_channel(con->name);
159                 BLI_addtail(conbase, chan);
160         }
161
162         /* Ensure there is an ipo to display */
163         if (!chan->ipo){
164                 chan->ipo = add_ipo(con->name, IPO_CO);
165         }
166
167         /* Make this the active channel */
168         OBACT->activecon = chan;
169
170         allqueue(REDRAWIPO, 0);
171         allqueue(REDRAWNLA, 0);
172 }
173
174 static void del_constraint_func (void *arg1v, void *arg2v)
175 {
176         bConstraint *con= arg1v;
177         Object *ob;
178
179         ListBase *lb= arg2v;
180         
181         ob=OBACT;
182         
183         if (ob->activecon && !strcmp(ob->activecon->name, con->name))
184                 ob->activecon = NULL;
185
186         free_constraint_data (con);
187
188         BLI_freelinkN(lb, con);
189
190         allqueue(REDRAWBUTSOBJECT, 0);
191         allqueue(REDRAWIPO, 0); 
192
193 }
194
195 static void verify_constraint_name_func (void *data, void *data2_unused)
196 {
197         ListBase *conlist;
198         bConstraint *con;
199         char ownerstr[64];
200         short type;
201         
202         con = (bConstraint*) data;
203         if (!con)
204                 return;
205         
206         conlist = get_constraint_client(ownerstr, &type, NULL);
207         unique_constraint_name (con, conlist);
208 }
209
210 static void constraint_changed_func (void *data, void *data2_unused)
211 {
212         bConstraint *con = (bConstraint*) data;
213
214         if (con->type == con->otype)
215                 return;
216
217         free_constraint_data (con);
218         con->data = new_constraint_data(con->type);
219
220 }
221
222 static void move_constraint_func (void *datav, void *data2_unused)
223 {
224         bConstraint *constraint_to_move= datav;
225         int val;
226         ListBase *conlist;
227         char ownerstr[64];
228         short   type;
229         bConstraint *curCon, *con, *neighbour;
230         
231         val= pupmenu("Move up%x1|Move down %x2");
232         
233         con = constraint_to_move;
234
235         if(val>0) {
236                 conlist = get_constraint_client(ownerstr, &type, NULL);
237                 for (curCon = conlist->first; curCon; curCon = curCon->next){
238                         if (curCon == con){
239                                 /* Move up */
240                                 if (val == 1 && con->prev){
241                                         neighbour = con->prev;
242                                         BLI_remlink(conlist, neighbour);
243                                         BLI_insertlink(conlist, con, neighbour);
244                                 }
245                                 /* Move down */
246                                 else if (val == 2 && con->next){
247                                         neighbour = con->next;
248                                         BLI_remlink (conlist, con);
249                                         BLI_insertlink(conlist, neighbour, con);
250                                 }
251                                 break;
252                         }
253                 }
254         }
255 }
256
257 static void get_constraint_typestring (char *str, bConstraint *con)
258 {
259         switch (con->type){
260         case CONSTRAINT_TYPE_CHILDOF:
261                 strcpy (str, "Child Of");
262                 return;
263         case CONSTRAINT_TYPE_NULL:
264                 strcpy (str, "Null");
265                 return;
266         case CONSTRAINT_TYPE_TRACKTO:
267                 strcpy (str, "Track To");
268                 return;
269         case CONSTRAINT_TYPE_KINEMATIC:
270                 strcpy (str, "IK Solver");
271                 return;
272         case CONSTRAINT_TYPE_ROTLIKE:
273                 strcpy (str, "Copy Rotation");
274                 return;
275         case CONSTRAINT_TYPE_LOCLIKE:
276                 strcpy (str, "Copy Location");
277                 return;
278         case CONSTRAINT_TYPE_ACTION:
279                 strcpy (str, "Action");
280                 return;
281         default:
282                 strcpy (str, "Unknown");
283                 return;
284         }
285 }
286
287 static BIFColorID get_constraint_col(bConstraint *con)
288 {
289         switch (con->type) {
290         case CONSTRAINT_TYPE_NULL:
291                 return BUTWHITE;
292         case CONSTRAINT_TYPE_KINEMATIC:
293                 return BUTPURPLE;
294         case CONSTRAINT_TYPE_TRACKTO:
295                 return BUTGREEN;
296         case CONSTRAINT_TYPE_ROTLIKE:
297                 return BUTBLUE;
298         case CONSTRAINT_TYPE_LOCLIKE:
299                 return BUTYELLOW;
300         case CONSTRAINT_TYPE_ACTION:
301                 return BUTPINK;
302         default:
303                 return REDALERT;
304         }
305 }
306
307 static void draw_constraint (uiBlock *block, ListBase *list, bConstraint *con, short *xco, short *yco, short type)
308 {
309         uiBut *but;
310         char typestr[64];
311         short height, width = 238;
312         BIFColorID curCol;
313
314         /* there is something weird in this function... opengl draw (glrects) doesnt match the buttons... */
315
316         uiBlockSetEmboss(block, UI_EMBOSSW);
317
318         get_constraint_typestring (typestr, con);
319
320         curCol = get_constraint_col(con);
321         /* Draw constraint header */
322         uiBlockSetCol(block, BUTSALMON);
323
324         but = uiDefIconBut(block, BUT, B_CONSTRAINT_REDRAW, ICON_X, *xco, *yco, 20, 20, list, 0.0, 0.0, 0.0, 0.0, "Delete constraint");
325
326         uiButSetFunc(but, del_constraint_func, con, list);
327
328         if (con->flag & CONSTRAINT_EXPAND) {
329                 uiBlockSetCol(block, BUTYELLOW);
330                 
331                 if (con->flag & CONSTRAINT_DISABLE)
332                         uiBlockSetCol(block, REDALERT);
333                 
334                 if (type==TARGET_BONE)
335                         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"); 
336                 else
337                         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"); 
338                 
339                 uiButSetFunc(but, constraint_changed_func, con, NULL);
340                 con->otype = con->type;
341                 
342                 but = uiDefBut(block, TEX, B_CONSTRAINT_REDRAW, "", *xco+120, *yco, 128, 20, con->name, 0.0, 32.0, 0.0, 0.0, "Constraint name"); 
343                 uiButSetFunc(but, verify_constraint_name_func, con, NULL);
344         }       
345         else{
346                 uiBlockSetEmboss(block, UI_EMBOSSP);
347                 uiBlockSetCol(block, BUTGREY);
348
349                 if (con->flag & CONSTRAINT_DISABLE) {
350                         uiBlockSetCol(block, REDALERT);
351                         BIF_set_color(REDALERT, COLORSHADE_MEDIUM);
352                 }
353                 else
354                         BIF_set_color(curCol, COLORSHADE_MEDIUM);
355
356                 glRects(*xco+34, *yco-12, *xco+266, *yco+5);
357                 
358                 but = uiDefBut(block, LABEL, B_CONSTRAINT_TEST, typestr, *xco+20, *yco, 100, 20, NULL, 0.0, 0.0, 0.0, 0.0, ""); 
359                 uiButSetFunc(but, move_constraint_func, con, NULL);
360                 but = uiDefBut(block, LABEL, B_CONSTRAINT_TEST, con->name, *xco+120, *yco, 128, 20, NULL, 0.0, 0.0, 0.0, 0.0, ""); 
361                 uiButSetFunc(but, move_constraint_func, con, NULL);
362         }
363
364         uiBlockSetCol(block, BUTGREY);  
365         
366         uiBlockSetEmboss(block, UI_EMBOSSW);
367         uiDefIconButS(block, ICONTOG|BIT|CONSTRAINT_EXPAND_BIT, B_CONSTRAINT_REDRAW, ICON_RIGHTARROW, *xco+248, *yco, 20, 20, &con->flag, 0.0, 0.0, 0.0, 0.0, "Collapse");
368
369
370         if (!(con->flag & CONSTRAINT_EXPAND)) {
371                 (*yco)-=21;
372                 return;
373         }
374
375         if (con->type!=CONSTRAINT_TYPE_NULL) {
376                 uiDefBut(block, NUMSLI|FLO, B_CONSTRAINT_REDRAW, "Influence:", *xco, *yco-20, 196, 20, &con->enforce, 0.0, 1.0, 0.0, 0.0, "Amount of influence this constraint will have on the final solution");
377                 but = uiDefBut(block, BUT, B_CONSTRAINT_REDRAW, "Edit Ipo", *xco+200, *yco-20, 64, 20, 0, 0.0, 1.0, 0.0, 0.0, "Show this constraint's ipo in the object's Ipo window");
378                 /* If this is on an object, add the constraint to the object */
379                 uiButSetFunc (but, activate_constraint_ipo_func, con, NULL);
380                 /* If this is on a bone, add the constraint to the action (if any) */
381                 (*yco)-=21;
382         }
383
384         /* Draw constraint data*/
385
386         switch (con->type){
387         case CONSTRAINT_TYPE_ACTION:
388                 {
389                         bActionConstraint *data = con->data;
390                         bArmature *arm;
391
392                         height = 86;
393                         BIF_set_color(curCol, COLORSHADE_MEDIUM);
394                         glRects(*xco+34, *yco-height-16, *xco+width+24, *yco-14);
395                         uiEmboss((float)*xco+34, (float)*yco-height-16, (float)*xco+width+24, (float)*yco-14, 1);
396
397                         /* Draw target parameters */
398                         uiDefIDPoinBut(block, test_obpoin_but, B_CONSTRAINT_CHANGETARGET, "OB:", *xco+((width/2)-48), *yco-20, 96, 18, &data->tar, "Target Object"); 
399
400                         arm = get_armature(data->tar);
401                         if (arm){
402                                 but=uiDefBut(block, TEX, B_CONSTRAINT_CHANGETARGET, "BO:", *xco+((width/2)-48), *yco-40,96,18, &data->subtarget, 0, 24, 0, 0, "Bone");
403                         }
404                         else
405                                 strcpy (data->subtarget, "");
406
407                         /* Draw action button */
408                         uiDefIDPoinBut(block, test_actionpoin_but, B_CONSTRAINT_CHANGETARGET, "AC:", *xco+((width/2)-120), *yco-60, 80, 18, &data->act, "Action containing the keyed motion for this bone"); 
409
410                         uiDefButS(block, NUM, B_CONSTRAINT_CHANGETARGET, "Start:", *xco+((width/2)-40), *yco-60, 80, 18, &data->start, 1, 18000, 0.0, 0.0, "Starting frame of the keyed motion"); 
411                         uiDefButS(block, NUM, B_CONSTRAINT_CHANGETARGET, "End:", *xco+((width/2)+40), *yco-60, 80, 18, &data->end, 1, 18000, 0.0, 0.0, "Ending frame of the keyed motion"); 
412                         
413                         /* Draw XYZ toggles */
414                         uiDefButI(block, MENU, B_CONSTRAINT_REDRAW, "Key on%t|X Rot%x0|Y Rot%x1|Z Rot%x2", *xco+((width/2)-120), *yco-80, 80, 18, &data->type, 0, 24, 0, 0, "Specify which transformation channel from the target is used to key the action");
415                         uiDefButF(block, NUM, B_CONSTRAINT_REDRAW, "Min:", *xco+((width/2)-40), *yco-80, 80, 18, &data->min, -180, 180, 0, 0, "Minimum value for target channel range");
416                         uiDefButF(block, NUM, B_CONSTRAINT_REDRAW, "Max:", *xco+((width/2)+40), *yco-80, 80, 18, &data->max, -180, 180, 0, 0, "Maximum value for target channel range");
417                         
418                 }
419                 break;
420         case CONSTRAINT_TYPE_LOCLIKE:
421                 {
422                         bLocateLikeConstraint *data = con->data;
423                         bArmature *arm;
424                         height = 66;
425                         BIF_set_color(curCol, COLORSHADE_MEDIUM);
426                         glRects(*xco+34, *yco-height-16, *xco+width+24, *yco-14);
427                         uiEmboss((float)*xco+34, (float)*yco-height-16, (float)*xco+width+24, (float)*yco-14, 1);
428
429                         /* Draw target parameters */
430                         uiDefIDPoinBut(block, test_obpoin_but, B_CONSTRAINT_CHANGETARGET, "OB:", *xco+((width/2)-48), *yco-20, 96, 18, &data->tar, "Target Object"); 
431
432                         arm = get_armature(data->tar);
433                         if (arm){
434                                 but=uiDefBut(block, TEX, B_CONSTRAINT_CHANGETARGET, "BO:", *xco+((width/2)-48), *yco-40,96,18, &data->subtarget, 0, 24, 0, 0, "Bone");
435                         }
436                         else
437                                 strcpy (data->subtarget, "");
438
439                         /* Draw XYZ toggles */
440                                 but=uiDefButI(block, TOG|BIT|0, B_CONSTRAINT_TEST, "X", *xco+((width/2)-48), *yco-60, 32, 18, &data->flag, 0, 24, 0, 0, "Copy X component");
441                                 but=uiDefButI(block, TOG|BIT|1, B_CONSTRAINT_TEST, "Y", *xco+((width/2)-16), *yco-60, 32, 18, &data->flag, 0, 24, 0, 0, "Copy Y component");
442                                 but=uiDefButI(block, TOG|BIT|2, B_CONSTRAINT_TEST, "Z", *xco+((width/2)+16), *yco-60, 32, 18, &data->flag, 0, 24, 0, 0, "Copy Z component");
443                 }
444                 break;
445         case CONSTRAINT_TYPE_ROTLIKE:
446                 {
447                         bRotateLikeConstraint *data = con->data;
448                         bArmature *arm;
449                         height = 46;
450                         BIF_set_color(curCol, COLORSHADE_MEDIUM);
451                         glRects(*xco+34, *yco-height-16, *xco+width+24, *yco-14);
452                         uiEmboss((float)*xco+34, (float)*yco-height-16, (float)*xco+width+24, (float)*yco-14, 1);
453
454                         uiDefIDPoinBut(block, test_obpoin_but, B_CONSTRAINT_CHANGETARGET, "OB:", *xco+((width/2)-48), *yco-20, 96, 18, &data->tar, "Target Object"); 
455
456                         arm = get_armature(data->tar);
457                         if (arm){
458                                 but=uiDefBut(block, TEX, B_CONSTRAINT_CHANGETARGET, "BO:", *xco+((width/2)-48), *yco-40,96,18, &data->subtarget, 0, 24, 0, 0, "Bone");
459                         }
460                         else
461                                 strcpy (data->subtarget, "");
462
463                 }
464                 break;
465         case CONSTRAINT_TYPE_KINEMATIC:
466                 {
467                         bKinematicConstraint *data = con->data;
468                         bArmature *arm;
469                         
470                         height = 66;
471                         BIF_set_color(curCol, COLORSHADE_MEDIUM);
472                         glRects(*xco+34, *yco-height-16, *xco+width+24, *yco-14);
473                         uiEmboss((float)*xco+34, (float)*yco-height-16, (float)*xco+width+24, (float)*yco-14, 1);
474                         
475                         uiDefButF(block, NUM, B_CONSTRAINT_REDRAW, "Tolerance:", *xco+((width/2)-96), *yco-20, 96, 18, &data->tolerance, 0.0001, 1.0, 0.0, 0.0, "Maximum distance to target after solving"); 
476                         uiDefButI(block, NUM, B_CONSTRAINT_REDRAW, "Iterations:", *xco+((width/2)), *yco-20, 96, 18, &data->iterations, 1, 10000, 0.0, 0.0, "Maximum number of solving iterations"); 
477
478                         uiDefIDPoinBut(block, test_obpoin_but, B_CONSTRAINT_CHANGETARGET, "OB:", *xco+((width/2)-48), *yco-40, 96, 18, &data->tar, "Target Object"); 
479                         
480                         arm = get_armature(data->tar);
481                         if (arm){
482                                 but=uiDefBut(block, TEX, B_CONSTRAINT_CHANGETARGET, "BO:", *xco+((width/2)-48), *yco-60,96,18, &data->subtarget, 0, 24, 0, 0, "Bone");
483                         }
484                         else
485                                 strcpy (data->subtarget, "");
486                         
487                 }
488                 break;
489         case CONSTRAINT_TYPE_NULL:
490                 {
491                         height = 20;
492                         BIF_set_color(curCol, COLORSHADE_MEDIUM);
493                         glRects(*xco+34, *yco-height-16, *xco+width+24, *yco-14);
494                         uiEmboss((float)*xco+34, (float)*yco-height-16, (float)*xco+width+24, (float)*yco-14, 1);
495                 }
496                 break;
497         case CONSTRAINT_TYPE_TRACKTO:
498                 {
499                         bTrackToConstraint *data = con->data;
500                         bArmature *arm;
501
502                         height = 46;
503                         BIF_set_color(curCol, COLORSHADE_MEDIUM);
504                         glRects(*xco+34, *yco-height-16, *xco+width+24, *yco-14);
505                         uiEmboss((float)*xco+34, (float)*yco-height-16, (float)*xco+width+24, (float)*yco-14, 1);
506                         
507                         uiDefIDPoinBut(block, test_obpoin_but, B_CONSTRAINT_CHANGETARGET, "OB:", *xco+((width/2)-48), *yco-20, 96, 18, &data->tar, "Target Object"); 
508                         
509                         arm = get_armature(data->tar);
510                         if (arm){
511                                 but=uiDefBut(block, TEX, B_CONSTRAINT_CHANGETARGET, "BO:", *xco+((width/2)-48), *yco-40,96,18, &data->subtarget, 0, 24, 0, 0, "Bone");
512                         }
513                         else
514                                 strcpy (data->subtarget, "");
515                 }
516                 break;
517         default:
518                 height = 0;
519                 break;
520         }
521
522         (*yco)-=(24+height);
523
524 }
525
526
527 void do_constraintbuts(unsigned short event)
528 {
529         ListBase *list;
530         short   type;
531
532         switch(event) {
533         case B_CONSTRAINT_CHANGENAME:
534                 break;
535         case B_CONSTRAINT_TEST:
536                 test_scene_constraints();
537                 allqueue (REDRAWVIEW3D, 0);
538                 allqueue (REDRAWBUTSOBJECT, 0);
539                 break;
540         case B_CONSTRAINT_REDRAW:
541                 test_scene_constraints();
542                 allqueue (REDRAWVIEW3D, 0);
543                 allqueue (REDRAWBUTSOBJECT, 0);
544                 break;
545         case B_CONSTRAINT_CHANGETARGET:
546                 test_scene_constraints();
547                 allqueue (REDRAWVIEW3D, 0);
548                 allqueue (REDRAWBUTSOBJECT, 0);
549                 break;
550         case B_CONSTRAINT_CHANGETYPE:
551                 test_scene_constraints();
552                 allqueue (REDRAWVIEW3D, 0);
553                 allqueue (REDRAWBUTSOBJECT, 0);
554                 break;
555         case B_CONSTRAINT_ADD:
556                 {
557                         bConstraint *con;
558                 //      ListBase *chanbase;
559                 //      bConstraintChannel *chan;
560
561                 //      Object *ob = OBACT;
562                         list = get_constraint_client(NULL, &type, NULL);
563                 //      chanbase= get_constraint_client_channels(0);
564                         if (list){
565                                 con = add_new_constraint();
566                                 unique_constraint_name(con, list);
567                 //              chan = add_new_constraint_channel(con->name);
568                 //              ob->activecon = chan;
569                 //              BLI_addtail(chanbase, chan);
570                                 BLI_addtail(list, con);
571                         }
572                         test_scene_constraints();
573                         allqueue (REDRAWVIEW3D, 0);
574                         allqueue (REDRAWBUTSOBJECT, 0);
575                 }
576                 break;
577         case B_CONSTRAINT_DEL:
578                 test_scene_constraints();
579                 allqueue (REDRAWVIEW3D, 0);
580                 allqueue (REDRAWBUTSOBJECT, 0);
581                 break;
582         default:
583                 break;
584         }
585 }
586
587 static void object_panel_constraint(void)
588 {
589         uiBlock *block;
590         ListBase *conlist;
591         bConstraint *curcon;
592         short xco, yco, type;
593         char ownerstr[64];
594         
595         block= uiNewBlock(&curarea->uiblocks, "object_panel_constraint", UI_EMBOSSX, UI_HELV, curarea->win);
596         uiNewPanelTabbed("Effects", "Object");
597         if(uiNewPanel(curarea, block, "Constraints", "Object", 640, 0, 318, 204)==0) return;
598
599         /* this is a variable height panel, newpanel doesnt force new size on existing panels */
600         /* so first we make it default height */
601         uiNewPanelHeight(block, 204);
602
603         conlist = get_constraint_client(ownerstr, &type, NULL);
604         
605         if (conlist) {
606                  
607                 uiBlockSetCol(block, BUTSALMON);
608                 uiDefBut(block, BUT, B_CONSTRAINT_ADD, "Add", 10, 190, 95, 20, 0, 0.0, 0, 0, 0,"Add new constraint");
609                 
610                 /* Go through the list of constraints and draw them */
611                 xco = 10;
612                 yco = 160;
613                 // local panel coords
614                 uiPanelPush(block);
615                 
616                 for (curcon = conlist->first; curcon; curcon=curcon->next) {
617                         /* Draw default constraint header */                    
618                         draw_constraint(block, conlist, curcon, &xco, &yco, type);      
619                 }
620                 
621                 uiPanelPop(block);
622                 
623                 if(yco < 0) uiNewPanelHeight(block, 204-yco);
624                 
625         }
626 }
627
628
629
630
631 /* *************** */
632
633
634 #include "BLI_editVert.h"
635 extern ListBase editNurb;
636
637 void do_common_editbuts(unsigned short event) // old name, is a mix of object and editing events.... 
638 {
639         EditVlak *evl;
640         Base *base;
641         Object *ob;
642         Mesh *me;
643         Nurb *nu;
644         Curve *cu;
645         MFace *mface;
646         BezTriple *bezt;
647         BPoint *bp;
648         unsigned int local;
649         int a, bit, index= -1;
650
651         switch(event) {
652                 
653         case B_MATWICH:
654                 if(G.obedit && G.obedit->actcol>0) {
655                         if(G.obedit->type == OB_MESH) {
656                                 evl= G.edvl.first;
657                                 while(evl) {
658                                         if( vlakselectedAND(evl, 1) ) {
659                                                 if(index== -1) index= evl->mat_nr;
660                                                 else if(index!=evl->mat_nr) {
661                                                         error("Mixed colors");
662                                                         return;
663                                                 }
664                                         }
665                                         evl= evl->next;
666                                 }
667                         }
668                         else if ELEM(G.obedit->type, OB_CURVE, OB_SURF) {
669                                 nu= editNurb.first;
670                                 while(nu) {
671                                         if( isNurbsel(nu) ) {
672                                                 if(index== -1) index= nu->mat_nr;
673                                                 else if(index!=nu->mat_nr) {
674                                                         error("Mixed colors");
675                                                         return;
676                                                 }
677                                         }
678                                         nu= nu->next;
679                                 }                               
680                         }
681                         if(index>=0) {
682                                 G.obedit->actcol= index+1;
683                                 scrarea_queue_winredraw(curarea);
684                         }
685                 }
686                 break;
687         case B_MATNEW:
688                 new_material_to_objectdata((G.scene->basact) ? (G.scene->basact->object) : 0);
689                 scrarea_queue_winredraw(curarea);
690                 allqueue(REDRAWVIEW3D_Z, 0);
691                 break;
692         case B_MATDEL:
693                 delete_material_index();
694                 scrarea_queue_winredraw(curarea);
695                 allqueue(REDRAWVIEW3D_Z, 0);
696                 break;
697         case B_MATASS:
698                 if(G.obedit && G.obedit->actcol>0) {
699                         if(G.obedit->type == OB_MESH) {
700                                 undo_push_mesh("Assign material index");
701                                 evl= G.edvl.first;
702                                 while(evl) {
703                                         if( vlakselectedAND(evl, 1) )
704                                                 evl->mat_nr= G.obedit->actcol-1;
705                                         evl= evl->next;
706                                 }
707                                 allqueue(REDRAWVIEW3D_Z, 0);
708                                 makeDispList(G.obedit);
709                         }
710                         else if ELEM(G.obedit->type, OB_CURVE, OB_SURF) {
711                                 nu= editNurb.first;
712                                 while(nu) {
713                                         if( isNurbsel(nu) )
714                                                 nu->mat_nr= G.obedit->actcol-1;
715                                         nu= nu->next;
716                                 }
717                         }
718                 }
719                 break;
720         case B_MATSEL:
721         case B_MATDESEL:
722                 if(G.obedit) {
723                         if(G.obedit->type == OB_MESH) {
724                                 evl= G.edvl.first;
725                                 while(evl) {
726                                         if(evl->mat_nr== G.obedit->actcol-1) {
727                                                 if(event==B_MATSEL) {
728                                                         if(evl->v1->h==0) evl->v1->f |= 1;
729                                                         if(evl->v2->h==0) evl->v2->f |= 1;
730                                                         if(evl->v3->h==0) evl->v3->f |= 1;
731                                                         if(evl->v4 && evl->v4->h==0) evl->v4->f |= 1;
732                                                 }
733                                                 else {
734                                                         if(evl->v1->h==0) evl->v1->f &= ~1;
735                                                         if(evl->v2->h==0) evl->v2->f &= ~1;
736                                                         if(evl->v3->h==0) evl->v3->f &= ~1;
737                                                         if(evl->v4 && evl->v4->h==0) evl->v4->f &= ~1;
738                                                 }
739                                         }
740                                         evl= evl->next;
741                                 }
742                                 tekenvertices_ext( event==B_MATSEL );
743                         }
744                         else if ELEM(G.obedit->type, OB_CURVE, OB_SURF) {
745                                 nu= editNurb.first;
746                                 while(nu) {
747                                         if(nu->mat_nr==G.obedit->actcol-1) {
748                                                 if(nu->bezt) {
749                                                         a= nu->pntsu;
750                                                         bezt= nu->bezt;
751                                                         while(a--) {
752                                                                 if(bezt->hide==0) {
753                                                                         if(event==B_MATSEL) {
754                                                                                 bezt->f1 |= 1;
755                                                                                 bezt->f2 |= 1;
756                                                                                 bezt->f3 |= 1;
757                                                                         }
758                                                                         else {
759                                                                                 bezt->f1 &= ~1;
760                                                                                 bezt->f2 &= ~1;
761                                                                                 bezt->f3 &= ~1;
762                                                                         }
763                                                                 }
764                                                                 bezt++;
765                                                         }
766                                                 }
767                                                 else if(nu->bp) {
768                                                         a= nu->pntsu*nu->pntsv;
769                                                         bp= nu->bp;
770                                                         while(a--) {
771                                                                 if(bp->hide==0) {
772                                                                         if(event==B_MATSEL) bp->f1 |= 1;
773                                                                         else bp->f1 &= ~1;
774                                                                 }
775                                                                 bp++;
776                                                         }
777                                                 }
778                                         }
779                                         nu= nu->next;
780                                 }
781                                 allqueue(REDRAWVIEW3D, 0);
782                         }
783                 }
784                 break;
785         case B_HIDE:
786                 if(G.obedit) {
787                         if(G.obedit->type == OB_MESH) hide_mesh(0);
788                         else if ELEM(G.obedit->type, OB_CURVE, OB_SURF) hideNurb(0);
789                 }
790                 break;
791         case B_REVEAL:
792                 if(G.obedit) {
793                         if(G.obedit->type == OB_MESH) reveal_mesh();
794                         else if ELEM(G.obedit->type, OB_CURVE, OB_SURF) revealNurb();
795                 }
796                 else if(G.f & G_FACESELECT) reveal_tface();
797                 
798                 break;
799         case B_SELSWAP:
800                 if(G.obedit) {
801                         if(G.obedit->type == OB_MESH) selectswap_mesh();
802                         else if ELEM(G.obedit->type, OB_CURVE, OB_SURF) selectswapNurb();
803                 }
804                 break;
805         case B_AUTOTEX:
806                 ob= OBACT;
807                 if(ob && G.obedit==0) {
808                         if(ob->type==OB_MESH) tex_space_mesh(ob->data);
809                         else if(ob->type==OB_MBALL) ;
810                         else tex_space_curve(ob->data);
811                 }
812                 break;
813         case B_DOCENTRE:
814                 docentre();
815                 break;
816         case B_DOCENTRENEW:
817                 docentre_new();
818                 break;
819         case B_DOCENTRECURSOR:
820                 docentre_cursor();
821                 break;
822         case B_SETSMOOTH:
823         case B_SETSOLID:
824                 if(G.obedit) {
825                         if(G.obedit->type == OB_MESH) {
826                                 evl= G.edvl.first;
827                                 if (event == B_SETSMOOTH) undo_push_mesh("Set Smooth");
828                                 else if (event==B_SETSOLID) undo_push_mesh("Set Solid");
829                                 while(evl) {
830                                         if( vlakselectedAND(evl, 1) ) {
831                                                 if(event==B_SETSMOOTH) evl->flag |= ME_SMOOTH;
832                                                 else evl->flag &= ~ME_SMOOTH;
833                                         }
834                                         evl= evl->next;
835                                 }
836
837                                 makeDispList(G.obedit);
838                                 allqueue(REDRAWVIEW3D, 0);
839                         }
840                         else {
841                                 nu= editNurb.first;
842                                 while(nu) {
843                                         if(isNurbsel(nu)) {
844                                                 if(event==B_SETSMOOTH) nu->flag |= ME_SMOOTH;
845                                                 else nu->flag &= ~ME_SMOOTH;
846                                         }
847                                         nu= nu->next;
848                                 }
849                                 
850                         }
851                 }
852                 else {
853                         base= FIRSTBASE;
854                         while(base) {
855                                 if(TESTBASELIB(base)) {
856                                         if(base->object->type==OB_MESH) {
857                                                 me= base->object->data;
858                                                 mface= me->mface;
859                                                 for(a=0; a<me->totface; a++, mface++) {
860                                                         if(event==B_SETSMOOTH) mface->flag |= ME_SMOOTH;
861                                                         else mface->flag &= ~ME_SMOOTH;
862                                                 }
863
864                                                 makeDispList(base->object);
865                                         }
866                                         else if ELEM(base->object->type, OB_SURF, OB_CURVE) {
867                                                 cu= base->object->data;
868                                                 nu= cu->nurb.first;
869                                                 while(nu) {
870                                                         if(event==B_SETSMOOTH) nu->flag |= ME_SMOOTH;
871                                                         else nu->flag &= ~ME_SMOOTH;
872                                                         nu= nu->next;
873                                                 }
874                                         }
875                                 }
876                                 base= base->next;
877                         }
878                         allqueue(REDRAWVIEW3D, 0);
879                 }
880                 break;
881
882         default:
883                 if(event>=B_OBLAY && event<=B_OBLAY+31) {
884                         local= BASACT->lay & 0xFF000000;
885                         BASACT->lay -= local;
886                         if(BASACT->lay==0 || (G.qual & LR_SHIFTKEY)==0) {
887                                 bit= event-B_OBLAY;
888                                 BASACT->lay= 1<<bit;
889                                 scrarea_queue_winredraw(curarea);
890                         }
891                         BASACT->lay += local;
892                         /* optimal redraw */
893                         if( (OBACT->lay & G.vd->lay) && (BASACT->lay & G.vd->lay) );
894                         else if( (OBACT->lay & G.vd->lay)==0 && (BASACT->lay & G.vd->lay)==0 );
895                         else allqueue(REDRAWVIEW3D, 0);
896                         
897                         OBACT->lay= BASACT->lay;
898                 }
899         }
900
901 }
902
903 void object_panel_draw(Object *ob)
904 {
905         ID *id;
906         uiBlock *block;
907         int xco, a, dx, dy;
908         
909         
910         block= uiNewBlock(&curarea->uiblocks, "object_panel_draw", UI_EMBOSSX, UI_HELV, curarea->win);
911         if(uiNewPanel(curarea, block, "Draw", "Object", 320, 0, 318, 204)==0) return;
912
913         /* LAYERS */
914         xco= 151;
915         dx= 32;
916         dy= 30;
917         for(a=0; a<10; a++) {
918                 /* the (a+10) evaluates correctly because of
919            precedence... brackets aren't a bad idea though */
920                 uiDefButI(block, TOG|BIT|(a+10), B_OBLAY+a+10, "",      (short)(xco+a*(dx/2)), 180, (short)(dx/2), (short)(dy/2), &(BASACT->lay), 0, 0, 0, 0, "");
921                 uiDefButI(block, TOG|BIT|a, B_OBLAY+a, "",(short)(xco+a*(dx/2)), (short)(180+dy/2), (short)(dx/2), (short)(1+dy/2), &(BASACT->lay), 0, 0, 0, 0, "");
922                 if(a==4) xco+= 5;
923         }
924
925         id= ob->data;
926         if(id && id->lib) uiSetButLock(1, "Can't edit library data");
927
928         uiBlockSetCol(block, BUTGREY);
929         uiDefBut(block, LABEL, 0, "Drawtype",                                           28,200,100,18, 0, 0, 0, 0, 0, "");
930         uiDefButC(block, MENU, REDRAWVIEW3D, "Drawtype%t|Bounds %x1|Wire %x2|Solid %x3|Shaded %x4",     
931                                                                                                                                 28,180,100,18, &ob->dt, 0, 0, 0, 0, "Sets the drawing type of the active object");
932         uiDefBut(block, LABEL, 0, "Draw Extra",                                         28,160,100,18, 0, 0, 0, 0, 0, "");
933         uiDefButC(block, TOG|BIT|0, REDRAWVIEW3D, "Bounds",             28, 140, 100, 18, &ob->dtx, 0, 0, 0, 0, "Displays the active object's bounds");
934         uiDefButS(block, MENU, REDRAWVIEW3D, "Boundary Display%t|Box%x0|Sphere%x1|Cylinder%x2|Cone%x3|Polyheder",
935                                                                                                                                 28, 120, 100, 18, &ob->boundtype, 0, 0, 0, 0, "Selects the boundary display type");
936         uiDefButC(block, TOG|BIT|5, REDRAWVIEW3D, "Wire",               28, 100, 100, 18, &ob->dtx, 0, 0, 0, 0, "Displays the active object's wireframe in shaded drawing modes");
937         uiDefButC(block, TOG|BIT|1, REDRAWVIEW3D, "Axis",               28, 80, 100, 18, &ob->dtx, 0, 0, 0, 0, "Displays the active object's centre and axis");
938         uiDefButC(block, TOG|BIT|2, REDRAWVIEW3D, "TexSpace",   28, 60, 100, 18, &ob->dtx, 0, 0, 0, 0, "Displays the active object's texture space");
939         uiDefButC(block, TOG|BIT|3, REDRAWVIEW3D, "Name",               28, 40, 100, 18, &ob->dtx, 0, 0, 0, 0, "Displays the active object's name");
940         
941         uiBlockSetCol(block, BUTGREY);
942         
943 }
944
945
946
947
948 void do_object_panels(unsigned short event)
949 {
950         Object *ob;
951         Base *base;
952         Effect *eff, *effn;
953         int type;
954         
955         ob= OBACT;
956
957         switch(event) {
958                 
959         case B_RECALCPATH:
960                 calc_curvepath(OBACT);
961                 allqueue(REDRAWVIEW3D, 0);
962                 break;
963         case B_MUL_IPO:
964                 scale_editipo();
965                 allqueue(REDRAWBUTSOBJECT, 0);
966                 break;
967         case B_AUTOTIMEOFS:
968                 auto_timeoffs();
969                 break;
970         case B_FRAMEMAP:
971                 G.scene->r.framelen= G.scene->r.framapto;
972                 G.scene->r.framelen/= G.scene->r.images;
973                 break;
974         case B_NEWEFFECT:
975                 if(ob) {
976                         if (BLI_countlist(&ob->effect)==MAX_EFFECT)
977                                 error("Unable to add: effect limit reached");
978                         else
979                                 copy_act_effect(ob);
980                 }
981                 allqueue(REDRAWBUTSOBJECT, 0);
982                 break;
983         case B_DELEFFECT:
984                 if(ob==0 || ob->type!=OB_MESH) break;
985                 eff= ob->effect.first;
986                 while(eff) {
987                         effn= eff->next;
988                         if(eff->flag & SELECT) {
989                                 BLI_remlink(&ob->effect, eff);
990                                 free_effect(eff);
991                                 break;
992                         }
993                         eff= effn;
994                 }
995                 allqueue(REDRAWBUTSOBJECT, 0);
996                 allqueue(REDRAWVIEW3D, 0);
997                 break;
998         case B_NEXTEFFECT:
999                 if(ob==0 || ob->type!=OB_MESH) break;
1000                 eff= ob->effect.first;
1001                 while(eff) {
1002                         if(eff->flag & SELECT) {
1003                                 if(eff->next) {
1004                                         eff->flag &= ~SELECT;
1005                                         eff->next->flag |= SELECT;
1006                                 }
1007                                 break;
1008                         }
1009                         eff= eff->next;
1010                 }
1011                 allqueue(REDRAWBUTSOBJECT, 0);
1012                 break;
1013         case B_PREVEFFECT:
1014                 if(ob==0 || ob->type!=OB_MESH) break;
1015                 eff= ob->effect.first;
1016                 while(eff) {
1017                         if(eff->flag & SELECT) {
1018                                 if(eff->prev) {
1019                                         eff->flag &= ~SELECT;
1020                                         eff->prev->flag |= SELECT;
1021                                 }
1022                                 break;
1023                         }
1024                         eff= eff->next;
1025                 }
1026                 allqueue(REDRAWBUTSOBJECT, 0);
1027                 break;
1028         case B_CHANGEEFFECT:
1029                 if(ob==0 || ob->type!=OB_MESH) break;
1030                 eff= ob->effect.first;
1031                 while(eff) {
1032                         if(eff->flag & SELECT) {
1033                                 if(eff->type!=eff->buttype) {
1034                                         BLI_remlink(&ob->effect, eff);
1035                                         type= eff->buttype;
1036                                         free_effect(eff);
1037                                         eff= add_effect(type);
1038                                         BLI_addtail(&ob->effect, eff);
1039                                 }
1040                                 break;
1041                         }
1042                         eff= eff->next;
1043                 }
1044                 allqueue(REDRAWBUTSOBJECT, 0);
1045                 allqueue(REDRAWVIEW3D, 0);
1046                 break;
1047         case B_CALCEFFECT:
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_PARTICLE) build_particle_system(ob);
1053                                 else if(eff->type==EFF_WAVE) object_wave(ob);
1054                         }
1055                         eff= eff->next;
1056                 }
1057                 allqueue(REDRAWVIEW3D, 0);
1058                 allqueue(REDRAWBUTSOBJECT, 0);
1059                 break;
1060         case B_RECALCAL:
1061                 base= FIRSTBASE;
1062                 while(base) {
1063                         if(base->lay & G.vd->lay) {
1064                                 ob= base->object;
1065                                 eff= ob->effect.first;
1066                                 while(eff) {
1067                                         if(eff->flag & SELECT) {
1068                                                 if(eff->type==EFF_PARTICLE) build_particle_system(ob);
1069                                         }
1070                                         eff= eff->next;
1071                                 }
1072                         }
1073                         base= base->next;
1074                 }
1075                 allqueue(REDRAWVIEW3D, 0);
1076                 break;
1077         case B_SETSPEED:
1078                 set_speed_editipo(hspeed);
1079                 break;
1080         case B_PRINTSPEED:
1081                 ob= OBACT;
1082                 if(ob) {
1083                         float vec[3];
1084                         CFRA++;
1085                         do_ob_ipo(ob);
1086                         where_is_object(ob);
1087                         VECCOPY(vec, ob->obmat[3]);
1088                         CFRA--;
1089                         do_ob_ipo(ob);
1090                         where_is_object(ob);
1091                         VecSubf(vec, vec, ob->obmat[3]);
1092                         prspeed= Normalise(vec);
1093                         scrarea_queue_winredraw(curarea);
1094                 }
1095                 break;
1096         case B_PRINTLEN:
1097                 ob= OBACT;
1098                 if(ob && ob->type==OB_CURVE) {
1099                         Curve *cu=ob->data;
1100                         
1101                         if(cu->path) prlen= cu->path->totdist; else prlen= -1.0;
1102                         scrarea_queue_winredraw(curarea);
1103                 } 
1104                 break;
1105         case B_RELKEY:
1106                 allspace(REMAKEIPO, 0);
1107                 allqueue(REDRAWBUTSOBJECT, 0);
1108                 allqueue(REDRAWIPO, 0);
1109                 break;
1110                 
1111         default:
1112                 if(event>=B_SELEFFECT && event<B_SELEFFECT+MAX_EFFECT) {
1113                         ob= OBACT;
1114                         if(ob) {
1115                                 int a=B_SELEFFECT;
1116                                 
1117                                 eff= ob->effect.first;
1118                                 while(eff) {
1119                                         if(event==a) eff->flag |= SELECT;
1120                                         else eff->flag &= ~SELECT;
1121                                         
1122                                         a++;
1123                                         eff= eff->next;
1124                                 }
1125                                 allqueue(REDRAWBUTSOBJECT, 0);
1126                         }
1127                 }
1128         }
1129
1130 }
1131
1132 void object_panel_effects(Object *ob)
1133 {
1134         Effect *eff;
1135         uiBlock *block;
1136         int a;
1137         short x, y;
1138         
1139         block= uiNewBlock(&curarea->uiblocks, "object_panel_effects", UI_EMBOSSX, UI_HELV, curarea->win);
1140         if(uiNewPanel(curarea, block, "Effects", "Object", 640, 0, 418, 204)==0) return;
1141
1142         uiBlockSetCol(block, BUTSALMON);
1143         
1144         /* EFFECTS */
1145         
1146         if (ob->type == OB_MESH) {
1147                 uiDefBut(block, BUT, B_NEWEFFECT, "NEW Effect", 550,187,124,27, 0, 0, 0, 0, 0, "Create a new effect");
1148                 uiDefBut(block, BUT, B_DELEFFECT, "Delete", 676,187,62,27, 0, 0, 0, 0, 0, "Delete the effect");
1149         }
1150
1151         uiBlockSetCol(block, BUTGREY);
1152         
1153         /* select effs */
1154         eff= ob->effect.first;
1155         a= 0;
1156         while(eff) {
1157                 
1158                 x= 15 * a + 550;
1159                 y= 172; // - 12*( abs(a/10) ) ;
1160                 uiDefButS(block, TOG|BIT|0, B_SELEFFECT+a, "", x, y, 15, 12, &eff->flag, 0, 0, 0, 0, "");
1161                 
1162                 a++;
1163                 if(a==MAX_EFFECT) break;
1164                 eff= eff->next;
1165         }
1166         
1167         eff= ob->effect.first;
1168         while(eff) {
1169                 if(eff->flag & SELECT) break;
1170                 eff= eff->next;
1171         }
1172         
1173         if(eff) {
1174                 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");
1175                 
1176                 if(eff->type==EFF_BUILD) {
1177                         BuildEff *bld;
1178                         
1179                         bld= (BuildEff *)eff;
1180                         
1181                         uiDefButF(block, NUM, 0, "Len:",                        649,138,95,21, &bld->len, 1.0, 9000.0, 100, 0, "Specify the total time the building requires");
1182                         uiDefButF(block, NUM, 0, "Sfra:",                       746,138,94,22, &bld->sfra, 1.0, 9000.0, 100, 0, "Specify the startframe of the effect");
1183                 }
1184                 else if(eff->type==EFF_WAVE) {
1185                         WaveEff *wav;
1186                         
1187                         wav= (WaveEff *)eff;
1188                         
1189                         uiBlockSetCol(block, BUTGREEN);
1190                         uiDefButS(block, TOG|BIT|1, B_CALCEFFECT, "X",          782,135,54,23, &wav->flag, 0, 0, 0, 0, "Enable X axis");
1191                         uiDefButS(block, TOG|BIT|2, B_CALCEFFECT, "Y",          840,135,47,23, &wav->flag, 0, 0, 0, 0, "Enable Y axis");
1192                         uiDefButS(block, TOG|BIT|3, B_CALCEFFECT, "Cycl",               890,135,111,23, &wav->flag, 0, 0, 0, 0, "Enable cyclic wave efefct");
1193                         
1194                         uiBlockSetCol(block, BUTGREY);
1195                         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");
1196                         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");
1197                         
1198                         uiDefButF(block, NUMSLI, B_CALCEFFECT, "Speed:",        550,100,216,20, &wav->speed, -2.0, 2.0, 0, 0, "Specify the wave speed");
1199                         uiDefButF(block, NUMSLI, B_CALCEFFECT, "Heigth:",       550,80,216,20, &wav->height, -2.0, 2.0, 0, 0, "Specify the amplitude of the wave");
1200                         uiDefButF(block, NUMSLI, B_CALCEFFECT, "Width:",        550,60,216,20, &wav->width, 0.0, 5.0, 0, 0, "Specify the width of the wave");
1201                         uiDefButF(block, NUMSLI, B_CALCEFFECT, "Narrow:",       550,40,216,20, &wav->narrow, 0.0, 10.0, 0, 0, "Specify how narrow the wave follows");
1202
1203                         uiDefButF(block, NUM, B_CALCEFFECT, "Time sta:",        780,100,219,20, &wav->timeoffs, -1000.0, 1000.0, 100, 0, "Specify startingframe of the wave");
1204
1205                         uiDefButF(block, NUM, B_CALCEFFECT, "Lifetime:",        780,80,219,20, &wav->lifetime,  -1000.0, 1000.0, 100, 0, "Specify the lifespan of the wave");
1206                         uiDefButF(block, NUM, B_CALCEFFECT, "Damptime:",        780,60,219,20, &wav->damp,  -1000.0, 1000.0, 100, 0, "Specify the dampingtime of the wave");
1207
1208                 }
1209                 else if(eff->type==EFF_PARTICLE) {
1210                         PartEff *paf;
1211                         
1212                         paf= (PartEff *)eff;
1213                         
1214                         uiDefBut(block, BUT, B_RECALCAL, "RecalcAll", 741,187,67,27, 0, 0, 0, 0, 0, "Update the particle system");
1215                         uiBlockSetCol(block, BUTGREEN);
1216                         uiDefButS(block, TOG|BIT|2, B_CALCEFFECT, "Static",     825,187,67,27, &paf->flag, 0, 0, 0, 0, "Make static particles");
1217                         uiBlockSetCol(block, BUTGREY);
1218                         
1219                         uiDefButI(block, NUM, B_CALCEFFECT, "Tot:",             550,146,91,20, &paf->totpart, 1.0, 100000.0, 0, 0, "Set the total number of particles");
1220                         if(paf->flag & PAF_STATIC) {
1221                                 uiDefButS(block, NUM, REDRAWVIEW3D, "Step:",            644,146,84,20, &paf->staticstep, 1.0, 100.0, 10, 0, "");
1222                         }
1223                         else {
1224                                 uiDefButF(block, NUM, B_CALCEFFECT, "Sta:",             644,146,84,20, &paf->sta, -250.0, 9000.0, 100, 0, "Specify the startframe");
1225                                 uiDefButF(block, NUM, B_CALCEFFECT, "End:",             731,146,97,20, &paf->end, 1.0, 9000.0, 100, 0, "Specify the endframe");
1226                         }
1227                         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");
1228                         uiDefButI(block, NUM, B_CALCEFFECT, "Keys:",            922,146,80,20, &paf->totkey, 1.0, 32.0, 0, 0, "Specify the number of key positions");
1229                         
1230                         uiBlockSetCol(block, BUTGREEN);
1231                         uiDefButS(block, NUM, B_REDR,           "CurMul:",              550,124,91,20, &paf->curmult, 0.0, 3.0, 0, 0, "Multiply the particles");
1232                         uiBlockSetCol(block, BUTGREY);
1233                         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");
1234                         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.");
1235                         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");
1236                         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");
1237
1238                         uiDefButF(block, NUM, B_CALCEFFECT, "Randlife:",        550,96,96,20, &paf->randlife, 0.0, 2.0, 10, 0, "Give the particlelife a random variation");
1239                         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");
1240
1241                         uiDefButF(block, NUM, B_DIFF,                   "VectSize",             885,96,116,20, &paf->vectsize, 0.0, 1.0, 10, 0, "Set the speed for Vect");      
1242                         uiBlockSetCol(block, BUTGREEN);
1243                         uiDefButS(block, TOG|BIT|3, B_CALCEFFECT, "Face",                               735,96,46,20, &paf->flag, 0, 0, 0, 0, "Emit particles also from faces");
1244                         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");
1245                         uiDefButS(block, TOG, REDRAWVIEW3D, "Vect",                                     837,96,45,20, &paf->stype, 0, 0, 0, 0, "Give the particles a rotation direction");
1246                         
1247                         uiBlockSetCol(block, BUTPURPLE);
1248                         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");
1249                         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");
1250                         uiDefButF(block, NUM, B_CALCEFFECT, "Rand:",            738,67,86,20, &paf->randfac, 0.0, 2.0, 10, 0, "Give the startingspeed a random variation");
1251                         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");
1252                         uiDefButF(block, NUM, B_CALCEFFECT, "Damp:",            913,67,89,20, &paf->damp, 0.0, 1.0, 10, 0, "Specify the damping factor");
1253
1254                         uiBlockSetCol(block, BUTGREY);
1255                         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");
1256                         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");
1257                         uiDefBut(block, LABEL, 0, "Force:",                                             550,9,72,20, 0, 1.0, 0, 0, 0, "");
1258                         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");
1259
1260                         uiDefBut(block, LABEL, 0, "Texture:",                           722,9,74,20, 0, 1.0, 0, 0, 0, "");
1261                         uiBlockSetCol(block, BUTGREEN);
1262                         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");
1263                         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");
1264                         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");
1265                         uiBlockSetCol(block, BUTGREY);
1266                         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");
1267                         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");
1268                         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");
1269                         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");
1270
1271                 }
1272         }
1273 }
1274
1275 static void object_panel_anim(Object *ob)
1276 {
1277         uiBlock *block;
1278         char str[32];
1279         
1280         block= uiNewBlock(&curarea->uiblocks, "object_panel_anim", UI_EMBOSSX, UI_HELV, curarea->win);
1281         if(uiNewPanel(curarea, block, "Anim settings", "Object", 0, 0, 318, 204)==0) return;
1282         
1283         uiBlockSetCol(block, BUTGREEN);
1284         uiDefButC(block, ROW,REDRAWVIEW3D,"TrackX",     27,190,58,17, &ob->trackflag, 12.0, 0.0, 0, 0, "Specify the axis that points to another object");
1285         uiDefButC(block, ROW,REDRAWVIEW3D,"Y",          85,190,19,17, &ob->trackflag, 12.0, 1.0, 0, 0, "Specify the axis that points to another object");
1286         uiDefButC(block, ROW,REDRAWVIEW3D,"Z",          104,190,19,17, &ob->trackflag, 12.0, 2.0, 0, 0, "Specify the axis that points to another object");
1287         uiDefButC(block, ROW,REDRAWVIEW3D,"-X",         124,190,24,17, &ob->trackflag, 12.0, 3.0, 0, 0, "Specify the axis that points to another object");
1288         uiDefButC(block, ROW,REDRAWVIEW3D,"-Y",         150,190,24,17, &ob->trackflag, 12.0, 4.0, 0, 0, "Specify the axis that points to another object");
1289         uiDefButC(block, ROW,REDRAWVIEW3D,"-Z",         177,190,24,17, &ob->trackflag, 12.0, 5.0, 0, 0, "Specify the axis that points to another object");
1290         uiDefButC(block, ROW,REDRAWVIEW3D,"UpX",        226,190,45,17, &ob->upflag, 13.0, 0.0, 0, 0, "Specify the axis that points up");
1291         uiDefButC(block, ROW,REDRAWVIEW3D,"Y",          274,190,20,17, &ob->upflag, 13.0, 1.0, 0, 0, "Specify the axis that points up");
1292         uiDefButC(block, ROW,REDRAWVIEW3D,"Z",          297,190,19,17, &ob->upflag, 13.0, 2.0, 0, 0, "Specify the axis that points up");
1293
1294         uiBlockSetCol(block, BUTGREEN);
1295         uiDefButC(block, TOG|BIT|0, REDRAWVIEW3D, "Draw Key",           25,160,70,19, &ob->ipoflag, 0, 0, 0, 0, "Draw object as key position");
1296         uiDefButC(block, TOG|BIT|1, REDRAWVIEW3D, "Draw Key Sel",       97,160,81,20, &ob->ipoflag, 0, 0, 0, 0, "Limit the drawing of object keys");
1297         uiDefButS(block, TOG|BIT|4, 0, "SlowPar",                       261,160,56,20, &ob->partype, 0, 0, 0, 0, "Create a delay in the parent relationship");
1298         uiDefButC(block, TOG|BIT|7, REDRAWVIEW3D, "Powertrack", 180,160,78,19, &ob->transflag, 0, 0, 0, 0, "Switch objects rotation off");
1299
1300
1301         uiBlockSetCol(block, BUTGREY);
1302         uiDefButC(block, TOG|BIT|3, REDRAWVIEW3D, "DupliFrames",        24,128,88,19, &ob->transflag, 0, 0, 0, 0, "Make copy of object for every frame");
1303         uiDefButC(block, TOG|BIT|4, REDRAWVIEW3D, "DupliVerts",         114,128,82,19, &ob->transflag, 0, 0, 0, 0, "Duplicate child objects on all vertices");
1304         uiBlockSetCol(block, BUTGREEN);
1305         uiDefButC(block, TOG|BIT|5, REDRAWVIEW3D, "Rot",                200,128,31,20, &ob->transflag, 0, 0, 0, 0, "Rotate dupli according to facenormal");
1306         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");
1307
1308         uiBlockSetCol(block, BUTGREY);
1309         uiDefButS(block, NUM, REDRAWVIEW3D, "DupSta:",          24,105,141,18, &ob->dupsta, 1.0, 1500.0, 0, 0, "Specify startframe for Dupliframes");
1310         uiDefButS(block, NUM, REDRAWVIEW3D, "DupEnd",           24,83,140,19, &ob->dupend, 1.0, 2500.0, 0, 0, "Specify endframe for Dupliframes");
1311         uiDefButS(block, NUM, REDRAWVIEW3D, "DupOn:",           169,104,146,19, &ob->dupon, 1.0, 1500.0, 0, 0, "");
1312         uiDefButS(block, NUM, REDRAWVIEW3D, "DupOff",           169,82,145,19, &ob->dupoff, 0.0, 1500.0, 0, 0, "");
1313
1314         uiBlockSetCol(block, BUTGREEN);
1315         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");
1316         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");
1317         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");
1318
1319         uiBlockSetCol(block, BUTGREY);
1320         sprintf(str, "%.4f", prspeed);
1321         uiDefBut(block, LABEL, 0, str,                                                  247,40,63,31, 0, 1.0, 0, 0, 0, "");
1322         uiDefBut(block, BUT, B_PRINTSPEED,      "PrSpeed",                      246,17,67,31, 0, 0, 0, 0, 0, "Print objectspeed");
1323
1324         uiBlockSetCol(block, BUTGREY);
1325         uiDefButF(block, NUM, REDRAWALL, "TimeOffset:",                 23,17,114,30, &ob->sf, -9000.0, 9000.0, 100, 0, "Specify an offset in frames");
1326         uiBlockSetCol(block, BUTSALMON);
1327         uiDefBut(block, BUT, B_AUTOTIMEOFS, "Automatic Time",   139,17,104,31, 0, 0, 0, 0, 0, "Generate automatic timeoffset values for all selected frames");
1328                 
1329 #if 0   
1330         /* IPO BUTTONS AS LAST */
1331         ScrArea *sa;
1332
1333         ok= 0;
1334         if(G.sipo) {
1335                 /* do these exist? */
1336                 sa= G.curscreen->areabase.first;
1337                 while(sa) {
1338                         if(sa->spacetype==SPACE_IPO && sa->spacedata.first==G.sipo) break;
1339                         sa= sa->next;
1340                 }
1341                 if(sa) {
1342                         if(G.sipo->ipo && G.sipo->ipo->curve.first) ok= 1;
1343                 }
1344         }
1345         
1346         uiBlockSetCol(block, BUTGREY);
1347         
1348                 sprintf(str, "%.3f", G.sipo->v2d.tot.xmin);
1349                 uiDefBut(block, LABEL, 0, str,                  1020, 140, 100, 19, 0, 0, 0, 0, 0, "");
1350                 sprintf(str, "%.3f", G.sipo->v2d.tot.xmax);
1351                 uiDefBut(block, LABEL, 0, str,                  1120, 140, 100, 19, 0, 0, 0, 0, 0, "");
1352         
1353                 uiDefButF(block, NUM, B_DIFF, "Xmin:",          1020, 120, 100, 19, &G.sipo->tot.xmin, -G.sipo->v2d.max[0], G.sipo->v2d.max[0], 100, 0, "");
1354                 uiDefButF(block, NUM, B_DIFF, "Xmax:",          1120, 120, 100, 19, &G.sipo->tot.xmax, -G.sipo->v2d.max[0], G.sipo->v2d.max[0], 100, 0, "");
1355                 
1356                 sprintf(str, "%.3f", G.sipo->v2d.tot.ymin);
1357                 uiDefBut(block, LABEL, 0, str,                  1020, 100, 100, 19, 0, 0, 0, 0, 0, "");
1358                 sprintf(str, "%.3f", G.sipo->v2d.tot.ymax);
1359                 uiDefBut(block, LABEL, 0, str,                  1120, 100, 100, 19, 0, 0, 0, 0, 0, "");
1360         
1361                 uiDefButF(block, NUM, B_DIFF, "Ymin:",          1020, 80, 100, 19, &G.sipo->tot.ymin, -G.sipo->v2d.max[1], G.sipo->v2d.max[1], 100, 0, "");
1362                 uiDefButF(block, NUM, B_DIFF, "Ymax:",          1120, 80, 100, 19, &G.sipo->tot.ymax, -G.sipo->v2d.max[1], G.sipo->v2d.max[1], 100, 0, "");
1363         
1364                 uiBlockSetCol(block, BUTSALMON);
1365                 uiDefBut(block, BUT, B_MUL_IPO, "SET",          1220,79,50,62, 0, 0, 0, 0, 0, "");
1366                 
1367                 
1368                 /* SPEED BUTTON */
1369                 uiBlockSetCol(block, BUTGREY);
1370                 uiDefButF(block, NUM, B_DIFF, "Speed:",         1020,23,164,28, &hspeed, 0.0, 180.0, 1, 0, "");
1371                 
1372                 uiBlockSetCol(block, BUTSALMON);
1373                 uiDefBut(block, BUT, B_SETSPEED,        "SET",          1185,23,83,29, 0, 0, 0, 0, 0, "");
1374
1375 #endif  
1376         
1377 }
1378
1379 void object_panels()
1380 {
1381         Object *ob;
1382
1383         /* check context here */
1384         ob= OBACT;
1385         if(ob) {
1386                 object_panel_anim(ob);
1387                 object_panel_draw(ob);
1388                 if(ob->type==OB_MESH) object_panel_effects(ob);
1389                 object_panel_constraint();
1390         }
1391 }
1392