~diresu/blender/blender-command-port

« back to all changes in this revision

Viewing changes to source/blender/src/buttons_object.c

  • Committer: theeth
  • Date: 2008-10-14 16:52:04 UTC
  • Revision ID: vcs-imports@canonical.com-20081014165204-r32w2gm6s0osvdhn
copy back trunk

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/**
 
2
 * $Id: buttons_object.c 17004 2008-10-10 05:32:04Z erwin $
 
3
 *
 
4
 * ***** BEGIN GPL 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.
 
10
 *
 
11
 * This program is distributed in the hope that it will be useful,
 
12
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 
13
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
14
 * GNU General Public License for more details.
 
15
 *
 
16
 * You should have received a copy of the GNU General Public License
 
17
 * along with this program; if not, write to the Free Software Foundation,
 
18
 * Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 
19
 *
 
20
 * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
 
21
 * All rights reserved.
 
22
 *
 
23
 * The Original Code is: all of this file.
 
24
 *
 
25
 * Contributor(s): none yet.
 
26
 *
 
27
 * ***** END GPL LICENSE BLOCK *****
 
28
 */
 
29
 
 
30
#include <time.h>
 
31
#include <math.h>
 
32
#include <stdlib.h>
 
33
#include <string.h>
 
34
 
 
35
#ifdef HAVE_CONFIG_H
 
36
#include <config.h>
 
37
#endif
 
38
 
 
39
#include "MEM_guardedalloc.h"
 
40
 
 
41
#include "DNA_ID.h"
 
42
#include "DNA_screen_types.h"
 
43
#include "DNA_space_types.h"
 
44
#include "DNA_scene_types.h"
 
45
 
 
46
#include "BKE_action.h"
 
47
#include "BKE_cloth.h"
 
48
#include "BKE_fluidsim.h"
 
49
#include "BKE_global.h"
 
50
#include "BKE_main.h"
 
51
#include "BKE_library.h"
 
52
#include "BKE_softbody.h"
 
53
#include "BKE_utildefines.h"
 
54
#include "BKE_particle.h"
 
55
#include "BKE_pointcache.h"
 
56
 
 
57
#include "BLI_blenlib.h"
 
58
#include "BLI_arithb.h"
 
59
 
 
60
#include "BSE_filesel.h"
 
61
#include "BSE_headerbuttons.h"
 
62
 
 
63
#include "BIF_butspace.h"
 
64
#include "BIF_editaction.h"
 
65
#include "BIF_editparticle.h"
 
66
#include "BIF_gl.h"
 
67
#include "BIF_glutil.h"
 
68
#include "BIF_graphics.h"
 
69
#include "BIF_interface.h"
 
70
#include "BIF_keyframing.h"
 
71
#include "BIF_keyval.h"
 
72
#include "BIF_mainqueue.h"
 
73
#include "BIF_mywindow.h"
 
74
#include "BIF_poseobject.h"
 
75
#include "BIF_resources.h"
 
76
#include "BIF_screen.h"
 
77
#include "BIF_space.h"
 
78
#include "BIF_toolbox.h"
 
79
#include "BIF_outliner.h"
 
80
 
 
81
#include "BDR_drawobject.h"
 
82
#include "BDR_editcurve.h"
 
83
 
 
84
#include "mydevice.h"
 
85
#include "blendef.h"
 
86
 
 
87
/* -----includes for this file specific----- */
 
88
 
 
89
 
 
90
#include "DNA_action_types.h"
 
91
#include "DNA_armature_types.h"
 
92
#include "DNA_camera_types.h"
 
93
#include "DNA_cloth_types.h"
 
94
#include "DNA_constraint_types.h"
 
95
#include "DNA_curve_types.h"
 
96
#include "DNA_effect_types.h"
 
97
#include "DNA_group_types.h"
 
98
#include "DNA_image_types.h"
 
99
#include "DNA_key_types.h"
 
100
#include "DNA_lamp_types.h"
 
101
#include "DNA_lattice_types.h"
 
102
#include "DNA_material_types.h"
 
103
#include "DNA_meta_types.h"
 
104
#include "DNA_mesh_types.h"
 
105
#include "DNA_modifier_types.h"
 
106
#include "DNA_object_types.h"
 
107
#include "DNA_object_force.h"
 
108
#include "DNA_object_fluidsim.h"
 
109
#include "DNA_particle_types.h"
 
110
#include "DNA_radio_types.h"
 
111
#include "DNA_screen_types.h"
 
112
#include "DNA_sound_types.h"
 
113
#include "DNA_texture_types.h"
 
114
#include "DNA_userdef_types.h"
 
115
#include "DNA_vfont_types.h"
 
116
#include "DNA_view3d_types.h"
 
117
#include "DNA_world_types.h"
 
118
#include "DNA_text_types.h"
 
119
 
 
120
#include "BKE_anim.h"
 
121
#include "BKE_armature.h"
 
122
#include "BKE_constraint.h"
 
123
#include "BKE_curve.h"
 
124
#include "BKE_deform.h"
 
125
#include "BKE_depsgraph.h"
 
126
#include "BKE_displist.h"
 
127
#include "BKE_effect.h"
 
128
#include "BKE_font.h"
 
129
#include "BKE_group.h"
 
130
#include "BKE_image.h"
 
131
#include "BKE_ipo.h"
 
132
#include "BKE_lattice.h"
 
133
#include "BKE_material.h"
 
134
#include "BKE_mball.h"
 
135
#include "BKE_mesh.h"
 
136
#include "BKE_modifier.h"
 
137
#include "BKE_object.h"
 
138
#include "BKE_particle.h"
 
139
#include "BKE_sound.h"
 
140
#include "BKE_texture.h"
 
141
#include "BKE_utildefines.h"
 
142
#include "BKE_DerivedMesh.h"
 
143
 
 
144
#include "LBM_fluidsim.h"
 
145
#include "elbeem.h"
 
146
 
 
147
#include "BIF_editconstraint.h"
 
148
#include "BIF_editdeform.h"
 
149
#include "BIF_editparticle.h"
 
150
 
 
151
#include "BSE_editipo.h"
 
152
#include "BSE_edit.h"
 
153
 
 
154
#include "BDR_editobject.h"
 
155
#include "BPY_extern.h"
 
156
 
 
157
#include "butspace.h" // own module
 
158
 
 
159
static float prspeed=0.0;
 
160
float prlen=0.0;
 
161
 
 
162
 
 
163
/* ********************* CONSTRAINT ***************************** */
 
164
 
 
165
static void constraint_active_func(void *ob_v, void *con_v)
 
166
{
 
167
        Object *ob= ob_v;
 
168
        bConstraint *con;
 
169
        ListBase *lb;
 
170
        
 
171
        /* lets be nice and escape if its active already */
 
172
        if(con_v) {
 
173
                con= con_v;
 
174
                if(con->flag & CONSTRAINT_ACTIVE) return;
 
175
        }
 
176
        
 
177
        lb= get_active_constraints(ob);
 
178
        if (lb == NULL) return;
 
179
        
 
180
        for(con= lb->first; con; con= con->next) {
 
181
                if(con==con_v) con->flag |= CONSTRAINT_ACTIVE;
 
182
                else con->flag &= ~CONSTRAINT_ACTIVE;
 
183
        }
 
184
 
 
185
        /* make sure ipowin and buttons shows it */
 
186
        if(ob->ipowin==ID_CO) {
 
187
                allqueue(REDRAWIPO, ID_CO);
 
188
                allspace(REMAKEIPO, 0);
 
189
                allqueue(REDRAWNLA, 0);
 
190
        }
 
191
        allqueue(REDRAWBUTSOBJECT, 0);
 
192
}
 
193
 
 
194
static void add_constraint_to_active(Object *ob, bConstraint *con)
 
195
{
 
196
        ListBase *list= get_active_constraints(ob);
 
197
        bPoseChannel *pchan= get_active_posechannel(ob);
 
198
        
 
199
        if (list) {
 
200
                unique_constraint_name(con, list);
 
201
                BLI_addtail(list, con);
 
202
                
 
203
                if (proxylocked_constraints_owner(ob, pchan))
 
204
                        con->flag |= CONSTRAINT_PROXY_LOCAL;
 
205
                
 
206
                con->flag |= CONSTRAINT_ACTIVE;
 
207
                for (con= con->prev; con; con= con->prev)
 
208
                        con->flag &= ~CONSTRAINT_ACTIVE;
 
209
        }
 
210
}
 
211
 
 
212
/* returns base ID for Ipo, sets actname to channel if appropriate */
 
213
/* should not make action... */
 
214
static void get_constraint_ipo_context(void *ob_v, char *actname)
 
215
{
 
216
        Object *ob= ob_v;
 
217
        
 
218
        /* todo: check object if it has ob-level action ipo */
 
219
        if (ob->flag & OB_POSEMODE) {
 
220
                bPoseChannel *pchan;
 
221
                
 
222
                pchan = get_active_posechannel(ob);
 
223
                if (pchan) {
 
224
                        BLI_strncpy(actname, pchan->name, 32);
 
225
                }
 
226
        }
 
227
        else if(ob->ipoflag & OB_ACTION_OB)
 
228
                strcpy(actname, "Object");
 
229
}       
 
230
 
 
231
/* initialize UI to show Ipo window and make sure channels etc exist */
 
232
static void enable_constraint_ipo_func (void *ob_v, void *con_v)
 
233
{
 
234
        Object *ob= ob_v;
 
235
        bConstraint *con = con_v;
 
236
        char actname[32]="";
 
237
        
 
238
        /* verifies if active constraint is set and shown in UI */
 
239
        constraint_active_func(ob_v, con_v);
 
240
        
 
241
        /* the context */
 
242
        get_constraint_ipo_context(ob, actname);
 
243
        
 
244
        /* adds ipo & channels & curve if needed */
 
245
        if(con->flag & CONSTRAINT_OWN_IPO)
 
246
                verify_ipo((ID *)ob, ID_CO, NULL, con->name, actname, 1);
 
247
        else
 
248
                verify_ipo((ID *)ob, ID_CO, actname, con->name, NULL, 1);
 
249
                
 
250
        /* make sure ipowin shows it */
 
251
        ob->ipowin= ID_CO;
 
252
        allqueue(REDRAWIPO, ID_CO);
 
253
        allspace(REMAKEIPO, 0);
 
254
        allqueue(REDRAWNLA, 0);
 
255
}
 
256
 
 
257
 
 
258
static void add_influence_key_to_constraint_func (void *ob_v, void *con_v)
 
259
{
 
260
        Object *ob= ob_v;
 
261
        bConstraint *con = con_v;
 
262
        IpoCurve *icu;
 
263
        char actname[32]="";
 
264
        
 
265
        /* verifies if active constraint is set and shown in UI */
 
266
        constraint_active_func(ob_v, con_v);
 
267
        
 
268
        /* the context */
 
269
        get_constraint_ipo_context(ob, actname);
 
270
 
 
271
        /* adds ipo & channels & curve if needed */
 
272
        if(con->flag & CONSTRAINT_OWN_IPO)
 
273
                icu= verify_ipocurve((ID *)ob, ID_CO, NULL, con->name, actname, CO_ENFORCE, 1);
 
274
        else
 
275
                icu= verify_ipocurve((ID *)ob, ID_CO, actname, con->name, NULL, CO_ENFORCE, 1);
 
276
                
 
277
        if (!icu) {
 
278
                error("Cannot get a curve from this IPO, may be dealing with linked data");
 
279
                return;
 
280
        }
 
281
        
 
282
        if(ob->action)
 
283
                insert_vert_icu(icu, get_action_frame(ob, (float)CFRA), con->enforce, 0);
 
284
        else
 
285
                insert_vert_icu(icu, CFRA, con->enforce, 0);
 
286
        
 
287
        /* make sure ipowin shows it */
 
288
        ob->ipowin= ID_CO;
 
289
        allqueue(REDRAWIPO, ID_CO);
 
290
        allspace(REMAKEIPO, 0);
 
291
        allqueue(REDRAWNLA, 0);
 
292
        
 
293
        BIF_undo_push("Insert Influence Key");
 
294
}
 
295
 
 
296
void del_constr_func (void *ob_v, void *con_v)
 
297
{
 
298
        bConstraint *con= con_v;
 
299
        bConstraintChannel *chan;
 
300
        ListBase *lb;
 
301
        
 
302
        /* remove ipo channel */
 
303
        lb= get_active_constraint_channels(ob_v, 0);
 
304
        if(lb) {
 
305
                chan = get_constraint_channel(lb, con->name);
 
306
                if(chan) {
 
307
                        if(chan->ipo) chan->ipo->id.us--;
 
308
                        BLI_freelinkN(lb, chan);
 
309
                }
 
310
        }
 
311
        /* remove constraint itself */
 
312
        lb= get_active_constraints(ob_v);
 
313
        free_constraint_data(con);
 
314
        BLI_freelinkN(lb, con);
 
315
        
 
316
        constraint_active_func(ob_v, NULL);
 
317
}
 
318
 
 
319
static void del_constraint_func (void *ob_v, void *con_v)
 
320
{
 
321
        del_constr_func (ob_v, con_v);
 
322
        BIF_undo_push("Delete constraint");
 
323
        allqueue(REDRAWBUTSOBJECT, 0);
 
324
        allqueue(REDRAWIPO, 0); 
 
325
}
 
326
 
 
327
static void verify_constraint_name_func (void *con_v, void *name_v)
 
328
{
 
329
        Object *ob= OBACT;
 
330
        bConstraint *con= con_v;
 
331
        char oldname[32];       
 
332
        
 
333
        if (!con)
 
334
                return;
 
335
        
 
336
        /* put on the stack */
 
337
        BLI_strncpy(oldname, (char *)name_v, 32);
 
338
        
 
339
        rename_constraint(ob, con, oldname);
 
340
        
 
341
        constraint_active_func(ob, con);
 
342
        allqueue(REDRAWACTION, 0); 
 
343
}
 
344
 
 
345
void const_moveUp(void *ob_v, void *con_v)
 
346
{
 
347
        bConstraint *con, *constr= con_v;
 
348
        ListBase *conlist;
 
349
        
 
350
        if(constr->prev) {
 
351
                conlist = get_active_constraints(ob_v);
 
352
                for(con= conlist->first; con; con= con->next) {
 
353
                        if(con==constr) {
 
354
                                BLI_remlink(conlist, con);
 
355
                                BLI_insertlink(conlist, con->prev->prev, con);
 
356
                                break;
 
357
                        }
 
358
                }
 
359
        }
 
360
}
 
361
 
 
362
static void constraint_moveUp(void *ob_v, void *con_v)
 
363
{
 
364
        const_moveUp(ob_v, con_v);
 
365
        BIF_undo_push("Move constraint");
 
366
}
 
367
 
 
368
void const_moveDown(void *ob_v, void *con_v)
 
369
{
 
370
        bConstraint *con, *constr= con_v;
 
371
        ListBase *conlist;
 
372
        
 
373
        if(constr->next) {
 
374
                conlist = get_active_constraints(ob_v);
 
375
                for(con= conlist->first; con; con= con->next) {
 
376
                        if(con==constr) {
 
377
                                BLI_remlink(conlist, con);
 
378
                                BLI_insertlink(conlist, con->next, con);
 
379
                                break;
 
380
                        }
 
381
                }
 
382
        }
 
383
}
 
384
 
 
385
static void constraint_moveDown(void *ob_v, void *con_v)
 
386
{
 
387
        const_moveDown(ob_v, con_v);
 
388
        BIF_undo_push("Move constraint");
 
389
}
 
390
 
 
391
/* autocomplete callback for  buttons */
 
392
void autocomplete_bone(char *str, void *arg_v)
 
393
{
 
394
        Object *ob= (Object *)arg_v;
 
395
        
 
396
        if(ob==NULL || ob->pose==NULL) return;
 
397
        
 
398
        /* search if str matches the beginning of name */
 
399
        if(str[0]) {
 
400
                AutoComplete *autocpl= autocomplete_begin(str, 32);
 
401
                bPoseChannel *pchan;
 
402
                
 
403
                for(pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next)
 
404
                        autocomplete_do_name(autocpl, pchan->name);
 
405
 
 
406
                autocomplete_end(autocpl, str);
 
407
        }
 
408
}
 
409
 
 
410
/* autocomplete callback for buttons */
 
411
void autocomplete_vgroup(char *str, void *arg_v)
 
412
{
 
413
        Object *ob= (Object *)arg_v;
 
414
        
 
415
        if(ob==NULL) return;
 
416
        
 
417
        /* search if str matches the beginning of a name */
 
418
        if(str[0]) {
 
419
                AutoComplete *autocpl= autocomplete_begin(str, 32);
 
420
                bDeformGroup *dg;
 
421
                
 
422
                for(dg= ob->defbase.first; dg; dg= dg->next)
 
423
                        if(dg->name!=str)
 
424
                                autocomplete_do_name(autocpl, dg->name);
 
425
 
 
426
                autocomplete_end(autocpl, str);
 
427
        }
 
428
}
 
429
 
 
430
/* pole angle callback */
 
431
void con_kinematic_set_pole_angle(void *ob_v, void *con_v)
 
432
{
 
433
        bConstraint *con= con_v;
 
434
        bKinematicConstraint *data = con->data;
 
435
 
 
436
        if(data->poletar) {
 
437
                if(data->flag & CONSTRAINT_IK_SETANGLE) {
 
438
                        data->flag |= CONSTRAINT_IK_GETANGLE;
 
439
                        data->flag &= ~CONSTRAINT_IK_SETANGLE;
 
440
                }
 
441
                else {
 
442
                        data->flag &= ~CONSTRAINT_IK_GETANGLE;
 
443
                        data->flag |= CONSTRAINT_IK_SETANGLE;
 
444
                }
 
445
        }
 
446
}
 
447
 
 
448
/* some commonly used macros in the constraints drawing code */
 
449
#define is_armature_target(target) (target && target->type==OB_ARMATURE)
 
450
#define is_armature_owner(ob) ((ob->type == OB_ARMATURE) && (ob->flag & OB_POSEMODE))
 
451
#define is_geom_target(target) (target && (ELEM(target->type, OB_MESH, OB_LATTICE)) )
 
452
 
 
453
/* Helper function for draw constraint - draws constraint space stuff 
 
454
 * This function should not be called if no menus are required 
 
455
 * owner/target: -1 = don't draw menu; 0= not posemode, 1 = posemode 
 
456
 */
 
457
static void draw_constraint_spaceselect (uiBlock *block, bConstraint *con, short xco, short yco, short owner, short target)
 
458
{
 
459
        short tarx, ownx;
 
460
        short bwidth;
 
461
        
 
462
        /* calculate sizes and placement of menus */
 
463
        if (owner == -1) {
 
464
                bwidth = 125;
 
465
                tarx = 120;
 
466
                ownx = 0;
 
467
        }
 
468
        else if (target == -1) {
 
469
                bwidth = 125;
 
470
                tarx = 0;
 
471
                ownx = 120;
 
472
        }
 
473
        else {
 
474
                bwidth = 100;
 
475
                tarx = 95;
 
476
                ownx = tarx + bwidth;
 
477
        }
 
478
        
 
479
        
 
480
        uiDefBut(block, LABEL, B_CONSTRAINT_TEST, "CSpace:", xco, yco, 80,18, NULL, 0.0, 0.0, 0.0, 0.0, ""); 
 
481
        
 
482
        uiBlockBeginAlign(block);
 
483
        
 
484
        /* Target-Space */
 
485
        if (target == 1) {
 
486
                uiDefButC(block, MENU, B_CONSTRAINT_TEST, "Target Space %t|World Space %x0|Pose Space %x2|Local with Parent %x3|Local Space %x1", 
 
487
                                                                                                tarx, yco, bwidth, 18, &con->tarspace, 0, 0, 0, 0, "Choose space that target is evaluated in"); 
 
488
        }
 
489
        else if (target == 0) {
 
490
                uiDefButC(block, MENU, B_CONSTRAINT_TEST, "Target Space %t|World Space %x0|Local (Without Parent) Space %x1", 
 
491
                                                                                tarx, yco, bwidth, 18, &con->tarspace, 0, 0, 0, 0, "Choose space that target is evaluated in"); 
 
492
        }
 
493
        
 
494
        /* Owner-Space */
 
495
        if (owner == 1) {
 
496
                uiDefButC(block, MENU, B_CONSTRAINT_TEST, "Owner Space %t|World Space %x0|Pose Space %x2|Local with Parent %x3|Local Space %x1", 
 
497
                                                                                                ownx, yco, bwidth, 18, &con->ownspace, 0, 0, 0, 0, "Choose space that owner is evaluated in");  
 
498
        }
 
499
        else if (owner == 0) {
 
500
                uiDefButC(block, MENU, B_CONSTRAINT_TEST, "Owner Space %t|World Space %x0|Local (Without Parent) Space %x1", 
 
501
                                                                                ownx, yco, bwidth, 18, &con->ownspace, 0, 0, 0, 0, "Choose space that owner is evaluated in");  
 
502
        }
 
503
        
 
504
        uiBlockEndAlign(block);
 
505
}
 
506
 
 
507
/* draw panel showing settings for a constraint */
 
508
static void draw_constraint (uiBlock *block, ListBase *list, bConstraint *con, short *xco, short *yco)
 
509
{
 
510
        Object *ob= OBACT;
 
511
        bPoseChannel *pchan= get_active_posechannel(ob);
 
512
        bConstraintTypeInfo *cti;
 
513
        uiBut *but;
 
514
        char typestr[32];
 
515
        short height, width = 265;
 
516
        short proxy_protected;
 
517
        int rb_col;
 
518
 
 
519
        /* get constraint typeinfo */
 
520
        cti= constraint_get_typeinfo(con);
 
521
        if (cti == NULL) {
 
522
                /* exception for 'Null' constraint - it doesn't have constraint typeinfo! */
 
523
                if (con->type == CONSTRAINT_TYPE_NULL)
 
524
                        strcpy(typestr, "Null");
 
525
                else
 
526
                        strcpy(typestr, "Unknown");
 
527
        }
 
528
        else
 
529
                strcpy(typestr, cti->name);
 
530
                
 
531
        /* determine whether constraint is proxy protected or not */
 
532
        if (proxylocked_constraints_owner(ob, pchan)) {
 
533
                proxy_protected= (con->flag & CONSTRAINT_PROXY_LOCAL) ? 0 : 1;
 
534
        }
 
535
        else
 
536
                proxy_protected= 0;
 
537
                
 
538
        /* unless button has own callback, it adds this callback to button */
 
539
        uiBlockSetFunc(block, constraint_active_func, ob, con);
 
540
 
 
541
        /* Draw constraint header */
 
542
        uiBlockSetEmboss(block, UI_EMBOSSN);
 
543
        
 
544
        /* rounded header */
 
545
        rb_col= (con->flag & CONSTRAINT_ACTIVE)?50:20;
 
546
        uiDefBut(block, ROUNDBOX, B_DIFF, "", *xco-10, *yco-1, width+40, 22, NULL, 5.0, 0.0, 
 
547
                         (con->flag & CONSTRAINT_EXPAND)?3:15 , rb_col-20, ""); 
 
548
        
 
549
        /* open/close */
 
550
        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");
 
551
        
 
552
        /* name */      
 
553
        if ((con->flag & CONSTRAINT_EXPAND) && (proxy_protected==0)) {
 
554
                if (con->flag & CONSTRAINT_DISABLE)
 
555
                        uiBlockSetCol(block, TH_REDALERT);
 
556
                
 
557
                uiBlockSetEmboss(block, UI_EMBOSS);
 
558
                
 
559
                uiDefBut(block, LABEL, B_CONSTRAINT_TEST, typestr, *xco+10, *yco, 100, 18, NULL, 0.0, 0.0, 0.0, 0.0, ""); 
 
560
                
 
561
                but = uiDefBut(block, TEX, B_CONSTRAINT_TEST, "", *xco+120, *yco, 85, 18, con->name, 0.0, 29.0, 0.0, 0.0, "Constraint name"); 
 
562
                uiButSetFunc(but, verify_constraint_name_func, con, NULL);
 
563
        }       
 
564
        else {
 
565
                uiBlockSetEmboss(block, UI_EMBOSSN);
 
566
                
 
567
                if (con->flag & CONSTRAINT_DISABLE)
 
568
                        uiBlockSetCol(block, TH_REDALERT);
 
569
                
 
570
                uiDefBut(block, LABEL, B_CONSTRAINT_TEST, typestr, *xco+10, *yco, 100, 18, NULL, 0.0, 0.0, 0.0, 0.0, ""); 
 
571
                
 
572
                uiDefBut(block, LABEL, B_CONSTRAINT_TEST, con->name, *xco+120, *yco-1, 135, 19, NULL, 0.0, 0.0, 0.0, 0.0, ""); 
 
573
        }
 
574
 
 
575
        uiBlockSetCol(block, TH_AUTO);  
 
576
        
 
577
        /* proxy-protected constraints cannot be edited, so hide up/down + close buttons */
 
578
        if (proxy_protected) {
 
579
                uiBlockSetEmboss(block, UI_EMBOSSN);
 
580
                
 
581
                /* draw a ghost icon (for proxy) and also a lock beside it, to show that constraint is "proxy locked" */
 
582
                uiDefIconBut(block, BUT, B_CONSTRAINT_TEST, ICON_GHOST, *xco+244, *yco, 19, 19, NULL, 0.0, 0.0, 0.0, 0.0, "Proxy Protected");
 
583
                uiDefIconBut(block, BUT, B_CONSTRAINT_TEST, ICON_LOCKED, *xco+262, *yco, 19, 19, NULL, 0.0, 0.0, 0.0, 0.0, "Proxy Protected");
 
584
                
 
585
                uiBlockSetEmboss(block, UI_EMBOSS);
 
586
        }
 
587
        else {
 
588
                short prev_proxylock, show_upbut, show_downbut;
 
589
                
 
590
                /* Up/Down buttons: 
 
591
                 *      Proxy-constraints are not allowed to occur after local (non-proxy) constraints
 
592
                 *      as that poses problems when restoring them, so disable the "up" button where
 
593
                 *      it may cause this situation. 
 
594
                 *
 
595
                 *      Up/Down buttons should only be shown (or not greyed - todo) if they serve some purpose. 
 
596
                 */
 
597
                if (proxylocked_constraints_owner(ob, pchan)) {
 
598
                        if (con->prev) {
 
599
                                prev_proxylock= (con->prev->flag & CONSTRAINT_PROXY_LOCAL) ? 0 : 1;
 
600
                        }
 
601
                        else
 
602
                                prev_proxylock= 0;
 
603
                }
 
604
                else
 
605
                        prev_proxylock= 0;
 
606
                        
 
607
                show_upbut= ((prev_proxylock == 0) && (con->prev));
 
608
                show_downbut= (con->next) ? 1 : 0;
 
609
                
 
610
                if (show_upbut || show_downbut) {
 
611
                        uiBlockBeginAlign(block);
 
612
                                uiBlockSetEmboss(block, UI_EMBOSS);
 
613
                                
 
614
                                if (show_upbut) {
 
615
                                        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 constraint up in constraint stack");
 
616
                                        uiButSetFunc(but, constraint_moveUp, ob, con);
 
617
                                }
 
618
                                
 
619
                                if (show_downbut) {
 
620
                                        but = uiDefIconBut(block, BUT, B_CONSTRAINT_TEST, VICON_MOVE_DOWN, *xco+width-50+18, *yco, 16, 18, NULL, 0.0, 0.0, 0.0, 0.0, "Move constraint down in constraint stack");
 
621
                                        uiButSetFunc(but, constraint_moveDown, ob, con);
 
622
                                }
 
623
                        uiBlockEndAlign(block);
 
624
                }
 
625
                
 
626
                
 
627
                /* Close 'button' - emboss calls here disable drawing of 'button' behind X */
 
628
                uiBlockSetEmboss(block, UI_EMBOSSN);
 
629
                
 
630
                        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");
 
631
                        uiButSetFunc(but, del_constraint_func, ob, con);
 
632
                
 
633
                uiBlockSetEmboss(block, UI_EMBOSS);
 
634
        }
 
635
        
 
636
        /* Set but-locks for protected settings (magic numbers are used here!) */
 
637
        if (proxy_protected)
 
638
                uiSetButLock(1, "Cannot edit Proxy-Protected Constraint");
 
639
        
 
640
        /* Draw constraint data */
 
641
        if ((con->flag & CONSTRAINT_EXPAND) == 0) {
 
642
                (*yco) -= 21;
 
643
        }
 
644
        else {
 
645
                switch (con->type) {
 
646
                case CONSTRAINT_TYPE_PYTHON:
 
647
                        {
 
648
                                bPythonConstraint *data = con->data;
 
649
                                bConstraintTarget *ct;
 
650
                                uiBut *but2;
 
651
                                int tarnum, theight;
 
652
                                static int pyconindex=0;
 
653
                                char *menustr;
 
654
                                
 
655
                                theight = (data->tarnum)? (data->tarnum * 38) : (38);
 
656
                                height = theight + 78;
 
657
                                uiDefBut(block, ROUNDBOX, B_DIFF, "", *xco-10, *yco-height, width+40, height-1, NULL, 5.0, 0.0, 12, rb_col, ""); 
 
658
                                
 
659
                                uiDefBut(block, LABEL, B_CONSTRAINT_TEST, "Script:", *xco+60, *yco-24, 55, 18, NULL, 0.0, 0.0, 0.0, 0.0, ""); 
 
660
                                
 
661
                                /* do the scripts menu */
 
662
                                menustr = buildmenu_pyconstraints(data->text, &pyconindex);
 
663
                                but2 = uiDefButI(block, MENU, B_CONSTRAINT_TEST, menustr,
 
664
                                      *xco+120, *yco-24, 150, 20, &pyconindex,
 
665
                                      0, 0, 0, 0, "Set the Script Constraint to use");
 
666
                                uiButSetFunc(but2, validate_pyconstraint_cb, data, &pyconindex);
 
667
                                MEM_freeN(menustr);     
 
668
                                
 
669
                                /* draw target(s) */
 
670
                                if (data->flag & PYCON_USETARGETS) {
 
671
                                        /* Draw target parameters */ 
 
672
                                        for (ct=data->targets.first, tarnum=1; ct; ct=ct->next, tarnum++) {
 
673
                                                char tarstr[32];
 
674
                                                short yoffset= ((tarnum-1) * 38);
 
675
                                                
 
676
                                                /* target label */
 
677
                                                sprintf(tarstr, "Target %d:", tarnum);
 
678
                                                uiDefBut(block, LABEL, B_CONSTRAINT_TEST, tarstr, *xco+45, *yco-(48+yoffset), 100, 18, NULL, 0.0, 0.0, 0.0, 0.0, ""); 
 
679
                                                
 
680
                                                /* target space-selector - per target */
 
681
                                                if (is_armature_target(ct->tar)) {
 
682
                                                        uiDefButS(block, MENU, B_CONSTRAINT_TEST, "Target Space %t|World Space %x0|Pose Space %x3|Local with Parent %x4|Local Space %x1", 
 
683
                                                                                                                        *xco+10, *yco-(66+yoffset), 100, 18, &ct->space, 0, 0, 0, 0, "Choose space that target is evaluated in");       
 
684
                                                }
 
685
                                                else {
 
686
                                                        uiDefButS(block, MENU, B_CONSTRAINT_TEST, "Target Space %t|World Space %x0|Local (Without Parent) Space %x1", 
 
687
                                                                                                                        *xco+10, *yco-(66+yoffset), 100, 18, &ct->space, 0, 0, 0, 0, "Choose space that target is evaluated in");       
 
688
                                                }
 
689
                                                
 
690
                                                uiBlockBeginAlign(block);
 
691
                                                        /* target object */
 
692
                                                        uiDefIDPoinBut(block, test_obpoin_but, ID_OB, B_CONSTRAINT_CHANGETARGET, "OB:", *xco+120, *yco-(48+yoffset), 150, 18, &ct->tar, "Target Object"); 
 
693
                                                        
 
694
                                                        /* subtarget */
 
695
                                                        if (is_armature_target(ct->tar)) {
 
696
                                                                but= uiDefBut(block, TEX, B_CONSTRAINT_CHANGETARGET, "BO:", *xco+120, *yco-(66+yoffset),150,18, &ct->subtarget, 0, 24, 0, 0, "Subtarget Bone");
 
697
                                                                uiButSetCompleteFunc(but, autocomplete_bone, (void *)ct->tar);
 
698
                                                        }
 
699
                                                        else if (is_geom_target(ct->tar)) {
 
700
                                                                but= uiDefBut(block, TEX, B_CONSTRAINT_CHANGETARGET, "VG:", *xco+120, *yco-(66+yoffset),150,18, &ct->subtarget, 0, 24, 0, 0, "Name of Vertex Group defining 'target' points");
 
701
                                                                uiButSetCompleteFunc(but, autocomplete_vgroup, (void *)ct->tar);
 
702
                                                        }
 
703
                                                        else {
 
704
                                                                strcpy(ct->subtarget, "");
 
705
                                                        }
 
706
                                                uiBlockEndAlign(block);
 
707
                                        }
 
708
                                }
 
709
                                else {
 
710
                                        /* Draw indication that no target needed */
 
711
                                        uiDefBut(block, LABEL, B_CONSTRAINT_TEST, "Target:", *xco+60, *yco-48, 55, 18, NULL, 0.0, 0.0, 0.0, 0.0, ""); 
 
712
                                        uiDefBut(block, LABEL, B_CONSTRAINT_TEST, "Not Applicable", *xco+120, *yco-48, 150, 18, NULL, 0.0, 0.0, 0.0, 0.0, ""); 
 
713
                                }
 
714
                                
 
715
                                /* settings */
 
716
                                uiBlockBeginAlign(block);
 
717
                                        but=uiDefBut(block, BUT, B_CONSTRAINT_TEST, "Options", *xco, *yco-(52+theight), (width/2),18, NULL, 0, 24, 0, 0, "Change some of the constraint's settings.");
 
718
                                        uiButSetFunc(but, BPY_pyconstraint_settings, data, NULL);
 
719
                                        
 
720
                                        but=uiDefBut(block, BUT, B_CONSTRAINT_TEST, "Refresh", *xco+((width/2)+10), *yco-(52+theight), (width/2),18, NULL, 0, 24, 0, 0, "Force constraint to refresh it's settings");
 
721
                                uiBlockEndAlign(block);
 
722
                                
 
723
                                /* constraint space settings */
 
724
                                draw_constraint_spaceselect(block, con, *xco, *yco-(73+theight), is_armature_owner(ob), -1);
 
725
                        }
 
726
                        break;
 
727
                case CONSTRAINT_TYPE_ACTION:
 
728
                        {
 
729
                                bActionConstraint *data = con->data;
 
730
                                float minval, maxval;
 
731
                                
 
732
                                height = 108;
 
733
                                uiDefBut(block, ROUNDBOX, B_DIFF, "", *xco-10, *yco-height, width+40,height-1, NULL, 5.0, 0.0, 12, rb_col, ""); 
 
734
                                
 
735
                                uiDefBut(block, LABEL, B_CONSTRAINT_TEST, "Target:", *xco+65, *yco-24, 50, 18, NULL, 0.0, 0.0, 0.0, 0.0, ""); 
 
736
                                
 
737
                                /* Draw target parameters */
 
738
                                uiBlockBeginAlign(block);
 
739
                                        uiDefIDPoinBut(block, test_obpoin_but, ID_OB, B_CONSTRAINT_CHANGETARGET, "OB:", *xco+120, *yco-24, 135, 18, &data->tar, "Target Object"); 
 
740
                                        
 
741
                                        if (is_armature_target(data->tar)) {
 
742
                                                but= uiDefBut(block, TEX, B_CONSTRAINT_CHANGETARGET, "BO:", *xco+120, *yco-42,135,18, &data->subtarget, 0, 24, 0, 0, "Subtarget Bone");
 
743
                                                uiButSetCompleteFunc(but, autocomplete_bone, (void *)data->tar);
 
744
                                        }
 
745
                                        else {
 
746
                                                strcpy(data->subtarget, "");
 
747
                                        }
 
748
                                
 
749
                                uiBlockEndAlign(block);
 
750
                                
 
751
                                /* Draw action/type buttons */
 
752
                                uiBlockBeginAlign(block);
 
753
                                        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"); 
 
754
                                        uiDefButS(block, MENU, B_CONSTRAINT_TEST, "Key on%t|Loc X%x20|Loc Y%x21|Loc Z%x22|Rot X%x0|Rot Y%x1|Rot Z%x2|Size X%x10|Size Y%x11|Size Z%x12", *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");
 
755
                                uiBlockEndAlign(block);
 
756
                                
 
757
                                /* Draw start/end frame buttons */
 
758
                                uiBlockBeginAlign(block);
 
759
                                        uiDefButI(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"); 
 
760
                                        uiDefButI(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"); 
 
761
                                uiBlockEndAlign(block);
 
762
                                
 
763
                                /* Draw minimum/maximum transform range buttons */
 
764
                                uiBlockBeginAlign(block);
 
765
                                        if (data->type < 10) { /* rotation */
 
766
                                                minval = -180.0f;
 
767
                                                maxval = 180.0f;
 
768
                                        }
 
769
                                        else if (data->type < 20) { /* scaling */
 
770
                                                minval = 0.0001f;
 
771
                                                maxval = 1000.0f;
 
772
                                        }
 
773
                                        else { /* location */
 
774
                                                minval = -1000.0f;
 
775
                                                maxval = 1000.0f;
 
776
                                        }
 
777
                                        uiDefButF(block, NUM, B_CONSTRAINT_TEST, "Min:", *xco+((width/2)+45), *yco-64, 78, 18, &data->min, minval, maxval, 0, 0, "Minimum value for target channel range");
 
778
                                        uiDefButF(block, NUM, B_CONSTRAINT_TEST, "Max:", *xco+((width/2)+45), *yco-84, 78, 18, &data->max, minval, maxval, 0, 0, "Maximum value for target channel range");
 
779
                                uiBlockEndAlign(block);
 
780
                                
 
781
                                /* constraint space settings */
 
782
                                draw_constraint_spaceselect(block, con, *xco, *yco-104, -1, is_armature_target(data->tar));
 
783
                        }
 
784
                        break;
 
785
                case CONSTRAINT_TYPE_CHILDOF:
 
786
                        {
 
787
                                bChildOfConstraint *data = con->data;
 
788
                                short normButWidth = (width/3);
 
789
                                
 
790
                                height = 165;
 
791
                                uiDefBut(block, ROUNDBOX, B_DIFF, "", *xco-10, *yco-height, width+40,height-1, NULL, 5.0, 0.0, 12, rb_col, ""); 
 
792
                                
 
793
                                uiDefBut(block, LABEL, B_CONSTRAINT_TEST, "Parent:", *xco+65, *yco-24, 50, 18, NULL, 0.0, 0.0, 0.0, 0.0, ""); 
 
794
                                
 
795
                                /* Draw target parameters */
 
796
                                uiBlockBeginAlign(block);
 
797
                                        uiDefIDPoinBut(block, test_obpoin_but, ID_OB, B_CONSTRAINT_CHANGETARGET, "OB:", *xco+120, *yco-24, 135, 18, &data->tar, "Target Object to use as Parent"); 
 
798
                                        
 
799
                                        if (is_armature_target(data->tar)) {
 
800
                                                but= uiDefBut(block, TEX, B_CONSTRAINT_CHANGETARGET, "BO:", *xco+120, *yco-42,135,18, &data->subtarget, 0, 24, 0, 0, "Subtarget Bone to use as Parent");
 
801
                                                uiButSetCompleteFunc(but, autocomplete_bone, (void *)data->tar);
 
802
                                        }
 
803
                                        else if (is_geom_target(data->tar)) {
 
804
                                                but= uiDefBut(block, TEX, B_CONSTRAINT_CHANGETARGET, "VG:", *xco+120, *yco-42,135,18, &data->subtarget, 0, 24, 0, 0, "Name of Vertex Group defining 'target' points");
 
805
                                                uiButSetCompleteFunc(but, autocomplete_vgroup, (void *)data->tar);
 
806
                                        }
 
807
                                        else {
 
808
                                                strcpy(data->subtarget, "");
 
809
                                        }
 
810
                                uiBlockEndAlign(block);
 
811
                                
 
812
                                /* Draw triples of channel toggles */
 
813
                                uiDefBut(block, LABEL, B_CONSTRAINT_TEST, "Use Channel(s):", *xco+65, *yco-64, 150, 18, NULL, 0.0, 0.0, 0.0, 0.0, ""); 
 
814
                                uiBlockBeginAlign(block); 
 
815
                                        uiDefButBitI(block, TOG, CHILDOF_LOCX, B_CONSTRAINT_TEST, "Loc X", *xco, *yco-84, normButWidth, 18, &data->flag, 0, 24, 0, 0, "Parent affects x-location"); 
 
816
                                        uiDefButBitI(block, TOG, CHILDOF_LOCY, B_CONSTRAINT_TEST, "Loc Y", *xco+normButWidth, *yco-84, normButWidth, 18, &data->flag, 0, 24, 0, 0, "Parent affects y-location"); 
 
817
                                        uiDefButBitI(block, TOG, CHILDOF_LOCZ, B_CONSTRAINT_TEST, "Loc Z", *xco+(normButWidth * 2), *yco-84, normButWidth, 18, &data->flag, 0, 24, 0, 0, "Parent affects z-location"); 
 
818
                                uiBlockEndAlign(block); 
 
819
                                
 
820
                                uiBlockBeginAlign(block); 
 
821
                                        uiDefButBitI(block, TOG, CHILDOF_ROTX, B_CONSTRAINT_TEST, "Rot X", *xco, *yco-105, normButWidth, 18, &data->flag, 0, 24, 0, 0, "Parent affects x-rotation"); 
 
822
                                        uiDefButBitI(block, TOG, CHILDOF_ROTY, B_CONSTRAINT_TEST, "Rot Y", *xco+normButWidth, *yco-105, normButWidth, 18, &data->flag, 0, 24, 0, 0, "Parent affects y-rotation"); 
 
823
                                        uiDefButBitI(block, TOG, CHILDOF_ROTZ, B_CONSTRAINT_TEST, "Rot Z", *xco+(normButWidth * 2), *yco-105, normButWidth, 18, &data->flag, 0, 24, 0, 0, "Parent affects z-rotation"); 
 
824
                                uiBlockEndAlign(block); 
 
825
                                
 
826
                                uiBlockBeginAlign(block); 
 
827
                                        uiDefButBitI(block, TOG, CHILDOF_SIZEX, B_CONSTRAINT_TEST, "Scale X", *xco, *yco-126, normButWidth, 18, &data->flag, 0, 24, 0, 0, "Parent affects x-scaling"); 
 
828
                                        uiDefButBitI(block, TOG, CHILDOF_SIZEY, B_CONSTRAINT_TEST, "Scale Y", *xco+normButWidth, *yco-126, normButWidth, 18, &data->flag, 0, 24, 0, 0, "Parent affects y-scaling"); 
 
829
                                        uiDefButBitI(block, TOG, CHILDOF_SIZEZ, B_CONSTRAINT_TEST, "Scale Z", *xco+(normButWidth * 2), *yco-126, normButWidth, 18, &data->flag, 0, 24, 0, 0, "Parent affects z-scaling"); 
 
830
                                uiBlockEndAlign(block);
 
831
                                
 
832
                                
 
833
                                /* Inverse options */
 
834
                                uiBlockBeginAlign(block);
 
835
                                        but=uiDefBut(block, BUT, B_CONSTRAINT_TEST, "Set Offset", *xco, *yco-151, (width/2),18, NULL, 0, 24, 0, 0, "Calculate current Parent-Inverse Matrix (i.e. restore offset from parent)");
 
836
                                        uiButSetFunc(but, childof_const_setinv, con, NULL);
 
837
                                        
 
838
                                        but=uiDefBut(block, BUT, B_CONSTRAINT_TEST, "Clear Offset", *xco+((width/2)+10), *yco-151, (width/2),18, NULL, 0, 24, 0, 0, "Clear Parent-Inverse Matrix (i.e. clear offset from parent)");
 
839
                                        uiButSetFunc(but, childof_const_clearinv, con, NULL);
 
840
                                uiBlockEndAlign(block);
 
841
                        }
 
842
                        break;
 
843
                case CONSTRAINT_TYPE_LOCLIKE:
 
844
                        {
 
845
                                bLocateLikeConstraint *data = con->data;
 
846
                                
 
847
                                height = 111;
 
848
                                uiDefBut(block, ROUNDBOX, B_DIFF, "", *xco-10, *yco-height, width+40,height-1, NULL, 5.0, 0.0, 12, rb_col, ""); 
 
849
                                
 
850
                                uiDefBut(block, LABEL, B_CONSTRAINT_TEST, "Target:", *xco+65, *yco-24, 50, 18, NULL, 0.0, 0.0, 0.0, 0.0, ""); 
 
851
                                
 
852
                                /* Draw target parameters */
 
853
                                uiBlockBeginAlign(block);
 
854
                                        uiDefIDPoinBut(block, test_obpoin_but, ID_OB, B_CONSTRAINT_CHANGETARGET, "OB:", *xco+120, *yco-24, 135, 18, &data->tar, "Target Object"); 
 
855
                                        
 
856
                                        if (is_armature_target(data->tar)) {
 
857
                                                but= uiDefBut(block, TEX, B_CONSTRAINT_CHANGETARGET, "BO:", *xco+120, *yco-42,135,18, &data->subtarget, 0, 24, 0, 0, "Subtarget Bone");
 
858
                                                uiButSetCompleteFunc(but, autocomplete_bone, (void *)data->tar);
 
859
                                        }
 
860
                                        else if (is_geom_target(data->tar)) {
 
861
                                                but= uiDefBut(block, TEX, B_CONSTRAINT_CHANGETARGET, "VG:", *xco+120, *yco-42,135,18, &data->subtarget, 0, 24, 0, 0, "Name of Vertex Group defining 'target' points");
 
862
                                                uiButSetCompleteFunc(but, autocomplete_vgroup, (void *)data->tar);
 
863
                                        }
 
864
                                        else {
 
865
                                                strcpy(data->subtarget, "");
 
866
                                        }
 
867
                                uiBlockEndAlign(block);
 
868
                                
 
869
                                /* Draw XYZ toggles */
 
870
                                uiBlockBeginAlign(block);
 
871
                                        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");
 
872
                                        uiDefButBitI(block, TOG, LOCLIKE_X_INVERT, B_CONSTRAINT_TEST, "-", *xco+((width/2)-16), *yco-64, 32, 18, &data->flag, 0, 24, 0, 0, "Invert X component");
 
873
                                        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");
 
874
                                        uiDefButBitI(block, TOG, LOCLIKE_Y_INVERT, B_CONSTRAINT_TEST, "-", *xco+((width/2)+48), *yco-64, 32, 18, &data->flag, 0, 24, 0, 0, "Invert Y component");
 
875
                                        uiDefButBitI(block, TOG, LOCLIKE_Z, B_CONSTRAINT_TEST, "Z", *xco+((width/2)+96), *yco-64, 32, 18, &data->flag, 0, 24, 0, 0, "Copy Z component");
 
876
                                        uiDefButBitI(block, TOG, LOCLIKE_Z_INVERT, B_CONSTRAINT_TEST, "-", *xco+((width/2)+128), *yco-64, 32, 18, &data->flag, 0, 24, 0, 0, "Invert Z component");
 
877
                                uiBlockEndAlign(block);
 
878
                                
 
879
                                /* Draw options */
 
880
                                uiDefButBitI(block, TOG, LOCLIKE_OFFSET, B_CONSTRAINT_TEST, "Offset", *xco, *yco-89, (width/2), 18, &data->flag, 0, 24, 0, 0, "Add original location onto copied location");
 
881
                                if (is_armature_target(data->tar)) {
 
882
                                        uiDefButF(block, NUM, B_CONSTRAINT_TEST, "Head/Tail:", *xco+(width/2), *yco-89, (width/2), 18, &con->headtail, 0.0, 1, 0.1, 0.1, "Target along length of bone: Head=0, Tail=1");
 
883
                                }
 
884
                                
 
885
                                /* constraint space settings */
 
886
                                draw_constraint_spaceselect(block, con, *xco, *yco-109, is_armature_owner(ob), is_armature_target(data->tar));
 
887
                        }
 
888
                        break;
 
889
                case CONSTRAINT_TYPE_ROTLIKE:
 
890
                        {
 
891
                                bRotateLikeConstraint *data = con->data;
 
892
                                
 
893
                                height = 101;
 
894
                                uiDefBut(block, ROUNDBOX, B_DIFF, "", *xco-10, *yco-height, width+40,height-1, NULL, 5.0, 0.0, 12, rb_col, ""); 
 
895
                                
 
896
                                uiDefBut(block, LABEL, B_CONSTRAINT_TEST, "Target:", *xco+65, *yco-24, 50, 18, NULL, 0.0, 0.0, 0.0, 0.0, ""); 
 
897
                                
 
898
                                /* Draw target parameters */
 
899
                                uiBlockBeginAlign(block);
 
900
                                        uiDefIDPoinBut(block, test_obpoin_but, ID_OB, B_CONSTRAINT_CHANGETARGET, "OB:", *xco+120, *yco-24, 135, 18, &data->tar, "Target Object"); 
 
901
                                        
 
902
                                        if (is_armature_target(data->tar)) {
 
903
                                                but= uiDefBut(block, TEX, B_CONSTRAINT_CHANGETARGET, "BO:", *xco+120, *yco-42,135,18, &data->subtarget, 0, 24, 0, 0, "Subtarget Bone");
 
904
                                                uiButSetCompleteFunc(but, autocomplete_bone, (void *)data->tar);
 
905
                                        }
 
906
                                        else if (is_geom_target(data->tar)) { 
 
907
                                                but= uiDefBut(block, TEX, B_CONSTRAINT_CHANGETARGET, "VG:", *xco+120, *yco-42,135,18, &data->subtarget, 0, 24, 0, 0, "Name of Vertex Group defining 'target' points");
 
908
                                                uiButSetCompleteFunc(but, autocomplete_vgroup, (void *)data->tar);
 
909
                                        }
 
910
                                        else {
 
911
                                                strcpy(data->subtarget, "");
 
912
                                        }
 
913
                                uiBlockEndAlign(block);
 
914
                                
 
915
                                /* Draw XYZ toggles */
 
916
                                uiBlockBeginAlign(block);
 
917
                                        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");
 
918
                                        uiDefButBitI(block, TOG, ROTLIKE_X_INVERT, B_CONSTRAINT_TEST, "-", *xco+((width/2)-16), *yco-64, 32, 18, &data->flag, 0, 24, 0, 0, "Invert X component");
 
919
                                        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");
 
920
                                        uiDefButBitI(block, TOG, ROTLIKE_Y_INVERT, B_CONSTRAINT_TEST, "-", *xco+((width/2)+48), *yco-64, 32, 18, &data->flag, 0, 24, 0, 0, "Invert Y component");
 
921
                                        uiDefButBitI(block, TOG, ROTLIKE_Z, B_CONSTRAINT_TEST, "Z", *xco+((width/2)+96), *yco-64, 32, 18, &data->flag, 0, 24, 0, 0, "Copy Z component");
 
922
                                        uiDefButBitI(block, TOG, ROTLIKE_Z_INVERT, B_CONSTRAINT_TEST, "-", *xco+((width/2)+128), *yco-64, 32, 18, &data->flag, 0, 24, 0, 0, "Invert Z component");
 
923
                                uiBlockEndAlign(block);
 
924
                                
 
925
                                /* draw offset toggle */
 
926
                                uiDefButBitI(block, TOG, ROTLIKE_OFFSET, B_CONSTRAINT_TEST, "Offset", *xco, *yco-64, 80, 18, &data->flag, 0, 24, 0, 0, "Add original rotation onto copied rotation");
 
927
                                
 
928
                                /* constraint space settings */
 
929
                                draw_constraint_spaceselect(block, con, *xco, *yco-94, is_armature_owner(ob), is_armature_target(data->tar));
 
930
                        }
 
931
                        break;
 
932
                case CONSTRAINT_TYPE_SIZELIKE:
 
933
                        {
 
934
                                bSizeLikeConstraint *data = con->data;
 
935
                                
 
936
                                height = 101;
 
937
                                
 
938
                                uiDefBut(block, ROUNDBOX, B_DIFF, "", *xco-10, *yco-height, width+40,height-1, NULL, 5.0, 0.0, 12, rb_col, ""); 
 
939
                                
 
940
                                uiDefBut(block, LABEL, B_CONSTRAINT_TEST, "Target:", *xco+65, *yco-24, 50, 18, NULL, 0.0, 0.0, 0.0, 0.0, ""); 
 
941
                                
 
942
                                /* Draw target parameters */
 
943
                                uiBlockBeginAlign(block);
 
944
                                        uiDefIDPoinBut(block, test_obpoin_but, ID_OB, B_CONSTRAINT_CHANGETARGET, "OB:", *xco+120, *yco-24, 135, 18, &data->tar, "Target Object"); 
 
945
                                        
 
946
                                        if (is_armature_target(data->tar)) {
 
947
                                                but= uiDefBut(block, TEX, B_CONSTRAINT_CHANGETARGET, "BO:", *xco+120, *yco-42,135,18, &data->subtarget, 0, 24, 0, 0, "Subtarget Bone");
 
948
                                                uiButSetCompleteFunc(but, autocomplete_bone, (void *)data->tar);
 
949
                                        }
 
950
                                        else if (is_geom_target(data->tar)) {
 
951
                                                but= uiDefBut(block, TEX, B_CONSTRAINT_CHANGETARGET, "VG:", *xco+120, *yco-42,135,18, &data->subtarget, 0, 24, 0, 0, "Name of Vertex Group defining 'target' points");
 
952
                                                uiButSetCompleteFunc(but, autocomplete_vgroup, (void *)data->tar);
 
953
                                        }
 
954
                                        else {
 
955
                                                strcpy(data->subtarget, "");
 
956
                                        }
 
957
                                uiBlockEndAlign(block);
 
958
                                
 
959
                                /* Draw XYZ toggles */
 
960
                                uiBlockBeginAlign(block);
 
961
                                        uiDefButBitI(block, TOG, SIZELIKE_X, B_CONSTRAINT_TEST, "X", *xco+((width/2)-48), *yco-64, 32, 18, &data->flag, 0, 24, 0, 0, "Copy X component");
 
962
                                        uiDefButBitI(block, TOG, SIZELIKE_Y, B_CONSTRAINT_TEST, "Y", *xco+((width/2)-16), *yco-64, 32, 18, &data->flag, 0, 24, 0, 0, "Copy Y component");
 
963
                                        uiDefButBitI(block, TOG, SIZELIKE_Z, B_CONSTRAINT_TEST, "Z", *xco+((width/2)+16), *yco-64, 32, 18, &data->flag, 0, 24, 0, 0, "Copy Z component");
 
964
                                uiBlockEndAlign(block);
 
965
                                
 
966
                                /* draw offset toggle */
 
967
                                uiDefButBitI(block, TOG, SIZELIKE_OFFSET, B_CONSTRAINT_TEST, "Offset", *xco, *yco-64, 80, 18, &data->flag, 0, 24, 0, 0, "Add original scaling onto copied scaling");
 
968
                                
 
969
                                /* constraint space settings */
 
970
                                draw_constraint_spaceselect(block, con, *xco, *yco-94, is_armature_owner(ob), is_armature_target(data->tar));
 
971
                        }
 
972
                        break;
 
973
                case CONSTRAINT_TYPE_KINEMATIC:
 
974
                        {
 
975
                                bKinematicConstraint *data = con->data;
 
976
                                
 
977
                                height = 146;
 
978
                                if(data->poletar) 
 
979
                                        height += 30;
 
980
 
 
981
                                uiDefBut(block, ROUNDBOX, B_DIFF, "", *xco-10, *yco-height, width+40,height-1, NULL, 5.0, 0.0, 12, rb_col, ""); 
 
982
                                
 
983
                                /* IK Target */
 
984
                                uiDefBut(block, LABEL, B_CONSTRAINT_TEST, "Target:", *xco, *yco-24, 80, 18, NULL, 0.0, 0.0, 0.0, 0.0, ""); 
 
985
                                
 
986
                                /* Draw target parameters */
 
987
                                uiBlockBeginAlign(block);
 
988
                                uiDefIDPoinBut(block, test_obpoin_but, ID_OB, B_CONSTRAINT_CHANGETARGET, "OB:", *xco, *yco-44, 137, 19, &data->tar, "Target Object"); 
 
989
 
 
990
                                if (is_armature_target(data->tar)) {
 
991
                                        but=uiDefBut(block, TEX, B_CONSTRAINT_CHANGETARGET, "BO:", *xco, *yco-62,137,19, &data->subtarget, 0, 24, 0, 0, "Subtarget Bone");
 
992
                                        uiButSetCompleteFunc(but, autocomplete_bone, (void *)data->tar);
 
993
                                }
 
994
                                else if (is_geom_target(data->tar)) {
 
995
                                        but= uiDefBut(block, TEX, B_CONSTRAINT_CHANGETARGET, "VG:", *xco, *yco-62,137,18, &data->subtarget, 0, 24, 0, 0, "Name of Vertex Group defining 'target' points");
 
996
                                        uiButSetCompleteFunc(but, autocomplete_vgroup, (void *)data->tar);
 
997
                                }
 
998
                                else {
 
999
                                        strcpy (data->subtarget, "");
 
1000
                                }
 
1001
                                
 
1002
                                uiBlockEndAlign(block);
 
1003
                                
 
1004
                                /* Settings */
 
1005
                                uiBlockBeginAlign(block);
 
1006
                                uiDefButBitS(block, TOG, CONSTRAINT_IK_TIP, B_CONSTRAINT_TEST, "Use Tail", *xco, *yco-92, 137, 19, &data->flag, 0, 0, 0, 0, "Include Bone's tail also last element in Chain");
 
1007
                                uiDefButS(block, NUM, B_CONSTRAINT_TEST, "ChainLen:", *xco, *yco-112,137,19, &data->rootbone, 0, 255, 0, 0, "If not zero, the amount of bones in this chain");
 
1008
                                
 
1009
                                uiBlockBeginAlign(block);
 
1010
                                uiDefButF(block, NUMSLI, B_CONSTRAINT_TEST, "PosW ", *xco+147, *yco-92, 137, 19, &data->weight, 0.01, 1.0, 2, 2, "For Tree-IK: weight of position control for this target");
 
1011
                                uiDefButBitS(block, TOG, CONSTRAINT_IK_ROT, B_CONSTRAINT_TEST, "Rot", *xco+147, *yco-112, 40,19, &data->flag, 0, 0, 0, 0, "Chain follows rotation of target");
 
1012
                                uiDefButF(block, NUMSLI, B_CONSTRAINT_TEST, "W ", *xco+187, *yco-112, 97, 19, &data->orientweight, 0.01, 1.0, 2, 2, "For Tree-IK: Weight of orientation control for this target");
 
1013
                                
 
1014
                                uiBlockBeginAlign(block);
 
1015
                                
 
1016
                                uiDefButBitS(block, TOG, CONSTRAINT_IK_STRETCH, B_CONSTRAINT_TEST, "Stretch", *xco, *yco-137,137,19, &data->flag, 0, 0, 0, 0, "Enable IK stretching");
 
1017
                                uiBlockBeginAlign(block);
 
1018
                                uiDefButS(block, NUM, B_CONSTRAINT_TEST, "Iterations:", *xco+147, *yco-137, 137, 19, &data->iterations, 1, 10000, 0, 0, "Maximum number of solving iterations"); 
 
1019
                                uiBlockEndAlign(block);
 
1020
                                
 
1021
                                /* Pole Vector */
 
1022
                                uiDefBut(block, LABEL, B_CONSTRAINT_TEST, "Pole Target:", *xco+147, *yco-24, 100, 18, NULL, 0.0, 0.0, 0.0, 0.0, ""); 
 
1023
                                
 
1024
                                uiBlockBeginAlign(block);
 
1025
                                uiDefIDPoinBut(block, test_obpoin_but, ID_OB, B_CONSTRAINT_CHANGETARGET, "OB:", *xco+147, *yco-44, 137, 19, &data->poletar, "Pole Target Object"); 
 
1026
                                if (is_armature_target(data->poletar)) {
 
1027
                                        but=uiDefBut(block, TEX, B_CONSTRAINT_CHANGETARGET, "BO:", *xco+147, *yco-62,137,19, &data->polesubtarget, 0, 24, 0, 0, "Pole Subtarget Bone");
 
1028
                                        uiButSetCompleteFunc(but, autocomplete_bone, (void *)data->poletar);
 
1029
                                }
 
1030
                                else if (is_geom_target(data->poletar)) {
 
1031
                                        but= uiDefBut(block, TEX, B_CONSTRAINT_CHANGETARGET, "VG:", *xco+147, *yco-62,137,18, &data->polesubtarget, 0, 24, 0, 0, "Name of Vertex Group defining pole 'target' points");
 
1032
                                        uiButSetCompleteFunc(but, autocomplete_vgroup, (void *)data->poletar);
 
1033
                                }
 
1034
                                else {
 
1035
                                        strcpy(data->polesubtarget, "");
 
1036
                                }
 
1037
                                
 
1038
                                if (data->poletar) {
 
1039
                                        uiBlockBeginAlign(block);
 
1040
#if 0
 
1041
                                        but = uiDefBut(block, BUT, B_CONSTRAINT_TEST, (data->flag & CONSTRAINT_IK_SETANGLE)? "Set Pole Offset": "Clear Pole Offset", *xco, *yco-167, 137, 19, 0, 0.0, 1.0, 0.0, 0.0, "Set the pole rotation offset from the current pose");
 
1042
                                        uiButSetFunc(but, con_kinematic_set_pole_angle, ob, con);
 
1043
                                        if (!(data->flag & CONSTRAINT_IK_SETANGLE))
 
1044
#endif                                  
 
1045
                                                uiDefButF(block, NUM, B_CONSTRAINT_TEST, "Pole Offset ", *xco, *yco-167, 137, 19, &data->poleangle, -180.0, 180.0, 0, 0, "Pole rotation offset");
 
1046
                                }
 
1047
                        }
 
1048
                        break;
 
1049
                case CONSTRAINT_TYPE_TRACKTO:
 
1050
                        {
 
1051
                                bTrackToConstraint *data = con->data;
 
1052
                                
 
1053
                                if (is_armature_target(data->tar)) 
 
1054
                                        height = 118;
 
1055
                                else
 
1056
                                        height = 96;
 
1057
                                        
 
1058
                                uiDefBut(block, ROUNDBOX, B_DIFF, "", *xco-10, *yco-height, width+40,height-1, NULL, 5.0, 0.0, 12, rb_col, ""); 
 
1059
                                
 
1060
                                uiDefBut(block, LABEL, B_CONSTRAINT_TEST, "Target:", *xco+65, *yco-24, 50, 18, NULL, 0.0, 0.0, 0.0, 0.0, ""); 
 
1061
                                
 
1062
                                /* Draw target parameters */
 
1063
                                uiBlockBeginAlign(block);
 
1064
                                        uiDefIDPoinBut(block, test_obpoin_but, ID_OB, B_CONSTRAINT_CHANGETARGET, "OB:", *xco+120, *yco-24, 135, 18, &data->tar, "Target Object"); 
 
1065
                                        
 
1066
                                        if (is_armature_target(data->tar)) {
 
1067
                                                but=uiDefBut(block, TEX, B_CONSTRAINT_CHANGETARGET, "BO:", *xco+120, *yco-42,135,18, &data->subtarget, 0, 24, 0, 0, "Subtarget Bone");
 
1068
                                                uiButSetCompleteFunc(but, autocomplete_bone, (void *)data->tar);
 
1069
                                        }
 
1070
                                        else if (is_geom_target(data->tar)) {
 
1071
                                                but= uiDefBut(block, TEX, B_CONSTRAINT_CHANGETARGET, "VG:", *xco+120, *yco-42,135,18, &data->subtarget, 0, 24, 0, 0, "Name of Vertex Group defining 'target' points");
 
1072
                                                uiButSetCompleteFunc(but, autocomplete_vgroup, (void *)data->tar);
 
1073
                                        }
 
1074
                                        else {
 
1075
                                                strcpy(data->subtarget, "");
 
1076
                                        }
 
1077
                                uiBlockEndAlign(block);
 
1078
                                
 
1079
                                uiBlockBeginAlign(block);
 
1080
                                        uiDefBut(block, LABEL, B_CONSTRAINT_TEST, "Align:", *xco+5, *yco-42, 50, 18, NULL, 0.0, 0.0, 0.0, 0.0, "");
 
1081
                                        
 
1082
                                        uiDefButBitI(block, TOG, 1, B_CONSTRAINT_TEST, "TargetZ", *xco+60, *yco-42, 50, 18, &data->flags, 0, 1, 0, 0, "Target Z axis, not world Z axis, will constrain up direction");
 
1083
                                uiBlockEndAlign(block);
 
1084
                                
 
1085
                                uiBlockBeginAlign(block);
 
1086
                                        uiDefBut(block, LABEL, B_CONSTRAINT_TEST, "To:", *xco+12, *yco-64, 25, 18, NULL, 0.0, 0.0, 0.0, 0.0, ""); 
 
1087
                                        
 
1088
                                        uiDefButI(block, ROW,B_CONSTRAINT_TEST,"X",     *xco+39, *yco-64,17,18, &data->reserved1, 12.0, 0.0, 0, 0, "X axis points to the target object");
 
1089
                                        uiDefButI(block, ROW,B_CONSTRAINT_TEST,"Y",     *xco+56, *yco-64,17,18, &data->reserved1, 12.0, 1.0, 0, 0, "Y axis points to the target object");
 
1090
                                        uiDefButI(block, ROW,B_CONSTRAINT_TEST,"Z",     *xco+73, *yco-64,17,18, &data->reserved1, 12.0, 2.0, 0, 0, "Z axis points to the target object");
 
1091
                                        uiDefButI(block, ROW,B_CONSTRAINT_TEST,"-X",    *xco+90, *yco-64,24,18, &data->reserved1, 12.0, 3.0, 0, 0, "-X axis points to the target object");
 
1092
                                        uiDefButI(block, ROW,B_CONSTRAINT_TEST,"-Y",    *xco+114, *yco-64,24,18, &data->reserved1, 12.0, 4.0, 0, 0, "-Y axis points to the target object");
 
1093
                                        uiDefButI(block, ROW,B_CONSTRAINT_TEST,"-Z",    *xco+138, *yco-64,24,18, &data->reserved1, 12.0, 5.0, 0, 0, "-Z axis points to the target object");
 
1094
                                uiBlockEndAlign(block);
 
1095
                                
 
1096
                                uiBlockBeginAlign(block);
 
1097
                                        uiDefBut(block, LABEL, B_CONSTRAINT_TEST, "Up:", *xco+174, *yco-64, 30, 18, NULL, 0.0, 0.0, 0.0, 0.0, "");
 
1098
                                        
 
1099
                                        uiDefButI(block, ROW,B_CONSTRAINT_TEST,"X",     *xco+204, *yco-64,17,18, &data->reserved2, 13.0, 0.0, 0, 0, "X axis points upward");
 
1100
                                        uiDefButI(block, ROW,B_CONSTRAINT_TEST,"Y",     *xco+221, *yco-64,17,18, &data->reserved2, 13.0, 1.0, 0, 0, "Y axis points upward");
 
1101
                                        uiDefButI(block, ROW,B_CONSTRAINT_TEST,"Z",     *xco+238, *yco-64,17,18, &data->reserved2, 13.0, 2.0, 0, 0, "Z axis points upward");
 
1102
                                uiBlockEndAlign(block);
 
1103
                                
 
1104
                                if (is_armature_target(data->tar)) {
 
1105
                                        uiDefButF(block, NUM, B_CONSTRAINT_TEST, "Head/Tail:", *xco, *yco-94, 241, 18, &con->headtail, 0.0, 1, 0.1, 0.1, "Target along length of bone: Head=0, Tail=1");
 
1106
                                        
 
1107
                                        /* constraint space settings */
 
1108
                                        draw_constraint_spaceselect(block, con, *xco, *yco-116, is_armature_owner(ob), is_armature_target(data->tar));
 
1109
                                }
 
1110
                                else {
 
1111
                                        /* constraint space settings */
 
1112
                                        draw_constraint_spaceselect(block, con, *xco, *yco-94, is_armature_owner(ob), is_armature_target(data->tar));
 
1113
                                }
 
1114
                        }
 
1115
                        break;
 
1116
                case CONSTRAINT_TYPE_MINMAX:
 
1117
                        {
 
1118
                                bMinMaxConstraint *data = con->data;
 
1119
                                
 
1120
                                if (is_armature_target(data->tar)) 
 
1121
                                        height = 88;
 
1122
                                else
 
1123
                                        height = 66;
 
1124
                                        
 
1125
                                uiDefBut(block, ROUNDBOX, B_DIFF, "", *xco-10, *yco-height, width+40,height-1, NULL, 5.0, 0.0, 12, rb_col, ""); 
 
1126
                                
 
1127
                                uiDefBut(block, LABEL, B_CONSTRAINT_TEST, "Target:", *xco+65, *yco-24, 50, 18, NULL, 0.0, 0.0, 0.0, 0.0, ""); 
 
1128
                                
 
1129
                                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"); 
 
1130
                                
 
1131
                                /* Draw target parameters */
 
1132
                                uiBlockBeginAlign(block);
 
1133
                                        uiDefIDPoinBut(block, test_obpoin_but, ID_OB, B_CONSTRAINT_CHANGETARGET, "OB:", *xco+120, *yco-24, 135, 18, &data->tar, "Target Object"); 
 
1134
                                        
 
1135
                                        if (is_armature_target(data->tar)) {
 
1136
                                                but=uiDefBut(block, TEX, B_CONSTRAINT_CHANGETARGET, "BO:", *xco+120, *yco-42,135,18, &data->subtarget, 0, 24, 0, 0, "Subtarget Bone");
 
1137
                                                uiButSetCompleteFunc(but, autocomplete_bone, (void *)data->tar);
 
1138
                                        }
 
1139
                                        else if (is_geom_target(data->tar)) {
 
1140
                                                but= uiDefBut(block, TEX, B_CONSTRAINT_CHANGETARGET, "VG:", *xco+120, *yco-42,135,18, &data->subtarget, 0, 24, 0, 0, "Name of Vertex Group defining 'target' points");
 
1141
                                                uiButSetCompleteFunc(but, autocomplete_vgroup, (void *)data->tar);
 
1142
                                        }
 
1143
                                        else {
 
1144
                                                strcpy(data->subtarget, "");
 
1145
                                        }
 
1146
                                uiBlockEndAlign(block);
 
1147
                                
 
1148
                                uiDefButBitI(block, TOG, MINMAX_STICKY, B_CONSTRAINT_TEST, "Sticky", *xco, *yco-24, 44, 18, &data->flag, 0, 24, 0, 0, "Immobilize object while constrained");
 
1149
                                uiDefButBitI(block, TOG, MINMAX_USEROT, B_CONSTRAINT_TEST, "Use Rot", *xco+44, *yco-24, 64, 18, &data->flag, 0, 24, 0, 0, "Use target object rotation");
 
1150
                                
 
1151
                                uiDefBut(block, LABEL, B_CONSTRAINT_TEST, "Max/Min:", *xco-8, *yco-64, 54, 18, NULL, 0.0, 0.0, 0.0, 0.0, ""); 
 
1152
                                
 
1153
                                uiBlockBeginAlign(block);                       
 
1154
                                        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");
 
1155
                                        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");
 
1156
                                        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");
 
1157
                                        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");
 
1158
                                        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");
 
1159
                                        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");
 
1160
                                uiBlockEndAlign(block);
 
1161
                                
 
1162
                                if (is_armature_target(data->tar)) {
 
1163
                                        uiDefButF(block, NUM, B_CONSTRAINT_TEST, "Head/Tail:", *xco, *yco-86, 241, 18, &con->headtail, 0.0, 1, 0.1, 0.1, "Target along length of bone: Head=0, Tail=1");
 
1164
                                }
 
1165
                                
 
1166
                        }
 
1167
                        break;
 
1168
                case CONSTRAINT_TYPE_LOCKTRACK:
 
1169
                        {
 
1170
                                bLockTrackConstraint *data = con->data;
 
1171
                                height = 66;
 
1172
                                uiDefBut(block, ROUNDBOX, B_DIFF, "", *xco-10, *yco-height, width+40,height-1, NULL, 5.0, 0.0, 12, rb_col, ""); 
 
1173
                                
 
1174
                                uiDefBut(block, LABEL, B_CONSTRAINT_TEST, "Target:", *xco+65, *yco-24, 50, 18, NULL, 0.0, 0.0, 0.0, 0.0, ""); 
 
1175
                                
 
1176
                                /* Draw target parameters */
 
1177
                                uiBlockBeginAlign(block);
 
1178
                                        uiDefIDPoinBut(block, test_obpoin_but, ID_OB, B_CONSTRAINT_CHANGETARGET, "OB:", *xco+120, *yco-24, 135, 18, &data->tar, "Target Object"); 
 
1179
                                        
 
1180
                                        if (is_armature_target(data->tar)) {
 
1181
                                                but=uiDefBut(block, TEX, B_CONSTRAINT_CHANGETARGET, "BO:", *xco+120, *yco-42,135,18, &data->subtarget, 0, 24, 0, 0, "Subtarget Bone");
 
1182
                                                uiButSetCompleteFunc(but, autocomplete_bone, (void *)data->tar);
 
1183
                                        }
 
1184
                                        else if (is_geom_target(data->tar)) {
 
1185
                                                but= uiDefBut(block, TEX, B_CONSTRAINT_CHANGETARGET, "VG:", *xco+120, *yco-42,135,18, &data->subtarget, 0, 24, 0, 0, "Name of Vertex Group defining 'target' points");
 
1186
                                                uiButSetCompleteFunc(but, autocomplete_vgroup, (void *)data->tar);
 
1187
                                        }
 
1188
                                        else {
 
1189
                                                strcpy(data->subtarget, "");
 
1190
                                        }
 
1191
                                uiBlockEndAlign(block);
 
1192
                                
 
1193
                                uiBlockBeginAlign(block);
 
1194
                                        uiDefBut(block, LABEL, B_CONSTRAINT_TEST, "To:", *xco+12, *yco-64, 25, 18, NULL, 0.0, 0.0, 0.0, 0.0, ""); 
 
1195
                                        
 
1196
                                        uiDefButI(block, ROW, B_CONSTRAINT_TEST,"X",    *xco+39, *yco-64,17,18, &data->trackflag, 12.0, 0.0, 0, 0, "X axis points to the target object");
 
1197
                                        uiDefButI(block, ROW, B_CONSTRAINT_TEST,"Y",    *xco+56, *yco-64,17,18, &data->trackflag, 12.0, 1.0, 0, 0, "Y axis points to the target object");
 
1198
                                        uiDefButI(block, ROW, B_CONSTRAINT_TEST,"Z",    *xco+73, *yco-64,17,18, &data->trackflag, 12.0, 2.0, 0, 0, "Z axis points to the target object");
 
1199
                                        uiDefButI(block, ROW, B_CONSTRAINT_TEST,"-X",   *xco+90, *yco-64,24,18, &data->trackflag, 12.0, 3.0, 0, 0, "-X axis points to the target object");
 
1200
                                        uiDefButI(block, ROW, B_CONSTRAINT_TEST,"-Y",   *xco+114, *yco-64,24,18, &data->trackflag, 12.0, 4.0, 0, 0, "-Y axis points to the target object");
 
1201
                                        uiDefButI(block, ROW, B_CONSTRAINT_TEST,"-Z",   *xco+138, *yco-64,24,18, &data->trackflag, 12.0, 5.0, 0, 0, "-Z axis points to the target object");
 
1202
                                uiBlockEndAlign(block);
 
1203
                                
 
1204
                                uiBlockBeginAlign(block);
 
1205
                                        uiDefBut(block, LABEL, B_CONSTRAINT_TEST, "Lock:", *xco+166, *yco-64, 38, 18, NULL, 0.0, 0.0, 0.0, 0.0, "");
 
1206
                                        
 
1207
                                        uiDefButI(block, ROW, B_CONSTRAINT_TEST,"X",    *xco+204, *yco-64,17,18, &data->lockflag, 13.0, 0.0, 0, 0, "X axis is locked");
 
1208
                                        uiDefButI(block, ROW, B_CONSTRAINT_TEST,"Y",    *xco+221, *yco-64,17,18, &data->lockflag, 13.0, 1.0, 0, 0, "Y axis is locked");
 
1209
                                        uiDefButI(block, ROW, B_CONSTRAINT_TEST,"Z",    *xco+238, *yco-64,17,18, &data->lockflag, 13.0, 2.0, 0, 0, "Z axis is locked");
 
1210
                                uiBlockEndAlign(block);
 
1211
                        }
 
1212
                        break;
 
1213
                case CONSTRAINT_TYPE_FOLLOWPATH:
 
1214
                        {
 
1215
                                bFollowPathConstraint *data = con->data;
 
1216
                                
 
1217
                                height = 66;
 
1218
                                uiDefBut(block, ROUNDBOX, B_DIFF, "", *xco-10, *yco-height, width+40,height-1, NULL, 5.0, 0.0, 12, rb_col, ""); 
 
1219
                                
 
1220
                                uiDefBut(block, LABEL, B_CONSTRAINT_TEST, "Target:", *xco+65, *yco-24, 50, 18, NULL, 0.0, 0.0, 0.0, 0.0, ""); 
 
1221
                                
 
1222
                                /* Draw target parameters */
 
1223
                                uiDefIDPoinBut(block, test_obpoin_but, ID_OB, B_CONSTRAINT_CHANGETARGET, "OB:", *xco+120, *yco-24, 135, 18, &data->tar, "Target Object"); 
 
1224
                                
 
1225
                                /* Draw Curve Follow toggle */
 
1226
                                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");
 
1227
                                
 
1228
                                /* Draw Offset number button */
 
1229
                                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"); 
 
1230
                                
 
1231
                                uiBlockBeginAlign(block);
 
1232
                                        uiDefBut(block, LABEL, B_CONSTRAINT_TEST, "Fw:", *xco+12, *yco-64, 27, 18, NULL, 0.0, 0.0, 0.0, 0.0, ""); 
 
1233
                                        
 
1234
                                        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");
 
1235
                                        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");
 
1236
                                        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");
 
1237
                                        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");
 
1238
                                        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");
 
1239
                                        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");
 
1240
                                uiBlockEndAlign(block);
 
1241
                                
 
1242
                                uiBlockBeginAlign(block);
 
1243
                                        uiDefBut(block, LABEL, B_CONSTRAINT_TEST, "Up:", *xco+174, *yco-64, 30, 18, NULL, 0.0, 0.0, 0.0, 0.0, "");
 
1244
                                        
 
1245
                                        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");
 
1246
                                        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");
 
1247
                                        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");
 
1248
                                uiBlockEndAlign(block);
 
1249
                        }
 
1250
                        break;
 
1251
                case CONSTRAINT_TYPE_STRETCHTO:
 
1252
                        {
 
1253
                                bStretchToConstraint *data = con->data;
 
1254
                                
 
1255
                                height = 105;
 
1256
                                uiDefBut(block, ROUNDBOX, B_DIFF, "", *xco-10, *yco-height, width+40,height-1, NULL, 5.0, 0.0, 12, rb_col, ""); 
 
1257
                                
 
1258
                                uiDefBut(block, LABEL, B_CONSTRAINT_TEST, "Target:", *xco+65, *yco-24, 50, 18, NULL, 0.0, 0.0, 0.0, 0.0, ""); 
 
1259
                                
 
1260
                                /* Draw target parameters */
 
1261
                                uiBlockBeginAlign(block);
 
1262
                                        uiDefIDPoinBut(block, test_obpoin_but, ID_OB, B_CONSTRAINT_CHANGETARGET, "OB:", *xco+120, *yco-24, 135, 18, &data->tar, "Target Object"); 
 
1263
                                        
 
1264
                                        if (is_armature_target(data->tar)) {
 
1265
                                                but=uiDefBut(block, TEX, B_CONSTRAINT_CHANGETARGET, "BO:", *xco+120, *yco-42,135,18, &data->subtarget, 0, 24, 0, 0, "Subtarget Bone");
 
1266
                                                uiButSetCompleteFunc(but, autocomplete_bone, (void *)data->tar);
 
1267
                                        }
 
1268
                                        else if (is_geom_target(data->tar)) {
 
1269
                                                but= uiDefBut(block, TEX, B_CONSTRAINT_CHANGETARGET, "VG:", *xco+120, *yco-42,135,18, &data->subtarget, 0, 24, 0, 0, "Name of Vertex Group defining 'target' points");
 
1270
                                                uiButSetCompleteFunc(but, autocomplete_vgroup, (void *)data->tar);
 
1271
                                        }
 
1272
                                        else {
 
1273
                                                strcpy(data->subtarget, "");
 
1274
                                        }
 
1275
                                uiBlockEndAlign(block);
 
1276
                                
 
1277
                                uiBlockBeginAlign(block);
 
1278
                                        if (is_armature_target(data->tar)) {
 
1279
                                                uiDefButF(block, BUTM, B_CONSTRAINT_TEST, "R", *xco, *yco-60, 20, 18, &data->orglength, 0.0, 0, 0, 0, "Recalculate RLength");
 
1280
                                                uiDefButF(block, NUM, B_CONSTRAINT_TEST, "Rest Length:", *xco+18, *yco-60,139,18, &data->orglength, 0.0, 100, 0.5, 0.5, "Length at Rest Position");
 
1281
                                                uiDefButF(block, NUM, B_CONSTRAINT_TEST, "Head/Tail:", *xco+155, *yco-60,98,18, &con->headtail, 0.0, 1, 0.1, 0.1, "Target along length of bone: Head=0, Tail=1");
 
1282
                                        }
 
1283
                                        else {
 
1284
                                                uiDefButF(block, BUTM, B_CONSTRAINT_TEST, "R", *xco, *yco-60, 20, 18, &data->orglength, 0.0, 0, 0, 0, "Recalculate RLength");
 
1285
                                                uiDefButF(block, NUM, B_CONSTRAINT_TEST, "Rest Length:", *xco+18, *yco-60, 237, 18, &data->orglength, 0.0, 100, 0.5, 0.5, "Length at Rest Position");
 
1286
                                        }
 
1287
                                uiBlockEndAlign(block);
 
1288
                                
 
1289
                                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");
 
1290
                                
 
1291
                                uiBlockBeginAlign(block);
 
1292
                                        uiDefBut(block, LABEL, B_CONSTRAINT_TEST, "Vol:",*xco+14, *yco-104,30,18, NULL, 0.0, 0.0, 0.0, 0.0, ""); 
 
1293
                                        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");
 
1294
                                        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");
 
1295
                                        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");
 
1296
                                        uiDefButI(block, ROW,B_CONSTRAINT_TEST,"NONE", *xco+114, *yco-104,50,18, &data->volmode, 12.0, 3.0, 0, 0, "Ignore Volume");
 
1297
                                uiBlockEndAlign(block);
 
1298
                                
 
1299
                                uiBlockBeginAlign(block);
 
1300
                                        uiDefBut(block, LABEL, B_CONSTRAINT_TEST,"Plane:",*xco+175, *yco-104,40,18, NULL, 0.0, 0.0, 0.0, 0.0, ""); 
 
1301
                                        uiDefButI(block, ROW,B_CONSTRAINT_TEST,"X",       *xco+215, *yco-104,20,18, &data->plane, 12.0, 0.0, 0, 0, "Keep X axis");
 
1302
                                        uiDefButI(block, ROW,B_CONSTRAINT_TEST,"Z",       *xco+235, *yco-104,20,18, &data->plane, 12.0, 2.0, 0, 0, "Keep Z axis");
 
1303
                                uiBlockEndAlign(block);
 
1304
                                }
 
1305
                        break;
 
1306
                case CONSTRAINT_TYPE_LOCLIMIT:
 
1307
                        {
 
1308
                                bLocLimitConstraint *data = con->data;
 
1309
                                
 
1310
                                int togButWidth = 50;
 
1311
                                int textButWidth = ((width/2)-togButWidth);
 
1312
                                
 
1313
                                height = 136; 
 
1314
                                uiDefBut(block, ROUNDBOX, B_DIFF, "", *xco-10, *yco-height, width+40,height-1, NULL, 5.0, 0.0, 12, rb_col, ""); 
 
1315
                                
 
1316
                                /* Draw Pairs of LimitToggle+LimitValue */
 
1317
                                uiBlockBeginAlign(block); 
 
1318
                                        uiDefButBitS(block, TOG, LIMIT_XMIN, B_CONSTRAINT_TEST, "minX", *xco, *yco-28, togButWidth, 18, &data->flag, 0, 24, 0, 0, "Use minimum x value"); 
 
1319
                                        uiDefButF(block, NUM, B_CONSTRAINT_TEST, "", *xco+togButWidth, *yco-28, (textButWidth-5), 18, &(data->xmin), -1000, 1000, 0.1,0.5,"Lowest x value to allow"); 
 
1320
                                uiBlockEndAlign(block); 
 
1321
                                
 
1322
                                uiBlockBeginAlign(block); 
 
1323
                                        uiDefButBitS(block, TOG, LIMIT_XMAX, B_CONSTRAINT_TEST, "maxX", *xco+(width-(textButWidth-5)-togButWidth), *yco-28, 50, 18, &data->flag, 0, 24, 0, 0, "Use maximum x value"); 
 
1324
                                        uiDefButF(block, NUM, B_CONSTRAINT_TEST, "", *xco+(width-textButWidth-5), *yco-28, (textButWidth-5), 18, &(data->xmax), -1000, 1000, 0.1,0.5,"Highest x value to allow"); 
 
1325
                                uiBlockEndAlign(block); 
 
1326
                                
 
1327
                                uiBlockBeginAlign(block); 
 
1328
                                        uiDefButBitS(block, TOG, LIMIT_YMIN, B_CONSTRAINT_TEST, "minY", *xco, *yco-50, togButWidth, 18, &data->flag, 0, 24, 0, 0, "Use minimum y value"); 
 
1329
                                        uiDefButF(block, NUM, B_CONSTRAINT_TEST, "", *xco+togButWidth, *yco-50, (textButWidth-5), 18, &(data->ymin), -1000, 1000, 0.1,0.5,"Lowest y value to allow"); 
 
1330
                                uiBlockEndAlign(block);
 
1331
                                
 
1332
                                uiBlockBeginAlign(block); 
 
1333
                                        uiDefButBitS(block, TOG, LIMIT_YMAX, B_CONSTRAINT_TEST, "maxY", *xco+(width-(textButWidth-5)-togButWidth), *yco-50, 50, 18, &data->flag, 0, 24, 0, 0, "Use maximum y value"); 
 
1334
                                        uiDefButF(block, NUM, B_CONSTRAINT_TEST, "", *xco+(width-textButWidth-5), *yco-50, (textButWidth-5), 18, &(data->ymax), -1000, 1000, 0.1,0.5,"Highest y value to allow"); 
 
1335
                                uiBlockEndAlign(block); 
 
1336
                                
 
1337
                                uiBlockBeginAlign(block); 
 
1338
                                        uiDefButBitS(block, TOG, LIMIT_ZMIN, B_CONSTRAINT_TEST, "minZ", *xco, *yco-72, togButWidth, 18, &data->flag, 0, 24, 0, 0, "Use minimum z value"); 
 
1339
                                        uiDefButF(block, NUM, B_CONSTRAINT_TEST, "", *xco+togButWidth, *yco-72, (textButWidth-5), 18, &(data->zmin), -1000, 1000, 0.1,0.5,"Lowest z value to allow"); 
 
1340
                                uiBlockEndAlign(block);
 
1341
                                
 
1342
                                uiBlockBeginAlign(block); 
 
1343
                                        uiDefButBitS(block, TOG, LIMIT_ZMAX, B_CONSTRAINT_TEST, "maxZ", *xco+(width-(textButWidth-5)-togButWidth), *yco-72, 50, 18, &data->flag, 0, 24, 0, 0, "Use maximum z value"); 
 
1344
                                        uiDefButF(block, NUM, B_CONSTRAINT_TEST, "", *xco+(width-textButWidth-5), *yco-72, (textButWidth-5), 18, &(data->zmax), -1000, 1000, 0.1,0.5,"Highest z value to allow"); 
 
1345
                                uiBlockEndAlign(block);
 
1346
                                
 
1347
                                /* special option(s) */
 
1348
                                uiDefButBitS(block, TOG, LIMIT_TRANSFORM, B_CONSTRAINT_TEST, "For Transform", *xco+(width/4), *yco-100, (width/2), 18, &data->flag2, 0, 24, 0, 0, "Transforms are affected by this constraint as well"); 
 
1349
                                
 
1350
                                /* constraint space settings */
 
1351
                                draw_constraint_spaceselect(block, con, *xco, *yco-130, is_armature_owner(ob), -1);
 
1352
                        }
 
1353
                        break;
 
1354
                case CONSTRAINT_TYPE_ROTLIMIT:
 
1355
                        {
 
1356
                                bRotLimitConstraint *data = con->data;
 
1357
                                int normButWidth = (width/3);
 
1358
                                
 
1359
                                height = 136; 
 
1360
                                
 
1361
                                uiDefBut(block, ROUNDBOX, B_DIFF, "", *xco-10, *yco-height, width+40,height-1, NULL, 5.0, 0.0, 12, rb_col, ""); 
 
1362
                                
 
1363
                                /* Draw Pairs of LimitToggle+LimitValue */
 
1364
                                uiBlockBeginAlign(block); 
 
1365
                                        uiDefButBitS(block, TOG, LIMIT_XROT, B_CONSTRAINT_TEST, "LimitX", *xco, *yco-28, normButWidth, 18, &data->flag, 0, 24, 0, 0, "Limit rotation on x-axis"); 
 
1366
                                        uiDefButF(block, NUM, B_CONSTRAINT_TEST, "min:", *xco+normButWidth, *yco-28, normButWidth, 18, &(data->xmin), -360, 360, 0.1,0.5,"Lowest x value to allow"); 
 
1367
                                        uiDefButF(block, NUM, B_CONSTRAINT_TEST, "max:", *xco+(normButWidth * 2), *yco-28, normButWidth, 18, &(data->xmax), -360, 360, 0.1,0.5,"Highest x value to allow"); 
 
1368
                                uiBlockEndAlign(block); 
 
1369
                                
 
1370
                                uiBlockBeginAlign(block); 
 
1371
                                        uiDefButBitS(block, TOG, LIMIT_YROT, B_CONSTRAINT_TEST, "LimitY", *xco, *yco-50, normButWidth, 18, &data->flag, 0, 24, 0, 0, "Limit rotation on y-axis"); 
 
1372
                                        uiDefButF(block, NUM, B_CONSTRAINT_TEST, "min:", *xco+normButWidth, *yco-50, normButWidth, 18, &(data->ymin), -360, 360, 0.1,0.5,"Lowest y value to allow"); 
 
1373
                                        uiDefButF(block, NUM, B_CONSTRAINT_TEST, "max:", *xco+(normButWidth * 2), *yco-50, normButWidth, 18, &(data->ymax), -360, 360, 0.1,0.5,"Highest y value to allow"); 
 
1374
                                uiBlockEndAlign(block); 
 
1375
                                
 
1376
                                uiBlockBeginAlign(block); 
 
1377
                                        uiDefButBitS(block, TOG, LIMIT_ZROT, B_CONSTRAINT_TEST, "LimitZ", *xco, *yco-72, normButWidth, 18, &data->flag, 0, 24, 0, 0, "Limit rotation on z-axis"); 
 
1378
                                        uiDefButF(block, NUM, B_CONSTRAINT_TEST, "min:", *xco+normButWidth, *yco-72, normButWidth, 18, &(data->zmin), -360, 360, 0.1,0.5,"Lowest z value to allow"); 
 
1379
                                        uiDefButF(block, NUM, B_CONSTRAINT_TEST, "max:", *xco+(normButWidth * 2), *yco-72, normButWidth, 18, &(data->zmax), -360, 360, 0.1,0.5,"Highest z value to allow"); 
 
1380
                                uiBlockEndAlign(block); 
 
1381
                                
 
1382
                                /* special option(s) */
 
1383
                                uiDefButBitS(block, TOG, LIMIT_TRANSFORM, B_CONSTRAINT_TEST, "For Transform", *xco+(width/4), *yco-100, (width/2), 18, &data->flag2, 0, 24, 0, 0, "Transforms are affected by this constraint as well"); 
 
1384
                                
 
1385
                                /* constraint space settings */
 
1386
                                draw_constraint_spaceselect(block, con, *xco, *yco-130, is_armature_owner(ob), -1);
 
1387
                        }
 
1388
                        break;
 
1389
                case CONSTRAINT_TYPE_SIZELIMIT:
 
1390
                        {
 
1391
                                bSizeLimitConstraint *data = con->data;
 
1392
                                
 
1393
                                int togButWidth = 50;
 
1394
                                int textButWidth = ((width/2)-togButWidth);
 
1395
                                
 
1396
                                height = 136; 
 
1397
                                        
 
1398
                                uiDefBut(block, ROUNDBOX, B_DIFF, "", *xco-10, *yco-height, width+40,height-1, NULL, 5.0, 0.0, 12, rb_col, ""); 
 
1399
                                
 
1400
                                /* Draw Pairs of LimitToggle+LimitValue */
 
1401
                                uiBlockBeginAlign(block); 
 
1402
                                        uiDefButBitS(block, TOG, LIMIT_XMIN, B_CONSTRAINT_TEST, "minX", *xco, *yco-28, togButWidth, 18, &data->flag, 0, 24, 0, 0, "Use minimum x value"); 
 
1403
                                        uiDefButF(block, NUM, B_CONSTRAINT_TEST, "", *xco+togButWidth, *yco-28, (textButWidth-5), 18, &(data->xmin), 0.0001, 1000, 0.1,0.5,"Lowest x value to allow"); 
 
1404
                                uiBlockEndAlign(block); 
 
1405
                                
 
1406
                                uiBlockBeginAlign(block); 
 
1407
                                        uiDefButBitS(block, TOG, LIMIT_XMAX, B_CONSTRAINT_TEST, "maxX", *xco+(width-(textButWidth-5)-togButWidth), *yco-28, 50, 18, &data->flag, 0, 24, 0, 0, "Use maximum x value"); 
 
1408
                                        uiDefButF(block, NUM, B_CONSTRAINT_TEST, "", *xco+(width-textButWidth-5), *yco-28, (textButWidth-5), 18, &(data->xmax), 0.0001, 1000, 0.1,0.5,"Highest x value to allow"); 
 
1409
                                uiBlockEndAlign(block); 
 
1410
                                
 
1411
                                
 
1412
                                uiBlockBeginAlign(block); 
 
1413
                                        uiDefButBitS(block, TOG, LIMIT_YMIN, B_CONSTRAINT_TEST, "minY", *xco, *yco-50, togButWidth, 18, &data->flag, 0, 24, 0, 0, "Use minimum y value"); 
 
1414
                                        uiDefButF(block, NUM, B_CONSTRAINT_TEST, "", *xco+togButWidth, *yco-50, (textButWidth-5), 18, &(data->ymin), 0.0001, 1000, 0.1,0.5,"Lowest y value to allow"); 
 
1415
                                uiBlockEndAlign(block); 
 
1416
                                
 
1417
                                uiBlockBeginAlign(block); 
 
1418
                                        uiDefButBitS(block, TOG, LIMIT_YMAX, B_CONSTRAINT_TEST, "maxY", *xco+(width-(textButWidth-5)-togButWidth), *yco-50, 50, 18, &data->flag, 0, 24, 0, 0, "Use maximum y value"); 
 
1419
                                        uiDefButF(block, NUM, B_CONSTRAINT_TEST, "", *xco+(width-textButWidth-5), *yco-50, (textButWidth-5), 18, &(data->ymax), 0.0001, 1000, 0.1,0.5,"Highest y value to allow"); 
 
1420
                                uiBlockEndAlign(block); 
 
1421
                                
 
1422
                                
 
1423
                                uiBlockBeginAlign(block); 
 
1424
                                        uiDefButBitS(block, TOG, LIMIT_ZMIN, B_CONSTRAINT_TEST, "minZ", *xco, *yco-72, togButWidth, 18, &data->flag, 0, 24, 0, 0, "Use minimum z value"); 
 
1425
                                        uiDefButF(block, NUM, B_CONSTRAINT_TEST, "", *xco+togButWidth, *yco-72, (textButWidth-5), 18, &(data->zmin), 0.0001, 1000, 0.1,0.5,"Lowest z value to allow"); 
 
1426
                                uiBlockEndAlign(block); 
 
1427
                                
 
1428
                                uiBlockBeginAlign(block); 
 
1429
                                        uiDefButBitS(block, TOG, LIMIT_ZMAX, B_CONSTRAINT_TEST, "maxZ", *xco+(width-(textButWidth-5)-togButWidth), *yco-72, 50, 18, &data->flag, 0, 24, 0, 0, "Use maximum z value"); 
 
1430
                                        uiDefButF(block, NUM, B_CONSTRAINT_TEST, "", *xco+(width-textButWidth-5), *yco-72, (textButWidth-5), 18, &(data->zmax), 0.0001, 1000, 0.1,0.5,"Highest z value to allow"); 
 
1431
                                uiBlockEndAlign(block);
 
1432
                                
 
1433
                                /* special option(s) */
 
1434
                                uiDefButBitS(block, TOG, LIMIT_TRANSFORM, B_CONSTRAINT_TEST, "For Transform", *xco+(width/4), *yco-100, (width/2), 18, &data->flag2, 0, 24, 0, 0, "Transforms are affected by this constraint as well"); 
 
1435
                                
 
1436
                                /* constraint space settings */
 
1437
                                draw_constraint_spaceselect(block, con, *xco, *yco-130, is_armature_owner(ob), -1);
 
1438
                        }
 
1439
                        break;
 
1440
                case CONSTRAINT_TYPE_DISTLIMIT:
 
1441
                        {
 
1442
                                bDistLimitConstraint *data = con->data;
 
1443
                                
 
1444
                                height = 105;
 
1445
                                uiDefBut(block, ROUNDBOX, B_DIFF, "", *xco-10, *yco-height, width+40,height-1, NULL, 5.0, 0.0, 12, rb_col, ""); 
 
1446
                                
 
1447
                                uiDefBut(block, LABEL, B_CONSTRAINT_TEST, "Target:", *xco+65, *yco-24, 50, 18, NULL, 0.0, 0.0, 0.0, 0.0, ""); 
 
1448
                                
 
1449
                                /* Draw target parameters */
 
1450
                                uiBlockBeginAlign(block);
 
1451
                                        uiDefIDPoinBut(block, test_obpoin_but, ID_OB, B_CONSTRAINT_CHANGETARGET, "OB:", *xco+120, *yco-24, 135, 18, &data->tar, "Target Object"); 
 
1452
                                        
 
1453
                                        if (is_armature_target(data->tar)) {
 
1454
                                                but=uiDefBut(block, TEX, B_CONSTRAINT_CHANGETARGET, "BO:", *xco+120, *yco-42,135,18, &data->subtarget, 0, 24, 0, 0, "Subtarget Bone");
 
1455
                                                uiButSetCompleteFunc(but, autocomplete_bone, (void *)data->tar);
 
1456
                                        }
 
1457
                                        else if (is_geom_target(data->tar)) {
 
1458
                                                but= uiDefBut(block, TEX, B_CONSTRAINT_CHANGETARGET, "VG:", *xco+120, *yco-42,135,18, &data->subtarget, 0, 24, 0, 0, "Name of Vertex Group defining 'target' points");
 
1459
                                                uiButSetCompleteFunc(but, autocomplete_vgroup, (void *)data->tar);
 
1460
                                        }
 
1461
                                        else {
 
1462
                                                strcpy(data->subtarget, "");
 
1463
                                        }
 
1464
                                uiBlockEndAlign(block);
 
1465
                                
 
1466
                                uiBlockBeginAlign(block);
 
1467
                                        if (is_armature_target(data->tar)) {
 
1468
                                                uiDefButF(block, BUTM, B_CONSTRAINT_TEST, "R", *xco, *yco-60, 20, 18, &data->dist, 0, 0, 0, 0, "Recalculate distance"); 
 
1469
                                                uiDefButF(block, NUM, B_CONSTRAINT_TEST, "Distance:", *xco+18, *yco-60,139,18, &data->dist, 0.0, 100, 0.5, 0.5, "Radius of limiting sphere");
 
1470
                                                uiDefButF(block, NUM, B_CONSTRAINT_TEST, "Head/Tail:", *xco+155, *yco-60,100,18, &con->headtail, 0.0, 1, 0.1, 0.1, "Target along length of bone: Head=0, Tail=1");
 
1471
                                        }
 
1472
                                        else {
 
1473
                                                uiDefButF(block, BUTM, B_CONSTRAINT_TEST, "R", *xco, *yco-60, 20, 18, &data->dist, 0, 0, 0, 0, "Recalculate distance"); 
 
1474
                                                uiDefButF(block, NUM, B_CONSTRAINT_TEST, "Distance:", *xco+18, *yco-60, 237, 18, &data->dist, 0.0, 100, 0.5, 0.5, "Radius of limiting sphere");
 
1475
                                        }
 
1476
                                        
 
1477
                                        /* disabled soft-distance controls... currently it doesn't work yet. It was intended to be used for soft-ik (see xsi-blog for details) */
 
1478
#if 0
 
1479
                                        uiDefButBitS(block, TOG, LIMITDIST_USESOFT, B_CONSTRAINT_TEST, "Soft", *xco, *yco-82, 50, 18, &data->flag, 0, 24, 0, 0, "Enables soft-distance");
 
1480
                                        if (data->flag & LIMITDIST_USESOFT)
 
1481
                                                uiDefButF(block, NUM, B_CONSTRAINT_TEST, "Soft-Distance:", *xco+50, *yco-82, 187, 18, &data->soft, 0.0, 100, 0.5, 0.5, "Distance surrounding radius when transforms should get 'delayed'");
 
1482
#endif
 
1483
                                uiBlockEndAlign(block);
 
1484
                                
 
1485
                                uiDefBut(block, LABEL, B_CONSTRAINT_TEST, "Clamp Region:",*xco+((width/2)-110), *yco-104,100,18, NULL, 0.0, 0.0, 0.0, 0.0, ""); 
 
1486
                                uiDefButS(block, MENU, B_CONSTRAINT_TEST, "Limit Mode%t|Inside %x0|Outside %x1|Surface %x2", *xco+(width/2), *yco-104, 100, 18, &data->mode, 0, 24, 0, 0, "Distances in relation to sphere of influence to allow");
 
1487
                        }
 
1488
                        break;
 
1489
                case CONSTRAINT_TYPE_RIGIDBODYJOINT:
 
1490
                        {
 
1491
                                bRigidBodyJointConstraint *data = con->data;
 
1492
                                float extremeLin = 999.f;
 
1493
                                float extremeAngX = 180.f;
 
1494
                                float extremeAngY = 45.f;
 
1495
                                float extremeAngZ = 45.f;
 
1496
                                int togButWidth = 70;
 
1497
                                int offsetY = 150;
 
1498
                                int textButWidth = ((width/2)-togButWidth);
 
1499
                                
 
1500
                height = 140;
 
1501
                                if (data->type==CONSTRAINT_RB_GENERIC6DOF)
 
1502
                                        height = 270;
 
1503
                                if (data->type==CONSTRAINT_RB_CONETWIST)
 
1504
                                        height = 200;
 
1505
                                
 
1506
                                uiDefBut(block, ROUNDBOX, B_DIFF, "", *xco-10, *yco-height, width+40,height-1, NULL, 5.0, 0.0, 12, rb_col, "");
 
1507
 
 
1508
                                uiDefButI(block, MENU, B_CONSTRAINT_TEST, "Joint Types%t|Ball%x1|Hinge%x2|Cone Twist%x4|Generic (experimental)%x12",//|Extra Force%x6",
 
1509
                                                                                                *xco, *yco-25, 150, 18, &data->type, 0, 0, 0, 0, "Choose the joint type");
 
1510
 
 
1511
                                uiDefButBitS(block, TOG, CONSTRAINT_DISABLE_LINKED_COLLISION, B_CONSTRAINT_TEST, "No Col.", *xco+155, *yco-25, 111, 18, &data->flag, 0, 24, 0, 0, "Disable Collision Between Linked Bodies");
 
1512
 
 
1513
 
 
1514
                                uiDefIDPoinBut(block, test_obpoin_but, ID_OB, B_CONSTRAINT_CHANGETARGET, "toObject:", *xco, *yco-50, 130, 18, &data->tar, "Child Object");
 
1515
                                uiDefButBitS(block, TOG, CONSTRAINT_DRAW_PIVOT, B_CONSTRAINT_TEST, "ShowPivot", *xco+135, *yco-50, 130, 18, &data->flag, 0, 24, 0, 0, "Show pivot position and rotation");                              
 
1516
                                
 
1517
                                uiDefButF(block, NUM, B_CONSTRAINT_TEST, "Pivot X:", *xco, *yco-75, 130, 18, &data->pivX, -1000, 1000, 100, 0.0, "Offset pivot on X");
 
1518
                                uiDefButF(block, NUM, B_CONSTRAINT_TEST, "Pivot Y:", *xco, *yco-100, 130, 18, &data->pivY, -1000, 1000, 100, 0.0, "Offset pivot on Y");
 
1519
                                uiDefButF(block, NUM, B_CONSTRAINT_TEST, "Pivot Z:", *xco, *yco-125, 130, 18, &data->pivZ, -1000, 1000, 100, 0.0, "Offset pivot on z");
 
1520
                                
 
1521
                                uiDefButF(block, NUM, B_CONSTRAINT_TEST, "Ax X:", *xco+135, *yco-75, 130, 18, &data->axX, -360, 360, 1500, 0.0, "Rotate pivot on X Axis (in degrees)");
 
1522
                                uiDefButF(block, NUM, B_CONSTRAINT_TEST, "Ax Y:", *xco+135, *yco-100, 130, 18, &data->axY, -360, 360, 1500, 0.0, "Rotate pivot on Y Axis (in degrees)");
 
1523
                                uiDefButF(block, NUM, B_CONSTRAINT_TEST, "Ax Z:", *xco+135, *yco-125, 130, 18, &data->axZ, -360, 360, 1500, 0.0, "Rotate pivot on Z Axis (in degrees)");
 
1524
                                
 
1525
                                if (data->type==CONSTRAINT_RB_GENERIC6DOF) {
 
1526
                                        /* Draw Pairs of LimitToggle+LimitValue */
 
1527
                                        uiBlockBeginAlign(block); 
 
1528
                                                uiDefButBitS(block, TOG, 1, B_CONSTRAINT_TEST, "LinMinX", *xco, *yco-offsetY, togButWidth, 18, &data->flag, 0, 24, 0, 0, "Use minimum x limit"); 
 
1529
                                                uiDefButF(block, NUM, B_CONSTRAINT_TEST, "", *xco+togButWidth, *yco-offsetY, (textButWidth-5), 18, &(data->minLimit[0]), -extremeLin, extremeLin, 0.1,0.5,"min x limit"); 
 
1530
                                        uiBlockEndAlign(block);
 
1531
                                        
 
1532
                                        uiBlockBeginAlign(block); 
 
1533
                                                uiDefButBitS(block, TOG, 1, B_CONSTRAINT_TEST, "LinMaxX", *xco+(width-(textButWidth-5)-togButWidth), *yco-offsetY, togButWidth, 18, &data->flag, 0, 24, 0, 0, "Use maximum x limit"); 
 
1534
                                                uiDefButF(block, NUM, B_CONSTRAINT_TEST, "", *xco+(width-textButWidth-5), *yco-offsetY, (textButWidth), 18, &(data->maxLimit[0]), -extremeLin, extremeLin, 0.1,0.5,"max x limit"); 
 
1535
                                        uiBlockEndAlign(block);
 
1536
                                        
 
1537
                                        offsetY += 20;
 
1538
                                        uiBlockBeginAlign(block); 
 
1539
                                                uiDefButBitS(block, TOG, 2, B_CONSTRAINT_TEST, "LinMinY", *xco, *yco-offsetY, togButWidth, 18, &data->flag, 0, 24, 0, 0, "Use minimum y limit"); 
 
1540
                                                uiDefButF(block, NUM, B_CONSTRAINT_TEST, "", *xco+togButWidth, *yco-offsetY, (textButWidth-5), 18, &(data->minLimit[1]), -extremeLin, extremeLin, 0.1,0.5,"min y limit"); 
 
1541
                                        uiBlockEndAlign(block);
 
1542
                                        
 
1543
                                        uiBlockBeginAlign(block); 
 
1544
                                                uiDefButBitS(block, TOG, 2, B_CONSTRAINT_TEST, "LinMaxY", *xco+(width-(textButWidth-5)-togButWidth), *yco-offsetY, togButWidth, 18, &data->flag, 0, 24, 0, 0, "Use maximum y limit"); 
 
1545
                                                uiDefButF(block, NUM, B_CONSTRAINT_TEST, "", *xco+(width-textButWidth-5), *yco-offsetY, (textButWidth), 18, &(data->maxLimit[1]), -extremeLin, extremeLin, 0.1,0.5,"max y limit"); 
 
1546
                                        uiBlockEndAlign(block);
 
1547
                                        
 
1548
                                        offsetY += 20;
 
1549
                                        uiBlockBeginAlign(block); 
 
1550
                                                uiDefButBitS(block, TOG, 4, B_CONSTRAINT_TEST, "LinMinZ", *xco, *yco-offsetY, togButWidth, 18, &data->flag, 0, 24, 0, 0, "Use minimum z limit"); 
 
1551
                                                uiDefButF(block, NUM, B_CONSTRAINT_TEST, "", *xco+togButWidth, *yco-offsetY, (textButWidth-5), 18, &(data->minLimit[2]), -extremeLin, extremeLin, 0.1,0.5,"min z limit"); 
 
1552
                                        uiBlockEndAlign(block);
 
1553
                                        
 
1554
                                        uiBlockBeginAlign(block); 
 
1555
                                                uiDefButBitS(block, TOG, 4, B_CONSTRAINT_TEST, "LinMaxZ", *xco+(width-(textButWidth-5)-togButWidth), *yco-offsetY, togButWidth, 18, &data->flag, 0, 24, 0, 0, "Use maximum z limit"); 
 
1556
                                                uiDefButF(block, NUM, B_CONSTRAINT_TEST, "", *xco+(width-textButWidth-5), *yco-offsetY, (textButWidth), 18, &(data->maxLimit[2]), -extremeLin, extremeLin, 0.1,0.5,"max z limit"); 
 
1557
                                        uiBlockEndAlign(block);
 
1558
                                        offsetY += 20;
 
1559
                                }
 
1560
                                if ((data->type==CONSTRAINT_RB_GENERIC6DOF) || (data->type==CONSTRAINT_RB_CONETWIST)) {
 
1561
                                        /* Draw Pairs of LimitToggle+LimitValue */
 
1562
                                        uiBlockBeginAlign(block); 
 
1563
                                                uiDefButBitS(block, TOG, 8, B_CONSTRAINT_TEST, "AngMinX", *xco, *yco-offsetY, togButWidth, 18, &data->flag, 0, 24, 0, 0, "Use minimum x limit"); 
 
1564
                                                uiDefButF(block, NUM, B_CONSTRAINT_TEST, "", *xco+togButWidth, *yco-offsetY, (textButWidth-5), 18, &(data->minLimit[3]), -extremeAngX, extremeAngX, 0.1,0.5,"min x limit"); 
 
1565
                                        uiBlockEndAlign(block);
 
1566
                                        uiBlockBeginAlign(block); 
 
1567
                                                uiDefButBitS(block, TOG, 8, B_CONSTRAINT_TEST, "AngMaxX", *xco+(width-(textButWidth-5)-togButWidth), *yco-offsetY, togButWidth, 18, &data->flag, 0, 24, 0, 0, "Use maximum x limit"); 
 
1568
                                                uiDefButF(block, NUM, B_CONSTRAINT_TEST, "", *xco+(width-textButWidth-5), *yco-offsetY, (textButWidth), 18, &(data->maxLimit[3]), -extremeAngX, extremeAngX, 0.1,0.5,"max x limit"); 
 
1569
                                        uiBlockEndAlign(block);
 
1570
                                        
 
1571
                                        offsetY += 20;
 
1572
                                        uiBlockBeginAlign(block); 
 
1573
                                                uiDefButBitS(block, TOG, 16, B_CONSTRAINT_TEST, "AngMinY", *xco, *yco-offsetY, togButWidth, 18, &data->flag, 0, 24, 0, 0, "Use minimum y limit"); 
 
1574
                                                uiDefButF(block, NUM, B_CONSTRAINT_TEST, "", *xco+togButWidth, *yco-offsetY, (textButWidth-5), 18, &(data->minLimit[4]), -extremeAngY, extremeAngY, 0.1,0.5,"min y limit"); 
 
1575
                                        uiBlockEndAlign(block);
 
1576
                                        
 
1577
                                        uiBlockBeginAlign(block); 
 
1578
                                                uiDefButBitS(block, TOG, 16, B_CONSTRAINT_TEST, "AngMaxY", *xco+(width-(textButWidth-5)-togButWidth), *yco-offsetY, togButWidth, 18, &data->flag, 0, 24, 0, 0, "Use maximum y limit"); 
 
1579
                                                uiDefButF(block, NUM, B_CONSTRAINT_TEST, "", *xco+(width-textButWidth-5), *yco-offsetY, (textButWidth), 18, &(data->maxLimit[4]), -extremeAngY, extremeAngY, 0.1,0.5,"max y limit"); 
 
1580
                                        uiBlockEndAlign(block);
 
1581
                                        
 
1582
                                        offsetY += 20;
 
1583
                                        uiBlockBeginAlign(block); 
 
1584
                                                uiDefButBitS(block, TOG, 32, B_CONSTRAINT_TEST, "AngMinZ", *xco, *yco-offsetY, togButWidth, 18, &data->flag, 0, 24, 0, 0, "Use minimum z limit"); 
 
1585
                                                uiDefButF(block, NUM, B_CONSTRAINT_TEST, "", *xco+togButWidth, *yco-offsetY, (textButWidth-5), 18, &(data->minLimit[5]), -extremeAngZ, extremeAngZ, 0.1,0.5,"min z limit"); 
 
1586
                                        uiBlockEndAlign(block);
 
1587
                                        
 
1588
                                        uiBlockBeginAlign(block); 
 
1589
                                                uiDefButBitS(block, TOG, 32, B_CONSTRAINT_TEST, "AngMaxZ", *xco+(width-(textButWidth-5)-togButWidth), *yco-offsetY, togButWidth, 18, &data->flag, 0, 24, 0, 0, "Use maximum z limit"); 
 
1590
                                                uiDefButF(block, NUM, B_CONSTRAINT_TEST, "", *xco+(width-textButWidth-5), *yco-offsetY, (textButWidth), 18, &(data->maxLimit[5]), -extremeAngZ, extremeAngZ, 0.1,0.5,"max z limit"); 
 
1591
                                        uiBlockEndAlign(block);
 
1592
                                }
 
1593
                                
 
1594
                        }
 
1595
                        break;
 
1596
                case CONSTRAINT_TYPE_CLAMPTO:
 
1597
                        {
 
1598
                                bClampToConstraint *data = con->data;
 
1599
                                
 
1600
                                height = 90;
 
1601
                                uiDefBut(block, ROUNDBOX, B_DIFF, "", *xco-10, *yco-height, width+40,height-1, NULL, 5.0, 0.0, 12, rb_col, ""); 
 
1602
                                
 
1603
                                uiDefBut(block, LABEL, B_CONSTRAINT_TEST, "Target:", *xco+65, *yco-24, 50, 18, NULL, 0.0, 0.0, 0.0, 0.0, ""); 
 
1604
                                
 
1605
                                /* Draw target parameters */
 
1606
                                uiDefIDPoinBut(block, test_obpoin_but, ID_OB, B_CONSTRAINT_CHANGETARGET, "OB:", *xco+120, *yco-24, 135, 18, &data->tar, "Target Object"); 
 
1607
                                
 
1608
                                /* Draw XYZ toggles */
 
1609
                                uiBlockBeginAlign(block);
 
1610
                                        uiDefBut(block, LABEL, B_CONSTRAINT_TEST, "Main Axis:", *xco, *yco-64, 90, 18, NULL, 0.0, 0.0, 0.0, 0.0, ""); 
 
1611
                                        uiDefButI(block, ROW, B_CONSTRAINT_TEST, "Auto", *xco+100, *yco-64, 50, 18, &data->flag, 12.0, CLAMPTO_AUTO, 0, 0, "Automatically determine main-axis of movement");
 
1612
                                        uiDefButI(block, ROW, B_CONSTRAINT_TEST, "X", *xco+150, *yco-64, 32, 18, &data->flag, 12.0, CLAMPTO_X, 0, 0, "Main axis of movement is x-axis");
 
1613
                                        uiDefButI(block, ROW, B_CONSTRAINT_TEST, "Y", *xco+182, *yco-64, 32, 18, &data->flag, 12.0, CLAMPTO_Y, 0, 0, "Main axis of movement is y-axis");
 
1614
                                        uiDefButI(block, ROW, B_CONSTRAINT_TEST, "Z", *xco+214, *yco-64, 32, 18, &data->flag, 12.0, CLAMPTO_Z, 0, 0, "Main axis of movement is z-axis");
 
1615
                                uiBlockEndAlign(block);
 
1616
                                
 
1617
                                /* Extra Options Controlling Behaviour */
 
1618
                                //uiBlockBeginAlign(block);
 
1619
                                        uiDefBut(block, LABEL, B_CONSTRAINT_TEST, "Options:", *xco, *yco-88, 90, 18, NULL, 0.0, 0.0, 0.0, 0.0, ""); 
 
1620
                                        uiDefButBitI(block, TOG, CLAMPTO_CYCLIC, B_CONSTRAINT_TEST, "Cyclic", *xco+((width/2)), *yco-88,60,19, &data->flag2, 0, 0, 0, 0, "Treat curve as cyclic curve (no clamping to curve bounding box)");
 
1621
                                //uiBlockEndAlign(block);
 
1622
                        }
 
1623
                        break;
 
1624
                case CONSTRAINT_TYPE_TRANSFORM:
 
1625
                        {
 
1626
                                bTransformConstraint *data = con->data;
 
1627
                                float fmin, fmax, tmin, tmax;
 
1628
                                
 
1629
                                height = 178;
 
1630
                                uiDefBut(block, ROUNDBOX, B_DIFF, "", *xco-10, *yco-height, width+40,height-1, NULL, 5.0, 0.0, 12, rb_col, ""); 
 
1631
                                
 
1632
                                /* Draw target parameters */                    
 
1633
                                uiDefBut(block, LABEL, B_CONSTRAINT_TEST, "Target:", *xco+65, *yco-24, 50, 18, NULL, 0.0, 0.0, 0.0, 0.0, ""); 
 
1634
                                
 
1635
                                /* Draw target parameters */
 
1636
                                uiBlockBeginAlign(block);
 
1637
                                        uiDefIDPoinBut(block, test_obpoin_but, ID_OB, B_CONSTRAINT_CHANGETARGET, "OB:", *xco+120, *yco-24, 135, 18, &data->tar, "Target Object to use as Parent"); 
 
1638
                                        
 
1639
                                        if (is_armature_target(data->tar)) {
 
1640
                                                but= uiDefBut(block, TEX, B_CONSTRAINT_CHANGETARGET, "BO:", *xco+120, *yco-42,135,18, &data->subtarget, 0, 24, 0, 0, "Subtarget Bone to use as Parent");
 
1641
                                                uiButSetCompleteFunc(but, autocomplete_bone, (void *)data->tar);
 
1642
                                        }
 
1643
                                        else if (is_geom_target(data->tar)) {
 
1644
                                                but= uiDefBut(block, TEX, B_CONSTRAINT_CHANGETARGET, "VG:", *xco+120, *yco-42,135,18, &data->subtarget, 0, 24, 0, 0, "Name of Vertex Group defining 'target' points");
 
1645
                                                uiButSetCompleteFunc(but, autocomplete_vgroup, (void *)data->tar);
 
1646
                                        }
 
1647
                                        else {
 
1648
                                                strcpy(data->subtarget, "");
 
1649
                                        }
 
1650
                                uiBlockEndAlign(block);
 
1651
                                
 
1652
                                /* Extrapolate Ranges? */
 
1653
                                uiDefButBitC(block, TOG, 1, B_CONSTRAINT_TEST, "Extrapolate", *xco-10, *yco-42,80,19, &data->expo, 0, 0, 0, 0, "Extrapolate ranges");
 
1654
                                
 
1655
                                /* Draw options for source motion */
 
1656
                                uiDefBut(block, LABEL, B_CONSTRAINT_TEST, "Source:", *xco-10, *yco-62, 50, 18, NULL, 0.0, 0.0, 0.0, 0.0, ""); 
 
1657
                                
 
1658
                                /*      draw Loc/Rot/Size toggles       */
 
1659
                                uiBlockBeginAlign(block);
 
1660
                                        uiDefButS(block, ROW, B_CONSTRAINT_TEST, "Loc", *xco-5, *yco-82, 45, 18, &data->from, 12.0, 0, 0, 0, "Use Location transform channels from Target");
 
1661
                                        uiDefButS(block, ROW, B_CONSTRAINT_TEST, "Rot", *xco+40, *yco-82, 45, 18, &data->from, 12.0, 1, 0, 0, "Use Rotation transform channels from Target");
 
1662
                                        uiDefButS(block, ROW, B_CONSTRAINT_TEST, "Scale", *xco+85, *yco-82, 45, 18, &data->from, 12.0, 2, 0, 0, "Use Scale transform channels from Target");
 
1663
                                uiBlockEndAlign(block);
 
1664
                                
 
1665
                                /* Draw Pairs of Axis: Min/Max Value*/
 
1666
                                if (data->from == 2) {
 
1667
                                        fmin= 0.0001;
 
1668
                                        fmax= 1000.0;
 
1669
                                }
 
1670
                                else if (data->from == 1) {
 
1671
                                        fmin= -360.0;
 
1672
                                        fmax= 360.0;
 
1673
                                }
 
1674
                                else {
 
1675
                                        fmin = -1000.0;
 
1676
                                        fmax= 1000.0;
 
1677
                                }
 
1678
                                
 
1679
                                uiBlockBeginAlign(block); 
 
1680
                                        uiDefBut(block, LABEL, B_CONSTRAINT_TEST, "X:", *xco-10, *yco-107, 30, 18, NULL, 0.0, 0.0, 0.0, 0.0, ""); 
 
1681
                                        uiDefButF(block, NUM, B_CONSTRAINT_TEST, "min", *xco+20, *yco-107, 55, 18, &data->from_min[0], fmin, fmax, 0, 0, "Bottom of range of x-axis source motion for source->target mapping"); 
 
1682
                                        uiDefButF(block, NUM, B_CONSTRAINT_TEST, "max", *xco+75, *yco-107, 55, 18, &data->from_max[0], fmin, fmax, 0, 0, "Top of range of x-axis source motion for source->target mapping"); 
 
1683
                                uiBlockEndAlign(block); 
 
1684
                                
 
1685
                                uiBlockBeginAlign(block); 
 
1686
                                        uiDefBut(block, LABEL, B_CONSTRAINT_TEST, "Y:", *xco-10, *yco-127, 30, 18, NULL, 0.0, 0.0, 0.0, 0.0, ""); 
 
1687
                                        uiDefButF(block, NUM, B_CONSTRAINT_TEST, "min", *xco+20, *yco-127, 55, 18, &data->from_min[1], fmin, fmax, 0, 0, "Bottom of range of y-axis source motion for source->target mapping"); 
 
1688
                                        uiDefButF(block, NUM, B_CONSTRAINT_TEST, "max", *xco+75, *yco-127, 55, 18, &data->from_max[1], fmin, fmax, 0, 0, "Top of range of y-axis source motion for source->target mapping"); 
 
1689
                                uiBlockEndAlign(block);
 
1690
                                
 
1691
                                uiBlockBeginAlign(block); 
 
1692
                                        uiDefBut(block, LABEL, B_CONSTRAINT_TEST, "Z:", *xco-10, *yco-147, 30, 18, NULL, 0.0, 0.0, 0.0, 0.0, ""); 
 
1693
                                        uiDefButF(block, NUM, B_CONSTRAINT_TEST, "min", *xco+20, *yco-147, 55, 18, &data->from_min[2], fmin, fmax, 0, 0, "Bottom of range of z-axis source motion for source->target mapping"); 
 
1694
                                        uiDefButF(block, NUM, B_CONSTRAINT_TEST, "max", *xco+75, *yco-147, 55, 18, &data->from_max[2], fmin, fmax, 0, 0, "Top of range of z-axis source motion for source->target mapping"); 
 
1695
                                uiBlockEndAlign(block); 
 
1696
                                
 
1697
                                
 
1698
                                /* Draw options for target motion */
 
1699
                                uiDefBut(block, LABEL, B_CONSTRAINT_TEST, "Destination:", *xco+150, *yco-62, 150, 18, NULL, 0.0, 0.0, 0.0, 0.0, ""); 
 
1700
                                
 
1701
                                /*      draw Loc/Rot/Size toggles       */
 
1702
                                uiBlockBeginAlign(block);
 
1703
                                        uiDefButS(block, ROW, B_CONSTRAINT_TEST, "Loc", *xco+150, *yco-82, 45, 18, &data->to, 12.0, 0, 0, 0, "Use as Location transform");
 
1704
                                        uiDefButS(block, ROW, B_CONSTRAINT_TEST, "Rot", *xco+195, *yco-82, 45, 18, &data->to, 12.0, 1, 0, 0, "Use as Rotation transform");
 
1705
                                        uiDefButS(block, ROW, B_CONSTRAINT_TEST, "Scale", *xco+245, *yco-82, 45, 18, &data->to, 12.0, 2, 0, 0, "Use as Scale transform");
 
1706
                                uiBlockEndAlign(block);
 
1707
                                
 
1708
                                /* Draw Pairs of Source-Axis: Min/Max Value*/
 
1709
                                if (data->to == 2) {
 
1710
                                        tmin= 0.0001;
 
1711
                                        tmax= 1000.0;
 
1712
                                }
 
1713
                                else if (data->to == 1) {
 
1714
                                        tmin= -360.0;
 
1715
                                        tmax= 360.0;
 
1716
                                }
 
1717
                                else {
 
1718
                                        tmin = -1000.0;
 
1719
                                        tmax= 1000.0;
 
1720
                                }
 
1721
                                
 
1722
                                uiBlockBeginAlign(block); 
 
1723
                                        uiDefButC(block, MENU, B_CONSTRAINT_TEST, "Axis Mapping%t|X->X%x0|Y->X%x1|Z->X%x2", *xco+150, *yco-107, 40, 18, &data->map[0], 0, 24, 0, 0, "Specify which source axis the x-axis destination uses");
 
1724
                                        uiDefButF(block, NUM, B_CONSTRAINT_TEST, "min", *xco+175, *yco-107, 50, 18, &data->to_min[0], tmin, tmax, 0, 0, "Bottom of range of x-axis destination motion for source->target mapping"); 
 
1725
                                        uiDefButF(block, NUM, B_CONSTRAINT_TEST, "max", *xco+240, *yco-107, 50, 18, &data->to_max[0], tmin, tmax, 0, 0, "Top of range of x-axis destination motion for source->target mapping"); 
 
1726
                                uiBlockEndAlign(block); 
 
1727
                                
 
1728
                                uiBlockBeginAlign(block); 
 
1729
                                        uiDefButC(block, MENU, B_CONSTRAINT_TEST, "Axis Mapping%t|X->Y%x0|Y->Y%x1|Z->Y%x2", *xco+150, *yco-127, 40, 18, &data->map[1], 0, 24, 0, 0, "Specify which source axis the y-axis destination uses");
 
1730
                                        uiDefButF(block, NUM, B_CONSTRAINT_TEST, "min", *xco+175, *yco-127, 50, 18, &data->to_min[1], tmin, tmax, 0, 0, "Bottom of range of y-axis destination motion for source->target mapping"); 
 
1731
                                        uiDefButF(block, NUM, B_CONSTRAINT_TEST, "max", *xco+240, *yco-127, 50, 18, &data->to_max[1], tmin, tmax, 0, 0, "Top of range of y-axis destination motion for source->target mapping"); 
 
1732
                                uiBlockEndAlign(block);
 
1733
                                
 
1734
                                uiBlockBeginAlign(block); 
 
1735
                                        uiDefButC(block, MENU, B_CONSTRAINT_TEST, "Axis Mapping%t|X->Z%x0|Y->Z%x1|Z->Z%x2", *xco+150, *yco-147, 40, 18, &data->map[2], 0, 24, 0, 0, "Specify which source axis the z-axis destination uses");
 
1736
                                        uiDefButF(block, NUM, B_CONSTRAINT_TEST, "min", *xco+175, *yco-147, 50, 18, &data->to_min[2], tmin, tmax, 0, 0, "Bottom of range of z-axis destination motion for source->target mapping"); 
 
1737
                                        uiDefButF(block, NUM, B_CONSTRAINT_TEST, "max", *xco+240, *yco-147, 50, 18, &data->to_max[2], tmin, tmax, 0, 0, "Top of range of z-axis destination motion for source->target mapping"); 
 
1738
                                uiBlockEndAlign(block); 
 
1739
                                
 
1740
                                /* constraint space settings */
 
1741
                                draw_constraint_spaceselect(block, con, *xco, *yco-170, is_armature_owner(ob), is_armature_target(data->tar));
 
1742
                        }
 
1743
                        break;
 
1744
                case CONSTRAINT_TYPE_NULL:
 
1745
                        {
 
1746
                                height = 17;
 
1747
                                uiDefBut(block, ROUNDBOX, B_DIFF, "", *xco-10, *yco-height, width+40,height-1, NULL, 5.0, 0.0, 12, rb_col, ""); 
 
1748
                        }
 
1749
                        break;
 
1750
                default:
 
1751
                        height = 0;
 
1752
                        break;
 
1753
                }
 
1754
                
 
1755
                (*yco)-=(24+height);
 
1756
        }
 
1757
 
 
1758
        if (ELEM(con->type, CONSTRAINT_TYPE_NULL, CONSTRAINT_TYPE_RIGIDBODYJOINT)==0) {
 
1759
                uiBlockBeginAlign(block);
 
1760
                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");
 
1761
                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");
 
1762
                /* If this is on an object or bone, add ipo channel the constraint */
 
1763
                uiButSetFunc (but, enable_constraint_ipo_func, ob, con);
 
1764
                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");
 
1765
                /* Add a keyframe to the influence IPO */
 
1766
                uiButSetFunc (but, add_influence_key_to_constraint_func, ob, con);
 
1767
                uiBlockEndAlign(block);
 
1768
                (*yco)-=24;
 
1769
        } 
 
1770
        else {
 
1771
                (*yco)-=3;
 
1772
        }
 
1773
        
 
1774
        /* clear any locks set up for proxies/lib-linking */
 
1775
        uiClearButLock();
 
1776
}
 
1777
 
 
1778
static uiBlock *add_constraintmenu(void *arg_unused)
 
1779
{
 
1780
        Object *ob= OBACT;
 
1781
        uiBlock *block;
 
1782
        ListBase *conlist;
 
1783
        short yco= 0;
 
1784
        
 
1785
        conlist = get_active_constraints(ob);
 
1786
        
 
1787
        block= uiNewBlock(&curarea->uiblocks, "add_constraintmenu", UI_EMBOSSP, UI_HELV, curarea->win);
 
1788
 
 
1789
        uiDefBut(block, BUTM, B_CONSTRAINT_ADD_CHILDOF, "Child Of",                     0, yco-=20, 160, 19, NULL, 0.0, 0.0, 1, 0, "");
 
1790
        uiDefBut(block, BUTM, B_CONSTRAINT_ADD_TRANSFORM, "Transformation", 0, yco-=20, 160, 19, NULL, 0.0, 0.0, 1, 0, "");
 
1791
        
 
1792
        uiDefBut(block, SEPR, 0, "",                                    0, yco-=6, 120, 6, NULL, 0.0, 0.0, 0, 0, "");
 
1793
        
 
1794
        uiDefBut(block, BUTM, B_CONSTRAINT_ADD_LOCLIKE, "Copy Location", 0, yco-=20, 160, 19, NULL, 0.0, 0.0, 1, 0, "");
 
1795
        uiDefBut(block, BUTM, B_CONSTRAINT_ADD_ROTLIKE, "Copy Rotation", 0, yco-=20, 160, 19, NULL, 0.0, 0.0, 1, 0, "");
 
1796
        uiDefBut(block, BUTM, B_CONSTRAINT_ADD_SIZELIKE, "Copy Scale", 0, yco-=20, 160, 19, NULL, 0.0, 0.0, 1, 0, "");
 
1797
        
 
1798
        uiDefBut(block, SEPR, 0, "",                                    0, yco-=6, 120, 6, NULL, 0.0, 0.0, 0, 0, "");
 
1799
        
 
1800
        uiDefBut(block, BUTM, B_CONSTRAINT_ADD_LOCLIMIT, "Limit Location", 0, yco-=20, 160, 19, NULL, 0.0, 0.0, 1, 0, "");
 
1801
        uiDefBut(block, BUTM, B_CONSTRAINT_ADD_ROTLIMIT, "Limit Rotation", 0, yco-=20, 160, 19, NULL, 0.0, 0.0, 1, 0, "");
 
1802
        uiDefBut(block, BUTM, B_CONSTRAINT_ADD_SIZELIMIT, "Limit Scale", 0, yco-=20, 160, 19, NULL, 0.0, 0.0, 1, 0, "");
 
1803
        uiDefBut(block, BUTM, B_CONSTRAINT_ADD_DISTLIMIT, "Limit Distance", 0, yco-=20, 160, 19, NULL, 0.0, 0.0, 1, 0, "");
 
1804
        
 
1805
        uiDefBut(block, SEPR, 0, "",                                    0, yco-=6, 120, 6, NULL, 0.0, 0.0, 0, 0, "");
 
1806
        
 
1807
        uiDefBut(block, BUTM, B_CONSTRAINT_ADD_TRACKTO, "Track To",     0, yco-=20, 160, 19, NULL, 0.0, 0.0, 1, 0, "");
 
1808
        uiDefBut(block, BUTM, B_CONSTRAINT_ADD_MINMAX, "Floor", 0, yco-=20, 160, 19, NULL, 0.0, 0.0, 1, 0, "");
 
1809
        uiDefBut(block, BUTM, B_CONSTRAINT_ADD_LOCKTRACK, "Locked Track", 0, yco-=20, 160, 19, NULL, 0.0, 0.0, 1, 0, "");
 
1810
        uiDefBut(block, BUTM, B_CONSTRAINT_ADD_FOLLOWPATH, "Follow Path", 0, yco-=20, 160, 19, NULL, 0.0, 0.0, 1, 0, "");
 
1811
                
 
1812
        uiDefBut(block, SEPR, 0, "",                                    0, yco-=6, 120, 6, NULL, 0.0, 0.0, 0, 0, "");
 
1813
        
 
1814
        uiDefBut(block, BUTM, B_CONSTRAINT_ADD_CLAMPTO, "Clamp To", 0, yco-=20, 160, 19, NULL, 0.0, 0.0, 1, 0, "");
 
1815
        uiDefBut(block, BUTM, B_CONSTRAINT_ADD_STRETCHTO, "Stretch To", 0, yco-=20, 160, 19, NULL, 0.0, 0.0, 1, 0, "");
 
1816
 
 
1817
        uiDefBut(block, BUTM, B_CONSTRAINT_ADD_RIGIDBODYJOINT, "Rigid Body Joint", 0, yco-=20, 160, 19, NULL, 0.0, 0.0, 1, 0, "");//rcruiz
 
1818
 
 
1819
        uiDefBut(block, SEPR, 0, "",                                    0, yco-=6, 120, 6, NULL, 0.0, 0.0, 0, 0, "");
 
1820
        
 
1821
        if (ob->flag & OB_POSEMODE) {
 
1822
                uiDefBut(block, BUTM, B_CONSTRAINT_ADD_KINEMATIC, "IK Solver", 0, yco-=20, 160, 19, NULL, 0.0, 0.0, 1, 0, "");
 
1823
        }
 
1824
        uiDefBut(block, BUTM, B_CONSTRAINT_ADD_ACTION, "Action", 0, yco-=20, 160, 19, NULL, 0.0, 0.0, 1, 0, "");
 
1825
        
 
1826
        uiDefBut(block, SEPR, 0, "",                                    0, yco-=6, 120, 6, NULL, 0.0, 0.0, 0, 0, "");
 
1827
 
 
1828
        uiDefBut(block, BUTM, B_CONSTRAINT_ADD_PYTHON, "Script", 0, yco-=20, 160, 19, NULL, 0.0, 0.0, 1, 0, "");
 
1829
        
 
1830
        uiDefBut(block, SEPR, 0, "", 0, yco-=6, 120, 6, NULL, 0.0, 0.0, 0, 0, "");
 
1831
        
 
1832
        uiDefBut(block, BUTM, B_CONSTRAINT_ADD_NULL, "Null",    0, yco-=20, 160, 19, NULL, 0.0, 0.0, 1, 0, "");
 
1833
        
 
1834
        
 
1835
        uiTextBoundsBlock(block, 50);
 
1836
        uiBlockSetDirection(block, UI_DOWN);
 
1837
                
 
1838
        return block;
 
1839
}
 
1840
 
 
1841
void do_constraintbuts(unsigned short event)
 
1842
{
 
1843
        Object *ob= OBACT;
 
1844
        bConstraint *con;
 
1845
        
 
1846
        switch(event) {
 
1847
        case B_CONSTRAINT_TEST:
 
1848
                allqueue(REDRAWVIEW3D, 0);
 
1849
                allqueue(REDRAWBUTSOBJECT, 0);
 
1850
                break;  // no handling
 
1851
        case B_CONSTRAINT_INF:
 
1852
                /* influence; do not execute actions for 1 dag_flush */
 
1853
                if (ob->pose)
 
1854
                        ob->pose->flag |= (POSE_LOCKED|POSE_DO_UNLOCK);
 
1855
 
 
1856
        case B_CONSTRAINT_CHANGETARGET:
 
1857
                if (ob->pose) ob->pose->flag |= POSE_RECALC;    // checks & sorts pose channels
 
1858
                DAG_scene_sort(G.scene);
 
1859
                break;
 
1860
        
 
1861
        case B_CONSTRAINT_ADD_NULL:
 
1862
                {
 
1863
                        con = add_new_constraint(CONSTRAINT_TYPE_NULL);
 
1864
                        add_constraint_to_active(ob, con);
 
1865
                        
 
1866
                        BIF_undo_push("Add constraint");
 
1867
                }
 
1868
                break;
 
1869
        case B_CONSTRAINT_ADD_PYTHON:
 
1870
                {
 
1871
                        con = add_new_constraint(CONSTRAINT_TYPE_PYTHON);
 
1872
                        add_constraint_to_active(ob, con);
 
1873
                        
 
1874
                        BIF_undo_push("Add constraint");
 
1875
                }
 
1876
                break;  
 
1877
        case B_CONSTRAINT_ADD_KINEMATIC:
 
1878
                {
 
1879
                        con = add_new_constraint(CONSTRAINT_TYPE_KINEMATIC);
 
1880
                        add_constraint_to_active(ob, con);
 
1881
                        
 
1882
                        BIF_undo_push("Add constraint");
 
1883
                }
 
1884
                break;
 
1885
        case B_CONSTRAINT_ADD_CHILDOF:
 
1886
                {
 
1887
                        con= add_new_constraint(CONSTRAINT_TYPE_CHILDOF);
 
1888
                        add_constraint_to_active(ob, con);
 
1889
                        
 
1890
                        /* if this constraint is being added to a posechannel, make sure
 
1891
                         * the constraint gets evaluated in pose-space
 
1892
                         */
 
1893
                        if (ob->flag & OB_POSEMODE) {
 
1894
                                con->ownspace = CONSTRAINT_SPACE_POSE;
 
1895
                                con->flag |= CONSTRAINT_SPACEONCE;
 
1896
                        }
 
1897
                        
 
1898
                        BIF_undo_push("Add constraint");
 
1899
                }
 
1900
                break;
 
1901
        case B_CONSTRAINT_ADD_TRACKTO:
 
1902
                {
 
1903
                        con = add_new_constraint(CONSTRAINT_TYPE_TRACKTO);
 
1904
                        add_constraint_to_active(ob, con);
 
1905
                        
 
1906
                        BIF_undo_push("Add constraint");
 
1907
                }
 
1908
                break;
 
1909
        case B_CONSTRAINT_ADD_MINMAX:
 
1910
                {
 
1911
                        con = add_new_constraint(CONSTRAINT_TYPE_MINMAX);
 
1912
                        add_constraint_to_active(ob, con);
 
1913
                        
 
1914
                        BIF_undo_push("Add constraint");
 
1915
                }
 
1916
                break;
 
1917
        case B_CONSTRAINT_ADD_ROTLIKE:
 
1918
                {
 
1919
                        con = add_new_constraint(CONSTRAINT_TYPE_ROTLIKE);
 
1920
                        add_constraint_to_active(ob, con);
 
1921
                        
 
1922
                        BIF_undo_push("Add constraint");
 
1923
                }
 
1924
                break;
 
1925
        case B_CONSTRAINT_ADD_LOCLIKE:
 
1926
                {
 
1927
                        con = add_new_constraint(CONSTRAINT_TYPE_LOCLIKE);
 
1928
                        add_constraint_to_active(ob, con);
 
1929
                        
 
1930
                        BIF_undo_push("Add constraint");
 
1931
                }
 
1932
                break;
 
1933
        case B_CONSTRAINT_ADD_SIZELIKE:
 
1934
                {
 
1935
                        con = add_new_constraint(CONSTRAINT_TYPE_SIZELIKE);
 
1936
                        add_constraint_to_active(ob, con);
 
1937
                        
 
1938
                        BIF_undo_push("Add constraint");
 
1939
                }
 
1940
                break;
 
1941
        case B_CONSTRAINT_ADD_ACTION:
 
1942
                {
 
1943
                        con = add_new_constraint(CONSTRAINT_TYPE_ACTION);
 
1944
                        add_constraint_to_active(ob, con);
 
1945
                        
 
1946
                        BIF_undo_push("Add constraint");
 
1947
                }
 
1948
                break;
 
1949
        case B_CONSTRAINT_ADD_LOCKTRACK:
 
1950
                {
 
1951
                        con = add_new_constraint(CONSTRAINT_TYPE_LOCKTRACK);
 
1952
                        add_constraint_to_active(ob, con);
 
1953
                        
 
1954
                        BIF_undo_push("Add constraint");
 
1955
                }
 
1956
                break;
 
1957
        case B_CONSTRAINT_ADD_FOLLOWPATH:
 
1958
                {
 
1959
                        con = add_new_constraint(CONSTRAINT_TYPE_FOLLOWPATH);
 
1960
                        add_constraint_to_active(ob, con);
 
1961
                        
 
1962
                        BIF_undo_push("Add constraint");
 
1963
                }
 
1964
                break;
 
1965
        case B_CONSTRAINT_ADD_STRETCHTO:
 
1966
                {
 
1967
                        con = add_new_constraint(CONSTRAINT_TYPE_STRETCHTO);
 
1968
                        add_constraint_to_active(ob, con);
 
1969
                        
 
1970
                        BIF_undo_push("Add constraint");
 
1971
                }
 
1972
                break;
 
1973
        case B_CONSTRAINT_ADD_LOCLIMIT:
 
1974
                {
 
1975
                        con = add_new_constraint(CONSTRAINT_TYPE_LOCLIMIT);
 
1976
                        add_constraint_to_active(ob, con);
 
1977
                        
 
1978
                        BIF_undo_push("Add constraint");
 
1979
                }
 
1980
                break;
 
1981
        case B_CONSTRAINT_ADD_ROTLIMIT:
 
1982
                {
 
1983
                        con = add_new_constraint(CONSTRAINT_TYPE_ROTLIMIT);
 
1984
                        add_constraint_to_active(ob, con);
 
1985
                        
 
1986
                        BIF_undo_push("Add constraint");
 
1987
                }
 
1988
                break;
 
1989
        case B_CONSTRAINT_ADD_SIZELIMIT:
 
1990
                {
 
1991
                        con = add_new_constraint(CONSTRAINT_TYPE_SIZELIMIT);
 
1992
                        add_constraint_to_active(ob, con);
 
1993
                        
 
1994
                        BIF_undo_push("Add constraint");
 
1995
                }
 
1996
                break;
 
1997
        case B_CONSTRAINT_ADD_RIGIDBODYJOINT:
 
1998
                {
 
1999
                        bRigidBodyJointConstraint *data;
 
2000
                        Base *base_iter;
 
2001
                        
 
2002
                        con = add_new_constraint(CONSTRAINT_TYPE_RIGIDBODYJOINT);
 
2003
                        add_constraint_to_active(ob, con);
 
2004
                        
 
2005
                        /* set selected first object as target - moved from new_constraint_data */
 
2006
                        data = (bRigidBodyJointConstraint*)con->data;
 
2007
                        base_iter = G.scene->base.first;
 
2008
            while ( base_iter && !data->tar ) {
 
2009
                if( ( ( base_iter->flag & SELECT ) &&
 
2010
//                     ( base_iter->lay & G.vd->lay ) ) &&
 
2011
                    ( base_iter != G.scene->basact ) ))
 
2012
                                {
 
2013
                        data->tar=base_iter->object;
 
2014
                                                break;
 
2015
                                }
 
2016
                base_iter = base_iter->next;
 
2017
            }
 
2018
                        
 
2019
                        BIF_undo_push("Add constraint");
 
2020
                }
 
2021
                break;
 
2022
        case B_CONSTRAINT_ADD_CLAMPTO:
 
2023
                {
 
2024
                        con = add_new_constraint(CONSTRAINT_TYPE_CLAMPTO);
 
2025
                        add_constraint_to_active(ob, con);
 
2026
                        
 
2027
                        BIF_undo_push("Add constraint");
 
2028
                }
 
2029
                break;
 
2030
        case B_CONSTRAINT_ADD_TRANSFORM:
 
2031
                {
 
2032
                        con = add_new_constraint(CONSTRAINT_TYPE_TRANSFORM);
 
2033
                        add_constraint_to_active(ob, con);
 
2034
                        
 
2035
                        BIF_undo_push("Add constraint");
 
2036
                }
 
2037
                break;
 
2038
        case B_CONSTRAINT_ADD_DISTLIMIT:
 
2039
                {
 
2040
                        con = add_new_constraint(CONSTRAINT_TYPE_DISTLIMIT);
 
2041
                        add_constraint_to_active(ob, con);
 
2042
                        
 
2043
                        BIF_undo_push("Add constraint");
 
2044
                }
 
2045
                break;
 
2046
 
 
2047
        default:
 
2048
                break;
 
2049
        }
 
2050
 
 
2051
        object_test_constraints(ob);
 
2052
        
 
2053
        if(ob->pose) update_pose_constraint_flags(ob->pose);
 
2054
        
 
2055
        if(ob->type==OB_ARMATURE) DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA|OB_RECALC_OB);
 
2056
        else DAG_object_flush_update(G.scene, ob, OB_RECALC_OB);
 
2057
        
 
2058
        allqueue (REDRAWVIEW3D, 0);
 
2059
        allqueue (REDRAWBUTSOBJECT, 0);
 
2060
}
 
2061
 
 
2062
void pointcache_bake(PTCacheID *pid, int startframe)
 
2063
{
 
2064
        Base *base;
 
2065
        ScrArea *sa;
 
2066
    PointCache *cache;
 
2067
        ListBase pidlist;
 
2068
        float frameleno= G.scene->r.framelen;
 
2069
        int cfrao= CFRA, didbreak =0, endframe, cstart, cend;
 
2070
        
 
2071
        G.scene->r.framelen= 1.0;               // baking has to be in uncorrected time
 
2072
        sbSetInterruptCallBack(blender_test_break); // make softbody module ESC aware
 
2073
        G.afbreek=0; // init global break system
 
2074
        
 
2075
        if(pid) {
 
2076
            cache= pid->cache;
 
2077
 
 
2078
                BKE_ptcache_id_time(pid, 0.0f, &cstart, &cend, NULL);
 
2079
 
 
2080
                startframe= startframe;
 
2081
                endframe= cend;
 
2082
 
 
2083
                cache->flag |= PTCACHE_BAKING;
 
2084
                cache->flag &= ~PTCACHE_BAKED;
 
2085
        }
 
2086
        else {
 
2087
                startframe= MAXFRAME;
 
2088
                endframe= 0;
 
2089
 
 
2090
                for(base=G.scene->base.first; base; base= base->next) {
 
2091
                        if(TESTBASELIB(base)) {
 
2092
                                BKE_ptcache_ids_from_object(&pidlist, base->object);
 
2093
 
 
2094
                                for(pid=pidlist.first; pid; pid=pid->next) {
 
2095
                                        cache= pid->cache;
 
2096
 
 
2097
                                        BKE_ptcache_id_time(pid, 0.0f, &cstart, &cend, NULL);
 
2098
 
 
2099
                                        startframe= MIN2(startframe, cstart);
 
2100
                                        endframe= MAX2(endframe, cend);
 
2101
 
 
2102
                                        cache->flag |= PTCACHE_BAKING;
 
2103
                                        cache->flag &= ~PTCACHE_BAKED;
 
2104
                                }
 
2105
 
 
2106
                                BLI_freelistN(&pidlist);
 
2107
                        }
 
2108
                }
 
2109
        }
 
2110
        
 
2111
        CFRA= startframe;
 
2112
        update_for_newframe_muted();    // put everything on this frame
 
2113
        
 
2114
        curarea->win_swap= 0;           // clean swapbuffers
 
2115
        
 
2116
        for(; CFRA <= endframe; CFRA++) {
 
2117
                set_timecursor(CFRA);
 
2118
                
 
2119
                update_for_newframe_muted();
 
2120
                
 
2121
                for(sa= G.curscreen->areabase.first; sa; sa= sa->next)
 
2122
                        if(sa->spacetype == SPACE_VIEW3D)
 
2123
                                scrarea_do_windraw(sa);
 
2124
                screen_swapbuffers();
 
2125
 
 
2126
                //blender_test_break() has a granularity of 10 ms, who cares .. baking the unit cube is kinda boring
 
2127
                if(blender_test_break()) {
 
2128
                        didbreak = 1;
 
2129
                        break;
 
2130
                }
 
2131
        }
 
2132
 
 
2133
        if(didbreak && G.qual!=LR_SHIFTKEY) {
 
2134
                /* failed to bake, free the frames we baked */
 
2135
                if(pid) {
 
2136
                        cache= pid->cache;
 
2137
 
 
2138
                        BKE_ptcache_id_time(pid, 0.0f, &cstart, &cend, NULL);
 
2139
 
 
2140
                        cache->flag &= ~PTCACHE_BAKING;
 
2141
                        BKE_ptcache_id_reset(pid, PTCACHE_RESET_OUTDATED);
 
2142
                }
 
2143
                else {
 
2144
                        for(base=G.scene->base.first; base; base= base->next) {
 
2145
                                if(TESTBASELIB(base)) {
 
2146
                                        BKE_ptcache_ids_from_object(&pidlist, base->object);
 
2147
 
 
2148
                                        for(pid=pidlist.first; pid; pid=pid->next) {
 
2149
                                                cache= pid->cache;
 
2150
 
 
2151
                                                BKE_ptcache_id_time(pid, 0.0f, &cstart, &cend, NULL);
 
2152
 
 
2153
                                                cache->flag &= ~PTCACHE_BAKING;
 
2154
 
 
2155
                                                BKE_ptcache_id_reset(pid, PTCACHE_RESET_OUTDATED);
 
2156
                                        }
 
2157
 
 
2158
                                        BLI_freelistN(&pidlist);
 
2159
                                }
 
2160
                        }
 
2161
                }
 
2162
        }
 
2163
        else {
 
2164
                /* succesfully finished baking */
 
2165
                if(pid) {
 
2166
                        cache= pid->cache;
 
2167
 
 
2168
                        cache->flag &= ~PTCACHE_BAKING;
 
2169
                        cache->flag |= PTCACHE_BAKED;
 
2170
                }
 
2171
                else {
 
2172
                        for(base=G.scene->base.first; base; base= base->next) {
 
2173
                                if(TESTBASELIB(base)) {
 
2174
                                        BKE_ptcache_ids_from_object(&pidlist, base->object);
 
2175
 
 
2176
                                        for(pid=pidlist.first; pid; pid=pid->next) {
 
2177
                                                cache= pid->cache;
 
2178
 
 
2179
                                                cache->flag &= ~PTCACHE_BAKING;
 
2180
                                                cache->flag |= PTCACHE_BAKED;
 
2181
                                        }
 
2182
 
 
2183
                                        BLI_freelistN(&pidlist);
 
2184
                                }
 
2185
                        }
 
2186
                }
 
2187
        }
 
2188
        
 
2189
        /* restore */
 
2190
        waitcursor(0);
 
2191
        sbSetInterruptCallBack(NULL); // softbody module won't ESC
 
2192
        G.afbreek=0; // reset global break system
 
2193
 
 
2194
        CFRA= cfrao;
 
2195
        G.scene->r.framelen= frameleno;
 
2196
        update_for_newframe_muted();
 
2197
        allqueue(REDRAWVIEW3D, 0);
 
2198
        allqueue(REDRAWBUTSOBJECT, 0);
 
2199
}
 
2200
 
 
2201
void pointcache_free(PTCacheID *pid, int cacheonly)
 
2202
{
 
2203
        Base *base;
 
2204
        ListBase pidlist;
 
2205
        
 
2206
        if(pid) {
 
2207
                if(cacheonly) {
 
2208
                        BKE_ptcache_id_reset(pid, PTCACHE_RESET_DEPSGRAPH);
 
2209
                }
 
2210
                else {
 
2211
                        BKE_ptcache_id_reset(pid, PTCACHE_RESET_BAKED);
 
2212
                        pid->cache->flag &= ~PTCACHE_BAKED;
 
2213
                }
 
2214
 
 
2215
                DAG_object_flush_update(G.scene, pid->ob, OB_RECALC_DATA);
 
2216
        }
 
2217
        else {
 
2218
                for(base=G.scene->base.first; base; base= base->next) {
 
2219
                        if(TESTBASELIB(base)) {
 
2220
                                BKE_ptcache_ids_from_object(&pidlist, base->object);
 
2221
 
 
2222
                                for(pid=pidlist.first; pid; pid=pid->next) {
 
2223
                                        if(cacheonly) {
 
2224
                                                BKE_ptcache_id_reset(pid, PTCACHE_RESET_DEPSGRAPH);
 
2225
                                        }
 
2226
                                        else {
 
2227
                                                BKE_ptcache_id_reset(pid, PTCACHE_RESET_BAKED);
 
2228
                                                pid->cache->flag &= ~PTCACHE_BAKED;
 
2229
                                        }
 
2230
 
 
2231
                                        DAG_object_flush_update(G.scene, pid->ob, OB_RECALC_DATA);
 
2232
                                }
 
2233
 
 
2234
                                BLI_freelistN(&pidlist);
 
2235
                        }
 
2236
                }
 
2237
        }
 
2238
 
 
2239
        allqueue(REDRAWVIEW3D, 0);
 
2240
        allqueue(REDRAWBUTSOBJECT, 0);
 
2241
}
 
2242
 
 
2243
// store processed path & file prefix for fluidsim bake directory
 
2244
void fluidsimFilesel(char *selection)
 
2245
{
 
2246
        Object *ob = OBACT;
 
2247
        char srcDir[FILE_MAXDIR+FILE_MAXFILE], srcFile[FILE_MAXFILE];
 
2248
        char prefix[FILE_MAXFILE];
 
2249
        char *srch, *srchSub, *srchExt, *lastFound;
 
2250
        int isElbeemSurf = 0;
 
2251
        FluidsimModifierData *fluidmd = (FluidsimModifierData *)modifiers_findByType(ob, eModifierType_Fluidsim);
 
2252
 
 
2253
        // make prefix
 
2254
        strcpy(srcDir, selection);
 
2255
        BLI_splitdirstring(srcDir, srcFile);
 
2256
        strcpy(prefix, srcFile);
 
2257
        // check if this is a previously generated surface mesh file
 
2258
        srch = strstr(prefix, "fluidsurface_");
 
2259
        // TODO search from back...
 
2260
        if(srch) {
 
2261
                srchSub = strstr(prefix,"_preview_");
 
2262
                if(!srchSub) srchSub = strstr(prefix,"_final_");
 
2263
                srchExt = strstr(prefix,".gz.bobj");
 
2264
                if(!srchExt) srchExt = strstr(prefix,".bobj");
 
2265
                if(srchSub && srchExt) {
 
2266
                        *srch = '\0';
 
2267
                        isElbeemSurf = 1;
 
2268
                }
 
2269
        }
 
2270
        if(!isElbeemSurf) {
 
2271
                // try to remove suffix
 
2272
                lastFound = NULL;
 
2273
                srch = strchr(prefix, '.'); // search last . from extension
 
2274
                while(srch) {
 
2275
                        lastFound = srch;
 
2276
                        if(srch) {
 
2277
                                srch++;
 
2278
                                srch = strchr(srch, '.');
 
2279
                        }
 
2280
                }
 
2281
                if(lastFound) {
 
2282
                        *lastFound = '\0';
 
2283
                } 
 
2284
        }
 
2285
 
 
2286
        if(fluidmd && fluidmd->fss) {
 
2287
                strcpy(fluidmd->fss->surfdataPath, srcDir);
 
2288
                //not necessary? strcat(ob->fluidsimSettings->surfdataPath, "/");
 
2289
                strcat(fluidmd->fss->surfdataPath, prefix);
 
2290
 
 
2291
                // redraw view & buttons...
 
2292
                allqueue(REDRAWBUTSOBJECT, 0);
 
2293
                allqueue(REDRAWVIEW3D, 0);
 
2294
                DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA);
 
2295
        }
 
2296
}
 
2297
 
 
2298
void do_object_panels(unsigned short event)
 
2299
{
 
2300
        Object *ob;
 
2301
        
 
2302
        ob= OBACT;
 
2303
        if(ob==NULL)
 
2304
                return;
 
2305
        
 
2306
        switch(event) {
 
2307
        case B_TRACKBUTS:
 
2308
                DAG_object_flush_update(G.scene, ob, OB_RECALC_OB);
 
2309
                allqueue(REDRAWVIEW3D, 0);
 
2310
                break;
 
2311
        case B_RECALCPATH:
 
2312
                DAG_object_flush_update(G.scene, OBACT, OB_RECALC_DATA);
 
2313
                allqueue(REDRAWVIEW3D, 0);
 
2314
                break;
 
2315
        case B_DUPLI_FRAME:
 
2316
                ob->transflag &= ~(OB_DUPLIVERTS|OB_DUPLIFACES|OB_DUPLIGROUP);
 
2317
                allqueue(REDRAWVIEW3D, 0);
 
2318
                allqueue(REDRAWBUTSOBJECT, 0);
 
2319
                break;
 
2320
        case B_DUPLI_VERTS:
 
2321
                ob->transflag &= ~(OB_DUPLIFRAMES|OB_DUPLIFACES|OB_DUPLIGROUP);
 
2322
                DAG_scene_sort(G.scene);
 
2323
                DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA|OB_RECALC_OB);
 
2324
                allqueue(REDRAWVIEW3D, 0);
 
2325
                allqueue(REDRAWBUTSOBJECT, 0);
 
2326
                break;
 
2327
        case B_DUPLI_FACES:
 
2328
                ob->transflag &= ~(OB_DUPLIVERTS|OB_DUPLIFRAMES|OB_DUPLIGROUP);
 
2329
                allqueue(REDRAWVIEW3D, 0);
 
2330
                allqueue(REDRAWBUTSOBJECT, 0);
 
2331
                break;
 
2332
        case B_DUPLI_GROUP:
 
2333
                ob->transflag &= ~(OB_DUPLIVERTS|OB_DUPLIFRAMES|OB_DUPLIFACES);
 
2334
                allqueue(REDRAWVIEW3D, 0);
 
2335
                allqueue(REDRAWBUTSOBJECT, 0);
 
2336
                break;
 
2337
                
 
2338
        case B_PRINTSPEED:
 
2339
                {
 
2340
                        float vec[3];
 
2341
                        CFRA++;
 
2342
                        do_ob_ipo(ob);
 
2343
                        where_is_object(ob);
 
2344
                        VECCOPY(vec, ob->obmat[3]);
 
2345
                        CFRA--;
 
2346
                        do_ob_ipo(ob);
 
2347
                        where_is_object(ob);
 
2348
                        VecSubf(vec, vec, ob->obmat[3]);
 
2349
                        prspeed= Normalize(vec);
 
2350
                        scrarea_queue_winredraw(curarea);
 
2351
                }
 
2352
                break;
 
2353
        case B_PRINTLEN:
 
2354
                if(ob->type==OB_CURVE) {
 
2355
                        Curve *cu=ob->data;
 
2356
                        
 
2357
                        if(cu->path) prlen= cu->path->totdist; else prlen= -1.0;
 
2358
                        scrarea_queue_winredraw(curarea);
 
2359
                } 
 
2360
                break;
 
2361
        case B_RELKEY:
 
2362
                allspace(REMAKEIPO, 0);
 
2363
                allqueue(REDRAWBUTSOBJECT, 0);
 
2364
                allqueue(REDRAWBUTSEDIT, 0);
 
2365
                allqueue(REDRAWIPO, 0);
 
2366
                DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA);
 
2367
                break;
 
2368
        case B_CURVECHECK:
 
2369
                DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA);
 
2370
                allqueue(REDRAWVIEW3D, 0);
 
2371
                break;
 
2372
        
 
2373
        case B_SOFTBODY_DEL_VG:
 
2374
                if(ob->soft) {
 
2375
                        ob->soft->vertgroup= 0;
 
2376
                        //ob->softflag |= OB_SB_REDO;
 
2377
                        DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA); 
 
2378
                        allqueue(REDRAWBUTSOBJECT, 0);
 
2379
                        allqueue(REDRAWVIEW3D, 0);
 
2380
                }
 
2381
                break;
 
2382
        case B_FLUIDSIM_BAKE:
 
2383
                /* write config files (currently no simulation) */
 
2384
                fluidsimBake(ob);
 
2385
                break;
 
2386
        case B_FLUIDSIM_MAKEPART:
 
2387
                if(ob==NULL || ob->type!=OB_MESH) break;
 
2388
                else {
 
2389
                        ParticleSettings *part = psys_new_settings("PSys", G.main);
 
2390
                        ParticleSystem *psys = MEM_callocN(sizeof(ParticleSystem), "particle_system");
 
2391
                        ModifierData *md;
 
2392
                        ParticleSystemModifierData *psmd;
 
2393
                        FluidsimModifierData *fluidmd = (FluidsimModifierData *)modifiers_findByType(ob, eModifierType_Fluidsim);
 
2394
 
 
2395
                        part->type = PART_FLUID;
 
2396
                        psys->part = part;
 
2397
                        psys->pointcache = BKE_ptcache_add();
 
2398
                        psys->flag |= PSYS_ENABLED;
 
2399
 
 
2400
                        fluidmd->fss->type = OB_FLUIDSIM_PARTICLE;
 
2401
 
 
2402
                        BLI_addtail(&ob->particlesystem,psys);
 
2403
 
 
2404
                        md= modifier_new(eModifierType_ParticleSystem);
 
2405
                        sprintf(md->name, "FluidParticleSystem" );
 
2406
                        psmd= (ParticleSystemModifierData*) md;
 
2407
                        psmd->psys=psys;
 
2408
                        BLI_addtail(&ob->modifiers, md);
 
2409
                }
 
2410
                allqueue(REDRAWVIEW3D, 0);
 
2411
                allqueue(REDRAWBUTSOBJECT, 0);
 
2412
                break;
 
2413
        case B_FLUIDSIM_CHANGETYPE:
 
2414
        {
 
2415
                FluidsimModifierData *fluidmd = (FluidsimModifierData *)modifiers_findByType(ob, eModifierType_Fluidsim);
 
2416
                fluidmd->fss->flag &= ~OB_FLUIDSIM_REVERSE; // clear flag
 
2417
                if(ob && ob->particlesystem.first && fluidmd->fss->type!=OB_FLUIDSIM_PARTICLE){
 
2418
                        ParticleSystem *psys;
 
2419
                        for(psys=ob->particlesystem.first; psys; psys=psys->next) {
 
2420
                                if(psys->part->type==PART_FLUID) {
 
2421
                                        /* clear modifier */
 
2422
                                        ParticleSystemModifierData *psmd= psys_get_modifier(ob,psys);
 
2423
                                        BLI_remlink(&ob->modifiers, psmd);
 
2424
                                        modifier_free((ModifierData *)psmd);
 
2425
 
 
2426
                                        /* clear particle system */
 
2427
                                        BLI_remlink(&ob->particlesystem,psys);
 
2428
                                        psys_free(ob,psys);
 
2429
 
 
2430
                                        BIF_undo_push("Delete particle system");
 
2431
 
 
2432
                                        DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA);
 
2433
 
 
2434
                                        allqueue(REDRAWVIEW3D, 0);
 
2435
                                        allqueue(REDRAWOOPS, 0);
 
2436
                                        break;
 
2437
                                }
 
2438
                        }
 
2439
                }
 
2440
                allqueue(REDRAWBUTSOBJECT, 0);
 
2441
                break;
 
2442
        }
 
2443
        case B_FLUIDSIM_SELDIR: 
 
2444
                {
 
2445
                        ScrArea *sa = closest_bigger_area();
 
2446
                        FluidsimModifierData *fluidmd = (FluidsimModifierData *)modifiers_findByType(ob, eModifierType_Fluidsim);
 
2447
                        /* choose dir for surface files */
 
2448
                        areawinset(sa->win);
 
2449
                        activate_fileselect(FILE_SPECIAL, "Select Directory", fluidmd->fss->surfdataPath, fluidsimFilesel);
 
2450
                }
 
2451
                break;
 
2452
        case B_GROUP_RELINK:
 
2453
                group_relink_nla_objects(ob);
 
2454
                allqueue(REDRAWVIEW3D, 0);
 
2455
                break;
 
2456
        case B_OBJECT_IPOFLAG:
 
2457
                if(ob->ipo) ob->ipo->showkey= (ob->ipoflag & OB_DRAWKEY)?1:0;
 
2458
                allqueue(REDRAWVIEW3D, 0);
 
2459
                break;
 
2460
        case B_CLOTH_CHANGEPREROLL:
 
2461
        {
 
2462
                ClothModifierData *clmd = (ClothModifierData *)modifiers_findByType(ob, eModifierType_Cloth);
 
2463
                if(clmd)
 
2464
                {
 
2465
                        PTCacheID pid;
 
2466
 
 
2467
                        BKE_ptcache_id_from_cloth(&pid, ob, clmd);
 
2468
 
 
2469
                        // do nothing in editmode
 
2470
                        if(pid.cache->flag & PTCACHE_BAKE_EDIT_ACTIVE)
 
2471
                                break;
 
2472
                        
 
2473
                        CFRA= 1;
 
2474
                        update_for_newframe_muted();
 
2475
                        DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA); 
 
2476
                        allqueue(REDRAWBUTSOBJECT, 0);
 
2477
                        allqueue(REDRAWVIEW3D, 0);
 
2478
                }
 
2479
        }
 
2480
        break;  
 
2481
        case B_BAKE_CACHE_CHANGE:
 
2482
        {
 
2483
                DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA); 
 
2484
                allqueue(REDRAWBUTSOBJECT, 0);
 
2485
                allqueue(REDRAWVIEW3D, 0);
 
2486
        }
 
2487
        break;
 
2488
        }
 
2489
 
 
2490
}
 
2491
 
 
2492
static void do_add_groupmenu(void *arg, int event)
 
2493
{
 
2494
        Object *ob= OBACT;
 
2495
        
 
2496
        if(ob) {
 
2497
                
 
2498
                if(event== -1) {
 
2499
                        Group *group= add_group( "Group" );
 
2500
                        add_to_group(group, ob);
 
2501
                }
 
2502
                else
 
2503
                        add_to_group(BLI_findlink(&G.main->group, event), ob);
 
2504
                        
 
2505
                ob->flag |= OB_FROMGROUP;
 
2506
                BASACT->flag |= OB_FROMGROUP;
 
2507
                allqueue(REDRAWBUTSOBJECT, 0);
 
2508
                allqueue(REDRAWVIEW3D, 0);
 
2509
        }               
 
2510
}
 
2511
 
 
2512
static uiBlock *add_groupmenu(void *arg_unused)
 
2513
{
 
2514
        uiBlock *block;
 
2515
        Group *group;
 
2516
        short xco=0, yco= 0, index=0;
 
2517
        char str[32];
 
2518
        
 
2519
        block= uiNewBlock(&curarea->uiblocks, "add_constraintmenu", UI_EMBOSSP, UI_HELV, curarea->win);
 
2520
        uiBlockSetButmFunc(block, do_add_groupmenu, NULL);
 
2521
 
 
2522
        uiDefBut(block, BUTM, B_NOP, "ADD NEW",         0, 20, 160, 19, NULL, 0.0, 0.0, 1, -1, "");
 
2523
        for(group= G.main->group.first; group; group= group->id.next, index++) {
 
2524
                
 
2525
                /*if(group->id.lib) strcpy(str, "L  ");*/ /* we cant allow adding objects inside linked groups, it wont be saved anyway */
 
2526
                if(group->id.lib==0) {
 
2527
                        strcpy(str, "   ");
 
2528
                        strcat(str, group->id.name+2);
 
2529
                        uiDefBut(block, BUTM, B_NOP, str,       xco*160, -20*yco, 160, 19, NULL, 0.0, 0.0, 1, index, "");
 
2530
                        
 
2531
                        yco++;
 
2532
                        if(yco>24) {
 
2533
                                yco= 0;
 
2534
                                xco++;
 
2535
                        }
 
2536
                }
 
2537
        }
 
2538
        
 
2539
        uiTextBoundsBlock(block, 50);
 
2540
        uiBlockSetDirection(block, UI_DOWN);    
 
2541
        
 
2542
        return block;
 
2543
}
 
2544
 
 
2545
static void group_ob_rem(void *gr_v, void *ob_v)
 
2546
{
 
2547
        Object *ob= OBACT;
 
2548
        
 
2549
        if(rem_from_group(gr_v, ob) && find_group(ob, NULL)==NULL) {
 
2550
                ob->flag &= ~OB_FROMGROUP;
 
2551
                BASACT->flag &= ~OB_FROMGROUP;
 
2552
        }
 
2553
        allqueue(REDRAWBUTSOBJECT, 0);
 
2554
        allqueue(REDRAWVIEW3D, 0);
 
2555
 
 
2556
}
 
2557
 
 
2558
static void group_local(void *gr_v, void *unused)
 
2559
{
 
2560
        Group *group= gr_v;
 
2561
        
 
2562
        group->id.lib= NULL;
 
2563
        
 
2564
        allqueue(REDRAWBUTSOBJECT, 0);
 
2565
        allqueue(REDRAWVIEW3D, 0);
 
2566
        
 
2567
}
 
2568
 
 
2569
static void object_panel_object(Object *ob)
 
2570
{
 
2571
        uiBlock *block;
 
2572
        uiBut *but;
 
2573
        Group *group;
 
2574
        int a, xco, yco=0;
 
2575
        short dx= 33, dy= 30;
 
2576
        int is_libdata = object_is_libdata(ob);
 
2577
        block= uiNewBlock(&curarea->uiblocks, "object_panel_object", UI_EMBOSS, UI_HELV, curarea->win);
 
2578
        if(uiNewPanel(curarea, block, "Object and Links", "Object", 0, 0, 318, 204)==0) return;
 
2579
        
 
2580
        
 
2581
        
 
2582
        /* object name */
 
2583
        uiBlockSetCol(block, TH_BUT_SETTING2);
 
2584
        uiSetButLock(is_libdata, ERROR_LIBDATA_MESSAGE);
 
2585
        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);
 
2586
        uiBlockSetCol(block, TH_AUTO);
 
2587
        
 
2588
        /* parent */
 
2589
        uiSetButLock(is_libdata, ERROR_LIBDATA_MESSAGE);
 
2590
        uiDefIDPoinBut(block, test_obpoin_but, ID_OB, B_OBJECTPANELPARENT, "Par:", xco+5, 180, 305-xco, 20, &ob->parent, "Parent Object"); 
 
2591
        
 
2592
        uiSetButLock(is_libdata, ERROR_LIBDATA_MESSAGE);
 
2593
        but = uiDefButS(block, NUM, B_NOP, "PassIndex:",                xco+5, 150, 305-xco, 20, &ob->index, 0.0, 1000.0, 0, 0, "Index # for the IndexOB render pass.");
 
2594
        
 
2595
        uiSetButLock(1, NULL);
 
2596
        uiDefBlockBut(block, add_groupmenu, NULL, "Add to Group", 10,150,150,20, "Add Object to a new Group");
 
2597
 
 
2598
        /* all groups */
 
2599
        for(group= G.main->group.first; group; group= group->id.next) {
 
2600
                if(object_in_group(ob, group)) {
 
2601
                        xco= 130;
 
2602
                        
 
2603
                        if(group->id.lib) {
 
2604
                                uiBlockBeginAlign(block);
 
2605
                                uiSetButLock(GET_INT_FROM_POINTER(group->id.lib), ERROR_LIBDATA_MESSAGE); /* We cant actually use this button */
 
2606
                                uiDefBut(block, TEX, B_IDNAME, "GR:",   10, 120-yco, 100, 20, group->id.name+2, 0.0, 21.0, 0, 0, "Displays Group name. Click to change.");
 
2607
                                uiClearButLock();
 
2608
                                
 
2609
                                but= uiDefIconBut(block, BUT, B_NOP, ICON_PARLIB, 110, 120-yco, 20, 20, NULL, 0.0, 0.0, 0.0, 0.0, "Make Group local");
 
2610
                                uiButSetFunc(but, group_local, group, NULL);
 
2611
                                uiBlockEndAlign(block);
 
2612
                        } else {
 
2613
                                but = uiDefBut(block, TEX, B_IDNAME, "GR:",     10, 120-yco, 120, 20, group->id.name+2, 0.0, 21.0, 0, 0, "Displays Group name. Click to change.");
 
2614
                                uiButSetFunc(but, test_idbutton_cb, group->id.name, NULL);
 
2615
                        }
 
2616
                        
 
2617
                        uiSetButLock(GET_INT_FROM_POINTER(group->id.lib), ERROR_LIBDATA_MESSAGE);
 
2618
                        uiBlockBeginAlign(block);
 
2619
                        uiDefButF(block, NUM, REDRAWALL, "X:",                  xco+5, 120-yco, 50, 20, &group->dupli_ofs[0], -100000, 100000, 100, 0, "Offset to use when instacing the group");
 
2620
                        uiDefButF(block, NUM, REDRAWALL, "Y:",                  xco+55, 120-yco, 50, 20, &group->dupli_ofs[1], -100000, 100000, 100, 0, "Offset to use when instacing the group");
 
2621
                        uiDefButF(block, NUM, REDRAWALL, "Z:",                  xco+105, 120-yco, 50, 20, &group->dupli_ofs[2], -100000, 100000, 100, 0, "Offset to use when instacing the group");
 
2622
                        uiBlockEndAlign(block);
 
2623
                        uiClearButLock();
 
2624
                        
 
2625
                        xco = 290;
 
2626
                        if(group->id.lib==0) { /* cant remove objects from linked groups */
 
2627
                                but = uiDefIconBut(block, BUT, B_NOP, VICON_X, xco, 120-yco, 20, 20, NULL, 0.0, 0.0, 0.0, 0.0, "Remove Group membership");
 
2628
                                uiButSetFunc(but, group_ob_rem, group, ob);
 
2629
                        }
 
2630
                        
 
2631
                        yco+= 20;
 
2632
                        xco= 10;
 
2633
                        
 
2634
                        /* layers */
 
2635
                        uiSetButLock(GET_INT_FROM_POINTER(group->id.lib), ERROR_LIBDATA_MESSAGE);
 
2636
                        uiBlockBeginAlign(block);
 
2637
                        for(a=0; a<5; a++)
 
2638
                                uiDefButBitI(block, TOG, 1<<a, REDRAWVIEW3D, "",        (short)(xco+a*(dx/2)), 120-yco, (short)(dx/2), (short)(dy/2), (int *)&(group->layer), 0, 0, 0, 0, "");
 
2639
                        for(a=0; a<5; a++)
 
2640
                                uiDefButBitI(block, TOG, 1<<(a+10), REDRAWVIEW3D, "",   (short)(xco+a*(dx/2)), 105-yco, (short)(dx/2), (short)(dy/2), (int *)&(group->layer), 0, 0, 0, 0, "");
 
2641
                        
 
2642
                        xco+= 7;
 
2643
                        uiBlockBeginAlign(block);
 
2644
                        for(a=5; a<10; a++)
 
2645
                                uiDefButBitI(block, TOG, 1<<a, REDRAWVIEW3D, "",        (short)(xco+a*(dx/2)), 120-yco, (short)(dx/2), (short)(dy/2), (int *)&(group->layer), 0, 0, 0, 0, "");
 
2646
                        for(a=5; a<10; a++)
 
2647
                                uiDefButBitI(block, TOG, 1<<(a+10), REDRAWVIEW3D, "",   (short)(xco+a*(dx/2)), 105-yco, (short)(dx/2), (short)(dy/2), (int *)&(group->layer), 0, 0, 0, 0, "");
 
2648
                        
 
2649
                        uiBlockEndAlign(block);
 
2650
                        uiClearButLock();
 
2651
 
 
2652
                        yco+= 40;
 
2653
                }
 
2654
        }
 
2655
        
 
2656
        if(120-yco < -10)
 
2657
                uiNewPanelHeight(block, 204 - (120-yco));
 
2658
}
 
2659
 
 
2660
static void object_panel_anim_timeoffset_callback( void *data, void *timeoffset_ui) {
 
2661
        Object *ob = (Object *)data;
 
2662
        ob->sf = (*(float *)timeoffset_ui) - (give_timeoffset(ob) - ob->sf);
 
2663
}
 
2664
 
 
2665
static void object_panel_anim(Object *ob)
 
2666
{
 
2667
        uiBlock *block;
 
2668
        uiBut *but;
 
2669
        static float timeoffset_ui;
 
2670
        char str[32];
 
2671
        
 
2672
        block= uiNewBlock(&curarea->uiblocks, "object_panel_anim", UI_EMBOSS, UI_HELV, curarea->win);
 
2673
        if(uiNewPanel(curarea, block, "Anim settings", "Object", 320, 0, 318, 204)==0) return;
 
2674
        
 
2675
        uiSetButLock(object_is_libdata(ob), ERROR_LIBDATA_MESSAGE);
 
2676
        
 
2677
        uiBlockBeginAlign(block);
 
2678
        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");
 
2679
        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");
 
2680
        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");
 
2681
        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");
 
2682
        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");
 
2683
        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");
 
2684
        uiBlockBeginAlign(block);
 
2685
        uiDefButS(block, ROW,REDRAWVIEW3D,"UpX",        226,180,45,19, &ob->upflag, 13.0, 0.0, 0, 0, "Specify the axis that points up");
 
2686
        uiDefButS(block, ROW,REDRAWVIEW3D,"Y",          274,180,20,19, &ob->upflag, 13.0, 1.0, 0, 0, "Specify the axis that points up");
 
2687
        uiDefButS(block, ROW,REDRAWVIEW3D,"Z",          298,180,19,19, &ob->upflag, 13.0, 2.0, 0, 0, "Specify the axis that points up");
 
2688
        
 
2689
        uiBlockBeginAlign(block);
 
2690
        uiDefButBitS(block, TOG, OB_DRAWKEY, B_OBJECT_IPOFLAG, "Draw Key",              24,155,71,19, &ob->ipoflag, 0, 0, 0, 0, "Draw object as key position");
 
2691
        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");
 
2692
        uiDefButBitS(block, TOG, OB_POWERTRACK, REDRAWVIEW3D, "Powertrack",             180,155,78,19, &ob->transflag, 0, 0, 0, 0, "Switch objects rotation off");
 
2693
        uiDefButBitS(block, TOG, PARSLOW, 0, "SlowPar",                                 260,155,56,19, &ob->partype, 0, 0, 0, 0, "Create a delay in the parent relationship");
 
2694
        uiBlockBeginAlign(block);
 
2695
        
 
2696
        uiDefButBitS(block, TOG, OB_DUPLIFRAMES, B_DUPLI_FRAME, "DupliFrames",  24,130,95,20, &ob->transflag, 0, 0, 0, 0, "Make copy of object for every frame");
 
2697
        uiDefButBitS(block, TOG, OB_DUPLIVERTS, B_DUPLI_VERTS, "DupliVerts",            119,130,95,20, &ob->transflag, 0, 0, 0, 0, "Duplicate child objects on all vertices");
 
2698
        uiDefButBitS(block, TOG, OB_DUPLIFACES, B_DUPLI_FACES, "DupliFaces",            214,130,102,20, &ob->transflag, 0, 0, 0, 0, "Duplicate child objects on all faces");
 
2699
        uiDefButBitS(block, TOG, OB_DUPLIGROUP, B_DUPLI_GROUP, "DupliGroup",            24,110,150,20, &ob->transflag, 0, 0, 0, 0, "Enable group instancing");
 
2700
        if(ob->transflag & OB_DUPLIFRAMES) {
 
2701
                uiDefButBitS(block, TOG, OB_DUPLINOSPEED, REDRAWVIEW3D, "No Speed",             174,110,142,20, &ob->transflag, 0, 0, 0, 0, "Set dupliframes to still, regardless of frame");
 
2702
        } else if(ob->transflag & OB_DUPLIVERTS) {
 
2703
                uiDefButBitS(block, TOG, OB_DUPLIROT, REDRAWVIEW3D, "Rot",                              174,110,142,20, &ob->transflag, 0, 0, 0, 0, "Rotate dupli according to vertex normal");
 
2704
        } else if(ob->transflag & OB_DUPLIFACES) {
 
2705
                uiDefButBitS(block, TOG, OB_DUPLIFACES_SCALE, REDRAWVIEW3D, "Scale",                    174,110,80,20, &ob->transflag, 0, 0, 0, 0, "Scale dupli based on face size");
 
2706
                uiDefButF(block, NUM, REDRAWVIEW3D, "",         254,110,62,20, &ob->dupfacesca, 0.001, 10000.0, 0, 0, "Scale the DupliFace objects");
 
2707
        } else {
 
2708
                uiDefIDPoinBut(block, test_grouppoin_but, ID_GR, B_GROUP_RELINK, "GR:", 174,110,142,20, &ob->dup_group, "Instance an existing group");
 
2709
        }
 
2710
        
 
2711
        uiBlockBeginAlign(block);
 
2712
        /* DupSta and DupEnd are both shorts, so the maxframe is greater then their range
 
2713
        just limit the buttons to the max short */
 
2714
        uiDefButI(block, NUM, REDRAWVIEW3D, "DupSta:",          24,85,141,19, &ob->dupsta, 1.0, 32767, 0, 0, "Specify startframe for Dupliframes");
 
2715
        uiDefButI(block, NUM, REDRAWVIEW3D, "DupOn:",           170,85,146,19, &ob->dupon, 1.0, 1500.0, 0, 0, "Specify the number of frames to use between DupOff frames");
 
2716
        uiDefButI(block, NUM, REDRAWVIEW3D, "DupEnd",           24,65,140,19, &ob->dupend, 1.0, 32767, 0, 0, "Specify endframe for Dupliframes");
 
2717
        uiDefButI(block, NUM, REDRAWVIEW3D, "DupOff",           171,65,145,19, &ob->dupoff, 0.0, 1500.0, 0, 0, "Specify recurring frames to exclude from the Dupliframes");
 
2718
        uiBlockEndAlign(block);
 
2719
        
 
2720
        uiBlockBeginAlign(block);
 
2721
        
 
2722
        timeoffset_ui = give_timeoffset(ob);
 
2723
        but = uiDefButF(block, NUM, REDRAWALL, "TimeOffset:",                   24,35,115,20, &timeoffset_ui, -MAXFRAMEF, MAXFRAMEF, 100, 0, "Animation offset in frames for ipo's and dupligroup instances");
 
2724
        uiButSetFunc(but, object_panel_anim_timeoffset_callback, ob, &timeoffset_ui);
 
2725
        
 
2726
        uiDefBut(block, BUT, B_AUTOTIMEOFS, "Auto",     139,35,34,20, 0, 0, 0, 0, 0, "Assign selected objects a timeoffset within a range, starting from the active object");
 
2727
        uiDefBut(block, BUT, B_OFSTIMEOFS, "Ofs",       173,35,34,20, 0, 0, 0, 0, 0, "Offset selected objects timeoffset");
 
2728
        uiDefBut(block, BUT, B_RANDTIMEOFS, "Rand",     207,35,34,20, 0, 0, 0, 0, 0, "Randomize selected objects timeoffset");
 
2729
        uiDefBut(block, BUT, B_PRINTSPEED,      "PrSpeed",                      250,35,65,20, 0, 0, 0, 0, 0, "Print objectspeed");
 
2730
        uiBlockEndAlign(block);
 
2731
        
 
2732
        uiBlockBeginAlign(block);
 
2733
        uiDefButBitS(block, TOG, OB_OFFS_OB, REDRAWALL, "OfsEdit",                      24,10,56,20, &ob->ipoflag, 0, 0, 0, 0, "Use timeoffset when inserting keys and display timeoffset for ipo and action views");
 
2734
        uiDefButBitS(block, TOG, OB_OFFS_PARENT, REDRAWALL, "OfsParent",                        82,10,56,20 , &ob->ipoflag, 0, 0, 0, 0, "Apply the timeoffset to this objects parent relationship");
 
2735
        uiDefButBitS(block, TOG, OB_OFFS_PARTICLE, REDRAWALL, "OfsParticle",            140,10,56,20, &ob->ipoflag, 0, 0, 0, 0, "Let the timeoffset work on the particle effect");
 
2736
        uiDefButBitS(block, TOG, OB_OFFS_PARENTADD, REDRAWALL, "AddParent",             196,10,56,20, &ob->ipoflag, 0, 0, 0, 0, "Add the parents timeoffset value");
 
2737
        uiBlockEndAlign(block);
 
2738
        
 
2739
        sprintf(str, "%.4f", prspeed);
 
2740
        uiDefBut(block, LABEL, 0, str,                                                  260,10,63,31, NULL, 1.0, 0, 0, 0, "");
 
2741
        
 
2742
}
 
2743
 
 
2744
static void object_panel_draw(Object *ob)
 
2745
{
 
2746
        uiBlock *block;
 
2747
        int xco, a, dx, dy;
 
2748
        
 
2749
        block= uiNewBlock(&curarea->uiblocks, "object_panel_draw", UI_EMBOSS, UI_HELV, curarea->win);
 
2750
        if(uiNewPanel(curarea, block, "Draw", "Object", 640, 0, 318, 204)==0) return;
 
2751
        
 
2752
        uiSetButLock(object_is_libdata(ob), ERROR_LIBDATA_MESSAGE);
 
2753
        
 
2754
        /* LAYERS */
 
2755
        xco= 65;
 
2756
        dx= 35;
 
2757
        dy= 30;
 
2758
        
 
2759
        uiDefBut(block, LABEL, 0, "Layers",                             10,170,100,20, NULL, 0, 0, 0, 0, "");
 
2760
        
 
2761
        uiBlockBeginAlign(block);
 
2762
        for(a=0; a<5; a++)
 
2763
                uiDefButBitI(block, TOG, 1<<a, B_OBLAY+a, "",   (short)(xco+a*(dx/2)), 180, (short)(dx/2), (short)(dy/2), (int *)&(BASACT->lay), 0, 0, 0, 0, "");
 
2764
        for(a=0; a<5; a++)
 
2765
                uiDefButBitI(block, TOG, 1<<(a+10), B_OBLAY+a+10, "",   (short)(xco+a*(dx/2)), 165, (short)(dx/2), (short)(dy/2), (int *)&(BASACT->lay), 0, 0, 0, 0, "");
 
2766
        
 
2767
        xco+= 7;
 
2768
        uiBlockBeginAlign(block);
 
2769
        for(a=5; a<10; a++)
 
2770
                uiDefButBitI(block, TOG, 1<<a, B_OBLAY+a, "",   (short)(xco+a*(dx/2)), 180, (short)(dx/2), (short)(dy/2), (int *)&(BASACT->lay), 0, 0, 0, 0, "");
 
2771
        for(a=5; a<10; a++)
 
2772
                uiDefButBitI(block, TOG, 1<<(a+10), B_OBLAY+a+10, "",   (short)(xco+a*(dx/2)), 165, (short)(dx/2), (short)(dy/2), (int *)&(BASACT->lay), 0, 0, 0, 0, "");
 
2773
        
 
2774
        uiBlockEndAlign(block);
 
2775
        
 
2776
        /* Object Color */
 
2777
        uiBlockBeginAlign(block);
 
2778
        uiDefButF(block, COL, REDRAWVIEW3D, "", 250, 180, 50, 15, ob->col, 0, 0, 0, 0, "Object color, used when faces have the ObCol mode enabled");
 
2779
        uiDefButF(block, NUM, REDRAWVIEW3D, "A:", 250, 165, 50, 15, &ob->col[3], 0.0f, 1.0f, 10, 2, "Object alpha, used when faces have the ObCol mode enabled");
 
2780
        uiBlockEndAlign(block); 
 
2781
        
 
2782
        uiDefBut(block, LABEL, 0, "Drawtype",                                           10,120,100,20, NULL, 0, 0, 0, 0, "");
 
2783
        
 
2784
        uiBlockBeginAlign(block);
 
2785
        uiDefButC(block, ROW, REDRAWVIEW3D, "Shaded",   10,100,100, 20, &ob->dt, 0, OB_SHADED, 0, 0, "Draw active object shaded or textured");
 
2786
        uiDefButC(block, ROW, REDRAWVIEW3D, "Solid",    10,80,100, 20, &ob->dt, 0, OB_SOLID, 0, 0, "Draw active object in solid");
 
2787
        uiDefButC(block, ROW, REDRAWVIEW3D, "Wire",             10,60, 100, 20, &ob->dt, 0, OB_WIRE, 0, 0, "Draw active object in wireframe");
 
2788
        uiDefButC(block, ROW, REDRAWVIEW3D, "Bounds",   10,40, 100, 20, &ob->dt, 0, OB_BOUNDBOX, 0, 0, "Only draw object with bounding box");
 
2789
        uiBlockEndAlign(block);
 
2790
        
 
2791
        uiDefBut(block, LABEL, 0, "Draw Extra",                                                 120,120,90,20, NULL, 0, 0, 0, 0, "");
 
2792
        
 
2793
        uiBlockBeginAlign(block);
 
2794
        uiDefButBitC(block, TOG, OB_BOUNDBOX, REDRAWVIEW3D, "Bounds",                           120, 100, 90, 20, &ob->dtx, 0, 0, 0, 0, "Displays the active object's bounds");
 
2795
        uiDefButBitC(block, TOG, OB_DRAWNAME, REDRAWVIEW3D, "Name",             210, 100, 90, 20, &ob->dtx, 0, 0, 0, 0, "Displays the active object's name");
 
2796
        
 
2797
        uiDefButS(block, MENU, REDRAWVIEW3D, "Boundary Display%t|Box%x0|Sphere%x1|Cylinder%x2|Cone%x3|Polyheder%x4",
 
2798
                          120, 80, 90, 20, &ob->boundtype, 0, 0, 0, 0, "Selects the boundary display type");
 
2799
        uiDefButBitC(block, TOG, OB_AXIS, REDRAWVIEW3D, "Axis",                 210, 80, 90, 20, &ob->dtx, 0, 0, 0, 0, "Displays the active object's center and axis");
 
2800
        
 
2801
        uiDefButBitC(block, TOG, OB_TEXSPACE, REDRAWVIEW3D, "TexSpace", 120, 60, 90, 20, &ob->dtx, 0, 0, 0, 0, "Displays the active object's texture space");
 
2802
        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");
 
2803
        
 
2804
        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)");
 
2805
        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");
 
2806
}
 
2807
 
 
2808
void object_panel_constraint(char *context)
 
2809
{
 
2810
        uiBlock *block;
 
2811
        Object *ob= OBACT;
 
2812
        ListBase *conlist;
 
2813
        bConstraint *curcon;
 
2814
        short xco, yco;
 
2815
        char str[64];
 
2816
        
 
2817
        block= uiNewBlock(&curarea->uiblocks, "object_panel_constraint", UI_EMBOSS, UI_HELV, curarea->win);
 
2818
        if(uiNewPanel(curarea, block, "Constraints", context, 960, 0, 318, 204)==0) return;
 
2819
        
 
2820
        uiSetButLock(object_is_libdata(ob), ERROR_LIBDATA_MESSAGE);
 
2821
        
 
2822
        /* this is a variable height panel, newpanel doesnt force new size on existing panels */
 
2823
        /* so first we make it default height */
 
2824
        uiNewPanelHeight(block, 204);
 
2825
        
 
2826
        /* do not allow this panel to draw in editmode - why?*/
 
2827
        if(G.obedit==OBACT) return;     // ??
 
2828
        
 
2829
        conlist = get_active_constraints(OBACT);
 
2830
        
 
2831
        if (conlist) {
 
2832
                uiDefBlockBut(block, add_constraintmenu, NULL, "Add Constraint", 0, 190, 130, 20, "Add a new constraint");
 
2833
                
 
2834
                /* print active object or bone */
 
2835
                str[0]= 0;
 
2836
                if (ob->flag & OB_POSEMODE) {
 
2837
                        bPoseChannel *pchan= get_active_posechannel(ob);
 
2838
                        if(pchan) sprintf(str, "To Bone: %s", pchan->name);
 
2839
                }
 
2840
                else {
 
2841
                        sprintf(str, "To Object: %s", ob->id.name+2);
 
2842
                }
 
2843
                uiDefBut(block, LABEL, 1, str,  150, 190, 150, 20, NULL, 0.0, 0.0, 0, 0, "Displays Active Object or Bone name");
 
2844
                
 
2845
                /* Go through the list of constraints and draw them */
 
2846
                xco = 10;
 
2847
                yco = 160;
 
2848
                
 
2849
                for (curcon = conlist->first; curcon; curcon=curcon->next) {
 
2850
                        /* hrms, the temporal constraint should not draw! */
 
2851
                        if(curcon->type==CONSTRAINT_TYPE_KINEMATIC) {
 
2852
                                bKinematicConstraint *data= curcon->data;
 
2853
                                if(data->flag & CONSTRAINT_IK_TEMP)
 
2854
                                        continue;
 
2855
                        }
 
2856
                        /* Draw default constraint header */
 
2857
                        draw_constraint(block, conlist, curcon, &xco, &yco);    
 
2858
                }
 
2859
                
 
2860
                if(yco < 0) uiNewPanelHeight(block, 204-yco);
 
2861
                
 
2862
        }
 
2863
}
 
2864
 
 
2865
void do_effects_panels(unsigned short event)
 
2866
{
 
2867
        Object *ob;
 
2868
        ModifierData *md;
 
2869
        ParticleSystemModifierData *psmd;
 
2870
        ParticleSystem *psys;
 
2871
        ParticleSettings *part;
 
2872
        LinkNode *node, *firstnode;
 
2873
        ID *id,*idtest;
 
2874
        int nr;
 
2875
        
 
2876
        ob= OBACT;
 
2877
 
 
2878
        psys=psys_get_current(ob);
 
2879
 
 
2880
        switch(event) {
 
2881
 
 
2882
    case B_AUTOTIMEOFS:
 
2883
                auto_timeoffs();
 
2884
                break;
 
2885
    case B_OFSTIMEOFS:
 
2886
                ofs_timeoffs();
 
2887
                break;
 
2888
    case B_RANDTIMEOFS:
 
2889
                rand_timeoffs();
 
2890
                break;
 
2891
        case B_FRAMEMAP:
 
2892
                G.scene->r.framelen= G.scene->r.framapto;
 
2893
                G.scene->r.framelen/= G.scene->r.images;
 
2894
                allqueue(REDRAWALL, 0);
 
2895
                break;
 
2896
        case B_PARTBROWSE:
 
2897
                if(G.buts->menunr== -2) {
 
2898
                        activate_databrowse((ID *)G.buts->lockpoin, ID_PA, 0, B_PARTBROWSE, &G.buts->menunr, do_effects_panels);
 
2899
                        return;
 
2900
                }
 
2901
                
 
2902
                if(G.buts->menunr < 0) return;
 
2903
                
 
2904
                if(G.buts->pin) {
 
2905
                        
 
2906
                }
 
2907
                else {
 
2908
                        psys= psys_get_current(ob);
 
2909
                        if(psys)
 
2910
                                part=psys->part;
 
2911
                        else
 
2912
                                part=NULL;
 
2913
 
 
2914
                        nr= 1;
 
2915
                        
 
2916
                        id= (ID *)part;
 
2917
                        
 
2918
                        idtest= G.main->particle.first;
 
2919
                        while(idtest) {
 
2920
                                if(nr==G.buts->menunr) {
 
2921
                                        break;
 
2922
                                }
 
2923
                                nr++;
 
2924
                                idtest= idtest->next;
 
2925
                        }
 
2926
 
 
2927
                        if(idtest==0) { /* new particle system */
 
2928
                                if(id){
 
2929
                                        idtest= (ID *)psys_copy_settings((ParticleSettings *)id);
 
2930
                                }
 
2931
                                else {
 
2932
                                        idtest= (ID *)psys_new_settings("PSys", G.main);
 
2933
                                }
 
2934
                                idtest->us--;
 
2935
                        }
 
2936
                        else if(((ParticleSettings*)idtest)->type==PART_FLUID) {
 
2937
                                error("Can't select fluid particles");
 
2938
                                break;
 
2939
                        }
 
2940
 
 
2941
                        if(idtest!=id) {
 
2942
                                short nr=0;
 
2943
                                if(id==0){ /* no psys previously -> no modifier -> need to create that also */
 
2944
                                        psys = MEM_callocN(sizeof(ParticleSystem), "particle_system");
 
2945
                                        psys->pointcache = BKE_ptcache_add();
 
2946
                                        psys->flag |= PSYS_ENABLED;
 
2947
                                        BLI_addtail(&ob->particlesystem,psys);
 
2948
 
 
2949
                                        md= modifier_new(eModifierType_ParticleSystem);
 
2950
                                        sprintf(md->name, "ParticleSystem %i", BLI_countlist(&ob->particlesystem));
 
2951
                                        psmd= (ParticleSystemModifierData*) md;
 
2952
                                        psmd->psys=psys;
 
2953
                                        BLI_addtail(&ob->modifiers, md);
 
2954
                                } else
 
2955
                                        id->us--;
 
2956
 
 
2957
                                idtest->us++;
 
2958
                                psys->part=(ParticleSettings*)idtest;
 
2959
                                psys->totpart=0;
 
2960
                                psys->flag= PSYS_ENABLED|PSYS_CURRENT;
 
2961
                                psys->cfra=bsystem_time(ob,G.scene->r.cfra+1,0.0);
 
2962
 
 
2963
                                /* check need for dupliobjects */
 
2964
                                nr=0;
 
2965
                                for(psys=ob->particlesystem.first; psys; psys=psys->next){
 
2966
                                        if(ELEM(psys->part->draw_as,PART_DRAW_OB,PART_DRAW_GR))
 
2967
                                                nr++;
 
2968
                                }
 
2969
                                if(nr)
 
2970
                                        ob->transflag |= OB_DUPLIPARTS;
 
2971
                                else
 
2972
                                        ob->transflag &= ~OB_DUPLIPARTS;
 
2973
 
 
2974
                                BIF_undo_push("Browse Particle System");
 
2975
 
 
2976
                                DAG_scene_sort(G.scene);
 
2977
                                DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA);
 
2978
 
 
2979
                                allqueue(REDRAWVIEW3D, 0);
 
2980
                                allqueue(REDRAWBUTSOBJECT, 0);
 
2981
                                allqueue(REDRAWOOPS, 0);
 
2982
                        }
 
2983
                        
 
2984
                }
 
2985
                break;
 
2986
        case B_PARTDELETE:
 
2987
                if(ob && ob->particlesystem.first){
 
2988
                        psys= psys_get_current(ob);
 
2989
                        if(psys) {
 
2990
                                /* clear modifier */
 
2991
                                psmd= psys_get_modifier(ob,psys);
 
2992
                                BLI_remlink(&ob->modifiers, psmd);
 
2993
                                modifier_free((ModifierData *)psmd);
 
2994
 
 
2995
                                /* clear particle system */
 
2996
                                BLI_remlink(&ob->particlesystem,psys);
 
2997
                                psys_free(ob,psys);
 
2998
 
 
2999
                                BIF_undo_push("Delete particle system");
 
3000
 
 
3001
                                DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA);
 
3002
 
 
3003
                                allqueue(REDRAWVIEW3D, 0);
 
3004
                                allqueue(REDRAWBUTSOBJECT, 0);
 
3005
                                allqueue(REDRAWOOPS, 0);
 
3006
                        }
 
3007
                }
 
3008
                break;
 
3009
        case B_PARTALONE: /* TODO: not too sure of how this works so someone check please, jahka */
 
3010
                if(ob && (psys=psys_get_current(ob))){
 
3011
                        if(psys->part) {
 
3012
                                if(psys->part->id.us>1){
 
3013
                                        if(okee("Make Single User")){
 
3014
                                                part=psys_copy_settings(psys->part);
 
3015
                                                part->id.us=1;
 
3016
                                                psys->part->id.us--;
 
3017
                                                psys->part=part;
 
3018
 
 
3019
                                                allqueue(REDRAWVIEW3D, 0);
 
3020
                                                allqueue(REDRAWBUTSOBJECT, 0);
 
3021
                                                allqueue(REDRAWOOPS, 0);
 
3022
 
 
3023
                                                BIF_undo_push("Make single user or local");
 
3024
                                        }
 
3025
                                }
 
3026
                        }
 
3027
                }
 
3028
                break;
 
3029
 
 
3030
        case B_PART_ALLOC:
 
3031
        case B_PART_DISTR:
 
3032
        case B_PART_INIT:
 
3033
        case B_PART_RECALC:
 
3034
        case B_PART_ALLOC_CHILD:
 
3035
        case B_PART_DISTR_CHILD:
 
3036
        case B_PART_INIT_CHILD:
 
3037
        case B_PART_RECALC_CHILD:
 
3038
                if(psys) {
 
3039
                        Base *base;
 
3040
                        Object *bob;
 
3041
                        ParticleSystem *bpsys;
 
3042
                        int flush;
 
3043
 
 
3044
                        nr=0;
 
3045
                        for(bpsys=ob->particlesystem.first; bpsys; bpsys=bpsys->next){
 
3046
                                if(ELEM(bpsys->part->draw_as,PART_DRAW_OB,PART_DRAW_GR))
 
3047
                                        nr++;
 
3048
                        }
 
3049
                        if(nr)
 
3050
                                ob->transflag |= OB_DUPLIPARTS;
 
3051
                        else
 
3052
                                ob->transflag &= ~OB_DUPLIPARTS;
 
3053
 
 
3054
                        if(psys->part->type==PART_REACTOR)
 
3055
                                if(psys->target_ob)
 
3056
                                        DAG_object_flush_update(G.scene, psys->target_ob, OB_RECALC_DATA);
 
3057
 
 
3058
                        for(base = G.scene->base.first; base; base= base->next) {
 
3059
                                bob= base->object;
 
3060
                                flush= 0;
 
3061
                                for(bpsys=bob->particlesystem.first; bpsys; bpsys=bpsys->next)
 
3062
                                        if(bpsys->part==psys->part)
 
3063
                                                flush= 1;
 
3064
 
 
3065
                                if(flush)
 
3066
                                        DAG_object_flush_update(G.scene, bob, OB_RECALC_DATA);
 
3067
                        }
 
3068
 
 
3069
                        DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA);
 
3070
                        allqueue(REDRAWVIEW3D, 0);
 
3071
                        allqueue(REDRAWBUTSOBJECT, 0);
 
3072
                }
 
3073
                break;
 
3074
        
 
3075
        /* there were separate update events before the pointcache refactor,
 
3076
         * now it only does a flush update which means it is recalculating
 
3077
         * more than strictly needed, but how to restore such partial updates
 
3078
         * i'm not sure - brecht. */
 
3079
#if 0
 
3080
        case B_PART_ALLOC:
 
3081
        case B_PART_ALLOC_CHILD:
 
3082
                if(psys){
 
3083
                        psys_flush_settings(psys->part,PSYS_ALLOC,event==B_PART_ALLOC);
 
3084
                        allqueue(REDRAWVIEW3D, 0);
 
3085
                        allqueue(REDRAWBUTSOBJECT, 0);
 
3086
                        allqueue(REDRAWOOPS, 0);
 
3087
                }
 
3088
                break;
 
3089
 
 
3090
        case B_PART_DISTR:
 
3091
        case B_PART_DISTR_CHILD:
 
3092
                if(psys){
 
3093
                        psys_flush_settings(psys->part,PSYS_DISTR,event==B_PART_DISTR);
 
3094
                        allqueue(REDRAWVIEW3D, 0);
 
3095
                        allqueue(REDRAWBUTSOBJECT, 0);
 
3096
                        allqueue(REDRAWOOPS, 0);
 
3097
                }
 
3098
                break;
 
3099
        case B_PART_INIT:
 
3100
        case B_PART_INIT_CHILD:
 
3101
                if(psys){
 
3102
                        psys_flush_settings(psys->part,PSYS_INIT,event==B_PART_INIT);
 
3103
                        allqueue(REDRAWVIEW3D, 0);
 
3104
                        allqueue(REDRAWBUTSOBJECT, 0);
 
3105
                        allqueue(REDRAWOOPS, 0);
 
3106
                }
 
3107
                break;
 
3108
        case B_PART_ENABLE:
 
3109
                if(psys) {
 
3110
                        DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA);
 
3111
                        allqueue(REDRAWVIEW3D, 0);
 
3112
                        allqueue(REDRAWBUTSOBJECT, 0);
 
3113
                        allqueue(REDRAWBUTSEDIT, 0);
 
3114
                }
 
3115
                break;
 
3116
                /* no break! */
 
3117
#endif
 
3118
        case B_PART_REDRAW_DEPS:
 
3119
                if(event == B_PART_REDRAW_DEPS)
 
3120
                        DAG_scene_sort(G.scene);
 
3121
                /* no break! */
 
3122
        case B_PART_REDRAW:
 
3123
                nr=0;
 
3124
                for(psys=ob->particlesystem.first; psys; psys=psys->next){
 
3125
                        if(ELEM(psys->part->draw_as,PART_DRAW_OB,PART_DRAW_GR))
 
3126
                                nr++;
 
3127
                }
 
3128
                if(nr)
 
3129
                        ob->transflag |= OB_DUPLIPARTS;
 
3130
                else
 
3131
                        ob->transflag &= ~OB_DUPLIPARTS;
 
3132
 
 
3133
                allqueue(REDRAWVIEW3D, 0);
 
3134
                allqueue(REDRAWBUTSOBJECT, 0);
 
3135
                break;
 
3136
        case B_PARTTYPE:
 
3137
                if(psys) {
 
3138
                        /* 1 = do DAG_object_flush_update */
 
3139
                        firstnode= psys_using_settings(psys->part, 1);
 
3140
 
 
3141
                        for(node=firstnode; node; node=node->next)
 
3142
                                psys_changed_type(node->link);
 
3143
                        
 
3144
                        BLI_linklist_free(firstnode, NULL);
 
3145
                        allqueue(REDRAWVIEW3D, 0);
 
3146
                        allqueue(REDRAWBUTSOBJECT, 0);
 
3147
                }
 
3148
                break;
 
3149
        case B_PARTACT:
 
3150
                allqueue(REDRAWVIEW3D, 0);
 
3151
                allqueue(REDRAWBUTSOBJECT, 0);
 
3152
                allqueue(REDRAWIPO, 0);
 
3153
                break;
 
3154
        case B_PARTTARGET:
 
3155
                if((psys=psys_get_current(ob))){
 
3156
                        if(psys->keyed_ob==ob || psys->target_ob==ob){
 
3157
                                if(psys->keyed_ob==ob)
 
3158
                                        psys->keyed_ob=NULL;
 
3159
                                else
 
3160
                                        psys->target_ob=NULL;
 
3161
                        }
 
3162
                        else{
 
3163
                                DAG_scene_sort(G.scene);
 
3164
                                DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA);
 
3165
                        }
 
3166
                        allqueue(REDRAWVIEW3D, 0);
 
3167
                        allqueue(REDRAWBUTSOBJECT, 0);
 
3168
                }
 
3169
                break;
 
3170
        case B_PART_REKEY:
 
3171
                PE_rekey();
 
3172
                allqueue(REDRAWVIEW3D, 0);
 
3173
                allqueue(REDRAWBUTSEDIT, 0);
 
3174
                break;
 
3175
        case B_PART_EDITABLE:
 
3176
                if((psys = psys_get_current(ob))) {
 
3177
                        if(psys->flag & PSYS_EDITED){
 
3178
                                if(okee("Lose changes done in particle mode?")){
 
3179
                                        if(psys->edit)
 
3180
                                                PE_free_particle_edit(psys);
 
3181
 
 
3182
                                        psys->flag &= ~PSYS_EDITED;
 
3183
                                        psys->recalc |= PSYS_RECALC_HAIR;
 
3184
 
 
3185
                                        DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA);
 
3186
                                }
 
3187
                        }
 
3188
                        else {
 
3189
                                if(psys_check_enabled(ob, psys)) {
 
3190
                                        psys->flag |= PSYS_EDITED;
 
3191
                                        if(G.f & G_PARTICLEEDIT)
 
3192
                                                PE_create_particle_edit(ob, psys);
 
3193
                                }
 
3194
                                else
 
3195
                                        error("Particle system not enabled, skipping set editable");
 
3196
                        }
 
3197
                }
 
3198
        case B_FIELD_DEP:
 
3199
                /* do this before scene sort, that one checks for CU_PATH */
 
3200
                if(ob->type==OB_CURVE && ob->pd->forcefield==PFIELD_GUIDE) {
 
3201
                        Curve *cu= ob->data;
 
3202
                        
 
3203
                        cu->flag |= (CU_PATH|CU_3D);
 
3204
                        do_curvebuts(B_CU3D);   /* all curves too */
 
3205
                }
 
3206
                DAG_scene_sort(G.scene);
 
3207
 
 
3208
                if(ob->type==OB_CURVE && ob->pd->forcefield==PFIELD_GUIDE)
 
3209
                        DAG_object_flush_update(G.scene, ob, OB_RECALC);
 
3210
                else
 
3211
                        DAG_object_flush_update(G.scene, ob, OB_RECALC_OB);
 
3212
 
 
3213
                allqueue(REDRAWVIEW3D, 0);
 
3214
                allqueue(REDRAWBUTSOBJECT, 0);
 
3215
                break;
 
3216
        case B_FIELD_CHANGE:
 
3217
                if(ob->pd->forcefield != PFIELD_TEXTURE && ob->pd->tex){
 
3218
                        ob->pd->tex->id.us--;
 
3219
                        ob->pd->tex=0;
 
3220
                }
 
3221
                DAG_object_flush_update(G.scene, ob, OB_RECALC_OB);
 
3222
                allqueue(REDRAWVIEW3D, 0);
 
3223
                break;
 
3224
        }
 
3225
 
 
3226
}
 
3227
 
 
3228
/* copy from buttons_editing.c */
 
3229
static void field_testTexture(char *name, ID **idpp)
 
3230
{
 
3231
        ID *id;
 
3232
 
 
3233
        for(id = G.main->tex.first; id; id = id->next) {
 
3234
                if(strcmp(name, id->name + 2) == 0) {
 
3235
                        *idpp = id;
 
3236
                        /* texture gets user, objects not: delete object = clear modifier */
 
3237
                        id_us_plus(id);
 
3238
                        return;
 
3239
                }
 
3240
        }
 
3241
        *idpp = 0;
 
3242
}
 
3243
 
 
3244
/* Panel for collision */
 
3245
static void object_collision__enabletoggle ( void *ob_v, void *arg2 )
 
3246
{
 
3247
        Object *ob = ob_v;
 
3248
        PartDeflect *pd= ob->pd;
 
3249
        ModifierData *md = modifiers_findByType ( ob, eModifierType_Collision );
 
3250
        
 
3251
        if ( !md )
 
3252
        {
 
3253
                if(pd && (pd->deflect))
 
3254
                {
 
3255
                        md = modifier_new ( eModifierType_Collision );
 
3256
                        BLI_addtail ( &ob->modifiers, md );
 
3257
                        DAG_scene_sort(G.scene);
 
3258
                        DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA);
 
3259
                        allqueue(REDRAWBUTSEDIT, 0);
 
3260
                        allqueue(REDRAWVIEW3D, 0);
 
3261
                }
 
3262
        }
 
3263
        else
 
3264
        {
 
3265
                DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA);
 
3266
                BLI_remlink ( &ob->modifiers, md );
 
3267
                modifier_free ( md );
 
3268
                DAG_scene_sort(G.scene);
 
3269
                allqueue(REDRAWBUTSEDIT, 0);
 
3270
        }
 
3271
}
 
3272
 
 
3273
/* Panels for particle interaction settings */
 
3274
static void object_panel_collision(Object *ob)
 
3275
{
 
3276
        uiBlock *block;
 
3277
        uiBut *but;
 
3278
 
 
3279
        block= uiNewBlock(&curarea->uiblocks, "object_panel_deflection", UI_EMBOSS, UI_HELV, curarea->win);
 
3280
        uiNewPanelTabbed("Fields", "Physics");
 
3281
        if(uiNewPanel(curarea, block, "Collision", "Physics", 0, 0, 318, 204)==0) return;
 
3282
 
 
3283
        uiSetButLock(object_is_libdata(ob), ERROR_LIBDATA_MESSAGE);
 
3284
        
 
3285
        /* should become button, option? */
 
3286
        if(ob->pd==NULL) {
 
3287
                ob->pd= MEM_callocN(sizeof(PartDeflect), "PartDeflect");
 
3288
                /* and if needed, init here */
 
3289
                ob->pd->pdef_sbdamp = 0.1f;
 
3290
                ob->pd->pdef_sbift  = 0.2f;
 
3291
                ob->pd->pdef_sboft  = 0.02f;
 
3292
        }
 
3293
        
 
3294
        /* only meshes collide now */
 
3295
        if(ob->pd && ob->type==OB_MESH) {
 
3296
                PartDeflect *pd= ob->pd;
 
3297
                
 
3298
                but = uiDefButBitS(block, TOG, 1, B_REDR, "Collision",10,160,150,20, &pd->deflect, 0, 0, 0, 0, "Enable this objects as a collider for physics systems");
 
3299
                uiButSetFunc(but, object_collision__enabletoggle, ob, NULL);
 
3300
 
 
3301
                uiDefBut(block, LABEL, 0, "",160,160,150,2, NULL, 0.0, 0, 0, 0, "");
 
3302
                
 
3303
                if(pd->deflect) {
 
3304
                        CollisionModifierData *collmd = (CollisionModifierData *)modifiers_findByType ( ob, eModifierType_Collision );
 
3305
                        
 
3306
                        uiDefBut(block, LABEL, 0, "Particle Interaction",                       10,135,310,20, NULL, 0.0, 0, 0, 0, "");
 
3307
 
 
3308
                        uiBlockBeginAlign(block);
 
3309
                        uiDefButF(block, NUM, B_FIELD_CHANGE, "Damping: ",              10,115,105,20, &pd->pdef_damp, 0.0, 1.0, 10, 2, "Amount of damping during particle collision");
 
3310
                        uiDefButF(block, NUM, B_FIELD_CHANGE, "Rnd: ",  115,115,75,20, &pd->pdef_rdamp, 0.0, 1.0, 10, 2, "Random variation of damping");
 
3311
                        uiDefButF(block, NUM, B_FIELD_CHANGE, "Friction: ",             10,95,105,20, &pd->pdef_frict, 0.0, 1.0, 10, 2, "Amount of friction during particle collision");
 
3312
                        uiDefButF(block, NUM, B_FIELD_CHANGE, "Rnd: ",  115,95,75,20, &pd->pdef_rfrict, 0.0, 1.0, 10, 2, "Random variation of friction");
 
3313
                        uiBlockEndAlign(block);
 
3314
 
 
3315
                        uiDefButBitS(block, TOG, PDEFLE_KILL_PART, B_FIELD_CHANGE, "Kill",200,115,120,20, &pd->flag, 0, 0, 0, 0, "Kill collided particles");
 
3316
                        uiDefButF(block, NUM, B_FIELD_CHANGE, "Permeability: ", 200,90,120,20, &pd->pdef_perm, 0.0, 1.0, 10, 2, "Chance that the particle will pass through the mesh");
 
3317
                        
 
3318
                        uiDefBut(block, LABEL, 0, "Soft Body and Cloth Interaction",                    10,65,310,20, NULL, 0.0, 0, 0, 0, "");
 
3319
 
 
3320
                        uiBlockBeginAlign(block);
 
3321
                        uiDefButF(block, NUM, B_FIELD_CHANGE, "Inner:", 10,45,150,20, &pd->pdef_sbift, 0.001, 1.0, 10, 0, "Inner face thickness");
 
3322
                        uiDefButF(block, NUM, B_FIELD_CHANGE, "Outer:", 160, 45,150,20, &pd->pdef_sboft, 0.001, 1.0, 10, 0, "Outer face thickness");
 
3323
                        uiBlockEndAlign(block);
 
3324
                        uiDefButF(block, NUM, B_FIELD_CHANGE, "Damping:",       10,25,150,20, &pd->pdef_sbdamp, 0.0, 1.0, 10, 0, "Amount of damping during collision");
 
3325
 
 
3326
                        uiDefButBitS(block, TOG, OB_SB_COLLFINAL, B_FIELD_CHANGE, "Ev.M.Stack", 160,25,150,20, &ob->softflag, 0, 0, 0, 0, "Pick collision object from modifier stack (softbody only)");
 
3327
                        
 
3328
                        // collision options
 
3329
                        if(collmd)
 
3330
                        {
 
3331
                                uiDefButS(block, NUM, B_FIELD_CHANGE, "Absorption: ",   10,0,150,20, &collmd->absorption, 0.0, 100, 1, 2, "How much of effector force gets lost during collision with this object (in percent).");
 
3332
                        }
 
3333
                }
 
3334
        }
 
3335
}
 
3336
static void object_panel_fields(Object *ob)
 
3337
{
 
3338
        uiBlock *block;
 
3339
        uiBut *but;
 
3340
        int particles=0;
 
3341
        static short actpsys=-1;
 
3342
        static char slot=0;
 
3343
 
 
3344
        block= uiNewBlock(&curarea->uiblocks, "object_panel_fields", UI_EMBOSS, UI_HELV, curarea->win);
 
3345
        if(uiNewPanel(curarea, block, "Fields", "Physics", 0, 0, 318, 204)==0) return;
 
3346
 
 
3347
        uiSetButLock(object_is_libdata(ob), ERROR_LIBDATA_MESSAGE);
 
3348
        
 
3349
        /* should become button, option? */
 
3350
        if(ob->pd==NULL) {
 
3351
                ob->pd= MEM_callocN(sizeof(PartDeflect), "PartDeflect");
 
3352
                /* and if needed, init here */
 
3353
                ob->pd->pdef_sbdamp = 0.1f;
 
3354
                ob->pd->pdef_sbift  = 0.2f;
 
3355
                ob->pd->pdef_sboft  = 0.02f;
 
3356
        }
 
3357
        
 
3358
        if(ob->pd) {
 
3359
                PartDeflect *pd= ob->pd;
 
3360
                char *menustr= MEM_mallocN(256, "temp string");
 
3361
                char *tipstr="Choose field type";
 
3362
 
 
3363
                uiBlockBeginAlign(block);
 
3364
 
 
3365
                if(ob->particlesystem.first) {
 
3366
                        ParticleSystem *psys;
 
3367
                        char *menustr2= psys_menu_string(ob,1);
 
3368
                        
 
3369
                        psys= psys_get_current(ob);
 
3370
                        if(psys && actpsys >= 0) {
 
3371
                                actpsys= psys_get_current_num(ob)+1;
 
3372
 
 
3373
                                if(psys->part->pd==NULL)
 
3374
                                        psys->part->pd= MEM_callocN(sizeof(PartDeflect), "PartDeflect");
 
3375
 
 
3376
                                if(psys->part->pd2==NULL)
 
3377
                                        psys->part->pd2= MEM_callocN(sizeof(PartDeflect), "PartDeflect");
 
3378
 
 
3379
                                pd= ((slot==1) ? psys->part->pd2 : psys->part->pd);
 
3380
                                particles=1;
 
3381
 
 
3382
                                uiDefButC(block, ROW, B_REDR, "",       10, 163, 14, 14, &slot, 3.0, 0, 0, 0, "Edit first particle effector slot");
 
3383
                                uiDefButC(block, ROW, B_REDR, "",       24, 163, 14, 14, &slot, 3.0, 1, 0, 0, "Edit second particle effector slot");
 
3384
                                uiBlockEndAlign(block);
 
3385
                                uiBlockBeginAlign(block);
 
3386
                        }
 
3387
                        else
 
3388
                                actpsys= -1; /* -1 = object */
 
3389
 
 
3390
                        but=uiDefButS(block, MENU, B_BAKE_REDRAWEDIT, menustr2, 10,180,70,20, &actpsys, 14.0, 0.0, 0, 0, "Browse systems");
 
3391
                        uiButSetFunc(but, PE_change_act, ob, &actpsys);
 
3392
 
 
3393
                        MEM_freeN(menustr2);
 
3394
                }
 
3395
 
 
3396
                /* setup menu button */
 
3397
                if(particles){
 
3398
                        sprintf(menustr, "Field Type%%t|None%%x0|Spherical%%x%d|Wind%%x%d|Vortex%%x%d|Magnetic%%x%d|Harmonic%%x%d|Charge%%x%d|Lennard-Jones%%x%d", 
 
3399
                                        PFIELD_FORCE, PFIELD_WIND, PFIELD_VORTEX, PFIELD_MAGNET, PFIELD_HARMONIC, PFIELD_CHARGE, PFIELD_LENNARDJ);
 
3400
 
 
3401
                        if(pd->forcefield==PFIELD_FORCE) tipstr= "Particle attracts or repels particles (On shared object layers)";
 
3402
                        else if(pd->forcefield==PFIELD_WIND) tipstr= "Constant force applied in direction of particle Z axis (On shared object layers)";
 
3403
                        else if(pd->forcefield==PFIELD_VORTEX) tipstr= "Particles swirl around Z-axis of the particle (On shared object layers)";
 
3404
                }
 
3405
                else{
 
3406
                        if(ob->type==OB_CURVE)
 
3407
                                sprintf(menustr, "Field Type%%t|None%%x0|Spherical%%x%d|Wind%%x%d|Vortex%%x%d|Curve Guide%%x%d|Magnetic%%x%d|Harmonic%%x%d|Texture%%x%d|Charge%%x%d|Lennard-Jones%%x%d", 
 
3408
                                                PFIELD_FORCE, PFIELD_WIND, PFIELD_VORTEX, PFIELD_GUIDE, PFIELD_MAGNET, PFIELD_HARMONIC, PFIELD_TEXTURE, PFIELD_CHARGE, PFIELD_LENNARDJ);
 
3409
                        else
 
3410
                                sprintf(menustr, "Field Type%%t|None%%x0|Spherical%%x%d|Wind%%x%d|Vortex%%x%d|Magnetic%%x%d|Harmonic%%x%d|Texture%%x%d|Charge%%x%d|Lennard-Jones%%x%d", 
 
3411
                                                PFIELD_FORCE, PFIELD_WIND, PFIELD_VORTEX, PFIELD_MAGNET, PFIELD_HARMONIC, PFIELD_TEXTURE, PFIELD_CHARGE, PFIELD_LENNARDJ);
 
3412
 
 
3413
                        if(pd->forcefield==PFIELD_FORCE) tipstr= "Object center attracts or repels particles (On shared object layers)";
 
3414
                        else if(pd->forcefield==PFIELD_WIND) tipstr= "Constant force applied in direction of Object Z axis (On shared object layers)";
 
3415
                        else if(pd->forcefield==PFIELD_VORTEX) tipstr= "Particles swirl around Z-axis of the Object (On shared object layers)";
 
3416
                        else if(pd->forcefield==PFIELD_GUIDE) tipstr= "Use a Curve Path to guide particles (On shared object layers)";
 
3417
                }
 
3418
                
 
3419
                if(ob->particlesystem.first)
 
3420
                        uiDefButS(block, MENU, B_FIELD_DEP, menustr,                    80,180,70,20, &pd->forcefield, 0.0, 0.0, 0, 0, tipstr);
 
3421
                else
 
3422
                        uiDefButS(block, MENU, B_FIELD_DEP, menustr,                    10,180,140,20, &pd->forcefield, 0.0, 0.0, 0, 0, tipstr);
 
3423
 
 
3424
                uiBlockEndAlign(block);
 
3425
                uiDefBut(block, LABEL, 0, "",160,180,150,2, NULL, 0.0, 0, 0, 0, "");
 
3426
                
 
3427
                if(pd->forcefield) {
 
3428
                        uiBlockBeginAlign(block);
 
3429
                        if(pd->forcefield == PFIELD_GUIDE) {
 
3430
                                uiDefButF(block, NUM, B_FIELD_CHANGE, "MinDist: ",      10,140,140,20, &pd->f_strength, 0.0, 1000.0, 10, 0, "The distance from which particles are affected fully.");
 
3431
                                uiDefButF(block, NUM, B_FIELD_CHANGE, "Fall-off: ",     10,120,140,20, &pd->f_power, 0.0, 10.0, 10, 0, "Falloff factor, between mindist and maxdist");
 
3432
                                uiDefButF(block, NUM, B_FIELD_CHANGE, "Free: ", 10,100,140,20, &pd->free_end, 0.0, 0.99, 10, 0, "Guide-free time from particle life's end");
 
3433
                                uiBlockEndAlign(block);
 
3434
                                uiBlockBeginAlign(block);
 
3435
                                uiDefButBitS(block, TOG, PFIELD_USEMAX, B_FIELD_CHANGE, "Use",  10,80,40,20, &pd->flag, 0.0, 0, 0, 0, "Use a maximum distance for the field to work");
 
3436
                                uiDefButF(block, NUM, B_FIELD_CHANGE, "MaxDist: ",      50,80,100,20, &pd->maxdist, 0, 1000.0, 10, 0, "Maximum distance for the field to work");
 
3437
                        }
 
3438
                        else {
 
3439
                                uiDefButF(block, NUM, B_FIELD_CHANGE, "Strength: ",     10,140,140,20, &pd->f_strength, -1000, 1000, 10, 3, "Strength of force field");
 
3440
                                
 
3441
                                if(pd->forcefield == PFIELD_TEXTURE){
 
3442
                                        uiDefIDPoinBut(block, field_testTexture, ID_TE, B_FIELD_CHANGE, "Texture: ", 10,120,140,20, &pd->tex, "Texture to use as force");
 
3443
                                        uiBlockEndAlign(block);
 
3444
                                        uiBlockBeginAlign(block);
 
3445
                                        uiDefButBitS(block, TOG, PFIELD_TEX_OBJECT, B_FIELD_CHANGE, "Use Object Co",    10,95,140,20, &pd->flag, 0.0, 0, 0, 0, "Use object/global coordinates for texture");
 
3446
                                        uiDefButBitS(block, TOG, PFIELD_TEX_ROOTCO, B_FIELD_CHANGE, "Root TexCo",       10,75,100,20, &pd->flag, 0.0, 0, 0, 0, "Texture coords from root particle locations");
 
3447
                                        uiDefButBitS(block, TOG, PFIELD_TEX_2D, B_FIELD_CHANGE, "2D",   120,75,30,20, &pd->flag, 0.0, 0, 0, 0, "Apply force only in 2d");
 
3448
                                }
 
3449
                                else if(pd->forcefield == PFIELD_HARMONIC) 
 
3450
                                        uiDefButF(block, NUM, B_FIELD_CHANGE, "Damp: ", 10,120,140,20, &pd->f_damp, 0, 10, 10, 0, "Damping of the harmonic force");     
 
3451
                                else if(pd->forcefield == PFIELD_WIND) 
 
3452
                                        uiDefButF(block, NUM, B_FIELD_CHANGE, "Noise: ",10,120,140,20, &pd->f_noise, 0, 10, 100, 0, "Noise of the wind force"); 
 
3453
                        }
 
3454
                        uiBlockEndAlign(block);
 
3455
                        
 
3456
                        uiBlockBeginAlign(block);
 
3457
                        if(pd->forcefield == PFIELD_GUIDE){
 
3458
                                uiDefButBitS(block, TOG, PFIELD_GUIDE_PATH_ADD, B_FIELD_CHANGE, "Additive",     10,40,140,20, &pd->flag, 0.0, 0, 0, 0, "Based on distance/falloff it adds a portion of the entire path");
 
3459
                        }
 
3460
                        else if(pd->forcefield==PFIELD_TEXTURE){
 
3461
                                uiDefButS(block, MENU, B_FIELD_CHANGE, "Texture mode%t|RGB%x0|Gradient%x1|Curl%x2",     10,50,140,20, &pd->tex_mode, 0.0, 0.0, 0, 0, "How the texture effect is calculated (RGB & Curl need a RGB texture else Gradient will be used instead)");
 
3462
        
 
3463
                                uiDefButF(block, NUM, B_FIELD_CHANGE, "Nabla:", 10,30,140,20, &pd->tex_nabla, 0.0001f, 1.0, 1, 0, "Specify the dimension of the area for gradient and curl calculation");
 
3464
                        }
 
3465
                        else if(particles==0 && ELEM(pd->forcefield,PFIELD_VORTEX,PFIELD_WIND)==0){
 
3466
                                //uiDefButF(block, NUM, B_FIELD_CHANGE, "Distance: ",   10,20,140,20, &pd->f_dist, 0, 1000.0, 10, 0, "Falloff power (real gravitational fallof = 2)");
 
3467
                                uiDefButBitS(block, TOG, PFIELD_PLANAR, B_FIELD_CHANGE, "Planar",       10,15,140,20, &pd->flag, 0.0, 0, 0, 0, "Create planar field");
 
3468
                        }
 
3469
                        uiBlockEndAlign(block);
 
3470
                        
 
3471
                        if(pd->forcefield==PFIELD_GUIDE){
 
3472
                                uiBlockBeginAlign(block);
 
3473
                                uiDefButF(block, NUMSLI, B_FIELD_CHANGE, "Clump:",              160,180,140,20, &pd->clump_fac, -1.0, 1.0, 1, 3, "Amount of clumpimg");
 
3474
                                uiDefButF(block, NUMSLI, B_FIELD_CHANGE, "Shape:",              160,160,140,20, &pd->clump_pow, -0.999, 0.999, 1, 3, "Shape of clumpimg");
 
3475
                                uiBlockEndAlign(block);
 
3476
 
 
3477
                                uiBlockBeginAlign(block);
 
3478
                                if(pd->kink){
 
3479
                                        uiDefButS(block, MENU, B_FIELD_CHANGE, "Kink:%t|Roll%x6|Rotation%x5|Braid%x4|Wave%x3|Radial%x2|Curl%x1|Nothing%x0", 160,120,70,20, &pd->kink, 14.0, 0.0, 0, 0, "Type of periodic offset on the curve");
 
3480
                                        uiDefButS(block, MENU, B_FIELD_CHANGE, "Axis %t|Z %x2|Y %x1|X %x0", 230,120,70,20, &pd->kink_axis, 14.0, 0.0, 0, 0, "Which axis to use for offset");
 
3481
                                        uiDefButF(block, NUM, B_FIELD_CHANGE, "Freq:",                  160,100,140,20, &pd->kink_freq, 0.0, 10.0, 1, 3, "The frequency of the offset (1/total length)");
 
3482
                                        uiDefButF(block, NUMSLI, B_FIELD_CHANGE, "Shape:",              160,80,140,20, &pd->kink_shape, -0.999, 0.999, 1, 3, "Adjust the offset to the beginning/end");
 
3483
                                        uiDefButF(block, NUM, B_FIELD_CHANGE, "Amplitude:",     160,60,140,20, &pd->kink_amp, 0.0, 10.0, 1, 3, "The amplitude of the offset");
 
3484
                                }
 
3485
                                else{
 
3486
                                        uiDefButS(block, MENU, B_FIELD_CHANGE, "Kink:%t|Roll%x6|Rotation%x5|Braid%x4|Wave%x3|Radial%x2|Curl%x1|Nothing%x0", 160,120,140,20, &pd->kink, 14.0, 0.0, 0, 0, "Type of periodic offset on the curve");
 
3487
                                }
 
3488
                                uiBlockEndAlign(block);
 
3489
                        }
 
3490
                        else{
 
3491
                                if(pd->forcefield==PFIELD_LENNARDJ) {
 
3492
                                        uiDefBut(block, LABEL, 0, "Fall-off determined",                160,140,140,20, NULL, 0.0, 0, 0, 0, "");
 
3493
                                        uiDefBut(block, LABEL, 0, "by particle sizes",          160,120,140,20, NULL, 0.0, 0, 0, 0, "");
 
3494
                                }
 
3495
                                else {
 
3496
                                        uiDefButS(block, MENU, B_FIELD_DEP, "Fall-off%t|Cone%x2|Tube%x1|Sphere%x0",     160,180,140,20, &pd->falloff, 0.0, 0.0, 0, 0, "Fall-off shape");
 
3497
                                        if(pd->falloff==PFIELD_FALL_TUBE)
 
3498
                                                uiDefBut(block, LABEL, 0, "Longitudinal",               160,160,140,20, NULL, 0.0, 0, 0, 0, "");
 
3499
                                        uiBlockBeginAlign(block);
 
3500
                                        uiDefButBitS(block, TOG, PFIELD_POSZ, B_FIELD_CHANGE, "Pos",    160,140,40,20, &pd->flag, 0.0, 0, 0, 0, "Effect only in direction of positive Z axis");
 
3501
                                        uiDefButF(block, NUM, B_FIELD_CHANGE, "Fall-off: ",     200,140,100,20, &pd->f_power, 0, 10, 10, 0, "Falloff power (real gravitational falloff = 2)");
 
3502
                                        uiDefButBitS(block, TOG, PFIELD_USEMAX, B_FIELD_CHANGE, "Use",  160,120,40,20, &pd->flag, 0.0, 0, 0, 0, "Use a maximum distance for the field to work");
 
3503
                                        uiDefButF(block, NUM, B_FIELD_CHANGE, "MaxDist: ",      200,120,100,20, &pd->maxdist, 0, 1000.0, 10, 0, "Maximum distance for the field to work");
 
3504
                                        uiDefButBitS(block, TOG, PFIELD_USEMIN, B_FIELD_CHANGE, "Use",  160,100,40,20, &pd->flag, 0.0, 0, 0, 0, "Use a minimum distance for the field's fall-off");
 
3505
                                        uiDefButF(block, NUM, B_FIELD_CHANGE, "MinDist: ",      200,100,100,20, &pd->mindist, 0, 1000.0, 10, 0, "Minimum distance for the field's fall-off");
 
3506
                                        uiBlockEndAlign(block);
 
3507
 
 
3508
                                        if(pd->falloff==PFIELD_FALL_TUBE){
 
3509
                                                uiDefBut(block, LABEL, 0, "Radial",             160,80,70,20, NULL, 0.0, 0, 0, 0, "");
 
3510
                                                uiBlockBeginAlign(block);
 
3511
                                                uiDefButF(block, NUM, B_FIELD_CHANGE, "Fall-off: ",     160,60,140,20, &pd->f_power_r, 0, 10, 10, 0, "Radial falloff power (real gravitational falloff = 2)");
 
3512
                                                uiDefButBitS(block, TOG, PFIELD_USEMAXR, B_FIELD_CHANGE, "Use", 160,40,40,20, &pd->flag, 0.0, 0, 0, 0, "Use a maximum radial distance for the field to work");
 
3513
                                                uiDefButF(block, NUM, B_FIELD_CHANGE, "MaxDist: ",      200,40,100,20, &pd->maxrad, 0, 1000.0, 10, 0, "Maximum radial distance for the field to work");
 
3514
                                                uiDefButBitS(block, TOG, PFIELD_USEMINR, B_FIELD_CHANGE, "Use", 160,20,40,20, &pd->flag, 0.0, 0, 0, 0, "Use a minimum radial distance for the field's fall-off");
 
3515
                                                uiDefButF(block, NUM, B_FIELD_CHANGE, "MinDist: ",      200,20,100,20, &pd->minrad, 0, 1000.0, 10, 0, "Minimum radial distance for the field's fall-off");
 
3516
                                                uiBlockEndAlign(block);
 
3517
                                        }
 
3518
                                        else if(pd->falloff==PFIELD_FALL_CONE){
 
3519
                                                uiDefBut(block, LABEL, 0, "Angular",            160,80,70,20, NULL, 0.0, 0, 0, 0, "");
 
3520
                                                uiBlockBeginAlign(block);
 
3521
                                                uiDefButF(block, NUM, B_FIELD_CHANGE, "Fall-off: ",     160,60,140,20, &pd->f_power_r, 0, 10, 10, 0, "Radial falloff power (real gravitational falloff = 2)");
 
3522
                                                uiDefButBitS(block, TOG, PFIELD_USEMAXR, B_FIELD_CHANGE, "Use", 160,40,40,20, &pd->flag, 0.0, 0, 0, 0, "Use a maximum angle for the field to work");
 
3523
                                                uiDefButF(block, NUM, B_FIELD_CHANGE, "MaxAngle: ",     200,40,100,20, &pd->maxrad, 0, 89.0, 10, 0, "Maximum angle for the field to work (in radians)");
 
3524
                                                uiDefButBitS(block, TOG, PFIELD_USEMINR, B_FIELD_CHANGE, "Use", 160,20,40,20, &pd->flag, 0.0, 0, 0, 0, "Use a minimum angle for the field's fall-off");
 
3525
                                                uiDefButF(block, NUM, B_FIELD_CHANGE, "MinAngle: ",     200,20,100,20, &pd->minrad, 0, 89.0, 10, 0, "Minimum angle for the field's fall-off (in radians)");
 
3526
                                                uiBlockEndAlign(block);
 
3527
                                        }
 
3528
                                }
 
3529
                        }
 
3530
 
 
3531
                }       
 
3532
                
 
3533
                MEM_freeN(menustr);
 
3534
        }
 
3535
}
 
3536
 
 
3537
/* Generic physics baking buttons */
 
3538
 
 
3539
static void object_physics__baketoggle(void *pid_v, void *unused_v)
 
3540
{
 
3541
        PTCacheID *pid = pid_v;
 
3542
        Object *ob = pid->ob;
 
3543
        PointCache *cache = pid->cache;
 
3544
        ClothModifierData *clmd;
 
3545
        int cageIndex, stack_index, startframe, endframe;
 
3546
 
 
3547
        // automatically enable modifier in editmode when we have a protected cache
 
3548
        if(!(cache->flag & PTCACHE_BAKED)) {
 
3549
                BKE_ptcache_id_time(pid, 0.0f, &startframe, &endframe, NULL);
 
3550
                pointcache_bake(pid, startframe);
 
3551
 
 
3552
                if(pid->type == PTCACHE_TYPE_CLOTH) {
 
3553
                        clmd= (ClothModifierData*)pid->data;
 
3554
                        cageIndex = modifiers_getCageIndex(ob, NULL );
 
3555
                        stack_index = modifiers_indexInObject(ob, (ModifierData *)clmd);
 
3556
                        if(stack_index >= cageIndex)
 
3557
                                ((ModifierData *)clmd)->mode ^= eModifierMode_OnCage;
 
3558
                }
 
3559
        }
 
3560
        else {
 
3561
                if(cache->flag & PTCACHE_BAKE_EDIT_ACTIVE) {
 
3562
                        notice("Can't free bake in editmode");
 
3563
                }
 
3564
                else {
 
3565
                        if(pid->type == PTCACHE_TYPE_CLOTH) {
 
3566
                                clmd= (ClothModifierData*)pid->data;
 
3567
                                ((ModifierData *)clmd)->mode ^= eModifierMode_OnCage;
 
3568
                        }
 
3569
 
 
3570
                        cache->flag &= ~PTCACHE_BAKED;
 
3571
                        BKE_ptcache_id_reset(pid, PTCACHE_RESET_OUTDATED);
 
3572
                        DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA);
 
3573
                }
 
3574
        }
 
3575
}
 
3576
 
 
3577
static void object_physics__rebake(void *pid_v, void *unused_v)
 
3578
{
 
3579
        PTCacheID *pid = pid_v;
 
3580
        int curframe = (int)G.scene->r.cfra;
 
3581
 
 
3582
        BKE_ptcache_id_clear(pid, PTCACHE_CLEAR_AFTER, curframe);
 
3583
        pointcache_bake(pid, curframe);
 
3584
}
 
3585
 
 
3586
static void object_physics__clearcache(void *pid_v, void *unused_v)
 
3587
{
 
3588
        PTCacheID *pid = pid_v;
 
3589
        Object *ob = pid->ob;
 
3590
        PointCache *cache = pid->cache;
 
3591
 
 
3592
        if(cache->flag & PTCACHE_BAKE_EDIT_ACTIVE)
 
3593
                return;
 
3594
 
 
3595
        BKE_ptcache_id_reset(pid, PTCACHE_RESET_BAKED);
 
3596
        DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA); 
 
3597
 
 
3598
        allqueue(REDRAWBUTSOBJECT, 0);
 
3599
        allqueue(REDRAWVIEW3D, 0);
 
3600
}
 
3601
 
 
3602
static void object_physics_bake_buttons(uiBlock *block, PTCacheID *pid, int y, int libdata)
 
3603
{
 
3604
        uiBut *but;
 
3605
        PointCache *cache;
 
3606
        
 
3607
        cache= pid->cache;
 
3608
 
 
3609
        if(!libdata && G.obedit)
 
3610
                uiSetButLock(1, "Can't change bake settings in editmode");
 
3611
 
 
3612
        if(cache->flag & PTCACHE_BAKED)
 
3613
                but = uiDefBut(block, BUT, REDRAWBUTSOBJECT, "Free Bake", 10,y+25,85,20, NULL, 0.0, 0.0, 0, 0, "Free baked simulation");
 
3614
        else
 
3615
                but = uiDefBut(block, BUT, REDRAWBUTSOBJECT, "Bake", 10,y+25,85,20, NULL, 0.0, 0.0, 0, 0, "Bake specified frame range");
 
3616
        uiButSetFunc(but, object_physics__baketoggle, pid, NULL);
 
3617
 
 
3618
        if(!libdata && !G.obedit && (cache->flag & PTCACHE_BAKED))
 
3619
                uiSetButLock(1, "Simulation frames are baked");
 
3620
 
 
3621
        uiBlockBeginAlign(block);
 
3622
        uiDefButI(block, NUM, B_BAKE_CACHE_CHANGE, "Start:", 100,y+25,105,20, &cache->startframe, 1, MAXFRAME, 1, 0, "Frame on which the simulation starts");
 
3623
        uiDefButI(block, NUM, B_BAKE_CACHE_CHANGE, "End:", 205,y+25,105,20, &cache->endframe, 1, MAXFRAME, 1, 0, "Frame on which the simulation stops");
 
3624
        uiBlockEndAlign(block);
 
3625
                        
 
3626
        if(cache->flag & PTCACHE_BAKED) {
 
3627
                if(pid->type == PTCACHE_TYPE_CLOTH ||
 
3628
                   (pid->type == PTCACHE_TYPE_SOFTBODY && !((SoftBody*)pid->data)->particles)) {
 
3629
                        if(!libdata && !G.obedit)
 
3630
                                uiClearButLock();
 
3631
 
 
3632
                        uiBlockBeginAlign(block);
 
3633
                        uiDefButBitI(block, TOG, PTCACHE_BAKE_EDIT, REDRAWVIEW3D, "Bake Editing",       10,y,100,20, &cache->flag, 0, 0, 0, 0, "Enable editing of the baked results in editmode.");
 
3634
                        but= uiDefBut(block, BUT, REDRAWBUTSOBJECT, "Rebake From Current Frame", 110,y,200,20, NULL, 0.0, 0.0, 0, 0, "Bake again from current frame");
 
3635
                        uiButSetFunc(but, object_physics__rebake, pid, NULL);
 
3636
                        uiBlockEndAlign(block);
 
3637
                }
 
3638
 
 
3639
                if(!libdata)
 
3640
                        uiClearButLock();
 
3641
        }
 
3642
        else {
 
3643
                char str[512];
 
3644
                int exist, startframe, endframe;
 
3645
 
 
3646
                if(!libdata)
 
3647
                        uiClearButLock();
 
3648
                
 
3649
                BKE_ptcache_id_time(pid, 0.0f, &startframe, &endframe, NULL);
 
3650
                exist= BKE_ptcache_id_exist(pid, startframe);
 
3651
 
 
3652
                sprintf(str, "%simulation frames in disk cache.", (exist)? "S": "No s");
 
3653
                uiDefBut(block, LABEL, 0, str, 10,y,200,20, NULL, 0.0, 0, 0, 0, "");
 
3654
 
 
3655
                if(exist) {
 
3656
                        but= uiDefBut(block, BUT, REDRAWBUTSOBJECT, "Free Cache", 210,y,100,20, NULL, 0.0, 0.0, 0, 0, "Free cached simulation results");
 
3657
                        uiButSetFunc(but, object_physics__clearcache, pid, NULL);
 
3658
                }
 
3659
        }
 
3660
}
 
3661
 
 
3662
/* Panel for softbodies */
 
3663
static void object_softbodies__enable(void *ob_v, void *arg2)
 
3664
{
 
3665
        Object *ob = ob_v;
 
3666
        ModifierData *md = modifiers_findByType(ob, eModifierType_Softbody);
 
3667
        PTCacheID pid;
 
3668
 
 
3669
        if(md) {
 
3670
                BLI_remlink(&ob->modifiers, md);
 
3671
                modifier_free(md);
 
3672
                BIF_undo_push("Del modifier");
 
3673
 
 
3674
                ob->softflag &= ~OB_SB_ENABLE;
 
3675
        } else {
 
3676
                md = modifier_new(eModifierType_Softbody);
 
3677
                BLI_addhead(&ob->modifiers, md);
 
3678
 
 
3679
                if (!ob->soft) {
 
3680
                        ob->soft= sbNew();
 
3681
                        ob->softflag |= OB_SB_GOAL|OB_SB_EDGES;
 
3682
 
 
3683
                        BKE_ptcache_id_from_softbody(&pid, ob, ob->soft);
 
3684
                        BKE_ptcache_id_clear(&pid, PTCACHE_CLEAR_ALL, 0);
 
3685
                }
 
3686
 
 
3687
                ob->softflag |= OB_SB_ENABLE;
 
3688
        }
 
3689
 
 
3690
        /* needed so that initial state is cached correctly */
 
3691
        DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA);
 
3692
 
 
3693
        allqueue(REDRAWBUTSEDIT, 0);
 
3694
        allqueue(REDRAWVIEW3D, 0);
 
3695
}
 
3696
 
 
3697
static int _can_softbodies_at_all(Object *ob)
 
3698
{
 
3699
        // list of Yes
 
3700
    if ((ob->type==OB_MESH)
 
3701
                || (ob->type==OB_CURVE)
 
3702
                || (ob->type==OB_LATTICE)
 
3703
                || (ob->type==OB_SURF)
 
3704
                ) return 1;
 
3705
        // else deny
 
3706
        return 0;
 
3707
}
 
3708
static void object_softbodies__enable_psys(void *ob_v, void *psys_v)
 
3709
{
 
3710
        ParticleSystem *psys = psys_v;
 
3711
        Object *ob = ob_v;
 
3712
 
 
3713
        if(psys->softflag & OB_SB_ENABLE) {
 
3714
                psys->softflag &= ~OB_SB_ENABLE;
 
3715
        }
 
3716
        else{
 
3717
                if (!psys->soft) {
 
3718
                        psys->soft= sbNew();
 
3719
                        psys->softflag |= OB_SB_GOAL|OB_SB_EDGES;
 
3720
                        psys->soft->particles=psys;
 
3721
                }
 
3722
                psys->softflag |= OB_SB_ENABLE;
 
3723
        }
 
3724
 
 
3725
        DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA);
 
3726
 
 
3727
        allqueue(REDRAWBUTSEDIT, 0);
 
3728
}
 
3729
 
 
3730
 
 
3731
#ifdef _work_on_sb_solver
 
3732
static char sbsolvers[] = "Solver %t|RKP almost SOFT not usable but for some german teachers %x1|STU ip semi implicit euler%x3|SI1  (half step)adaptive semi implict euler %x2|SI2  (use dv)adaptive semi implict euler %x4|SOFT  step size controlled midpoint(1rst choice for real softbodies)%x0";
 
3733
/* SIF would have been candidate  .. well lack of time .. brecht is busy .. better make a stable version for peach now :) */
 
3734
static char sbsolvers[] = "SIF  semi implicit euler with fixed step size (worth a try with real stiff egdes)%x3|SOFT  step size controlled midpoint(1rst choice for real softbodies)%x0";
 
3735
#else
 
3736
static char sbsolvers[] = "RKCP correct physics (harder to get stable but usefull for education :)%x1|SOFT  step size controlled midpoint(1rst choice for real softbodies)%x0";
 
3737
#endif
 
3738
 
 
3739
static void object_softbodies_collision(Object *ob)
 
3740
{
 
3741
        SoftBody *sb=ob->soft;
 
3742
        uiBlock *block;
 
3743
        static int val;
 
3744
        short *softflag=&ob->softflag, psys_cur=0;
 
3745
        int ob_has_hair=psys_ob_has_hair(ob);
 
3746
        static PTCacheID staticpid;
 
3747
        int libdata;
 
3748
 
 
3749
    if(!_can_softbodies_at_all(ob)) return;
 
3750
        /*bah that is ugly! creating missing data members in UI code*/
 
3751
        if(ob->pd == NULL){
 
3752
                ob->pd= MEM_callocN(sizeof(PartDeflect), "PartDeflect");
 
3753
                ob->pd->pdef_sbdamp = 0.1f;
 
3754
                ob->pd->pdef_sbift  = 0.2f;
 
3755
                ob->pd->pdef_sboft  = 0.02f;
 
3756
        }
 
3757
        block= uiNewBlock(&curarea->uiblocks, "object_softbodies_collision", UI_EMBOSS, UI_HELV, curarea->win);
 
3758
        uiNewPanelTabbed("Soft Body", "Physics"); 
 
3759
        if(uiNewPanel(curarea, block, "Soft Body Collision", "Physics", 651, 0, 318, 204)==0) return;
 
3760
 
 
3761
        libdata= object_is_libdata(ob);
 
3762
        uiSetButLock(libdata, ERROR_LIBDATA_MESSAGE);
 
3763
 
 
3764
        if(ob_has_hair) {
 
3765
                if(PE_get_current_num(ob) >= 0) {
 
3766
                        ParticleSystem *psys = PE_get_current(ob);
 
3767
                        if(psys) {
 
3768
                                sb = psys->soft;
 
3769
                                softflag = &psys->softflag;
 
3770
                                psys_cur = 1;
 
3771
                        }
 
3772
                }
 
3773
        }
 
3774
 
 
3775
        if(psys_cur) {
 
3776
                if(*softflag & OB_SB_ENABLE)
 
3777
                        val = 1;
 
3778
                else
 
3779
                        val = 0;
 
3780
        }
 
3781
        else
 
3782
                val = modifiers_isSoftbodyEnabled(ob);
 
3783
 
 
3784
        if(!val) {
 
3785
                uiDefBut(block, LABEL, 0, "",10,10,1,2, NULL, 0.0, 0, 0, 0, ""); /* tell UI we go to 10,10*/
 
3786
                uiBlockBeginAlign(block);
 
3787
                if(psys_cur){
 
3788
                        uiDefBut(block, LABEL, 0, "Hair is not a softbody.",10,190,300,20, NULL, 0.0, 0, 0, 0, ""); 
 
3789
                }
 
3790
                else {
 
3791
                        uiDefBut(block, LABEL, 0, "Object is not a softbody.",10,190,300,20, NULL, 0.0, 0, 0, 0, ""); 
 
3792
                }
 
3793
                uiBlockEndAlign(block);
 
3794
        }
 
3795
        else{
 
3796
                BKE_ptcache_id_from_softbody(&staticpid, ob, sb);
 
3797
                object_physics_bake_buttons(block, &staticpid, 125, libdata);
 
3798
 
 
3799
                /* SELF COLLISION STUFF */
 
3800
                if ((ob->type==OB_MESH)||(ob->type==OB_CURVE) ) {
 
3801
                        uiBlockBeginAlign(block);
 
3802
                        if (*softflag & OB_SB_EDGES){
 
3803
                                uiDefButBitS(block, TOG, OB_SB_SELF, B_BAKE_CACHE_CHANGE, "Self Collision",             10,80,150,20, softflag, 0, 0, 0, 0, "enable naive vertex ball self collision");
 
3804
                                if(*softflag & OB_SB_SELF){
 
3805
                                        uiDefButF(block, NUM, B_BAKE_CACHE_CHANGE, "Ball Size:", 160,80,150,20, &sb->colball, -10.0,  10.0, 10, 0, "Absolute ball size or factor if not manual adjusted");
 
3806
                                        uiDefButS(block, ROW, B_BAKE_CACHE_CHANGE, "Man",10,60,60,20, &sb->sbc_mode, 4.0,SBC_MODE_MANUAL, 0, 0, "Manual adjust");
 
3807
                                        uiDefButS(block, ROW, B_BAKE_CACHE_CHANGE, "Av",70,60,60,20, &sb->sbc_mode, 4.0,SBC_MODE_AVG, 0, 0, "Average Spring lenght * Ball Size");
 
3808
                                        uiDefButS(block, ROW, B_BAKE_CACHE_CHANGE, "Min",130,60,60,20, &sb->sbc_mode, 4.0,SBC_MODE_MIN, 0, 0, "Minimal Spring lenght * Ball Size");
 
3809
                                        uiDefButS(block, ROW, B_BAKE_CACHE_CHANGE, "Max",190,60,60,20, &sb->sbc_mode, 4.0,SBC_MODE_MAX, 0, 0, "Maximal Spring lenght * Ball Size");
 
3810
                                        uiDefButS(block, ROW, B_BAKE_CACHE_CHANGE, "AvMiMa",250,60,60,20, &sb->sbc_mode, 4.0,SBC_MODE_AVGMINMAX, 0, 0, "(Min+Max)/2 * Ball Size");
 
3811
                                        uiDefButF(block, NUM, B_BAKE_CACHE_CHANGE, "B Stiff:", 10,40,150,20, &sb->ballstiff, 0.001,  100.0, 10, 0, "Ball inflating presure");
 
3812
                                        uiDefButF(block, NUM, B_BAKE_CACHE_CHANGE, "B Damp:", 160,40,150,20, &sb->balldamp,  0.001,  1.0, 10, 0, "Blending to inelastic collision");
 
3813
                                }
 
3814
                        }
 
3815
                        else{
 
3816
                                uiDefBut(block, LABEL, 0, "<Self Collision> not available because there",10,80,300,20, NULL, 0.0, 0, 0, 0, ""); 
 
3817
                                uiDefBut(block, LABEL, 0, "are no edges, enable <Use Edges>",10,60,300,20, NULL, 0.0, 0, 0, 0, ""); 
 
3818
                        }
 
3819
 
 
3820
                        uiBlockEndAlign(block);
 
3821
                        /*SOLVER SETTINGS*/
 
3822
                        /* done in another panel now*/
 
3823
                }
 
3824
 
 
3825
                uiDefBut(block, LABEL, 0, "",10,10,1,2, NULL, 0.0, 0, 0, 0, ""); /* tell UI we go to 10,10*/
 
3826
        }
 
3827
        uiBlockEndAlign(block);
 
3828
}
 
3829
static void object_softbodies_solver(Object *ob)
 
3830
{
 
3831
        SoftBody *sb=ob->soft;
 
3832
        uiBlock *block;
 
3833
        static int val;
 
3834
        short *softflag=&ob->softflag, psys_cur=0, adaptive_mode=0;
 
3835
        int ob_has_hair=psys_ob_has_hair(ob);
 
3836
        if(!_can_softbodies_at_all(ob)) return;
 
3837
        block= uiNewBlock(&curarea->uiblocks, "object_softbodies_solver", UI_EMBOSS, UI_HELV, curarea->win);
 
3838
        uiNewPanelTabbed("Soft Body", "Physics"); 
 
3839
        if(uiNewPanel(curarea, block, "Soft Body Solver", "Physics", 651, 0, 318, 204)==0) return;
 
3840
 
 
3841
        uiSetButLock(object_is_libdata(ob), ERROR_LIBDATA_MESSAGE);
 
3842
 
 
3843
        /* doubt that is really needed here but for now */ 
 
3844
        if(ob_has_hair) {
 
3845
                if(PE_get_current_num(ob) >= 0) {
 
3846
                        ParticleSystem *psys = PE_get_current(ob);
 
3847
                        if(psys) {
 
3848
                                sb = psys->soft;
 
3849
                                softflag = &psys->softflag;
 
3850
                                psys_cur = 1;
 
3851
                        }
 
3852
                }
 
3853
        }
 
3854
 
 
3855
        if(psys_cur) {
 
3856
                if(*softflag & OB_SB_ENABLE)
 
3857
                        val = 1;
 
3858
                else
 
3859
                        val = 0;
 
3860
        }
 
3861
        else
 
3862
                val = modifiers_isSoftbodyEnabled(ob);
 
3863
 
 
3864
        if(!val) { 
 
3865
                uiDefBut(block, LABEL, 0, "",10,10,1,2, NULL, 0.0, 0, 0, 0, ""); /* tell UI we go to 10,10*/
 
3866
                if(psys_cur){
 
3867
                        uiDefBut(block, LABEL, 0, "Hair is not a softbody.",10,190,300,20, NULL, 0.0, 0, 0, 0, ""); 
 
3868
                }
 
3869
                else {
 
3870
                        uiDefBut(block, LABEL, 0, "Object is not a softbody.",10,190,300,20, NULL, 0.0, 0, 0, 0, ""); 
 
3871
                }
 
3872
        }
 
3873
        else{ 
 
3874
                if ((ob->type==OB_MESH)||(ob->type==OB_CURVE) ) {
 
3875
                        /*SOLVER SETTINGS*/
 
3876
                        uiBlockBeginAlign(block);
 
3877
                        uiDefBut(block, LABEL, 0, "Solver select",10,200,300,20, NULL, 0.0, 0, 0, 0, ""); 
 
3878
                        uiDefButS(block, MENU, B_BAKE_CACHE_CHANGE, sbsolvers,10,180,300,20, &sb->solver_ID, 14.0, 0.0, 0, 0, "Select Solver");
 
3879
                        uiBlockEndAlign(block);
 
3880
 
 
3881
                        /*some have adapive step size - some not*/
 
3882
                        switch (sb->solver_ID) {
 
3883
                        case 0:
 
3884
                        case 1:
 
3885
                                {adaptive_mode = 1; break;}
 
3886
                        case 3:
 
3887
                                {adaptive_mode = 0; break;}
 
3888
                        default: printf("SB_solver?\n"); // should never happen
 
3889
                        }
 
3890
                        if(adaptive_mode){
 
3891
                                uiBlockBeginAlign(block);
 
3892
                                uiDefBut(block, LABEL, 0, "Step size controls",10,160,300,20, NULL, 0.0, 0, 0, 0, "");
 
3893
                                uiDefButF(block, NUM, B_BAKE_CACHE_CHANGE, "Error Lim:",        10,140,280,20, &sb->rklimit , 0.001, 10.0, 10, 0, "The Runge-Kutta ODE solver error limit, low value gives more precision, high values speed");
 
3894
                                uiDefButBitS(block, TOG, SBSO_OLDERR, B_BAKE_CACHE_CHANGE,"V", 290,140,20,20, &sb->solverflags,  0,  0, 0, 0, "Use velocities for automagic step sizes");
 
3895
                                uiDefButS(block, NUM, B_BAKE_CACHE_CHANGE, "MinS:", 10,120,150,20, &sb->minloops,  0.00,  30000.0, 10, 0, "Minimal # solver steps/frame ");
 
3896
                                uiDefButS(block, NUM, B_BAKE_CACHE_CHANGE, "MaxS:", 160,120,150,20, &sb->maxloops,  0.00,  30000.0, 10, 0, "Maximal # solver steps/frame ");
 
3897
                                uiBlockEndAlign(block);
 
3898
 
 
3899
                                uiBlockBeginAlign(block);
 
3900
                                uiDefBut(block, LABEL, 0, "Collision helpers",10,100,300,20, NULL, 0.0, 0, 0, 0, "");
 
3901
                                uiDefButS(block, NUM, B_BAKE_CACHE_CHANGE, "Choke:", 10,80,150,20, &sb->choke, 0.00,  100.0, 10, 0, "'Viscosity' inside collision target ");
 
3902
                                uiDefButS(block, NUM, B_BAKE_CACHE_CHANGE, "Fuzzy:", 160,80,150,20, &sb->fuzzyness,  1.00,  100.0, 10, 0, "Fuzzyness while on collision, high values make collsion handling faster but less stable");
 
3903
                                uiBlockEndAlign(block);
 
3904
 
 
3905
                                uiBlockBeginAlign(block);
 
3906
                                uiDefBut(block, LABEL, 0, "Diagnosis",10,60,300,20, NULL, 0.0, 0, 0, 0, "");
 
3907
                                uiDefButBitS(block, TOG, SBSO_MONITOR, B_BAKE_CACHE_CHANGE,"Print Performance to Console", 10,40,300,20, &sb->solverflags,  0,  0, 0, 0, "Turn on SB diagnose console prints");                         
 
3908
                                uiBlockEndAlign(block);
 
3909
                        } 
 
3910
                        else{
 
3911
                                uiBlockEndAlign(block);
 
3912
                                uiBlockBeginAlign(block);
 
3913
                                uiDefButS(block, NUM, B_BAKE_CACHE_CHANGE, "Fuzzy:", 210,100,90,20, &sb->fuzzyness,  1.00,  100.0, 10, 0, "Fuzzyness while on collision, high values make collsion handling faster but less stable");
 
3914
                                uiDefButBitS(block, TOG, SBSO_MONITOR, B_BAKE_CACHE_CHANGE,"M", 290,100,20,20, &sb->solverflags,  0,  0, 0, 0, "Turn on SB diagnose console prints");
 
3915
                                uiBlockEndAlign(block);
 
3916
                                uiDefButS(block, NUM, B_BAKE_CACHE_CHANGE, "Steps:", 10,80,100,20, &sb->minloops,  1.00,  30000.0, 10, 0, "Solver steps/frame ");
 
3917
                                uiDefButS(block, NUM, B_BAKE_CACHE_CHANGE, "Choke:", 210,80,100,20, &sb->choke, 0.00,  100.0, 10, 0, "'Viscosity' inside collision target ");
 
3918
                        }
 
3919
 
 
3920
                        uiBlockEndAlign(block);
 
3921
 
 
3922
                }
 
3923
        }
 
3924
        uiBlockEndAlign(block);
 
3925
}
 
3926
 
 
3927
static void object_softbodies(Object *ob)
 
3928
{
 
3929
        SoftBody *sb=ob->soft;
 
3930
        ParticleSystem *psys=NULL;
 
3931
        uiBlock *block;
 
3932
        uiBut *but;
 
3933
        ModifierData *md;
 
3934
        static int val;
 
3935
        short *softflag=&ob->softflag, psys_cur=0;
 
3936
        int ob_has_hair = psys_ob_has_hair(ob);
 
3937
        static short actsoft= -1;
 
3938
 
 
3939
    if(!_can_softbodies_at_all(ob)) return;
 
3940
        block= uiNewBlock(&curarea->uiblocks, "object_softbodies", UI_EMBOSS, UI_HELV, curarea->win);
 
3941
        uiNewPanelTabbed("Soft Body", "Physics"); 
 
3942
        if(uiNewPanel(curarea, block, "Soft Body", "Physics", 640, 0, 318, 204)==0) return;
 
3943
        uiSetButLock(object_is_libdata(ob), ERROR_LIBDATA_MESSAGE);
 
3944
 
 
3945
        if(ob_has_hair) {
 
3946
                psys= psys_get_current(ob);
 
3947
 
 
3948
                if(psys && actsoft >= 0) {
 
3949
                        actsoft= psys_get_current_num(ob)+1;
 
3950
 
 
3951
                        sb=psys->soft;
 
3952
                        softflag=&psys->softflag;
 
3953
                        psys_cur=1;
 
3954
                }
 
3955
                else
 
3956
                        actsoft= -1; /* -1 = object */
 
3957
        }
 
3958
 
 
3959
        if(psys_cur && psys) {
 
3960
                if(*softflag & OB_SB_ENABLE)
 
3961
                        val = 1;
 
3962
                else
 
3963
                        val = 0;
 
3964
 
 
3965
                but = uiDefButI(block, TOG, REDRAWBUTSOBJECT, "Soft Body",      10,200,130,20, &val, 0, 0, 0, 0, "Sets hair to become soft body");
 
3966
                uiButSetFunc(but, object_softbodies__enable_psys, ob, psys);
 
3967
        }
 
3968
        else {
 
3969
                md = modifiers_findByType(ob, eModifierType_Softbody);
 
3970
                val = (md != NULL);
 
3971
 
 
3972
                if(ob_has_hair)
 
3973
                        but = uiDefButI(block, TOG, REDRAWBUTSOBJECT, "Soft Body",      10,200,130,20, &val, 0, 0, 0, 0, "Sets object to become soft body");
 
3974
                else
 
3975
                        but = uiDefButI(block, TOG, REDRAWBUTSOBJECT, "Soft Body",      10,200,130,20, &val, 0, 0, 0, 0, "Sets object to become soft body");
 
3976
 
 
3977
                uiButSetFunc(but, object_softbodies__enable, ob, NULL);
 
3978
 
 
3979
                if(md) {
 
3980
                        uiBlockBeginAlign(block);
 
3981
                        uiDefIconButBitI(block, TOG, eModifierMode_Render, B_BAKE_CACHE_CHANGE, ICON_SCENE, 145, 200, 20, 20,&md->mode, 0, 0, 1, 0, "Enable soft body during rendering");
 
3982
                        but= uiDefIconButBitI(block, TOG, eModifierMode_Realtime, B_BAKE_CACHE_CHANGE, VICON_VIEW3D, 165, 200, 20, 20,&md->mode, 0, 0, 1, 0, "Enable soft body during interactive display");
 
3983
                        uiBlockEndAlign(block);
 
3984
                }
 
3985
        }
 
3986
 
 
3987
        if(ob_has_hair) {
 
3988
                char *menustr = psys_menu_string(ob,1);
 
3989
 
 
3990
                but=uiDefButS(block, MENU, B_BAKE_REDRAWEDIT, menustr, 210,200,100,20, &actsoft, 14.0, 0.0, 0, 0, "Browse systems");
 
3991
                uiButSetFunc(but, PE_change_act, ob, &actsoft);
 
3992
                
 
3993
                MEM_freeN(menustr);
 
3994
        }
 
3995
 
 
3996
 
 
3997
        
 
3998
        uiDefBut(block, LABEL, 0, "",10,10,300,0, NULL, 0.0, 0, 0, 0, ""); /* tell UI we go to 10,10*/
 
3999
 
 
4000
        if(val) {
 
4001
                int defCount;
 
4002
                char *menustr;
 
4003
                static char str[128];
 
4004
 
 
4005
                if(sb->pointcache->flag & PTCACHE_BAKED)
 
4006
                        uiSetButLock(1, "Simulation frames are baked");
 
4007
 
 
4008
                //if(ob->softflag & OB_SB_BAKESET) {
 
4009
                //      uiBlockBeginAlign(block);
 
4010
                //      uiDefButI(block, NUM, B_DIFF, "Start:",                 10, 170,100,20, &sb->sfra, 1.0, 10000.0, 10, 0, "Start frame for baking");
 
4011
                //      uiDefButI(block, NUM, B_DIFF, "End:",                   110, 170,100,20, &sb->efra, 1.0, 10000.0, 10, 0, "End frame for baking");
 
4012
                //      uiDefButI(block, NUM, B_DIFF, "Interval:",              210, 170,100,20, &sb->interval, 1.0, 10.0, 10, 0, "Interval in frames between baked keys");
 
4013
                //      uiBlockEndAlign(block);
 
4014
 
 
4015
                //      uiDefButS(block, TOG, B_DIFF, "Local",                  10, 145,100,20, &sb->local, 0.0, 0.0, 0, 0, "Use local coordinates for baking");
 
4016
 
 
4017
 
 
4018
                //      uiClearButLock();
 
4019
                //      uiBlockBeginAlign(block);
 
4020
 
 
4021
                //      if(sb->keys) {
 
4022
                //              char str[128];
 
4023
                //              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");
 
4024
                //              sprintf(str, "Stored %d vertices %d keys %.3f MB", sb->totpoint, sb->totkey, ((float)16*sb->totpoint*sb->totkey)/(1024.0*1024.0));
 
4025
                //              uiDefBut(block, LABEL, 0, str, 10, 100,300,20, NULL, 0.0, 0.0, 00, 0, "");
 
4026
                //      }
 
4027
                //      else                            
 
4028
                //              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");
 
4029
                //}
 
4030
                //else {
 
4031
                        /* GENERAL STUFF */
 
4032
                        if (sb->totpoint){
 
4033
                        sprintf(str, "Vertex Mass; Object mass %f [k]",sb->nodemass*sb->totpoint/1000.0f);
 
4034
                        }
 
4035
                        else{
 
4036
                        sprintf(str, "Vertex Mass");
 
4037
                        }
 
4038
                        uiBlockBeginAlign(block);
 
4039
                        uiDefButF(block, NUM, B_BAKE_CACHE_CHANGE, "Friction:", 10, 170,150,20, &sb->mediafrict, 0.0, 50.0, 10, 0, "General media friction for point movements");
 
4040
                        uiDefButF(block, NUM, B_BAKE_CACHE_CHANGE, "Mass:",        160, 170,150,20, &sb->nodemass , 0.001, 50000.0, 10, 0, str);
 
4041
                        uiDefButF(block, NUM, B_BAKE_CACHE_CHANGE, "Grav:",        10,150,150,20, &sb->grav , -10.0, 10.0, 10, 0, "Apply gravitation to point movement");
 
4042
                        uiDefButF(block, NUM, B_BAKE_CACHE_CHANGE, "Speed:",       160,150,150,20, &sb->physics_speed , 0.01, 100.0, 10, 0, "Tweak timing for physics to control frequency and speed");
 
4043
                        uiBlockEndAlign(block);
 
4044
 
 
4045
                        /* GOAL STUFF */
 
4046
                        uiBlockBeginAlign(block);
 
4047
                        uiDefButBitS(block, TOG, OB_SB_GOAL, B_BAKE_CACHE_CHANGE, "Use Goal",   10,120,130,20, softflag, 0, 0, 0, 0, "Define forces for vertices to stick to animated position");
 
4048
                        if (*softflag & OB_SB_GOAL){
 
4049
                                if(ob->type==OB_MESH) {
 
4050
                                        menustr= get_vertexgroup_menustr(ob);
 
4051
                                        defCount=BLI_countlist(&ob->defbase);
 
4052
                                        if(defCount==0) sb->vertgroup= 0;
 
4053
                                        uiDefButS(block, MENU, B_BAKE_CACHE_CHANGE, menustr,    140,120,20,20, &sb->vertgroup, 0, defCount, 0, 0, "Browses available vertex groups");
 
4054
                                        MEM_freeN (menustr);
 
4055
 
 
4056
                                        if(sb->vertgroup) {
 
4057
                                                bDeformGroup *defGroup = BLI_findlink(&ob->defbase, sb->vertgroup-1);
 
4058
                                                if(defGroup)
 
4059
                                                        uiDefBut(block, BUT, B_BAKE_CACHE_CHANGE, defGroup->name,       160,120,130,20, NULL, 0.0, 0.0, 0, 0, "Name of current vertex group");
 
4060
                                                else
 
4061
                                                        uiDefBut(block, BUT, B_BAKE_CACHE_CHANGE, "(no group)", 160,120,130,20, NULL, 0.0, 0.0, 0, 0, "Vertex Group doesn't exist anymore");
 
4062
                                                uiDefIconBut(block, BUT, B_SOFTBODY_DEL_VG, ICON_X, 290,120,20,20, 0, 0, 0, 0, 0, "Disable use of vertex group");
 
4063
                                        }
 
4064
                                        else
 
4065
                                                uiDefButF(block, NUM, B_BAKE_CACHE_CHANGE, "Goal:",     160,120,150,20, &sb->defgoal, 0.0, 1.0, 10, 0, "Default Goal (vertex target position) value, when no Vertex Group used");
 
4066
                                }
 
4067
                                else {
 
4068
                                        uiDefButS(block, TOG, B_BAKE_CACHE_CHANGE, "W",                 140,120,20,20, &sb->vertgroup, 0, 1, 0, 0, "Use control point weight values");
 
4069
                                        uiDefButF(block, NUM, B_BAKE_CACHE_CHANGE, "Goal:",     160,120,150,20, &sb->defgoal, 0.0, 1.0, 10, 0, "Default Goal (vertex target position) value, when no Vertex Group used");
 
4070
                                }
 
4071
 
 
4072
                                uiDefButF(block, NUM, B_BAKE_CACHE_CHANGE, "G Stiff:",  10,100,150,20, &sb->goalspring, 0.0, 0.999, 10, 0, "Goal (vertex target position) spring stiffness");
 
4073
                                uiDefButF(block, NUM, B_BAKE_CACHE_CHANGE, "G Damp:",   160,100,150,20, &sb->goalfrict  , 0.0, 50.0, 10, 0, "Goal (vertex target position) friction");
 
4074
                                uiDefButF(block, NUM, B_BAKE_CACHE_CHANGE, "G Min:",            10,80,150,20, &sb->mingoal, 0.0, 1.0, 10, 0, "Goal minimum, vertex group weights are scaled to match this range");
 
4075
                                uiDefButF(block, NUM, B_BAKE_CACHE_CHANGE, "G Max:",            160,80,150,20, &sb->maxgoal, 0.0, 1.0, 10, 0, "Goal maximum, vertex group weights are scaled to match this range");
 
4076
                        }
 
4077
                        uiBlockEndAlign(block);
 
4078
 
 
4079
                        /* EDGE SPRING STUFF */
 
4080
                        if(ob->type!=OB_SURF) {
 
4081
                                uiBlockBeginAlign(block);
 
4082
                                uiDefButBitS(block, TOG, OB_SB_EDGES, B_BAKE_CACHE_CHANGE, "Use Edges",         10,50,90,20, softflag, 0, 0, 0, 0, "Use Edges as springs");
 
4083
                        if (*softflag & OB_SB_EDGES){
 
4084
                                uiDefButBitS(block, TOG, OB_SB_QUADS, B_BAKE_CACHE_CHANGE, "Stiff Quads",               110,50,90,20, softflag, 0, 0, 0, 0, "Adds diagonal springs on 4-gons");
 
4085
                                uiDefButBitS(block, TOG, OB_SB_EDGECOLL, B_BAKE_CACHE_CHANGE, "CEdge",          220,50,45,20, softflag, 0, 0, 0, 0, "Edge collide too"); 
 
4086
                                uiDefButBitS(block, TOG, OB_SB_FACECOLL, B_BAKE_CACHE_CHANGE, "CFace",          265,50,45,20, softflag, 0, 0, 0, 0, "Faces collide too SLOOOOOW warning "); 
 
4087
                                uiDefButF(block, NUM, B_BAKE_CACHE_CHANGE, "Pull:",     10,30,75,20, &sb->inspring, 0.0,  0.999, 10, 0, "Edge spring stiffness when longer than rest length");
 
4088
                                uiDefButF(block, NUM, B_BAKE_CACHE_CHANGE, "Push:",     85,30,75,20, &sb->inpush, 0.0,  0.999, 10, 0, "Edge spring stiffness when shorter than rest length");
 
4089
                                uiDefButF(block, NUM, B_BAKE_CACHE_CHANGE, "Damp:",     160,30,70,20, &sb->infrict, 0.0,  50.0, 10, 0, "Edge spring friction");
 
4090
                            uiDefButS(block, NUM, B_BAKE_CACHE_CHANGE, "SL:",250 ,30,60,20, &sb->springpreload, 0.0,  200.0, 10, 0, "Alter spring lenght to shrink/blow up (unit %) 0 to disable ");
 
4091
                                
 
4092
                                uiDefButBitS(block, TOG,OB_SB_AERO_ANGLE,B_BAKE_CACHE_CHANGE, "N",10,10,20,20, softflag, 0, 0, 0, 0, "New aero(uses angle and length)");
 
4093
                                uiDefButS(block, NUM, B_BAKE_CACHE_CHANGE, "Aero:",     30,10,60,20, &sb->aeroedge,  0.00,  30000.0, 10, 0, "Make edges 'sail'");
 
4094
                            uiDefButS(block, NUM, B_BAKE_CACHE_CHANGE, "Plas:", 90,10,60,20, &sb->plastic, 0.0,  100.0, 10, 0, "Permanent deform");
 
4095
                                if(ob->type==OB_MESH) {
 
4096
                                        uiDefButF(block, NUM, B_BAKE_CACHE_CHANGE, "Be:", 150,10,80,20, &sb->secondspring, 0.0,  10.0, 10, 0, "Bending Stiffness");
 
4097
                                        if (*softflag & OB_SB_QUADS){ 
 
4098
                                        uiDefButF(block, NUM, B_BAKE_CACHE_CHANGE, "Sh:", 230,10,80,20, &sb->shearstiff, 0.0,  1.0, 10, 0, "Shear Stiffness");
 
4099
                                        }
 
4100
                                }
 
4101
                                else sb->secondspring = 0;
 
4102
                                uiDefBut(block, LABEL, 0, "",10,10,1,0, NULL, 0.0, 0, 0, 0, ""); /* tell UI we go to 10,10*/
 
4103
                        }
 
4104
                                uiBlockEndAlign(block);
 
4105
                        }
 
4106
                //}
 
4107
        }
 
4108
        uiBlockEndAlign(block);
 
4109
}
 
4110
 
 
4111
static void object_panel_particle_bake(Object *ob)
 
4112
{
 
4113
        uiBlock *block;
 
4114
        ParticleSystem *psys= psys_get_current(ob);
 
4115
        static PTCacheID staticpid;
 
4116
        int libdata;
 
4117
 
 
4118
        if (psys==NULL || psys->part==NULL) return;
 
4119
        if (ELEM(psys->part->type, PART_HAIR, PART_FLUID)) return;
 
4120
        if (psys->part->phystype == PART_PHYS_KEYED) return;
 
4121
        
 
4122
        block= uiNewBlock(&curarea->uiblocks, "object_panel_particle_bake", UI_EMBOSS, UI_HELV, curarea->win);
 
4123
        uiNewPanelTabbed("Particle System", "Particle");
 
4124
        if(uiNewPanel(curarea, block, "Bake", "Particle", 320, 0, 318, 204)==0) return;
 
4125
        
 
4126
        libdata= object_is_libdata(ob);
 
4127
        uiSetButLock(libdata, ERROR_LIBDATA_MESSAGE);
 
4128
        
 
4129
        BKE_ptcache_id_from_particles(&staticpid, ob, psys);
 
4130
        object_physics_bake_buttons(block, &staticpid, 10, libdata);
 
4131
}
 
4132
 
 
4133
 /* Panels for new particles*/
 
4134
static void object_panel_particle_children(Object *ob)
 
4135
{
 
4136
        uiBlock *block;
 
4137
        ParticleSystem *psys = psys_get_current(ob);
 
4138
        ParticleSettings *part;
 
4139
        short butx=0, buty=160, butw=150, buth=20;
 
4140
        static short kink_ui=0;
 
4141
 
 
4142
        if (psys==NULL) return;
 
4143
        part=psys->part;
 
4144
        if(part==NULL) return;
 
4145
                
 
4146
        block= uiNewBlock(&curarea->uiblocks, "object_panel_particle_child", UI_EMBOSS, UI_HELV, curarea->win);
 
4147
        uiNewPanelTabbed("Extras", "Particle");
 
4148
        if(uiNewPanel(curarea, block, "Children", "Particle", 1300, 0, 318, 204)==0) return;
 
4149
 
 
4150
        uiSetButLock((part->id.lib != NULL), ERROR_LIBDATA_MESSAGE);
 
4151
 
 
4152
        if(part->type == PART_FLUID) {
 
4153
                uiDefBut(block, LABEL, 0, "No settings for fluid particles",                                    butx,(buty-=2*buth),2*butw,buth, NULL, 0.0, 0, 0, 0, "");
 
4154
                return;
 
4155
        }
 
4156
 
 
4157
        uiDefButS(block, MENU, B_PART_ALLOC_CHILD, "Children from:%t|Faces%x2|Particles%x1|None%x0", butx,buty,butw,buth, &part->childtype, 14.0, 0.0, 0, 0, "Create child particles");
 
4158
 
 
4159
        if(part->childtype==0) return;
 
4160
 
 
4161
        if(part->childtype==PART_CHILD_FACES && !(part->phystype==PART_PHYS_KEYED || part->type==PART_HAIR)) {
 
4162
                uiDefBut(block, LABEL, 0, "Hair or keyed",      butx,(buty-=2*buth),butw,buth, NULL, 0.0, 0, 0, 0, "");
 
4163
                uiDefBut(block, LABEL, 0, "particles needed!",  butx,(buty-=2*buth),butw,buth, NULL, 0.0, 0, 0, 0, "");
 
4164
                return;
 
4165
        }
 
4166
 
 
4167
        uiBlockBeginAlign(block);
 
4168
 
 
4169
        buty -= buth/2;
 
4170
        
 
4171
        uiDefButI(block, NUM, B_PART_ALLOC_CHILD, "Amount:", butx,(buty-=buth),butw,buth, &part->child_nbr, 0.0, MAX_PART_CHILDREN, 0, 0, "Amount of children/parent");
 
4172
        uiDefButI(block, NUM, B_DIFF, "Render Amount:", butx,(buty-=buth),butw,buth, &part->ren_child_nbr, 0.0, MAX_PART_CHILDREN, 0, 0, "Amount of children/parent for rendering");
 
4173
 
 
4174
        if(part->from!=PART_FROM_PARTICLE && part->childtype==PART_CHILD_FACES) {
 
4175
                uiDefButF(block, NUMSLI, B_PART_DISTR_CHILD, "VParents:",               butx,(buty-=buth),butw,buth, &part->parents, 0.0, 1.0, 1, 3, "Relative amount of virtual parents");
 
4176
                }
 
4177
        else {
 
4178
                uiDefButF(block, NUM, B_PART_RECALC_CHILD, "Rad:",              butx,(buty-=buth),butw,buth, &part->childrad, 0.0, 10.0, 1, 3, "Radius of children around parent");
 
4179
                uiDefButF(block, NUMSLI, B_PART_RECALC_CHILD, "Round:",         butx,(buty-=buth),butw,buth, &part->childflat, 0.0, 1.0, 1, 3, "Roundness of children around parent");
 
4180
        }
 
4181
        uiBlockEndAlign(block);
 
4182
 
 
4183
        buty -= buth/2;
 
4184
 
 
4185
        /* clump */
 
4186
        uiBlockBeginAlign(block);
 
4187
        uiDefButF(block, NUMSLI, B_PART_RECALC_CHILD, "Clump:",         butx,(buty-=buth),butw,buth, &part->clumpfac, -1.0, 1.0, 1, 3, "Amount of clumpimg");
 
4188
        uiDefButF(block, NUMSLI, B_PART_RECALC_CHILD, "Shape:",         butx,(buty-=buth),butw,buth, &part->clumppow, -0.999, 0.999, 1, 3, "Shape of clumpimg");
 
4189
        uiBlockEndAlign(block);
 
4190
 
 
4191
        buty -= buth/2;
 
4192
 
 
4193
        uiBlockBeginAlign(block);
 
4194
        if(part->draw_as != PART_DRAW_PATH) {
 
4195
                uiDefButF(block, NUM, B_PART_REDRAW, "Size:",           butx,(buty-=buth),butw/2,buth, &part->childsize, 0.01, 100, 10, 1, "A multiplier for the child particle size");
 
4196
                uiDefButF(block, NUM, B_PART_REDRAW, "Rand:",           butx+butw/2,buty,butw/2,buth, &part->childrandsize, 0.0, 1.0, 10, 1, "Random variation to the size of the child particles");
 
4197
        }
 
4198
        if(part->childtype == PART_CHILD_FACES) {
 
4199
                /* only works if children could be emitted from volume, but that option isn't available now */
 
4200
                /*uiDefButF(block, NUM, B_PART_REDRAW, "Spread:",butx,(buty-=buth),butw/2,buth, &part->childspread, -1.0, 1.0, 10, 1, "Spread children from the faces");*/
 
4201
                uiDefButBitI(block, TOG, PART_CHILD_SEAMS, B_PART_DISTR_CHILD, "Use Seams",     butx,(buty-=buth),butw,buth, &part->flag, 0, 0, 0, 0, "Use seams to determine parents");
 
4202
        }
 
4203
        uiBlockEndAlign(block);
 
4204
 
 
4205
        butx=160;
 
4206
        buty=180;
 
4207
 
 
4208
        if(part->phystype==PART_PHYS_KEYED || part->type==PART_HAIR)
 
4209
                uiDefButBitS(block, TOG, 1, B_PART_REDRAW, "Kink/Branch",        butx,(buty-=buth),butw,buth, &kink_ui, 0, 0, 0, 0, "Show kink and branch options");
 
4210
        else
 
4211
                buty-=buth;
 
4212
 
 
4213
        if(kink_ui || !(part->phystype==PART_PHYS_KEYED || part->type==PART_HAIR)) {
 
4214
                buty -= buth/2;
 
4215
 
 
4216
                /* kink */
 
4217
                uiBlockBeginAlign(block);
 
4218
                if(part->kink) {
 
4219
                        uiDefButS(block, MENU, B_PART_RECALC_CHILD, "Kink:%t|Braid%x4|Wave%x3|Radial%x2|Curl%x1|Nothing%x0", butx,(buty-=buth),butw/2,buth, &part->kink, 14.0, 0.0, 0, 0, "Type of periodic offset on the path");
 
4220
                        uiDefButS(block, MENU, B_PART_RECALC_CHILD, "Axis %t|Z %x2|Y %x1|X %x0", butx+butw/2,buty,butw/2,buth, &part->kink_axis, 14.0, 0.0, 0, 0, "Which axis to use for offset");
 
4221
                        uiDefButF(block, NUM, B_PART_RECALC_CHILD, "Freq:",                     butx,(buty-=buth),butw,buth, &part->kink_freq, 0.0, 10.0, 1, 3, "The frequency of the offset (1/total length)");
 
4222
                        uiDefButF(block, NUMSLI, B_PART_RECALC_CHILD, "Shape:",         butx,(buty-=buth),butw,buth, &part->kink_shape, -0.999, 0.999, 1, 3, "Adjust the offset to the beginning/end");
 
4223
                        uiDefButF(block, NUM, B_PART_RECALC_CHILD, "Amplitude:",        butx,(buty-=buth),butw,buth, &part->kink_amp, 0.0, 10.0, 1, 3, "The amplitude of the offset");
 
4224
                }
 
4225
                else {
 
4226
                        uiDefButS(block, MENU, B_PART_RECALC_CHILD, "Kink:%t|Braid%x4|Wave%x3|Radial%x2|Curl%x1|Nothing%x0", butx,(buty-=buth),butw,buth, &part->kink, 14.0, 0.0, 0, 0, "Type of periodic offset on the path");
 
4227
                        buty-=3*buth;
 
4228
                }
 
4229
                uiBlockEndAlign(block);
 
4230
 
 
4231
                if(part->childtype==PART_CHILD_PARTICLES && (part->phystype==PART_PHYS_KEYED || part->type==PART_HAIR)) {
 
4232
                        if(part->flag & PART_BRANCHING) {
 
4233
                                uiDefButBitI(block, TOG, PART_BRANCHING, B_PART_RECALC_CHILD, "Branching",      butx,(buty-=2*buth),butw,buth, &part->flag, 0, 0, 0, 0, "Branch child paths from eachother");
 
4234
                                uiDefButBitI(block, TOG, PART_ANIM_BRANCHING, B_PART_RECALC_CHILD, "Animated",  butx,(buty-=buth),butw/2,buth, &part->flag, 0, 0, 0, 0, "Animate branching");
 
4235
                                uiDefButBitI(block, TOG, PART_SYMM_BRANCHING, B_PART_RECALC_CHILD, "Symmetric", butx+butw/2,buty,butw/2,buth, &part->flag, 0, 0, 0, 0, "Start and end points are the same");
 
4236
                                uiDefButF(block, NUM, B_PART_RECALC_CHILD, "Threshold:",        butx,(buty-=buth),butw,buth, &part->branch_thres, 0.0, 1.0, 1, 3, "Threshold of branching");
 
4237
                        }
 
4238
                        else
 
4239
                                uiDefButBitI(block, TOG, PART_BRANCHING, B_PART_RECALC_CHILD, "Branching",      butx,(buty-=2*buth),butw,buth, &part->flag, 0, 0, 0, 0, "Branch child paths from eachother");
 
4240
                }
 
4241
        }
 
4242
        else {
 
4243
        /* rough */
 
4244
                buty -= buth/2;
 
4245
 
 
4246
                uiBlockBeginAlign(block);
 
4247
                uiDefButF(block, NUMSLI, B_PART_RECALC_CHILD, "Rough1:",        butx,(buty-=buth),butw,buth, &part->rough1, 0.0, 10.0, 1, 3, "Amount of location dependant rough");
 
4248
                uiDefButF(block, NUM, B_PART_RECALC_CHILD, "Size1:",    butx,(buty-=buth),butw,buth, &part->rough1_size, 0.01, 10.0, 1, 3, "Size of location dependant rough");
 
4249
                uiBlockEndAlign(block);
 
4250
                buty -= buth/2;
 
4251
                uiBlockBeginAlign(block);
 
4252
                uiDefButF(block, NUMSLI, B_PART_RECALC_CHILD, "Rough2:",        butx,(buty-=buth),butw,buth, &part->rough2, 0.0, 10.0, 1, 3, "Amount of random rough");
 
4253
                uiDefButF(block, NUM, B_PART_RECALC_CHILD, "Size2:",    butx,(buty-=buth),butw,buth, &part->rough2_size, 0.01, 10.0, 1, 3, "Size of random rough");
 
4254
                uiDefButF(block, NUMSLI, B_PART_RECALC_CHILD, "Thresh:",        butx,(buty-=buth),butw,buth, &part->rough2_thres, 0.00, 1.0, 1, 3, "Amount of particles left untouched by random rough");
 
4255
                uiBlockEndAlign(block);
 
4256
                buty -= buth/2;
 
4257
                uiBlockBeginAlign(block);
 
4258
                uiDefButF(block, NUMSLI, B_PART_RECALC_CHILD, "RoughE:",        butx,(buty-=buth),butw,buth, &part->rough_end, 0.0, 10.0, 1, 3, "Amount of end point rough");
 
4259
                uiDefButF(block, NUMSLI, B_PART_RECALC_CHILD, "Shape:", butx,(buty-=buth),butw,buth, &part->rough_end_shape, 0.0, 10.0, 1, 3, "Shape of end point rough");
 
4260
                uiBlockEndAlign(block);
 
4261
        }
 
4262
}
 
4263
static void particle_set_vg(void *ob_v, void *vgnum_v)
 
4264
{
 
4265
        Object *ob= ob_v;
 
4266
        ParticleSystem *psys=psys_get_current(ob);
 
4267
        short vgnum = *((short *)vgnum_v);
 
4268
 
 
4269
        if(vgnum==PSYS_VG_DENSITY)
 
4270
                psys->recalc|=PSYS_DISTR;
 
4271
        else if(vgnum!=PSYS_VG_SIZE)
 
4272
                psys->recalc|=PSYS_INIT;
 
4273
 
 
4274
        DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA);
 
4275
        allqueue(REDRAWVIEW3D, 0);
 
4276
}
 
4277
static void particle_del_vg(void *ob_v, void *vgnum_v)
 
4278
{
 
4279
        Object *ob= ob_v;
 
4280
        ParticleSystem *psys=psys_get_current(ob);
 
4281
        short vgnum = *((short *)vgnum_v);
 
4282
 
 
4283
        if(vgnum==PSYS_VG_DENSITY) {
 
4284
                psys->recalc|=PSYS_DISTR;
 
4285
        }
 
4286
 
 
4287
        psys->vgroup[vgnum]=0;
 
4288
 
 
4289
        DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA);
 
4290
        allqueue(REDRAWVIEW3D, 0);
 
4291
}
 
4292
static void object_panel_particle_extra(Object *ob)
 
4293
{
 
4294
        uiBlock *block;
 
4295
        uiBut *but;
 
4296
        ParticleSystem *psys=psys_get_current(ob);
 
4297
        ParticleSettings *part;
 
4298
        short butx=0, buty=160, butw=150, buth=20;
 
4299
        static short vgnum=0;
 
4300
 
 
4301
        if (psys==NULL) return;
 
4302
        part=psys->part;
 
4303
        if(part==NULL) return;
 
4304
                
 
4305
        block= uiNewBlock(&curarea->uiblocks, "object_panel_particle_extra", UI_EMBOSS, UI_HELV, curarea->win);
 
4306
        if(uiNewPanel(curarea, block, "Extras", "Particle", 980, 0, 318, 204)==0) return;
 
4307
 
 
4308
        uiSetButLock((part->id.lib != NULL), ERROR_LIBDATA_MESSAGE);
 
4309
 
 
4310
        if(part->type == PART_FLUID) {
 
4311
                uiDefBut(block, LABEL, 0, "No settings for fluid particles",                                    butx,(buty-=2*buth),2*butw,buth, NULL, 0.0, 0, 0, 0, "");
 
4312
                return;
 
4313
        }
 
4314
 
 
4315
        uiDefBut(block, LABEL, 0, "Effectors:", butx,buty,butw,buth, NULL, 0.0, 0, 0, 0, "");
 
4316
        uiBlockBeginAlign(block);
 
4317
        uiDefIDPoinBut(block, test_grouppoin_but, ID_GR, B_PART_RECALC, "GR:", butx, (buty-=buth), butw/2, buth, &part->eff_group, "Limit effectors to this Group"); 
 
4318
        uiDefButBitI(block, TOG, PART_SIZE_DEFL, B_PART_RECALC, "Size Deflect", butx+butw/2,buty,butw/2,buth, &part->flag, 0, 0, 0, 0, "Use particle's size in deflection");
 
4319
        uiDefButBitI(block, TOG, PART_DIE_ON_COL, B_PART_RECALC, "Die on hit",butx,(buty-=buth),butw/2,buth, &part->flag, 0, 0, 0, 0, "Particles die when they collide with a deflector object");
 
4320
        uiDefButBitI(block, TOG, PART_STICKY, B_PART_RECALC, "Sticky",  butx+butw/2,buty,butw/2,buth, &part->flag, 0, 0, 0, 0, "Particles stick to collided objects if they die in the collision");
 
4321
        uiBlockEndAlign(block);
 
4322
 
 
4323
        uiDefBut(block, LABEL, 0, "Time:",      butx,(buty-=buth),butw/3,buth, NULL, 0.0, 0, 0, 0, "");
 
4324
        uiBlockBeginAlign(block);
 
4325
        uiDefButBitI(block, TOG, PART_GLOB_TIME, B_PART_RECALC, "Global",        butx,(buty-=buth),butw/2,buth, &part->flag, 0, 0, 0, 0, "Set all ipos that work on particles to be calculated in global/object time");
 
4326
        uiDefButBitI(block, TOG, PART_ABS_TIME, B_PART_RECALC, "Absolute",       butx+butw/2,buty,butw/2,buth, &part->flag, 0, 0, 0, 0, "Set all ipos that work on particles to be calculated in absolute/relative time");
 
4327
 
 
4328
        //if(part->flag & PART_LOOP){
 
4329
        //      uiDefButBitI(block, TOG, PART_LOOP, B_PART_RECALC, "Loop",       butx,(buty-=buth),butw/2,buth, &part->flag, 0, 0, 0, 0, "Loop particle lives");
 
4330
        //      uiDefButBitI(block, TOG, PART_LOOP_INSTANT, B_PART_RECALC, "Instantly",  butx+butw/2,buty,butw/2,buth, &part->flag, 0, 0, 0, 0, "Loop particle life at time of death");
 
4331
        //}
 
4332
        //else
 
4333
                uiDefButBitI(block, TOG, PART_LOOP, B_PART_RECALC, "Loop",       butx,(buty-=buth),butw,buth, &part->flag, 0, 0, 0, 0, "Loop particle lives");
 
4334
 
 
4335
        uiDefButF(block, NUM, B_PART_RECALC, "Tweak:",  butx,(buty-=buth),butw,buth, &part->timetweak, 0.0, 10.0, 1, 0, "A multiplier for physics timestep (1.0 means one frame = 1/25 seconds)");
 
4336
        uiBlockEndAlign(block);
 
4337
 
 
4338
        if(ob->type==OB_MESH) {
 
4339
                char *menustr= get_vertexgroup_menustr(ob);
 
4340
                int defCount=BLI_countlist(&ob->defbase);
 
4341
                if(defCount==0) psys->vgroup[vgnum]= 0;
 
4342
 
 
4343
                uiDefBut(block, LABEL, 0, "Vertex group:",      butx,(buty-=2*buth),butw,buth, NULL, 0.0, 0, 0, 0, "");
 
4344
 
 
4345
                uiBlockBeginAlign(block);
 
4346
                
 
4347
                uiDefButS(block, MENU, B_PART_REDRAW, "Attribute%t|Effector%x11|TanRot%x10|TanVel%x9|Size%x8|RoughE%x7|Rough2%x6|Rough1%x5|Kink%x4|Clump%x3|Length%x2|Velocity%x1|Density%x0", butx,(buty-=buth),butw-40,buth, &vgnum, 14.0, 0.0, 0, 0, "Attribute effected by vertex group");
 
4348
                but=uiDefButBitS(block, TOG, (1<<vgnum), B_PART_RECALC, "Neg",  butx+butw-40,buty,40,buth, &psys->vg_neg, 0, 0, 0, 0, "Negate the effect of the vertex group");
 
4349
                uiButSetFunc(but, particle_set_vg, (void *)ob, (void *)(&vgnum));
 
4350
                
 
4351
                butx+=butw;
 
4352
 
 
4353
                but= uiDefButS(block, MENU, B_PART_RECALC, menustr,     butx,buty,buth,buth, psys->vgroup+vgnum, 0, defCount, 0, 0, "Browses available vertex groups");
 
4354
                uiButSetFunc(but, particle_set_vg, (void *)ob, (void *)(&vgnum));
 
4355
                MEM_freeN (menustr);
 
4356
 
 
4357
                if(psys->vgroup[vgnum]) {
 
4358
                        bDeformGroup *defGroup = BLI_findlink(&ob->defbase, psys->vgroup[vgnum]-1);
 
4359
                        if(defGroup)
 
4360
                                uiDefBut(block, BUT, B_PART_REDRAW, defGroup->name,     butx+buth,buty,butw-2*buth,buth, NULL, 0.0, 0.0, 0, 0, "Name of current vertex group");
 
4361
                        else{
 
4362
                                uiDefBut(block, BUT, B_PART_REDRAW, "(no group)",       butx+buth,buty,butw-2*buth,buth, NULL, 0.0, 0.0, 0, 0, "Vertex Group doesn't exist anymore");
 
4363
                        }
 
4364
                        but=uiDefIconBut(block, BUT, B_PART_RECALC, ICON_X, butx+butw-buth,buty,buth,buth, 0, 0, 0, 0, 0, "Disable use of vertex group");
 
4365
                        uiButSetFunc(but, particle_del_vg, (void *)ob, (void *)(&vgnum));
 
4366
                }
 
4367
 
 
4368
                uiBlockEndAlign(block);
 
4369
        }
 
4370
        
 
4371
        buty=butx=160;
 
4372
 
 
4373
        uiDefButI(block, NUM, B_PART_DISTR, "Seed:",                            butx,(buty-=buth),butw,buth, &psys->seed, 0.0, 255.0, 1, 0, "Set an offset in the random table");
 
4374
        if(part->type == PART_HAIR) {
 
4375
                uiBlockBeginAlign(block);
 
4376
                uiDefButF(block, NUM, B_PART_RECALC, "Stiff:",  butx,(buty-=buth),(butw*3)/5,buth, &part->eff_hair, 0.0, 1.0, 0, 0, "Hair stiffness for effectors");
 
4377
                uiDefButBitI(block, TOG, PART_CHILD_EFFECT, B_PART_RECALC, "Children", butx+(butw*3)/5,buty,(butw*2)/5,buth, &part->flag, 0, 0, 0, 0, "Apply effectors to children");
 
4378
                uiBlockEndAlign(block);
 
4379
        }
 
4380
        else if(part->phystype == PART_PHYS_NEWTON)
 
4381
                uiDefButBitI(block, TOG, PART_SELF_EFFECT, B_PART_RECALC, "Self Effect",         butx,(buty-=buth),butw,buth, &part->flag, 0, 0, 0, 0, "Particle effectors effect themselves");
 
4382
        else
 
4383
                buty-=buth;
 
4384
 
 
4385
        /* size changes must create a recalc event always so that sizes are updated properly */
 
4386
        uiDefButF(block, NUM, B_PART_RECALC, "Size:",   butx,(buty-=buth),butw,buth, &part->size, 0.01, 100, 10, 1, "The size of the particles");
 
4387
        uiDefButF(block, NUM, B_PART_RECALC, "Rand:",   butx,(buty-=buth),butw,buth, &part->randsize, 0.0, 1.0, 10, 1, "Give the particle size a random variation");
 
4388
 
 
4389
        uiDefButBitI(block, TOG, PART_SIZEMASS, B_PART_RECALC, "Mass from size",         butx,(buty-=buth),butw,buth, &part->flag, 0, 0, 0, 0, "Multiply mass with particle size");
 
4390
        uiDefButF(block, NUM, B_PART_RECALC, "Mass:",   butx,(buty-=buth),butw,buth, &part->mass, 0.01, 100, 10, 1, "Specify the mass of the particles");
 
4391
}
 
4392
/* copy from buttons_shading.c */
 
4393
static void autocomplete_uv(char *str, void *arg_v)
 
4394
{
 
4395
        Mesh *me;
 
4396
        CustomDataLayer *layer;
 
4397
        AutoComplete *autocpl;
 
4398
        int a;
 
4399
 
 
4400
        if(str[0]==0)
 
4401
                return;
 
4402
 
 
4403
        autocpl= autocomplete_begin(str, 32);
 
4404
                
 
4405
        /* search if str matches the beginning of name */
 
4406
        for(me= G.main->mesh.first; me; me=me->id.next)
 
4407
                for(a=0, layer= me->fdata.layers; a<me->fdata.totlayer; a++, layer++)
 
4408
                        if(layer->type == CD_MTFACE)
 
4409
                                autocomplete_do_name(autocpl, layer->name);
 
4410
        
 
4411
        autocomplete_end(autocpl, str);
 
4412
}
 
4413
static void object_panel_particle_visual(Object *ob)
 
4414
{
 
4415
        uiBlock *block;
 
4416
        uiBut *but;
 
4417
        ParticleSystem *psys=psys_get_current(ob);
 
4418
        ParticleSettings *part;
 
4419
        short butx=0, buty=160, butw=150, buth=20;
 
4420
        static short bbuvnum=0;
 
4421
 
 
4422
        if (psys==NULL) return;
 
4423
        part=psys->part;
 
4424
        if(part==NULL) return;
 
4425
                
 
4426
        block= uiNewBlock(&curarea->uiblocks, "object_panel_particle_visual", UI_EMBOSS, UI_HELV, curarea->win);
 
4427
        if(uiNewPanel(curarea, block, "Visualization", "Particle", 640, 0, 318, 204)==0) return;
 
4428
 
 
4429
        uiDefButS(block, MENU, B_PART_RECALC, "Billboard %x9|Group %x8|Object %x7|Path %x6|Line %x5|Axis %x4|Cross %x3|Circle %x2|Point %x1|None %x0", butx,buty,butw,buth, &part->draw_as, 14.0, 0.0, 0, 0, "How particles are visualized");
 
4430
 
 
4431
        if(part->draw_as==PART_DRAW_NOT) {
 
4432
                uiDefButBitS(block, TOG, PART_DRAW_EMITTER, B_PART_REDRAW, "Render emitter",    butx,(buty-=2*buth),butw,buth, &part->draw, 0, 0, 0, 0, "Render emitter object");
 
4433
                return;
 
4434
        }
 
4435
 
 
4436
        uiDefBut(block, LABEL, 0, "Draw:",      butx,(buty-=buth),butw,buth, NULL, 0.0, 0, 0, 0, "");
 
4437
        uiBlockBeginAlign(block);
 
4438
        uiDefButBitS(block, TOG, PART_DRAW_VEL, B_PART_REDRAW, "Vel",   butx,(buty-=buth),butw/3,buth, &part->draw, 0, 0, 0, 0, "Show particle velocity");
 
4439
        uiDefButBitS(block, TOG, PART_DRAW_SIZE, B_PART_REDRAW, "Size", butx+butw/3,buty,butw/3,buth, &part->draw, 0, 0, 0, 0, "Show particle size");
 
4440
        uiDefButBitS(block, TOG, PART_DRAW_NUM, B_PART_REDRAW, "Num",   butx+2*butw/3,buty,butw/3,buth, &part->draw, 0, 0, 0, 0, "Show particle number");
 
4441
        uiDefButS(block, NUM, B_PART_REDRAW, "Draw Size:", butx,(buty-=buth),butw,buth, &part->draw_size, 0.0, 10.0, 0, 0, "Size of particles on viewport in pixels (0=default)");
 
4442
        uiDefButS(block, NUM, B_PART_RECALC_CHILD, "Disp:",             butx,(buty-=buth),butw,buth, &part->disp, 0.0, 100.0, 10, 0, "Percentage of particles to display in 3d view");
 
4443
        uiBlockEndAlign(block);
 
4444
 
 
4445
        uiDefBut(block, LABEL, 0, "Render:",    butx,(buty-=buth),butw,buth, NULL, 0.0, 0, 0, 0, "");
 
4446
        uiBlockBeginAlign(block);
 
4447
        uiDefButS(block, NUM, B_PART_DISTR, "Material:",                                        butx,(buty-=buth),butw-30,buth, &part->omat, 1.0, 16.0, 0, 0, "Specify material used for the particles");
 
4448
        uiDefButBitS(block, TOG, PART_DRAW_MAT_COL, B_PART_RECALC, "Col",       butx+butw-30,buty,30,buth, &part->draw, 0, 0, 0, 0, "Draw particles using material's diffuse color");
 
4449
        uiDefButBitS(block, TOG, PART_DRAW_EMITTER, B_PART_REDRAW, "Emitter",   butx,(buty-=buth),butw/2,buth, &part->draw, 0, 0, 0, 0, "Render emitter Object also");
 
4450
        uiDefButBitS(block, TOG, PART_DRAW_PARENT, B_PART_REDRAW, "Parents",                            butx+butw/2,buty,butw/2,buth, &part->draw, 0, 0, 0, 0, "Render parent particles");
 
4451
        uiDefButBitI(block, TOG, PART_UNBORN, B_PART_REDRAW, "Unborn",                  butx,(buty-=buth),butw/2,buth, &part->flag, 0, 0, 0, 0, "Show particles before they are emitted");
 
4452
        uiDefButBitI(block, TOG, PART_DIED, B_PART_REDRAW, "Died",                              butx+butw/2,buty,butw/2,buth, &part->flag, 0, 0, 0, 0, "Show particles after they have died");
 
4453
 
 
4454
        uiBlockEndAlign(block);
 
4455
 
 
4456
        butx=160;
 
4457
        buty=160-buth;
 
4458
 
 
4459
        uiBlockBeginAlign(block);
 
4460
 
 
4461
        switch(part->draw_as) {
 
4462
                case PART_DRAW_OB:
 
4463
                        uiDefIDPoinBut(block, test_obpoin_but, ID_OB, B_PART_REDRAW_DEPS, "OB:",        butx,(buty-=buth),butw,buth, &part->dup_ob, "Show this Object in place of particles"); 
 
4464
                        break;
 
4465
                case PART_DRAW_GR:
 
4466
                        uiDefIDPoinBut(block, test_grouppoin_but, ID_GR, B_PART_REDRAW_DEPS, "GR:",     butx,(buty-=buth),butw,buth, &part->dup_group, "Show Objects in this Group in place of particles"); 
 
4467
                        uiDefButBitS(block, TOG, PART_DRAW_WHOLE_GR, B_PART_REDRAW, "Dupli Group",      butx,(buty-=buth),butw,buth, &part->draw, 0, 0, 0, 0, "Use whole group at once");
 
4468
                        if((part->draw & PART_DRAW_WHOLE_GR)==0)
 
4469
                                uiDefButBitS(block, TOG, PART_DRAW_RAND_GR, B_PART_REDRAW, "Pick Random",       butx,(buty-=buth),butw,buth, &part->draw, 0, 0, 0, 0, "Pick objects from group randomly");
 
4470
                        break;
 
4471
                case PART_DRAW_BB:
 
4472
                        uiDefButBitS(block, TOG, PART_DRAW_BB_LOCK, B_PART_REDRAW, "Lock",      butx,(buty+=buth),butw/2,buth, &part->draw, 0, 0, 0, 0, "Lock the billboards align axis");
 
4473
                        uiDefButS(block, MENU, B_PART_REDRAW, "Align to%t|Velocity%x4|View%x3|Z%x2|Y%x1|X%x0", butx+butw/2,buty,butw/2,buth, &part->bb_align, 14.0, 0.0, 0, 0, "In respect to what the billboards are aligned");
 
4474
                        uiDefButF(block, NUM, B_PART_REDRAW, "Tilt:", butx,(buty-=buth),butw/2,buth, &part->bb_tilt, -1.0, 1.0, 0, 0, "Tilt of the billboards");
 
4475
                        uiDefButF(block, NUM, B_PART_REDRAW, "Rand:", butx+butw/2,buty,butw/2,buth, &part->bb_rand_tilt, 0.0, 1.0, 0, 0, "Random tilt of the billboards");
 
4476
                        uiDefButS(block, NUM, B_PART_REDRAW, "UV Split:", butx,(buty-=buth),butw,buth, &part->bb_uv_split, 1.0, 10.0, 0, 0, "Amount of rows/columns to split uv coordinates for billboards");
 
4477
                        uiDefButS(block, MENU, B_PART_REDRAW, "Animate%t|Angle%x2|Time%x1|None%x0", butx,(buty-=buth),butw/2,buth, &part->bb_anim, 14.0, 0.0, 0, 0, "How to animate billboard textures");
 
4478
                        uiDefButS(block, MENU, B_PART_REDRAW, "Offset%t|Random%x2|Linear%x1|None%x0", butx+butw/2,buty,butw/2,buth, &part->bb_split_offset, 14.0, 0.0, 0, 0, "How to offset billboard textures");
 
4479
                        uiDefButF(block, NUM, B_PART_REDRAW, "OffsetX:", butx,(buty-=buth),butw,buth, part->bb_offset, -1.0, 1.0, 0, 0, "Offset billboards horizontally");
 
4480
                        uiDefButF(block, NUM, B_PART_REDRAW, "OffsetY:", butx,(buty-=buth),butw,buth, part->bb_offset+1, -1.0, 1.0, 0, 0, "Offset billboards vertically");
 
4481
                        uiDefIDPoinBut(block, test_obpoin_but, ID_OB, B_PART_REDRAW, "OB:",     butx,(buty-=buth),butw,buth, &part->bb_ob, "Billboards face this object (default is active camera)"); 
 
4482
                        uiDefButS(block, MENU, B_PART_REDRAW, "UV channel%t|Split%x2|Time-Index (X-Y)%x1|Normal%x0", butx,(buty-=buth),butw,buth, &bbuvnum, 14.0, 0.0, 0, 0, "UV channel");
 
4483
                        but=uiDefBut(block, TEX, B_PART_REDRAW, "UV:", butx,(buty-=buth),butw,buth, psys->bb_uvname+bbuvnum, 0, 31, 0, 0, "Set name of UV layer to use with billboards, default is active UV layer");
 
4484
                        uiButSetCompleteFunc(but, autocomplete_uv, NULL);
 
4485
                        break;
 
4486
                case PART_DRAW_LINE:
 
4487
                        uiDefButBitS(block, TOG, PART_DRAW_VEL_LENGTH, B_PART_REDRAW, "Speed",  butx,(buty-=buth),butw,buth, &part->draw, 0, 0, 0, 0, "Multiply line length by particle speed");
 
4488
                        uiDefButF(block, NUM, B_PART_REDRAW, "Back:", butx,(buty-=buth),butw,buth, &part->draw_line[0], 0.0, 10.0, 0, 0, "Length of the line's tail");
 
4489
                        uiDefButF(block, NUM, B_PART_REDRAW, "Front:", butx,(buty-=buth),butw,buth, &part->draw_line[1], 0.0, 10.0, 0, 0, "Length of the line's head");
 
4490
                        break;
 
4491
                case PART_DRAW_PATH:
 
4492
                        if(part->phystype==PART_PHYS_KEYED || part->type==PART_HAIR) {
 
4493
                                uiDefButS(block, NUM, B_PART_RECALC, "Steps:",  butx,(buty+=buth),butw,buth, &part->draw_step, 0.0, 7.0, 0, 0, "How many steps paths are drawn with (power of 2)");
 
4494
                                uiDefButS(block, NUM, B_PART_REDRAW, "Render:", butx,(buty-=buth),butw,buth, &part->ren_step, 0.0, 9.0, 0, 0, "How many steps paths are rendered with (power of 2)");
 
4495
 
 
4496
                                uiDefButBitI(block, TOG, PART_ABS_LENGTH, B_PART_RECALC, "Abs Length",   butx,(buty-=buth),butw,buth, &part->flag, 0, 0, 0, 0, "Use maximum length for children");
 
4497
                                uiDefButF(block, NUM, B_PART_RECALC, "Max Length:",             butx,(buty-=buth),butw,buth, &part->abslength, 0.0, 10000.0, 1, 3, "Absolute maximum path length for children, in blender units");
 
4498
                                uiDefButF(block, NUMSLI, B_PART_RECALC, "RLength:",             butx,(buty-=buth),butw,buth, &part->randlength, 0.0, 1.0, 1, 3, "Give path length a random variation");
 
4499
                                uiBlockEndAlign(block);
 
4500
 
 
4501
                                uiDefButBitI(block, TOG, PART_HAIR_BSPLINE, B_PART_RECALC, "B-Spline",   butx,(buty-=buth),butw,buth, &part->flag, 0, 0, 0, 0, "Interpolate hair using B-Splines");
 
4502
 
 
4503
                                uiBlockBeginAlign(block);
 
4504
                                uiDefButBitS(block, TOG, PART_DRAW_REN_STRAND, B_PART_REDRAW, "Strand render",   butx,buty-=buth,butw,buth, &part->draw, 0, 0, 0, 0, "Use the strand primitive for rendering");
 
4505
                                if(part->draw & PART_DRAW_REN_STRAND) {
 
4506
                                        uiDefButS(block, NUM, B_PART_REDRAW, "Angle:",  butx,(buty-=buth),butw,buth, &part->adapt_angle, 0.0, 45.0, 0, 0, "How many degrees path has to curve to make another render segment");
 
4507
                                }
 
4508
                                else {
 
4509
                                        uiDefButBitS(block, TOG, PART_DRAW_REN_ADAPT, B_PART_REDRAW, "Adaptive render",  butx,buty-=buth,butw,buth, &part->draw, 0, 0, 0, 0, "Draw steps of the particle path");
 
4510
                                        if(part->draw & PART_DRAW_REN_ADAPT) {
 
4511
                                                uiDefButS(block, NUM, B_PART_REDRAW, "Angle:",  butx,(buty-=buth),butw/2,buth, &part->adapt_angle, 0.0, 45.0, 0, 0, "How many degrees path has to curve to make another render segment");
 
4512
                                                uiDefButS(block, NUM, B_PART_REDRAW, "Pixel:",  butx+butw/2,buty,(butw+1)/2,buth, &part->adapt_pix, 0.0, 50.0, 0, 0, "How many pixels path has to cover to make another render segment");
 
4513
                                        }
 
4514
                                }
 
4515
                        }
 
4516
                        else {
 
4517
                                uiDefBut(block, LABEL, 0, "Hair or keyed",      butx,(buty-=2*buth),butw,buth, NULL, 0.0, 0, 0, 0, "");
 
4518
                                uiDefBut(block, LABEL, 0, "particles needed!",  butx,(buty-=2*buth),butw,buth, NULL, 0.0, 0, 0, 0, "");
 
4519
                        }
 
4520
                        break;
 
4521
        }
 
4522
        uiBlockEndAlign(block);
 
4523
}
 
4524
static void object_panel_particle_simplification(Object *ob)
 
4525
{
 
4526
        uiBlock *block;
 
4527
        ParticleSystem *psys=psys_get_current(ob);
 
4528
        ParticleSettings *part;
 
4529
        short butx=0, buty=160, butw=150, buth=20;
 
4530
 
 
4531
        if (psys==NULL) return;
 
4532
        part=psys->part;
 
4533
        if(part==NULL) return;
 
4534
 
 
4535
        if(part->draw_as!=PART_DRAW_PATH || !(part->draw & PART_DRAW_REN_STRAND))
 
4536
                return;
 
4537
        if(part->childtype!=PART_CHILD_FACES)
 
4538
                return;
 
4539
        
 
4540
        block= uiNewBlock(&curarea->uiblocks, "object_panel_particle_simplification", UI_EMBOSS, UI_HELV, curarea->win);
 
4541
        uiNewPanelTabbed("Visualization", "Particle");
 
4542
        if(uiNewPanel(curarea, block, "Simplification", "Particle", 640, 0, 318, 204)==0) return;
 
4543
 
 
4544
        uiBlockBeginAlign(block);
 
4545
        uiDefButBitS(block, TOG, PART_SIMPLIFY_ENABLE, B_PART_REDRAW, "Child Simplification", butx,buty-=buth,butw,buth, &part->simplify_flag, 0, 0, 0, 0, "Remove child strands as the object becomes smaller on the screen");
 
4546
        uiBlockEndAlign(block);
 
4547
        if(part->simplify_flag & PART_SIMPLIFY_ENABLE) {
 
4548
                buty -= 10;
 
4549
 
 
4550
                uiBlockBeginAlign(block);
 
4551
                uiDefButS(block, NUM, B_NOP, "Reference Size:", butx,(buty-=buth),butw,buth, &part->simplify_refsize, 1.0, 32768.0, 0, 0, "Reference size size in pixels, after which simplification begins");
 
4552
                uiDefButF(block, NUM, B_NOP, "Rate:", butx,(buty-=buth),butw,buth, &part->simplify_rate, 0.0, 1.0, 0, 0, "Speed of simplification");
 
4553
                uiDefButF(block, NUM, B_NOP, "Transition:", butx,(buty-=buth),butw,buth, &part->simplify_transition, 0.0, 1.0, 0, 0, "Transition period for fading out strands");
 
4554
                uiBlockEndAlign(block);
 
4555
 
 
4556
                buty -= 10;
 
4557
 
 
4558
                uiBlockBeginAlign(block);
 
4559
                uiDefButBitS(block, TOG, PART_SIMPLIFY_VIEWPORT, B_PART_REDRAW, "Viewport", butx,buty-=buth,butw,buth, &part->simplify_flag, 0, 0, 0, 0, "Remove child strands as the object goes outside the viewport");
 
4560
                uiDefButF(block, NUM, B_NOP, "Rate:", butx,(buty-=buth),butw,buth, &part->simplify_viewport, 0.0, 0.999, 0, 0, "Speed of simplification");
 
4561
                uiBlockEndAlign(block);
 
4562
        }
 
4563
        uiBlockEndAlign(block);
 
4564
}
 
4565
static void boidrule_moveDown(void *part_v, void *rule_v)
 
4566
{
 
4567
        ParticleSettings *part = part_v;
 
4568
        char r, *rule = rule_v;
 
4569
 
 
4570
        int n= rule - part->boidrule;
 
4571
 
 
4572
        if(n+1 < BOID_TOT_RULES) {
 
4573
                r=part->boidrule[n];
 
4574
                part->boidrule[n]=part->boidrule[n+1];
 
4575
                part->boidrule[n+1]=r;
 
4576
        }
 
4577
}
 
4578
static void boidrule_moveUp(void *part_v, void *rule_v)
 
4579
{
 
4580
        ParticleSettings *part = part_v;
 
4581
        char r, *rule = rule_v;
 
4582
 
 
4583
        int n= rule - part->boidrule;
 
4584
 
 
4585
        if(n-1 >= 0) {
 
4586
                r=part->boidrule[n];
 
4587
                part->boidrule[n]=part->boidrule[n-1];
 
4588
                part->boidrule[n-1]=r;
 
4589
        }
 
4590
}
 
4591
static void object_panel_particle_physics(Object *ob)
 
4592
{
 
4593
        uiBlock *block;
 
4594
        uiBut *but;
 
4595
        ParticleSystem *psys=psys_get_current(ob);
 
4596
        ParticleSettings *part;
 
4597
        short butx=0, buty=160, butw=150, buth=20;
 
4598
 
 
4599
        if (psys==NULL) return;
 
4600
        
 
4601
        part=psys->part;
 
4602
 
 
4603
        if(part==NULL) return;
 
4604
                
 
4605
        block= uiNewBlock(&curarea->uiblocks, "object_panel_particle_physics", UI_EMBOSS, UI_HELV, curarea->win);
 
4606
        if(uiNewPanel(curarea, block, "Physics", "Particle", 320, 0, 318, 204)==0) return;
 
4607
        
 
4608
        if(part->type == PART_FLUID) {
 
4609
                uiDefBut(block, LABEL, 0, "No settings for fluid particles",                                    butx,(buty-=2*buth),2*butw,buth, NULL, 0.0, 0, 0, 0, "");
 
4610
                return;
 
4611
        }
 
4612
 
 
4613
        if(ob->id.lib)
 
4614
                uiSetButLock(1, "Can't edit library data");
 
4615
        else if(psys->flag & PSYS_EDITED)
 
4616
                uiSetButLock(1, "Hair is edited!");
 
4617
        else if(psys->pointcache->flag & PTCACHE_BAKED)
 
4618
                uiSetButLock(1, "Simulation frames are baked!");
 
4619
 
 
4620
        if(part->phystype==PART_PHYS_KEYED){
 
4621
                uiBlockBeginAlign(block);
 
4622
                uiDefButBitI(block, TOG, PSYS_FIRST_KEYED, B_PART_RECALC, "First",       butx,buty,45,buth, &psys->flag, 0, 0, 0, 0, "Sets the system to be the starting point of keyed particles");
 
4623
                uiDefButS(block, MENU, B_PART_RECALC, "Physics %t|Boids%x3|Keyed %x2|Newtonian %x1|None %x0", butx+45,buty,butw-45,buth, &part->phystype, 14.0, 0.0, 0, 0, "Select particle physics type");
 
4624
                uiBlockEndAlign(block);
 
4625
        }
 
4626
        else
 
4627
                uiDefButS(block, MENU, B_PART_RECALC, "Physics%t|Boids%x3|Keyed%x2|Newtonian%x1|None%x0", butx,buty,butw,buth, &part->phystype, 14.0, 0.0, 0, 0, "Select particle physics type");
 
4628
 
 
4629
        if(part->phystype==PART_PHYS_BOIDS) {
 
4630
                int i;
 
4631
                char *rules[BOID_TOT_RULES] = {"Collision", "Avoid", "Crowd", "Center", "AvVel", "Velocity", "Goal", "Level"};
 
4632
                char *ruletext[BOID_TOT_RULES] = {
 
4633
                        "Avoid deflector objects",
 
4634
                        "Avoid predators",
 
4635
                        "Avoid other boids",
 
4636
                        "Get to flock center",
 
4637
                        "Maintain average velocity",
 
4638
                        "Match velocity of nearby boids",
 
4639
                        "Seek goal",
 
4640
                        "Keep the Z level"
 
4641
                };
 
4642
                /* left column */
 
4643
                uiDefBut(block, LABEL, 0, "Behaviour:",         butx,(buty-=buth),butw,buth, NULL, 0.0, 0, 0, 0, "");
 
4644
                uiBlockBeginAlign(block);
 
4645
                for(i=0; i<BOID_TOT_RULES; i++) {
 
4646
                        uiBlockSetCol(block, TH_BUT_ACTION);
 
4647
 
 
4648
                        but = uiDefIconBut(block, BUT, B_PART_RECALC, VICON_MOVE_UP, butx, (buty-=buth), 20, 20, NULL, 0.0, 0.0, 0.0, 0.0, "Move rule up");
 
4649
                        uiButSetFunc(but, boidrule_moveUp, part, part->boidrule+i);
 
4650
 
 
4651
                        but = uiDefIconBut(block, BUT, B_PART_RECALC, VICON_MOVE_DOWN, butx+20, buty, 20, 20, NULL, 0.0, 0.0, 0.0, 0.0, "Move rule down");
 
4652
                        uiButSetFunc(but, boidrule_moveDown, part, part->boidrule+i);
 
4653
 
 
4654
                        uiBlockSetCol(block, TH_BUT_SETTING2);
 
4655
 
 
4656
                        uiDefButF(block, NUM, B_PART_RECALC, rules[part->boidrule[i]],          butx+40,buty,butw-40,buth, part->boidfac+part->boidrule[i], -1.0, 2.0, 1, 3, ruletext[part->boidrule[i]]);
 
4657
                }
 
4658
                uiBlockSetCol(block, TH_AUTO);
 
4659
                uiBlockEndAlign(block);
 
4660
 
 
4661
                buty=140;
 
4662
                butx=160;
 
4663
                
 
4664
                uiDefBut(block, LABEL, 0, "Physics:",           butx,buty,butw,buth, NULL, 0.0, 0, 0, 0, "");
 
4665
                uiBlockBeginAlign(block);
 
4666
                uiDefButBitI(block, TOG, PART_BOIDS_2D, B_PART_RECALC, "2D",     butx,(buty-=buth),butw,buth, &part->flag, 0, 0, 0, 0, "Constrain boids to a surface");
 
4667
                uiDefButF(block, NUM, B_PART_RECALC, "MaxVelocity:",            butx,(buty-=buth),butw,buth, &part->max_vel, 0.0, 200.0, 1, 3, "Maximum velocity");
 
4668
                uiDefButF(block, NUM, B_PART_RECALC, "AvVelocity:",             butx,(buty-=buth),butw,buth, &part->average_vel, 0.0, 1.0, 1, 3, "The usual speed % of max velocity");
 
4669
                uiDefButF(block, NUM, B_PART_RECALC, "LatAcc:",         butx,(buty-=buth),butw,buth, &part->max_lat_acc, 0.0, 1.0, 1, 3, "Lateral acceleration % of max velocity");
 
4670
                uiDefButF(block, NUM, B_PART_RECALC, "TanAcc:",         butx,(buty-=buth),butw,buth, &part->max_tan_acc, 0.0, 1.0, 1, 3, "Tangential acceleration % of max velocity");
 
4671
                if(part->flag & PART_BOIDS_2D) {
 
4672
                        uiDefButF(block, NUM, B_PART_RECALC, "GroundZ:",                butx,(buty-=buth),butw,buth, &part->groundz, -100.0, 100.0, 1, 3, "Default Z value");
 
4673
                        uiDefIDPoinBut(block, test_obpoin_but, ID_OB, B_PARTTARGET, "OB:",      butx,(buty-=buth),butw,buth, &psys->keyed_ob, "Constrain boids to object's surface"); 
 
4674
                }
 
4675
                else {
 
4676
                        uiDefButF(block, NUM, B_PART_RECALC, "Banking:",                butx,(buty-=buth),butw,buth, &part->banking, -10.0, 10.0, 1, 3, "Banking of boids on turns (1.0==natural banking)");
 
4677
                        uiDefButF(block, NUM, B_PART_RECALC, "MaxBank:",                butx,(buty-=buth),butw,buth, &part->max_bank, 0.0, 1.0, 1, 3, "How much a boid can bank at a single step");
 
4678
                }
 
4679
                uiBlockEndAlign(block);
 
4680
                uiDefButS(block, NUM, B_PART_RECALC, "N:",              butx,(buty-=buth),butw,buth, &part->boidneighbours, 1.0, 10.0, 1, 3, "How many neighbours to consider for each boid");
 
4681
        }
 
4682
        else {
 
4683
                /* left column */
 
4684
                uiDefBut(block, LABEL, 0, "Initial velocity:",          butx,(buty-=buth),butw,buth, NULL, 0.0, 0, 0, 0, "");
 
4685
                uiBlockBeginAlign(block);
 
4686
                uiBlockSetCol(block, TH_BUT_SETTING2);
 
4687
                uiDefButF(block, NUM, B_PART_RECALC, "Object:",         butx,(buty-=buth*4/5),butw,buth*4/5, &part->obfac, -1.0, 1.0, 1, 3, "Let the object give the particle a starting speed");
 
4688
                uiDefButF(block, NUM, B_PART_RECALC, "Normal:",         butx,(buty-=buth*4/5),butw,buth*4/5, &part->normfac, -200.0, 200.0, 1, 3, "Let the surface normal give the particle a starting speed");
 
4689
                uiDefButF(block, NUM, B_PART_RECALC, "Random:",         butx,(buty-=buth*4/5),butw,buth*4/5, &part->randfac, 0.0, 200.0, 1, 3, "Give the starting speed a random variation");
 
4690
                if(part->type==PART_REACTOR) {
 
4691
                        uiDefButF(block, NUM, B_PART_RECALC, "Particle:",               butx,(buty-=buth*4/5),butw,buth*4/5, &part->partfac, -10.0, 10.0, 1, 3, "Let the target particle give the particle a starting speed");
 
4692
                        uiDefButF(block, NUM, B_PART_RECALC, "Reactor:",                butx,(buty-=buth*4/5),butw,buth*4/5, &part->reactfac, -10.0, 10.0, 1, 3, "Let the vector away from the target particles location give the particle a starting speed");
 
4693
                }
 
4694
                else {
 
4695
                        uiDefButF(block, NUM, B_PART_RECALC, "Tan:",            butx,(buty-=buth*4/5),butw,buth*4/5, &part->tanfac, -200.0, 200.0, 1, 3, "Let the surface tangent give the particle a starting speed");
 
4696
                        uiDefButF(block, NUM, B_PART_RECALC, "Rot:",            butx,(buty-=buth*4/5),butw,buth*4/5, &part->tanphase, -1.0, 1.0, 1, 3, "Rotate the surface tangent");
 
4697
                }
 
4698
                uiBlockSetCol(block, TH_AUTO);
 
4699
                uiBlockEndAlign(block);
 
4700
 
 
4701
                buty=160;
 
4702
                butx=160;
 
4703
                
 
4704
                if(part->phystype==PART_PHYS_NEWTON)
 
4705
                        uiDefButS(block, MENU, B_PART_RECALC, "Integration%t|RK4%x2|Midpoint%x1|Euler%x0", butx,buty,butw,buth, &part->integrator, 14.0, 0.0, 0, 0, "Select physics integrator type");
 
4706
                
 
4707
                uiDefBut(block, LABEL, 0, "Rotation:",  butx, (buty-=buth),butw,buth, NULL, 0.0, 0, 0, 0, "");
 
4708
                uiBlockBeginAlign(block);
 
4709
                uiDefButBitI(block, TOG, PART_ROT_DYN, B_PART_RECALC, "Dynamic",         butx,(buty-=buth*4/5),butw/2,buth*4/5, &part->flag, 0, 0, 0, 0, "Sets rotation to dynamic/constant");
 
4710
                uiDefButS(block, MENU, B_PART_RECALC, "Rotation%t|Object Z%x8|Object Y%x7|Object X%x6|Global Z%x5|Global Y%x4|Global X%x3|Velocity%x2|Normal%x1|None%x0", butx+butw/2,buty,butw/2,buth*4/5, &part->rotmode, 14.0, 0.0, 0, 0, "Particles initial rotation");
 
4711
                uiBlockSetCol(block, TH_BUT_SETTING2);
 
4712
                uiDefButF(block, NUM, B_PART_RECALC, "Random:",         butx,(buty-=buth*4/5),butw,buth*4/5, &part->randrotfac, 0.0, 1.0, 1, 3, "Randomize rotation");
 
4713
                uiDefButF(block, NUM, B_PART_RECALC, "Phase:",                  butx,(buty-=buth*4/5),butw/2,buth*4/5, &part->phasefac, -1.0, 1.0, 1, 3, "Initial rotation phase");
 
4714
                uiDefButF(block, NUM, B_PART_RECALC, "Rand:",                   butx+butw/2,buty,butw/2,buth*4/5, &part->randphasefac, 0.0, 1.0, 1, 3, "Randomize rotation phase");
 
4715
                uiBlockSetCol(block, TH_AUTO);
 
4716
 
 
4717
                uiDefButS(block, MENU, B_PART_RECALC, "Angular v %t|Random%x2|Spin%x1|None%x0", butx,(buty-=buth*4/5),butw,buth*4/5, &part->avemode, 14.0, 0.0, 0, 0, "Select particle angular velocity mode");
 
4718
                uiBlockSetCol(block, TH_BUT_SETTING2);
 
4719
                if(ELEM(part->avemode,PART_AVE_RAND,PART_AVE_SPIN))
 
4720
                        uiDefButF(block, NUM, B_PART_RECALC, "Angular v:",              butx,(buty-=buth*4/5),butw,buth*4/5, &part->avefac, -200.0, 200.0, 1, 3, "Angular velocity amount");
 
4721
                uiBlockSetCol(block, TH_AUTO);
 
4722
                uiBlockEndAlign(block);
 
4723
                
 
4724
                if(part->phystype==PART_PHYS_NEWTON) {
 
4725
                        butx=0;
 
4726
                        buty=40;
 
4727
                        uiDefBut(block, LABEL, 0, "Global effects:",    butx,buty,butw,buth, NULL, 0.0, 0, 0, 0, "");
 
4728
 
 
4729
                        butw=103;
 
4730
                        uiBlockBeginAlign(block);
 
4731
                        uiDefButF(block, NUM, B_PART_RECALC, "AccX:",           butx,(buty-=buth),butw,buth, part->acc, -200.0, 200.0, 10, 0, "Specify a constant acceleration along the X-axis");
 
4732
                        uiDefButF(block, NUM, B_PART_RECALC, "AccY:",           butx+butw,buty,butw,buth, part->acc+1,-200.0, 200.0, 10, 0, "Specify a constant acceleration along the Y-axis");
 
4733
                        uiDefButF(block, NUM, B_PART_RECALC, "AccZ:",           butx+2*butw,buty,butw+1,buth, part->acc+2, -200.0, 200.0, 10, 0, "Specify a constant acceleration along the Z-axis");
 
4734
 
 
4735
                        uiDefButF(block, NUM, B_PART_RECALC, "Drag:",           butx,(buty-=buth),butw,buth, &part->dragfac, 0.0, 1.0, 1, 0, "Specify the amount of air-drag");
 
4736
                        uiDefButF(block, NUM, B_PART_RECALC, "Brown:",          butx+butw,buty,butw,buth, &part->brownfac, 0.0, 200.0, 1, 0, "Specify the amount of brownian motion");
 
4737
                        uiDefButF(block, NUM, B_PART_RECALC, "Damp:",           butx+2*butw,buty,butw+1,buth, &part->dampfac, 0.0, 1.0, 1, 0, "Specify the amount of damping");
 
4738
                        uiBlockEndAlign(block);
 
4739
                }
 
4740
                else if(part->phystype==PART_PHYS_KEYED) {
 
4741
                        short totkpsys=1;
 
4742
                        butx=0;
 
4743
                        buty=40;
 
4744
                        uiDefBut(block, LABEL, 0, "Keyed Target:",                                                      butx,buty,butw,buth, NULL, 0.0, 0, 0, 0, "");
 
4745
                        if(psys->keyed_ob){
 
4746
                                if(psys->keyed_ob==ob || BLI_findlink(&psys->keyed_ob->particlesystem,psys->keyed_psys-1)==0)
 
4747
                                        uiBlockSetCol(block, TH_REDALERT);
 
4748
                                else
 
4749
                                        totkpsys = BLI_countlist(&psys->keyed_ob->particlesystem);
 
4750
                        }
 
4751
                        else
 
4752
                                uiBlockSetCol(block, TH_REDALERT);
 
4753
 
 
4754
                        uiBlockBeginAlign(block);
 
4755
                        uiDefIDPoinBut(block, test_obpoin_but, ID_OB, B_PARTTARGET, "OB:",      butx,(buty-=buth),butw*2/3,buth, &psys->keyed_ob, "The object that has the target particle system"); 
 
4756
                        uiDefButS(block, NUM, B_PARTTARGET, "Psys:",            butx+butw*2/3,buty,butw/3,buth, &psys->keyed_psys, 1.0, totkpsys, 0, 0, "The target particle system number in the object");
 
4757
                        uiBlockEndAlign(block);
 
4758
                        
 
4759
                        uiBlockSetCol(block, TH_AUTO);
 
4760
 
 
4761
                        butx=160;
 
4762
 
 
4763
                        if(psys->flag & PSYS_FIRST_KEYED)
 
4764
                                uiDefButBitI(block, TOG, PSYS_KEYED_TIME, B_PART_RECALC, "Timed",        butx,buty,butw,buth, &psys->flag, 0, 0, 0, 0, "Use intermediate key times");
 
4765
                        else
 
4766
                                uiDefButF(block, NUMSLI, B_PART_RECALC, "Time:",                butx,buty,butw,buth, &part->keyed_time, 0.0, 1.0, 1, 3, "Keyed key time relative to remaining particle life");
 
4767
                }
 
4768
        }
 
4769
}
 
4770
 
 
4771
static void object_panel_particle_system(Object *ob)
 
4772
{
 
4773
        uiBlock *block;
 
4774
        uiBut *but;
 
4775
        ParticleSystem *psys=NULL;
 
4776
        ParticleSettings *part;
 
4777
        ID *id, *idfrom;
 
4778
        ModifierData *md;
 
4779
        short butx=0, buty=160, butw=150, buth=20;
 
4780
        char str[30], *lockmessage= NULL;
 
4781
        static short partact;
 
4782
        short totpart, lock= 0;
 
4783
 
 
4784
        block= uiNewBlock(&curarea->uiblocks, "object_panel_particle_system", UI_EMBOSS, UI_HELV, curarea->win);
 
4785
        if(uiNewPanel(curarea, block, "Particle System", "Particle", 0, 0, 318, 204)==0) return;
 
4786
        
 
4787
        if(ob->id.lib) uiSetButLock(1, "Can't edit library data");
 
4788
 
 
4789
        if(ELEM4(ob->type,OB_MESH,OB_FONT,OB_CURVE,OB_SURF)==0) {
 
4790
                uiDefBut(block, LABEL, 0, "Only Mesh or Curve Objects can generate particles", 10,180,300,20, NULL, 0.0, 0, 0, 0, "");
 
4791
                return;
 
4792
        }
 
4793
        psys=psys_get_current(ob);
 
4794
 
 
4795
        if(psys)
 
4796
                id=(ID*)(psys->part);
 
4797
        else
 
4798
                id=NULL;
 
4799
        idfrom=&ob->id;
 
4800
 
 
4801
        if(psys==0 || psys->part->type != PART_FLUID) {
 
4802
        /* browse buttons */
 
4803
                uiBlockSetCol(block, TH_BUT_SETTING2);
 
4804
                butx= std_libbuttons(block, butx, buty, 0, NULL, B_PARTBROWSE, ID_PA, 0, id, idfrom, &(G.buts->menunr), B_PARTALONE, 0, B_PARTDELETE, 0, 0);
 
4805
        }
 
4806
 
 
4807
        uiBlockSetCol(block, TH_AUTO);
 
4808
        
 
4809
        partact=psys_get_current_num(ob)+1;
 
4810
        totpart=BLI_countlist(&ob->particlesystem);
 
4811
        sprintf(str, "%d Part", totpart);
 
4812
        but=uiDefButS(block, NUM, B_PARTACT, str, 230,buty,83,buth, &partact, 1.0, totpart+1, 0, 0, "Shows the number of particle systems in the object and the active particle system");
 
4813
        uiButSetFunc(but, PE_change_act, ob, &partact);
 
4814
 
 
4815
        if(psys==NULL)
 
4816
                return;
 
4817
 
 
4818
        part=psys->part;
 
4819
 
 
4820
        if(part==NULL)
 
4821
                return;
 
4822
 
 
4823
        butx=0;
 
4824
 
 
4825
        if(part->type == PART_FLUID) {
 
4826
                uiDefBut(block, LABEL, 0, "No settings for fluid particles",                                    butx,buty,2*butw,buth, NULL, 0.0, 0, 0, 0, "");
 
4827
                return;
 
4828
        }
 
4829
 
 
4830
        buty -= (buth+5);
 
4831
 
 
4832
        if(part->type == PART_HAIR){
 
4833
                if(psys->flag & PSYS_EDITED)
 
4834
                        uiDefBut(block, BUT, B_PART_EDITABLE, "Free Edit",              butx+butw+10,buty,butw,buth, NULL, 0.0, 0.0, 10, 0, "Free editing");
 
4835
                else
 
4836
                        uiDefBut(block, BUT, B_PART_EDITABLE, "Set Editable",   butx+butw+10,buty,butw,buth, NULL, 0.0, 0.0, 10, 0, "Finalize hair to enable editing in particle mode");
 
4837
 
 
4838
        }
 
4839
 
 
4840
        md= (ModifierData*)psys_get_modifier(ob, psys);
 
4841
        if(md) {
 
4842
                uiBlockBeginAlign(block);
 
4843
                uiDefIconButBitI(block, TOG, eModifierMode_Render, B_PART_RECALC, ICON_SCENE, butx+butw-40, buty, 20, 20,&md->mode, 0, 0, 1, 0, "Enable particle system during rendering");
 
4844
                but= uiDefIconButBitI(block, TOG, eModifierMode_Realtime, B_PART_RECALC, VICON_VIEW3D, butx+butw-20, buty, 20, 20,&md->mode, 0, 0, 1, 0, "Enable particle system during interactive display");
 
4845
                uiBlockEndAlign(block);
 
4846
        }
 
4847
 
 
4848
        if(psys->flag & PSYS_EDITED) {
 
4849
                lockmessage= "Hair is edited!";
 
4850
                lock= 1;
 
4851
        }
 
4852
        else if(psys->pointcache->flag & PTCACHE_BAKED) {
 
4853
                lockmessage= "Simulation frames are baked!";
 
4854
                lock= 1;
 
4855
        }
 
4856
 
 
4857
        if(lock)
 
4858
                uiSetButLock(1, lockmessage);
 
4859
 
 
4860
        uiDefButS(block, MENU, B_PARTTYPE, "Type%t|Hair%x2|Reactor%x1|Emitter%x0", butx,buty,butw-45,buth, &part->type, 14.0, 0.0, 0, 0, "Type of particle system");
 
4861
 
 
4862
        buty-=5;
 
4863
        uiDefBut(block, LABEL, 0, "Basic:",                                     butx,(buty-=buth),butw,buth, NULL, 0.0, 0, 0, 0, "");
 
4864
        uiBlockBeginAlign(block);
 
4865
 
 
4866
        if(part->distr==PART_DISTR_GRID && part->from != PART_FROM_VERT)
 
4867
                uiDefButI(block, NUM, B_PART_ALLOC, "Resol:",           butx,(buty-=buth),butw,buth, &part->grid_res, 1.0, 100.0, 0, 0, "The resolution of the particle grid");
 
4868
        else
 
4869
                uiDefButI(block, NUM, B_PART_ALLOC, "Amount:",          butx,(buty-=buth),butw,buth, &part->totpart, 0.0, 100000.0, 0, 0, "The total number of particles");
 
4870
        if(part->type==PART_REACTOR) {
 
4871
                uiDefButBitI(block, TOG, PART_REACT_STA_END, B_PART_INIT, "Sta/End",     butx,(buty-=buth),butw/2,buth, &part->flag, 0, 0, 0, 0, "Give birth to unreacted particles eventually");
 
4872
                uiDefButS(block, MENU, B_PART_RECALC, "React on %t|Near %x2|Collision %x1|Death %x0", butx+butw/2,buty,butw/2,buth, &part->reactevent, 14.0, 0.0, 0, 0, "The event of target particles to react");
 
4873
                if(part->flag&PART_REACT_STA_END) {
 
4874
                        uiDefButF(block, NUM, B_PART_INIT, "Sta:",              butx,(buty-=buth),butw,buth, &part->sta, 1.0, part->end, 100, 1, "Frame # to start emitting particles");
 
4875
                        uiDefButF(block, NUM, B_PART_INIT, "End:",              butx,(buty-=buth),butw,buth, &part->end, part->sta, MAXFRAMEF, 100, 1, "Frame # to stop emitting particles");
 
4876
                }
 
4877
                if(part->from!=PART_FROM_PARTICLE) {
 
4878
                        uiDefButBitI(block, TOG, PART_REACT_MULTIPLE, B_PART_RECALC, "Multi React",      butx,(buty-=buth),butw,buth, &part->flag, 0, 0, 0, 0, "React multiple times");
 
4879
                        uiDefButF(block, NUM, B_PART_RECALC, "Shape:",          butx,(buty-=buth),butw,buth, &part->reactshape, 0.0, 10.0, 100, 1, "Power of reaction strength dependence on distance to target");
 
4880
                }
 
4881
        }
 
4882
        else if(part->type==PART_HAIR) {
 
4883
                uiDefButS(block, NUM, B_PART_RECALC, "Segments:",       butx,(buty-=buth),butw,buth, &part->hair_step, 2.0, 50.0, 0, 0, "Amount of hair segments");
 
4884
        }
 
4885
        else {
 
4886
                uiDefButF(block, NUM, B_PART_INIT, "Sta:",              butx,(buty-=buth),butw,buth, &part->sta, -MAXFRAMEF, part->end, 100, 1, "Frame # to start emitting particles");
 
4887
                uiDefButF(block, NUM, B_PART_INIT, "End:",              butx,(buty-=buth),butw,buth, &part->end, part->sta, MAXFRAMEF, 100, 1, "Frame # to stop emitting particles");
 
4888
        }
 
4889
 
 
4890
        if(part->type!=PART_HAIR) {
 
4891
                uiDefButF(block, NUM, B_PART_INIT, "Life:",     butx,(buty-=buth),butw,buth, &part->lifetime, 1.0, MAXFRAMEF, 100, 1, "Specify the life span of the particles");
 
4892
                uiDefButF(block, NUM, B_PART_INIT, "Rand:",     butx,(buty-=buth),butw,buth, &part->randlife, 0.0, 2.0, 10, 1, "Give the particle life a random variation");
 
4893
        }
 
4894
 
 
4895
        uiBlockEndAlign(block);
 
4896
 
 
4897
        butx=160;
 
4898
        buty=120;
 
4899
 
 
4900
        buty-=10;
 
4901
 
 
4902
        uiDefBut(block, LABEL, 0, "Emit From:",                                                 butx,buty,butw,buth, NULL, 0.0, 0, 0, 0, "");
 
4903
        uiBlockBeginAlign(block);
 
4904
 
 
4905
        if(lock) uiClearButLock();
 
4906
        uiDefButBitI(block, TOG, PART_TRAND, B_PART_DISTR, "Random",    butx,(buty-=buth),butw/2,buth, &part->flag, 0, 0, 0, 0, "Emit in random order of elements");
 
4907
        if(lock) uiSetButLock(1, lockmessage);
 
4908
 
 
4909
        if(part->type==PART_REACTOR)
 
4910
                uiDefButS(block, MENU, B_PART_DISTR, "Particle %x3|Volume %x2|Faces %x1|Verts %x0", butx+butw/2,buty,butw/2,buth, &part->from, 14.0, 0.0, 0, 0, "Where to emit particles from");
 
4911
        else
 
4912
                uiDefButS(block, MENU, B_PART_DISTR, "Volume %x2|Faces %x1|Verts%x0", butx+butw/2,buty,butw/2,buth, &part->from, 14.0, 0.0, 0, 0, "Where to emit particles from");
 
4913
 
 
4914
        if(ELEM(part->from,PART_FROM_FACE,PART_FROM_VOLUME)) {
 
4915
                if(lock) uiClearButLock();
 
4916
                uiDefButBitI(block, TOG, PART_EDISTR, B_PART_DISTR, "Even",butx,(buty-=buth),butw/2,buth, &part->flag, 0, 0, 0, 0, "Use even distribution from faces based on face areas or edge lengths");
 
4917
                if(lock) uiSetButLock(1, lockmessage);
 
4918
                uiDefButS(block, MENU, B_PART_DISTR, "Distribution %t|Grid%x2|Random%x1|Jittered%x0", butx+butw/2,buty,butw/2,buth, &part->distr, 14.0, 0.0, 0, 0, "How to distribute particles on selected element");
 
4919
                if(part->distr==PART_DISTR_JIT) {
 
4920
                        uiDefButF(block, NUM, B_PART_DISTR, "Amount:",          butx,(buty-=buth),butw,buth, &part->jitfac, 0, 2.0, 1, 1, "Amount of jitter applied to the sampling");
 
4921
                        uiDefButI(block, NUM, B_PART_DISTR, "P/F:",             butx,(buty-=buth),butw,buth, &part->userjit, 0, 1000.0, 1, 1, "Emission locations / face (0 = automatic)");
 
4922
                }
 
4923
                if(part->distr==PART_DISTR_GRID){
 
4924
                        uiDefButBitI(block, TOG, PART_GRID_INVERT, B_PART_DISTR, "Invert",butx,(buty-=buth),butw,buth, &part->flag, 0, 0, 0, 0, "Invert what is considered object and what is not.");                           
 
4925
                }
 
4926
        }
 
4927
        uiBlockEndAlign(block);
 
4928
        
 
4929
        buty=30;
 
4930
 
 
4931
        if(part->type==PART_REACTOR) {
 
4932
                ParticleSystem *tpsys=0;
 
4933
                Object *tob=0;
 
4934
                int tottpsys;
 
4935
 
 
4936
                uiDefBut(block, LABEL, 0, "Target:", butx,(buty-=buth),butw,buth, NULL, 0.0, 0, 0, 0, "");
 
4937
 
 
4938
                if(psys->target_ob)
 
4939
                        tob=psys->target_ob;
 
4940
                else
 
4941
                        tob=ob;
 
4942
 
 
4943
                tottpsys=BLI_countlist(&tob->particlesystem);
 
4944
 
 
4945
                uiBlockBeginAlign(block);
 
4946
                
 
4947
                if(tob->particlesystem.first==0)
 
4948
                        uiBlockSetCol(block, TH_REDALERT);
 
4949
                
 
4950
                uiDefIDPoinBut(block, test_obpoin_but, ID_OB, B_PARTTARGET, "OB:",      butx,(buty-=buth),butw*2/3,buth, &psys->target_ob, "The object that has the target particle system (empty if same object)"); 
 
4951
 
 
4952
                tpsys=BLI_findlink(&tob->particlesystem,psys->target_psys-1);
 
4953
                if(tpsys) {
 
4954
                        if(tob==ob && tpsys==psys)
 
4955
                                uiBlockSetCol(block, TH_REDALERT);
 
4956
                }
 
4957
                else
 
4958
                        uiBlockSetCol(block, TH_REDALERT);
 
4959
 
 
4960
                uiDefButS(block, NUM, B_PARTTARGET, "Psys:",            butx+butw*2/3,buty,butw/3,buth, &psys->target_psys, 1.0, tottpsys, 0, 0, "The target particle system number in the object");
 
4961
                uiBlockEndAlign(block);
 
4962
                
 
4963
                uiBlockSetCol(block, TH_AUTO);
 
4964
        }
 
4965
}
 
4966
 
 
4967
/* NT - Panel for fluidsim settings */
 
4968
#ifndef DISABLE_ELBEEM
 
4969
static int _can_fluidsim_at_all(Object *ob)
 
4970
{
 
4971
        // list of Yes
 
4972
        if ((ob->type==OB_MESH)) return 1;
 
4973
        // else deny
 
4974
        return 0;
 
4975
}
 
4976
 
 
4977
/* Panel for fluidsim */
 
4978
static void object_fluidsim__enabletoggle(void *ob_v, void *arg2)
 
4979
{
 
4980
        Object *ob = ob_v;
 
4981
        ModifierData *md = modifiers_findByType(ob, eModifierType_Fluidsim);
 
4982
 
 
4983
        if (!md) {
 
4984
                md = modifier_new(eModifierType_Fluidsim);
 
4985
                BLI_addhead(&ob->modifiers, md);
 
4986
                
 
4987
                DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA|OB_RECALC_OB);
 
4988
                allqueue(REDRAWBUTSEDIT, 0);
 
4989
                allqueue(REDRAWVIEW3D, 0);
 
4990
        }
 
4991
        else {
 
4992
                Object *ob = ob_v;
 
4993
                ModifierData *md = modifiers_findByType(ob, eModifierType_Fluidsim);
 
4994
        
 
4995
                if (!md)
 
4996
                        return;
 
4997
 
 
4998
                BLI_remlink(&ob->modifiers, md);
 
4999
 
 
5000
                modifier_free(md);
 
5001
 
 
5002
                BIF_undo_push("Del modifier");
 
5003
                
 
5004
                //ob->softflag |= OB_SB_RESET;
 
5005
                allqueue(REDRAWBUTSEDIT, 0);
 
5006
                allqueue(REDRAWVIEW3D, 0);
 
5007
                allqueue(REDRAWIMAGE, 0);
 
5008
                allqueue(REDRAWOOPS, 0);
 
5009
                DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA|OB_RECALC_OB);
 
5010
                object_handle_update(ob);
 
5011
                countall();
 
5012
        }
 
5013
}
 
5014
#endif
 
5015
 
 
5016
static void object_panel_fluidsim(Object *ob)
 
5017
{
 
5018
#ifndef DISABLE_ELBEEM
 
5019
        uiBlock *block;
 
5020
        int yline = 174;
 
5021
        const int lineHeight = 20;
 
5022
        const int separateHeight = 2;
 
5023
        const int objHeight = 20;
 
5024
        FluidsimModifierData *fluidmd = (FluidsimModifierData *)modifiers_findByType(ob, eModifierType_Fluidsim);
 
5025
        int libdata = 0;
 
5026
        static int val = 0;
 
5027
        uiBut *but=NULL;
 
5028
        
 
5029
        block= uiNewBlock(&curarea->uiblocks, "object_fluidsim", UI_EMBOSS, UI_HELV, curarea->win);
 
5030
        if(uiNewPanel(curarea, block, "Fluid", "Physics", 1060, 0, 318, 204)==0) return;
 
5031
 
 
5032
        libdata= object_is_libdata(ob);
 
5033
        uiSetButLock(libdata, ERROR_LIBDATA_MESSAGE);
 
5034
        
 
5035
        val = (fluidmd ? 1:0);
 
5036
        
 
5037
        if(!_can_fluidsim_at_all(ob))
 
5038
        {
 
5039
                uiDefBut(block, LABEL, 0, "Fluidsim can be activated on mesh only.",  10,200,300,20, NULL, 0.0, 0, 0, 0, "");
 
5040
        }
 
5041
        else    
 
5042
        {       
 
5043
                but = uiDefButI(block, TOG, REDRAWBUTSOBJECT, "Fluid",  0,200,130,20, &val, 0, 0, 0, 0, "Sets object to participate in fluid simulation");
 
5044
                uiButSetFunc(but, object_fluidsim__enabletoggle, ob, NULL);
 
5045
 
 
5046
                /*
 
5047
                // no pointcache used in fluidsim *YET*
 
5048
                md = (ModifierData*)clmd;
 
5049
                if(md) {
 
5050
                        uiBlockBeginAlign(block);
 
5051
                        uiDefIconButBitI(block, TOG, eModifierMode_Render, B_BAKE_CACHE_CHANGE, ICON_SCENE, 145, 200, 20, 20,&md->mode, 0, 0, 1, 0, "Enable fluidsim during rendering");
 
5052
                        but= uiDefIconButBitI(block, TOG, eModifierMode_Realtime, B_BAKE_CACHE_CHANGE, VICON_VIEW3D, 165, 200, 20, 20,&md->mode, 0, 0, 1, 0, "Enable fluidsim during interactive display");
 
5053
                        uiBlockEndAlign(block);
 
5054
                }
 
5055
                */
 
5056
        }
 
5057
 
 
5058
        uiDefBut(block, LABEL, 0, "",0,0,300,0, NULL, 0.0, 0, 0, 0, ""); /* tell UI we go to 10,10*/
 
5059
 
 
5060
        if(fluidmd)
 
5061
        {
 
5062
                FluidsimSettings *fss = fluidmd->fss;
 
5063
                
 
5064
                if(!fss)
 
5065
                        return;
 
5066
                
 
5067
                /* GENERAL STUFF */
 
5068
                /*
 
5069
                if(!libdata) {
 
5070
                        uiClearButLock();
 
5071
                        if(cache->flag & PTCACHE_BAKE_EDIT_ACTIVE)
 
5072
                                uiSetButLock(1, "Please leave editmode.");
 
5073
                        else if(cache->flag & PTCACHE_BAKED)
 
5074
                                uiSetButLock(1, "Simulation frames are baked");
 
5075
                }
 
5076
                */
 
5077
                uiBlockBeginAlign ( block );
 
5078
                uiDefButS ( block, ROW, B_FLUIDSIM_CHANGETYPE   ,"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." );
 
5079
                uiDefButS ( block, ROW, B_FLUIDSIM_CHANGETYPE   ,"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." );
 
5080
                uiDefButS ( block, ROW, B_FLUIDSIM_CHANGETYPE   ,"Obstacle",     230, yline, 70,objHeight, &fss->type, 15.0, OB_FLUIDSIM_OBSTACLE, 20.0, 3.0, "Object is a fixed obstacle." );
 
5081
                yline -= lineHeight;
 
5082
                
 
5083
                uiDefButS ( block, ROW, B_FLUIDSIM_CHANGETYPE   ,"Inflow",          90, yline, 52,objHeight, &fss->type, 15.0, OB_FLUIDSIM_INFLOW,  20.0, 4.0, "Object adds fluid to the simulation." );
 
5084
                uiDefButS ( block, ROW, B_FLUIDSIM_CHANGETYPE   ,"Outflow",   142, yline, 52,objHeight, &fss->type, 15.0, OB_FLUIDSIM_OUTFLOW, 20.0, 5.0, "Object removes fluid from the simulation." );
 
5085
                uiDefButS ( block, ROW, B_FLUIDSIM_MAKEPART     ,"Particle",     194, yline, 52,objHeight, &fss->type, 15.0, OB_FLUIDSIM_PARTICLE,20.0, 3.0, "Object is made a particle system to display particles generated by a fluidsim domain object." );
 
5086
                uiDefButS ( block, ROW, B_FLUIDSIM_CHANGETYPE   ,"Control",      246, yline, 54,objHeight, &fss->type, 15.0, OB_FLUIDSIM_CONTROL,20.0, 3.0, "Object is made a fluid control mesh, which influences the fluid." );
 
5087
                uiBlockEndAlign ( block );
 
5088
                yline -= lineHeight;
 
5089
                yline -= separateHeight;
 
5090
 
 
5091
 
 
5092
                /* display specific settings for each type */
 
5093
                if ( fss->type == OB_FLUIDSIM_DOMAIN )
 
5094
                {
 
5095
                        const int maxRes = 1024;
 
5096
                        char memString[32];
 
5097
                        Mesh *mesh = ob->data;
 
5098
                
 
5099
                        // use mesh bounding box and object scaling
 
5100
                        // TODO fix redraw issue
 
5101
                        fluid_get_bb(mesh->mvert, mesh->totvert, ob->obmat, fss->bbStart, fss->bbSize);
 
5102
                        elbeemEstimateMemreq ( fss->resolutionxyz,
 
5103
                                               fss->bbSize[0],fss->bbSize[1],fss->bbSize[2], fss->maxRefine, memString );
 
5104
                
 
5105
                        uiBlockBeginAlign ( block );
 
5106
                        uiDefButS ( block, ROW, REDRAWBUTSOBJECT, "Std",         0,yline, 25,objHeight, &fss->show_advancedoptions, 16.0, 0, 20.0, 0, "Show standard domain options." );
 
5107
                        uiDefButS ( block, ROW, REDRAWBUTSOBJECT, "Adv",        20,yline, 25,objHeight, &fss->show_advancedoptions, 16.0, 1, 20.0, 1, "Show advanced domain options." );
 
5108
                        uiDefButS ( block, ROW, REDRAWBUTSOBJECT, "Bnd",        40,yline, 25,objHeight, &fss->show_advancedoptions, 16.0, 2, 20.0, 2, "Show domain boundary options." );
 
5109
                        uiDefButS ( block, ROW, REDRAWBUTSOBJECT, "Par",        60,yline, 25,objHeight, &fss->show_advancedoptions, 16.0, 3, 20.0, 3, "Show particle options." );
 
5110
                        uiBlockEndAlign ( block );
 
5111
                
 
5112
                        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." );
 
5113
                        
 
5114
                        yline -= lineHeight;
 
5115
                        yline -= separateHeight;
 
5116
                
 
5117
                        if ( fss->show_advancedoptions == 1 )
 
5118
                        {
 
5119
                                // advanced options
 
5120
                                uiDefBut ( block, LABEL, 0, "Gravity:",         0, yline,  120,objHeight, NULL, 0.0, 0, 0, 0, "" );
 
5121
                                uiBlockBeginAlign ( block );
 
5122
                                uiDefButF ( block, NUM, B_DIFF, "X:",    120, yline,  60,objHeight, &fss->gravx, -1000.1, 1000.1, 10, 0, "Gravity in X direction" );
 
5123
                                uiDefButF ( block, NUM, B_DIFF, "Y:",   180, yline,  60,objHeight, &fss->gravy, -1000.1, 1000.1, 10, 0, "Gravity in Y direction" );
 
5124
                                uiDefButF ( block, NUM, B_DIFF, "Z:",   240, yline,  60,objHeight, &fss->gravz, -1000.1, 1000.1, 10, 0, "Gravity in Z direction" );
 
5125
                                uiBlockEndAlign ( block );
 
5126
                                yline -= lineHeight;
 
5127
                                yline -= separateHeight;
 
5128
                
 
5129
                                /* viscosity */
 
5130
                                if ( fss->viscosityMode==1 ) /*manual*/
 
5131
                                        uiBlockBeginAlign ( block );
 
5132
                                uiDefButS ( block, MENU, REDRAWVIEW3D, "Viscosity%t|Manual %x1|Water %x2|Oil %x3|Honey %x4",
 
5133
                                                0,yline, 90,objHeight, &fss->viscosityMode, 0, 0, 0, 0, "Set viscosity of the fluid to a preset value, or use manual input." );
 
5134
                                if ( fss->viscosityMode==1 )
 
5135
                                {
 
5136
                                        uiBlockBeginAlign ( block );    
 
5137
                                        uiDefButF ( block, NUM, B_DIFF, "Value:",     120, yline, 90,objHeight, &fss->viscosityValue,       0.0, 10.0, 10, 0, "Viscosity setting: value that is multiplied by 10 to the power of (exponent*-1)." );
 
5138
                                        uiDefButS ( block, NUM, B_DIFF, "Neg-Exp.:", 210, yline, 90,objHeight, &fss->viscosityExponent, 0,   10,  10, 0, "Negative exponent for the viscosity value (to simplify entering small values e.g. 5*10^-6." );
 
5139
                                        uiBlockEndAlign ( block );
 
5140
                                }
 
5141
                                else
 
5142
                                {
 
5143
                                        // display preset values
 
5144
                                        uiDefBut ( block, LABEL,   0, fluidsimViscosityPresetString[fss->viscosityMode],  120,yline,180,objHeight, NULL, 0.0, 0, 0, 0, "" );
 
5145
                                }
 
5146
 
 
5147
                                yline -= lineHeight;
 
5148
                                yline -= separateHeight;
 
5149
                
 
5150
                                uiDefBut ( block, LABEL, 0, "Realworld-size:",          0,yline,120,objHeight, NULL, 0.0, 0, 0, 0, "" );
 
5151
                                uiDefButF ( block, NUM, B_DIFF, "", 120, yline,180,objHeight, &fss->realsize, 0.001, 10.0, 10, 0, "Size of the simulation domain in meters." );
 
5152
                                yline -= lineHeight;
 
5153
                                yline -= separateHeight;
 
5154
                
 
5155
                                uiDefBut ( block, LABEL, 0, "Gridlevels:",              0,yline,120,objHeight, NULL, 0.0, 0, 0, 0, "" );
 
5156
                                uiDefButI ( block, NUM, B_DIFF, "", 120, yline,180,objHeight, &fss->maxRefine, -1, 4, 10, 0, "Number of coarsened Grids to use (set to -1 for automatic selection)." );
 
5157
                                yline -= lineHeight;
 
5158
                                yline -= separateHeight;
 
5159
                
 
5160
                                uiDefBut ( block, LABEL, 0, "Compressibility:",         0,yline,120,objHeight, NULL, 0.0, 0, 0, 0, "" );
 
5161
                                uiDefButF ( block, NUM, B_DIFF, "", 120, yline,180,objHeight, &fss->gstar, 0.001, 0.10, 10,0, "Allowed compressibility due to gravitational force for standing fluid (directly affects simulation step size)." );
 
5162
                                yline -= lineHeight;
 
5163
                
 
5164
                        }
 
5165
                        else if ( fss->show_advancedoptions == 2 )
 
5166
                        {
 
5167
                                // copied from obstacle...
 
5168
                                //yline -= lineHeight + 5;
 
5169
                                //uiDefBut(block, LABEL, 0, "Domain boundary type settings:",           0,yline,300,objHeight, NULL, 0.0, 0, 0, 0, "");
 
5170
                                //yline -= lineHeight;
 
5171
 
 
5172
                                uiDefBut ( block, LABEL, 0, "Boundary type:",           0,yline,120,objHeight, NULL, 0.0, 0, 0, 0, "" );
 
5173
                                uiBlockBeginAlign ( block ); // domain
 
5174
                                uiDefButS ( block, ROW, REDRAWBUTSOBJECT ,"Noslip",    120, yline,60,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." );
 
5175
                                uiDefButS ( block, ROW, REDRAWBUTSOBJECT ,"Part",          180, yline,60,objHeight, &fss->typeFlags, 15.0, OB_FSBND_PARTSLIP, 20.0, 2.0, "Mix between no-slip and free-slip. Non moving objects only!" );
 
5176
                                uiDefButS ( block, ROW, REDRAWBUTSOBJECT ,"Free",        240, yline,60,objHeight, &fss->typeFlags, 15.0, OB_FSBND_FREESLIP, 20.0, 3.0, "Obstacle only causes zero normal velocity (=not sticky). Non moving objects only!" );
 
5177
                                uiBlockEndAlign ( block );
 
5178
                                yline -= lineHeight;
 
5179
                                yline -= separateHeight;
 
5180
 
 
5181
                                uiDefBut ( block, LABEL, 0, "PartSlip Amount:",         0,yline,120,objHeight, NULL, 0.0, 0, 0, 0, "" );
 
5182
                                if ( fss->typeFlags&OB_FSBND_PARTSLIP )
 
5183
                                {
 
5184
                                        uiDefButF ( block, NUM, B_DIFF, "", 120, yline,180,objHeight, &fss->partSlipValue, 0.0, 1.0, 10,0, "Amount of mixing between no- and free-slip, 0=stickier, 1=same as free slip." );
 
5185
                                }
 
5186
                                else
 
5187
                                {
 
5188
                                        uiDefBut ( block, LABEL, 0, "-",        120,yline,180,objHeight, NULL, 0.0, 0, 0, 0, "" );
 
5189
                                }
 
5190
 
 
5191
                                yline -= lineHeight;
 
5192
                                yline -= separateHeight;
 
5193
 
 
5194
                                // copied from obstacle...
 
5195
 
 
5196
                                uiDefBut ( block, LABEL, 0, "Surface Subdiv:",          0,yline,120,objHeight, NULL, 0.0, 0, 0, 0, "" );
 
5197
                                uiDefButI ( block, NUM, B_DIFF, "", 120, yline,180,objHeight, &fss->surfaceSubdivs, 0.0, 5.0, 10,0, "Number of isosurface subdivisions. This is necessary for the inclusion of particles into the surface generation. Warning - can lead to longer computation times!" );
 
5198
                                yline -= lineHeight;
 
5199
                                yline -= separateHeight;
 
5200
                
 
5201
                                uiDefBut ( block, LABEL, 0, "Surface Smoothing:",               0,yline,120,objHeight, NULL, 0.0, 0, 0, 0, "" );
 
5202
                                uiDefButF ( block, NUM, B_DIFF, "", 120, yline,180,objHeight, &fss->surfaceSmoothing, 0.0, 5.0, 10,0, "Amount of surface smoothing (0=off, 1=normal, >1=stronger smoothing)." );
 
5203
                                yline -= lineHeight;
 
5204
                                yline -= separateHeight;
 
5205
                
 
5206
                                // use new variable...
 
5207
                                uiDefBut ( block, LABEL, 0, "Generate SpeedVecs:",              0,yline,120,objHeight, NULL, 0.0, 0, 0, 0, "" );
 
5208
                                uiDefButBitC ( block, TOG, 1, REDRAWBUTSOBJECT, "Disable",     120, yline,180,objHeight, &fss->domainNovecgen, 0, 0, 0, 0, "Default is to generate and use fluidsim vertex speed vectors, this option switches calculation off during bake, and disables loading." );
 
5209
                                yline -= lineHeight;
 
5210
                        }
 
5211
                        else if ( fss->show_advancedoptions == 3 )
 
5212
                        {
 
5213
                                uiDefBut ( block, LABEL, 0, "Tracer Particles:",                0,yline,120,objHeight, NULL, 0.0, 0, 0, 0, "" );
 
5214
                                uiDefButI ( block, NUM, B_DIFF, "", 120, yline,180,objHeight, &fss->generateTracers, 0.0, 10000.0, 10,0, "Number of tracer particles to generate." );
 
5215
                                yline -= lineHeight;
 
5216
                                yline -= separateHeight;
 
5217
 
 
5218
                                uiDefBut ( block, LABEL, 0, "Generate Particles:",              0,yline,120,objHeight, NULL, 0.0, 0, 0, 0, "" );
 
5219
                                uiDefButF ( block, NUM, B_DIFF, "", 120, yline,180,objHeight, &fss->generateParticles, 0.0, 10.0, 10,0, "Amount of particles to generate (0=off, 1=normal, >1=more)." );
 
5220
                                yline -= lineHeight;
 
5221
                        }
 
5222
                        else
 
5223
                        {
 
5224
                                uiDefBut ( block, LABEL,   0, "Req. BAKE Mem.:",  0,yline,120,objHeight, NULL, 0.0, 0, 0, 0, "" );
 
5225
                                uiDefBut ( block, LABEL,   0, memString,  120,yline,180,objHeight, NULL, 0.0, 0, 0, 0, "" );
 
5226
                                yline -= lineHeight;
 
5227
                                yline -= separateHeight;
 
5228
 
 
5229
                                uiDefBut ( block, LABEL, 0, "Resolution:",              0,yline,90,objHeight, NULL, 0.0, 0, 0, 0, "" );
 
5230
                                uiBlockBeginAlign ( block );
 
5231
                                uiDefButS ( block, NUM, REDRAWBUTSOBJECT, "Res.:",   90, yline,105,objHeight, &fss->resolutionxyz, 1, maxRes, 10, 0, "Domain resolution in X, Y and Z direction" );
 
5232
                                uiDefButS ( block, NUM, B_DIFF, "Prev-Res.:",     195, yline,105,objHeight, &fss->previewresxyz, 1, 100, 10, 0, "Resolution of the preview meshes to generate, also in X, Y and Z direction" );
 
5233
                                uiBlockEndAlign ( block );
 
5234
                                yline -= lineHeight;
 
5235
                                yline -= separateHeight;
 
5236
 
 
5237
                                uiDefBut ( block, LABEL, 0, "Time:",            0,yline,90,objHeight, NULL, 0.0, 0, 0, 0, "" );
 
5238
                                uiBlockBeginAlign ( block );
 
5239
                                uiDefButF ( block, NUM, B_DIFF, "Start:",   90, yline,105,objHeight, &fss->animStart, 0.0, 100.0, 10, 0, "Simulation time of the first blender frame." );
 
5240
                                uiDefButF ( block, NUM, B_DIFF, "End:",     195, yline,105,objHeight, &fss->animEnd, 0.0, 100.0, 10, 0, "Simulation time of the last blender frame." );
 
5241
                                uiBlockEndAlign ( block );
 
5242
                                yline -= lineHeight;
 
5243
                                yline -= separateHeight;
 
5244
                
 
5245
                                if ( ( fss->guiDisplayMode<1 ) || ( fss->guiDisplayMode>3 ) ) { fss->guiDisplayMode=2; } // can be changed by particle setting
 
5246
                                uiDefBut ( block, LABEL,   0, "Disp.-Qual.:",            0,yline, 90,objHeight, NULL, 0.0, 0, 0, 0, "" );
 
5247
                                uiBlockBeginAlign ( block );
 
5248
                                uiDefButS ( block, MENU, B_BAKE_CACHE_CHANGE, "GuiDisplayMode%t|Geometry %x1|Preview %x2|Final %x3",
 
5249
                                            90,yline,105,objHeight, &fss->guiDisplayMode, 0, 0, 0, 0, "How to display the fluid mesh in the Blender GUI." );
 
5250
                                uiDefButS ( block, MENU, B_DIFF, "RenderDisplayMode%t|Geometry %x1|Preview %x2|Final %x3",
 
5251
                                            195,yline,105,objHeight, &fss->renderDisplayMode, 0, 0, 0, 0, "How to display the fluid mesh for rendering." );
 
5252
                                uiBlockEndAlign ( block );
 
5253
                                yline -= lineHeight;
 
5254
                                yline -= separateHeight;
 
5255
 
 
5256
                                uiDefBut ( block, LABEL, 0, "Reverse:",         0,yline,90,objHeight, NULL, 0.0, 0, 0, 0, "" );
 
5257
                                uiDefButBitI ( block, TOG, OB_FLUIDSIM_REVERSE, REDRAWBUTSOBJECT, "Enable",     90, yline,210,objHeight, &fss->flag, 0, 0, 0, 0, "Reverse fluid frames." );
 
5258
                                yline -= lineHeight;
 
5259
                                yline -= separateHeight;
 
5260
 
 
5261
                                uiDefBut ( block, LABEL,   0, "Path:",  0,yline,90,objHeight, NULL, 0.0, 0, 0, 0, "" );
 
5262
                                uiDefIconBut ( block, BUT, B_FLUIDSIM_SELDIR, ICON_FILESEL,  90, yline,  20, objHeight,                   0, 0, 0, 0, 0,  "Select Directory (and/or filename prefix) to store baked fluid simulation files in" );
 
5263
                                uiDefBut ( block, TEX,     B_BAKE_CACHE_CHANGE,"",            110, yline, 190, objHeight, fss->surfdataPath, 0.0,79.0, 0, 0,  "Enter Directory (and/or filename prefix) to store baked fluid simulation files in" );
 
5264
                                yline -= lineHeight + 2;
 
5265
                                // FIXME what is the 79.0 above?
 
5266
                        }
 
5267
                }
 
5268
                else if (
 
5269
                        ( fss->type == OB_FLUIDSIM_FLUID )
 
5270
                        || ( fss->type == OB_FLUIDSIM_INFLOW )
 
5271
                )
 
5272
                {
 
5273
                        yline -=lineHeight - 10;
 
5274
                        uiDefBut ( block, LABEL, 0, "Volume init:",             0,yline,120,objHeight, NULL, 0.0, 0, 0, 0, "" );
 
5275
                        uiBlockBeginAlign ( block ); // fluid
 
5276
                        uiDefButC ( block, ROW, REDRAWBUTSOBJECT ,"Volume",    120, yline,60,objHeight, &fss->volumeInitType, 15.0, 1, 20.0, 1.0, "Type of volume init: use only inner region of mesh." );
 
5277
                        uiDefButC ( block, ROW, REDRAWBUTSOBJECT ,"Shell",   180, yline,60,objHeight, &fss->volumeInitType, 15.0, 2, 20.0, 2.0, "Type of volume init: use only the hollow shell defined by the faces of the mesh." );
 
5278
                        uiDefButC ( block, ROW, REDRAWBUTSOBJECT ,"Both",    240, yline,60,objHeight, &fss->volumeInitType, 15.0, 3, 20.0, 3.0, "Type of volume init: use both the inner volume and the outer shell." );
 
5279
                        uiBlockEndAlign ( block );
 
5280
                        yline -= lineHeight;
 
5281
                        yline -= separateHeight;
 
5282
                
 
5283
                        if ( fss->type == OB_FLUIDSIM_FLUID )  uiDefBut ( block, LABEL, 0, "Initial velocity:",         0,yline,120,objHeight, NULL, 0.0, 0, 0, 0, "" );
 
5284
                        if ( fss->type == OB_FLUIDSIM_INFLOW ) uiDefBut ( block, LABEL, 0, "Inflow velocity:",            0,yline,120,objHeight, NULL, 0.0, 0, 0, 0, "" );
 
5285
                        //yline -= lineHeight;
 
5286
 
 
5287
                        uiBlockBeginAlign ( block );
 
5288
                        uiDefButF ( block, NUM, B_DIFF, "X:",   120, yline, 60,objHeight, &fss->iniVelx, -1000.1, 1000.1, 10, 0, "Fluid velocity in X direction" );
 
5289
                        uiDefButF ( block, NUM, B_DIFF, "Y:", 180, yline, 60,objHeight, &fss->iniVely, -1000.1, 1000.1, 10, 0, "Fluid velocity in Y direction" );
 
5290
                        uiDefButF ( block, NUM, B_DIFF, "Z:", 240, yline, 60,objHeight, &fss->iniVelz, -1000.1, 1000.1, 10, 0, "Fluid velocity in Z direction" );
 
5291
                        uiBlockEndAlign ( block );
 
5292
                        yline -= lineHeight;
 
5293
                        yline -= separateHeight;
 
5294
                
 
5295
                        if ( fss->type == OB_FLUIDSIM_INFLOW )   // inflow
 
5296
                        {
 
5297
                                uiDefBut ( block, LABEL, 0, "Local Coords:",            0,yline,120,objHeight, NULL, 0.0, 0, 0, 0, "" );
 
5298
                                uiDefButBitS ( block, TOG, OB_FSINFLOW_LOCALCOORD, REDRAWBUTSOBJECT, "Enable",     120, yline,180,objHeight, &fss->typeFlags, 0, 0, 0, 0, "Use local coordinates for inflow (e.g. for rotating objects)." );
 
5299
                                yline -= lineHeight;
 
5300
                                yline -= separateHeight;
 
5301
                        }
 
5302
                        else
 
5303
                        {
 
5304
                        }
 
5305
                
 
5306
                        // domainNovecgen "misused" here
 
5307
                        uiDefBut ( block, LABEL, 0, "Animated Mesh:",           0,yline,120,objHeight, NULL, 0.0, 0, 0, 0, "" );
 
5308
                        uiDefButBitC ( block, TOG, 1, REDRAWBUTSOBJECT, "Export",     120, yline,180,objHeight, &fss->domainNovecgen, 0, 0, 0, 0, "Export this mesh as an animated one. Slower, only use if really necessary (e.g. armatures or parented objects), animated pos/rot/scale IPOs do not require it." );
 
5309
                        yline -= lineHeight;
 
5310
                
 
5311
                } // fluid inflow
 
5312
                else if ( ( fss->type == OB_FLUIDSIM_OUTFLOW ) )
 
5313
                {
 
5314
                        yline -= lineHeight - 10;
 
5315
                        uiDefBut ( block, LABEL, 0, "Volumen init:",            0,yline,120,objHeight, NULL, 0.0, 0, 0, 0, "" );
 
5316
                        uiBlockBeginAlign ( block ); // outflow
 
5317
                        uiDefButC ( block, ROW, REDRAWBUTSOBJECT ,"Volume",    120, yline,60,objHeight, &fss->volumeInitType, 15.0, 1, 20.0, 1.0, "Type of volume init: use only inner region of mesh." );
 
5318
                        uiDefButC ( block, ROW, REDRAWBUTSOBJECT ,"Shell",   180, yline,60,objHeight, &fss->volumeInitType, 15.0, 2, 20.0, 2.0, "Type of volume init: use only the hollow shell defined by the faces of the mesh." );
 
5319
                        uiDefButC ( block, ROW, REDRAWBUTSOBJECT ,"Both",    240, yline,60,objHeight, &fss->volumeInitType, 15.0, 3, 20.0, 3.0, "Type of volume init: use both the inner volume and the outer shell." );
 
5320
                        uiBlockEndAlign ( block );
 
5321
                        yline -= lineHeight;
 
5322
                        yline -= separateHeight;
 
5323
                
 
5324
                        // domainNovecgen "misused" here
 
5325
                        uiDefBut ( block, LABEL, 0, "Animated Mesh:",           0,yline,120,objHeight, NULL, 0.0, 0, 0, 0, "" );
 
5326
                        uiDefButBitC ( block, TOG, 1, REDRAWBUTSOBJECT, "Export",     120, yline,180,objHeight, &fss->domainNovecgen, 0, 0, 0, 0, "Export this mesh as an animated one. Slower, only use if really necessary (e.g. armatures or parented objects), animated pos/rot/scale IPOs do not require it." );
 
5327
                        yline -= lineHeight;
 
5328
                
 
5329
                        //uiDefBut(block, LABEL, 0, "No additional settings as of now...",              0,yline,300,objHeight, NULL, 0.0, 0, 0, 0, "");
 
5330
                }
 
5331
                else if ( ( fss->type == OB_FLUIDSIM_OBSTACLE ) )
 
5332
                {
 
5333
                
 
5334
                        yline -= lineHeight - 10; // obstacle
 
5335
                        uiDefBut ( block, LABEL, 0, "Volume init:",             0,yline,120,objHeight, NULL, 0.0, 0, 0, 0, "" );
 
5336
                        uiBlockBeginAlign ( block ); // obstacle
 
5337
                        uiDefButC ( block, ROW, REDRAWBUTSOBJECT ,"Volume",    120, yline,60,objHeight, &fss->volumeInitType, 15.0, 1, 20.0, 1.0, "Type of volume init: use only inner region of mesh." );
 
5338
                        uiDefButC ( block, ROW, REDRAWBUTSOBJECT ,"Shell",   180, yline,60,objHeight, &fss->volumeInitType, 15.0, 2, 20.0, 2.0, "Type of volume init: use only the hollow shell defined by the faces of the mesh." );
 
5339
                        uiDefButC ( block, ROW, REDRAWBUTSOBJECT ,"Both",    240, yline,60,objHeight, &fss->volumeInitType, 15.0, 3, 20.0, 3.0, "Type of volume init: use both the inner volume and the outer shell." );
 
5340
                        uiBlockEndAlign ( block );
 
5341
                        yline -= lineHeight;
 
5342
                        yline -= separateHeight;
 
5343
 
 
5344
                        uiDefBut ( block, LABEL, 0, "Boundary type:",           0,yline,120,objHeight, NULL, 0.0, 0, 0, 0, "" );
 
5345
                        uiBlockBeginAlign ( block ); // obstacle
 
5346
                        uiDefButS ( block, ROW, REDRAWBUTSOBJECT ,"Noslip",    120, yline,60,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." );
 
5347
                        uiDefButS ( block, ROW, REDRAWBUTSOBJECT ,"Part",          180, yline,60,objHeight, &fss->typeFlags, 15.0, OB_FSBND_PARTSLIP, 20.0, 2.0, "Mix between no-slip and free-slip. Non moving objects only!" );
 
5348
                        uiDefButS ( block, ROW, REDRAWBUTSOBJECT ,"Free",        240, yline,60,objHeight, &fss->typeFlags, 15.0, OB_FSBND_FREESLIP, 20.0, 3.0, "Obstacle only causes zero normal velocity (=not sticky). Non moving objects only!" );
 
5349
                        uiBlockEndAlign ( block );
 
5350
                        yline -= lineHeight;
 
5351
                        yline -= separateHeight;
 
5352
                
 
5353
                        // domainNovecgen "misused" here
 
5354
                        uiDefBut ( block, LABEL, 0, "Animated Mesh:",           0,yline,120,objHeight, NULL, 0.0, 0, 0, 0, "" );
 
5355
                        uiDefButBitC ( block, TOG, 1, REDRAWBUTSOBJECT, "Export",     120, yline,180,objHeight, &fss->domainNovecgen, 0, 0, 0, 0, "Export this mesh as an animated one. Slower, only use if really necessary (e.g. armatures or parented objects), animated loc/rot/scale IPOs do not require it." );
 
5356
                        yline -= lineHeight;
 
5357
                        yline -= separateHeight;
 
5358
                
 
5359
                        uiDefBut ( block, LABEL, 0, "PartSlip Amount:",         0,yline,120,objHeight, NULL, 0.0, 0, 0, 0, "" );
 
5360
                        if ( fss->typeFlags&OB_FSBND_PARTSLIP )
 
5361
                        {
 
5362
                                uiDefButF ( block, NUM, B_DIFF, "", 120, yline,180,objHeight, &fss->partSlipValue, 0.0, 1.0, 10,0, "Amount of mixing between no- and free-slip, 0=stickier, 1=same as free slip." );
 
5363
                        }
 
5364
                        else { uiDefBut ( block, LABEL, 0, "-", 120,yline,180,objHeight, NULL, 0.0, 0, 0, 0, "" ); }
 
5365
                        yline -= lineHeight;
 
5366
                        yline -= separateHeight;
 
5367
                
 
5368
                        // generateParticles "misused" here
 
5369
                        uiDefBut ( block, LABEL, 0, "Impact Factor:",           0,yline,120,objHeight, NULL, 0.0, 0, 0, 0, "" );
 
5370
                        uiDefButF ( block, NUM, B_DIFF, "", 120, yline,180,objHeight, &fss->surfaceSmoothing, -2.0, 10.0, 10,0, "This is an unphysical value for moving objects - it controls the impact an obstacle has on the fluid, =0 behaves a bit like outflow (deleting fluid), =1 is default, while >1 results in high forces. Can be used to tweak total mass." );
 
5371
                        yline -= lineHeight;
 
5372
 
 
5373
                }
 
5374
                else if ( fss->type == OB_FLUIDSIM_PARTICLE )
 
5375
                {
 
5376
                
 
5377
                        //fss->type == 0; // off, broken...
 
5378
                        if ( 1 )
 
5379
                        {
 
5380
                                // limited selection, old fixed:        fss->typeFlags = (1<<5)|(1<<1);
 
5381
                #                               define PARTBUT_WIDTH (180/3)
 
5382
                                yline -=lineHeight - 10;
 
5383
                                uiDefBut ( block, LABEL, 0, "Particle type:",           0,yline,120,objHeight, NULL, 0.0, 0, 0, 0, "" );
 
5384
                                uiBlockBeginAlign ( block );
 
5385
                                uiDefButBitS ( block, TOG, ( 1<<2 ) , REDRAWBUTSOBJECT, "Drops",     120 + 0*PARTBUT_WIDTH, yline, PARTBUT_WIDTH,objHeight, &fss->typeFlags, 0, 0, 0, 0, "Show drop particles." );
 
5386
                                uiDefButBitS ( block, TOG, ( 1<<4 ) , REDRAWBUTSOBJECT, "Floats",    120 + 1*PARTBUT_WIDTH, yline, PARTBUT_WIDTH,objHeight, &fss->typeFlags, 0, 0, 0, 0, "Show floating foam particles." );
 
5387
                                uiDefButBitS ( block, TOG, ( 1<<5 ) , REDRAWBUTSOBJECT, "Tracer",    120 + 2*PARTBUT_WIDTH, yline, PARTBUT_WIDTH,objHeight, &fss->typeFlags, 0, 0, 0, 0, "Show tracer particles." );
 
5388
                                uiBlockEndAlign ( block );
 
5389
                                yline -= lineHeight;
 
5390
                                yline -= separateHeight;
 
5391
                #                               undef PARTBUT_WIDTH
 
5392
                
 
5393
                
 
5394
                                uiDefBut ( block, LABEL, 0, "Size Influence:",          0,yline,120,objHeight, NULL, 0.0, 0, 0, 0, "" );
 
5395
                                uiDefButF ( block, NUM, B_DIFF, "", 120, yline,180,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." );
 
5396
                                yline -= lineHeight;
 
5397
                                yline -= separateHeight;
 
5398
 
 
5399
                                uiDefBut ( block, LABEL, 0, "Alpha Influence:",         0,yline,120,objHeight, NULL, 0.0, 0, 0, 0, "" );
 
5400
                                uiDefButF ( block, NUM, B_DIFF, "", 120, yline,180,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)." );
 
5401
                                yline -= lineHeight;
 
5402
                                yline -= separateHeight;
 
5403
                
 
5404
                                // FSPARTICLE also select input files
 
5405
                                uiDefBut ( block, LABEL,   0, "Path:",  0,yline,120,objHeight, NULL, 0.0, 0, 0, 0, "" );
 
5406
                                uiBlockBeginAlign ( block );
 
5407
                                uiDefIconBut ( block, BUT, B_FLUIDSIM_SELDIR, ICON_FILESEL,  120, yline,  20, objHeight,                   0, 0, 0, 0, 0,  "Select fluid simulation bake directory/prefix to load particles from, same as for domain object." );
 
5408
                                uiDefBut ( block, TEX,     B_BAKE_CACHE_CHANGE,"",            140, yline, 160, objHeight, fss->surfdataPath, 0.0,79.0, 0, 0,  "Enter fluid simulation bake directory/prefix to load particles from, same as for domain object." );
 
5409
                                uiBlockEndAlign ( block );
 
5410
                                yline -= lineHeight;
 
5411
                        } // disabled for now...
 
5412
                
 
5413
                }
 
5414
                else if ( fss->type == OB_FLUIDSIM_CONTROL )
 
5415
                {
 
5416
                        yline -=lineHeight - 10;
 
5417
                        uiDefBut ( block, LABEL, 0, "Time:",            0,yline,100,objHeight, NULL, 0.0, 0, 0, 0, "" );
 
5418
                        uiBlockBeginAlign ( block );
 
5419
                        uiDefButF ( block, NUM, B_DIFF, "Start:",   120, yline,90,objHeight, &fss->cpsTimeStart, 0.0, 100.0, 10, 0, "Specifies time when the control particles are activated." );
 
5420
                        uiDefButF ( block, NUM, B_DIFF, "End:",     210, yline,90,objHeight, &fss->cpsTimeEnd  , 0.0, 100.0, 10, 0, "Specifies time when the control particles are deactivated." );
 
5421
                        uiBlockEndAlign ( block );
 
5422
                        yline -= lineHeight;
 
5423
                        yline -= separateHeight;
 
5424
 
 
5425
                        uiDefBut ( block, LABEL, 0, "Attraction force:", 0,yline,100,objHeight, NULL, 0.0, 0, 0, 0, "" );
 
5426
                        uiBlockBeginAlign ( block );
 
5427
                        uiDefButF ( block, NUM, B_DIFF, "Strength:",   120, yline,90,objHeight, &fss->attractforceStrength, -10.0, 10.0, 10, 0, "Force strength for directional attraction towards the control object." );
 
5428
                        uiDefButF ( block, NUM, B_DIFF, "Radius:",     210, yline,90,objHeight, &fss->attractforceRadius, 0.0, 10.0, 10, 0, "Specifies the force field radius around the control object." );
 
5429
                        uiBlockEndAlign ( block );
 
5430
                        yline -= lineHeight;
 
5431
                        yline -= separateHeight;
 
5432
 
 
5433
                        uiDefBut ( block, LABEL, 0, "Velocity force:", 0,yline,100,objHeight, NULL, 0.0, 0, 0, 0, "" );
 
5434
                        uiBlockBeginAlign ( block );
 
5435
                        uiDefButF ( block, NUM, B_DIFF, "Strength:",   120, yline,90,objHeight, &fss->velocityforceStrength, 0.0, 10.0, 10, 0, "Force strength of how much of the control object's velocity is influencing the fluid velocity." );
 
5436
                        uiDefButF ( block, NUM, B_DIFF, "Radius:",     210, yline,90,objHeight, &fss->velocityforceRadius, 0.0, 10.0, 10, 0, "Specifies the force field radius around the control object." );
 
5437
                        uiBlockEndAlign ( block );
 
5438
                        yline -= lineHeight;
 
5439
                        yline -= separateHeight;
 
5440
 
 
5441
                        uiDefBut ( block, LABEL, 0, "Quality:",         0,yline,100,objHeight, NULL, 0.0, 0, 0, 0, "" );
 
5442
                        uiDefButF ( block, NUM, B_DIFF, "",   120, yline,180,objHeight, &fss->cpsQuality, 5.0, 100.0, 10, 0, "Specifies the quality which is used for object sampling (higher = better but slower)." );
 
5443
                        yline -= lineHeight;
 
5444
                        yline -= separateHeight;
 
5445
 
 
5446
                        uiDefBut ( block, LABEL, 0, "Reverse:",         0,yline,100,objHeight, NULL, 0.0, 0, 0, 0, "" );
 
5447
                        uiDefButBitI ( block, TOG, OB_FLUIDSIM_REVERSE, REDRAWBUTSOBJECT, "Enable",     120, yline,180,objHeight, &fss->flag, 0, 0, 0, 0, "Reverse control object movement." );
 
5448
                        yline -= lineHeight;
 
5449
 
 
5450
 
 
5451
                }
 
5452
                else
 
5453
                {
 
5454
                        yline -= lineHeight + 5;
 
5455
                        /* not yet set */
 
5456
                        uiDefBut ( block, LABEL, 0, "Select object type for simulation",                0,yline,300,objHeight, NULL, 0.0, 0, 0, 0, "" );
 
5457
                        yline -= lineHeight;
 
5458
                }
 
5459
                return;
 
5460
        } 
 
5461
 
 
5462
#endif // DISABLE_ELBEEM
 
5463
}
 
5464
 
 
5465
/* Panel for cloth */
 
5466
static void object_cloth__enabletoggle(void *ob_v, void *arg2)
 
5467
{
 
5468
        Object *ob = ob_v;
 
5469
        ModifierData *md = modifiers_findByType(ob, eModifierType_Cloth);
 
5470
 
 
5471
        if (!md) {
 
5472
                md = modifier_new(eModifierType_Cloth);
 
5473
                BLI_addtail(&ob->modifiers, md);
 
5474
                
 
5475
                DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA);
 
5476
                allqueue(REDRAWBUTSEDIT, 0);
 
5477
                allqueue(REDRAWVIEW3D, 0);
 
5478
        }
 
5479
        else {
 
5480
                Object *ob = ob_v;
 
5481
                ModifierData *md = modifiers_findByType(ob, eModifierType_Cloth);
 
5482
        
 
5483
                if (!md)
 
5484
                        return;
 
5485
 
 
5486
                BLI_remlink(&ob->modifiers, md);
 
5487
 
 
5488
                modifier_free(md);
 
5489
 
 
5490
                BIF_undo_push("Del modifier");
 
5491
                
 
5492
                //ob->softflag |= OB_SB_RESET;
 
5493
                allqueue(REDRAWBUTSEDIT, 0);
 
5494
                allqueue(REDRAWVIEW3D, 0);
 
5495
                allqueue(REDRAWIMAGE, 0);
 
5496
                allqueue(REDRAWOOPS, 0);
 
5497
                DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA);
 
5498
                object_handle_update(ob);
 
5499
                countall();
 
5500
        }
 
5501
}
 
5502
 
 
5503
static void cloth_presets_material(void *ob_v, void *arg2)
 
5504
{
 
5505
        Object *ob = ob_v;
 
5506
        ClothModifierData *clmd = (ClothModifierData *)modifiers_findByType(ob, eModifierType_Cloth);
 
5507
        
 
5508
        if(!clmd) return;
 
5509
        if(clmd->sim_parms->presets==0) return;
 
5510
        
 
5511
        if(clmd->sim_parms->presets==1) /* SILK */
 
5512
        {
 
5513
                clmd->sim_parms->structural = clmd->sim_parms->shear = 5.0;
 
5514
                clmd->sim_parms->bending = 0.05;
 
5515
                clmd->sim_parms->Cdis = 0.0;
 
5516
                clmd->sim_parms->mass = 0.15;
 
5517
        }
 
5518
        else if(clmd->sim_parms->presets==2) /* COTTON */
 
5519
        {
 
5520
                clmd->sim_parms->structural = clmd->sim_parms->shear = 15.0;
 
5521
                clmd->sim_parms->bending = 0.5;
 
5522
                clmd->sim_parms->Cdis = 5.0;
 
5523
                clmd->sim_parms->mass = 0.3;
 
5524
        }
 
5525
        else if(clmd->sim_parms->presets==3) /* RUBBER */
 
5526
        {
 
5527
                clmd->sim_parms->structural = clmd->sim_parms->shear = 15.0;
 
5528
                clmd->sim_parms->bending = 25.0;
 
5529
                clmd->sim_parms->Cdis = 25.0;
 
5530
                clmd->sim_parms->stepsPerFrame = MAX2(clmd->sim_parms->stepsPerFrame, 7.0);
 
5531
                clmd->sim_parms->mass = 3.0;
 
5532
        }
 
5533
        else if(clmd->sim_parms->presets==4) /* DENIM */
 
5534
        {
 
5535
                clmd->sim_parms->structural = clmd->sim_parms->shear = 40.0;
 
5536
                clmd->sim_parms->bending = 10.0;
 
5537
                clmd->sim_parms->Cdis = 25.0;
 
5538
                clmd->sim_parms->stepsPerFrame = MAX2(clmd->sim_parms->stepsPerFrame, 12.0);
 
5539
                clmd->sim_parms->mass = 1.0;
 
5540
        }
 
5541
        else if(clmd->sim_parms->presets==5) /* LEATHER */
 
5542
        {
 
5543
                clmd->sim_parms->structural = clmd->sim_parms->shear = 80.0;
 
5544
                clmd->sim_parms->bending = 150.0;
 
5545
                clmd->sim_parms->Cdis = 25.0;
 
5546
                clmd->sim_parms->stepsPerFrame = MAX2(clmd->sim_parms->stepsPerFrame, 15.0);
 
5547
                clmd->sim_parms->mass = 0.4;
 
5548
        }
 
5549
}
 
5550
 
 
5551
static void cloth_presets_custom_material(void *ob_v, void *arg2)
 
5552
{
 
5553
        Object *ob = ob_v;
 
5554
        ClothModifierData *clmd = (ClothModifierData *)modifiers_findByType(ob, eModifierType_Cloth);
 
5555
        
 
5556
        if(!clmd) return;
 
5557
        
 
5558
        clmd->sim_parms->presets = 0;
 
5559
}
 
5560
 
 
5561
static int _can_cloth_at_all(Object *ob)
 
5562
{
 
5563
        // list of Yes
 
5564
        if ((ob->type==OB_MESH)) return 1;
 
5565
        // else deny
 
5566
        return 0;
 
5567
}
 
5568
 
 
5569
static void object_panel_cloth(Object *ob)
 
5570
{
 
5571
        uiBlock *block=NULL;
 
5572
        uiBut *but=NULL;
 
5573
        static int val, val2;
 
5574
        ClothModifierData *clmd = (ClothModifierData *)modifiers_findByType(ob, eModifierType_Cloth);
 
5575
        PointCache *cache;
 
5576
        ModifierData *md;
 
5577
        int libdata = 0;
 
5578
        
 
5579
        block= uiNewBlock(&curarea->uiblocks, "object_cloth", UI_EMBOSS, UI_HELV, curarea->win);
 
5580
        if(uiNewPanel(curarea, block, "Cloth ", "Physics", 640, 0, 318, 204)==0) return;
 
5581
 
 
5582
        libdata= object_is_libdata(ob);
 
5583
        uiSetButLock(libdata, ERROR_LIBDATA_MESSAGE);
 
5584
        
 
5585
        val = (clmd ? 1:0);
 
5586
        
 
5587
        if(!_can_cloth_at_all(ob))
 
5588
        {
 
5589
                uiDefBut(block, LABEL, 0, "Cloth can be activated on mesh only.",  10,200,300,20, NULL, 0.0, 0, 0, 0, "");
 
5590
        }
 
5591
        else    
 
5592
        {
 
5593
                but = uiDefButI(block, TOG, REDRAWBUTSOBJECT, "Cloth",  10,200,130,20, &val, 0, 0, 0, 0, "Sets object to become cloth");
 
5594
                uiButSetFunc(but, object_cloth__enabletoggle, ob, NULL);
 
5595
 
 
5596
                md = (ModifierData*)clmd;
 
5597
                if(md) {
 
5598
                        uiBlockBeginAlign(block);
 
5599
                        uiDefIconButBitI(block, TOG, eModifierMode_Render, B_BAKE_CACHE_CHANGE, ICON_SCENE, 145, 200, 20, 20,&md->mode, 0, 0, 1, 0, "Enable cloth during rendering");
 
5600
                        but= uiDefIconButBitI(block, TOG, eModifierMode_Realtime, B_BAKE_CACHE_CHANGE, VICON_VIEW3D, 165, 200, 20, 20,&md->mode, 0, 0, 1, 0, "Enable cloth during interactive display");
 
5601
                        uiBlockEndAlign(block);
 
5602
                }
 
5603
        }
 
5604
 
 
5605
        uiDefBut(block, LABEL, 0, "",10,10,300,0, NULL, 0.0, 0, 0, 0, ""); /* tell UI we go to 10,10*/
 
5606
        
 
5607
        if(clmd)
 
5608
        {
 
5609
                int defCount;
 
5610
                char *clvg1, *clvg2;
 
5611
                char clmvg [] = "Vertex Groups%t|";
 
5612
 
 
5613
                val2=0;
 
5614
                cache= clmd->point_cache;
 
5615
                
 
5616
                /* GENERAL STUFF */
 
5617
                if(!libdata) {
 
5618
                        uiClearButLock();
 
5619
                        if(cache->flag & PTCACHE_BAKE_EDIT_ACTIVE)
 
5620
                                uiSetButLock(1, "Please leave editmode.");
 
5621
                        else if(cache->flag & PTCACHE_BAKED)
 
5622
                                uiSetButLock(1, "Simulation frames are baked");
 
5623
                }
 
5624
                
 
5625
                uiDefBut(block, LABEL, 0, "Material Preset:",  10,170,150,20, NULL, 0.0, 0, 0, 0, "");
 
5626
                but=uiDefButS(block, MENU, B_BAKE_CACHE_CHANGE, "Silk %x1|Cotton %x2|Rubber %x3|Denim %x4|Leather %x5|Custom %x0",
 
5627
                             160,170,150,20, &clmd->sim_parms->presets, 0, 0, 0, 0, "");
 
5628
                uiButSetFunc(but, cloth_presets_material, ob, NULL);
 
5629
                
 
5630
                uiBlockBeginAlign(block);
 
5631
                but = uiDefButF(block, NUM, B_BAKE_CACHE_CHANGE, "StructStiff:", 10,150,150,20, &clmd->sim_parms->structural, 1.0, 10000.0, 100, 0, "Overall stiffness of structure");
 
5632
                uiButSetFunc(but, cloth_presets_custom_material, ob, NULL);
 
5633
                
 
5634
                but = uiDefButF(block, NUM, B_BAKE_CACHE_CHANGE, "BendStiff:", 160,150,150,20, &clmd->sim_parms->bending, 0.0, 10000.0, 1000, 0, "Wrinkle coefficient (higher = less smaller but more big wrinkles)");
 
5635
                uiButSetFunc(but, cloth_presets_custom_material, ob, NULL);
 
5636
                
 
5637
                but = uiDefButF(block, NUM, B_BAKE_CACHE_CHANGE, "Spring Damp:", 10,130,150,20, &clmd->sim_parms->Cdis, 0.0, 50.0, 100, 0, "Damping of cloth velocity (higher = more smooth, less jiggling)");
 
5638
                uiButSetFunc(but, cloth_presets_custom_material, ob, NULL);
 
5639
 
 
5640
                uiDefButF(block, NUM, B_BAKE_CACHE_CHANGE, "Air Damp:", 160,130,150,20, &clmd->sim_parms->Cvi, 0.0, 10.0, 10, 0, "Air has normaly some thickness which slows falling things down");
 
5641
                
 
5642
                uiDefButI(block, NUM, B_BAKE_CACHE_CHANGE, "Quality:", 10,110,150,20, &clmd->sim_parms->stepsPerFrame, 4.0, 80.0, 5, 0, "Quality of the simulation (higher=better=slower)");
 
5643
                
 
5644
                uiDefButF(block, NUM, B_BAKE_CACHE_CHANGE, "Mass:", 160,110,150,20, &clmd->sim_parms->mass, 0.0, 10.0, 1000, 0, "Mass of cloth material.");
 
5645
                
 
5646
                uiDefBut(block, LABEL, 0, "Gravity:",  10,90,60,20, NULL, 0.0, 0, 0, 0, "");
 
5647
                
 
5648
                uiDefButF(block, NUM, B_BAKE_CACHE_CHANGE, "X:", 70,90,80,20, &clmd->sim_parms->gravity[0], -100.0, 100.0, 10, 0, "Apply gravitation to point movement");
 
5649
                uiDefButF(block, NUM, B_BAKE_CACHE_CHANGE, "Y:", 150,90,80,20, &clmd->sim_parms->gravity[1], -100.0, 100.0, 10, 0, "Apply gravitation to point movement");
 
5650
                uiDefButF(block, NUM, B_BAKE_CACHE_CHANGE, "Z:", 230,90,80,20, &clmd->sim_parms->gravity[2], -100.0, 100.0, 10, 0, "Apply gravitation to point movement");
 
5651
                uiBlockEndAlign(block);
 
5652
                
 
5653
                /* GOAL STUFF */
 
5654
                uiBlockBeginAlign(block);
 
5655
                
 
5656
                
 
5657
                uiDefButBitI(block, TOG, CLOTH_SIMSETTINGS_FLAG_GOAL, B_BAKE_CACHE_CHANGE, "Pinning of cloth",  10,60,150,20, &clmd->sim_parms->flags, 0, 0, 0, 0, "Define forces for vertices to stick to animated position");
 
5658
                
 
5659
                if ((clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_GOAL) && (BLI_countlist (&ob->defbase) > 0))
 
5660
                {
 
5661
                        if(ob->type==OB_MESH) 
 
5662
                        {
 
5663
                                
 
5664
                                defCount = sizeof (clmvg);
 
5665
                                clvg1 = get_vertexgroup_menustr (ob);
 
5666
                                clvg2 = MEM_callocN (strlen (clvg1) + 1 + defCount, "clothVgMS");
 
5667
                                if (! clvg2) {
 
5668
                                        printf ("draw_modifier: error allocating memory for cloth vertex group menu string.\n");
 
5669
                                        return;
 
5670
                                }
 
5671
                                defCount = BLI_countlist (&ob->defbase);
 
5672
                                if (defCount == 0) 
 
5673
                                {
 
5674
                                        clmd->sim_parms->vgroup_mass = 0;
 
5675
                                }
 
5676
                                else
 
5677
                                {
 
5678
                                        if(!clmd->sim_parms->vgroup_mass)
 
5679
                                                clmd->sim_parms->vgroup_mass = 1;
 
5680
                                        else if(clmd->sim_parms->vgroup_mass > defCount)
 
5681
                                                clmd->sim_parms->vgroup_mass = defCount;
 
5682
                                }
 
5683
                                                        
 
5684
                                sprintf (clvg2, "%s%s", clmvg, clvg1);
 
5685
                                
 
5686
                                uiDefButS(block, MENU, B_BAKE_CACHE_CHANGE, clvg2, 160,60,150,20, &clmd->sim_parms->vgroup_mass, 0, defCount, 0, 0, "Browses available vertex groups");
 
5687
                                MEM_freeN (clvg1);
 
5688
                                MEM_freeN (clvg2);
 
5689
                        }
 
5690
                        
 
5691
                        uiDefButF(block, NUM, B_BAKE_CACHE_CHANGE, "Pin Stiff:", 10,40,150,20, &clmd->sim_parms->goalspring, 0.0, 50.0, 50, 0, "Pin (vertex target position) spring stiffness");
 
5692
                        uiDefBut(block, LABEL, 0, "",160,40,150,20, NULL, 0.0, 0, 0, 0, "");    
 
5693
                        // uiDefButI(block, NUM, B_BAKE_CACHE_CHANGE, "Pin Damp:", 160,50,150,20, &clmd->sim_parms->goalfrict, 1.0, 100.0, 10, 0, "Pined damping (higher = doesn't oszilate so much)");
 
5694
                        /*
 
5695
                        // nobody is changing these ones anyway
 
5696
                        uiDefButF(block, NUM, B_BAKE_CACHE_CHANGE, "G Min:",            10,30,150,20, &clmd->sim_parms->mingoal, 0.0, 1.0, 10, 0, "Goal minimum, vertex group weights are scaled to match this range");
 
5697
                        uiDefButF(block, NUM, B_BAKE_CACHE_CHANGE, "G Max:",            160,30,150,20, &clmd->sim_parms->maxgoal, 0.0, 1.0, 10, 0, "Goal maximum, vertex group weights are scaled to match this range");
 
5698
                        */
 
5699
                }
 
5700
                else if (clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_GOAL)
 
5701
                {
 
5702
                        uiDefBut(block, LABEL, 0, " ",  160,60,150,20, NULL, 0.0, 0, 0, 0, "");
 
5703
                        uiDefBut(block, LABEL, 0, "No vertex group for pinning available.",  10,30,300,20, NULL, 0.0, 0, 0, 0, "");
 
5704
                }
 
5705
                
 
5706
                uiBlockEndAlign(block); 
 
5707
                
 
5708
                /*
 
5709
                // no tearing supported anymore since modifier stack restrictions 
 
5710
                uiBlockBeginAlign(block);
 
5711
                uiDefButBitI(block, TOG, CSIMSETT_FLAG_TEARING_ENABLED, B_EFFECT_DEP, "Tearing",        10,0,150,20, &clmd->sim_parms->flags, 0, 0, 0, 0, "Sets object to become a cloth collision object");
 
5712
                
 
5713
                if (clmd->sim_parms->flags & CSIMSETT_FLAG_TEARING_ENABLED)
 
5714
                {
 
5715
                uiDefButI(block, NUM, B_DIFF, "Max extent:",       160,0,150,20, &clmd->sim_parms->maxspringlen, 1.0, 1000.0, 10, 0, "Maximum extension before spring gets cut");
 
5716
        }
 
5717
                
 
5718
                uiBlockEndAlign(block); 
 
5719
                */
 
5720
        }
 
5721
        
 
5722
        uiBlockEndAlign(block);
 
5723
        
 
5724
        uiBlockEndAlign(block);
 
5725
}
 
5726
 
 
5727
static void object_panel_cloth_II(Object *ob)
 
5728
{
 
5729
        uiBlock *block;
 
5730
        ClothModifierData *clmd = NULL;
 
5731
        PointCache *cache;
 
5732
        static PTCacheID staticpid;
 
5733
        int libdata;
 
5734
 
 
5735
        block= uiNewBlock(&curarea->uiblocks, "object_cloth_II", UI_EMBOSS, UI_HELV, curarea->win);
 
5736
        uiNewPanelTabbed("Cloth ", "Physics");
 
5737
        if(uiNewPanel(curarea, block, "Cloth Collision", "Physics", 651, 0, 318, 204)==0) return;
 
5738
 
 
5739
        libdata= object_is_libdata(ob);
 
5740
        uiSetButLock(libdata, ERROR_LIBDATA_MESSAGE);
 
5741
        
 
5742
        clmd = (ClothModifierData *)modifiers_findByType(ob, eModifierType_Cloth);
 
5743
        
 
5744
        if(clmd)
 
5745
        {
 
5746
                BKE_ptcache_id_from_cloth(&staticpid, ob, clmd);
 
5747
                cache= staticpid.cache;
 
5748
 
 
5749
                if(!libdata) {
 
5750
                        uiClearButLock();
 
5751
                        if(cache->flag & PTCACHE_BAKE_EDIT_ACTIVE)
 
5752
                                uiSetButLock(1, "Please leave editmode.");
 
5753
                }
 
5754
 
 
5755
                object_physics_bake_buttons(block, &staticpid, 135, libdata);
 
5756
 
 
5757
                uiDefBut(block, LABEL, 0, "",10,140,300,20, NULL, 0.0, 0, 0, 0, "");
 
5758
 
 
5759
                if(!libdata) {
 
5760
                        if(!(cache->flag & PTCACHE_BAKE_EDIT_ACTIVE))
 
5761
                                if(cache->flag & PTCACHE_BAKED)
 
5762
                                        uiSetButLock(1, "Simulation frames are baked");
 
5763
                }
 
5764
                
 
5765
                /*
 
5766
                TODO: implement this again in cloth!
 
5767
                if(length>1) // B_CLOTH_CHANGEPREROLL
 
5768
                uiDefButI(block, NUM, B_CLOTH_CHANGEPREROLL, "Preroll:", 10,80,145,20, &clmd->sim_parms->preroll, 0, length-1, 1, 0, "Simulation starts on this frame");        
 
5769
                else
 
5770
                uiDefBut(block, LABEL, 0, " ",  10,80,145,20, NULL, 0.0, 0, 0, 0, "");
 
5771
                */
 
5772
#ifdef WITH_BULLET
 
5773
                uiDefButBitI(block, TOG, CLOTH_COLLSETTINGS_FLAG_ENABLED, B_BAKE_CACHE_CHANGE, "Enable collisions",     10,60,150,20, &clmd->coll_parms->flags, 0, 0, 0, 0, "Enable collisions with this object");
 
5774
                if (clmd->coll_parms->flags & CLOTH_COLLSETTINGS_FLAG_ENABLED)
 
5775
                {
 
5776
                        uiDefButF(block, NUM, B_BAKE_CACHE_CHANGE, "Min Distance:",        160,60,150,20, &clmd->coll_parms->epsilon, 0.001f, 1.0, 0.01f, 0, "Minimum distance between collision objects before collision response takes in, can be changed for each frame");
 
5777
                        uiDefButS(block, NUM, B_BAKE_CACHE_CHANGE, "Collision Quality:",           10,40,150,20, &clmd->coll_parms->loop_count, 1.0, 20.0, 1.0, 0, "How many collision iterations should be done. (higher = better = slower)");
 
5778
                        uiDefButF(block, NUM, B_BAKE_CACHE_CHANGE, "Friction:",    160,40,150,20, &clmd->coll_parms->friction, 0.0, 80.0, 1.0, 0, "Friction force if a collision happened (0=movement not changed, 100=no movement left)");
 
5779
                        
 
5780
                        uiDefButBitI(block, TOG, CLOTH_COLLSETTINGS_FLAG_SELF, B_BAKE_CACHE_CHANGE, "Enable selfcollisions",    10,20,150,20, &clmd->coll_parms->flags, 0, 0, 0, 0, "Enable selfcollisions with this object");
 
5781
                        if (clmd->coll_parms->flags & CLOTH_COLLSETTINGS_FLAG_SELF)     
 
5782
                        {
 
5783
                                uiDefButF(block, NUM, B_BAKE_CACHE_CHANGE, "Min Distance:",        160,20,150,20, &clmd->coll_parms->selfepsilon, 0.5f, 1.0, 0.01f, 0, "0.5 means no distance at all, 1.0 is maximum distance");
 
5784
                                // self_loop_count
 
5785
                                uiDefButS(block, NUM, B_BAKE_CACHE_CHANGE, "Selfcoll Quality:",    10,0,150,20, &clmd->coll_parms->self_loop_count, 1.0, 10.0, 1.0, 0, "How many selfcollision iterations should be done. (higher = better = slower), can be changed for each frame");
 
5786
                        }
 
5787
                        else
 
5788
                                uiDefBut(block, LABEL, 0, "",160,20,150,20, NULL, 0.0, 0, 0, 0, "");    
 
5789
                }
 
5790
                else
 
5791
                        uiDefBut(block, LABEL, 0, "",160,60,150,20, NULL, 0.0, 0, 0, 0, "");    
 
5792
#else
 
5793
                uiDefBut(block, LABEL, 0, "No collisions available (compile with bullet).",10,60,300,20, NULL, 0.0, 0, 0, 0, "");
 
5794
#endif
 
5795
        }
 
5796
        
 
5797
        uiBlockEndAlign(block);
 
5798
        
 
5799
}
 
5800
 
 
5801
static void object_panel_cloth_III(Object *ob)
 
5802
{
 
5803
        uiBlock *block;
 
5804
        ClothModifierData *clmd = NULL;
 
5805
        PointCache *cache;
 
5806
        int libdata;
 
5807
 
 
5808
        block= uiNewBlock(&curarea->uiblocks, "object_cloth_III", UI_EMBOSS, UI_HELV, curarea->win);
 
5809
        uiNewPanelTabbed("Cloth ", "Physics");
 
5810
        if(uiNewPanel(curarea, block, "Cloth Advanced", "Physics", 651, 0, 318, 204)==0) return;
 
5811
 
 
5812
        libdata= object_is_libdata(ob);
 
5813
        uiSetButLock(libdata, ERROR_LIBDATA_MESSAGE);
 
5814
        
 
5815
        clmd = (ClothModifierData *)modifiers_findByType(ob, eModifierType_Cloth);
 
5816
        
 
5817
        if(clmd)
 
5818
        {
 
5819
                int defCount;
 
5820
                char *clvg1, *clvg2;
 
5821
                char clmvg [] = "Vertex Groups%t|None%x0|";
 
5822
                char clmvg2 [] = "Vertex Groups%t|None%x0|";
 
5823
 
 
5824
                cache= clmd->point_cache;
 
5825
                
 
5826
                if(!libdata) {
 
5827
                        uiClearButLock();
 
5828
                        if(cache->flag & PTCACHE_BAKE_EDIT_ACTIVE)
 
5829
                                uiSetButLock(1, "Please leave editmode.");
 
5830
                        else if(cache->flag & PTCACHE_BAKED)
 
5831
                                uiSetButLock(1, "Simulation frames are baked");
 
5832
                }
 
5833
                
 
5834
                uiDefButBitI(block, TOG, CLOTH_SIMSETTINGS_FLAG_SCALING, B_BAKE_CACHE_CHANGE, "Enable stiffness scaling",10,130,300,20, &clmd->sim_parms->flags, 0, 0, 0, 0, "If enabled, stiffness can be scaled along a weight painted vertex group.");
 
5835
                
 
5836
                if ((clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_SCALING)&& (BLI_countlist (&ob->defbase) > 0))
 
5837
                {       
 
5838
                        uiDefBut(block, LABEL, 0, "StructStiff VGroup:",10,110,150,20, NULL, 0.0, 0, 0, 0, "");
 
5839
                        uiDefBut(block, LABEL, 0, "BendStiff VGroup:",160,110,150,20, NULL, 0.0, 0, 0, 0, "");
 
5840
                        
 
5841
                        defCount = sizeof (clmvg);
 
5842
                        clvg1 = get_vertexgroup_menustr (ob);
 
5843
                        clvg2 = MEM_callocN (strlen (clvg1) + 1 + defCount, "clothVgST");
 
5844
                        if (! clvg2) {
 
5845
                                printf ("draw_modifier: error allocating memory for cloth vertex group menu string.\n");
 
5846
                                return;
 
5847
                        }
 
5848
                        defCount = BLI_countlist (&ob->defbase);
 
5849
                        if (defCount == 0) 
 
5850
                        {
 
5851
                                clmd->sim_parms->vgroup_struct = 0;
 
5852
                        }
 
5853
                        else
 
5854
                        {
 
5855
                                if(clmd->sim_parms->vgroup_struct > defCount)
 
5856
                                        clmd->sim_parms->vgroup_struct = 0;
 
5857
                        }
 
5858
                                                
 
5859
                        sprintf (clvg2, "%s%s", clmvg, clvg1);
 
5860
                        
 
5861
                        uiDefButS(block, MENU, B_BAKE_CACHE_CHANGE, clvg2,      10,90,150,20, &clmd->sim_parms->vgroup_struct, 0, defCount, 0, 0, "Browses available vertex groups");
 
5862
                        MEM_freeN (clvg1);
 
5863
                        MEM_freeN (clvg2);
 
5864
                        
 
5865
                        defCount = sizeof (clmvg);
 
5866
                        clvg1 = get_vertexgroup_menustr (ob);
 
5867
                        clvg2 = MEM_callocN (strlen (clvg1) + 1 + defCount, "clothVgBD");
 
5868
                        if (! clvg2) {
 
5869
                                printf ("draw_modifier: error allocating memory for cloth vertex group menu string.\n");
 
5870
                                return;
 
5871
                        }
 
5872
                        defCount = BLI_countlist (&ob->defbase);
 
5873
                        if (defCount == 0) 
 
5874
                        {
 
5875
                                clmd->sim_parms->vgroup_bend = 0;
 
5876
                        }
 
5877
                        else
 
5878
                        {
 
5879
                                if(clmd->sim_parms->vgroup_bend > defCount)
 
5880
                                        clmd->sim_parms->vgroup_bend = 0;
 
5881
                        }
 
5882
                                                
 
5883
                        sprintf (clvg2, "%s%s", clmvg2, clvg1);
 
5884
                        
 
5885
                        uiDefButS(block, MENU, B_BAKE_CACHE_CHANGE, clvg2, 160,90,150,20, &clmd->sim_parms->vgroup_bend, 0, defCount, 0, 0, "Browses available vertex groups");
 
5886
                        MEM_freeN (clvg1);
 
5887
                        MEM_freeN (clvg2);
 
5888
                        
 
5889
                        uiDefButF(block, NUM, B_BAKE_CACHE_CHANGE, "StructStiff Max:",10,70,150,20, &clmd->sim_parms->max_struct, clmd->sim_parms->structural, 10000.0, 0.01f, 0, "Maximum structural stiffness value");
 
5890
                        
 
5891
                        uiDefButF(block, NUM, B_BAKE_CACHE_CHANGE, "BendStiff Max:",160,70,150,20, &clmd->sim_parms->max_bend, clmd->sim_parms->bending, 10000.0, 0.01f, 0, "Maximum bending stiffness value");
 
5892
 
 
5893
                }
 
5894
                else if (clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_SCALING)
 
5895
                {
 
5896
                        uiDefBut(block, LABEL, 0, " ",  10,110,300,20, NULL, 0.0, 0, 0, 0, "");
 
5897
                        uiDefBut(block, LABEL, 0, "No vertex group for stiffness scaling available.",  10,90,300,20, NULL, 0.0, 0, 0, 0, "");
 
5898
                }
 
5899
        
 
5900
                
 
5901
                
 
5902
        }
 
5903
        
 
5904
        uiBlockEndAlign(block);
 
5905
        
 
5906
}
 
5907
 
 
5908
void object_panels()
 
5909
{
 
5910
        Object *ob;
 
5911
 
 
5912
        /* check context here */
 
5913
        ob= OBACT;
 
5914
        if(ob) {
 
5915
                object_panel_object(ob);
 
5916
                object_panel_anim(ob);
 
5917
                object_panel_draw(ob);
 
5918
                object_panel_constraint("Object");
 
5919
 
 
5920
                uiClearButLock();
 
5921
        }
 
5922
}
 
5923
 
 
5924
void physics_panels()
 
5925
{
 
5926
        Object *ob;
 
5927
        
 
5928
        /* check context here */
 
5929
        ob= OBACT;
 
5930
        if(ob) {
 
5931
                object_panel_fields(ob);
 
5932
                if(ob->type==OB_MESH)
 
5933
                        object_panel_collision(ob);
 
5934
                object_softbodies(ob);
 
5935
                object_softbodies_collision(ob);
 
5936
                object_softbodies_solver(ob);
 
5937
                object_panel_cloth(ob);
 
5938
                object_panel_cloth_II(ob);
 
5939
                object_panel_cloth_III(ob);
 
5940
                object_panel_fluidsim(ob);
 
5941
        }
 
5942
}
 
5943
void particle_panels()
 
5944
{
 
5945
        Object *ob;
 
5946
        ParticleSystem *psys;
 
5947
 
 
5948
        ob=OBACT;
 
5949
 
 
5950
        if(ob && ob->type==OB_MESH) {
 
5951
                object_panel_particle_system(ob);
 
5952
 
 
5953
                psys=psys_get_current(ob);
 
5954
 
 
5955
                if(psys ){
 
5956
                        object_panel_particle_bake(ob);
 
5957
                        object_panel_particle_physics(ob);
 
5958
                        object_panel_particle_visual(ob);
 
5959
                        object_panel_particle_simplification(ob);
 
5960
                        object_panel_particle_extra(ob);
 
5961
                        object_panel_particle_children(ob);
 
5962
                }
 
5963
        }
 
5964
}