Added baking for softbodies.
[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 #include "MEM_guardedalloc.h"
43
44 #include "DNA_screen_types.h"
45 #include "DNA_space_types.h"
46 #include "DNA_scene_types.h"
47
48 #include "BKE_global.h"
49 #include "BKE_main.h"
50 #include "BKE_library.h"
51 #include "BKE_softbody.h"
52
53 #include "BLI_blenlib.h"
54 #include "BLI_arithb.h"
55
56 #include "BSE_filesel.h"
57 #include "BSE_headerbuttons.h"
58
59 #include "BIF_gl.h"
60 #include "BIF_graphics.h"
61 #include "BIF_keyval.h"
62 #include "BIF_mainqueue.h"
63 #include "BIF_resources.h"
64 #include "BIF_screen.h"
65 #include "BIF_mywindow.h"
66 #include "BIF_space.h"
67 #include "BIF_glutil.h"
68 #include "BIF_interface.h"
69 #include "BIF_toolbox.h"
70 #include "BDR_editcurve.h"
71 #include "BDR_drawobject.h"
72
73 //#include "BIF_editsca.h"
74
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_object_force.h"
100 #include "DNA_radio_types.h"
101 #include "DNA_screen_types.h"
102 #include "DNA_sound_types.h"
103 #include "DNA_texture_types.h"
104 #include "DNA_userdef_types.h"
105 #include "DNA_vfont_types.h"
106 #include "DNA_view3d_types.h"
107 #include "DNA_world_types.h"
108
109 #include "BKE_anim.h"
110 #include "BKE_armature.h"
111 #include "BKE_constraint.h"
112 #include "BKE_curve.h"
113 #include "BKE_displist.h"
114 #include "BKE_effect.h"
115 #include "BKE_font.h"
116 #include "BKE_ika.h"
117 #include "BKE_image.h"
118 #include "BKE_ipo.h"
119 #include "BKE_lattice.h"
120 #include "BKE_material.h"
121 #include "BKE_mball.h"
122 #include "BKE_mesh.h"
123 #include "BKE_object.h"
124 #include "BKE_sound.h"
125 #include "BKE_texture.h"
126 #include "BKE_utildefines.h"
127
128 #include "BIF_editconstraint.h"
129 #include "BSE_editipo.h"
130 #include "BDR_editobject.h"
131
132 #include "butspace.h" // own module
133
134 static float prspeed=0.0;
135 float prlen=0.0;
136
137
138 /* ********************* function prototypes ******************** */
139 void object_panel_draw(Object *);
140 void object_panel_hooks(Object *);
141 void object_panel_effects(Object *);
142
143 /* ********************* CONSTRAINT ***************************** */
144
145 #if 0
146 static void add_influence_key_to_constraint_func (void *arg1v, void *unused)
147 {
148         bConstraint *con = arg1v;
149         add_influence_key_to_constraint(con);
150 }
151 #endif
152
153 static void activate_constraint_ipo_func (void *arg1v, void *unused)
154 {
155
156         bConstraint *con = arg1v;
157         bConstraintChannel *chan;
158         ListBase *conbase;
159
160         get_constraint_client(NULL, NULL, NULL);
161
162         conbase = get_constraint_client_channels(1);
163
164         if (!conbase)
165                 return;
166
167         /* See if this list already has an appropriate channel */
168         chan = find_constraint_channel(conbase, con->name);
169
170         if (!chan){
171                 /* Add a new constraint channel */
172                 chan = add_new_constraint_channel(con->name);
173                 BLI_addtail(conbase, chan);
174         }
175
176         /* Ensure there is an ipo to display */
177         if (!chan->ipo){
178                 chan->ipo = add_ipo(con->name, IPO_CO);
179         }
180
181         /* Make this the active channel */
182         OBACT->activecon = chan;
183
184         allqueue(REDRAWIPO, 0);
185         allqueue(REDRAWNLA, 0);
186 }
187
188 static void del_constraint_func (void *arg1v, void *arg2v)
189 {
190         bConstraint *con= arg1v;
191         Object *ob;
192
193         ListBase *lb= arg2v;
194         
195         ob=OBACT;
196         
197         if (ob->activecon && !strcmp(ob->activecon->name, con->name))
198                 ob->activecon = NULL;
199
200         free_constraint_data (con);
201
202         BLI_freelinkN(lb, con);
203
204         BIF_undo_push("Delete constraint");
205         allqueue(REDRAWBUTSOBJECT, 0);
206         allqueue(REDRAWIPO, 0); 
207
208 }
209
210 static void verify_constraint_name_func (void *data, void *data2_unused)
211 {
212         ListBase *conlist;
213         bConstraint *con;
214         char ownerstr[64];
215         short type;
216         
217         con = (bConstraint*) data;
218         if (!con)
219                 return;
220         
221         conlist = get_constraint_client(ownerstr, &type, NULL);
222         unique_constraint_name (con, conlist);
223 }
224
225 static void constraint_changed_func (void *data, void *data2_unused)
226 {
227         bConstraint *con = (bConstraint*) data;
228
229         if (con->type == con->otype)
230                 return;
231
232         free_constraint_data (con);
233         con->data = new_constraint_data(con->type);
234
235 }
236
237 static void move_constraint_func (void *datav, void *data2_unused)
238 {
239         bConstraint *constraint_to_move= datav;
240         int val;
241         ListBase *conlist;
242         char ownerstr[64];
243         short   type;
244         bConstraint *curCon, *con, *neighbour;
245         
246         val= pupmenu("Move up%x1|Move down %x2");
247         
248         con = constraint_to_move;
249
250         if(val>0) {
251                 conlist = get_constraint_client(ownerstr, &type, NULL);
252                 for (curCon = conlist->first; curCon; curCon = curCon->next){
253                         if (curCon == con){
254                                 /* Move up */
255                                 if (val == 1 && con->prev){
256                                         neighbour = con->prev;
257                                         BLI_remlink(conlist, neighbour);
258                                         BLI_insertlink(conlist, con, neighbour);
259                                 }
260                                 /* Move down */
261                                 else if (val == 2 && con->next){
262                                         neighbour = con->next;
263                                         BLI_remlink (conlist, con);
264                                         BLI_insertlink(conlist, neighbour, con);
265                                 }
266                                 break;
267                         }
268                 }
269         }
270 }
271
272 static void get_constraint_typestring (char *str, bConstraint *con)
273 {
274         switch (con->type){
275         case CONSTRAINT_TYPE_CHILDOF:
276                 strcpy (str, "Child Of");
277                 return;
278         case CONSTRAINT_TYPE_NULL:
279                 strcpy (str, "Null");
280                 return;
281         case CONSTRAINT_TYPE_TRACKTO:
282                 strcpy (str, "Track To");
283                 return;
284         case CONSTRAINT_TYPE_KINEMATIC:
285                 strcpy (str, "IK Solver");
286                 return;
287         case CONSTRAINT_TYPE_ROTLIKE:
288                 strcpy (str, "Copy Rotation");
289                 return;
290         case CONSTRAINT_TYPE_LOCLIKE:
291                 strcpy (str, "Copy Location");
292                 return;
293         case CONSTRAINT_TYPE_ACTION:
294                 strcpy (str, "Action");
295                 return;
296         case CONSTRAINT_TYPE_LOCKTRACK:
297                 strcpy (str, "Locked Track");
298                 return;
299         case CONSTRAINT_TYPE_FOLLOWPATH:
300                 strcpy (str, "Follow Path");
301                 return;
302         case CONSTRAINT_TYPE_STRETCHTO:
303                 strcpy (str, "Stretch To");
304                 return;
305         default:
306                 strcpy (str, "Unknown");
307                 return;
308         }
309 }
310
311 static int get_constraint_col(bConstraint *con)
312 {
313         switch (con->type) {
314         case CONSTRAINT_TYPE_NULL:
315                 return TH_BUT_NEUTRAL;
316         case CONSTRAINT_TYPE_KINEMATIC:
317                 return TH_BUT_SETTING2;
318         case CONSTRAINT_TYPE_TRACKTO:
319                 return TH_BUT_SETTING;
320         case CONSTRAINT_TYPE_ROTLIKE:
321                 return TH_BUT_SETTING1;
322         case CONSTRAINT_TYPE_LOCLIKE:
323                 return TH_BUT_POPUP;
324         case CONSTRAINT_TYPE_ACTION:
325                 return TH_BUT_ACTION;
326         case CONSTRAINT_TYPE_LOCKTRACK:
327                 return TH_BUT_SETTING;
328         case CONSTRAINT_TYPE_FOLLOWPATH:
329                 return TH_BUT_SETTING2;
330         case CONSTRAINT_TYPE_STRETCHTO:
331                 return TH_BUT_SETTING;
332         default:
333                 return TH_REDALERT;
334         }
335 }
336
337 static void draw_constraint (uiBlock *block, ListBase *list, bConstraint *con, short *xco, short *yco, short type)
338 {
339         uiBut *but;
340         char typestr[64];
341         short height, width = 265;
342         int curCol;
343
344         get_constraint_typestring (typestr, con);
345
346         curCol = get_constraint_col(con);
347
348         /* Draw constraint header */
349         uiBlockSetEmboss(block, UI_EMBOSSN);
350         
351         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");
352
353         if (con->flag & CONSTRAINT_EXPAND) {
354                 
355                 if (con->flag & CONSTRAINT_DISABLE) {
356                         BIF_ThemeColor(TH_REDALERT);
357                         uiBlockSetCol(block, TH_REDALERT);
358                 }
359                 else
360                         BIF_ThemeColor(curCol);
361
362                 /*if (type==TARGET_BONE)
363                         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"); 
364                 else
365                         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"); 
366                 */
367                 uiBlockSetEmboss(block, UI_EMBOSSX);
368                 
369                 /* rounded header */
370                 BIF_ThemeColorShade(curCol, -20);
371                 uiSetRoundBox(3);
372                 uiRoundBox((float)*xco+4, (float)*yco-18, (float)*xco+width+30, (float)*yco+6, 5.0);
373
374                 but = uiDefBut(block, LABEL, B_CONSTRAINT_TEST, typestr, *xco+10, *yco-1, 100, 19, NULL, 0.0, 0.0, 0.0, 0.0, ""); 
375
376                 uiButSetFunc(but, constraint_changed_func, con, NULL);
377                 con->otype = con->type;
378                 
379                 but = uiDefBut(block, TEX, B_CONSTRAINT_REDRAW, "", *xco+120, *yco-1, 135, 19, con->name, 0.0, 29.0, 0.0, 0.0, "Constraint name"); 
380                 uiButSetFunc(but, verify_constraint_name_func, con, NULL);
381         }       
382         else{
383                 uiBlockSetEmboss(block, UI_EMBOSSN);
384
385                 if (con->flag & CONSTRAINT_DISABLE) {
386                         uiBlockSetCol(block, TH_REDALERT);
387                         BIF_ThemeColor(TH_REDALERT);
388                 }
389                 else
390                         BIF_ThemeColor(curCol);
391                         
392                 /* coloured rectangle to hold constraint controls */
393                 if (con->type!=CONSTRAINT_TYPE_NULL) glRects(*xco+3, *yco-36, *xco+width+30, *yco-15);
394         
395                 /* rounded header */
396                 BIF_ThemeColorShade(curCol, -20);
397                 uiSetRoundBox(3);
398                 uiRoundBox((float)*xco+4, (float)*yco-15, (float)*xco+width+30, (float)*yco+6, 5.0);
399                 
400                 but = uiDefBut(block, LABEL, B_CONSTRAINT_TEST, typestr, *xco+10, *yco-1, 100, 19, NULL, 0.0, 0.0, 0.0, 0.0, ""); 
401                 uiButSetFunc(but, move_constraint_func, con, NULL);
402                 
403                 but = uiDefBut(block, LABEL, B_CONSTRAINT_TEST, con->name, *xco+120, *yco-1, 135, 19, NULL, 0.0, 0.0, 0.0, 0.0, ""); 
404                 uiButSetFunc(but, move_constraint_func, con, NULL);
405         }
406
407         uiBlockSetCol(block, TH_AUTO);  
408         
409         uiBlockSetEmboss(block, UI_EMBOSSN);
410         
411         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");
412         uiButSetFunc(but, del_constraint_func, con, list);
413
414         uiBlockSetEmboss(block, UI_EMBOSSX);
415
416
417         /* Draw constraint data*/
418         if (!(con->flag & CONSTRAINT_EXPAND)) {
419                 (*yco)-=21;
420         }
421         else {
422                 switch (con->type){
423                 case CONSTRAINT_TYPE_ACTION:
424                         {
425                                 bActionConstraint *data = con->data;
426                                 bArmature *arm;
427
428                                 height = 86;
429                                 
430                                 BIF_ThemeColor(curCol);
431                                 glRects(*xco+3, *yco-height-39, *xco+width+30, *yco-18);
432
433                                 uiDefBut(block, LABEL, B_CONSTRAINT_TEST, "Target:", *xco+65, *yco-24, 50, 18, NULL, 0.0, 0.0, 0.0, 0.0, ""); 
434
435                                 /* Draw target parameters */
436                                 uiBlockBeginAlign(block);
437                                 uiDefIDPoinBut(block, test_obpoin_but, B_CONSTRAINT_CHANGETARGET, "OB:", *xco+120, *yco-24, 135, 18, &data->tar, "Target Object"); 
438
439                                 arm = get_armature(data->tar);
440                                 if (arm){
441                                         but=uiDefBut(block, TEX, B_CONSTRAINT_CHANGETARGET, "BO:", *xco+120, *yco-42,135,18, &data->subtarget, 0, 24, 0, 0, "Subtarget Bone");
442                                 }
443                                 else
444                                         strcpy (data->subtarget, "");
445                                 uiBlockEndAlign(block);
446
447                                 /* Draw action button */
448                                 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"); 
449                                 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");
450
451                                 uiBlockBeginAlign(block);
452                                 uiDefButS(block, NUM, B_CONSTRAINT_CHANGETARGET, "Start:", *xco+((width/2)-36), *yco-64, 78, 18, &data->start, 1, MAXFRAME, 0.0, 0.0, "Starting frame of the keyed motion"); 
453                                 uiDefButS(block, NUM, B_CONSTRAINT_CHANGETARGET, "End:", *xco+((width/2)-36), *yco-84, 78, 18, &data->end, 1, MAXFRAME, 0.0, 0.0, "Ending frame of the keyed motion"); 
454                                 uiBlockEndAlign(block);
455                                 
456                                 uiBlockBeginAlign(block);
457                                 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");
458                                 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");
459                                 uiBlockEndAlign(block);
460                         }
461                         break;
462                 case CONSTRAINT_TYPE_LOCLIKE:
463                         {
464                                 bLocateLikeConstraint *data = con->data;
465                                 bArmature *arm;
466                                 height = 66;
467                                 
468                                 BIF_ThemeColor(curCol);
469                                 glRects(*xco+3, *yco-height-39, *xco+width+30, *yco-18);
470
471                                 uiDefBut(block, LABEL, B_CONSTRAINT_TEST, "Target:", *xco+65, *yco-24, 50, 18, NULL, 0.0, 0.0, 0.0, 0.0, ""); 
472
473                                 /* Draw target parameters */
474                                 uiBlockBeginAlign(block);
475                                 uiDefIDPoinBut(block, test_obpoin_but, B_CONSTRAINT_CHANGETARGET, "OB:", *xco+120, *yco-24, 135, 18, &data->tar, "Target Object"); 
476
477                                 arm = get_armature(data->tar);
478                                 if (arm){
479                                         but=uiDefBut(block, TEX, B_CONSTRAINT_CHANGETARGET, "BO:", *xco+120, *yco-42,135,18, &data->subtarget, 0, 24, 0, 0, "Subtarget Bone");
480                                 }
481                                 else
482                                         strcpy (data->subtarget, "");
483                                 uiBlockEndAlign(block);
484                                 
485                                 /* Draw XYZ toggles */
486                                 uiBlockBeginAlign(block);
487                                 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");
488                                 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");
489                                 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");
490                                 uiBlockEndAlign(block);
491                         }
492                         break;
493                 case CONSTRAINT_TYPE_ROTLIKE:
494                         {
495                                 bRotateLikeConstraint *data = con->data;
496                                 bArmature *arm;
497                                 height = 46;
498
499                                 BIF_ThemeColor(curCol);
500                                 glRects(*xco+3, *yco-height-39, *xco+width+30, *yco-18);
501                                 
502                                 uiDefBut(block, LABEL, B_CONSTRAINT_TEST, "Target:", *xco+65, *yco-24, 50, 18, NULL, 0.0, 0.0, 0.0, 0.0, ""); 
503
504                                 /* Draw target parameters */
505                                 uiBlockBeginAlign(block);
506                                 uiDefIDPoinBut(block, test_obpoin_but, B_CONSTRAINT_CHANGETARGET, "OB:", *xco+120, *yco-24, 135, 18, &data->tar, "Target Object"); 
507
508                                 arm = get_armature(data->tar);
509                                 if (arm){
510                                         but=uiDefBut(block, TEX, B_CONSTRAINT_CHANGETARGET, "BO:", *xco+120, *yco-42,135,18, &data->subtarget, 0, 24, 0, 0, "Subtarget Bone");
511                                 }
512                                 else
513                                         strcpy (data->subtarget, "");
514                                 uiBlockEndAlign(block);
515                         }
516                         break;
517                 case CONSTRAINT_TYPE_KINEMATIC:
518                         {
519                                 bKinematicConstraint *data = con->data;
520                                 bArmature *arm;
521                                 
522                                 height = 66;
523                                 
524                                 BIF_ThemeColor(curCol);
525                                 glRects(*xco+3, *yco-height-39, *xco+width+30, *yco-18);
526                                 
527                                 uiDefBut(block, LABEL, B_CONSTRAINT_TEST, "Target:", *xco+65, *yco-24, 50, 18, NULL, 0.0, 0.0, 0.0, 0.0, ""); 
528
529                                 /* Draw target parameters */
530                                 uiBlockBeginAlign(block);
531                                 uiDefIDPoinBut(block, test_obpoin_but, B_CONSTRAINT_CHANGETARGET, "OB:", *xco+120, *yco-24, 135, 18, &data->tar, "Target Object"); 
532
533                                 arm = get_armature(data->tar);
534                                 if (arm){
535                                         but=uiDefBut(block, TEX, B_CONSTRAINT_CHANGETARGET, "BO:", *xco+120, *yco-42,135,18, &data->subtarget, 0, 24, 0, 0, "Subtarget Bone");
536                                 }
537                                 else
538                                         strcpy (data->subtarget, "");
539                                 uiBlockEndAlign(block);
540         
541                                 uiDefButF(block, NUM, B_CONSTRAINT_REDRAW, "Tolerance:", *xco+((width/2)-117), *yco-64, 120, 18, &data->tolerance, 0.0001f, 1.0, 0.0, 0.0, "Maximum distance to target after solving"); 
542                                 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"); 
543                                 
544                         }
545                         break;
546                 case CONSTRAINT_TYPE_TRACKTO:
547                         {
548                                 bTrackToConstraint *data = con->data;
549                                 bArmature *arm;
550
551                                 height = 66;
552                                 
553                                 BIF_ThemeColor(curCol);
554                                 glRects(*xco+3, *yco-height-39, *xco+width+30, *yco-18);
555                                 
556                                 uiDefBut(block, LABEL, B_CONSTRAINT_TEST, "Target:", *xco+65, *yco-24, 50, 18, NULL, 0.0, 0.0, 0.0, 0.0, ""); 
557
558                                 /* Draw target parameters */
559                                 uiBlockBeginAlign(block);
560                                 uiDefIDPoinBut(block, test_obpoin_but, B_CONSTRAINT_CHANGETARGET, "OB:", *xco+120, *yco-24, 135, 18, &data->tar, "Target Object"); 
561
562                                 arm = get_armature(data->tar);
563                                 if (arm){
564                                         but=uiDefBut(block, TEX, B_CONSTRAINT_CHANGETARGET, "BO:", *xco+120, *yco-42,135,18, &data->subtarget, 0, 24, 0, 0, "Subtarget Bone");
565                                 }
566                                 else
567                                         strcpy (data->subtarget, "");
568                                 uiBlockEndAlign(block);
569
570                                 uiBlockBeginAlign(block);
571                                 uiDefBut(block, LABEL, B_CONSTRAINT_TEST, "To:", *xco+12, *yco-64, 25, 18, NULL, 0.0, 0.0, 0.0, 0.0, ""); 
572                                 
573                                 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");
574                                 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");
575                                 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");
576                                 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");
577                                 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");
578                                 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");
579                                 uiBlockEndAlign(block);
580                                 
581                                 uiBlockBeginAlign(block);
582                                 uiDefBut(block, LABEL, B_CONSTRAINT_TEST, "Up:", *xco+174, *yco-64, 30, 18, NULL, 0.0, 0.0, 0.0, 0.0, "");
583                                 
584                                 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");
585                                 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");
586                                 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");
587                                 uiBlockEndAlign(block);
588                         }
589                         break;
590                 case CONSTRAINT_TYPE_LOCKTRACK:
591                         {
592                                 bLockTrackConstraint *data = con->data;
593                                 bArmature *arm;
594                                 height = 66;
595                                 
596                                 BIF_ThemeColor(curCol);
597                                 glRects(*xco+3, *yco-height-39, *xco+width+30, *yco-18);
598
599                                 uiDefBut(block, LABEL, B_CONSTRAINT_TEST, "Target:", *xco+65, *yco-24, 50, 18, NULL, 0.0, 0.0, 0.0, 0.0, ""); 
600
601                                 /* Draw target parameters */
602                                 uiBlockBeginAlign(block);
603                                 uiDefIDPoinBut(block, test_obpoin_but, B_CONSTRAINT_CHANGETARGET, "OB:", *xco+120, *yco-24, 135, 18, &data->tar, "Target Object"); 
604
605                                 arm = get_armature(data->tar);
606                                 if (arm){
607                                         but=uiDefBut(block, TEX, B_CONSTRAINT_CHANGETARGET, "BO:", *xco+120, *yco-42,135,18, &data->subtarget, 0, 24, 0, 0, "Subtarget Bone");
608                                 }
609                                 else
610                                         strcpy (data->subtarget, "");
611                                 uiBlockEndAlign(block);
612                                 
613                                 uiBlockBeginAlign(block);
614                                 uiDefBut(block, LABEL, B_CONSTRAINT_TEST, "To:", *xco+12, *yco-64, 25, 18, NULL, 0.0, 0.0, 0.0, 0.0, ""); 
615                                 
616                                 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");
617                                 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");
618                                 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");
619                                 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");
620                                 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");
621                                 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");
622                                 uiBlockEndAlign(block);
623                                 
624                                 uiBlockBeginAlign(block);
625                                 uiDefBut(block, LABEL, B_CONSTRAINT_TEST, "Lock:", *xco+166, *yco-64, 38, 18, NULL, 0.0, 0.0, 0.0, 0.0, "");
626                                 
627                                 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");
628                                 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");
629                                 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");
630                                 uiBlockEndAlign(block);
631                         }
632                         break;
633                 case CONSTRAINT_TYPE_FOLLOWPATH:
634                         {
635                                 bFollowPathConstraint *data = con->data;
636
637                                 height = 66;
638                                 
639                                 BIF_ThemeColor(curCol);
640                                 glRects(*xco+3, *yco-height-39, *xco+width+30, *yco-18);
641                                 
642                                 uiDefBut(block, LABEL, B_CONSTRAINT_TEST, "Target:", *xco+65, *yco-24, 50, 18, NULL, 0.0, 0.0, 0.0, 0.0, ""); 
643
644                                 /* Draw target parameters */
645                                 uiDefIDPoinBut(block, test_obpoin_but, B_CONSTRAINT_CHANGETARGET, "OB:", *xco+120, *yco-24, 135, 18, &data->tar, "Target Object"); 
646                                 
647                                 /* Draw Curve Follow toggle */
648                                 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");
649
650                                 /* Draw Offset number button */
651                                 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"); 
652
653                                 uiBlockBeginAlign(block);
654                                 uiDefBut(block, LABEL, B_CONSTRAINT_TEST, "Fw:", *xco+12, *yco-64, 27, 18, NULL, 0.0, 0.0, 0.0, 0.0, ""); 
655                                 
656                                 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");
657                                 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");
658                                 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");
659                                 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");
660                                 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");
661                                 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");
662                                 uiBlockEndAlign(block);
663                                 
664                                 uiBlockBeginAlign(block);
665                                 uiDefBut(block, LABEL, B_CONSTRAINT_TEST, "Up:", *xco+174, *yco-64, 30, 18, NULL, 0.0, 0.0, 0.0, 0.0, "");
666                                 
667                                 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");
668                                 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");
669                                 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");
670                                 uiBlockEndAlign(block);
671                         }
672                         break;
673                 case CONSTRAINT_TYPE_STRETCHTO:
674                         {
675                                 bStretchToConstraint *data = con->data;
676                                 bArmature *arm;
677                                 height = 105;
678                                 BIF_ThemeColor(curCol);
679
680                                 glRects(*xco+3, *yco-height-39, *xco+width+30, *yco-18);
681                                 
682                                 uiDefBut(block, LABEL, B_CONSTRAINT_TEST, "Target:", *xco+65, *yco-24, 50, 18, NULL, 0.0, 0.0, 0.0, 0.0, ""); 
683
684
685                                 /* Draw target parameters */
686                                 uiBlockBeginAlign(block);
687                                 uiDefIDPoinBut(block, test_obpoin_but, B_CONSTRAINT_CHANGETARGET, "OB:", *xco+120, *yco-24, 135, 18, &data->tar, "Target Object"); 
688
689                                 arm = get_armature(data->tar);
690                                 if (arm){
691                                         but=uiDefBut(block, TEX, B_CONSTRAINT_CHANGETARGET, "BO:", *xco+120, *yco-42,135,18, &data->subtarget, 0, 24, 0, 0, "Subtarget Bone");
692                                 }
693                                 else
694                                         strcpy (data->subtarget, "");
695                                 uiBlockEndAlign(block);
696
697                                 
698                                 uiBlockBeginAlign(block);
699                                 uiDefButF(block,BUTM,B_CONSTRAINT_REDRAW,"R",*xco, *yco-60,20,18,&(data->orglength),0.0,0,0,0,"Recalculate RLenght");
700                                 uiDefButF(block,NUM,B_CONSTRAINT_REDRAW,"Rest Length:",*xco+18, *yco-60,237,18,&(data->orglength),0.0,100,0.5,0.5,"Lenght at Rest Position");
701                                 uiBlockEndAlign(block);
702
703                                 uiDefButF(block,NUM,B_CONSTRAINT_REDRAW,"Volume Variation:",*xco+18, *yco-82,237,18,&(data->bulge),0.0,100,0.5,0.5,"Factor between volume variation and stretching");
704
705                                 uiBlockBeginAlign(block);
706                                 uiDefBut(block, LABEL, B_CONSTRAINT_TEST, "Vol:",*xco+14, *yco-104,30,18, NULL, 0.0, 0.0, 0.0, 0.0, ""); 
707                                 uiDefButI(block, ROW,B_CONSTRAINT_REDRAW,"XZ",   *xco+44, *yco-104,30,18, &data->volmode, 12.0, 0.0, 0, 0, "Keep Volume: Scaling X & Z");
708                                 uiDefButI(block, ROW,B_CONSTRAINT_REDRAW,"X",    *xco+74, *yco-104,20,18, &data->volmode, 12.0, 1.0, 0, 0, "Keep Volume: Scaling X");
709                                 uiDefButI(block, ROW,B_CONSTRAINT_REDRAW,"Z",    *xco+94, *yco-104,20,18, &data->volmode, 12.0, 2.0, 0, 0, "Keep Volume: Scaling Z");
710                                 uiDefButI(block, ROW,B_CONSTRAINT_REDRAW,"NONE", *xco+114, *yco-104,50,18, &data->volmode, 12.0, 3.0, 0, 0, "Ignore Volume");
711                                 uiBlockEndAlign(block);
712
713                                 
714                                 uiBlockBeginAlign(block);
715                                 uiDefBut(block, LABEL, B_CONSTRAINT_TEST,"Plane:",*xco+175, *yco-104,40,18, NULL, 0.0, 0.0, 0.0, 0.0, ""); 
716                                 uiDefButI(block, ROW,B_CONSTRAINT_REDRAW,"X",     *xco+215, *yco-104,20,18, &data->plane, 12.0, 0.0, 0, 0, "Keep X axis");
717                                 uiDefButI(block, ROW,B_CONSTRAINT_REDRAW,"Z",     *xco+235, *yco-104,20,18, &data->plane, 12.0, 2.0, 0, 0, "Keep Z axis");
718                                 uiBlockEndAlign(block);
719                                 }
720                         break;
721                 case CONSTRAINT_TYPE_NULL:
722                         {
723                                 height = 17;
724                                 
725                                 BIF_ThemeColor(curCol);
726                                 glRects(*xco+3, *yco-height-17, *xco+width+30, *yco-18);
727                                 
728                         }
729                         break;
730                 default:
731                         height = 0;
732                         break;
733                 }
734
735                 (*yco)-=(24+height);
736         }
737
738         if (con->type!=CONSTRAINT_TYPE_NULL) {
739                 uiDefButF(block, NUMSLI, B_CONSTRAINT_REDRAW, "Influence ", *xco+17, *yco, 197, 19, &(con->enforce), 0.0, 1.0, 0.0, 0.0, "Amount of influence this constraint will have on the final solution");
740                 but = uiDefBut(block, BUT, B_CONSTRAINT_REDRAW, "Edit", *xco+215, *yco, 41, 19, 0, 0.0, 1.0, 0.0, 0.0, "Show this constraint's ipo in the object's Ipo window");
741                 /* If this is on an object, add the constraint to the object */
742                 uiButSetFunc (but, activate_constraint_ipo_func, con, NULL);
743                 /* If this is on a bone, add the constraint to the action (if any) */
744                 //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");
745                 /* Add a keyframe to the influence IPO */
746                 //uiButSetFunc (but, add_influence_key_to_constraint_func, con, NULL);
747                 (*yco)-=24;
748         } else {
749                 (*yco)-=3;
750         }
751         
752 }
753
754 static uiBlock *add_constraintmenu(void *arg_unused)
755 {
756         uiBlock *block;
757         
758         ListBase *conlist;
759         char ownerstr[64];
760         short type;
761         short yco= 0;
762         
763         conlist = get_constraint_client(ownerstr, &type, NULL);
764         
765         block= uiNewBlock(&curarea->uiblocks, "add_constraintmenu", UI_EMBOSSP, UI_HELV, curarea->win);
766
767         uiDefBut(block, BUTM, B_CONSTRAINT_ADD_LOCLIKE,"Copy Location",         0, yco-=20, 160, 19, NULL, 0.0, 0.0, 1, 0, "");
768         uiDefBut(block, BUTM, B_CONSTRAINT_ADD_ROTLIKE,"Copy Rotation",         0, yco-=20, 160, 19, NULL, 0.0, 0.0, 1, 0, "");
769         
770         uiDefBut(block, SEPR, 0, "",                                    0, yco-=6, 120, 6, NULL, 0.0, 0.0, 0, 0, "");
771         
772         uiDefBut(block, BUTM, B_CONSTRAINT_ADD_TRACKTO,"Track To",              0, yco-=20, 160, 19, NULL, 0.0, 0.0, 1, 0, "");
773         uiDefBut(block, BUTM, B_CONSTRAINT_ADD_LOCKTRACK,"Locked Track",                0, yco-=20, 160, 19, NULL, 0.0, 0.0, 1, 0, "");
774         uiDefBut(block, BUTM, B_CONSTRAINT_ADD_FOLLOWPATH,"Follow Path",                0, yco-=20, 160, 19, NULL, 0.0, 0.0, 1, 0, "");
775         
776         uiDefBut(block, SEPR, 0, "",                                    0, yco-=6, 120, 6, NULL, 0.0, 0.0, 0, 0, "");
777         
778         uiDefBut(block, BUTM, B_CONSTRAINT_ADD_STRETCHTO,"Stretch To",          0, yco-=20, 160, 19, NULL, 0.0, 0.0, 1, 0, "");
779
780         if (type==TARGET_BONE) {
781         
782                 uiDefBut(block, SEPR, 0, "",                                    0, yco-=6, 120, 6, NULL, 0.0, 0.0, 0, 0, "");
783                 
784                 uiDefBut(block, BUTM, B_CONSTRAINT_ADD_KINEMATIC,"IK Solver",           0, yco-=20, 160, 19, NULL, 0.0, 0.0, 1, 0, "");
785                 uiDefBut(block, BUTM, B_CONSTRAINT_ADD_ACTION,"Action",         0, yco-=20, 160, 19, NULL, 0.0, 0.0, 1, 0, "");
786                 
787         }
788         uiDefBut(block, SEPR, 0, "",                                    0, yco-=6, 120, 6, NULL, 0.0, 0.0, 0, 0, "");
789
790         uiDefBut(block, BUTM, B_CONSTRAINT_ADD_NULL,"Null",             0, yco-=20, 160, 19, NULL, 0.0, 0.0, 1, 0, "");
791         
792         uiTextBoundsBlock(block, 50);
793         uiBlockSetDirection(block, UI_DOWN);
794                 
795         return block;
796 }
797
798 void do_constraintbuts(unsigned short event)
799 {
800         switch(event) {
801         case B_CONSTRAINT_CHANGENAME:
802                 break;
803         case B_CONSTRAINT_TEST:
804                 test_scene_constraints();
805                 allqueue (REDRAWVIEW3D, 0);
806                 allqueue (REDRAWBUTSOBJECT, 0);
807                 break;
808         case B_CONSTRAINT_REDRAW:
809                 test_scene_constraints();
810                 allqueue (REDRAWVIEW3D, 0);
811                 allqueue (REDRAWBUTSOBJECT, 0);
812                 break;
813         case B_CONSTRAINT_CHANGETARGET:
814                 test_scene_constraints();
815                 allqueue (REDRAWVIEW3D, 0);
816                 allqueue (REDRAWBUTSOBJECT, 0);
817                 break;
818         case B_CONSTRAINT_CHANGETYPE:
819                 test_scene_constraints();
820                 allqueue (REDRAWVIEW3D, 0);
821                 allqueue (REDRAWBUTSOBJECT, 0);
822                 break;
823         case B_CONSTRAINT_ADD_NULL:
824                 {
825                         bConstraint *con;
826                         
827                         con = add_new_constraint(CONSTRAINT_TYPE_NULL);
828                         add_constraint_to_client(con);
829
830                         test_scene_constraints();
831                         BIF_undo_push("Add constraint");
832                         allqueue (REDRAWVIEW3D, 0);
833                         allqueue (REDRAWBUTSOBJECT, 0);
834                 }
835                 break;
836         case B_CONSTRAINT_ADD_KINEMATIC:
837                 {
838                         bConstraint *con;
839                         
840                         con = add_new_constraint(CONSTRAINT_TYPE_KINEMATIC);
841                         add_constraint_to_client(con);
842
843                         test_scene_constraints();
844                         BIF_undo_push("Add constraint");
845                         allqueue (REDRAWVIEW3D, 0);
846                         allqueue (REDRAWBUTSOBJECT, 0);
847                 }
848                 break;
849         case B_CONSTRAINT_ADD_TRACKTO:
850                 {
851                         bConstraint *con;
852
853                         con = add_new_constraint(CONSTRAINT_TYPE_TRACKTO);
854                         add_constraint_to_client(con);
855
856                         test_scene_constraints();
857                         BIF_undo_push("Add constraint");
858                         allqueue (REDRAWVIEW3D, 0);
859                         allqueue (REDRAWBUTSOBJECT, 0);
860                 }
861                 break;
862         case B_CONSTRAINT_ADD_ROTLIKE:
863                 {
864                         bConstraint *con;
865
866                         con = add_new_constraint(CONSTRAINT_TYPE_ROTLIKE);
867                         add_constraint_to_client(con);
868
869                         test_scene_constraints();
870                         BIF_undo_push("Add constraint");
871                         allqueue (REDRAWVIEW3D, 0);
872                         allqueue (REDRAWBUTSOBJECT, 0);
873                 }
874                 break;
875         case B_CONSTRAINT_ADD_LOCLIKE:
876                 {
877                         bConstraint *con;
878
879                         con = add_new_constraint(CONSTRAINT_TYPE_LOCLIKE);
880                         add_constraint_to_client(con);
881
882                         test_scene_constraints();
883                         BIF_undo_push("Add constraint");
884                         allqueue (REDRAWVIEW3D, 0);
885                         allqueue (REDRAWBUTSOBJECT, 0);
886                 }
887                 break;
888         case B_CONSTRAINT_ADD_ACTION:
889                 {
890                         bConstraint *con;
891
892                         con = add_new_constraint(CONSTRAINT_TYPE_ACTION);
893                         add_constraint_to_client(con);
894
895                         test_scene_constraints();
896                         BIF_undo_push("Add constraint");
897                         allqueue (REDRAWVIEW3D, 0);
898                         allqueue (REDRAWBUTSOBJECT, 0);
899                 }
900                 break;
901         case B_CONSTRAINT_ADD_LOCKTRACK:
902                 {
903                         bConstraint *con;
904
905                         con = add_new_constraint(CONSTRAINT_TYPE_LOCKTRACK);
906                         add_constraint_to_client(con);
907
908                         test_scene_constraints();
909                         BIF_undo_push("Add constraint");
910                         allqueue (REDRAWVIEW3D, 0);
911                         allqueue (REDRAWBUTSOBJECT, 0);
912                 }
913                 break;
914         case B_CONSTRAINT_ADD_FOLLOWPATH:
915                 {
916                         bConstraint *con;
917
918                         con = add_new_constraint(CONSTRAINT_TYPE_FOLLOWPATH);
919                         add_constraint_to_client(con);
920
921                         test_scene_constraints();
922                         allqueue (REDRAWVIEW3D, 0);
923                         allqueue (REDRAWBUTSOBJECT, 0);
924                 }
925                 break;
926         case B_CONSTRAINT_ADD_STRETCHTO:
927         {
928                 bConstraint *con;
929                 con = add_new_constraint(CONSTRAINT_TYPE_STRETCHTO);
930                 add_constraint_to_client(con);
931                         
932                 test_scene_constraints();
933                 BIF_undo_push("Add constraint");
934                 allqueue(REDRAWVIEW3D,0);
935                 allqueue(REDRAWBUTSOBJECT,0);
936         }
937                 break;
938
939         case B_CONSTRAINT_DEL:
940                 test_scene_constraints();
941                 allqueue (REDRAWVIEW3D, 0);
942                 allqueue (REDRAWBUTSOBJECT, 0);
943                 break;
944         default:
945                 break;
946         }
947
948         clear_object_constraint_status(OBACT);
949         make_displists_by_armature (OBACT);
950 }
951
952 static void object_panel_constraint(void)
953 {
954         uiBlock *block;
955         ListBase *conlist;
956         bConstraint *curcon;
957         short xco, yco, type;
958         char ownerstr[64];
959         
960         block= uiNewBlock(&curarea->uiblocks, "object_panel_constraint", UI_EMBOSS, UI_HELV, curarea->win);
961         if(uiNewPanel(curarea, block, "Constraints", "Object", 640, 0, 318, 204)==0) return;
962
963         /* this is a variable height panel, newpanel doesnt force new size on existing panels */
964         /* so first we make it default height */
965         uiNewPanelHeight(block, 204);
966
967         conlist = get_constraint_client(ownerstr, &type, NULL);
968         
969         if (conlist) {
970                  
971                 uiDefBlockBut(block, add_constraintmenu, NULL, "Add Constraint", 0, 190, 130, 20, "Add a new constraint");
972                 
973                 /* print active object or bone */
974                 {
975                         short type;
976                         void *data=NULL;
977                         char str[64];
978                         
979                         str[0]= 0;
980                         get_constraint_client(NULL, &type, &data);
981                         if (data && type==TARGET_BONE){
982                                 sprintf(str, "To Bone: %s", ((Bone*)data)->name);
983                         }
984                         else if(OBACT) {
985                                 Object *ob= OBACT;
986                                 sprintf(str, "To Object: %s", ob->id.name+2);
987                         }
988                         uiDefBut(block, LABEL, 1, str,  150, 190, 150, 20, NULL, 0.0, 0.0, 0, 0, "Displays Active Object or Bone name");
989                 }
990                 
991                 /* Go through the list of constraints and draw them */
992                 xco = 10;
993                 yco = 160;
994                 // local panel coords
995                 uiPanelPush(block);
996                 
997                 for (curcon = conlist->first; curcon; curcon=curcon->next) {
998                         /* Draw default constraint header */                    
999                         draw_constraint(block, conlist, curcon, &xco, &yco, type);      
1000                 }
1001                 
1002                 uiPanelPop(block);
1003                 
1004                 if(yco < 0) uiNewPanelHeight(block, 204-yco);
1005                 
1006         }
1007 }
1008
1009 void object_panel_draw(Object *ob)
1010 {
1011         uiBlock *block;
1012         int xco, a, dx, dy;
1013         
1014         block= uiNewBlock(&curarea->uiblocks, "object_panel_draw", UI_EMBOSS, UI_HELV, curarea->win);
1015         if(uiNewPanel(curarea, block, "Draw", "Object", 320, 0, 318, 204)==0) return;
1016
1017         /* LAYERS */
1018         xco= 151;
1019         dx= 32;
1020         dy= 30;
1021
1022         uiBlockBeginAlign(block);
1023         for(a=0; a<5; a++)
1024                 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, "");
1025         for(a=0; a<5; a++)
1026                 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, "");
1027                 
1028         xco+= 5;
1029         uiBlockBeginAlign(block);
1030         for(a=5; a<10; a++)
1031                 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, "");
1032         for(a=5; a<10; a++)
1033                 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, "");
1034
1035         uiBlockEndAlign(block);
1036
1037         uiDefBut(block, LABEL, 0, "Drawtype",                                           28,200,100,18, NULL, 0, 0, 0, 0, "");
1038         uiDefButC(block, MENU, REDRAWVIEW3D, "Drawtype%t|Bounds %x1|Wire %x2|Solid %x3|Shaded %x4",     
1039                                                                                                                                 28,180,100,18, &ob->dt, 0, 0, 0, 0, "Sets the drawing type of the active object");
1040         uiDefBut(block, LABEL, 0, "Draw Extra",                                         28,160,100,18, NULL, 0, 0, 0, 0, "");
1041         uiBlockBeginAlign(block);
1042         uiDefButC(block, TOG|BIT|0, REDRAWVIEW3D, "Bounds",             28, 140, 100, 18, &ob->dtx, 0, 0, 0, 0, "Displays the active object's bounds");
1043         uiDefButS(block, MENU, REDRAWVIEW3D, "Boundary Display%t|Box%x0|Sphere%x1|Cylinder%x2|Cone%x3|Polyheder%x4",
1044                                                                                                                         28, 120, 100, 18, &ob->boundtype, 0, 0, 0, 0, "Selects the boundary display type");
1045         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");
1046         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");
1047         uiDefButBitC(block, TOG, OB_TEXSPACE, REDRAWVIEW3D, "TexSpace", 28, 60, 100, 18, &ob->dtx, 0, 0, 0, 0, "Displays the active object's texture space");
1048         uiDefButBitC(block, TOG, OB_DRAWNAME, REDRAWVIEW3D, "Name",             28, 40, 100, 18, &ob->dtx, 0, 0, 0, 0, "Displays the active object's name");
1049         
1050         
1051 }
1052
1053 void object_panel_hooks(Object *ob)
1054 {
1055         uiBlock *block;
1056         ObHook *hook;
1057         int tothook=0, nr, active;
1058         char *cp;
1059         
1060         block= uiNewBlock(&curarea->uiblocks, "object_panel_hooks", UI_EMBOSS, UI_HELV, curarea->win);
1061         uiNewPanelTabbed("Draw", "Object");
1062         if(uiNewPanel(curarea, block, "Hooks", "Object", 320, 0, 318, 204)==0) return;
1063
1064         if(ob->hooks.first==NULL) {
1065                 uiDefBut(block, LABEL, 0, "Add hooks in Editmode", 10,180,300,19, NULL, 0, 0, 0, 0, "");
1066                 return;
1067         }
1068         
1069         /* build menu */
1070         for(hook= ob->hooks.first; hook; hook= hook->next) tothook++;
1071         
1072         cp= MEM_callocN(32*tothook+32, "temp string");
1073         strcpy(cp, "Active Hook %t|");
1074
1075         for(hook= ob->hooks.first; hook; hook= hook->next) {
1076                 strcat(cp, hook->name);
1077                 strcat(cp, " |");
1078         }
1079         /* active is stored in first hook */
1080         hook= ob->hooks.first;
1081         if(hook->active<1 || hook->active > tothook) hook->active= 1;
1082         active= hook->active;
1083         
1084         uiBlockBeginAlign(block);
1085         uiDefButS(block, MENU, B_REDR, cp,                                      10,180,150,19, &hook->active, 0, 0, 0, 0, "Set active hook");
1086         MEM_freeN(cp);
1087
1088         for(nr=1, hook= ob->hooks.first; hook; hook= hook->next, nr++) {
1089                 if(nr==active) break;
1090         }
1091         if(hook==NULL) printf("error in object_panel_hooks\n");
1092         
1093         uiDefBut(block, TEX, B_REDR, "Name: ",                          160,180,150,19, hook->name, 0, 31, 0, 0, "Set name of hook");
1094
1095         uiBlockBeginAlign(block);
1096         uiDefButF(block, NUM, B_MAKEDISP, "Falloff: ",          160,140,150,19, &hook->falloff, 0.0, 100.0, 100, 0, "If not zero, the distance from hook where influence ends");
1097         uiDefButF(block, NUMSLI, B_MAKEDISP, "Force: ",         160,120,150,19, &hook->force, 0.0, 1.0, 100, 0, "Set relative force of hook");
1098         uiBlockEndAlign(block);
1099
1100         uiDefIDPoinBut(block, test_obpoin_but, B_CLR_HOOK, "Parent:",   10, 120, 150, 19, &hook->parent, "Parent Object for hook, also recalculates and clears offset"); 
1101
1102         uiBlockBeginAlign(block);
1103         uiDefBut(block, BUT, B_DEL_HOOK, "Delete",                              10,80,150,19, NULL, 0.0, 0.0, 0, 0, "Delete hook");
1104         uiDefBut(block, BUT, B_CLR_HOOK, "Clear offset",                160,80,150,19, NULL, 0.0, 0.0, 0, 0, "Recalculate and clear offset (transform) of hook");
1105 }
1106
1107 static void softbody_bake(Object *ob)
1108 {
1109         SoftBody *sb= ob->soft;
1110         ScrArea *sa;
1111         int cfrao= CFRA;
1112         unsigned short event=0;
1113         short val;
1114         
1115         CFRA= sb->sfra;
1116         sbObjectToSoftbody(ob);
1117         ob->softflag |= OB_SB_BAKEDO;
1118         
1119         curarea->win_swap= WIN_BACK_OK;         // clean swapbuffers
1120         
1121         for(; CFRA <= sb->efra; CFRA++) {
1122                 set_timecursor(CFRA);
1123                 
1124                 update_for_newframe_muted();
1125                 
1126                 for(sa= G.curscreen->areabase.first; sa; sa= sa->next) {
1127                         if(sa->spacetype == SPACE_VIEW3D) {
1128                                 scrarea_do_windraw(sa);
1129                         }
1130                 }
1131                 screen_swapbuffers();
1132                 
1133                 while(qtest()) {
1134                         
1135                         event= extern_qread(&val);
1136                         if(event==ESCKEY) break;
1137                 }
1138                 if(event==ESCKEY) break;
1139         }
1140         
1141         if(event==ESCKEY) sbObjectToSoftbody(ob);       // clears all
1142         
1143         /* restore */
1144         waitcursor(0);
1145         ob->softflag &= ~OB_SB_BAKEDO;
1146         CFRA= cfrao;
1147         update_for_newframe_muted();
1148         allqueue(REDRAWVIEW3D, 0);
1149         allqueue(REDRAWBUTSOBJECT, 0);
1150 }
1151
1152
1153 void do_object_panels(unsigned short event)
1154 {
1155         Object *ob;
1156         ObHook *hook;
1157         Effect *eff;
1158         
1159         ob= OBACT;
1160
1161         switch(event) {
1162         case B_TRACKBUTS:
1163                 ob= OBACT;
1164                 if(ob && ob->parent && ob->parent->type==OB_CURVE) freedisplist(&ob->disp);
1165                 allqueue(REDRAWVIEW3D, 0);
1166                 break;
1167         case B_DEL_HOOK:
1168                 hook= ob->hooks.first;
1169                 if(hook) {
1170                         int active= hook->active, nr;
1171                         for(nr=1, hook=ob->hooks.first; hook; hook=hook->next, nr++) {
1172                                 if(active==nr) break;
1173                         }
1174                         if(hook) {
1175                                 BLI_remlink(&ob->hooks, hook);
1176                                 if(hook->indexar) MEM_freeN(hook->indexar);
1177                                 MEM_freeN(hook);
1178                         }
1179                         freedisplist(&ob->disp);
1180                         BIF_undo_push("Delete hook");
1181                         allqueue(REDRAWVIEW3D, 0);
1182                         allqueue(REDRAWBUTSOBJECT, 0);
1183                 }
1184                 break;
1185         case B_CLR_HOOK:
1186                 hook= ob->hooks.first;
1187                 if(hook) {
1188                         int active= hook->active, nr;
1189                         for(nr=1, hook=ob->hooks.first; hook; hook=hook->next, nr++) {
1190                                 if(active==nr) break;
1191                         }
1192                         if(hook && hook->parent) {
1193                                 Mat4Invert(hook->parent->imat, hook->parent->obmat);
1194                                 /* apparently this call goes from right to left... */
1195                                 Mat4MulSerie(hook->parentinv, hook->parent->imat, ob->obmat, NULL, 
1196                                                         NULL, NULL, NULL, NULL, NULL);
1197                                 BIF_undo_push("Clear hook");
1198                                 allqueue(REDRAWVIEW3D, 0);
1199                         }
1200                 }
1201                 break;
1202         case B_RECALCPATH:
1203                 calc_curvepath(OBACT);
1204                 allqueue(REDRAWVIEW3D, 0);
1205                 break;
1206         case B_PRINTSPEED:
1207                 ob= OBACT;
1208                 if(ob) {
1209                         float vec[3];
1210                         CFRA++;
1211                         do_ob_ipo(ob);
1212                         where_is_object(ob);
1213                         VECCOPY(vec, ob->obmat[3]);
1214                         CFRA--;
1215                         do_ob_ipo(ob);
1216                         where_is_object(ob);
1217                         VecSubf(vec, vec, ob->obmat[3]);
1218                         prspeed= Normalise(vec);
1219                         scrarea_queue_winredraw(curarea);
1220                 }
1221                 break;
1222         case B_PRINTLEN:
1223                 ob= OBACT;
1224                 if(ob && ob->type==OB_CURVE) {
1225                         Curve *cu=ob->data;
1226                         
1227                         if(cu->path) prlen= cu->path->totdist; else prlen= -1.0;
1228                         scrarea_queue_winredraw(curarea);
1229                 } 
1230                 break;
1231         case B_RELKEY:
1232                 allspace(REMAKEIPO, 0);
1233                 allqueue(REDRAWBUTSOBJECT, 0);
1234                 allqueue(REDRAWIPO, 0);
1235                 break;
1236         case B_CURVECHECK:
1237                 curve_changes_other_objects(OBACT);
1238                 allqueue(REDRAWVIEW3D, 0);
1239                 break;
1240         
1241         case B_SOFTBODY_CHANGE:
1242                 ob= OBACT;
1243                 if(ob) {
1244                         ob->softflag |= OB_SB_REDO;
1245                         allqueue(REDRAWBUTSOBJECT, 0);
1246                         allqueue(REDRAWVIEW3D, 0);
1247                 }
1248                 break;
1249         case B_SOFTBODY_DEL_VG:
1250                 ob= OBACT;
1251                 if(ob && ob->soft) {
1252                         ob->soft->vertgroup= 0;
1253                         ob->softflag |= OB_SB_REDO;
1254                         allqueue(REDRAWBUTSOBJECT, 0);
1255                         allqueue(REDRAWVIEW3D, 0);
1256                 }
1257                 break;
1258         case B_SOFTBODY_BAKE:
1259                 ob= OBACT;
1260                 if(ob && ob->soft) softbody_bake(ob);
1261                 break;
1262         case B_SOFTBODY_BAKE_FREE:
1263                 ob= OBACT;
1264                 if(ob && ob->soft) sbObjectToSoftbody(ob);
1265                 allqueue(REDRAWBUTSOBJECT, 0);
1266                 allqueue(REDRAWVIEW3D, 0);
1267                 break;
1268                 
1269         default:
1270                 if(event>=B_SELEFFECT && event<B_SELEFFECT+MAX_EFFECT) {
1271                         ob= OBACT;
1272                         if(ob) {
1273                                 int a=B_SELEFFECT;
1274                                 
1275                                 eff= ob->effect.first;
1276                                 while(eff) {
1277                                         if(event==a) eff->flag |= SELECT;
1278                                         else eff->flag &= ~SELECT;
1279                                         
1280                                         a++;
1281                                         eff= eff->next;
1282                                 }
1283                                 allqueue(REDRAWBUTSOBJECT, 0);
1284                         }
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,B_TRACKBUTS,"TrackX",      24,190,59,19, &ob->trackflag, 12.0, 0.0, 0, 0, "Specify the axis that points to another object");
1300         uiDefButC(block, ROW,B_TRACKBUTS,"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,B_TRACKBUTS,"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,B_TRACKBUTS,"-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,B_TRACKBUTS,"-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,B_TRACKBUTS,"-Z",          178,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",          298,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",           24,160,71,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",                                       260,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,89,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, (MAXFRAMEF - 1.0f), 0, 0, "Specify startframe for Dupliframes");
1321         uiDefButS(block, NUM, REDRAWVIEW3D, "DupOn:",           170,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, MAXFRAMEF, 0, 0, "Specify endframe for Dupliframes");
1323         uiDefButS(block, NUM, REDRAWVIEW3D, "DupOff",           171,82,145,19, &ob->dupoff, 0.0, 1500.0, 0, 0, "");
1324         uiBlockBeginAlign(block);
1325         uiDefButC(block, TOG|BIT|2, REDRAWALL, "Offs Ob",                       24,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",         140,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:",                 24,17,115,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",                      248,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, NULL, 1.0, 0, 0, 0, "");
1337         
1338 }
1339
1340 void do_effects_panels(unsigned short event)
1341 {
1342         Object *ob;
1343         Base *base;
1344         Effect *eff, *effn;
1345         int type;
1346         
1347         ob= OBACT;
1348
1349         switch(event) {
1350
1351     case B_AUTOTIMEOFS:
1352                 auto_timeoffs();
1353                 break;
1354         case B_FRAMEMAP:
1355                 G.scene->r.framelen= G.scene->r.framapto;
1356                 G.scene->r.framelen/= G.scene->r.images;
1357                 break;
1358         case B_NEWEFFECT:
1359                 if(ob) {
1360                         if (BLI_countlist(&ob->effect)==MAX_EFFECT)
1361                                 error("Unable to add: effect limit reached");
1362                         else
1363                                 copy_act_effect(ob);
1364                 }
1365                 BIF_undo_push("New effect");
1366                 allqueue(REDRAWBUTSOBJECT, 0);
1367                 break;
1368         case B_DELEFFECT:
1369                 if(ob==0 || ob->type!=OB_MESH) break;
1370                 eff= ob->effect.first;
1371                 while(eff) {
1372                         effn= eff->next;
1373                         if(eff->flag & SELECT) {
1374                                 BLI_remlink(&ob->effect, eff);
1375                                 free_effect(eff);
1376                                 break;
1377                         }
1378                         eff= effn;
1379                 }
1380                 BIF_undo_push("Delete effect");
1381                 allqueue(REDRAWVIEW3D, 0);
1382                 allqueue(REDRAWBUTSOBJECT, 0);
1383                 break;
1384         case B_NEXTEFFECT:
1385                 if(ob==0 || ob->type!=OB_MESH) break;
1386                 eff= ob->effect.first;
1387                 while(eff) {
1388                         if(eff->flag & SELECT) {
1389                                 if(eff->next) {
1390                                         eff->flag &= ~SELECT;
1391                                         eff->next->flag |= SELECT;
1392                                 }
1393                                 break;
1394                         }
1395                         eff= eff->next;
1396                 }
1397                 allqueue(REDRAWBUTSOBJECT, 0);
1398                 break;
1399         case B_PREVEFFECT:
1400                 if(ob==0 || ob->type!=OB_MESH) break;
1401                 eff= ob->effect.first;
1402                 while(eff) {
1403                         if(eff->flag & SELECT) {
1404                                 if(eff->prev) {
1405                                         eff->flag &= ~SELECT;
1406                                         eff->prev->flag |= SELECT;
1407                                 }
1408                                 break;
1409                         }
1410                         eff= eff->next;
1411                 }
1412                 allqueue(REDRAWBUTSOBJECT, 0);
1413                 break;
1414         case B_CHANGEEFFECT:
1415                 if(ob==0 || ob->type!=OB_MESH) break;
1416                 eff= ob->effect.first;
1417                 while(eff) {
1418                         if(eff->flag & SELECT) {
1419                                 if(eff->type!=eff->buttype) {
1420                                         BLI_remlink(&ob->effect, eff);
1421                                         type= eff->buttype;
1422                                         free_effect(eff);
1423                                         eff= add_effect(type);
1424                                         BLI_addtail(&ob->effect, eff);
1425                                 }
1426                                 break;
1427                         }
1428                         eff= eff->next;
1429                 }
1430                 allqueue(REDRAWVIEW3D, 0);
1431                 allqueue(REDRAWBUTSOBJECT, 0);
1432                 break;
1433         case B_CALCEFFECT:
1434                 if(ob==0 || ob->type!=OB_MESH) break;
1435                 eff= ob->effect.first;
1436                 while(eff) {
1437                         if(eff->flag & SELECT) {
1438                                 if(eff->type==EFF_PARTICLE) build_particle_system(ob);
1439                                 else if(eff->type==EFF_WAVE) freedisplist(&ob->disp);
1440                         }
1441                         eff= eff->next;
1442                 }
1443                 allqueue(REDRAWVIEW3D, 0);
1444                 allqueue(REDRAWBUTSOBJECT, 0);
1445                 break;
1446         case B_RECALCAL:
1447                 base= FIRSTBASE;
1448                 while(base) {
1449                         if(base->lay & G.vd->lay) {
1450                                 ob= base->object;
1451                                 eff= ob->effect.first;
1452                                 while(eff) {
1453                                         if(eff->flag & SELECT) {
1454                                                 if(eff->type==EFF_PARTICLE) build_particle_system(ob);
1455                                         }
1456                                         eff= eff->next;
1457                                 }
1458                         }
1459                         base= base->next;
1460                 }
1461                 allqueue(REDRAWVIEW3D, 0);
1462                 break;
1463
1464         default:
1465                 if(event>=B_SELEFFECT && event<B_SELEFFECT+MAX_EFFECT) {
1466                         ob= OBACT;
1467                         if(ob) {
1468                                 int a=B_SELEFFECT;
1469                                 
1470                                 eff= ob->effect.first;
1471                                 while(eff) {
1472                                         if(event==a) eff->flag |= SELECT;
1473                                         else eff->flag &= ~SELECT;
1474                                         
1475                                         a++;
1476                                         eff= eff->next;
1477                                 }
1478                                 allqueue(REDRAWBUTSOBJECT, 0);
1479                         }
1480                 }
1481         }
1482
1483 }
1484
1485 /* Panel for particle interaction settings */
1486 static void object_panel_deflectors(Object *ob)
1487 {
1488         uiBlock *block;
1489
1490         block= uiNewBlock(&curarea->uiblocks, "object_panel_deflectors", UI_EMBOSS, UI_HELV, curarea->win);
1491         uiNewPanelTabbed("Constraints", "Object");
1492         if(uiNewPanel(curarea, block, "Particle Interaction", "Object", 640, 0, 318, 204)==0) return;
1493
1494         /* should become button, option? */
1495         if(ob->pd==NULL) {
1496                 ob->pd= MEM_callocN(sizeof(PartDeflect), "PartDeflect");
1497                 /* and if needed, init here */
1498                 ob->pd->pdef_sbdamp = 0.1;
1499                 ob->pd->pdef_sbift  = 0.2;
1500                 ob->pd->pdef_sboft  = 0.02;
1501         }
1502         
1503         if(ob->pd) {
1504                 PartDeflect *pd= ob->pd;
1505                 
1506                 uiBlockBeginAlign(block);
1507                 uiDefButS(block, ROW, REDRAWVIEW3D, "None",                     10,160,50,20, &pd->forcefield, 1.0, 0, 0, 0, "No force");
1508                 uiDefButS(block, ROW, REDRAWVIEW3D, "Wind",                     60,160,50,20, &pd->forcefield, 1.0, PFIELD_WIND, 0, 0, "Constant force applied in direction of Object Z axis");
1509                 uiDefButS(block, ROW, REDRAWVIEW3D, "Force field",      110,160,100,20, &pd->forcefield, 1.0, PFIELD_FORCE, 0, 0, "Object center attracts or repels particles");
1510                 uiDefButS(block, ROW, REDRAWVIEW3D, "Vortex field",     210,160,100,20, &pd->forcefield, 1.0, PFIELD_VORTEX, 0, 0, "Particles swirl around Z-axis of the object");
1511
1512                 uiBlockBeginAlign(block);
1513                 uiDefButF(block, NUM, REDRAWVIEW3D, "Strength: ",       10,130,150,20, &pd->f_strength, -1000, 1000, 1000, 0, "Strength of force field");
1514                 uiDefButF(block, NUM, REDRAWVIEW3D, "Fall-off: ",       160,130,150,20, &pd->f_power, 0, 10, 100, 0, "Falloff power (real gravitational fallof = 2)");
1515                 uiDefButBitS(block, TOG, PFIELD_USEMAX, REDRAWVIEW3D, "Use MaxDist",    10,110,150,20, &pd->flag, 0.0, 0, 0, 0, "Use a maximum distance for the field to work");
1516                 uiDefButF(block, NUM, REDRAWVIEW3D, "MaxDist: ",        160,110,150,20, &pd->maxdist, 0, 1000.0, 100, 0, "Maximum distance for the field to work");
1517
1518                 /* only meshes collide now */
1519                 if(ob->type==OB_MESH) {
1520                         uiBlockBeginAlign(block);
1521                         uiDefButS(block, TOG|BIT|0, B_DIFF, "Deflection",10,50,200,20, &pd->deflect, 0, 0, 0, 0, "Deflects particles based on collision");
1522                         uiDefButF(block, NUM, B_DIFF, "Damping: ",      10,30,200,20, &pd->pdef_damp, 0.0, 1.0, 10, 0, "Amount of damping during particle collision");
1523                         uiDefButF(block, NUM, B_DIFF, "Rnd Damping: ",  10,10,200,20, &pd->pdef_rdamp, 0.0, 1.0, 10, 0, "Random variation of damping");
1524                         uiDefButF(block, NUM, B_DIFF, "Permeability: ",         10,-10,200,20, &pd->pdef_perm, 0.0, 1.0, 10, 0, "Chance that the particle will pass through the mesh");
1525                 }
1526                 uiBlockEndAlign(block);
1527
1528                 if(ob->type==OB_MESH) {
1529                         uiBlockBeginAlign(block);
1530                         uiDefBut(block, LABEL, 0, "Softbody",   210, 50,110,20, NULL, 0.0, 0.0, 0, 0, "");      
1531                         uiDefButF(block, NUM, B_DIFF, "D",      210,30,110,20, &pd->pdef_sbdamp, 0.0, 1.0, 10, 0, "Amount of damping during softbody collision");
1532                         uiDefButF(block, NUM, B_DIFF, "I",      210,10,110,20, &pd->pdef_sbift, 0.001, 1.0, 10, 0, "Inner face thickness");
1533                         uiDefButF(block, NUM, B_DIFF, "O",              210,-10,110,20, &pd->pdef_sboft, 0.001, 1.0, 10, 0, "Outer face thickness");
1534                 }
1535                 uiBlockEndAlign(block);
1536         
1537         
1538         }
1539 }
1540
1541
1542 /* Panel for softbodies */
1543
1544 static void object_softbodies(Object *ob)
1545 {
1546         uiBlock *block;
1547         
1548         block= uiNewBlock(&curarea->uiblocks, "object_softbodies", UI_EMBOSS, UI_HELV, curarea->win);
1549         uiNewPanelTabbed("Constraints", "Object");
1550         if(uiNewPanel(curarea, block, "Softbody", "Object", 640, 0, 318, 204)==0) return;
1551
1552         uiDefButBitS(block, TOG, OB_SB_ENABLE, REDRAWBUTSOBJECT, "Enable Soft Body",    10,200,150,20, &ob->softflag, 0, 0, 0, 0, "Sets object to become soft body");
1553         uiDefBut(block, LABEL, 0, "",   160, 200,150,20, NULL, 0.0, 0.0, 0, 0, "");     // alignment reason
1554         
1555         if(ob->softflag & OB_SB_ENABLE) {
1556                 SoftBody *sb= ob->soft;
1557                 int defCount;
1558                 char *menustr;
1559                 
1560                 if(sb==NULL) {
1561                         sb= ob->soft= sbNew();
1562                         ob->softflag |= OB_SB_GOAL|OB_SB_EDGES;
1563                         // default add edges for softbody
1564                         if(ob->type==OB_MESH) {
1565                                 Mesh *me= ob->data;
1566                                 if(me->medge==NULL) make_edges(me);
1567                         }
1568                 }
1569                 
1570                 uiDefButBitS(block, TOG, OB_SB_BAKESET, REDRAWBUTSOBJECT, "Bake settings",      180,200,130,20, &ob->softflag, 0, 0, 0, 0, "To convert simulation into baked (cached) result");
1571                 
1572                 if(sb->keys) uiSetButLock(1, "SoftBody is baked, free it first");
1573                 
1574                 if(ob->softflag & OB_SB_BAKESET) {
1575                         uiBlockBeginAlign(block);
1576                         uiDefButS(block, NUM, B_DIFF, "Start:",                 10, 170,100,20, &sb->sfra, 1.0, 10000.0, 10, 0, "Start frame for baking");
1577                         uiDefButS(block, NUM, B_DIFF, "End:",                   110, 170,100,20, &sb->efra, 1.0, 10000.0, 10, 0, "End frame for baking");
1578                         uiDefButS(block, NUM, B_DIFF, "Interval:",              210, 170,100,20, &sb->interval, 1.0, 10.0, 10, 0, "Interval in frames between baked keys");
1579                         
1580                         uiClearButLock();
1581                         
1582                         uiBlockBeginAlign(block);
1583                         if(sb->keys) {
1584                                 char str[128];
1585                                 uiDefIconTextBut(block, BUT, B_SOFTBODY_BAKE_FREE, ICON_X, "FREE BAKE", 10, 120,300,20, NULL, 0.0, 0.0, 0, 0, "Free baked result");
1586                                 sprintf(str, "Stored %d vertices %d keys %.3f MB", sb->totpoint, sb->totkey, ((float)16*sb->totpoint*sb->totkey)/(1024.0*1024.0));
1587                                 uiDefBut(block, LABEL, 0, str, 10, 100,300,20, NULL, 0.0, 0.0, 00, 0, "");
1588                         }
1589                         else                            
1590                                 uiDefBut(block, BUT, B_SOFTBODY_BAKE, "BAKE",   10, 120,300,20, NULL, 0.0, 0.0, 10, 0, "Start baking. Press ESC to exit without baking");
1591                 }
1592                 else {
1593                         /* GENERAL STUFF */
1594                         uiBlockBeginAlign(block);
1595                         uiDefButF(block, NUM, B_DIFF, "Friction:",              10, 170,150,20, &sb->mediafrict, 0.0, 10.0, 10, 0, "General Friction for point movements");
1596                         uiDefButF(block, NUM, B_DIFF, "Mass:",                  160, 170,150,20, &sb->nodemass , 0.001, 50.0, 10, 0, "Point Mass, the heavier the slower");
1597                         uiDefButF(block, NUM, B_DIFF, "Grav:",                  10,150,100,20, &sb->grav , 0.0, 10.0, 10, 0, "Apply gravitation to point movement");
1598                         uiDefButF(block, NUM, B_DIFF, "RKL:",                   110,150,100,20, &sb->rklimit , 0.01, 1.0, 10, 0, "Runge-Kutta ODE solver error limit");
1599                         uiDefButF(block, NUM, B_DIFF, "Time:",                  210,150,100,20, &sb->physics_speed , 0.01, 100.0, 10, 0, "Tweak timing for physics to control frequency and speed");
1600                         uiDefButBitS(block, TOG, OB_SB_POSTDEF, B_DIFF, "PostDef",      10,130,300,20, &ob->softflag, 0, 0, 0, 0, "Apply Soft AFTER Deform");
1601                         uiBlockEndAlign(block);
1602                         
1603                         /* GOAL STUFF */
1604                         uiBlockBeginAlign(block);
1605                         uiDefButBitS(block, TOG, OB_SB_GOAL, B_DIFF, "Use Goal",        10,100,130,20, &ob->softflag, 0, 0, 0, 0, "Define forces for vertices to stick to animated position");
1606                         
1607                         menustr= get_vertexgroup_menustr(ob);
1608                         defCount=BLI_countlist(&ob->defbase);
1609                         if(defCount==0) sb->vertgroup= 0;
1610                         uiDefButS(block, MENU, B_SOFTBODY_CHANGE, menustr,              140,100,20,20, &sb->vertgroup, 0, defCount, 0, 0, "Browses available vertex groups");
1611                         
1612                         if(sb->vertgroup) {
1613                                 bDeformGroup *defGroup = BLI_findlink(&ob->defbase, sb->vertgroup-1);
1614                                 if(defGroup)
1615                                         uiDefBut(block, BUT, B_DIFF, defGroup->name,    160,100,130,20, NULL, 0.0, 0.0, 0, 0, "Name of current vertex group");
1616                                 else
1617                                         uiDefBut(block, BUT, B_DIFF, "(no group)",      160,100,130,20, NULL, 0.0, 0.0, 0, 0, "Vertex Group doesn't exist anymore");
1618                                 uiDefIconBut(block, BUT, B_SOFTBODY_DEL_VG, ICON_X, 290,100,20,20, 0, 0, 0, 0, 0, "Disable use of vertex group");
1619                         }
1620                         else {
1621                                 uiDefButF(block, NUM, B_SOFTBODY_CHANGE, "Goal:",       160,100,150,20, &sb->defgoal, 0.0, 1.0, 10, 0, "Default Goal (vertex target position) value, when no Vertex Group used");
1622                         }
1623                         MEM_freeN (menustr);
1624
1625                         uiDefButF(block, NUM, B_DIFF, "GSpring:",       10,80,150,20, &sb->goalspring, 0.0, 0.999, 10, 0, "Goal (vertex target position) Spring Constant");
1626                         uiDefButF(block, NUM, B_DIFF, "GFrict:",        160,80,150,20, &sb->goalfrict  , 0.0, 10.0, 10, 0, "Goal (vertex target position) Friction Constant");
1627                         uiDefButF(block, NUM, B_SOFTBODY_CHANGE, "GMin:",               10,60,150,20, &sb->mingoal, 0.0, 1.0, 10, 0, "Min Goal bound");
1628                         uiDefButF(block, NUM, B_SOFTBODY_CHANGE, "GMax:",               160,60,150,20, &sb->maxgoal, 0.0, 1.0, 10, 0, "Max Goal bound");
1629                         uiBlockEndAlign(block);
1630                         
1631                         /* EDGE SPRING STUFF */
1632                         uiBlockBeginAlign(block);
1633                         uiDefButBitS(block, TOG, OB_SB_EDGES, B_SOFTBODY_CHANGE, "Use Edges",           10,30,150,20, &ob->softflag, 0, 0, 0, 0, "Use Robust 2nd order solver");
1634                         uiDefButBitS(block, TOG, OB_SB_QUADS, B_SOFTBODY_CHANGE, "Stiff Quads",         160,30,150,20, &ob->softflag, 0, 0, 0, 0, "Sets object to have diagonal springs on 4-gons");
1635                         uiDefButF(block, NUM, B_DIFF, "ESpring:",       10,10,150,20, &sb->inspring, 0.0,  0.999, 10, 0, "Edge Spring Constant");
1636                         uiDefButF(block, NUM, B_DIFF, "EFrict:",        160,10,150,20, &sb->infrict, 0.0,  10.0, 10, 0, "Edge Friction Constant");
1637                         uiBlockEndAlign(block);
1638                 }
1639         }
1640         uiBlockEndAlign(block);
1641
1642 }
1643
1644 void object_panel_effects(Object *ob)
1645 {
1646         Effect *eff;
1647         uiBlock *block;
1648         int a;
1649         short x, y;
1650         
1651         block= uiNewBlock(&curarea->uiblocks, "object_panel_effects", UI_EMBOSS, UI_HELV, curarea->win);
1652         uiNewPanelTabbed("Constraints", "Object");
1653         if(uiNewPanel(curarea, block, "Effects", "Object", 640, 0, 318, 204)==0) return;
1654
1655         /* EFFECTS */
1656         
1657         if (ob->type == OB_MESH) {
1658                 uiBlockBeginAlign(block);
1659                 uiDefBut(block, BUT, B_NEWEFFECT, "NEW Effect", 550,187,124,27, 0, 0, 0, 0, 0, "Create a new effect");
1660                 uiDefBut(block, BUT, B_DELEFFECT, "Delete", 676,187,62,27, 0, 0, 0, 0, 0, "Delete the effect");
1661                 uiBlockEndAlign(block);
1662         }
1663
1664         /* select effs */
1665         eff= ob->effect.first;
1666         a= 0;
1667         while(eff) {
1668                 
1669                 x= 15 * a + 550;
1670                 y= 172; // - 12*( abs(a/10) ) ;
1671                 uiDefButS(block, TOG|BIT|0, B_SELEFFECT+a, "", x, y, 15, 12, &eff->flag, 0, 0, 0, 0, "");
1672                 
1673                 a++;
1674                 if(a==MAX_EFFECT) break;
1675                 eff= eff->next;
1676         }
1677         
1678         eff= ob->effect.first;
1679         while(eff) {
1680                 if(eff->flag & SELECT) break;
1681                 eff= eff->next;
1682         }
1683         
1684         if(eff) {
1685                 uiDefButS(block, MENU, B_CHANGEEFFECT, "Build %x0|Particles %x1|Wave %x2", 895,187,107,27, &eff->buttype, 0, 0, 0, 0, "Set effect type");
1686                 
1687                 if(eff->type==EFF_BUILD) {
1688                         BuildEff *bld;
1689                         
1690                         bld= (BuildEff *)eff;
1691                         
1692                         uiDefButF(block, NUM, 0, "Len:",                        649,138,95,21, &bld->len, 1.0, 9000.0, 100, 0, "Specify the total time the build effect requires");
1693                         uiDefButF(block, NUM, 0, "Sfra:",                       746,138,94,22, &bld->sfra, 1.0, 9000.0, 100, 0, "Specify the startframe of the effect");
1694                 }
1695                 else if(eff->type==EFF_WAVE) {
1696                         WaveEff *wav;
1697                         
1698                         wav= (WaveEff *)eff;
1699                         uiBlockBeginAlign(block);
1700                         uiDefButS(block, TOG|BIT|1, B_CALCEFFECT, "X",          782,135,54,23, &wav->flag, 0, 0, 0, 0, "Enable X axis motion");
1701                         uiDefButS(block, TOG|BIT|2, B_CALCEFFECT, "Y",          840,135,47,23, &wav->flag, 0, 0, 0, 0, "Enable Y axis motion");
1702                         uiDefButS(block, TOG|BIT|3, B_CALCEFFECT, "Cycl",       890,135,111,23, &wav->flag, 0, 0, 0, 0, "Enable cyclic wave effect");
1703                         uiBlockBeginAlign(block);
1704                         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");
1705                         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");
1706                         uiBlockBeginAlign(block);
1707                         uiDefButF(block, NUMSLI, B_CALCEFFECT, "Speed:",        550,100,216,20, &wav->speed, -2.0, 2.0, 0, 0, "Specify the wave speed");
1708                         uiDefButF(block, NUMSLI, B_CALCEFFECT, "Heigth:",       550,80,216,20, &wav->height, -2.0, 2.0, 0, 0, "Specify the amplitude of the wave");
1709                         uiDefButF(block, NUMSLI, B_CALCEFFECT, "Width:",        550,60,216,20, &wav->width, 0.0, 5.0, 0, 0, "Specify the width of the wave");
1710                         uiDefButF(block, NUMSLI, B_CALCEFFECT, "Narrow:",       550,40,216,20, &wav->narrow, 0.0, 10.0, 0, 0, "Specify how narrow the wave follows");
1711                         uiBlockBeginAlign(block);
1712                         uiDefButF(block, NUM, B_CALCEFFECT, "Time sta:",        780,100,219,20, &wav->timeoffs, -1000.0, 1000.0, 100, 0, "Specify startingframe of the wave");
1713
1714                         uiDefButF(block, NUM, B_CALCEFFECT, "Lifetime:",        780,80,219,20, &wav->lifetime,  -1000.0, 1000.0, 100, 0, "Specify the lifespan of the wave");
1715                         uiDefButF(block, NUM, B_CALCEFFECT, "Damptime:",        780,60,219,20, &wav->damp,  -1000.0, 1000.0, 100, 0, "Specify the dampingtime of the wave");
1716                         uiBlockEndAlign(block);
1717                 }
1718                 else if(eff->type==EFF_PARTICLE) {
1719                         PartEff *paf;
1720                         
1721                         paf= (PartEff *)eff;
1722                         
1723                         uiDefBut(block, BUT, B_RECALCAL, "RecalcAll", 741,187,67,27, 0, 0, 0, 0, 0, "Update the particle system");
1724                         uiBlockBeginAlign(block);
1725                         uiDefButS(block, TOG|BIT|2, B_CALCEFFECT, "Static",     825,187,67,27, &paf->flag, 0, 0, 0, 0, "Make static particles (deform only works with SubSurf)");
1726                         if(paf->flag & PAF_STATIC)
1727                                 uiDefButS(block, TOG|BIT|4, B_DIFF, "Animated",825,167,67,20, &paf->flag, 0, 0, 0, 0, "Static particles are recalculated each rendered frame");
1728                         
1729                         uiBlockBeginAlign(block);
1730                         uiDefButI(block, NUM, B_CALCEFFECT, "Tot:",                     550,146,91,20, &paf->totpart, 1.0, 100000.0, 0, 0, "Set the total number of particles");
1731                         if(paf->flag & PAF_STATIC) {
1732                                 uiDefButS(block, NUM, REDRAWVIEW3D, "Step:",    644,146,84+97,20, &paf->staticstep, 1.0, 100.0, 10, 0, "For static duplicators, the Step value skips particles");
1733                         }
1734                         else {
1735                                 uiDefButF(block, NUM, B_CALCEFFECT, "Sta:",             644,146,84,20, &paf->sta, -250.0, 9000.0, 100, 0, "Specify the startframe");
1736                                 uiDefButF(block, NUM, B_CALCEFFECT, "End:",             731,146,97,20, &paf->end, 1.0, 9000.0, 100, 0, "Specify the endframe");
1737                         }
1738                         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");
1739                         uiDefButI(block, NUM, B_CALCEFFECT, "Keys:",            922,146,80,20, &paf->totkey, 1.0, 100.0, 0, 0, "Specify the number of key positions");
1740                         
1741                         uiDefButS(block, NUM, B_REDR,           "CurMul:",              550,124,91,20, &paf->curmult, 0.0, 3.0, 0, 0, "Multiply the particles");
1742                         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");
1743                         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.");
1744                         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");
1745                         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");
1746                         
1747                         uiBlockBeginAlign(block);
1748                         uiDefButF(block, NUM, B_CALCEFFECT, "Randlife:",        550,96,96,20, &paf->randlife, 0.0, 2.0, 10, 0, "Give the particlelife a random variation");
1749                         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");
1750
1751                         uiDefButS(block, TOG|BIT|3, B_CALCEFFECT, "Face",               735,96,46,20, &paf->flag, 0, 0, 0, 0, "Emit particles also from faces");
1752                         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");
1753                         uiDefButS(block, TOG, REDRAWVIEW3D, "Vect",                             837,96,45,20, &paf->stype, 0, 0, 0, 0, "Give the particles a rotation direction");
1754                         uiDefButF(block, NUM, B_DIFF,                   "VectSize",             885,96,116,20, &paf->vectsize, 0.0, 1.0, 10, 0, "Set the speed for Vect");      
1755
1756                         uiBlockBeginAlign(block);
1757                         uiBlockSetCol(block, TH_BUT_SETTING2);
1758                         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");
1759                         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");
1760                         uiDefButF(block, NUM, B_CALCEFFECT, "Rand:",            738,67,86,20, &paf->randfac, 0.0, 2.0, 10, 0, "Give the startingspeed a random variation");
1761                         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");
1762                         uiDefButF(block, NUM, B_CALCEFFECT, "Damp:",            913,67,89,20, &paf->damp, 0.0, 1.0, 10, 0, "Specify the damping factor");
1763                         uiBlockSetCol(block, TH_AUTO);
1764                         
1765                         uiBlockBeginAlign(block);
1766                         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");
1767                         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");
1768                         uiDefBut(block, LABEL, 0, "Force:",                             550,9,72,20, NULL, 1.0, 0, 0, 0, "");
1769                         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");
1770
1771                         uiBlockBeginAlign(block);
1772                         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");
1773                         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");
1774                         uiDefBut(block, LABEL, 0, "Texture:",                   722,9,74,20, NULL, 1.0, 0, 0, 0, "");
1775                         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");
1776                         uiBlockEndAlign(block);
1777
1778                         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");
1779
1780                         uiBlockBeginAlign(block);
1781                         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 vector");
1782                         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 vector");
1783                         uiDefButF(block, NUM, B_CALCEFFECT, "Nabla:",           911,9,91,20, &paf->nabla, 0.0001f, 1.0, 1, 0, "Specify the dimension of the area for gradient calculation");
1784
1785                 }
1786         }
1787 }
1788
1789 void object_panels()
1790 {
1791         Object *ob;
1792
1793         /* check context here */
1794         ob= OBACT;
1795         if(ob) {
1796                 if(ob->id.lib) uiSetButLock(1, "Can't edit library data");
1797
1798                 object_panel_anim(ob);
1799                 object_panel_draw(ob);
1800                 object_panel_hooks(ob);
1801                 object_panel_constraint();
1802                 if(ob->type==OB_MESH) {
1803                         object_panel_effects(ob);
1804                 }
1805                 object_panel_deflectors(ob);
1806                 object_softbodies(ob);
1807
1808                 uiClearButLock();
1809         }
1810 }
1811