Feature: Sofbody bake "Local"
[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_ID.h"
45 #include "DNA_screen_types.h"
46 #include "DNA_space_types.h"
47 #include "DNA_scene_types.h"
48
49 #include "BKE_action.h"
50 #include "BKE_global.h"
51 #include "BKE_main.h"
52 #include "BKE_library.h"
53 #include "BKE_softbody.h"
54 #include "BKE_utildefines.h"
55
56 #include "BLI_blenlib.h"
57 #include "BLI_arithb.h"
58
59 #include "BSE_filesel.h"
60 #include "BSE_headerbuttons.h"
61
62 #include "BIF_butspace.h"
63 #include "BIF_editaction.h"
64 #include "BIF_gl.h"
65 #include "BIF_glutil.h"
66 #include "BIF_graphics.h"
67 #include "BIF_interface.h"
68 #include "BIF_keyval.h"
69 #include "BIF_mainqueue.h"
70 #include "BIF_mywindow.h"
71 #include "BIF_poseobject.h"
72 #include "BIF_resources.h"
73 #include "BIF_screen.h"
74 #include "BIF_space.h"
75 #include "BIF_toolbox.h"
76
77 #include "BDR_drawobject.h"
78 #include "BDR_editcurve.h"
79
80 #include "mydevice.h"
81 #include "blendef.h"
82
83 /* -----includes for this file specific----- */
84
85
86 #include "DNA_action_types.h"
87 #include "DNA_armature_types.h"
88 #include "DNA_camera_types.h"
89 #include "DNA_constraint_types.h"
90 #include "DNA_curve_types.h"
91 #include "DNA_effect_types.h"
92 #include "DNA_group_types.h"
93 #include "DNA_image_types.h"
94 #include "DNA_key_types.h"
95 #include "DNA_lamp_types.h"
96 #include "DNA_lattice_types.h"
97 #include "DNA_material_types.h"
98 #include "DNA_meta_types.h"
99 #include "DNA_mesh_types.h"
100 #include "DNA_modifier_types.h"
101 #include "DNA_object_types.h"
102 #include "DNA_object_force.h"
103 #include "DNA_object_fluidsim.h"
104 #include "DNA_radio_types.h"
105 #include "DNA_screen_types.h"
106 #include "DNA_sound_types.h"
107 #include "DNA_texture_types.h"
108 #include "DNA_userdef_types.h"
109 #include "DNA_vfont_types.h"
110 #include "DNA_view3d_types.h"
111 #include "DNA_world_types.h"
112
113 #include "BKE_anim.h"
114 #include "BKE_armature.h"
115 #include "BKE_constraint.h"
116 #include "BKE_curve.h"
117 #include "BKE_deform.h"
118 #include "BKE_depsgraph.h"
119 #include "BKE_displist.h"
120 #include "BKE_effect.h"
121 #include "BKE_font.h"
122 #include "BKE_group.h"
123 #include "BKE_image.h"
124 #include "BKE_ipo.h"
125 #include "BKE_lattice.h"
126 #include "BKE_material.h"
127 #include "BKE_mball.h"
128 #include "BKE_mesh.h"
129 #include "BKE_modifier.h"
130 #include "BKE_object.h"
131 #include "BKE_sound.h"
132 #include "BKE_texture.h"
133 #include "BKE_utildefines.h"
134 #include "BKE_DerivedMesh.h"
135
136 #include "LBM_fluidsim.h"
137
138 #include "BIF_editconstraint.h"
139 #include "BIF_editdeform.h"
140
141 #include "BSE_editipo.h"
142 #include "BSE_edit.h"
143
144 #include "BDR_editobject.h"
145
146 #include "butspace.h" // own module
147
148 static float prspeed=0.0;
149 float prlen=0.0;
150
151
152 /* ********************* CONSTRAINT ***************************** */
153
154 static void constraint_active_func(void *ob_v, void *con_v)
155 {
156         Object *ob= ob_v;
157         bConstraint *con;
158         ListBase *lb;
159         
160         /* lets be nice and escape if its active already */
161         if(con_v) {
162                 con= con_v;
163                 if(con->flag & CONSTRAINT_ACTIVE) return;
164         }
165         
166         lb= get_active_constraints(ob);
167         
168         for(con= lb->first; con; con= con->next) {
169                 if(con==con_v) con->flag |= CONSTRAINT_ACTIVE;
170                 else con->flag &= ~CONSTRAINT_ACTIVE;
171         }
172
173         /* make sure ipowin and buttons shows it */
174         if(ob->ipowin==ID_CO) {
175                 allqueue(REDRAWIPO, ID_CO);
176                 allspace(REMAKEIPO, 0);
177                 allqueue(REDRAWNLA, 0);
178         }
179         allqueue(REDRAWBUTSOBJECT, 0);
180 }
181
182 static void add_constraint_to_active(Object *ob, bConstraint *con)
183 {
184         ListBase *list;
185         
186         list = get_active_constraints(ob);
187         if (list) {
188                 unique_constraint_name(con, list);
189                 BLI_addtail(list, con);
190                 
191                 con->flag |= CONSTRAINT_ACTIVE;
192                 for(con= con->prev; con; con= con->prev)
193                         con->flag &= ~CONSTRAINT_ACTIVE;
194         }
195 }
196
197 /* returns base ID for Ipo, sets actname to channel if appropriate */
198 /* should not make action... */
199 static void get_constraint_ipo_context(Object *ob, char *actname)
200 {
201         
202         /* todo; check object if it has ob-level action ipo */
203         
204         if (ob->flag & OB_POSEMODE) {
205                 bPoseChannel *pchan;
206                 
207                 pchan = get_active_posechannel(ob);
208                 if (pchan) {
209                         BLI_strncpy(actname, pchan->name, 32);
210                 }
211         }
212         else if(ob->ipoflag & OB_ACTION_OB)
213                 strcpy(actname, "Object");
214 }       
215
216 /* initialize UI to show Ipo window and make sure channels etc exist */
217 static void enable_constraint_ipo_func (void *ob_v, void *con_v)
218 {
219         Object *ob= ob_v;
220         bConstraint *con = con_v;
221         char actname[32]="";
222         
223         /* verifies if active constraint is set and shown in UI */
224         constraint_active_func(ob_v, con_v);
225         
226         /* the context */
227         get_constraint_ipo_context(ob, actname);
228         
229         /* adds ipo & channels & curve if needed */
230         verify_ipo((ID *)ob, ID_CO, actname, con->name);
231         
232         /* make sure ipowin shows it */
233         ob->ipowin= ID_CO;
234         allqueue(REDRAWIPO, ID_CO);
235         allspace(REMAKEIPO, 0);
236         allqueue(REDRAWNLA, 0);
237 }
238
239
240 static void add_influence_key_to_constraint_func (void *ob_v, void *con_v)
241 {
242         Object *ob= ob_v;
243         bConstraint *con = con_v;
244         IpoCurve *icu;
245         char actname[32]="";
246         
247         /* verifies if active constraint is set and shown in UI */
248         constraint_active_func(ob_v, con_v);
249         
250         /* the context */
251         get_constraint_ipo_context(ob, actname);
252
253         /* adds ipo & channels & curve if needed */
254         icu= verify_ipocurve((ID *)ob, ID_CO, actname, con->name, CO_ENFORCE);
255
256         if(ob->action)
257                 insert_vert_ipo(icu, get_action_frame(ob, (float)CFRA), con->enforce);
258         else
259                 insert_vert_ipo(icu, CFRA, con->enforce);
260         
261         /* make sure ipowin shows it */
262         ob->ipowin= ID_CO;
263         allqueue(REDRAWIPO, ID_CO);
264         allspace(REMAKEIPO, 0);
265         allqueue(REDRAWNLA, 0);
266         
267         BIF_undo_push("Insert Influence Key");
268 }
269
270
271 static void del_constraint_func (void *ob_v, void *con_v)
272 {
273         bConstraint *con= con_v;
274         bConstraintChannel *chan;
275         ListBase *lb;
276         
277         /* remove ipo channel */
278         lb= get_active_constraint_channels(ob_v, 0);
279         if(lb) {
280                 chan = get_constraint_channel(lb, con->name);
281                 if(chan) {
282                         if(chan->ipo) chan->ipo->id.us--;
283                         BLI_freelinkN(lb, chan);
284                 }
285         }
286         /* remove constraint itself */
287         lb= get_active_constraints(ob_v);
288         free_constraint_data (con);
289         BLI_freelinkN(lb, con);
290         
291         constraint_active_func(ob_v, NULL);
292
293         BIF_undo_push("Delete constraint");
294         allqueue(REDRAWBUTSOBJECT, 0);
295         allqueue(REDRAWIPO, 0); 
296
297 }
298
299 static void verify_constraint_name_func (void *ob_v, void *con_v)
300 {
301         ListBase *conlist;
302         bConstraint *con= con_v;
303         
304         if (!con)
305                 return;
306         
307         conlist = get_active_constraints(ob_v);
308         unique_constraint_name (con, conlist);
309         constraint_active_func(ob_v, con);
310
311 }
312
313 static void get_constraint_typestring (char *str, bConstraint *con)
314 {
315         switch (con->type){
316         case CONSTRAINT_TYPE_CHILDOF:
317                 strcpy (str, "Child Of");
318                 return;
319         case CONSTRAINT_TYPE_NULL:
320                 strcpy (str, "Null");
321                 return;
322         case CONSTRAINT_TYPE_TRACKTO:
323                 strcpy (str, "Track To");
324                 return;
325         case CONSTRAINT_TYPE_MINMAX:
326                 strcpy (str, "Floor");
327                 return;
328         case CONSTRAINT_TYPE_KINEMATIC:
329                 strcpy (str, "IK Solver");
330                 return;
331         case CONSTRAINT_TYPE_ROTLIKE:
332                 strcpy (str, "Copy Rotation");
333                 return;
334         case CONSTRAINT_TYPE_LOCLIKE:
335                 strcpy (str, "Copy Location");
336                 return;
337         case CONSTRAINT_TYPE_SIZELIKE:
338                 strcpy (str, "Copy Size");
339                 return;
340         case CONSTRAINT_TYPE_ACTION:
341                 strcpy (str, "Action");
342                 return;
343         case CONSTRAINT_TYPE_LOCKTRACK:
344                 strcpy (str, "Locked Track");
345                 return;
346         case CONSTRAINT_TYPE_FOLLOWPATH:
347                 strcpy (str, "Follow Path");
348                 return;
349         case CONSTRAINT_TYPE_STRETCHTO:
350                 strcpy (str, "Stretch To");
351                 return;
352         default:
353                 strcpy (str, "Unknown");
354                 return;
355         }
356 }
357
358 static int get_constraint_col(bConstraint *con)
359 {
360         switch (con->type) {
361         case CONSTRAINT_TYPE_NULL:
362                 return TH_BUT_NEUTRAL;
363         case CONSTRAINT_TYPE_KINEMATIC:
364                 return TH_BUT_SETTING2;
365         case CONSTRAINT_TYPE_TRACKTO:
366                 return TH_BUT_SETTING;
367         case CONSTRAINT_TYPE_ROTLIKE:
368                 return TH_BUT_SETTING1;
369         case CONSTRAINT_TYPE_LOCLIKE:
370                 return TH_BUT_POPUP;
371         case CONSTRAINT_TYPE_MINMAX:
372                 return TH_BUT_POPUP;
373         case CONSTRAINT_TYPE_SIZELIKE:
374                 return TH_BUT_POPUP;
375         case CONSTRAINT_TYPE_ACTION:
376                 return TH_BUT_ACTION;
377         case CONSTRAINT_TYPE_LOCKTRACK:
378                 return TH_BUT_SETTING;
379         case CONSTRAINT_TYPE_FOLLOWPATH:
380                 return TH_BUT_SETTING2;
381         case CONSTRAINT_TYPE_STRETCHTO:
382                 return TH_BUT_SETTING;
383         default:
384                 return TH_REDALERT;
385         }
386 }
387
388 static void constraint_moveUp(void *ob_v, void *con_v)
389 {
390         bConstraint *con, *constr= con_v;
391         ListBase *conlist;
392         
393         if(constr->prev) {
394                 conlist = get_active_constraints(ob_v);
395                 for(con= conlist->first; con; con= con->next) {
396                         if(con==constr) {
397                                 BLI_remlink(conlist, con);
398                                 BLI_insertlink(conlist, con->prev->prev, con);
399                                 break;
400                         }
401                 }
402         }
403         BIF_undo_push("Move constraint");
404 }
405
406 static void constraint_moveDown(void *ob_v, void *con_v)
407 {
408         bConstraint *con, *constr= con_v;
409         ListBase *conlist;
410         
411         if(constr->next) {
412                 conlist = get_active_constraints(ob_v);
413                 for(con= conlist->first; con; con= con->next) {
414                         if(con==constr) {
415                                 BLI_remlink(conlist, con);
416                                 BLI_insertlink(conlist, con->next, con);
417                                 break;
418                         }
419                 }
420         }
421         BIF_undo_push("Move constraint");
422 }
423
424 /* autocomplete callback for ID buttons */
425 void autocomplete_bone(char *str, void *arg_v)
426 {
427         Object *ob= (Object *)arg_v;
428         char truncate[40]= {0};
429         
430         if(ob==NULL || ob->pose==NULL) return;
431         
432         /* search if str matches the beginning of an ID struct */
433         if(str[0]) {
434                 bPoseChannel *pchan;
435                 
436                 for(pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) {
437                         int a;
438                         
439                         for(a=0; a<31; a++) {
440                                 if(str[a]==0 || str[a]!=pchan->name[a])
441                                         break;
442                         }
443                         /* found a match */
444                         if(str[a]==0) {
445                                 /* first match */
446                                 if(truncate[0]==0)
447                                         BLI_strncpy(truncate, pchan->name, 32);
448                                 else {
449                                         /* remove from truncate what is not in bone->name */
450                                         for(a=0; a<31; a++) {
451                                                 if(truncate[a]!=pchan->name[a])
452                                                         truncate[a]= 0;
453                                         }
454                                 }
455                         }
456                 }
457                 if(truncate[0])
458                         BLI_strncpy(str, truncate, 32);
459         }
460 }
461
462 /* autocomplete callback for ID buttons */
463 void autocomplete_vgroup(char *str, void *arg_v)
464 {
465         Object *ob= (Object *)arg_v;
466         char truncate[40]= {0};
467         
468         if(ob==NULL) return;
469         
470         /* search if str matches the beginning of an ID struct */
471         if(str[0]) {
472                 bDeformGroup *dg;
473                 
474                 for(dg= ob->defbase.first; dg; dg= dg->next) {
475                         int a;
476                         
477                         for(a=0; a<31; a++) {
478                                 if(str[a]==0 || str[a]!=dg->name[a])
479                                         break;
480                         }
481                         /* found a match */
482                         if(str[a]==0) {
483                                 /* first match */
484                                 if(truncate[0]==0)
485                                         BLI_strncpy(truncate, dg->name, 32);
486                                 else {
487                                         /* remove from truncate what is not in bone->name */
488                                         for(a=0; a<31; a++) {
489                                                 if(truncate[a]!=dg->name[a])
490                                                         truncate[a]= 0;
491                                         }
492                                 }
493                         }
494                 }
495                 if(truncate[0])
496                         BLI_strncpy(str, truncate, 32);
497         }
498 }
499
500 static void draw_constraint (uiBlock *block, ListBase *list, bConstraint *con, short *xco, short *yco)
501 {
502         Object *ob= OBACT;
503         uiBut *but;
504         char typestr[64];
505         short height, width = 265;
506         int curCol, rb_col;
507
508         /* unless button has own callback, it adds this callback to button */
509         uiBlockSetFunc(block, constraint_active_func, ob, con);
510         
511         get_constraint_typestring (typestr, con);
512
513         curCol = get_constraint_col(con);
514
515         /* Draw constraint header */
516         uiBlockSetEmboss(block, UI_EMBOSSN);
517         
518         /* rounded header */
519         rb_col= (con->flag & CONSTRAINT_ACTIVE)?40:20;
520         uiDefBut(block, ROUNDBOX, B_DIFF, "", *xco-10, *yco-1, width+40, 22, NULL, 5.0, 0.0, 
521                          (con->flag & CONSTRAINT_EXPAND)?3:15 , rb_col-20, ""); 
522         
523         /* open/close */
524         uiDefIconButBitS(block, ICONTOG, CONSTRAINT_EXPAND, B_CONSTRAINT_TEST, ICON_DISCLOSURE_TRI_RIGHT, *xco-10, *yco, 20, 20, &con->flag, 0.0, 0.0, 0.0, 0.0, "Collapse/Expand Constraint");
525         
526         /* up down */
527         uiBlockSetEmboss(block, UI_EMBOSS);
528         but = uiDefIconBut(block, BUT, B_CONSTRAINT_TEST, VICON_MOVE_UP, *xco+width-50, *yco, 16, 18, NULL, 0.0, 0.0, 0.0, 0.0, "Move modifier up in stack");
529         uiButSetFunc(but, constraint_moveUp, ob, con);
530         
531         but = uiDefIconBut(block, BUT, B_CONSTRAINT_TEST, VICON_MOVE_DOWN, *xco+width-50+20, *yco, 16, 18, NULL, 0.0, 0.0, 0.0, 0.0, "Move modifier down in stack");
532         uiButSetFunc(but, constraint_moveDown, ob, con);
533         
534         if (con->flag & CONSTRAINT_EXPAND) {
535                 
536                 if (con->flag & CONSTRAINT_DISABLE) {
537                         BIF_ThemeColor(TH_REDALERT);
538                         uiBlockSetCol(block, TH_REDALERT);
539                 }
540                 else
541                         BIF_ThemeColor(curCol);
542
543                 /*if (type==TARGET_BONE)
544                         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"); 
545                 else
546                         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"); 
547                 */
548                 uiBlockSetEmboss(block, UI_EMBOSS);
549                 
550                 uiDefBut(block, LABEL, B_CONSTRAINT_TEST, typestr, *xco+10, *yco, 100, 18, NULL, 0.0, 0.0, 0.0, 0.0, ""); 
551                 
552                 but = uiDefBut(block, TEX, B_CONSTRAINT_TEST, "", *xco+120, *yco, 85, 18, con->name, 0.0, 29.0, 0.0, 0.0, "Constraint name"); 
553                 uiButSetFunc(but, verify_constraint_name_func, ob, con);
554         }       
555         else{
556                 uiBlockSetEmboss(block, UI_EMBOSSN);
557
558                 if (con->flag & CONSTRAINT_DISABLE) {
559                         uiBlockSetCol(block, TH_REDALERT);
560                         BIF_ThemeColor(TH_REDALERT);
561                 }
562                 else
563                         BIF_ThemeColor(curCol);
564                 
565                 uiDefBut(block, LABEL, B_CONSTRAINT_TEST, typestr, *xco+10, *yco, 100, 18, NULL, 0.0, 0.0, 0.0, 0.0, ""); 
566                 
567                 uiDefBut(block, LABEL, B_CONSTRAINT_TEST, con->name, *xco+120, *yco-1, 135, 19, NULL, 0.0, 0.0, 0.0, 0.0, ""); 
568         }
569
570         uiBlockSetCol(block, TH_AUTO);  
571         
572         uiBlockSetEmboss(block, UI_EMBOSSN);
573         
574         but = uiDefIconBut(block, BUT, B_CONSTRAINT_CHANGETARGET, ICON_X, *xco+262, *yco, 19, 19, list, 0.0, 0.0, 0.0, 0.0, "Delete constraint");
575         uiButSetFunc(but, del_constraint_func, ob, con);
576
577         uiBlockSetEmboss(block, UI_EMBOSS);
578
579
580         /* Draw constraint data*/
581         if (!(con->flag & CONSTRAINT_EXPAND)) {
582                 (*yco)-=21;
583         }
584         else {
585                 switch (con->type){
586                 case CONSTRAINT_TYPE_ACTION:
587                         {
588                                 bActionConstraint *data = con->data;
589                                 bArmature *arm;
590
591                                 height = 88;
592                                 uiDefBut(block, ROUNDBOX, B_DIFF, "", *xco-10, *yco-height, width+40,height-1, NULL, 5.0, 0.0, 12, rb_col, ""); 
593                                 
594                                 uiDefBut(block, LABEL, B_CONSTRAINT_TEST, "Target:", *xco+65, *yco-24, 50, 18, NULL, 0.0, 0.0, 0.0, 0.0, ""); 
595
596                                 /* Draw target parameters */
597                                 uiBlockBeginAlign(block);
598                                 uiDefIDPoinBut(block, test_obpoin_but, ID_OB, B_CONSTRAINT_CHANGETARGET, "OB:", *xco+120, *yco-24, 135, 18, &data->tar, "Target Object"); 
599
600                                 arm = get_armature(data->tar);
601                                 if (arm){
602                                         but=uiDefBut(block, TEX, B_CONSTRAINT_CHANGETARGET, "BO:", *xco+120, *yco-42,135,18, &data->subtarget, 0, 24, 0, 0, "Subtarget Bone");
603                                         uiButSetCompleteFunc(but, autocomplete_bone, (void *)data->tar);
604                                 }
605                                 else
606                                         strcpy (data->subtarget, "");
607                                 uiBlockEndAlign(block);
608
609                                 /* Draw action button */
610                                 uiBlockBeginAlign(block);
611                                 uiDefButS(block, TOG, B_CONSTRAINT_TEST, "Local",                                               *xco+((width/2)-117), *yco-46, 78, 18, &data->local, 0, 0, 0, 0, "Use true local rotation difference");
612                                 uiDefIDPoinBut(block, test_actionpoin_but, ID_AC, B_CONSTRAINT_TEST, "AC:",     *xco+((width/2)-117), *yco-64, 78, 18, &data->act, "Action containing the keyed motion for this bone"); 
613                                 uiDefButS(block, MENU, B_CONSTRAINT_TEST, "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");
614
615                                 uiBlockBeginAlign(block);
616                                 uiDefButS(block, NUM, B_CONSTRAINT_TEST, "Start:", *xco+((width/2)-36), *yco-64, 78, 18, &data->start, 1, MAXFRAME, 0.0, 0.0, "Starting frame of the keyed motion"); 
617                                 uiDefButS(block, NUM, B_CONSTRAINT_TEST, "End:", *xco+((width/2)-36), *yco-84, 78, 18, &data->end, 1, MAXFRAME, 0.0, 0.0, "Ending frame of the keyed motion"); 
618                                 
619                                 uiBlockBeginAlign(block);
620                                 uiDefButF(block, NUM, B_CONSTRAINT_TEST, "Min:", *xco+((width/2)+45), *yco-64, 78, 18, &data->min, -180, 180, 0, 0, "Minimum value for target channel range");
621                                 uiDefButF(block, NUM, B_CONSTRAINT_TEST, "Max:", *xco+((width/2)+45), *yco-84, 78, 18, &data->max, -180, 180, 0, 0, "Maximum value for target channel range");
622                                 uiBlockEndAlign(block);
623                         }
624                         break;
625                 case CONSTRAINT_TYPE_LOCLIKE:
626                         {
627                                 bLocateLikeConstraint *data = con->data;
628                                 bArmature *arm;
629                                 
630                                 height = 66;
631                                 uiDefBut(block, ROUNDBOX, B_DIFF, "", *xco-10, *yco-height, width+40,height-1, NULL, 5.0, 0.0, 12, rb_col, ""); 
632
633                                 uiDefBut(block, LABEL, B_CONSTRAINT_TEST, "Target:", *xco+65, *yco-24, 50, 18, NULL, 0.0, 0.0, 0.0, 0.0, ""); 
634
635                                 /* Draw target parameters */
636                                 uiBlockBeginAlign(block);
637                                 uiDefIDPoinBut(block, test_obpoin_but, ID_OB, B_CONSTRAINT_CHANGETARGET, "OB:", *xco+120, *yco-24, 135, 18, &data->tar, "Target Object"); 
638
639                                 arm = get_armature(data->tar);
640                                 if (arm){
641                                         but=uiDefBut(block, TEX, B_CONSTRAINT_CHANGETARGET, "BO:", *xco+120, *yco-42,135,18, &data->subtarget, 0, 24, 0, 0, "Subtarget Bone");
642                                         uiButSetCompleteFunc(but, autocomplete_bone, (void *)data->tar);
643                                 }
644                                 else
645                                         strcpy (data->subtarget, "");
646                                 uiBlockEndAlign(block);
647                                 
648                                 /* Draw XYZ toggles */
649                                 uiBlockBeginAlign(block);
650                                 if (arm)
651                                         uiDefButBitS(block, TOG, CONSTRAINT_LOCAL, B_CONSTRAINT_TEST, "Local", *xco+((width/2)-98), *yco-64, 50, 18, &con->flag, 0, 24, 0, 0, "Work on a Pose's local transform");
652                                 but=uiDefButBitI(block, TOG, LOCLIKE_X, B_CONSTRAINT_TEST, "X", *xco+((width/2)-48), *yco-64, 32, 18, &data->flag, 0, 24, 0, 0, "Copy X component");
653                                 but=uiDefButBitI(block, TOG, LOCLIKE_Y, B_CONSTRAINT_TEST, "Y", *xco+((width/2)-16), *yco-64, 32, 18, &data->flag, 0, 24, 0, 0, "Copy Y component");
654                                 but=uiDefButBitI(block, TOG, LOCLIKE_Z, B_CONSTRAINT_TEST, "Z", *xco+((width/2)+16), *yco-64, 32, 18, &data->flag, 0, 24, 0, 0, "Copy Z component");
655                                 uiBlockEndAlign(block);
656                         }
657                         break;
658                 case CONSTRAINT_TYPE_ROTLIKE:
659                         {
660                                 bRotateLikeConstraint *data = con->data;
661                                 bArmature *arm;
662                                 
663                                 /* also old files stuff... version patch is too much code! */
664                                 if(data->flag==0) data->flag = ROTLIKE_X|ROTLIKE_Y|ROTLIKE_Z;
665                                 
666                                 height = 66;
667                                 uiDefBut(block, ROUNDBOX, B_DIFF, "", *xco-10, *yco-height, width+40,height-1, NULL, 5.0, 0.0, 12, rb_col, ""); 
668                                 
669                                 uiDefBut(block, LABEL, B_CONSTRAINT_TEST, "Target:", *xco+65, *yco-24, 50, 18, NULL, 0.0, 0.0, 0.0, 0.0, ""); 
670
671                                 /* Draw target parameters */
672                                 uiBlockBeginAlign(block);
673                                 uiDefIDPoinBut(block, test_obpoin_but, ID_OB, B_CONSTRAINT_CHANGETARGET, "OB:", *xco+120, *yco-24, 135, 18, &data->tar, "Target Object"); 
674
675                                 arm = get_armature(data->tar);
676                                 if (arm){
677                                         but=uiDefBut(block, TEX, B_CONSTRAINT_CHANGETARGET, "BO:", *xco+120, *yco-42,135,18, &data->subtarget, 0, 24, 0, 0, "Subtarget Bone");
678                                         uiButSetCompleteFunc(but, autocomplete_bone, (void *)data->tar);
679                                 }
680                                 else
681                                         strcpy (data->subtarget, "");
682                                 uiBlockEndAlign(block);
683                                 
684                                 /* Draw XYZ toggles */
685                                 uiBlockBeginAlign(block);
686                                 if (arm)
687                                         uiDefButBitS(block, TOG, CONSTRAINT_LOCAL, B_CONSTRAINT_TEST, "Local", *xco+((width/2)-98), *yco-64, 50, 18, &con->flag, 0, 24, 0, 0, "Work on a Pose's local transform");
688                                 uiDefButBitI(block, TOG, ROTLIKE_X, B_CONSTRAINT_TEST, "X", *xco+((width/2)-48), *yco-64, 32, 18, &data->flag, 0, 24, 0, 0, "Copy X component");
689                                 uiDefButBitI(block, TOG, ROTLIKE_Y, B_CONSTRAINT_TEST, "Y", *xco+((width/2)-16), *yco-64, 32, 18, &data->flag, 0, 24, 0, 0, "Copy Y component");
690                                 uiDefButBitI(block, TOG, ROTLIKE_Z, B_CONSTRAINT_TEST, "Z", *xco+((width/2)+16), *yco-64, 32, 18, &data->flag, 0, 24, 0, 0, "Copy Z component");
691                                 uiBlockEndAlign(block);
692                         }
693                         break;
694                 case CONSTRAINT_TYPE_SIZELIKE:
695                         {
696                                 bSizeLikeConstraint *data = con->data;
697                                 bArmature *arm;
698                                 height = 66;
699                         
700                                 BIF_ThemeColor(curCol);
701                                 glRects(*xco+3, *yco-height-39, *xco+width+30, *yco-18);
702
703                                 uiDefBut(block, LABEL, B_CONSTRAINT_TEST, "Target:", *xco+65, *yco-24, 50, 18, NULL, 0.0, 0.0, 0.0, 0.0, ""); 
704
705                                 /* Draw target parameters */
706                                 uiBlockBeginAlign(block);
707                                 uiDefIDPoinBut(block, test_obpoin_but, ID_OB, B_CONSTRAINT_CHANGETARGET, "OB:", *xco+120, *yco-24, 135, 18, &data->tar, "Target Object"); 
708                                 
709                                 arm = get_armature(data->tar);
710                                 if (arm){
711                                         but=uiDefBut(block, TEX, B_CONSTRAINT_CHANGETARGET, "BO:", *xco+120, *yco-42,135,18, &data->subtarget, 0, 24, 0, 0, "Subtarget Bone");
712                                         uiButSetCompleteFunc(but, autocomplete_bone, (void *)data->tar);
713                                 }
714                                 else
715                                         strcpy (data->subtarget, "");
716                                 uiBlockEndAlign(block);
717
718                                 /* Draw XYZ toggles */
719                                 uiBlockBeginAlign(block);
720                                 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");
721                                 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");
722                                 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");
723                                 uiBlockEndAlign(block);
724                         }
725                         break;
726                 case CONSTRAINT_TYPE_KINEMATIC:
727                         {
728                                 bKinematicConstraint *data = con->data;
729                                 bArmature *arm;
730                                 
731                                 height = 108;
732                                 uiDefBut(block, ROUNDBOX, B_DIFF, "", *xco-10, *yco-height, width+40,height-1, NULL, 5.0, 0.0, 12, rb_col, ""); 
733                                 
734                                 uiDefBut(block, LABEL, B_CONSTRAINT_TEST, "Target:", *xco+65, *yco-24, 50, 18, NULL, 0.0, 0.0, 0.0, 0.0, ""); 
735
736                                 /* Draw target parameters */
737                                 uiDefButBitS(block, TOG, CONSTRAINT_IK_ROT, B_CONSTRAINT_TEST, "Rot", *xco, *yco-24,60,19, &data->flag, 0, 0, 0, 0, "Chain follows rotation of target");
738                                 
739                                 uiBlockBeginAlign(block);
740                                 uiDefIDPoinBut(block, test_obpoin_but, ID_OB, B_CONSTRAINT_CHANGETARGET, "OB:", *xco+120, *yco-24, 135, 19, &data->tar, "Target Object"); 
741
742                                 arm = get_armature(data->tar);
743                                 if (arm) {
744                                         but=uiDefBut(block, TEX, B_CONSTRAINT_CHANGETARGET, "BO:", *xco+120, *yco-42,135,19, &data->subtarget, 0, 24, 0, 0, "Subtarget Bone");
745                                         uiButSetCompleteFunc(but, autocomplete_bone, (void *)data->tar);
746                                 }
747                                 else
748                                         strcpy (data->subtarget, "");
749         
750                                 uiBlockBeginAlign(block);
751                                 uiDefButBitS(block, TOG, CONSTRAINT_IK_TIP, B_CONSTRAINT_TEST, "Use Tip", *xco, *yco-64, 142, 19, &data->flag, 0, 0, 0, 0, "Include Bone's tip als last element in Chain");
752                                 uiDefButI(block, NUM, B_CONSTRAINT_TEST, "ChainLen:", *xco+142, *yco-64,143,19, &data->rootbone, 0, 255, 0, 0, "If not zero, the amount of bones in this chain");
753                                 
754                                 uiBlockBeginAlign(block);
755                                 uiDefButF(block, NUMSLI, B_CONSTRAINT_TEST, "PosW ", *xco, *yco-86, 142, 19, &data->weight, 0.01, 1.0, 2, 2, "For Tree-IK: weight of position control for this target");
756                                 uiDefButF(block, NUMSLI, B_CONSTRAINT_TEST, "RotW ", *xco+142, *yco-86, 143, 19, &data->orientweight, 0.01, 1.0, 2, 2, "For Tree-IK: Weight of orientation control for this target");
757                                 uiDefButF(block, NUM, B_CONSTRAINT_TEST, "Tolerance:", *xco, *yco-106, 142, 19, &data->tolerance, 0.0001f, 1.0, 0, 0, "Maximum distance to target after solving"); 
758                                 uiDefButS(block, NUM, B_CONSTRAINT_TEST, "Iterations:", *xco+142, *yco-106, 143, 19, &data->iterations, 1, 10000, 0, 0, "Maximum number of solving iterations"); 
759                                 
760                         }
761                         break;
762                 case CONSTRAINT_TYPE_TRACKTO:
763                         {
764                                 bTrackToConstraint *data = con->data;
765                                 bArmature *arm;
766
767                                 height = 66;
768                                 uiDefBut(block, ROUNDBOX, B_DIFF, "", *xco-10, *yco-height, width+40,height-1, NULL, 5.0, 0.0, 12, rb_col, ""); 
769                                 
770                                 uiDefBut(block, LABEL, B_CONSTRAINT_TEST, "Target:", *xco+65, *yco-24, 50, 18, NULL, 0.0, 0.0, 0.0, 0.0, ""); 
771
772                                 /* Draw target parameters */
773                                 uiBlockBeginAlign(block);
774                                 uiDefIDPoinBut(block, test_obpoin_but, ID_OB, B_CONSTRAINT_CHANGETARGET, "OB:", *xco+120, *yco-24, 135, 18, &data->tar, "Target Object"); 
775
776                                 arm = get_armature(data->tar);
777                                 if (arm){
778                                         but=uiDefBut(block, TEX, B_CONSTRAINT_CHANGETARGET, "BO:", *xco+120, *yco-42,135,18, &data->subtarget, 0, 24, 0, 0, "Subtarget Bone");
779                                         uiButSetCompleteFunc(but, autocomplete_bone, (void *)data->tar);
780                                 }
781                                 else
782                                         strcpy (data->subtarget, "");
783                                 uiBlockEndAlign(block);
784
785                                 uiBlockBeginAlign(block);
786                                 uiDefBut(block, LABEL, B_CONSTRAINT_TEST, "To:", *xco+12, *yco-64, 25, 18, NULL, 0.0, 0.0, 0.0, 0.0, ""); 
787                                 
788                                 uiDefButI(block, ROW,B_CONSTRAINT_TEST,"X",     *xco+39, *yco-64,17,18, &data->reserved1, 12.0, 0.0, 0, 0, "The axis that points to the target object");
789                                 uiDefButI(block, ROW,B_CONSTRAINT_TEST,"Y",     *xco+56, *yco-64,17,18, &data->reserved1, 12.0, 1.0, 0, 0, "The axis that points to the target object");
790                                 uiDefButI(block, ROW,B_CONSTRAINT_TEST,"Z",     *xco+73, *yco-64,17,18, &data->reserved1, 12.0, 2.0, 0, 0, "The axis that points to the target object");
791                                 uiDefButI(block, ROW,B_CONSTRAINT_TEST,"-X",    *xco+90, *yco-64,24,18, &data->reserved1, 12.0, 3.0, 0, 0, "The axis that points to the target object");
792                                 uiDefButI(block, ROW,B_CONSTRAINT_TEST,"-Y",    *xco+114, *yco-64,24,18, &data->reserved1, 12.0, 4.0, 0, 0, "The axis that points to the target object");
793                                 uiDefButI(block, ROW,B_CONSTRAINT_TEST,"-Z",    *xco+138, *yco-64,24,18, &data->reserved1, 12.0, 5.0, 0, 0, "The axis that points to the target object");
794                                 uiBlockEndAlign(block);
795                                 
796                                 uiBlockBeginAlign(block);
797                                 uiDefBut(block, LABEL, B_CONSTRAINT_TEST, "Up:", *xco+174, *yco-64, 30, 18, NULL, 0.0, 0.0, 0.0, 0.0, "");
798                                 
799                                 uiDefButI(block, ROW,B_CONSTRAINT_TEST,"X",     *xco+204, *yco-64,17,18, &data->reserved2, 13.0, 0.0, 0, 0, "The axis that points upward");
800                                 uiDefButI(block, ROW,B_CONSTRAINT_TEST,"Y",     *xco+221, *yco-64,17,18, &data->reserved2, 13.0, 1.0, 0, 0, "The axis that points upward");
801                                 uiDefButI(block, ROW,B_CONSTRAINT_TEST,"Z",     *xco+238, *yco-64,17,18, &data->reserved2, 13.0, 2.0, 0, 0, "The axis that points upward");
802                                 uiBlockEndAlign(block);
803                         }
804                         break;
805                 case CONSTRAINT_TYPE_MINMAX:
806                         {
807                                 bMinMaxConstraint *data = con->data;
808                                 bArmature *arm;
809
810                                 height = 66;
811                                 uiDefBut(block, ROUNDBOX, B_DIFF, "", *xco-10, *yco-height, width+40,height-1, NULL, 5.0, 0.0, 12, rb_col, ""); 
812                                 
813                                 uiDefBut(block, LABEL, B_CONSTRAINT_TEST, "Target:", *xco+65, *yco-24, 50, 18, NULL, 0.0, 0.0, 0.0, 0.0, ""); 
814
815                                 uiDefButF(block, NUM, B_CONSTRAINT_TEST, "Offset:", *xco, *yco-44, 100, 18, &data->offset, -100, 100, 100.0, 0.0, "Offset from the position of the object center"); 
816
817                                 /* Draw target parameters */
818                                 uiBlockBeginAlign(block);
819                                 uiDefIDPoinBut(block, test_obpoin_but, ID_OB, B_CONSTRAINT_CHANGETARGET, "OB:", *xco+120, *yco-24, 135, 18, &data->tar, "Target Object"); 
820
821                                 arm = get_armature(data->tar);
822                                 if (arm){
823                                         but=uiDefBut(block, TEX, B_CONSTRAINT_CHANGETARGET, "BO:", *xco+120, *yco-42,135,18, &data->subtarget, 0, 24, 0, 0, "Subtarget Bone");
824                                         uiButSetCompleteFunc(but, autocomplete_bone, (void *)data->tar);
825                                 }
826                                 else
827                                         strcpy (data->subtarget, "");
828                                 uiBlockEndAlign(block);
829
830                                 but=uiDefButBitS(block, TOG, 1, B_CONSTRAINT_TEST, "Sticky", *xco, *yco-24, 54, 18, &data->sticky, 0, 24, 0, 0, "Immobilize object while constrained");
831                                 
832                                 uiDefBut(block, LABEL, B_CONSTRAINT_TEST, "Max/Min:", *xco-8, *yco-64, 54, 18, NULL, 0.0, 0.0, 0.0, 0.0, ""); 
833
834                                 uiBlockBeginAlign(block);                       
835                                 uiDefButI(block, ROW,B_CONSTRAINT_TEST,"X",     *xco+51, *yco-64,17,18, &data->minmaxflag, 12.0, 0.0, 0, 0, "Will not pass below X of target");
836                                 uiDefButI(block, ROW,B_CONSTRAINT_TEST,"Y",     *xco+67, *yco-64,17,18, &data->minmaxflag, 12.0, 1.0, 0, 0, "Will not pass below Y of target");
837                                 uiDefButI(block, ROW,B_CONSTRAINT_TEST,"Z",     *xco+85, *yco-64,17,18, &data->minmaxflag, 12.0, 2.0, 0, 0, "Will not pass below Z of target");
838                                 uiDefButI(block, ROW,B_CONSTRAINT_TEST,"-X",    *xco+102, *yco-64,24,18, &data->minmaxflag, 12.0, 3.0, 0, 0, "Will not pass above X of target");
839                                 uiDefButI(block, ROW,B_CONSTRAINT_TEST,"-Y",    *xco+126, *yco-64,24,18, &data->minmaxflag, 12.0, 4.0, 0, 0, "Will not pass above Y of target");
840                                 uiDefButI(block, ROW,B_CONSTRAINT_TEST,"-Z",    *xco+150, *yco-64,24,18, &data->minmaxflag, 12.0, 5.0, 0, 0, "Will not pass above Z of target");
841                                 uiBlockEndAlign(block);
842                         }
843                         break;
844                 case CONSTRAINT_TYPE_LOCKTRACK:
845                         {
846                                 bLockTrackConstraint *data = con->data;
847                                 bArmature *arm;
848                                 height = 66;
849                                 uiDefBut(block, ROUNDBOX, B_DIFF, "", *xco-10, *yco-height, width+40,height-1, NULL, 5.0, 0.0, 12, rb_col, ""); 
850
851                                 uiDefBut(block, LABEL, B_CONSTRAINT_TEST, "Target:", *xco+65, *yco-24, 50, 18, NULL, 0.0, 0.0, 0.0, 0.0, ""); 
852
853                                 /* Draw target parameters */
854                                 uiBlockBeginAlign(block);
855                                 uiDefIDPoinBut(block, test_obpoin_but, ID_OB, B_CONSTRAINT_CHANGETARGET, "OB:", *xco+120, *yco-24, 135, 18, &data->tar, "Target Object"); 
856
857                                 arm = get_armature(data->tar);
858                                 if (arm){
859                                         but=uiDefBut(block, TEX, B_CONSTRAINT_CHANGETARGET, "BO:", *xco+120, *yco-42,135,18, &data->subtarget, 0, 24, 0, 0, "Subtarget Bone");
860                                         uiButSetCompleteFunc(but, autocomplete_bone, (void *)data->tar);
861                                 }
862                                 else
863                                         strcpy (data->subtarget, "");
864                                 uiBlockEndAlign(block);
865                                 
866                                 uiBlockBeginAlign(block);
867                                 uiDefBut(block, LABEL, B_CONSTRAINT_TEST, "To:", *xco+12, *yco-64, 25, 18, NULL, 0.0, 0.0, 0.0, 0.0, ""); 
868                                 
869                                 uiDefButI(block, ROW,B_CONSTRAINT_TEST,"X",     *xco+39, *yco-64,17,18, &data->trackflag, 12.0, 0.0, 0, 0, "The axis that points to the target object");
870                                 uiDefButI(block, ROW,B_CONSTRAINT_TEST,"Y",     *xco+56, *yco-64,17,18, &data->trackflag, 12.0, 1.0, 0, 0, "The axis that points to the target object");
871                                 uiDefButI(block, ROW,B_CONSTRAINT_TEST,"Z",     *xco+73, *yco-64,17,18, &data->trackflag, 12.0, 2.0, 0, 0, "The axis that points to the target object");
872                                 uiDefButI(block, ROW,B_CONSTRAINT_TEST,"-X",    *xco+90, *yco-64,24,18, &data->trackflag, 12.0, 3.0, 0, 0, "The axis that points to the target object");
873                                 uiDefButI(block, ROW,B_CONSTRAINT_TEST,"-Y",    *xco+114, *yco-64,24,18, &data->trackflag, 12.0, 4.0, 0, 0, "The axis that points to the target object");
874                                 uiDefButI(block, ROW,B_CONSTRAINT_TEST,"-Z",    *xco+138, *yco-64,24,18, &data->trackflag, 12.0, 5.0, 0, 0, "The axis that points to the target object");
875                                 uiBlockEndAlign(block);
876                                 
877                                 uiBlockBeginAlign(block);
878                                 uiDefBut(block, LABEL, B_CONSTRAINT_TEST, "Lock:", *xco+166, *yco-64, 38, 18, NULL, 0.0, 0.0, 0.0, 0.0, "");
879                                 
880                                 uiDefButI(block, ROW,B_CONSTRAINT_TEST,"X",     *xco+204, *yco-64,17,18, &data->lockflag, 13.0, 0.0, 0, 0, "The axis that is locked");
881                                 uiDefButI(block, ROW,B_CONSTRAINT_TEST,"Y",     *xco+221, *yco-64,17,18, &data->lockflag, 13.0, 1.0, 0, 0, "The axis that is locked");
882                                 uiDefButI(block, ROW,B_CONSTRAINT_TEST,"Z",     *xco+238, *yco-64,17,18, &data->lockflag, 13.0, 2.0, 0, 0, "The axis that is locked");
883                                 uiBlockEndAlign(block);
884                         }
885                         break;
886                 case CONSTRAINT_TYPE_FOLLOWPATH:
887                         {
888                                 bFollowPathConstraint *data = con->data;
889
890                                 height = 66;
891                                 uiDefBut(block, ROUNDBOX, B_DIFF, "", *xco-10, *yco-height, width+40,height-1, NULL, 5.0, 0.0, 12, rb_col, ""); 
892                                 
893                                 uiDefBut(block, LABEL, B_CONSTRAINT_TEST, "Target:", *xco+65, *yco-24, 50, 18, NULL, 0.0, 0.0, 0.0, 0.0, ""); 
894
895                                 /* Draw target parameters */
896                                 uiDefIDPoinBut(block, test_obpoin_but, ID_OB, B_CONSTRAINT_CHANGETARGET, "OB:", *xco+120, *yco-24, 135, 18, &data->tar, "Target Object"); 
897                                 
898                                 /* Draw Curve Follow toggle */
899                                 but=uiDefButBitI(block, TOG, 1, 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");
900
901                                 /* Draw Offset number button */
902                                 uiDefButF(block, NUM, B_CONSTRAINT_TEST, "Offset:", *xco+155, *yco-44, 100, 18, &data->offset, -MAXFRAMEF, MAXFRAMEF, 100.0, 0.0, "Offset from the position corresponding to the time frame"); 
903
904                                 uiBlockBeginAlign(block);
905                                 uiDefBut(block, LABEL, B_CONSTRAINT_TEST, "Fw:", *xco+12, *yco-64, 27, 18, NULL, 0.0, 0.0, 0.0, 0.0, ""); 
906                                 
907                                 uiDefButI(block, ROW,B_CONSTRAINT_TEST,"X",     *xco+39, *yco-64,17,18, &data->trackflag, 12.0, 0.0, 0, 0, "The axis that points forward along the path");
908                                 uiDefButI(block, ROW,B_CONSTRAINT_TEST,"Y",     *xco+56, *yco-64,17,18, &data->trackflag, 12.0, 1.0, 0, 0, "The axis that points forward along the path");
909                                 uiDefButI(block, ROW,B_CONSTRAINT_TEST,"Z",     *xco+73, *yco-64,17,18, &data->trackflag, 12.0, 2.0, 0, 0, "The axis that points forward along the path");
910                                 uiDefButI(block, ROW,B_CONSTRAINT_TEST,"-X",    *xco+90, *yco-64,24,18, &data->trackflag, 12.0, 3.0, 0, 0, "The axis that points forward along the path");
911                                 uiDefButI(block, ROW,B_CONSTRAINT_TEST,"-Y",    *xco+114, *yco-64,24,18, &data->trackflag, 12.0, 4.0, 0, 0, "The axis that points forward along the path");
912                                 uiDefButI(block, ROW,B_CONSTRAINT_TEST,"-Z",    *xco+138, *yco-64,24,18, &data->trackflag, 12.0, 5.0, 0, 0, "The axis that points forward along the path");
913                                 uiBlockEndAlign(block);
914                                 
915                                 uiBlockBeginAlign(block);
916                                 uiDefBut(block, LABEL, B_CONSTRAINT_TEST, "Up:", *xco+174, *yco-64, 30, 18, NULL, 0.0, 0.0, 0.0, 0.0, "");
917                                 
918                                 uiDefButI(block, ROW,B_CONSTRAINT_TEST,"X",     *xco+204, *yco-64,17,18, &data->upflag, 13.0, 0.0, 0, 0, "The axis that points upward");
919                                 uiDefButI(block, ROW,B_CONSTRAINT_TEST,"Y",     *xco+221, *yco-64,17,18, &data->upflag, 13.0, 1.0, 0, 0, "The axis that points upward");
920                                 uiDefButI(block, ROW,B_CONSTRAINT_TEST,"Z",     *xco+238, *yco-64,17,18, &data->upflag, 13.0, 2.0, 0, 0, "The axis that points upward");
921                                 uiBlockEndAlign(block);
922                         }
923                         break;
924                 case CONSTRAINT_TYPE_STRETCHTO:
925                         {
926                                 bStretchToConstraint *data = con->data;
927                                 bArmature *arm;
928                                 
929                                 height = 105;
930                                 uiDefBut(block, ROUNDBOX, B_DIFF, "", *xco-10, *yco-height, width+40,height-1, NULL, 5.0, 0.0, 12, rb_col, ""); 
931                                 
932                                 uiDefBut(block, LABEL, B_CONSTRAINT_TEST, "Target:", *xco+65, *yco-24, 50, 18, NULL, 0.0, 0.0, 0.0, 0.0, ""); 
933
934
935                                 /* Draw target parameters */
936                                 uiBlockBeginAlign(block);
937                                 uiDefIDPoinBut(block, test_obpoin_but, ID_OB, B_CONSTRAINT_CHANGETARGET, "OB:", *xco+120, *yco-24, 135, 18, &data->tar, "Target Object"); 
938
939                                 arm = get_armature(data->tar);
940                                 if (arm){
941                                         but=uiDefBut(block, TEX, B_CONSTRAINT_CHANGETARGET, "BO:", *xco+120, *yco-42,135,18, &data->subtarget, 0, 24, 0, 0, "Subtarget Bone");
942                                         uiButSetCompleteFunc(but, autocomplete_bone, (void *)data->tar);
943                                 }
944                                 else
945                                         strcpy (data->subtarget, "");
946                                 uiBlockEndAlign(block);
947
948                                 
949                                 uiBlockBeginAlign(block);
950                                 uiDefButF(block,BUTM,B_CONSTRAINT_TEST,"R",*xco, *yco-60,20,18,&(data->orglength),0.0,0,0,0,"Recalculate RLenght");
951                                 uiDefButF(block,NUM,B_CONSTRAINT_TEST,"Rest Length:",*xco+18, *yco-60,237,18,&(data->orglength),0.0,100,0.5,0.5,"Lenght at Rest Position");
952                                 uiBlockEndAlign(block);
953
954                                 uiDefButF(block,NUM,B_CONSTRAINT_TEST,"Volume Variation:",*xco+18, *yco-82,237,18,&(data->bulge),0.0,100,0.5,0.5,"Factor between volume variation and stretching");
955
956                                 uiBlockBeginAlign(block);
957                                 uiDefBut(block, LABEL, B_CONSTRAINT_TEST, "Vol:",*xco+14, *yco-104,30,18, NULL, 0.0, 0.0, 0.0, 0.0, ""); 
958                                 uiDefButI(block, ROW,B_CONSTRAINT_TEST,"XZ",     *xco+44, *yco-104,30,18, &data->volmode, 12.0, 0.0, 0, 0, "Keep Volume: Scaling X & Z");
959                                 uiDefButI(block, ROW,B_CONSTRAINT_TEST,"X",      *xco+74, *yco-104,20,18, &data->volmode, 12.0, 1.0, 0, 0, "Keep Volume: Scaling X");
960                                 uiDefButI(block, ROW,B_CONSTRAINT_TEST,"Z",      *xco+94, *yco-104,20,18, &data->volmode, 12.0, 2.0, 0, 0, "Keep Volume: Scaling Z");
961                                 uiDefButI(block, ROW,B_CONSTRAINT_TEST,"NONE", *xco+114, *yco-104,50,18, &data->volmode, 12.0, 3.0, 0, 0, "Ignore Volume");
962                                 uiBlockEndAlign(block);
963
964                                 
965                                 uiBlockBeginAlign(block);
966                                 uiDefBut(block, LABEL, B_CONSTRAINT_TEST,"Plane:",*xco+175, *yco-104,40,18, NULL, 0.0, 0.0, 0.0, 0.0, ""); 
967                                 uiDefButI(block, ROW,B_CONSTRAINT_TEST,"X",       *xco+215, *yco-104,20,18, &data->plane, 12.0, 0.0, 0, 0, "Keep X axis");
968                                 uiDefButI(block, ROW,B_CONSTRAINT_TEST,"Z",       *xco+235, *yco-104,20,18, &data->plane, 12.0, 2.0, 0, 0, "Keep Z axis");
969                                 uiBlockEndAlign(block);
970                                 }
971                         break;
972                 case CONSTRAINT_TYPE_NULL:
973                         {
974                                 height = 17;
975                                 uiDefBut(block, ROUNDBOX, B_DIFF, "", *xco-10, *yco-height, width+40,height-1, NULL, 5.0, 0.0, 12, rb_col, ""); 
976                                 
977                         }
978                         break;
979                 default:
980                         height = 0;
981                         break;
982                 }
983
984                 (*yco)-=(24+height);
985         }
986
987         if (con->type!=CONSTRAINT_TYPE_NULL) {
988                 uiBlockBeginAlign(block);
989                 uiDefButF(block, NUMSLI, B_CONSTRAINT_INF, "Influence ", *xco, *yco, 197, 20, &(con->enforce), 0.0, 1.0, 0.0, 0.0, "Amount of influence this constraint will have on the final solution");
990                 but = uiDefBut(block, BUT, B_CONSTRAINT_TEST, "Show", *xco+200, *yco, 45, 20, 0, 0.0, 1.0, 0.0, 0.0, "Show constraint's ipo in the Ipo window, adds a channel if not there");
991                 /* If this is on an object or bone, add ipo channel the constraint */
992                 uiButSetFunc (but, enable_constraint_ipo_func, ob, con);
993                 but = uiDefBut(block, BUT, B_CONSTRAINT_TEST, "Key", *xco+245, *yco, 40, 20, 0, 0.0, 1.0, 0.0, 0.0, "Add an influence keyframe to the constraint");
994                 /* Add a keyframe to the influence IPO */
995                 uiButSetFunc (but, add_influence_key_to_constraint_func, ob, con);
996                 uiBlockEndAlign(block);
997                 (*yco)-=24;
998         } else {
999                 (*yco)-=3;
1000         }
1001         
1002 }
1003
1004 static uiBlock *add_constraintmenu(void *arg_unused)
1005 {
1006         Object *ob= OBACT;
1007         uiBlock *block;
1008         ListBase *conlist;
1009         short yco= 0;
1010         
1011         conlist = get_active_constraints(ob);
1012         
1013         block= uiNewBlock(&curarea->uiblocks, "add_constraintmenu", UI_EMBOSSP, UI_HELV, curarea->win);
1014
1015         uiDefBut(block, BUTM, B_CONSTRAINT_ADD_LOCLIKE,"Copy Location",         0, yco-=20, 160, 19, NULL, 0.0, 0.0, 1, 0, "");
1016         uiDefBut(block, BUTM, B_CONSTRAINT_ADD_ROTLIKE,"Copy Rotation",         0, yco-=20, 160, 19, NULL, 0.0, 0.0, 1, 0, "");
1017         uiDefBut(block, BUTM, B_CONSTRAINT_ADD_SIZELIKE,"Copy Size",            0, yco-=20, 160, 19, NULL, 0.0, 0.0, 1, 0, "");
1018         
1019         uiDefBut(block, SEPR, 0, "",                                    0, yco-=6, 120, 6, NULL, 0.0, 0.0, 0, 0, "");
1020         
1021         uiDefBut(block, BUTM, B_CONSTRAINT_ADD_TRACKTO,"Track To",              0, yco-=20, 160, 19, NULL, 0.0, 0.0, 1, 0, "");
1022         uiDefBut(block, BUTM, B_CONSTRAINT_ADD_MINMAX,"Floor",          0, yco-=20, 160, 19, NULL, 0.0, 0.0, 1, 0, "");
1023         uiDefBut(block, BUTM, B_CONSTRAINT_ADD_LOCKTRACK,"Locked Track",                0, yco-=20, 160, 19, NULL, 0.0, 0.0, 1, 0, "");
1024         uiDefBut(block, BUTM, B_CONSTRAINT_ADD_FOLLOWPATH,"Follow Path",                0, yco-=20, 160, 19, NULL, 0.0, 0.0, 1, 0, "");
1025         
1026         uiDefBut(block, SEPR, 0, "",                                    0, yco-=6, 120, 6, NULL, 0.0, 0.0, 0, 0, "");
1027         
1028         uiDefBut(block, BUTM, B_CONSTRAINT_ADD_STRETCHTO,"Stretch To",          0, yco-=20, 160, 19, NULL, 0.0, 0.0, 1, 0, "");
1029
1030         if (ob->flag & OB_POSEMODE) {
1031                 uiDefBut(block, SEPR, 0, "",                                    0, yco-=6, 120, 6, NULL, 0.0, 0.0, 0, 0, "");
1032                 
1033                 uiDefBut(block, BUTM, B_CONSTRAINT_ADD_KINEMATIC,"IK Solver",           0, yco-=20, 160, 19, NULL, 0.0, 0.0, 1, 0, "");
1034                 uiDefBut(block, BUTM, B_CONSTRAINT_ADD_ACTION,"Action",         0, yco-=20, 160, 19, NULL, 0.0, 0.0, 1, 0, "");
1035                 
1036         }
1037         uiDefBut(block, SEPR, 0, "",                                    0, yco-=6, 120, 6, NULL, 0.0, 0.0, 0, 0, "");
1038
1039         uiDefBut(block, BUTM, B_CONSTRAINT_ADD_NULL,"Null",             0, yco-=20, 160, 19, NULL, 0.0, 0.0, 1, 0, "");
1040         
1041         uiTextBoundsBlock(block, 50);
1042         uiBlockSetDirection(block, UI_DOWN);
1043                 
1044         return block;
1045 }
1046
1047 void do_constraintbuts(unsigned short event)
1048 {
1049         Object *ob= OBACT;
1050         
1051         switch(event) {
1052         case B_CONSTRAINT_TEST:
1053                 break;  // no handling
1054         case B_CONSTRAINT_INF:
1055                 /* influence; do not execute actions for 1 dag_flush */
1056                 if(ob->pose)
1057                         ob->pose->flag |= (POSE_LOCKED|POSE_DO_UNLOCK);
1058
1059         case B_CONSTRAINT_CHANGETARGET:
1060                 if(ob->pose) ob->pose->flag |= POSE_RECALC;     // checks & sorts pose channels
1061                 DAG_scene_sort(G.scene);
1062                 break;
1063                 
1064         case B_CONSTRAINT_ADD_NULL:
1065                 {
1066                         bConstraint *con;
1067                         
1068                         con = add_new_constraint(CONSTRAINT_TYPE_NULL);
1069                         add_constraint_to_active(ob, con);
1070
1071                         BIF_undo_push("Add constraint");
1072                 }
1073                 break;
1074         case B_CONSTRAINT_ADD_KINEMATIC:
1075                 {
1076                         bConstraint *con;
1077                         
1078                         con = add_new_constraint(CONSTRAINT_TYPE_KINEMATIC);
1079                         add_constraint_to_active(ob, con);
1080
1081                         BIF_undo_push("Add constraint");
1082                 }
1083                 break;
1084         case B_CONSTRAINT_ADD_TRACKTO:
1085                 {
1086                         bConstraint *con;
1087
1088                         con = add_new_constraint(CONSTRAINT_TYPE_TRACKTO);
1089                         add_constraint_to_active(ob, con);
1090
1091                         BIF_undo_push("Add constraint");
1092                 }
1093                 break;
1094         case B_CONSTRAINT_ADD_MINMAX:
1095                 {
1096                         bConstraint *con;
1097
1098                         con = add_new_constraint(CONSTRAINT_TYPE_MINMAX);
1099                         add_constraint_to_active(ob, con);
1100
1101                         BIF_undo_push("Add constraint");
1102                 }
1103                 break;
1104         case B_CONSTRAINT_ADD_ROTLIKE:
1105                 {
1106                         bConstraint *con;
1107
1108                         con = add_new_constraint(CONSTRAINT_TYPE_ROTLIKE);
1109                         add_constraint_to_active(ob, con);
1110
1111                         BIF_undo_push("Add constraint");
1112                 }
1113                 break;
1114         case B_CONSTRAINT_ADD_LOCLIKE:
1115                 {
1116                         bConstraint *con;
1117
1118                         con = add_new_constraint(CONSTRAINT_TYPE_LOCLIKE);
1119                         add_constraint_to_active(ob, con);
1120
1121                         BIF_undo_push("Add constraint");
1122                 }
1123                 break;
1124         case B_CONSTRAINT_ADD_SIZELIKE:
1125                 {
1126                         bConstraint *con;
1127  
1128                         con = add_new_constraint(CONSTRAINT_TYPE_SIZELIKE);
1129                         add_constraint_to_active(ob, con);
1130   
1131                         BIF_undo_push("Add constraint");
1132                 }
1133                 break;
1134         case B_CONSTRAINT_ADD_ACTION:
1135                 {
1136                         bConstraint *con;
1137
1138                         con = add_new_constraint(CONSTRAINT_TYPE_ACTION);
1139                         add_constraint_to_active(ob, con);
1140
1141                         BIF_undo_push("Add constraint");
1142                 }
1143                 break;
1144         case B_CONSTRAINT_ADD_LOCKTRACK:
1145                 {
1146                         bConstraint *con;
1147
1148                         con = add_new_constraint(CONSTRAINT_TYPE_LOCKTRACK);
1149                         add_constraint_to_active(ob, con);
1150
1151                         BIF_undo_push("Add constraint");
1152                 }
1153                 break;
1154         case B_CONSTRAINT_ADD_FOLLOWPATH:
1155                 {
1156                         bConstraint *con;
1157
1158                         con = add_new_constraint(CONSTRAINT_TYPE_FOLLOWPATH);
1159                         add_constraint_to_active(ob, con);
1160
1161                 }
1162                 break;
1163         case B_CONSTRAINT_ADD_STRETCHTO:
1164                 {
1165                         bConstraint *con;
1166                         con = add_new_constraint(CONSTRAINT_TYPE_STRETCHTO);
1167                         add_constraint_to_active(ob, con);
1168                                 
1169                         BIF_undo_push("Add constraint");
1170                 }
1171                 break;
1172
1173         default:
1174                 break;
1175         }
1176
1177         object_test_constraints(ob);
1178         
1179         if(ob->pose) update_pose_constraint_flags(ob->pose);
1180         
1181         if(ob->type==OB_ARMATURE) DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA);
1182         else DAG_object_flush_update(G.scene, ob, OB_RECALC_OB);
1183         
1184         allqueue (REDRAWVIEW3D, 0);
1185         allqueue (REDRAWBUTSOBJECT, 0);
1186 }
1187
1188 static void softbody_bake(Object *ob)
1189 {
1190         SoftBody *sb= ob->soft;
1191         ScrArea *sa;
1192         float frameleno= G.scene->r.framelen;
1193         int cfrao= CFRA;
1194         unsigned short event=0;
1195         short val;
1196         
1197         G.scene->r.framelen= 1.0;               // baking has to be in uncorrected time
1198         CFRA= sb->sfra;
1199         update_for_newframe_muted();    // put everything on this frame
1200         sbObjectToSoftbody(ob); // put softbody in restposition
1201         ob->softflag |= OB_SB_BAKEDO;
1202         
1203         curarea->win_swap= 0;           // clean swapbuffers
1204         
1205         for(; CFRA <= sb->efra; CFRA++) {
1206                 set_timecursor(CFRA);
1207                 
1208                 update_for_newframe_muted();
1209                 
1210                 for(sa= G.curscreen->areabase.first; sa; sa= sa->next) {
1211                         if(sa->spacetype == SPACE_VIEW3D) {
1212                                 scrarea_do_windraw(sa);
1213                         }
1214                 }
1215                 screen_swapbuffers();
1216                 
1217                 while(qtest()) {
1218                         
1219                         event= extern_qread(&val);
1220                         if(event==ESCKEY) break;
1221                 }
1222                 if(event==ESCKEY) break;
1223         }
1224         
1225         if(event==ESCKEY) sbObjectToSoftbody(ob);       // clears all
1226         
1227         /* restore */
1228         waitcursor(0);
1229         ob->softflag &= ~OB_SB_BAKEDO;
1230         CFRA= cfrao;
1231         G.scene->r.framelen= frameleno;
1232         update_for_newframe_muted();
1233         allqueue(REDRAWVIEW3D, 0);
1234         allqueue(REDRAWBUTSOBJECT, 0);
1235 }
1236
1237
1238 // NT store processed path & file prefix for fluidsim bake directory
1239 void fluidsimFilesel(char *selection)
1240 {
1241         Object *ob = OBACT;
1242         char srcDir[FILE_MAXDIR+FILE_MAXFILE], srcFile[FILE_MAXFILE];
1243         char prefix[FILE_MAXFILE];
1244         char *srch, *srchSub, *srchExt, *lastFound;
1245         int isElbeemSurf = 0;
1246
1247         // check cfg?
1248         // make prefix
1249         strcpy(srcDir, selection);
1250         BLI_splitdirstring(srcDir, srcFile);
1251         strcpy(prefix, srcFile);
1252         // check if this is a previously generated surface mesh file
1253         srch = strstr(prefix, "fluidsurface_");
1254         // TODO search from back...
1255         if(srch) {
1256                 srchSub = strstr(prefix,"_preview_");
1257                 if(!srchSub) srchSub = strstr(prefix,"_final_");
1258                 srchExt = strstr(prefix,".gz.bobj");
1259                 if(!srchExt) srchExt = strstr(prefix,".bobj");
1260                 if(srchSub && srchExt) {
1261                         *srch = '\0';
1262                         isElbeemSurf = 1;
1263                 }
1264         }
1265         if(!isElbeemSurf) {
1266                 // try to remove suffix
1267                 lastFound = NULL;
1268                 srch = strchr(prefix, '.'); // search last . from extension
1269                 while(srch) {
1270                         lastFound = srch;
1271                         if(srch) {
1272                                 srch++;
1273                                 srch = strchr(srch, '.');
1274                         }
1275                 }
1276                 if(lastFound) {
1277                         *lastFound = '\0';
1278                 } 
1279         }
1280
1281         if(ob->fluidsimSettings) {
1282                 //strcpy(ob->fluidsimSettings->surfdataPath, selection);
1283                 strcpy(ob->fluidsimSettings->surfdataPath, srcDir);
1284                 //not necessary? strcat(ob->fluidsimSettings->surfdataPath, "/");
1285                 strcat(ob->fluidsimSettings->surfdataPath, prefix);
1286
1287                 // redraw view & buttons...
1288                 allqueue(REDRAWBUTSOBJECT, 0);
1289                 allqueue(REDRAWVIEW3D, 0);
1290                 DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA);
1291         }
1292 }
1293
1294 void do_object_panels(unsigned short event)
1295 {
1296         Object *ob;
1297         Effect *eff;
1298         
1299         ob= OBACT;
1300
1301         switch(event) {
1302         case B_TRACKBUTS:
1303                 ob= OBACT;
1304                 DAG_object_flush_update(G.scene, ob, OB_RECALC_OB);
1305                 allqueue(REDRAWVIEW3D, 0);
1306                 break;
1307         case B_RECALCPATH:
1308                 DAG_object_flush_update(G.scene, OBACT, OB_RECALC_DATA);
1309                 allqueue(REDRAWVIEW3D, 0);
1310                 break;
1311         case B_PRINTSPEED:
1312                 ob= OBACT;
1313                 if(ob) {
1314                         float vec[3];
1315                         CFRA++;
1316                         do_ob_ipo(ob);
1317                         where_is_object(ob);
1318                         VECCOPY(vec, ob->obmat[3]);
1319                         CFRA--;
1320                         do_ob_ipo(ob);
1321                         where_is_object(ob);
1322                         VecSubf(vec, vec, ob->obmat[3]);
1323                         prspeed= Normalise(vec);
1324                         scrarea_queue_winredraw(curarea);
1325                 }
1326                 break;
1327         case B_PRINTLEN:
1328                 ob= OBACT;
1329                 if(ob && ob->type==OB_CURVE) {
1330                         Curve *cu=ob->data;
1331                         
1332                         if(cu->path) prlen= cu->path->totdist; else prlen= -1.0;
1333                         scrarea_queue_winredraw(curarea);
1334                 } 
1335                 break;
1336         case B_RELKEY:
1337                 allspace(REMAKEIPO, 0);
1338                 allqueue(REDRAWBUTSOBJECT, 0);
1339                 allqueue(REDRAWIPO, 0);
1340                 DAG_object_flush_update(G.scene, OBACT, OB_RECALC_DATA);
1341                 break;
1342         case B_CURVECHECK:
1343                 DAG_object_flush_update(G.scene, OBACT, OB_RECALC_DATA);
1344                 allqueue(REDRAWVIEW3D, 0);
1345                 break;
1346         
1347         case B_SOFTBODY_CHANGE:
1348                 ob= OBACT;
1349                 if(ob) {
1350                         ob->softflag |= OB_SB_REDO;
1351                         allqueue(REDRAWBUTSOBJECT, 0);
1352                         allqueue(REDRAWVIEW3D, 0);
1353                 }
1354                 break;
1355         case B_SOFTBODY_DEL_VG:
1356                 ob= OBACT;
1357                 if(ob && ob->soft) {
1358                         ob->soft->vertgroup= 0;
1359                         ob->softflag |= OB_SB_REDO;
1360                         allqueue(REDRAWBUTSOBJECT, 0);
1361                         allqueue(REDRAWVIEW3D, 0);
1362                 }
1363                 break;
1364         case B_SOFTBODY_BAKE:
1365                 ob= OBACT;
1366                 if(ob && ob->soft) softbody_bake(ob);
1367                 break;
1368         case B_SOFTBODY_BAKE_FREE:
1369                 ob= OBACT;
1370                 if(ob && ob->soft) sbObjectToSoftbody(ob);
1371                 allqueue(REDRAWBUTSOBJECT, 0);
1372                 allqueue(REDRAWVIEW3D, 0);
1373                 break;
1374
1375         case B_FLUIDSIM_BAKE:
1376                 ob= OBACT;
1377                 /* write config files (currently no simulation) */
1378                 fluidsimBake(ob);
1379                 break;
1380         case B_FLUIDSIM_MAKEPART:
1381                 ob= OBACT;
1382                 {
1383                         PartEff *paf= NULL;
1384                         /* prepare fluidsim particle display */
1385                         // simplified delete effect, create new - recalc some particles...
1386                         if(ob==NULL || ob->type!=OB_MESH) break;
1387                         ob->fluidsimSettings->type = 0;
1388                         // reset type, and init particle system once normally
1389                         eff= ob->effect.first;
1390                         //if((eff) && (eff->flag & SELECT)) { BLI_remlink(&ob->effect, eff); free_effect(eff); }
1391                         if(!eff){ copy_act_effect(ob); DAG_scene_sort(G.scene); }
1392                         paf = give_parteff(ob);
1393                         paf->totpart = 1000; paf->sta = paf->end = 1.0; // generate some particles...
1394                         build_particle_system(ob);
1395                         
1396                         ob->fluidsimSettings->type = OB_FLUIDSIM_PARTICLE;
1397                 }
1398                 allqueue(REDRAWVIEW3D, 0);
1399                 allqueue(REDRAWBUTSOBJECT, 0);
1400                 break;
1401         case B_FLUIDSIM_SELDIR: {
1402                         ScrArea *sa = closest_bigger_area();
1403                         ob= OBACT;
1404                         /* choose dir for surface files */
1405                         areawinset(sa->win);
1406                         activate_fileselect(FILE_SPECIAL, "Select Directory", ob->fluidsimSettings->surfdataPath, fluidsimFilesel);
1407                 }
1408                 break;
1409         case B_FLUIDSIM_FORCEREDRAW:
1410                 /* force redraw */
1411                 allqueue(REDRAWBUTSOBJECT, 0);
1412                 allqueue(REDRAWVIEW3D, 0);
1413                 DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA);
1414                 break;
1415         case B_GROUP_RELINK:
1416                 group_relink_nla_objects(OBACT);
1417                 allqueue(REDRAWVIEW3D, 0);
1418                 break;
1419                 
1420         default:
1421                 if(event>=B_SELEFFECT && event<B_SELEFFECT+MAX_EFFECT) {
1422                         ob= OBACT;
1423                         if(ob) {
1424                                 int a=B_SELEFFECT;
1425                                 
1426                                 eff= ob->effect.first;
1427                                 while(eff) {
1428                                         if(event==a) eff->flag |= SELECT;
1429                                         else eff->flag &= ~SELECT;
1430                                         
1431                                         a++;
1432                                         eff= eff->next;
1433                                 }
1434                                 allqueue(REDRAWBUTSOBJECT, 0);
1435                         }
1436                 }
1437         }
1438
1439 }
1440
1441 static void do_add_groupmenu(void *arg, int event)
1442 {
1443         Object *ob= OBACT;
1444         
1445         if(ob) {
1446                 
1447                 if(event== -1) {
1448                         Group *group= add_group();
1449                         add_to_group(group, ob);
1450                 }
1451                 else
1452                         add_to_group(BLI_findlink(&G.main->group, event), ob);
1453                         
1454                 ob->flag |= OB_FROMGROUP;
1455                 BASACT->flag |= OB_FROMGROUP;
1456                 allqueue(REDRAWBUTSOBJECT, 0);
1457                 allqueue(REDRAWVIEW3D, 0);
1458         }               
1459 }
1460
1461 static uiBlock *add_groupmenu(void *arg_unused)
1462 {
1463         uiBlock *block;
1464         Group *group;
1465         short yco= 0;
1466         char str[32];
1467         
1468         block= uiNewBlock(&curarea->uiblocks, "add_constraintmenu", UI_EMBOSSP, UI_HELV, curarea->win);
1469         uiBlockSetButmFunc(block, do_add_groupmenu, NULL);
1470
1471         uiDefBut(block, BUTM, B_NOP, "ADD NEW",         0, 20, 160, 19, NULL, 0.0, 0.0, 1, -1, "");
1472         for(group= G.main->group.first; group; group= group->id.next, yco++) {
1473                 if(group->id.lib) strcpy(str, "L  ");
1474                 else strcpy(str, "   ");
1475                 strcat(str, group->id.name+2);
1476                 uiDefBut(block, BUTM, B_NOP, str,       0, -20*yco, 160, 19, NULL, 0.0, 0.0, 1, yco, "");
1477         }
1478         
1479         uiTextBoundsBlock(block, 50);
1480         uiBlockSetDirection(block, UI_DOWN);    
1481         
1482         return block;
1483 }
1484
1485 static void group_ob_rem(void *gr_v, void *ob_v)
1486 {
1487         Object *ob= OBACT;
1488         
1489         rem_from_group(gr_v, ob);
1490         if(find_group(ob)==NULL) {
1491                 ob->flag &= ~OB_FROMGROUP;
1492                 BASACT->flag &= ~OB_FROMGROUP;
1493         }
1494         allqueue(REDRAWBUTSOBJECT, 0);
1495         allqueue(REDRAWVIEW3D, 0);
1496
1497 }
1498
1499 static void group_local(void *gr_v, void *unused)
1500 {
1501         Group *group= gr_v;
1502         
1503         group->id.lib= NULL;
1504         
1505         allqueue(REDRAWBUTSOBJECT, 0);
1506         allqueue(REDRAWVIEW3D, 0);
1507         
1508 }
1509
1510 static void object_panel_object(Object *ob)
1511 {
1512         uiBlock *block;
1513         uiBut *but;
1514         Group *group;
1515         int a=0, xco;
1516         
1517         block= uiNewBlock(&curarea->uiblocks, "object_panel_object", UI_EMBOSS, UI_HELV, curarea->win);
1518         if(uiNewPanel(curarea, block, "Object and Links", "Object", 0, 0, 318, 204)==0) return;
1519         
1520         if(ob->id.lib) uiSetButLock(1, "Can't edit library data");
1521         
1522         /* object name */
1523         uiBlockSetCol(block, TH_BUT_SETTING2);
1524         xco= std_libbuttons(block, 10, 180, 0, NULL, 0, ID_OB, 0, &ob->id, NULL, &(G.buts->menunr), B_OBALONE, B_OBLOCAL, 0, 0, B_KEEPDATA);
1525         uiBlockSetCol(block, TH_AUTO);
1526         
1527         /* parent */
1528         uiDefIDPoinBut(block, test_obpoin_but, ID_OB, B_OBJECTPANELPARENT, "Par:", xco+5, 180, 305-xco, 20, &ob->parent, "Parent Object"); 
1529
1530         uiDefBlockBut(block, add_groupmenu, NULL, "Add to Group", 10,150,150,20, "Add Object to a new Group");
1531
1532         /* all groups */
1533         uiBlockBeginAlign(block);
1534         for(group= G.main->group.first; group; group= group->id.next) {
1535                 if(object_in_group(ob, group)) {
1536                         xco= 160;
1537                         
1538                         but = uiDefBut(block, TEX, B_IDNAME, "GR:",     10, 120-a, 150, 20, group->id.name+2, 0.0, 19.0, 0, 0, "Displays Group name. Click to change.");
1539                         uiButSetFunc(but, test_idbutton_cb, group->id.name, NULL);
1540                         
1541                         if(group->id.lib) {
1542                                 but= uiDefIconBut(block, BUT, B_NOP, ICON_PARLIB, 160, 120-a, 20, 20, NULL, 0.0, 0.0, 0.0, 0.0, "Make Group local");
1543                                 uiButSetFunc(but, group_local, group, NULL);
1544                                 xco= 180;
1545                         }
1546                         but = uiDefIconBut(block, BUT, B_NOP, VICON_X, xco, 120-a, 20, 20, NULL, 0.0, 0.0, 0.0, 0.0, "Remove Group membership");
1547                         uiButSetFunc(but, group_ob_rem, group, ob);
1548                         
1549                         a+= 20;
1550                 }
1551         }
1552 }
1553
1554 static void object_panel_anim(Object *ob)
1555 {
1556         uiBlock *block;
1557         char str[32];
1558         
1559         block= uiNewBlock(&curarea->uiblocks, "object_panel_anim", UI_EMBOSS, UI_HELV, curarea->win);
1560         if(uiNewPanel(curarea, block, "Anim settings", "Object", 320, 0, 318, 204)==0) return;
1561         
1562         if(ob->id.lib) uiSetButLock(1, "Can't edit library data");
1563         
1564         uiBlockBeginAlign(block);
1565         uiDefButS(block, ROW,B_TRACKBUTS,"TrackX",      24,180,59,19, &ob->trackflag, 12.0, 0.0, 0, 0, "Specify the axis that points to another object");
1566         uiDefButS(block, ROW,B_TRACKBUTS,"Y",           85,180,19,19, &ob->trackflag, 12.0, 1.0, 0, 0, "Specify the axis that points to another object");
1567         uiDefButS(block, ROW,B_TRACKBUTS,"Z",           104,180,19,19, &ob->trackflag, 12.0, 2.0, 0, 0, "Specify the axis that points to another object");
1568         uiDefButS(block, ROW,B_TRACKBUTS,"-X",          124,180,24,19, &ob->trackflag, 12.0, 3.0, 0, 0, "Specify the axis that points to another object");
1569         uiDefButS(block, ROW,B_TRACKBUTS,"-Y",          150,180,24,19, &ob->trackflag, 12.0, 4.0, 0, 0, "Specify the axis that points to another object");
1570         uiDefButS(block, ROW,B_TRACKBUTS,"-Z",          178,180,24,19, &ob->trackflag, 12.0, 5.0, 0, 0, "Specify the axis that points to another object");
1571         uiBlockBeginAlign(block);
1572         uiDefButS(block, ROW,REDRAWVIEW3D,"UpX",        226,180,45,19, &ob->upflag, 13.0, 0.0, 0, 0, "Specify the axis that points up");
1573         uiDefButS(block, ROW,REDRAWVIEW3D,"Y",          274,180,20,19, &ob->upflag, 13.0, 1.0, 0, 0, "Specify the axis that points up");
1574         uiDefButS(block, ROW,REDRAWVIEW3D,"Z",          298,180,19,19, &ob->upflag, 13.0, 2.0, 0, 0, "Specify the axis that points up");
1575         
1576         uiBlockBeginAlign(block);
1577         uiDefButBitS(block, TOG, OB_DRAWKEY, REDRAWVIEW3D, "Draw Key",          24,155,71,19, &ob->ipoflag, 0, 0, 0, 0, "Draw object as key position");
1578         uiDefButBitS(block, TOG, OB_DRAWKEYSEL, REDRAWVIEW3D, "Draw Key Sel",   97,155,81,19, &ob->ipoflag, 0, 0, 0, 0, "Limit the drawing of object keys");
1579         uiDefButBitS(block, TOG, OB_POWERTRACK, REDRAWVIEW3D, "Powertrack",             180,155,78,19, &ob->transflag, 0, 0, 0, 0, "Switch objects rotation off");
1580         uiDefButBitS(block, TOG, PARSLOW, 0, "SlowPar",                                 260,155,56,19, &ob->partype, 0, 0, 0, 0, "Create a delay in the parent relationship");
1581         uiBlockBeginAlign(block);
1582         
1583         uiDefButBitS(block, TOG, OB_DUPLIFRAMES, REDRAWVIEW3D, "DupliFrames",   24,130,89,20, &ob->transflag, 0, 0, 0, 0, "Make copy of object for every frame");
1584         uiDefButBitS(block, TOG, OB_DUPLIVERTS, REDRAWVIEW3D, "DupliVerts",             114,130,82,20, &ob->transflag, 0, 0, 0, 0, "Duplicate child objects on all vertices");
1585         uiDefButBitS(block, TOG, OB_DUPLIROT, REDRAWVIEW3D, "Rot",                              200,130,31,20, &ob->transflag, 0, 0, 0, 0, "Rotate dupli according to facenormal");
1586         uiDefButBitS(block, TOG, OB_DUPLINOSPEED, REDRAWVIEW3D, "No Speed",             234,130,82,20, &ob->transflag, 0, 0, 0, 0, "Set dupliframes to still, regardless of frame");
1587         
1588         uiDefButBitS(block, TOG, OB_DUPLIGROUP, REDRAWVIEW3D, "DupliGroup",             24,110,150,20, &ob->transflag, 0, 0, 0, 0, "Make copy of object for every frame");
1589         uiDefIDPoinBut(block, test_grouppoin_but, ID_GR, B_GROUP_RELINK, "GR:", 174,110,142,20, &ob->dup_group, "Duplicate this entire Group"); 
1590
1591         uiBlockBeginAlign(block);
1592         uiDefButS(block, NUM, REDRAWVIEW3D, "DupSta:",          24,85,141,19, &ob->dupsta, 1.0, (MAXFRAMEF - 1.0f), 0, 0, "Specify startframe for Dupliframes");
1593         uiDefButS(block, NUM, REDRAWVIEW3D, "DupOn:",           170,85,146,19, &ob->dupon, 1.0, 1500.0, 0, 0, "");
1594         uiDefButS(block, NUM, REDRAWVIEW3D, "DupEnd",           24,65,140,19, &ob->dupend, 1.0, MAXFRAMEF, 0, 0, "Specify endframe for Dupliframes");
1595         uiDefButS(block, NUM, REDRAWVIEW3D, "DupOff",           171,65,145,19, &ob->dupoff, 0.0, 1500.0, 0, 0, "");
1596         uiBlockBeginAlign(block);
1597         uiDefButBitS(block, TOG, OB_OFFS_OB, REDRAWALL, "Offs Ob",                      24,35,56,20, &ob->ipoflag, 0, 0, 0, 0, "Let the timeoffset work on its own objectipo");
1598         uiDefButBitS(block, TOG, OB_OFFS_PARENT, REDRAWALL, "Offs Par",                 82,35,56,20 , &ob->ipoflag, 0, 0, 0, 0, "Let the timeoffset work on the parent");
1599         uiDefButBitS(block, TOG, OB_OFFS_PARTICLE, REDRAWALL, "Offs Particle",          140,35,103,20, &ob->ipoflag, 0, 0, 0, 0, "Let the timeoffset work on the particle effect");
1600         
1601         uiBlockBeginAlign(block);
1602         uiDefButF(block, NUM, REDRAWALL, "TimeOffset:",                 24,10,115,20, &ob->sf, -MAXFRAMEF, MAXFRAMEF, 100, 0, "Specify an offset in frames");
1603         uiDefBut(block, BUT, B_AUTOTIMEOFS, "Automatic Time",   139,10,104,20, 0, 0, 0, 0, 0, "Generate automatic timeoffset values for all selected frames");
1604         uiDefBut(block, BUT, B_PRINTSPEED,      "PrSpeed",                      248,10,67,20, 0, 0, 0, 0, 0, "Print objectspeed");
1605         uiBlockEndAlign(block);
1606         
1607         sprintf(str, "%.4f", prspeed);
1608         uiDefBut(block, LABEL, 0, str,                                                  247,35,63,31, NULL, 1.0, 0, 0, 0, "");
1609         
1610 }
1611
1612 static void object_panel_draw(Object *ob)
1613 {
1614         uiBlock *block;
1615         int xco, a, dx, dy;
1616         
1617         block= uiNewBlock(&curarea->uiblocks, "object_panel_draw", UI_EMBOSS, UI_HELV, curarea->win);
1618         if(uiNewPanel(curarea, block, "Draw", "Object", 640, 0, 318, 204)==0) return;
1619         
1620         if(ob->id.lib) uiSetButLock(1, "Can't edit library data");
1621         
1622         /* LAYERS */
1623         xco= 120;
1624         dx= 35;
1625         dy= 30;
1626         
1627         uiDefBut(block, LABEL, 0, "Layers",                             10,170,100,20, NULL, 0, 0, 0, 0, "");
1628         
1629         uiBlockBeginAlign(block);
1630         for(a=0; a<5; a++)
1631                 uiDefButBitI(block, TOG, 1<<a, B_OBLAY+a, "",   (short)(xco+a*(dx/2)), 180, (short)(dx/2), (short)(dy/2), &(BASACT->lay), 0, 0, 0, 0, "");
1632         for(a=0; a<5; a++)
1633                 uiDefButBitI(block, TOG, 1<<(a+10), B_OBLAY+a+10, "",   (short)(xco+a*(dx/2)), 165, (short)(dx/2), (short)(dy/2), &(BASACT->lay), 0, 0, 0, 0, "");
1634         
1635         xco+= 7;
1636         uiBlockBeginAlign(block);
1637         for(a=5; a<10; a++)
1638                 uiDefButBitI(block, TOG, 1<<a, B_OBLAY+a, "",   (short)(xco+a*(dx/2)), 180, (short)(dx/2), (short)(dy/2), &(BASACT->lay), 0, 0, 0, 0, "");
1639         for(a=5; a<10; a++)
1640                 uiDefButBitI(block, TOG, 1<<(a+10), B_OBLAY+a+10, "",   (short)(xco+a*(dx/2)), 165, (short)(dx/2), (short)(dy/2), &(BASACT->lay), 0, 0, 0, 0, "");
1641         
1642         uiBlockEndAlign(block);
1643         
1644         uiDefBut(block, LABEL, 0, "Drawtype",                                           10,120,100,20, NULL, 0, 0, 0, 0, "");
1645         
1646         uiBlockBeginAlign(block);
1647         uiDefButC(block, ROW, REDRAWVIEW3D, "Shaded",   10,100,100, 20, &ob->dt, 0, OB_SHADED, 0, 0, "Draw active object shaded or textured");
1648         uiDefButC(block, ROW, REDRAWVIEW3D, "Solid",    10,80,100, 20, &ob->dt, 0, OB_SOLID, 0, 0, "Draw active object in solid");
1649         uiDefButC(block, ROW, REDRAWVIEW3D, "Wire",             10,60, 100, 20, &ob->dt, 0, OB_WIRE, 0, 0, "Draw active object in wireframe");
1650         uiDefButC(block, ROW, REDRAWVIEW3D, "Bounds",   10,40, 100, 20, &ob->dt, 0, OB_BOUNDBOX, 0, 0, "Only draw object with bounding box");
1651         uiBlockEndAlign(block);
1652         
1653         uiDefBut(block, LABEL, 0, "Draw Extra",                                                 120,120,90,20, NULL, 0, 0, 0, 0, "");
1654         
1655         uiBlockBeginAlign(block);
1656         uiDefButBitC(block, TOG, OB_BOUNDBOX, REDRAWVIEW3D, "Bounds",                           120, 100, 90, 20, &ob->dtx, 0, 0, 0, 0, "Displays the active object's bounds");
1657         uiDefButBitC(block, TOG, OB_DRAWNAME, REDRAWVIEW3D, "Name",             210, 100, 90, 20, &ob->dtx, 0, 0, 0, 0, "Displays the active object's name");
1658         
1659         uiDefButS(block, MENU, REDRAWVIEW3D, "Boundary Display%t|Box%x0|Sphere%x1|Cylinder%x2|Cone%x3|Polyheder%x4",
1660                           120, 80, 90, 20, &ob->boundtype, 0, 0, 0, 0, "Selects the boundary display type");
1661         uiDefButBitC(block, TOG, OB_AXIS, REDRAWVIEW3D, "Axis",                 210, 80, 90, 20, &ob->dtx, 0, 0, 0, 0, "Displays the active object's centre and axis");
1662         
1663         uiDefButBitC(block, TOG, OB_TEXSPACE, REDRAWVIEW3D, "TexSpace", 120, 60, 90, 20, &ob->dtx, 0, 0, 0, 0, "Displays the active object's texture space");
1664         uiDefButBitC(block, TOG, OB_DRAWWIRE, REDRAWVIEW3D, "Wire",             210, 60, 90, 20, &ob->dtx, 0, 0, 0, 0, "Adds the active object's wireframe over solid drawing");
1665         
1666         uiDefButBitC(block, TOG, OB_DRAWTRANSP, REDRAWVIEW3D, "Transp", 120, 40, 90, 20, &ob->dtx, 0, 0, 0, 0, "Enables transparent materials for the active object (Mesh only)");
1667         uiDefButBitC(block, TOG, OB_DRAWXRAY, REDRAWVIEW3D, "X-ray",    210, 40, 90, 20, &ob->dtx, 0, 0, 0, 0, "Makes the active object draw in front of others");
1668         
1669 }
1670
1671 void object_panel_constraint(char *context)
1672 {
1673         uiBlock *block;
1674         Object *ob= OBACT;
1675         ListBase *conlist;
1676         bConstraint *curcon;
1677         short xco, yco;
1678         char str[64];
1679         
1680         block= uiNewBlock(&curarea->uiblocks, "object_panel_constraint", UI_EMBOSS, UI_HELV, curarea->win);
1681         if(uiNewPanel(curarea, block, "Constraints", context, 960, 0, 318, 204)==0) return;
1682         
1683         if(ob->id.lib) uiSetButLock(1, "Can't edit library data");
1684         
1685         /* this is a variable height panel, newpanel doesnt force new size on existing panels */
1686         /* so first we make it default height */
1687         uiNewPanelHeight(block, 204);
1688         
1689         if(G.obedit==OBACT) return;     // ??
1690         
1691         conlist = get_active_constraints(OBACT);
1692         
1693         if (conlist) {
1694                 
1695                 uiDefBlockBut(block, add_constraintmenu, NULL, "Add Constraint", 0, 190, 130, 20, "Add a new constraint");
1696                 
1697                 /* print active object or bone */
1698                 str[0]= 0;
1699                 if (ob->flag & OB_POSEMODE){
1700                         bPoseChannel *pchan= get_active_posechannel(ob);
1701                         if(pchan) sprintf(str, "To Bone: %s", pchan->name);
1702                 }
1703                 else {
1704                         sprintf(str, "To Object: %s", ob->id.name+2);
1705                 }
1706                 uiDefBut(block, LABEL, 1, str,  150, 190, 150, 20, NULL, 0.0, 0.0, 0, 0, "Displays Active Object or Bone name");
1707                 
1708                 /* Go through the list of constraints and draw them */
1709                 xco = 10;
1710                 yco = 160;
1711                 
1712                 for (curcon = conlist->first; curcon; curcon=curcon->next) {
1713                         /* hrms, the temporal constraint should not draw! */
1714                         if(curcon->type==CONSTRAINT_TYPE_KINEMATIC) {
1715                                 bKinematicConstraint *data= curcon->data;
1716                                 if(data->flag & CONSTRAINT_IK_TEMP)
1717                                         continue;
1718                         }
1719                         /* Draw default constraint header */
1720                         draw_constraint(block, conlist, curcon, &xco, &yco);    
1721                 }
1722                 
1723                 if(yco < 0) uiNewPanelHeight(block, 204-yco);
1724                 
1725         }
1726 }
1727
1728 void do_effects_panels(unsigned short event)
1729 {
1730         Object *ob;
1731         Base *base;
1732         Effect *eff, *effn;
1733         PartEff *paf;
1734         
1735         ob= OBACT;
1736
1737         switch(event) {
1738
1739     case B_AUTOTIMEOFS:
1740                 auto_timeoffs();
1741                 break;
1742         case B_FRAMEMAP:
1743                 G.scene->r.framelen= G.scene->r.framapto;
1744                 G.scene->r.framelen/= G.scene->r.images;
1745                 allqueue(REDRAWALL, 0);
1746                 break;
1747         case B_NEWEFFECT:
1748                 if(ob) {
1749                         if (BLI_countlist(&ob->effect)==MAX_EFFECT)
1750                                 error("Unable to add: effect limit reached");
1751                         else
1752                                 copy_act_effect(ob);
1753                 }
1754                 DAG_scene_sort(G.scene);
1755                 BIF_undo_push("New effect");
1756                 allqueue(REDRAWBUTSOBJECT, 0);
1757                 break;
1758         case B_DELEFFECT:
1759                 if(ob==NULL || ob->type!=OB_MESH) break;
1760                 eff= ob->effect.first;
1761                 while(eff) {
1762                         effn= eff->next;
1763                         if(eff->flag & SELECT) {
1764                                 BLI_remlink(&ob->effect, eff);
1765                                 free_effect(eff);
1766                                 break;
1767                         }
1768                         eff= effn;
1769                 }
1770                 BIF_undo_push("Delete effect");
1771                 allqueue(REDRAWVIEW3D, 0);
1772                 allqueue(REDRAWBUTSOBJECT, 0);
1773                 break;
1774         case B_NEXTEFFECT:
1775                 if(ob==0 || ob->type!=OB_MESH) break;
1776                 eff= ob->effect.first;
1777                 while(eff) {
1778                         if(eff->flag & SELECT) {
1779                                 if(eff->next) {
1780                                         eff->flag &= ~SELECT;
1781                                         eff->next->flag |= SELECT;
1782                                 }
1783                                 break;
1784                         }
1785                         eff= eff->next;
1786                 }
1787                 allqueue(REDRAWBUTSOBJECT, 0);
1788                 break;
1789         case B_PREVEFFECT:
1790                 if(ob==0 || ob->type!=OB_MESH) break;
1791                 eff= ob->effect.first;
1792                 while(eff) {
1793                         if(eff->flag & SELECT) {
1794                                 if(eff->prev) {
1795                                         eff->flag &= ~SELECT;
1796                                         eff->prev->flag |= SELECT;
1797                                 }
1798                                 break;
1799                         }
1800                         eff= eff->next;
1801                 }
1802                 allqueue(REDRAWBUTSOBJECT, 0);
1803                 break;
1804         case B_EFFECT_DEP:
1805                 DAG_scene_sort(G.scene);
1806                 /* no break, pass on */
1807         case B_CALCEFFECT:
1808                 if(ob==NULL || ob->type!=OB_MESH) break;
1809                 eff= ob->effect.first;
1810                 while(eff) {
1811                         if(eff->flag & SELECT) {
1812                                 if(eff->type==EFF_PARTICLE) build_particle_system(ob);
1813                         }
1814                         eff= eff->next;
1815                 }
1816                 allqueue(REDRAWVIEW3D, 0);
1817                 allqueue(REDRAWBUTSOBJECT, 0);
1818                 break;
1819         case B_PAF_SET_VG:
1820                 
1821                 paf= give_parteff(ob);
1822                 if(paf) {
1823                         bDeformGroup *dg= get_named_vertexgroup(ob, paf->vgroupname);
1824                         if(dg)
1825                                 paf->vertgroup= get_defgroup_num(ob, dg)+1;
1826                         else
1827                                 paf->vertgroup= 0;
1828                         
1829                         DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA);
1830                         allqueue(REDRAWVIEW3D, 0);
1831                 }
1832                 break;
1833         case B_PAF_SET_VG1:
1834                 
1835                 paf= give_parteff(ob);
1836                 if(paf) {
1837                         bDeformGroup *dg= get_named_vertexgroup(ob, paf->vgroupname_v);
1838                         if(dg)
1839                                 paf->vertgroup_v= get_defgroup_num(ob, dg)+1;
1840                         else
1841                                 paf->vertgroup_v= 0;
1842                         
1843                         DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA);
1844                         allqueue(REDRAWVIEW3D, 0);
1845                 }
1846                 break;
1847         case B_FIELD_DEP:
1848                 DAG_scene_sort(G.scene);
1849                 DAG_object_flush_update(G.scene, ob, OB_RECALC_OB);
1850                 if(ob->type==OB_CURVE && ob->pd->forcefield==PFIELD_GUIDE) {
1851                         Curve *cu= ob->data;
1852                         
1853                         cu->flag |= (CU_PATH|CU_3D);
1854                         do_curvebuts(B_CU3D);   /* all curves too */
1855                         
1856                         DAG_object_flush_update(G.scene, OBACT, OB_RECALC_DATA);
1857                 }
1858                 allqueue(REDRAWVIEW3D, 0);
1859                 allqueue(REDRAWBUTSOBJECT, 0);
1860                 break;
1861         case B_FIELD_CHANGE:
1862                 DAG_object_flush_update(G.scene, ob, OB_RECALC_OB);
1863                 allqueue(REDRAWVIEW3D, 0);
1864                 break;
1865         case B_RECALCAL:
1866                 base= FIRSTBASE;
1867                 while(base) {
1868                         if(base->lay & G.vd->lay) {
1869                                 ob= base->object;
1870                                 eff= ob->effect.first;
1871                                 while(eff) {
1872                                         if(eff->flag & SELECT) {
1873                                                 if(eff->type==EFF_PARTICLE) build_particle_system(ob);
1874                                         }
1875                                         eff= eff->next;
1876                                 }
1877                         }
1878                         base= base->next;
1879                 }
1880                 allqueue(REDRAWVIEW3D, 0);
1881                 break;
1882         default:
1883                 if(event>=B_SELEFFECT && event<B_SELEFFECT+MAX_EFFECT) {
1884                         ob= OBACT;
1885                         if(ob) {
1886                                 int a=B_SELEFFECT;
1887                                 
1888                                 eff= ob->effect.first;
1889                                 while(eff) {
1890                                         if(event==a) eff->flag |= SELECT;
1891                                         else eff->flag &= ~SELECT;
1892                                         
1893                                         a++;
1894                                         eff= eff->next;
1895                                 }
1896                                 allqueue(REDRAWBUTSOBJECT, 0);
1897                         }
1898                 }
1899         }
1900
1901 }
1902
1903 /* Panel for particle interaction settings */
1904 static void object_panel_fields(Object *ob)
1905 {
1906         uiBlock *block;
1907
1908         block= uiNewBlock(&curarea->uiblocks, "object_panel_fields", UI_EMBOSS, UI_HELV, curarea->win);
1909         if(uiNewPanel(curarea, block, "Fields and Deflection", "Physics", 0, 0, 318, 204)==0) return;
1910
1911         if(ob->id.lib) uiSetButLock(1, "Can't edit library data");
1912         
1913         /* should become button, option? */
1914         if(ob->pd==NULL) {
1915                 ob->pd= MEM_callocN(sizeof(PartDeflect), "PartDeflect");
1916                 /* and if needed, init here */
1917                 ob->pd->pdef_sbdamp = 0.1f;
1918                 ob->pd->pdef_sbift  = 0.2f;
1919                 ob->pd->pdef_sboft  = 0.02f;
1920         }
1921         
1922         if(ob->pd) {
1923                 PartDeflect *pd= ob->pd;
1924                 char *menustr= MEM_mallocN(256, "temp string");
1925                 char *tipstr="Choose field type";
1926                 
1927                 uiDefBut(block, LABEL, 0, "Fields",             10,180,140,20, NULL, 0.0, 0, 0, 0, "");
1928                 
1929                 /* setup menu button */
1930                 sprintf(menustr, "Field Type%%t|None %%x0|Spherical %%x%d|Wind %%x%d|Vortex %%x%d|Curve Guide %%x%d", 
1931                                 PFIELD_FORCE, PFIELD_WIND, PFIELD_VORTEX, PFIELD_GUIDE);
1932                 
1933                 if(pd->forcefield==PFIELD_FORCE) tipstr= "Object center attracts or repels particles";
1934                 else if(pd->forcefield==PFIELD_WIND) tipstr= "Constant force applied in direction of Object Z axis";
1935                 else if(pd->forcefield==PFIELD_VORTEX) tipstr= "Particles swirl around Z-axis of the Object";
1936                 else if(pd->forcefield==PFIELD_GUIDE) tipstr= "Use a Curve Path to guide particles";
1937                 
1938                 uiDefButS(block, MENU, B_FIELD_DEP, menustr,                    10,160,140,20, &pd->forcefield, 0.0, 0.0, 0, 0, tipstr);
1939                 MEM_freeN(menustr);
1940                 
1941                 if(pd->forcefield) {
1942                         uiBlockBeginAlign(block);
1943                         if(pd->forcefield == PFIELD_GUIDE) {
1944                                 uiDefButF(block, NUM, B_FIELD_CHANGE, "MinDist: ",      10,120,140,20, &pd->f_strength, 0.0, 1000.0, 10, 0, "The distance from which particles are affected fully.");
1945                                 uiDefButF(block, NUM, B_FIELD_CHANGE, "Fall-off: ",     10,100,140,20, &pd->f_power, 0.0, 10.0, 10, 0, "Falloff factor, between mindist and maxdist");
1946                         }
1947                         else {  
1948                                 uiDefButF(block, NUM, B_FIELD_CHANGE, "Strength: ",     10,110,140,20, &pd->f_strength, -1000, 1000, 10, 0, "Strength of force field");
1949                                 uiDefButF(block, NUM, B_FIELD_CHANGE, "Fall-off: ",     10,90,140,20, &pd->f_power, 0, 10, 10, 0, "Falloff power (real gravitational fallof = 2)");
1950                         }
1951                         
1952                         uiBlockBeginAlign(block);
1953                         uiDefButBitS(block, TOG, PFIELD_USEMAX, B_FIELD_CHANGE, "Use MaxDist",  10,60,140,20, &pd->flag, 0.0, 0, 0, 0, "Use a maximum distance for the field to work");
1954                         uiDefButF(block, NUM, B_FIELD_CHANGE, "MaxDist: ",      10,40,140,20, &pd->maxdist, 0, 1000.0, 10, 0, "Maximum distance for the field to work");
1955                         uiBlockEndAlign(block);
1956                         
1957                         if(pd->forcefield == PFIELD_GUIDE)
1958                                 uiDefButBitS(block, TOG, PFIELD_GUIDE_PATH_ADD, B_FIELD_CHANGE, "Additive",     10,10,140,20, &pd->flag, 0.0, 0, 0, 0, "Based on distance/falloff it adds a portion of the entire path");
1959                         
1960                 }
1961                 
1962                 uiDefBut(block, LABEL, 0, "Deflection", 160,180,140,20, NULL, 0.0, 0, 0, 0, "");
1963                         
1964                 /* only meshes collide now */
1965                 if(ob->type==OB_MESH) {
1966                         uiDefButBitS(block, TOG, 1, B_REDR, "Deflection",160,160,150,20, &pd->deflect, 0, 0, 0, 0, "Deflects particles based on collision");
1967                         if(pd->deflect) {
1968                                 uiDefBut(block, LABEL, 0, "Particles",                  160,140,150,20, NULL, 0.0, 0, 0, 0, "");
1969                                 
1970                                 uiBlockBeginAlign(block);
1971                                 uiDefButF(block, NUM, B_DIFF, "Damping: ",              160,120,150,20, &pd->pdef_damp, 0.0, 1.0, 10, 0, "Amount of damping during particle collision");
1972                                 uiDefButF(block, NUM, B_DIFF, "Rnd Damping: ",  160,100,150,20, &pd->pdef_rdamp, 0.0, 1.0, 10, 0, "Random variation of damping");
1973                                 uiDefButF(block, NUM, B_DIFF, "Permeability: ", 160,80,150,20, &pd->pdef_perm, 0.0, 1.0, 10, 0, "Chance that the particle will pass through the mesh");
1974                                 uiBlockEndAlign(block);
1975                                 
1976                                 uiDefBut(block, LABEL, 0, "Soft Body",                  160,60,150,20, NULL, 0.0, 0, 0, 0, "");
1977
1978                                 uiBlockBeginAlign(block);
1979                                 uiDefButF(block, NUM, B_DIFF, "Damping:",       160,40,150,20, &pd->pdef_sbdamp, 0.0, 1.0, 10, 0, "Amount of damping during soft body collision");
1980                                 uiDefButF(block, NUM, B_DIFF, "Inner:", 160,20,150,20, &pd->pdef_sbift, 0.001, 1.0, 10, 0, "Inner face thickness");
1981                                 uiDefButF(block, NUM, B_DIFF, "Outer:", 160, 0,150,20, &pd->pdef_sboft, 0.001, 1.0, 10, 0, "Outer face thickness");
1982                         }
1983                 }               
1984         }
1985 }
1986
1987
1988 /* Panel for softbodies */
1989 static void object_softbodies__enable(void *ob_v, void *arg2)
1990 {
1991         Object *ob = ob_v;
1992         ModifierData *md = modifiers_findByType(ob, eModifierType_Softbody);
1993
1994         if (modifiers_isSoftbodyEnabled(ob)) {
1995                 if (md) {
1996                         md->mode &= ~(eModifierMode_Render|eModifierMode_Realtime);
1997                 }
1998         } else {
1999                 if (!md) {
2000                         md = modifier_new(eModifierType_Softbody);
2001                         BLI_addhead(&ob->modifiers, md);
2002                 }
2003
2004                 md->mode |= eModifierMode_Render|eModifierMode_Realtime;
2005
2006                 if (!ob->soft) {
2007                         ob->soft= sbNew();
2008                         ob->softflag |= OB_SB_GOAL|OB_SB_EDGES;
2009                 }
2010         }
2011
2012         allqueue(REDRAWBUTSEDIT, 0);
2013 }
2014
2015 static void object_softbodies(Object *ob)
2016 {
2017         uiBlock *block;
2018         
2019         block= uiNewBlock(&curarea->uiblocks, "object_softbodies", UI_EMBOSS, UI_HELV, curarea->win);
2020         if(uiNewPanel(curarea, block, "Soft Body", "Physics", 640, 0, 318, 204)==0) return;
2021
2022         if(ob->id.lib) uiSetButLock(1, "Can't edit library data");
2023         
2024         /* do not allow to combine with force fields */
2025         /* if(ob->pd && ob->pd->deflect) { */
2026         /* no reason for that any more BM */
2027         if(0) {
2028                 uiDefBut(block, LABEL, 0, "Object has Deflection,",             10,160,300,20, NULL, 0.0, 0, 0, 0, "");
2029                 uiDefBut(block, LABEL, 0, "no Soft Body possible",              10,140,300,20, NULL, 0.0, 0, 0, 0, "");
2030         } else {
2031                 static int val;
2032                 uiBut *but;
2033
2034                 val = modifiers_isSoftbodyEnabled(ob);
2035                 but = uiDefButI(block, TOG, REDRAWBUTSOBJECT, "Enable Soft Body",       10,200,150,20, &val, 0, 0, 0, 0, "Sets object to become soft body");
2036                 uiButSetFunc(but, object_softbodies__enable, ob, NULL);
2037                 uiDefBut(block, LABEL, 0, "",   160, 200,150,20, NULL, 0.0, 0.0, 0, 0, "");     // alignment reason
2038         }
2039         
2040         if(modifiers_isSoftbodyEnabled(ob)) {
2041                 SoftBody *sb= ob->soft;
2042                 int defCount;
2043                 char *menustr;
2044                 
2045                 if(sb==NULL) {
2046                         sb= ob->soft= sbNew();
2047                         ob->softflag |= OB_SB_GOAL|OB_SB_EDGES;
2048                 }
2049                 
2050                 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");
2051                 
2052                 if(sb->keys) uiSetButLock(1, "Soft Body is baked, free it first");
2053                 
2054                 if(ob->softflag & OB_SB_BAKESET) {
2055                         uiBlockBeginAlign(block);
2056                         uiDefButI(block, NUM, B_DIFF, "Start:",                 10, 170,100,20, &sb->sfra, 1.0, 10000.0, 10, 0, "Start frame for baking");
2057                         uiDefButI(block, NUM, B_DIFF, "End:",                   110, 170,100,20, &sb->efra, 1.0, 10000.0, 10, 0, "End frame for baking");
2058                         uiDefButI(block, NUM, B_DIFF, "Interval:",              210, 170,100,20, &sb->interval, 1.0, 10.0, 10, 0, "Interval in frames between baked keys");
2059                         uiBlockEndAlign(block);
2060                         
2061                         uiDefButS(block, TOG, B_DIFF, "Local",                  10, 145,100,20, &sb->local, 0.0, 0.0, 0, 0, "Use local coordinates for baking");
2062                         
2063                         uiClearButLock();
2064                         uiBlockBeginAlign(block);
2065                         
2066                         if(sb->keys) {
2067                                 char str[128];
2068                                 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");
2069                                 sprintf(str, "Stored %d vertices %d keys %.3f MB", sb->totpoint, sb->totkey, ((float)16*sb->totpoint*sb->totkey)/(1024.0*1024.0));
2070                                 uiDefBut(block, LABEL, 0, str, 10, 100,300,20, NULL, 0.0, 0.0, 00, 0, "");
2071                         }
2072                         else                            
2073                                 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");
2074                 }
2075                 else {
2076                         /* GENERAL STUFF */
2077                         uiBlockBeginAlign(block);
2078                         uiDefButF(block, NUM, B_DIFF, "Friction:",              10, 170,150,20, &sb->mediafrict, 0.0, 10.0, 10, 0, "General media friction for point movements");
2079                         uiDefButF(block, NUM, B_DIFF, "Mass:",                  160, 170,150,20, &sb->nodemass , 0.001, 50.0, 10, 0, "Point Mass, the heavier the slower");
2080                         uiDefButF(block, NUM, B_DIFF, "Grav:",                  10,150,150,20, &sb->grav , 0.0, 10.0, 10, 0, "Apply gravitation to point movement");
2081                         uiDefButF(block, NUM, B_DIFF, "Speed:",                 160,150,150,20, &sb->physics_speed , 0.01, 100.0, 10, 0, "Tweak timing for physics to control frequency and speed");
2082                         uiDefButF(block, NUM, B_DIFF, "Error Limit:",   10,130,150,20, &sb->rklimit , 0.01, 1.0, 10, 0, "The Runge-Kutta ODE solver error limit, low value gives more precision");
2083                         uiBlockEndAlign(block);
2084                         
2085                         /* GOAL STUFF */
2086                         uiBlockBeginAlign(block);
2087                         uiDefButBitS(block, TOG, OB_SB_GOAL, B_SOFTBODY_CHANGE, "Use Goal",     10,100,130,20, &ob->softflag, 0, 0, 0, 0, "Define forces for vertices to stick to animated position");
2088                         
2089                         if(ob->type==OB_MESH) {
2090                                 menustr= get_vertexgroup_menustr(ob);
2091                                 defCount=BLI_countlist(&ob->defbase);
2092                                 if(defCount==0) sb->vertgroup= 0;
2093                                 uiDefButS(block, MENU, B_SOFTBODY_CHANGE, menustr,      140,100,20,20, &sb->vertgroup, 0, defCount, 0, 0, "Browses available vertex groups");
2094                                 MEM_freeN (menustr);
2095
2096                                 if(sb->vertgroup) {
2097                                         bDeformGroup *defGroup = BLI_findlink(&ob->defbase, sb->vertgroup-1);
2098                                         if(defGroup)
2099                                                 uiDefBut(block, BUT, B_DIFF, defGroup->name,    160,100,130,20, NULL, 0.0, 0.0, 0, 0, "Name of current vertex group");
2100                                         else
2101                                                 uiDefBut(block, BUT, B_DIFF, "(no group)",      160,100,130,20, NULL, 0.0, 0.0, 0, 0, "Vertex Group doesn't exist anymore");
2102                                         uiDefIconBut(block, BUT, B_SOFTBODY_DEL_VG, ICON_X, 290,100,20,20, 0, 0, 0, 0, 0, "Disable use of vertex group");
2103                                 }
2104                                 else
2105                                         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");
2106                         }
2107                         else {
2108                                 uiDefButS(block, TOG, B_SOFTBODY_CHANGE, "W",                   140,100,20,20, &sb->vertgroup, 0, 1, 0, 0, "Use control point weight values");
2109                                 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");
2110                         }
2111
2112                         uiDefButF(block, NUM, B_DIFF, "G Stiff:",       10,80,150,20, &sb->goalspring, 0.0, 0.999, 10, 0, "Goal (vertex target position) spring stiffness");
2113                         uiDefButF(block, NUM, B_DIFF, "G Damp:",        160,80,150,20, &sb->goalfrict  , 0.0, 10.0, 10, 0, "Goal (vertex target position) friction");
2114                         uiDefButF(block, NUM, B_SOFTBODY_CHANGE, "G Min:",              10,60,150,20, &sb->mingoal, 0.0, 1.0, 10, 0, "Goal minimum, vertex group weights are scaled to match this range");
2115                         uiDefButF(block, NUM, B_SOFTBODY_CHANGE, "G Max:",              160,60,150,20, &sb->maxgoal, 0.0, 1.0, 10, 0, "Goal maximum, vertex group weights are scaled to match this range");
2116                         uiBlockEndAlign(block);
2117                         
2118                         /* EDGE SPRING STUFF */
2119                         if(ob->type!=OB_SURF) {
2120                                 uiBlockBeginAlign(block);
2121                                 uiDefButBitS(block, TOG, OB_SB_EDGES, B_SOFTBODY_CHANGE, "Use Edges",           10,30,150,20, &ob->softflag, 0, 0, 0, 0, "Use Edges as springs");
2122                                 uiDefButBitS(block, TOG, OB_SB_QUADS, B_SOFTBODY_CHANGE, "Stiff Quads",         160,30,150,20, &ob->softflag, 0, 0, 0, 0, "Adds diagonal springs on 4-gons");
2123                                 uiDefButF(block, NUM, B_DIFF, "E Stiff:",       10,10,150,20, &sb->inspring, 0.0,  0.999, 10, 0, "Edge spring stiffness");
2124                                 uiDefButF(block, NUM, B_DIFF, "E Damp:",        160,10,150,20, &sb->infrict, 0.0,  10.0, 10, 0, "Edge spring friction");
2125                                 uiBlockEndAlign(block);
2126                         }
2127                 }
2128         }
2129         uiBlockEndAlign(block);
2130
2131 }
2132
2133 static void object_panel_particles_motion(Object *ob)
2134 {
2135         uiBlock *block;
2136         uiBut *but;
2137         PartEff *paf= give_parteff(ob);
2138
2139         if (paf==NULL) return;
2140                 
2141         block= uiNewBlock(&curarea->uiblocks, "object_panel_particles_motion", UI_EMBOSS, UI_HELV, curarea->win);
2142         uiNewPanelTabbed("Particles ", "Physics");
2143         if(uiNewPanel(curarea, block, "Particle Motion", "Physics", 320, 0, 318, 204)==0) return;
2144         
2145         if(ob->id.lib) uiSetButLock(1, "Can't edit library data");
2146         
2147         /* top row */
2148         uiBlockBeginAlign(block);
2149         uiDefButI(block, NUM, B_CALCEFFECT, "Keys:",    0,180,75,20, &paf->totkey, 1.0, 100.0, 0, 0, "Specify the number of key positions");
2150         uiDefButBitS(block, TOG, PAF_BSPLINE, B_CALCEFFECT, "Bspline",  75,180,75,20, &paf->flag, 0, 0, 0, 0, "Use B spline formula for particle interpolation");
2151         uiDefButI(block, NUM, B_CALCEFFECT, "Seed:",    150,180,75,20, &paf->seed, 0.0, 255.0, 0, 0, "Set an offset in the random table");
2152         uiDefButF(block, NUM, B_CALCEFFECT, "RLife:",   225,180,85,20, &paf->randlife, 0.0, 2.0, 10, 1, "Give the particlelife a random variation");
2153         uiBlockEndAlign(block);
2154         
2155         /* left collumn */
2156         uiDefBut(block, LABEL, 0, "Velocity:",                  0,160,150,20, NULL, 0.0, 0, 0, 0, "");
2157         uiBlockBeginAlign(block);
2158         uiBlockSetCol(block, TH_BUT_SETTING2);
2159         uiDefButF(block, NUM, B_CALCEFFECT, "Normal:",          0,140,150,18, &paf->normfac, -2.0, 2.0, 1, 3, "Let the mesh give the particle a starting speed");
2160         uiDefButF(block, NUM, B_CALCEFFECT, "Object:",          0,122,150,18, &paf->obfac, -1.0, 1.0, 1, 3, "Let the object give the particle a starting speed");
2161         uiDefButF(block, NUM, B_CALCEFFECT, "Random:",          0,104,150,18, &paf->randfac, 0.0, 2.0, 1, 3, "Give the startingspeed a random variation");
2162         uiDefButF(block, NUM, B_CALCEFFECT, "Texture:",         0,86,150,18, &paf->texfac, 0.0, 2.0, 1, 3, "Let the texture give the particle a starting speed");
2163         uiDefButF(block, NUM, B_CALCEFFECT, "Damping:",         0,68,150,18, &paf->damp, 0.0, 1.0, 1, 3, "Specify the damping factor");
2164         uiBlockSetCol(block, TH_AUTO);
2165         but=uiDefBut(block, TEX, B_PAF_SET_VG1, "VGroup:",      0,50,150,18, paf->vgroupname_v, 0, 31, 0, 0, "Name of vertex group to use for speed control");
2166         uiButSetCompleteFunc(but, autocomplete_vgroup, (void *)OBACT);
2167         uiBlockEndAlign(block);
2168         
2169         uiDefBut(block, LABEL, 0, "Texture Emission",                   0,30,150,20, NULL, 0.0, 0, 0, 0, "");
2170         uiBlockBeginAlign(block);
2171         uiDefButBitS(block, TOG3, PAF_TEXTIME, B_CALCEFFECT, "TexEmit",         0,10,75,20, &(paf->flag2), 0, 0, 0, 0, "Use a texture to define emission of particles");
2172         uiDefButS(block, NUM, B_CALCEFFECT, "Tex:",             75,10,75,20, &paf->timetex, 1.0, 10.0, 0, 0, "Specify texture used for the texture emission");
2173         
2174         /* right collumn */
2175         uiDefIDPoinBut(block, test_grouppoin_but, ID_GR, B_CALCEFFECT, "GR:", 160, 155, 150, 20, &paf->group, "Limit Force Fields to this Group"); 
2176
2177         uiBlockBeginAlign(block);
2178         uiDefBut(block, LABEL, 0, "Force:",                             160,130,75,20, NULL, 0.0, 0, 0, 0, "");
2179         uiDefButF(block, NUM, B_CALCEFFECT, "X:",               235,130,75,20, paf->force, -1.0, 1.0, 1, 2, "Specify the X axis of a continues force");
2180         uiDefButF(block, NUM, B_CALCEFFECT, "Y:",               160,110,75,20, paf->force+1,-1.0, 1.0, 1, 2, "Specify the Y axis of a continues force");
2181         uiDefButF(block, NUM, B_CALCEFFECT, "Z:",               235,110,75,20, paf->force+2, -1.0, 1.0, 1, 2, "Specify the Z axis of a continues force");
2182         
2183         uiBlockBeginAlign(block);
2184         uiDefButS(block, NUM, B_CALCEFFECT, "Tex:",             160,80,75,20, &paf->speedtex, 1.0, 10.0, 0, 2, "Specify the texture used for force");
2185         uiDefButF(block, NUM, B_CALCEFFECT, "X:",               235,80,75,20, paf->defvec, -1.0, 1.0, 1, 2, "Specify the X axis of a force, determined by the texture");
2186         uiDefButF(block, NUM, B_CALCEFFECT, "Y:",               160,60,75,20, paf->defvec+1,-1.0, 1.0, 1, 2, "Specify the Y axis of a force, determined by the texture");
2187         uiDefButF(block, NUM, B_CALCEFFECT, "Z:",               235,60,75,20, paf->defvec+2, -1.0, 1.0, 1, 2, "Specify the Z axis of a force, determined by the texture");
2188         
2189         uiBlockBeginAlign(block);
2190         uiDefButS(block, ROW, B_CALCEFFECT, "Int",              160,30,50,20, &paf->texmap, 14.0, 0.0, 0, 0, "Use texture intensity as a factor for texture force");
2191         uiDefButS(block, ROW, B_CALCEFFECT, "RGB",              210,30,50,20, &paf->texmap, 14.0, 1.0, 0, 0, "Use RGB values as a factor for particle speed vector");
2192         uiDefButS(block, ROW, B_CALCEFFECT, "Grad",             260,30,50,20, &paf->texmap, 14.0, 2.0, 0, 0, "Use texture gradient as a factor for particle speed vector");
2193         
2194         uiDefButF(block, NUM, B_CALCEFFECT, "Nabla:",   160,10,150,20, &paf->nabla, 0.0001f, 1.0, 1, 0, "Specify the dimension of the area for gradient calculation");
2195         
2196 }
2197
2198
2199 static void object_panel_particles(Object *ob)
2200 {
2201         uiBlock *block;
2202         uiBut *but;
2203         PartEff *paf= give_parteff(ob);
2204         
2205         block= uiNewBlock(&curarea->uiblocks, "object_panel_particles", UI_EMBOSS, UI_HELV, curarea->win);
2206         if(uiNewPanel(curarea, block, "Particles ", "Physics", 320, 0, 318, 204)==0) return;
2207
2208         if(ob->id.lib) uiSetButLock(1, "Can't edit library data");
2209         
2210         if (ob->type == OB_MESH) {
2211                 uiBlockBeginAlign(block);
2212                 if(paf==NULL)
2213                         uiDefBut(block, BUT, B_NEWEFFECT, "NEW",        0,180,75,20, 0, 0, 0, 0, 0, "Create a new Particle effect");
2214                 else
2215                         uiDefBut(block, BUT, B_DELEFFECT, "Delete", 0,180,75,20, 0, 0, 0, 0, 0, "Delete the effect");
2216         }
2217         else uiDefBut(block, LABEL, 0, "Only Mesh Objects can generate particles",                              10,180,300,20, NULL, 0.0, 0, 0, 0, "");
2218         
2219         
2220         if(paf==NULL) return;
2221         
2222         uiDefBut(block, BUT, B_RECALCAL, "RecalcAll",           75,180,75,20, 0, 0, 0, 0, 0, "Update all particle systems");
2223         uiBlockEndAlign(block);
2224         
2225         uiDefBut(block, LABEL, 0, "Emit:",                                      0,150,75,20, NULL, 0.0, 0, 0, 0, "");
2226         uiBlockBeginAlign(block);
2227         uiDefButI(block, NUM, B_CALCEFFECT, "Amount:",          0,130,150,20, &paf->totpart, 1.0, 100000.0, 0, 0, "The total number of particles");
2228         if(paf->flag & PAF_STATIC) {
2229                 uiDefButS(block, NUM, REDRAWVIEW3D, "Step:",    0,110,150,20, &paf->staticstep, 1.0, 100.0, 10, 0, "For static duplicators, the Step value skips particles");
2230         }
2231         else {
2232                 uiDefButF(block, NUM, B_CALCEFFECT, "Sta:",             0,110,75,20, &paf->sta, -250.0, MAXFRAMEF, 100, 1, "Frame # to start emitting particles");
2233                 uiDefButF(block, NUM, B_CALCEFFECT, "End:",             75,110,75,20, &paf->end, 1.0, MAXFRAMEF, 100, 1, "Frame # to stop emitting particles");
2234         }
2235         uiDefButF(block, NUM, B_CALCEFFECT, "Life:",            0,90,75,20, &paf->lifetime, 1.0, MAXFRAMEF, 100, 1, "Specify the life span of the particles");
2236         uiDefButS(block, NUM, B_CALCEFFECT, "Disp:",            75,90,75,20, &paf->disp, 0.0, 100.0, 10, 0, "Percentage of particles to calculate for 3d view");
2237         uiBlockEndAlign(block);
2238         
2239         uiDefBut(block, LABEL, 0, "From:",                                      0,70,75,20, NULL, 0.0, 0, 0, 0, "");
2240         uiBlockBeginAlign(block);
2241         uiDefButBitS(block, TOGN, PAF_OFACE, B_CALCEFFECT, "Verts",     0,50,75,20, &paf->flag, 0, 0, 0, 0, "Emit particles from vertices");
2242         uiDefButBitS(block, TOG, PAF_FACE, B_CALCEFFECT, "Faces",       75,50,75,20, &paf->flag, 0, 0, 0, 0, "Emit particles from faces");
2243         if(paf->flag & PAF_FACE) {
2244                 uiDefButBitS(block, TOG, PAF_TRAND, B_CALCEFFECT, "Rand",       0,30,50,20, &paf->flag, 0, 0, 0, 0, "Use true random distribution from faces");
2245                 uiDefButBitS(block, TOG, PAF_EDISTR, B_CALCEFFECT, "Even",      50,30,50,20, &paf->flag, 0, 0, 0, 0, "Use even distribution from faces based on face areas");
2246                 uiDefButS(block, NUM, B_CALCEFFECT, "P/F:",                                     100,30,50,20, &paf->userjit, 0.0, 200.0, 1, 0, "Jitter table distribution: maximum particles per face (0=uses default)");
2247         }
2248         else uiBlockEndAlign(block);    /* vgroup button no align */
2249         
2250         but=uiDefBut(block, TEX, B_PAF_SET_VG, "VGroup:",                                       0,10,150,20, paf->vgroupname, 0, 31, 0, 0, "Name of vertex group to use");
2251         uiButSetCompleteFunc(but, autocomplete_vgroup, (void *)OBACT);
2252         uiBlockEndAlign(block);
2253         
2254         /* right collumn */
2255         uiBlockBeginAlign(block);
2256         uiDefButBitS(block, TOG, PAF_STATIC, B_EFFECT_DEP, "Static",    160,180,75,20, &paf->flag, 0, 0, 0, 0, "Make static particles (deform only works with SubSurf)");
2257         if(paf->flag & PAF_STATIC) {
2258                 uiDefButBitS(block, TOG, PAF_ANIMATED, B_DIFF, "Animated",      235,180,75,20, &paf->flag, 0, 0, 0, 0, "Static particles are recalculated each rendered frame");
2259         }
2260         uiBlockEndAlign(block);
2261
2262         uiDefBut(block, LABEL, 0, "Display:",                           160,150,75,20, NULL, 0.0, 0, 0, 0, "");
2263         uiBlockBeginAlign(block);
2264         uiDefButS(block, NUM, B_CALCEFFECT, "Material:",        160,130,150,20, &paf->omat, 1.0, 16.0, 0, 0, "Specify material used for the particles");
2265         uiDefButS(block, TOG|BIT|7, B_REDR, "Mesh",                     160,110,50,20, &paf->flag, 0, 0, 0, 0, "Render emitter Mesh also");
2266         uiDefButBitS(block, TOG, PAF_UNBORN, B_DIFF, "Unborn",210,110,50,20, &paf->flag, 0, 0, 0, 0, "Make particles appear before they are emitted");
2267         uiDefButBitS(block, TOG, PAF_DIED, B_DIFF, "Died",      260,110,50,20, &paf->flag, 0, 0, 0, 0, "Make particles appear after they have died");
2268         uiDefButS(block, TOG, REDRAWVIEW3D, "Vect",                     160,90,75,20, &paf->stype, 0, 0, 0, 0, "Give the particles a direction and rotation");
2269         uiDefButF(block, NUM, B_DIFF,           "Size:",                235,90,75,20, &paf->vectsize, 0.0, 1.0, 10, 1, "The amount the Vect option influences halo size");      
2270         uiBlockEndAlign(block);
2271
2272         uiDefBut(block, LABEL, 0, "Children:",                          160,70,75,20, NULL, 0.0, 0, 0, 0, "");
2273         uiBlockBeginAlign(block);
2274         uiDefButS(block, NUM, B_REDR,           "Generation:",  160,50,150,20, &paf->curmult, 0.0, 3.0, 0, 0, "Current generation of particles");
2275         uiDefButS(block, NUM, B_CALCEFFECT, "Num:",                     160,30,75,20, paf->child+paf->curmult, 1.0, 600.0, 100, 0, "Specify the number of generations of particles that can multiply itself");
2276         uiDefButF(block, NUM, B_CALCEFFECT, "Prob:",            235,30,75,20, paf->mult+paf->curmult, 0.0, 1.0, 10, 1, "Probability \"dying\" particle spawns a new one.");
2277         uiDefButF(block, NUM, B_CALCEFFECT, "Life:",            160,10,75,20, paf->life+paf->curmult, 1.0, 600.0, 100, 1, "Specify the lifespan of the next generation particles");
2278         uiDefButS(block, NUM, B_CALCEFFECT, "Mat:",                     235,10,75,20, paf->mat+paf->curmult, 1.0, 8.0, 0, 0, "Specify the material used for the particles");
2279         uiBlockEndAlign(block);
2280         
2281 }
2282
2283 /* NT - Panel for fluidsim settings */
2284 static void object_panel_fluidsim(Object *ob)
2285 {
2286         uiBlock *block;
2287         int yline = 160;
2288         const int lineHeight = 20;
2289         const int separateHeight = 3;
2290         const int objHeight = 20;
2291         
2292         block= uiNewBlock(&curarea->uiblocks, "object_fluidsim", UI_EMBOSS, UI_HELV, curarea->win);
2293         uiNewPanelTabbed("Soft Body", "Physics");
2294         if(uiNewPanel(curarea, block, "Fluid Simulation", "Physics", 1060, 0, 318, 204)==0) return;
2295
2296         if(ob->id.lib) uiSetButLock(1, "Can't edit library data");
2297         
2298         if(ob->type==OB_MESH) {
2299                 uiDefButBitS(block, TOG, OB_FLUIDSIM_ENABLE, REDRAWBUTSOBJECT, "Enable",         0,yline, 75,objHeight, 
2300                                 &ob->fluidsimFlag, 0, 0, 0, 0, "Sets object to participate in fluid simulation");
2301
2302                 if(ob->fluidsimFlag & OB_FLUIDSIM_ENABLE) {
2303                         FluidsimSettings *fss= ob->fluidsimSettings;
2304                         
2305                         if(fss==NULL) {
2306                                 fss = ob->fluidsimSettings = fluidsimSettingsNew(ob);
2307                         }
2308                         
2309                         uiBlockBeginAlign(block);
2310                         uiDefButS(block, ROW, REDRAWBUTSOBJECT ,"Domain",           90, yline, 70,objHeight, &fss->type, 15.0, OB_FLUIDSIM_DOMAIN,  20.0, 1.0, "Bounding box of this object represents the computational domain of the fluid simulation.");
2311                         uiDefButS(block, ROW, REDRAWBUTSOBJECT ,"Fluid",           160, yline, 70,objHeight, &fss->type, 15.0, OB_FLUIDSIM_FLUID,   20.0, 2.0, "Object represents a volume of fluid in the simulation.");
2312                         uiDefButS(block, ROW, REDRAWBUTSOBJECT ,"Obstacle",      230, yline, 70,objHeight, &fss->type, 15.0, OB_FLUIDSIM_OBSTACLE,20.0, 3.0, "Object is a fixed obstacle.");
2313                         yline -= lineHeight;
2314
2315                         uiDefButS(block, ROW, REDRAWBUTSOBJECT ,"Inflow",           90, yline, 70,objHeight, &fss->type, 15.0, OB_FLUIDSIM_INFLOW,  20.0, 4.0, "Object adds fluid to the simulation.");
2316                         uiDefButS(block, ROW, REDRAWBUTSOBJECT ,"Outflow",   160, yline, 70,objHeight, &fss->type, 15.0, OB_FLUIDSIM_OUTFLOW, 20.0, 5.0, "Object removes fluid from the simulation.");
2317                         uiDefButS(block, ROW, B_FLUIDSIM_MAKEPART ,"Particle",   230, yline, 70,objHeight, &fss->type, 15.0, OB_FLUIDSIM_PARTICLE,20.0, 3.0, "Object is a fixed obstacle.");
2318                         uiBlockEndAlign(block);
2319                         yline -= lineHeight;
2320                         yline -= 2*separateHeight;
2321
2322                         /* display specific settings for each type */
2323                         if(fss->type == OB_FLUIDSIM_DOMAIN) {
2324                                 const int maxRes = 512;
2325                                 char memString[32];
2326
2327                                 // use mesh bounding box and object scaling
2328                                 // TODO fix redraw issue
2329                                 elbeemEstimateMemreq(fss->resolutionxyz, 
2330                                                 ob->fluidsimSettings->bbSize[0],ob->fluidsimSettings->bbSize[1],ob->fluidsimSettings->bbSize[2], fss->maxRefine, memString);
2331                                 
2332                                 //uiDefButBitS(block, TOG, 1, REDRAWBUTSOBJECT, "Advanced>>",    0,yline, 75,objHeight, &fss->show_advancedoptions, 0, 0, 0, 0, "Show advanced domain options.");
2333                                 uiDefButS(block, ROW, REDRAWBUTSOBJECT, "Std",   0,yline, 25,objHeight, &fss->show_advancedoptions, 16.0, 0, 20.0, 0, "Show standard domain options.");
2334                                 uiDefButS(block, ROW, REDRAWBUTSOBJECT, "Adv",  25,yline, 25,objHeight, &fss->show_advancedoptions, 16.0, 1, 20.0, 1, "Show advanced domain options.");
2335                                 uiDefButS(block, ROW, REDRAWBUTSOBJECT, "Bnd",  50,yline, 25,objHeight, &fss->show_advancedoptions, 16.0, 2, 20.0, 2, "Show domain boundary options.");
2336                           
2337                                 uiDefBut(block, BUT, B_FLUIDSIM_BAKE, "BAKE",90, yline,210,objHeight, NULL, 0.0, 0.0, 10, 0, "Perform simulation and output and surface&preview meshes for each frame.");
2338                                 yline -= lineHeight;
2339                                 yline -= 2*separateHeight;
2340
2341                                 if(fss->show_advancedoptions == 0) {
2342                                         uiDefBut(block, LABEL,   0, "Req. BAKE Memory:",  0,yline,150,objHeight, NULL, 0.0, 0, 0, 0, "");
2343                                         uiDefBut(block, LABEL,   0, memString,  200,yline,100,objHeight, NULL, 0.0, 0, 0, 0, "");
2344                                         yline -= lineHeight;
2345
2346                                         uiDefButS(block, NUM, REDRAWBUTSOBJECT, "Resolution:", 0, yline,150,objHeight, &fss->resolutionxyz, 1, maxRes, 10, 0, "Domain resolution in X,Y and Z direction");
2347                                         uiDefButS(block, NUM, B_DIFF,           "Preview-Res.:", 150, yline,150,objHeight, &fss->previewresxyz, 1, 100, 10, 0, "Resolution of the preview meshes to generate, also in X,Y and Z direction");
2348                                         yline -= lineHeight;
2349                                         yline -= 1*separateHeight;
2350
2351                                         uiDefButF(block, NUM, B_DIFF, "Start time:",   0, yline,150,objHeight, &fss->animStart, 0.0, 100.0, 10, 0, "Simulation time of the first blender frame.");
2352                                         uiDefButF(block, NUM, B_DIFF, "End time:",   150, yline,150,objHeight, &fss->animEnd  , 0.0, 100.0, 10, 0, "Simulation time of the last blender frame.");
2353                                         yline -= lineHeight;
2354                                         yline -= 2*separateHeight;
2355
2356                                         if((fss->guiDisplayMode<1) || (fss->guiDisplayMode>3)){ fss->guiDisplayMode=2; } // can be changed by particle setting
2357                                         uiDefBut(block, LABEL,   0, "Disp.-Qual.:",              0,yline, 90,objHeight, NULL, 0.0, 0, 0, 0, "");
2358                                         uiDefButS(block, MENU, B_FLUIDSIM_FORCEREDRAW, "GuiDisplayMode%t|Geometry %x1|Preview %x2|Final %x3",   
2359                                                          90,yline,105,objHeight, &fss->guiDisplayMode, 0, 0, 0, 0, "How to display the fluid mesh in the blender gui.");
2360                                         uiDefButS(block, MENU, B_DIFF, "RenderDisplayMode%t|Geometry %x1|Preview %x2|Final %x3",        
2361                                                         195,yline,105,objHeight, &fss->renderDisplayMode, 0, 0, 0, 0, "How to display the fluid mesh for rendering.");
2362                                         yline -= lineHeight;
2363                                         yline -= 1*separateHeight;
2364
2365                                         uiDefIconBut(block, BUT, B_FLUIDSIM_SELDIR, ICON_FILESEL,  0, yline,  20, objHeight,                   0, 0, 0, 0, 0,  "Select Directory (and/or filename prefix) to store baked fluid simulation files in");
2366                                         uiDefBut(block, TEX,     B_FLUIDSIM_FORCEREDRAW,"",           20, yline, 280, objHeight, fss->surfdataPath, 0.0,79.0, 0, 0,  "Enter Directory (and/or filename prefix) to store baked fluid simulation files in");
2367                                         // FIXME what is the 79.0 above?
2368                                 } else if(fss->show_advancedoptions == 1) {
2369                                         // advanced options
2370                                         uiBlockBeginAlign(block);
2371                                         uiDefBut(block, LABEL, 0, "Gravity:",           0, yline,  90,objHeight, NULL, 0.0, 0, 0, 0, "");
2372                                         uiDefButF(block, NUM, B_DIFF, "X:",    90, yline,  70,objHeight, &fss->gravx, -1000.1, 1000.1, 10, 0, "Gravity in X direction");
2373                                         uiDefButF(block, NUM, B_DIFF, "Y:",   160, yline,  70,objHeight, &fss->gravy, -1000.1, 1000.1, 10, 0, "Gravity in Y direction");
2374                                         uiDefButF(block, NUM, B_DIFF, "Z:",   230, yline,  70,objHeight, &fss->gravz, -1000.1, 1000.1, 10, 0, "Gravity in Z direction");
2375                                         uiBlockEndAlign(block);
2376                                         yline -= lineHeight;
2377                                         yline -= 1*separateHeight;
2378
2379                                         /* viscosity */
2380                                         uiBlockBeginAlign(block);
2381                                         uiDefButS(block, MENU, REDRAWVIEW3D, "Viscosity%t|Manual %x1|Water %x2|Oil %x3|Honey %x4",      
2382                                                         0,yline, 90,objHeight, &fss->viscosityMode, 0, 0, 0, 0, "Set viscosity of the fluid to a preset value, or use manual input.");
2383                                         if(fss->viscosityMode==1) {
2384                                                 uiDefButF(block, NUM, B_DIFF, "Value:",     90, yline, 105,objHeight, &fss->viscosityValue,       0.0, 1.0, 10, 0, "Viscosity setting, value that is multiplied by 10 to the power of (exponent*-1).");
2385                                                 uiDefButS(block, NUM, B_DIFF, "Neg-Exp.:", 195, yline, 105,objHeight, &fss->viscosityExponent, 0,   10,  10, 0, "Negative exponent for the viscosity value (to simplify entering small values e.g. 5*10^-6.");
2386                                         } else {
2387                                                 // display preset values
2388                                                 uiDefBut(block, LABEL,   0, fluidsimViscosityPresetString[fss->viscosityMode],  90,yline,200,objHeight, NULL, 0.0, 0, 0, 0, "");
2389                                         }
2390                                         uiBlockEndAlign(block);
2391                                         yline -= lineHeight;
2392                                         yline -= 1*separateHeight;
2393
2394                                         uiDefBut(block, LABEL, 0, "Realworld-size:",            0,yline,150,objHeight, NULL, 0.0, 0, 0, 0, "");
2395                                         uiDefButF(block, NUM, B_DIFF, "", 150, yline,150,objHeight, &fss->realsize, 0.001, 10.0, 10, 0, "Size of the simulation domain in meters.");
2396                                         yline -= lineHeight;
2397                                         yline -= 2*separateHeight;
2398
2399                                         uiDefBut(block, LABEL, 0, "Gridlevels:",                0,yline,150,objHeight, NULL, 0.0, 0, 0, 0, "");
2400                                         uiDefButI(block, NUM, B_DIFF, "", 150, yline,150,objHeight, &fss->maxRefine, -1, 4, 10, 0, "Number of coarsened Grids to use (set to -1 for automatic selection).");
2401                                         yline -= lineHeight;
2402
2403                                         uiDefBut(block, LABEL, 0, "Compressibility:",           0,yline,150,objHeight, NULL, 0.0, 0, 0, 0, "");
2404                                         uiDefButF(block, NUM, B_DIFF, "", 150, yline,150,objHeight, &fss->gstar, 0.001, 0.10, 10,0, "Allowed compressibility due to gravitational force for standing fluid (directly affects simulation step size).");
2405                                         yline -= lineHeight;
2406
2407                                 } else if(fss->show_advancedoptions == 2) {
2408                                         // copied from obstacle...
2409                                         //yline -= lineHeight + 5;
2410                                         uiDefBut(block, LABEL, 0, "Domain boundary type settings:",             0,yline,300,objHeight, NULL, 0.0, 0, 0, 0, "");
2411                                         yline -= lineHeight;
2412                                         uiBlockBeginAlign(block);
2413                                         uiDefButI(block, ROW, REDRAWBUTSOBJECT ,"Noslip",   00, yline,100,objHeight, &fss->typeFlags, 15.0, OB_FSBND_NOSLIP,   20.0, 1.0, "Obstacle causes zero normal and tangential velocity (=sticky). Default for all. Only option for moving objects.");
2414                                         uiDefButI(block, ROW, REDRAWBUTSOBJECT ,"Part",    100, yline,100,objHeight, &fss->typeFlags, 15.0, OB_FSBND_PARTSLIP, 20.0, 2.0, "Mix between no-slip and free-slip. Non moving objects only!");
2415                                         uiDefButI(block, ROW, REDRAWBUTSOBJECT ,"Free",          200, yline,100,objHeight, &fss->typeFlags, 15.0, OB_FSBND_FREESLIP, 20.0, 3.0, "Obstacle only causes zero normal velocity (=not sticky). Non moving objects only!");
2416                                         uiBlockEndAlign(block);
2417                                         yline -= lineHeight;
2418                                         if(fss->typeFlags&OB_FSBND_PARTSLIP) {
2419                                                 uiDefBut(block, LABEL, 0, "PartSlipValue:",             0,yline,150,objHeight, NULL, 0.0, 0, 0, 0, "");
2420                                                 uiDefButF(block, NUM, B_DIFF, "", 150, yline,150,objHeight, &fss->partSlipValue, 0.0, 0.1, 10,0, ".");
2421                                                 yline -= lineHeight;
2422                                         }
2423
2424                                         uiDefBut(block, LABEL, 0, "Generate Particles:",                0,yline,200,objHeight, NULL, 0.0, 0, 0, 0, "");
2425                                         uiDefButF(block, NUM, B_DIFF, "", 200, yline,100,objHeight, &fss->generateParticles, 0.0, 10.0, 10,0, "Amount of particles to generate (0=off, 1=normal, >1=more).");
2426                                         yline -= lineHeight;
2427
2428                                         uiDefBut(block, LABEL, 0, "Generate&Use SpeedVecs:",            0,yline,200,objHeight, NULL, 0.0, 0, 0, 0, "");
2429                                   uiDefButBitI(block, TOG, OB_FSDOMAIN_NOVECGEN, REDRAWBUTSOBJECT, "Disable",     200, yline,100,objHeight, &fss->typeFlags, 0, 0, 0, 0, "Default is to generate and use fluidsim vertex speed vectors, this option switches calculation off during bake, and disables loading.");
2430                                         yline -= lineHeight;
2431                                         // copied from obstacle...
2432                                 }
2433                         }
2434                         else if(
2435                                         (fss->type == OB_FLUIDSIM_FLUID) 
2436                                         || (fss->type == OB_FLUIDSIM_INFLOW) 
2437                                         ) {
2438                                 yline -= lineHeight + 5;
2439                                 if(fss->type == OB_FLUIDSIM_FLUID)  uiDefBut(block, LABEL, 0, "Initial velocity:",              0,yline,200,objHeight, NULL, 0.0, 0, 0, 0, "");
2440                                 if(fss->type == OB_FLUIDSIM_INFLOW) uiDefBut(block, LABEL, 0, "Inflow velocity:",                 0,yline,200,objHeight, NULL, 0.0, 0, 0, 0, "");
2441                                 yline -= lineHeight;
2442                                 uiBlockBeginAlign(block);
2443                                 uiDefButF(block, NUM, B_DIFF, "X:",   0, yline, 100,objHeight, &fss->iniVelx, -1000.1, 1000.1, 10, 0, "Fluid velocity in X direction");
2444                                 uiDefButF(block, NUM, B_DIFF, "Y:", 100, yline, 100,objHeight, &fss->iniVely, -1000.1, 1000.1, 10, 0, "Fluid velocity in Y direction");
2445                                 uiDefButF(block, NUM, B_DIFF, "Z:", 200, yline, 100,objHeight, &fss->iniVelz, -1000.1, 1000.1, 10, 0, "Fluid velocity in Z direction");
2446                                 uiBlockEndAlign(block);
2447                                 yline -= lineHeight;
2448
2449                                 if(fss->type == OB_FLUIDSIM_INFLOW) {
2450                                         uiDefBut(block, LABEL, 0, "Local Inflow Coords",                0,yline,200,objHeight, NULL, 0.0, 0, 0, 0, "");
2451                                   uiDefButBitI(block, TOG, OB_FSINFLOW_LOCALCOORD, REDRAWBUTSOBJECT, "Enable",     200, yline,100,objHeight, &fss->typeFlags, 0, 0, 0, 0, "Use local coordinates for inflow (e.g. for rotating objects).");
2452                                   yline -= lineHeight;
2453                                 }
2454                         }
2455                         else if( (fss->type == OB_FLUIDSIM_OUTFLOW) )   {
2456                                 yline -= lineHeight + 5;
2457                                 uiDefBut(block, LABEL, 0, "No additional settings as of now...",                0,yline,300,objHeight, NULL, 0.0, 0, 0, 0, "");
2458                         }
2459                         else if( (fss->type == OB_FLUIDSIM_OBSTACLE) )  {
2460                                 yline -= lineHeight + 5;
2461
2462                                 uiBlockBeginAlign(block);
2463                                 uiDefButI(block, ROW, REDRAWBUTSOBJECT ,"Noslip",   00, yline,100,objHeight, &fss->typeFlags, 15.0, OB_FSBND_NOSLIP,   20.0, 1.0, "Obstacle causes zero normal and tangential velocity (=sticky). Default for all. Only option for moving objects.");
2464                                 uiDefButI(block, ROW, REDRAWBUTSOBJECT ,"Part",    100, yline,100,objHeight, &fss->typeFlags, 15.0, OB_FSBND_PARTSLIP, 20.0, 2.0, "Mix between no-slip and free-slip. Non moving objects only!");
2465                                 uiDefButI(block, ROW, REDRAWBUTSOBJECT ,"Free",          200, yline,100,objHeight, &fss->typeFlags, 15.0, OB_FSBND_FREESLIP, 20.0, 3.0, "Obstacle only causes zero normal velocity (=not sticky). Non moving objects only!");
2466                                 uiBlockEndAlign(block);
2467                                 yline -= lineHeight;
2468
2469                                 if(fss->typeFlags&OB_FSBND_PARTSLIP) {
2470                                         uiDefBut(block, LABEL, 0, "PartSlipValue:",             0,yline,150,objHeight, NULL, 0.0, 0, 0, 0, "");
2471                                         uiDefButF(block, NUM, B_DIFF, "", 150, yline,150,objHeight, &fss->partSlipValue, 0.0, 0.1, 10,0, ".");
2472                                         yline -= lineHeight;
2473                                 }
2474
2475                                 yline -= lineHeight;
2476                         }
2477                         else if(fss->type == OB_FLUIDSIM_PARTICLE) {
2478
2479                                 if(fss->guiDisplayMode==0) fss->guiDisplayMode=2; // default drops
2480                                 uiDefBut(block, LABEL,   0, "Part.-Type:",               0,yline,100,objHeight, NULL, 0.0, 0, 0, 0, "");
2481                                 // TODO make toggle buttons
2482                                 //uiDefButS(block, MENU, B_FLUIDSIM_FORCEREDRAW, "Gui%t|Bubble %x2|Drop %x4|Newparts %x8|Float %x16",   
2483                                                  //100,yline,200,objHeight, &fss->guiDisplayMode, 0, 0, 0, 0, "Which type of particles to display.");
2484                                 //uiDefButS(block, MENU, B_DIFF, "Render%t|Geometry %x1|Preview %x2|Final %x3", 
2485                                                 //195,yline,105,objHeight, &fss->renderDisplayMode, 0, 0, 0, 0, "How to display the fluid mesh for rendering.");
2486                                 uiDefBut(block, LABEL,   0, "Drops",    100,yline,200,objHeight, NULL, 0.0, 0, 0, 0, "");
2487                                 fss->guiDisplayMode = 4; // fix to drops for now
2488                                 yline -= lineHeight;
2489
2490                                 uiDefBut(block, LABEL, 0, "Size Influence:",            0,yline,150,objHeight, NULL, 0.0, 0, 0, 0, "");
2491                                 uiDefButF(block, NUM, B_DIFF, "", 150, yline,150,objHeight, &fss->particleInfSize, 0.0, 2.0,   10,0, "Amount of particle size scaling: 0=off (all same size), 1=full (range 0.2-2.0), >1=stronger.");
2492                                 yline -= lineHeight;
2493                                 uiDefBut(block, LABEL, 0, "Alpha Influence:",           0,yline,150,objHeight, NULL, 0.0, 0, 0, 0, "");
2494                                 uiDefButF(block, NUM, B_DIFF, "", 150, yline,150,objHeight, &fss->particleInfAlpha, 0.0, 2.0,   10,0, "Amount of particle alpha change, inverse of size influence: 0=off (all same alpha), 1=full (large particles get lower alphas, smaller ones higher values).");
2495                                 yline -= lineHeight;
2496
2497                                 yline -= 1*separateHeight;
2498
2499                                 // FSPARTICLE also select input files
2500                                 uiDefIconBut(block, BUT, B_FLUIDSIM_SELDIR, ICON_FILESEL,  0, yline,  20, objHeight,                   0, 0, 0, 0, 0,  "Select Directory (and/or filename prefix) to store baked fluid simulation files in");
2501                                 uiDefBut(block, TEX,     B_FLUIDSIM_FORCEREDRAW,"",           20, yline, 280, objHeight, fss->surfdataPath, 0.0,79.0, 0, 0,  "Enter Directory (and/or filename prefix) to store baked fluid simulation files in");
2502                                 yline -= lineHeight;
2503
2504
2505                         }
2506                         else {
2507                                 yline -= lineHeight + 5;
2508                                 /* not yet set */
2509                                 uiDefBut(block, LABEL, 0, "Select object type for simulation",          0,yline,300,objHeight, NULL, 0.0, 0, 0, 0, "");
2510                                 yline -= lineHeight;
2511                         }
2512
2513                 } else {
2514                         yline -= lineHeight + 5;
2515                         uiDefBut(block, LABEL, 0, "Object not enabled for fluid simulation...", 0,yline,300,objHeight, NULL, 0.0, 0, 0, 0, "");
2516                         yline -= lineHeight;
2517                 }
2518         } else {
2519                 yline -= lineHeight + 5;
2520                 uiDefBut(block, LABEL, 0, "Only Mesh Objects can participate", 0,yline,300,objHeight, NULL, 0.0, 0, 0, 0, "");
2521                 yline -= lineHeight;
2522         }
2523 }
2524
2525 void object_panels()
2526 {
2527         Object *ob;
2528
2529         /* check context here */
2530         ob= OBACT;
2531         if(ob) {
2532                 object_panel_object(ob);
2533                 object_panel_anim(ob);
2534                 object_panel_draw(ob);
2535                 object_panel_constraint("Object");
2536
2537                 uiClearButLock();
2538         }
2539 }
2540
2541 void physics_panels()
2542 {
2543         Object *ob;
2544         
2545         /* check context here */
2546         ob= OBACT;
2547         if(ob) {
2548                 object_panel_fields(ob);
2549                 object_panel_particles(ob);
2550                 object_panel_particles_motion(ob);
2551                 object_softbodies(ob);
2552                 object_panel_fluidsim(ob);
2553         }
2554 }
2555