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