413cb79c7cc10d69343b86bfbcd5b8c3c1758a50
[blender-staging.git] / source / blender / editors / space_view3d / view3d_buttons.c
1 /**
2  * $Id:
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) 2009 Blender Foundation.
21  * All rights reserved.
22  *
23  * 
24  * Contributor(s): Blender Foundation
25  *
26  * ***** END GPL LICENSE BLOCK *****
27  */
28
29 #include <string.h>
30 #include <stdio.h>
31 #include <math.h>
32 #include <float.h>
33
34 #include "DNA_action_types.h"
35 #include "DNA_armature_types.h"
36 #include "DNA_curve_types.h"
37 #include "DNA_camera_types.h"
38 #include "DNA_lamp_types.h"
39 #include "DNA_lattice_types.h"
40 #include "DNA_meta_types.h"
41 #include "DNA_mesh_types.h"
42 #include "DNA_meshdata_types.h"
43 #include "DNA_object_types.h"
44 #include "DNA_space_types.h"
45 #include "DNA_scene_types.h"
46 #include "DNA_screen_types.h"
47 #include "DNA_userdef_types.h"
48 #include "DNA_view3d_types.h"
49 #include "DNA_world_types.h"
50
51 #include "MEM_guardedalloc.h"
52
53 #include "BLI_arithb.h"
54 #include "BLI_blenlib.h"
55 #include "BLI_editVert.h"
56 #include "BLI_rand.h"
57
58 #include "BKE_action.h"
59 #include "BKE_brush.h"
60 #include "BKE_context.h"
61 #include "BKE_curve.h"
62 #include "BKE_customdata.h"
63 #include "BKE_depsgraph.h"
64 #include "BKE_object.h"
65 #include "BKE_global.h"
66 #include "BKE_scene.h"
67 #include "BKE_screen.h"
68 #include "BKE_utildefines.h"
69
70 #include "BIF_gl.h"
71 #include "BIF_transform.h"
72
73 #include "WM_api.h"
74 #include "WM_types.h"
75
76 #include "RNA_access.h"
77 #include "RNA_define.h"
78
79 #include "ED_armature.h"
80 #include "ED_curve.h"
81 #include "ED_image.h"
82 #include "ED_keyframing.h"
83 #include "ED_mesh.h"
84 #include "ED_object.h"
85 #include "ED_particle.h"
86 #include "ED_screen.h"
87 #include "ED_types.h"
88 #include "ED_util.h"
89
90 #include "UI_interface.h"
91 #include "UI_resources.h"
92 #include "UI_view2d.h"
93
94 #include "view3d_intern.h"      // own include
95
96
97 /* ******************* view3d space & buttons ************** */
98 #define B_NOP           1
99 #define B_REDR          2
100 #define B_OBJECTPANELROT        1007
101 #define B_OBJECTPANELMEDIAN 1008
102 #define B_ARMATUREPANEL1        1009
103 #define B_ARMATUREPANEL2        1010
104 #define B_OBJECTPANELPARENT 1011
105 #define B_OBJECTPANEL           1012
106 #define B_ARMATUREPANEL3        1013
107 #define B_OBJECTPANELSCALE      1014
108 #define B_OBJECTPANELDIMS       1015
109 #define B_TRANSFORMSPACEADD     1016
110 #define B_TRANSFORMSPACECLEAR   1017
111 #define B_SETPT_AUTO    2125
112 #define B_SETPT_VECTOR  2126
113 #define B_SETPT_ALIGN   2127
114 #define B_SETPT_FREE    2128
115 #define B_RECALCMBALL   2501
116
117 #define B_WEIGHT0_0             2840
118 #define B_WEIGHT1_4             2841
119 #define B_WEIGHT1_2             2842
120 #define B_WEIGHT3_4             2843
121 #define B_WEIGHT1_0             2844
122
123 #define B_OPA1_8                2845
124 #define B_OPA1_4                2846
125 #define B_OPA1_2                2847
126 #define B_OPA3_4                2848
127 #define B_OPA1_0                2849
128
129 #define B_CLR_WPAINT    2850
130
131 #define B_RV3D_LOCKED   2900
132 #define B_RV3D_BOXVIEW  2901
133 #define B_RV3D_BOXCLIP  2902
134
135 #define B_IDNAME                3000
136
137 /* temporary struct for storing transform properties */
138 typedef struct {
139         float ob_eul[4];        // used for quat too....
140         float ob_scale[3]; // need temp space due to linked values
141         float ob_dims[3];
142         short link_scale;
143         float ve_median[5];
144         int curdef;
145         float *defweightp;
146 } TransformProperties;
147
148
149 /* is used for both read and write... */
150 static void v3d_editvertex_buts(const bContext *C, uiBlock *block, View3D *v3d, Object *ob, float lim)
151 {
152         MDeformVert *dvert=NULL;
153         TransformProperties *tfp= v3d->properties_storage;
154         float median[5], ve_median[5];
155         int tot, totw, totweight, totedge;
156         char defstr[320];
157         
158         median[0]= median[1]= median[2]= median[3]= median[4]= 0.0;
159         tot= totw= totweight= totedge= 0;
160         defstr[0]= 0;
161
162         if(ob->type==OB_MESH) {
163                 Mesh *me= ob->data;
164                 EditMesh *em = me->edit_mesh;
165                 EditVert *eve, *evedef=NULL;
166                 EditEdge *eed;
167                 
168                 eve= em->verts.first;
169                 while(eve) {
170                         if(eve->f & SELECT) {
171                                 evedef= eve;
172                                 tot++;
173                                 VecAddf(median, median, eve->co);
174                         }
175                         eve= eve->next;
176                 }
177                 eed= em->edges.first;
178                 while(eed) {
179                         if((eed->f & SELECT)) {
180                                 totedge++;
181                                 median[3]+= eed->crease;
182                         }
183                         eed= eed->next;
184                 }
185
186                 /* check for defgroups */
187                 if(evedef)
188                         dvert= CustomData_em_get(&em->vdata, evedef->data, CD_MDEFORMVERT);
189                 if(tot==1 && dvert && dvert->totweight) {
190                         bDeformGroup *dg;
191                         int i, max=1, init=1;
192                         char str[320];
193                         
194                         for (i=0; i<dvert->totweight; i++){
195                                 dg = BLI_findlink (&ob->defbase, dvert->dw[i].def_nr);
196                                 if(dg) {
197                                         max+= BLI_snprintf(str, sizeof(str), "%s %%x%d|", dg->name, dvert->dw[i].def_nr); 
198                                         if(max<320) strcat(defstr, str);
199                                 }
200                                 else printf("oh no!\n");
201                                 if(tfp->curdef==dvert->dw[i].def_nr) {
202                                         init= 0;
203                                         tfp->defweightp= &dvert->dw[i].weight;
204                                 }
205                         }
206                         
207                         if(init) {      // needs new initialized 
208                                 tfp->curdef= dvert->dw[0].def_nr;
209                                 tfp->defweightp= &dvert->dw[0].weight;
210                         }
211                 }
212         }
213         else if(ob->type==OB_CURVE || ob->type==OB_SURF) {
214                 Curve *cu= ob->data;
215                 Nurb *nu;
216                 BPoint *bp;
217                 BezTriple *bezt;
218                 int a;
219                 
220                 nu= cu->editnurb->first;
221                 while(nu) {
222                         if((nu->type & 7)==CU_BEZIER) {
223                                 bezt= nu->bezt;
224                                 a= nu->pntsu;
225                                 while(a--) {
226                                         if(bezt->f2 & SELECT) {
227                                                 VecAddf(median, median, bezt->vec[1]);
228                                                 tot++;
229                                                 median[4]+= bezt->weight;
230                                                 totweight++;
231                                         }
232                                         else {
233                                                 if(bezt->f1 & SELECT) {
234                                                         VecAddf(median, median, bezt->vec[0]);
235                                                         tot++;
236                                                 }
237                                                 if(bezt->f3 & SELECT) {
238                                                         VecAddf(median, median, bezt->vec[2]);
239                                                         tot++;
240                                                 }
241                                         }
242                                         bezt++;
243                                 }
244                         }
245                         else {
246                                 bp= nu->bp;
247                                 a= nu->pntsu*nu->pntsv;
248                                 while(a--) {
249                                         if(bp->f1 & SELECT) {
250                                                 VecAddf(median, median, bp->vec);
251                                                 median[3]+= bp->vec[3];
252                                                 totw++;
253                                                 tot++;
254                                                 median[4]+= bp->weight;
255                                                 totweight++;
256                                         }
257                                         bp++;
258                                 }
259                         }
260                         nu= nu->next;
261                 }
262         }
263         else if(ob->type==OB_LATTICE) {
264                 Lattice *lt= ob->data;
265                 BPoint *bp;
266                 int a;
267                 
268                 a= lt->editlatt->pntsu*lt->editlatt->pntsv*lt->editlatt->pntsw;
269                 bp= lt->editlatt->def;
270                 while(a--) {
271                         if(bp->f1 & SELECT) {
272                                 VecAddf(median, median, bp->vec);
273                                 tot++;
274                                 median[4]+= bp->weight;
275                                 totweight++;
276                         }
277                         bp++;
278                 }
279         }
280         
281         if(tot==0) return;
282
283         median[0] /= (float)tot;
284         median[1] /= (float)tot;
285         median[2] /= (float)tot;
286         if(totedge) median[3] /= (float)totedge;
287         else if(totw) median[3] /= (float)totw;
288         if(totweight) median[4] /= (float)totweight;
289         
290         if(v3d->flag & V3D_GLOBAL_STATS)
291                 Mat4MulVecfl(ob->obmat, median);
292         
293         if(block) {     // buttons
294                 int but_y;
295                 if((ob->parent) && (ob->partype == PARBONE))    but_y = 135;
296                 else                                                                                    but_y = 150;
297                 
298                 uiBlockBeginAlign(block);
299                 uiDefButBitS(block, TOG, V3D_GLOBAL_STATS, B_REDR, "Global",            160, but_y, 70, 19, &v3d->flag, 0, 0, 0, 0, "Displays global values");
300                 uiDefButBitS(block, TOGN, V3D_GLOBAL_STATS, B_REDR, "Local",            230, but_y, 70, 19, &v3d->flag, 0, 0, 0, 0, "Displays local values");
301                 uiBlockEndAlign(block);
302                 
303                 memcpy(tfp->ve_median, median, sizeof(tfp->ve_median));
304                 
305                 uiBlockBeginAlign(block);
306                 if(tot==1) {
307                         uiDefButF(block, NUM, B_OBJECTPANELMEDIAN, "Vertex X:", 10, 110, 290, 19, &(tfp->ve_median[0]), -lim, lim, 10, 3, "");
308                         uiDefButF(block, NUM, B_OBJECTPANELMEDIAN, "Vertex Y:", 10, 90, 290, 19, &(tfp->ve_median[1]), -lim, lim, 10, 3, "");
309                         uiDefButF(block, NUM, B_OBJECTPANELMEDIAN, "Vertex Z:", 10, 70, 290, 19, &(tfp->ve_median[2]), -lim, lim, 10, 3, "");
310                         if(totw==1)
311                                 uiDefButF(block, NUM, B_OBJECTPANELMEDIAN, "Vertex W:", 10, 50, 290, 19, &(tfp->ve_median[3]), 0.01, 100.0, 10, 3, "");
312                         uiBlockEndAlign(block);
313         
314                         if(defstr[0]) {
315                                 uiDefBut(block, LABEL, 1, "Vertex Deform Groups",               10, 40, 290, 20, NULL, 0.0, 0.0, 0, 0, "");
316
317                                 uiBlockBeginAlign(block);
318                                 uiDefButF(block, NUM, B_NOP, "Weight:",                 10, 20, 150, 19, tfp->defweightp, 0.0f, 1.0f, 10, 3, "Weight value");
319                                 uiDefButI(block, MENU, B_REDR, defstr,  160, 20, 140, 19, &tfp->curdef, 0.0, 0.0, 0, 0, "Current Vertex Group");
320                                 uiBlockEndAlign(block);
321                         }
322                         else if(totweight)
323                                 uiDefButF(block, NUM, B_OBJECTPANELMEDIAN, "Weight:",   10, 20, 290, 19, &(tfp->ve_median[4]), 0.0, 1.0, 10, 3, "");
324
325                 }
326                 else {
327                         uiDefButF(block, NUM, B_OBJECTPANELMEDIAN, "Median X:", 10, 110, 290, 19, &(tfp->ve_median[0]), -lim, lim, 10, 3, "");
328                         uiDefButF(block, NUM, B_OBJECTPANELMEDIAN, "Median Y:", 10, 90, 290, 19, &(tfp->ve_median[1]), -lim, lim, 10, 3, "");
329                         uiDefButF(block, NUM, B_OBJECTPANELMEDIAN, "Median Z:", 10, 70, 290, 19, &(tfp->ve_median[2]), -lim, lim, 10, 3, "");
330                         if(totw==tot)
331                                 uiDefButF(block, NUM, B_OBJECTPANELMEDIAN, "Median W:", 10, 50, 290, 19, &(tfp->ve_median[3]), 0.01, 100.0, 10, 3, "");
332                         uiBlockEndAlign(block);
333                         if(totweight)
334                                 uiDefButF(block, NUM, B_OBJECTPANELMEDIAN, "Weight:",   10, 20, 290, 19, &(tfp->ve_median[4]), 0.0, 1.0, 10, 3, "Weight is used for SoftBody Goal");
335                 }
336                 
337                 if(ob->type==OB_CURVE && (totw==0)) { /* bez curves have no w */
338                         uiBlockBeginAlign(block);
339                         uiDefBut(block, BUT,B_SETPT_AUTO,"Auto",        10, 44, 72, 19, 0, 0, 0, 0, 0, "Auto handles (Shift H)");
340                         uiDefBut(block, BUT,B_SETPT_VECTOR,"Vector",82, 44, 73, 19, 0, 0, 0, 0, 0, "Vector handles (V)");
341                         uiDefBut(block, BUT,B_SETPT_ALIGN,"Align",155, 44, 73, 19, 0, 0, 0, 0, 0, "Align handles (H Toggles)");
342                         uiDefBut(block, BUT,B_SETPT_FREE,"Free",        227, 44, 72, 19, 0, 0, 0, 0, 0, "Align handles (H Toggles)");
343                         uiBlockEndAlign(block);
344                 }
345                 
346                 if(totedge==1)
347                         uiDefButF(block, NUM, B_OBJECTPANELMEDIAN, "Crease W:", 10, 30, 290, 19, &(tfp->ve_median[3]), 0.0, 1.0, 10, 3, "");
348                 else if(totedge>1)
349                         uiDefButF(block, NUM, B_OBJECTPANELMEDIAN, "Median Crease W:",  10, 30, 290, 19, &(tfp->ve_median[3]), 0.0, 1.0, 10, 3, "");
350                 
351         }
352         else {  // apply
353                 memcpy(ve_median, tfp->ve_median, sizeof(tfp->ve_median));
354                 
355                 if(v3d->flag & V3D_GLOBAL_STATS) {
356                         Mat4Invert(ob->imat, ob->obmat);
357                         Mat4MulVecfl(ob->imat, median);
358                         Mat4MulVecfl(ob->imat, ve_median);
359                 }
360                 VecSubf(median, ve_median, median);
361                 median[3]= ve_median[3]-median[3];
362                 median[4]= ve_median[4]-median[4];
363                 
364                 if(ob->type==OB_MESH) {
365                         Mesh *me= ob->data;
366                         EditMesh *em = me->edit_mesh;
367                         EditVert *eve;
368                         EditEdge *eed;
369                         
370                         eve= em->verts.first;
371                         while(eve) {
372                                 if(eve->f & SELECT) {
373                                         VecAddf(eve->co, eve->co, median);
374                                 }
375                                 eve= eve->next;
376                         }
377                         
378                         for(eed= em->edges.first; eed; eed= eed->next) {
379                                 if(eed->f & SELECT) {
380                                         /* ensure the median can be set to zero or one */
381                                         if(ve_median[3]==0.0f) eed->crease= 0.0f;
382                                         else if(ve_median[3]==1.0f) eed->crease= 1.0f;
383                                         else {
384                                                 eed->crease+= median[3];
385                                                 CLAMP(eed->crease, 0.0, 1.0);
386                                         }
387                                 }
388                         }
389                         
390                         recalc_editnormals(em);
391                 }
392                 else if(ob->type==OB_CURVE || ob->type==OB_SURF) {
393                         Curve *cu= ob->data;
394                         Nurb *nu;
395                         BPoint *bp;
396                         BezTriple *bezt;
397                         int a;
398                         
399                         nu= cu->editnurb->first;
400                         while(nu) {
401                                 if((nu->type & 7)==1) {
402                                         bezt= nu->bezt;
403                                         a= nu->pntsu;
404                                         while(a--) {
405                                                 if(bezt->f2 & SELECT) {
406                                                         VecAddf(bezt->vec[0], bezt->vec[0], median);
407                                                         VecAddf(bezt->vec[1], bezt->vec[1], median);
408                                                         VecAddf(bezt->vec[2], bezt->vec[2], median);
409                                                         bezt->weight+= median[4];
410                                                 }
411                                                 else {
412                                                         if(bezt->f1 & SELECT) {
413                                                                 VecAddf(bezt->vec[0], bezt->vec[0], median);
414                                                         }
415                                                         if(bezt->f3 & SELECT) {
416                                                                 VecAddf(bezt->vec[2], bezt->vec[2], median);
417                                                         }
418                                                 }
419                                                 bezt++;
420                                         }
421                                 }
422                                 else {
423                                         bp= nu->bp;
424                                         a= nu->pntsu*nu->pntsv;
425                                         while(a--) {
426                                                 if(bp->f1 & SELECT) {
427                                                         VecAddf(bp->vec, bp->vec, median);
428                                                         bp->vec[3]+= median[3];
429                                                         bp->weight+= median[4];
430                                                 }
431                                                 bp++;
432                                         }
433                                 }
434                                 test2DNurb(nu);
435                                 testhandlesNurb(nu); /* test for bezier too */
436
437                                 nu= nu->next;
438                         }
439                 }
440                 else if(ob->type==OB_LATTICE) {
441                         Lattice *lt= ob->data;
442                         BPoint *bp;
443                         int a;
444                         
445                         a= lt->editlatt->pntsu*lt->editlatt->pntsv*lt->editlatt->pntsw;
446                         bp= lt->editlatt->def;
447                         while(a--) {
448                                 if(bp->f1 & SELECT) {
449                                         VecAddf(bp->vec, bp->vec, median);
450                                         bp->weight+= median[4];
451                                 }
452                                 bp++;
453                         }
454                 }
455                 
456 //              ED_undo_push(C, "Transform properties");
457         }
458 }
459
460 /* assumes armature active */
461 static void validate_bonebutton_cb(bContext *C, void *bonev, void *namev)
462 {
463         Object *ob= CTX_data_active_object(C);
464         
465         if(ob && ob->type==OB_ARMATURE) {
466                 Bone *bone= bonev;
467                 char oldname[32], newname[32];
468                 
469                 /* need to be on the stack */
470                 BLI_strncpy(newname, bone->name, 32);
471                 BLI_strncpy(oldname, (char *)namev, 32);
472                 /* restore */
473                 BLI_strncpy(bone->name, oldname, 32);
474                 
475                 armature_bone_rename(ob, oldname, newname); // editarmature.c
476         }
477 }
478
479 static void v3d_posearmature_buts(uiBlock *block, View3D *v3d, Object *ob, float lim)
480 {
481         uiBut *but;
482         bArmature *arm;
483         bPoseChannel *pchan;
484         Bone *bone= NULL;
485         TransformProperties *tfp= v3d->properties_storage;
486
487         arm = ob->data;
488         if (!arm || !ob->pose) return;
489
490         for(pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) {
491                 bone = pchan->bone;
492                 if(bone && (bone->flag & BONE_ACTIVE) && (bone->layer & arm->layer))
493                         break;
494         }
495         if (!pchan || !bone) return;
496
497         if((ob->parent) && (ob->partype == PARBONE))
498                 but= uiDefBut (block, TEX, B_NOP, "Bone:",                              160, 130, 140, 19, bone->name, 1, 31, 0, 0, "");
499         else
500                 but= uiDefBut(block, TEX, B_NOP, "Bone:",                               160, 140, 140, 19, bone->name, 1, 31, 0, 0, "");
501         uiButSetFunc(but, validate_bonebutton_cb, bone, NULL);
502         uiButSetCompleteFunc(but, autocomplete_bone, (void *)ob);
503
504         QuatToEul(pchan->quat, tfp->ob_eul);
505         tfp->ob_eul[0]*= 180.0/M_PI;
506         tfp->ob_eul[1]*= 180.0/M_PI;
507         tfp->ob_eul[2]*= 180.0/M_PI;
508         
509         uiBlockBeginAlign(block);
510         uiDefIconButBitS(block, ICONTOG, OB_LOCK_LOCX, B_REDR, ICON_UNLOCKED,   10,140,20,19, &(pchan->protectflag), 0, 0, 0, 0, "Protects this value from being Transformed");
511         uiDefButF(block, NUM, B_ARMATUREPANEL2, "LocX:",        30, 140, 120, 19, pchan->loc, -lim, lim, 100, 3, "");
512         uiDefIconButBitS(block, ICONTOG, OB_LOCK_LOCY, B_REDR, ICON_UNLOCKED,   10,120,20,19, &(pchan->protectflag), 0, 0, 0, 0, "Protects this value from being Transformed");
513         uiDefButF(block, NUM, B_ARMATUREPANEL2, "LocY:",        30, 120, 120, 19, pchan->loc+1, -lim, lim, 100, 3, "");
514         uiDefIconButBitS(block, ICONTOG, OB_LOCK_LOCZ, B_REDR, ICON_UNLOCKED,   10,100,20,19, &(pchan->protectflag), 0, 0, 0, 0, "Protects this value from being Transformed");
515         uiDefButF(block, NUM, B_ARMATUREPANEL2, "LocZ:",        30, 100, 120, 19, pchan->loc+2, -lim, lim, 100, 3, "");
516
517         uiBlockBeginAlign(block);
518         uiDefIconButBitS(block, ICONTOG, OB_LOCK_ROTX, B_REDR, ICON_UNLOCKED,   10,70,20,19, &(pchan->protectflag), 0, 0, 0, 0, "Protects this value from being Transformed");
519         uiDefButF(block, NUM, B_ARMATUREPANEL3, "RotX:",        30, 70, 120, 19, tfp->ob_eul, -1000.0, 1000.0, 100, 3, "");
520         uiDefIconButBitS(block, ICONTOG, OB_LOCK_ROTY, B_REDR, ICON_UNLOCKED,   10,50,20,19, &(pchan->protectflag), 0, 0, 0, 0, "Protects this value from being Transformed");
521         uiDefButF(block, NUM, B_ARMATUREPANEL3, "RotY:",        30, 50, 120, 19, tfp->ob_eul+1, -1000.0, 1000.0, 100, 3, "");
522         uiDefIconButBitS(block, ICONTOG, OB_LOCK_ROTZ, B_REDR, ICON_UNLOCKED,   10,30,20,19, &(pchan->protectflag), 0, 0, 0, 0, "Protects this value from being Transformed");
523         uiDefButF(block, NUM, B_ARMATUREPANEL3, "RotZ:",        30, 30, 120, 19, tfp->ob_eul+2, -1000.0, 1000.0, 100, 3, "");
524         
525         uiBlockBeginAlign(block);
526         uiDefIconButBitS(block, ICONTOG, OB_LOCK_SCALEX, B_REDR, ICON_UNLOCKED, 160,70,20,19, &(pchan->protectflag), 0, 0, 0, 0, "Protects this value from being Transformed");
527         uiDefButF(block, NUM, B_ARMATUREPANEL2, "ScaleX:",      180, 70, 120, 19, pchan->size, -lim, lim, 10, 3, "");
528         uiDefIconButBitS(block, ICONTOG, OB_LOCK_SCALEY, B_REDR, ICON_UNLOCKED, 160,50,20,19, &(pchan->protectflag), 0, 0, 0, 0, "Protects this value from being Transformed");
529         uiDefButF(block, NUM, B_ARMATUREPANEL2, "ScaleY:",      180, 50, 120, 19, pchan->size+1, -lim, lim, 10, 3, "");
530         uiDefIconButBitS(block, ICONTOG, OB_LOCK_SCALEZ, B_REDR, ICON_UNLOCKED, 160,30,20,19, &(pchan->protectflag), 0, 0, 0, 0, "Protects this value from being Transformed");
531         uiDefButF(block, NUM, B_ARMATUREPANEL2, "ScaleZ:",      180, 30, 120, 19, pchan->size+2, -lim, lim, 10, 3, "");
532         uiBlockEndAlign(block);
533 }
534
535 /* assumes armature editmode */
536 void validate_editbonebutton_cb(bContext *C, void *bonev, void *namev)
537 {
538         EditBone *eBone= bonev;
539         char oldname[32], newname[32];
540         
541         /* need to be on the stack */
542         BLI_strncpy(newname, eBone->name, 32);
543         BLI_strncpy(oldname, (char *)namev, 32);
544         /* restore */
545         BLI_strncpy(eBone->name, oldname, 32);
546         
547         armature_bone_rename(CTX_data_edit_object(C), oldname, newname); // editarmature.c
548         WM_event_add_notifier(C, NC_OBJECT|ND_BONE_SELECT, CTX_data_edit_object(C)); // XXX fix
549 }
550
551 static void v3d_editarmature_buts(uiBlock *block, View3D *v3d, Object *ob, float lim)
552 {
553         bArmature *arm= ob->data;
554         EditBone *ebone;
555         uiBut *but;
556         TransformProperties *tfp= v3d->properties_storage;
557         
558         ebone= arm->edbo->first;
559
560         for (ebone = arm->edbo->first; ebone; ebone=ebone->next){
561                 if ((ebone->flag & BONE_ACTIVE) && (ebone->layer & arm->layer))
562                         break;
563         }
564
565         if (!ebone)
566                 return;
567         
568         if((ob->parent) && (ob->partype == PARBONE))
569                 but= uiDefBut(block, TEX, B_NOP, "Bone:", 160, 130, 140, 19, ebone->name, 1, 31, 0, 0, "");
570         else
571                 but= uiDefBut(block, TEX, B_NOP, "Bone:",                       160, 150, 140, 19, ebone->name, 1, 31, 0, 0, "");
572         uiButSetFunc(but, validate_editbonebutton_cb, ebone, NULL);
573
574         uiBlockBeginAlign(block);
575         uiDefButF(block, NUM, B_ARMATUREPANEL1, "HeadX:",       10, 70, 140, 19, ebone->head, -lim, lim, 10, 3, "");
576         uiDefButF(block, NUM, B_ARMATUREPANEL1, "HeadY:",       10, 50, 140, 19, ebone->head+1, -lim, lim, 10, 3, "");
577         uiDefButF(block, NUM, B_ARMATUREPANEL1, "HeadZ:",       10, 30, 140, 19, ebone->head+2, -lim, lim, 10, 3, "");
578         uiBlockBeginAlign(block);
579         uiDefButF(block, NUM, B_ARMATUREPANEL1, "TailX:",       160, 70, 140, 19, ebone->tail, -lim, lim, 10, 3, "");
580         uiDefButF(block, NUM, B_ARMATUREPANEL1, "TailY:",       160, 50, 140, 19, ebone->tail+1, -lim, lim, 10, 3, "");
581         uiDefButF(block, NUM, B_ARMATUREPANEL1, "TailZ:",       160, 30, 140, 19, ebone->tail+2, -lim, lim, 10, 3, "");
582         uiBlockEndAlign(block);
583         
584         tfp->ob_eul[0]= 180.0*ebone->roll/M_PI;
585         uiDefButF(block, NUM, B_ARMATUREPANEL1, "Roll:",        10, 100, 140, 19, tfp->ob_eul, -lim, lim, 1000, 3, "");
586
587         uiDefButBitI(block, TOG, BONE_EDITMODE_LOCKED, B_REDR, "Lock", 160, 100, 140, 19, &(ebone->flag), 0, 0, 0, 0, "Prevents bone from being transformed in edit mode");
588         
589         uiBlockBeginAlign(block);
590         uiDefButF(block, NUM, B_ARMATUREPANEL1, "TailRadius:",  10, 150, 140, 19, &ebone->rad_tail, 0, lim, 10, 3, "");
591         if (ebone->parent && ebone->flag & BONE_CONNECTED )
592                 uiDefButF(block, NUM, B_ARMATUREPANEL1, "HeadRadius:",  10, 130, 140, 19, &ebone->parent->rad_tail, 0, lim, 10, 3, "");
593         else
594                 uiDefButF(block, NUM, B_ARMATUREPANEL1, "HeadRadius:",  10, 130, 140, 19, &ebone->rad_head, 0, lim, 10, 3, "");
595         uiBlockEndAlign(block);
596 }
597
598 static void v3d_editmetaball_buts(uiBlock *block, Object *ob, float lim)
599 {
600         MetaElem *lastelem= NULL; // XXX
601
602         if(lastelem) {
603                 uiBlockBeginAlign(block);
604                 uiDefButF(block, NUM, B_RECALCMBALL, "LocX:", 10, 70, 140, 19, &lastelem->x, -lim, lim, 100, 3, "");
605                 uiDefButF(block, NUM, B_RECALCMBALL, "LocY:", 10, 50, 140, 19, &lastelem->y, -lim, lim, 100, 3, "");
606                 uiDefButF(block, NUM, B_RECALCMBALL, "LocZ:", 10, 30, 140, 19, &lastelem->z, -lim, lim, 100, 3, "");
607
608                 uiBlockBeginAlign(block);
609                 if(lastelem->type!=MB_BALL)
610                         uiDefButF(block, NUM, B_RECALCMBALL, "dx:", 160, 70, 140, 19, &lastelem->expx, 0, lim, 100, 3, "");
611                 if((lastelem->type!=MB_BALL) && (lastelem->type!=MB_TUBE))
612                         uiDefButF(block, NUM, B_RECALCMBALL, "dy:", 160, 50, 140, 19, &lastelem->expy, 0, lim, 100, 3, "");
613                 if((lastelem->type==MB_ELIPSOID) || (lastelem->type==MB_CUBE))
614                         uiDefButF(block, NUM, B_RECALCMBALL, "dz:", 160, 30, 140, 19, &lastelem->expz, 0, lim, 100, 3, "");
615
616                 uiBlockEndAlign(block); 
617
618                 uiBlockBeginAlign(block);
619                 uiDefButF(block, NUM, B_RECALCMBALL, "Radius:", 10, 120, 140, 19, &lastelem->rad, 0, lim, 100, 3, "Size of the active metaball");
620                 uiDefButF(block, NUM, B_RECALCMBALL, "Stiffness:", 10, 100, 140, 19, &lastelem->s, 0, 10, 100, 3, "Stiffness of the active metaball");
621                 uiBlockEndAlign(block);
622                 
623                 uiDefButS(block, MENU, B_RECALCMBALL, "Type%t|Ball%x0|Tube%x4|Plane%x5|Elipsoid%x6|Cube%x7", 160, 120, 140, 19, &lastelem->type, 0.0, 0.0, 0, 0, "Set active element type");
624                 
625         }
626 }
627
628 /* test if 'ob' is a parent somewhere in par's parents */
629 static int test_parent_loop(Object *par, Object *ob)
630 {
631         if(par == NULL) return 0;
632         if(ob == par) return 1;
633         return test_parent_loop(par->parent, ob);
634 }
635
636 static void do_view3d_region_buttons(bContext *C, void *arg, int event)
637 {
638         Scene *scene= CTX_data_scene(C);
639         Object *obedit= CTX_data_edit_object(C);
640         View3D *v3d= CTX_wm_view3d(C);
641         BoundBox *bb;
642         Object *ob= OBACT;
643         TransformProperties *tfp= v3d->properties_storage;
644         VPaint *wpaint= scene->toolsettings->wpaint;
645         
646         switch(event) {
647         
648         case B_REDR:
649                 ED_area_tag_redraw(CTX_wm_area(C));
650                 return; /* no notifier! */
651                 
652         case B_OBJECTPANEL:
653                 DAG_object_flush_update(scene, ob, OB_RECALC_OB);
654                 break;
655                 
656         case B_OBJECTPANELROT:
657                 if(ob) {
658                         ob->rot[0]= M_PI*tfp->ob_eul[0]/180.0;
659                         ob->rot[1]= M_PI*tfp->ob_eul[1]/180.0;
660                         ob->rot[2]= M_PI*tfp->ob_eul[2]/180.0;
661                         DAG_object_flush_update(scene, ob, OB_RECALC_OB);
662                 }
663                 break;
664
665         case B_OBJECTPANELSCALE:
666                 if(ob) {
667
668                         /* link scale; figure out which axis changed */
669                         if (tfp->link_scale) {
670                                 float ratio, tmp, max = 0.0;
671                                 int axis;
672                                 
673                                 axis = 0;
674                                 max = fabs(tfp->ob_scale[0] - ob->size[0]);
675                                 tmp = fabs(tfp->ob_scale[1] - ob->size[1]);
676                                 if (tmp > max) {
677                                         axis = 1;
678                                         max = tmp;
679                                 }
680                                 tmp = fabs(tfp->ob_scale[2] - ob->size[2]);
681                                 if (tmp > max) {
682                                         axis = 2;
683                                         max = tmp;
684                                 }
685                         
686                                 if (ob->size[axis] != tfp->ob_scale[axis]) {
687                                         if (fabs(ob->size[axis]) > FLT_EPSILON) {
688                                                 ratio = tfp->ob_scale[axis] / ob->size[axis];
689                                                 ob->size[0] *= ratio;
690                                                 ob->size[1] *= ratio;
691                                                 ob->size[2] *= ratio;
692                                         }
693                                 }
694                         }
695                         else {
696                                 VECCOPY(ob->size, tfp->ob_scale);
697                                 
698                         }
699                         DAG_object_flush_update(scene, ob, OB_RECALC_OB);
700                 }
701                 break;
702
703         case B_OBJECTPANELDIMS:
704                 bb= object_get_boundbox(ob);
705                 if(bb) {
706                         float old_dims[3], scale[3], ratio, len[3];
707                         int axis;
708
709                         Mat4ToSize(ob->obmat, scale);
710
711                         len[0] = bb->vec[4][0] - bb->vec[0][0];
712                         len[1] = bb->vec[2][1] - bb->vec[0][1];
713                         len[2] = bb->vec[1][2] - bb->vec[0][2];
714
715                         old_dims[0] = fabs(scale[0]) * len[0];
716                         old_dims[1] = fabs(scale[1]) * len[1];
717                         old_dims[2] = fabs(scale[2]) * len[2];
718
719                         /* for each axis changed */
720                         for (axis = 0; axis<3; axis++) {
721                                 if (fabs(old_dims[axis] - tfp->ob_dims[axis]) > 0.0001) {
722                                         if (old_dims[axis] > 0.0) {
723                                                 ratio = tfp->ob_dims[axis] / old_dims[axis]; 
724                                                 if (tfp->link_scale) {
725                                                         ob->size[0] *= ratio;
726                                                         ob->size[1] *= ratio;
727                                                         ob->size[2] *= ratio;
728                                                         break;
729                                                 }
730                                                 else {
731                                                         ob->size[axis] *= ratio;
732                                                 }
733                                         }
734                                         else {
735                                                 if (len[axis] > 0) {
736                                                         ob->size[axis] = tfp->ob_dims[axis] / len[axis];
737                                                 }
738                                         }
739                                 }
740                         }
741                         
742                         /* prevent multiple B_OBJECTPANELDIMS events to keep scaling, cycling with TAB on buttons can cause that */
743                         VECCOPY(tfp->ob_dims, old_dims);
744                         
745                         DAG_object_flush_update(scene, ob, OB_RECALC_OB);
746                 }
747                 break;
748         
749         case B_OBJECTPANELMEDIAN:
750                 if(ob) {
751                         v3d_editvertex_buts(C, NULL, v3d, ob, 1.0);
752                         DAG_object_flush_update(scene, ob, OB_RECALC_DATA);
753                 }
754                 break;
755                 
756                 /* note; this case also used for parbone */
757         case B_OBJECTPANELPARENT:
758                 if(ob) {
759                         if(ob->id.lib || test_parent_loop(ob->parent, ob) ) 
760                                 ob->parent= NULL;
761                         else {
762                                 DAG_scene_sort(scene);
763                                 DAG_object_flush_update(scene, ob, OB_RECALC_OB);
764                         }
765                 }
766                 break;
767                 
768         case B_ARMATUREPANEL1:
769                 {
770                         bArmature *arm= obedit->data;
771                         EditBone *ebone, *child;
772                         
773                         for (ebone = arm->edbo->first; ebone; ebone=ebone->next){
774                                 if ((ebone->flag & BONE_ACTIVE) && (ebone->layer & arm->layer))
775                                         break;
776                         }
777                         if (ebone) {
778                                 ebone->roll= M_PI*tfp->ob_eul[0]/180.0;
779                                 //      Update our parent
780                                 if (ebone->parent && ebone->flag & BONE_CONNECTED){
781                                         VECCOPY (ebone->parent->tail, ebone->head);
782                                 }
783                         
784                                 //      Update our children if necessary
785                                 for (child = arm->edbo->first; child; child=child->next){
786                                         if (child->parent == ebone && (child->flag & BONE_CONNECTED)){
787                                                 VECCOPY (child->head, ebone->tail);
788                                         }
789                                 }
790                                 if(arm->flag & ARM_MIRROR_EDIT) {
791                                         EditBone *eboflip= ED_armature_bone_get_mirrored(arm->edbo, ebone);
792                                         if(eboflip) {
793                                                 eboflip->roll= -ebone->roll;
794                                                 eboflip->head[0]= -ebone->head[0];
795                                                 eboflip->tail[0]= -ebone->tail[0];
796                                                 
797                                                 //      Update our parent
798                                                 if (eboflip->parent && eboflip->flag & BONE_CONNECTED){
799                                                         VECCOPY (eboflip->parent->tail, eboflip->head);
800                                                 }
801                                                 
802                                                 //      Update our children if necessary
803                                                 for (child = arm->edbo->first; child; child=child->next){
804                                                         if (child->parent == eboflip && (child->flag & BONE_CONNECTED)){
805                                                                 VECCOPY (child->head, eboflip->tail);
806                                                         }
807                                                 }
808                                         }
809                                 }
810                         }
811                 }
812                 break;
813         case B_ARMATUREPANEL3:  // rotate button on channel
814                 {
815                         bArmature *arm;
816                         bPoseChannel *pchan;
817                         Bone *bone;
818                         float eul[3];
819                         
820                         arm = ob->data;
821                         if (!arm || !ob->pose) return;
822                                 
823                         for(pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) {
824                                 bone = pchan->bone;
825                                 if(bone && (bone->flag & BONE_ACTIVE) && (bone->layer & arm->layer))
826                                         break;
827                         }
828                         if (!pchan) return;
829                         
830                         /* make a copy to eul[3], to allow TAB on buttons to work */
831                         eul[0]= M_PI*tfp->ob_eul[0]/180.0;
832                         eul[1]= M_PI*tfp->ob_eul[1]/180.0;
833                         eul[2]= M_PI*tfp->ob_eul[2]/180.0;
834                         EulToQuat(eul, pchan->quat);
835                 }
836                 /* no break, pass on */
837         case B_ARMATUREPANEL2:
838                 {
839                         ob->pose->flag |= (POSE_LOCKED|POSE_DO_UNLOCK);
840                         DAG_object_flush_update(scene, ob, OB_RECALC_DATA);
841                 }
842                 break;
843         case B_TRANSFORMSPACEADD:
844                 BIF_manageTransformOrientation(C, 1, 0);
845                 break;
846         case B_TRANSFORMSPACECLEAR:
847                 BIF_clearTransformOrientation(C);
848                 break;
849                 
850         case B_WEIGHT0_0:
851                 wpaint->weight = 0.0f;
852                 break;
853                 
854         case B_WEIGHT1_4:
855                 wpaint->weight = 0.25f;
856                 break;
857         case B_WEIGHT1_2:
858                 wpaint->weight = 0.5f;
859                 break;
860         case B_WEIGHT3_4:
861                 wpaint->weight = 0.75f;
862                 break;
863         case B_WEIGHT1_0:
864                 wpaint->weight = 1.0f;
865                 break;
866                 
867         case B_OPA1_8:
868                 wpaint->a = 0.125f;
869                 break;
870         case B_OPA1_4:
871                 wpaint->a = 0.25f;
872                 break;
873         case B_OPA1_2:
874                 wpaint->a = 0.5f;
875                 break;
876         case B_OPA3_4:
877                 wpaint->a = 0.75f;
878                 break;
879         case B_OPA1_0:
880                 wpaint->a = 1.0f;
881                 break;
882         case B_CLR_WPAINT:
883 //              if(!multires_level1_test()) {
884                 {
885                         bDeformGroup *defGroup = BLI_findlink(&ob->defbase, ob->actdef-1);
886                         if(defGroup) {
887                                 Mesh *me= ob->data;
888                                 int a;
889                                 for(a=0; a<me->totvert; a++)
890                                         remove_vert_defgroup (ob, defGroup, a);
891                                 DAG_object_flush_update(scene, ob, OB_RECALC_DATA);
892                         }
893                 }
894                 break;
895         case B_RV3D_LOCKED:
896         case B_RV3D_BOXVIEW:
897         case B_RV3D_BOXCLIP:
898                 {
899                         ScrArea *sa= CTX_wm_area(C);
900                         ARegion *ar= sa->regionbase.last;
901                         RegionView3D *rv3d;
902                         short viewlock;
903                         
904                         ar= ar->prev;
905                         rv3d= ar->regiondata;
906                         viewlock= rv3d->viewlock;
907                         
908                         if((viewlock & RV3D_LOCKED)==0)
909                                 viewlock= 0;
910                         else if((viewlock & RV3D_BOXVIEW)==0)
911                                 viewlock &= ~RV3D_BOXCLIP;
912                         
913                         for(; ar; ar= ar->prev) {
914                                 if(ar->alignment==RGN_ALIGN_QSPLIT) {
915                                         rv3d= ar->regiondata;
916                                         rv3d->viewlock= viewlock;
917                                 }
918                         }
919                         
920                         if(rv3d->viewlock & RV3D_BOXVIEW)
921                                 view3d_boxview_copy(sa, sa->regionbase.last);
922                         
923                         ED_area_tag_redraw(sa);
924                 }
925                 break;
926         }
927
928         /* default for now */
929         WM_event_add_notifier(C, NC_OBJECT|ND_TRANSFORM, ob);
930 }
931
932 void removeTransformOrientation_func(bContext *C, void *target, void *unused)
933 {
934         BIF_removeTransformOrientation(C, (TransformOrientation *) target);
935 }
936
937 void selectTransformOrientation_func(bContext *C, void *target, void *unused)
938 {
939         BIF_selectTransformOrientation(C, (TransformOrientation *) target);
940 }
941
942 static void view3d_panel_transform_spaces(const bContext *C, ARegion *ar, short cntrl)
943 {
944         Scene *scene= CTX_data_scene(C);
945         Object *obedit= CTX_data_edit_object(C);
946         View3D *v3d= CTX_wm_view3d(C);
947         ListBase *transform_spaces = &scene->transform_spaces;
948         TransformOrientation *ts = transform_spaces->first;
949         uiBlock *block;
950         uiBut *but;
951         int xco = 20, yco = 70, height = 140;
952         int index;
953
954         block= uiBeginBlock(C, ar, "view3d_panel_transform", UI_EMBOSS, UI_HELV);
955         if(uiNewPanel(C, ar, block, "Transform Orientations", "View3d", 1000, 0, 318, height)==0) return;
956
957         uiNewPanelHeight(block, height);
958
959         uiBlockBeginAlign(block);
960         
961         if (obedit)
962                 uiDefBut(block, BUT, B_TRANSFORMSPACEADD, "Add", xco,120,80,20, 0, 0, 0, 0, 0, "Add the selected element as a Transform Orientation");
963         else
964                 uiDefBut(block, BUT, B_TRANSFORMSPACEADD, "Add", xco,120,80,20, 0, 0, 0, 0, 0, "Add the active object as a Transform Orientation");
965
966         uiDefBut(block, BUT, B_TRANSFORMSPACECLEAR, "Clear", xco + 80,120,80,20, 0, 0, 0, 0, 0, "Removal all Transform Orientations");
967         
968         uiBlockEndAlign(block);
969         
970         uiBlockBeginAlign(block);
971         
972         uiDefButS(block, ROW, B_REDR, "Global", xco,            90, 40,20, &v3d->twmode, 5.0, (float)V3D_MANIP_GLOBAL,0, 0, "Global Transform Orientation");
973         uiDefButS(block, ROW, B_REDR, "Local",  xco + 40,       90, 40,20, &v3d->twmode, 5.0, (float)V3D_MANIP_LOCAL, 0, 0, "Local Transform Orientation");
974         uiDefButS(block, ROW, B_REDR, "Normal", xco + 80,       90, 40,20, &v3d->twmode, 5.0, (float)V3D_MANIP_NORMAL,0, 0, "Normal Transform Orientation");
975         uiDefButS(block, ROW, B_REDR, "View",           xco + 120,      90, 40,20, &v3d->twmode, 5.0, (float)V3D_MANIP_VIEW,    0, 0, "View Transform Orientation");
976         
977         for (index = V3D_MANIP_CUSTOM, ts = transform_spaces->first ; ts ; ts = ts->next, index++) {
978
979                 UI_ThemeColor(TH_BUT_ACTION);
980                 if (v3d->twmode == index) {
981                         but = uiDefIconButS(block,ROW, B_REDR, ICON_CHECKBOX_HLT, xco,yco,XIC,YIC, &v3d->twmode, 5.0, (float)index, 0, 0, "Use this Custom Transform Orientation");
982                 }
983                 else {
984                         but = uiDefIconButS(block,ROW, B_REDR, ICON_CHECKBOX_DEHLT, xco,yco,XIC,YIC, &v3d->twmode, 5.0, (float)index, 0, 0, "Use this Custom Transform Orientation");
985                 }
986                 uiButSetFunc(but, selectTransformOrientation_func, ts, NULL);
987                 uiDefBut(block, TEX, 0, "", xco+=XIC, yco,100+XIC,20, &ts->name, 0, 30, 0, 0, "Edits the name of this Transform Orientation");
988                 but = uiDefIconBut(block, BUT, B_REDR, ICON_X, xco+=100+XIC,yco,XIC,YIC, 0, 0, 0, 0, 0, "Deletes this Transform Orientation");
989                 uiButSetFunc(but, removeTransformOrientation_func, ts, NULL);
990
991                 xco = 20;
992                 yco -= 25;
993         }
994         uiBlockEndAlign(block);
995         
996         if(yco < 0) uiNewPanelHeight(block, height-yco);
997         uiEndBlock(C, block);
998 }
999
1000 static void weight_paint_buttons(Scene *scene, uiBlock *block)
1001 {
1002         VPaint *wpaint= scene->toolsettings->wpaint;
1003         Object *ob;
1004         ob= OBACT;
1005         
1006         if(ob==NULL || ob->type!=OB_MESH) return;
1007         
1008         uiBlockBeginAlign(block);
1009         uiDefButF(block, NUMSLI, B_REDR, "Weight:",10,170,225,19, &wpaint->weight, 0, 1, 10, 0, "Sets the current vertex group's bone deformation strength");
1010         
1011         uiDefBut(block, BUT, B_WEIGHT0_0 , "0",                  10,150,45,19, 0, 0, 0, 0, 0, "");
1012         uiDefBut(block, BUT, B_WEIGHT1_4 , "1/4",                55,150,45,19, 0, 0, 0, 0, 0, "");
1013         uiDefBut(block, BUT, B_WEIGHT1_2 , "1/2",                100,150,45,19, 0, 0, 0, 0, 0, "");
1014         uiDefBut(block, BUT, B_WEIGHT3_4 , "3/4",                145,150,45,19, 0, 0, 0, 0, 0, "");
1015         uiDefBut(block, BUT, B_WEIGHT1_0 , "1",                  190,150,45,19, 0, 0, 0, 0, 0, "");
1016         
1017         uiDefButF(block, NUMSLI, B_NOP, "Opacity ",             10,130,225,19, &wpaint->a, 0.0, 1.0, 0, 0, "The amount of pressure on the brush");
1018         
1019         uiDefBut(block, BUT, B_OPA1_8 , "1/8",          10,110,45,19, 0, 0, 0, 0, 0, "");
1020         uiDefBut(block, BUT, B_OPA1_4 , "1/4",          55,110,45,19, 0, 0, 0, 0, 0, "");
1021         uiDefBut(block, BUT, B_OPA1_2 , "1/2",          100,110,45,19, 0, 0, 0, 0, 0, "");
1022         uiDefBut(block, BUT, B_OPA3_4 , "3/4",          145,110,45,19, 0, 0, 0, 0, 0, "");
1023         uiDefBut(block, BUT, B_OPA1_0 , "1",            190,110,45,19, 0, 0, 0, 0, 0, "");
1024         
1025         uiDefButF(block, NUMSLI, B_NOP, "Size ",        10,90,225,19, &wpaint->size, 2.0, 64.0, 0, 0, "The size of the brush");
1026         
1027         uiBlockBeginAlign(block);
1028         uiDefButS(block, ROW, B_NOP, "Mix",             250,170,60,17, &wpaint->mode, 1.0, 0.0, 0, 0, "Mix the vertex colors");
1029         uiDefButS(block, ROW, B_NOP, "Add",             250,152,60,17, &wpaint->mode, 1.0, 1.0, 0, 0, "Add the vertex colors");
1030         uiDefButS(block, ROW, B_NOP, "Sub",             250,134,60,17, &wpaint->mode, 1.0, 2.0, 0, 0, "Subtract from the vertex color");
1031         uiDefButS(block, ROW, B_NOP, "Mul",             250,116,60,17, &wpaint->mode, 1.0, 3.0, 0, 0, "Multiply the vertex color");
1032         uiDefButS(block, ROW, B_NOP, "Blur",            250, 98,60,17, &wpaint->mode, 1.0, 4.0, 0, 0, "Blur the weight with surrounding values");
1033         uiDefButS(block, ROW, B_NOP, "Lighter", 250, 80,60,17, &wpaint->mode, 1.0, 5.0, 0, 0, "Paint over darker areas only");
1034         uiDefButS(block, ROW, B_NOP, "Darker",          250, 62,60,17, &wpaint->mode, 1.0, 6.0, 0, 0, "Paint over lighter areas only");
1035         uiBlockEndAlign(block);
1036         
1037         /* draw options same as below */
1038         uiBlockBeginAlign(block);
1039         if (FACESEL_PAINT_TEST) {
1040                 Mesh *me= ob->data;
1041                 uiDefButBitI(block, TOG, ME_DRAWFACES, B_REDR, "Faces", 10,45,60,19, &me->drawflag, 0, 0, 0, 0, "Displays all faces as shades");
1042                 uiDefButBitI(block,TOG, ME_DRAWEDGES, B_REDR,"Edges",70,45,60,19, &me->drawflag, 2.0, 0, 0, 0,  "Displays edges of visible faces");
1043                 uiDefButBitI(block,TOG, ME_HIDDENEDGES, B_REDR,"Hidden Edges",130,45,100,19, &me->drawflag, 2.0, 1.0, 0, 0,  "Displays edges of hidden faces");
1044         } else{ 
1045                 uiDefButBitC(block, TOG, OB_DRAWWIRE, B_REDR, "Wire",   10,45,75,19, &ob->dtx, 0, 0, 0, 0, "Displays the active object's wireframe in shaded drawing modes");
1046         }
1047         uiBlockEndAlign(block);
1048         
1049         uiBlockBeginAlign(block);
1050         uiDefButBitS(block, TOG, VP_AREA, 0, "All Faces",       10,20,60,19, &wpaint->flag, 0, 0, 0, 0, "Paint on all faces inside brush (otherwise only on face under mouse cursor)");
1051         uiDefButBitS(block, TOG, VP_SOFT, 0, "Vert Dist", 70,20,60,19, &wpaint->flag, 0, 0, 0, 0, "Use distances to vertices (instead of all vertices of face)");
1052         uiDefButBitS(block, TOGN, VP_HARD, 0, "Soft",           130,20,60,19, &wpaint->flag, 0, 0, 0, 0, "Use a soft brush");
1053         uiDefButBitS(block, TOG, VP_NORMALS, 0, "Normals",      190,20,60,19, &wpaint->flag, 0, 0, 0, 0, "Applies the vertex normal before painting");
1054         uiDefButBitS(block, TOG, VP_SPRAY, 0, "Spray",          250,20,55,19, &wpaint->flag, 0, 0, 0, 0, "Keep applying paint effect while holding mouse");
1055         uiBlockEndAlign(block);
1056         
1057         if(ob) {
1058                 uiBlockBeginAlign(block);
1059                 uiDefButBitS(block, TOG, VP_ONLYVGROUP, B_REDR, "Vgroup",               10,0,100,19, &wpaint->flag, 0, 0, 0, 0, "Only paint on vertices in the selected vertex group.");
1060                 uiDefButBitS(block, TOG, VP_MIRROR_X, B_REDR, "X-Mirror",       110,0,100,19, &wpaint->flag, 0, 0, 0, 0, "Mirrored Paint, applying on mirrored Weight Group name");
1061                 uiDefBut(block, BUT, B_CLR_WPAINT, "Clear",                                     210,0,100,19, NULL, 0, 0, 0, 0, "Removes reference to this deform group from all vertices");
1062                 uiBlockEndAlign(block);
1063         }
1064 }
1065
1066 static Brush **get_brush_source(const bContext *C)
1067 {
1068         if(G.f & G_SCULPTMODE)
1069                 return &CTX_data_scene(C)->toolsettings->sculpt->brush;
1070         else if(G.f & G_TEXTUREPAINT)
1071                 return &CTX_data_scene(C)->toolsettings->imapaint.brush;
1072         return NULL;
1073 }
1074
1075 static void brush_idpoin_handle(bContext *C, ID *id, int event)
1076 {
1077         Brush **br = get_brush_source(C);
1078
1079         if(!br)
1080                 return;
1081
1082         switch(event) {
1083         case UI_ID_BROWSE:
1084                 (*br) = (Brush*)id;
1085                 break;
1086         case UI_ID_DELETE:
1087                 brush_delete(br);
1088                 break;
1089         case UI_ID_RENAME:
1090                 /* XXX ? */
1091                 break;
1092         case UI_ID_ADD_NEW:
1093                 if(id) {
1094                         (*br) = copy_brush((Brush*)id);
1095                         id->us--;
1096                 }
1097                 else
1098                         (*br) = add_brush("Brush");
1099                 break;
1100         case UI_ID_OPEN:
1101                 /* XXX not implemented */
1102                 break;
1103         }
1104 }
1105
1106 static void view3d_panel_brush(const bContext *C, ARegion *ar, short cntrl)
1107 {
1108         uiBlock *block;
1109         Brush **brp = get_brush_source(C), *br;
1110         short w = 268, h = 400, cx = 10, cy = h;
1111         rctf rect;
1112
1113         if(!brp)
1114                 return;
1115         br = *brp;
1116
1117         block= uiBeginBlock(C, ar, "view3d_panel_brush", UI_EMBOSS, UI_HELV);
1118         if(uiNewPanel(C, ar, block, "Brush", "View3d", 340, 10, 318, h)==0) return;
1119         uiBlockSetHandleFunc(block, do_view3d_region_buttons, NULL);
1120
1121         uiBlockBeginAlign(block);
1122         uiDefIDPoinButs(block, CTX_data_main(C), NULL, &br->id, ID_BR, NULL, cx, cy,
1123                         brush_idpoin_handle, UI_ID_BROWSE|UI_ID_RENAME|UI_ID_ADD_NEW|UI_ID_OPEN|UI_ID_DELETE|UI_ID_ALONE);
1124         cy-= 25;
1125         uiBlockEndAlign(block);
1126
1127         if(!br)
1128                 return;
1129
1130         if(G.f & G_SCULPTMODE) {
1131                 uiBlockBeginAlign(block);       
1132                 uiDefButC(block,ROW,B_REDR,"Draw",cx,cy,67,19,&br->sculpt_tool,14.0,SCULPT_TOOL_DRAW,0,0,"Draw lines on the model");
1133                 uiDefButC(block,ROW,B_REDR,"Smooth",cx+67,cy,67,19,&br->sculpt_tool,14.0,SCULPT_TOOL_SMOOTH,0,0,"Interactively smooth areas of the model");
1134                 uiDefButC(block,ROW,B_REDR,"Pinch",cx+134,cy,67,19,&br->sculpt_tool,14.0,SCULPT_TOOL_PINCH,0,0,"Interactively pinch areas of the model");
1135                 uiDefButC(block,ROW,B_REDR,"Inflate",cx+201,cy,67,19,&br->sculpt_tool,14,SCULPT_TOOL_INFLATE,0,0,"Push vertices along the direction of their normals");
1136                 cy-= 20;
1137                 uiDefButC(block,ROW,B_REDR,"Grab", cx,cy,89,19,&br->sculpt_tool,14,SCULPT_TOOL_GRAB,0,0,"Grabs a group of vertices and moves them with the mouse");
1138                 uiDefButC(block,ROW,B_REDR,"Layer", cx+89,cy,89,19,&br->sculpt_tool,14, SCULPT_TOOL_LAYER,0,0,"Adds a layer of depth");
1139                 uiDefButC(block,ROW,B_REDR,"Flatten", cx+178,cy,90,19,&br->sculpt_tool,14, SCULPT_TOOL_FLATTEN,0,0,"Interactively flatten areas of the model");
1140                 cy-= 25;
1141                 uiBlockEndAlign(block);
1142         }
1143
1144         uiBlockBeginAlign(block);
1145         uiDefButI(block,NUMSLI,B_NOP,"Size: ",cx,cy,w,19,&br->size,1.0,200.0,0,0,"Set brush radius in pixels");
1146         cy-= 20;
1147         uiDefButF(block,NUMSLI,B_NOP,"Strength: ",cx,cy,w,19,&br->alpha,0,1.0,0,0,"Set brush strength");
1148         cy-= 25;
1149         uiBlockEndAlign(block);
1150
1151         uiBlockBeginAlign(block);
1152
1153         uiDefButBitS(block, TOG, BRUSH_AIRBRUSH, B_NOP, "Airbrush", cx,cy,w/3,19, &br->flag,0,0,0,0, "Brush makes changes without waiting for the mouse to move");
1154         uiDefButBitS(block, TOG, BRUSH_ANCHORED, B_NOP, "Rake", cx+w/3,cy,w/3,19, &br->flag,0,0,0,0, "");
1155         uiDefButBitS(block, TOG, BRUSH_RAKE, B_NOP, "Anchored", cx+w*2.0/3,cy,w/3,19, &br->flag,0,0,0,0, "");
1156         cy-= 20;
1157         uiDefButBitS(block, TOG, BRUSH_SPACE, B_NOP, "Space", cx,cy,w/3,19, &br->flag,0,0,0,0, "");
1158         uiDefButF(block,NUMSLI,B_NOP,"Spacing: ",cx+w/3,cy,w*2.0/3,19,&br->spacing,1.0,500,0,0,"");
1159         cy-= 20;
1160         uiBlockEndAlign(block);
1161
1162         rect.xmin= cx; rect.xmax= cx + w;
1163         rect.ymin= cy - 200; rect.ymax= cy;
1164         uiBlockBeginAlign(block);
1165         curvemap_buttons(block, br->curve, (char)0, B_NOP, 0, &rect);
1166         uiBlockEndAlign(block);
1167         
1168         uiEndBlock(C, block);
1169 }
1170
1171 static void sculptmode_draw_interface_tools(Scene *scene, uiBlock *block, unsigned short cx, unsigned short cy)
1172 {
1173         Sculpt *s = scene->toolsettings->sculpt;
1174         
1175         //XXX if(sd->brush_type != SMOOTH_BRUSH && sd->brush_type != GRAB_BRUSH && sd->brush_type != FLATTEN_BRUSH) {
1176         {
1177                 /*uiDefButBitS(block,ROW,B_NOP,"Add",cx,cy,89,19,&br->dir,15.0,1.0,0, 0,"Add depth to model [Shift]");
1178                 uiDefButBitS(block,ROW,B_NOP,"Sub",cx+89,cy,89,19,&br->dir,15.0,2.0,0, 0,"Subtract depth from model [Shift]");
1179                 */}
1180         //XXX if(sd->brush_type!=GRAB_BRUSH)
1181         
1182         uiBlockBeginAlign(block);
1183         uiDefBut( block,LABEL,B_NOP,"Symmetry",cx,cy,90,19,NULL,0,0,0,0,"");
1184         cy-= 20;
1185         uiBlockBeginAlign(block);
1186         uiDefButBitI(block, TOG, SCULPT_SYMM_X, B_NOP, "X", cx,cy,40,19, &s->flags, 0,0,0,0, "Mirror brush across X axis");
1187         uiDefButBitI(block, TOG, SCULPT_SYMM_Y, B_NOP, "Y", cx+40,cy,40,19, &s->flags, 0,0,0,0, "Mirror brush across Y axis");
1188         uiDefButBitI(block, TOG, SCULPT_SYMM_Z, B_NOP, "Z", cx+80,cy,40,19, &s->flags, 0,0,0,0, "Mirror brush across Z axis");
1189         uiBlockEndAlign(block);
1190         
1191         
1192         cy+= 20;
1193         uiBlockBeginAlign(block);
1194         uiDefBut( block,LABEL,B_NOP,"LockAxis",cx+140,cy,90,19,NULL,0,0,0,0,"");
1195         cy-= 20;
1196         uiBlockBeginAlign(block);
1197         uiDefButBitI(block, TOG, SCULPT_LOCK_X, B_NOP, "X", cx+140,cy,40,19, &s->flags, 0,0,0,0, "Constrain X axis");
1198         uiDefButBitI(block, TOG, SCULPT_LOCK_Y, B_NOP, "Y", cx+180,cy,40,19, &s->flags, 0,0,0,0, "Constrain Y axis");
1199         uiDefButBitI(block, TOG, SCULPT_LOCK_Z, B_NOP, "Z", cx+220,cy,40,19, &s->flags, 0,0,0,0, "Constrain Z axis");
1200         uiBlockEndAlign(block);
1201                 
1202         cx+= 210;
1203 }
1204
1205
1206 static void view3d_panel_object(const bContext *C, ARegion *ar, short cntrl)    // VIEW3D_HANDLER_OBJECT
1207 {
1208         Scene *scene= CTX_data_scene(C);
1209         Object *obedit= CTX_data_edit_object(C);
1210         View3D *v3d= CTX_wm_view3d(C);
1211         uiBlock *block;
1212         uiBut *bt;
1213         Object *ob= OBACT;
1214         TransformProperties *tfp;
1215         float lim;
1216         static char hexcol[128];
1217         
1218         if(ob==NULL) return;
1219
1220         /* make sure we got storage */
1221         if(v3d->properties_storage==NULL)
1222                 v3d->properties_storage= MEM_callocN(sizeof(TransformProperties), "TransformProperties");
1223         tfp= v3d->properties_storage;
1224         
1225         block= uiBeginBlock(C, ar, "view3d_panel_object", UI_EMBOSS, UI_HELV);
1226         uiBlockSetHandleFunc(block, do_view3d_region_buttons, NULL);
1227         
1228         if((G.f & G_SCULPTMODE) && !obedit) {
1229                 if(!uiNewPanel(C, ar, block, "Transform Properties", "View3d", 10, 230, 318, 234))
1230                         return;
1231         } else if(G.f & G_PARTICLEEDIT && !obedit){
1232                 if(!uiNewPanel(C, ar, block, "Transform Properties", "View3d", 10, 230, 318, 234))
1233                         return;
1234         } else {
1235                 if(!uiNewPanel(C, ar, block, "Transform Properties", "View3d", 10, 230, 318, 204))
1236                         return;
1237         }
1238
1239 // XXX  uiSetButLock(object_is_libdata(ob), ERROR_LIBDATA_MESSAGE);
1240         
1241         if(G.f & (G_VERTEXPAINT|G_TEXTUREPAINT|G_WEIGHTPAINT)) {
1242         }
1243         else {
1244                 bt= uiDefBut(block, TEX, B_IDNAME, "OB: ",      10,180,140,20, ob->id.name+2, 0.0, 21.0, 0, 0, "");
1245                 uiButSetFunc(bt, test_idbutton_cb, ob->id.name, NULL);
1246
1247                 if((G.f & G_PARTICLEEDIT)==0) {
1248                         uiBlockBeginAlign(block);
1249                         uiDefIDPoinBut(block, test_obpoin_but, ID_OB, B_OBJECTPANELPARENT, "Par:", 160, 180, 140, 20, &ob->parent, "Parent Object"); 
1250                         if((ob->parent) && (ob->partype == PARBONE)) {
1251                                 bt= uiDefBut(block, TEX, B_OBJECTPANELPARENT, "ParBone:", 160, 160, 140, 20, ob->parsubstr, 0, 30, 0, 0, "");
1252                                 uiButSetCompleteFunc(bt, autocomplete_bone, (void *)ob->parent);
1253                         }
1254                         else {
1255                                 strcpy(ob->parsubstr, "");
1256                         }
1257                         uiBlockEndAlign(block);
1258                 }
1259         }
1260
1261         lim= 10000.0f*MAX2(1.0, v3d->grid);
1262
1263         if(ob==obedit) {
1264                 if(ob->type==OB_ARMATURE) v3d_editarmature_buts(block, v3d, ob, lim);
1265                 if(ob->type==OB_MBALL) v3d_editmetaball_buts(block, ob, lim);
1266                 else v3d_editvertex_buts(C, block, v3d, ob, lim);
1267         }
1268         else if(ob->flag & OB_POSEMODE) {
1269                 v3d_posearmature_buts(block, v3d, ob, lim);
1270         }
1271         else if(G.f & G_WEIGHTPAINT) {
1272                 uiNewPanelTitle(block, "Weight Paint Properties");
1273                 weight_paint_buttons(scene, block);
1274         }
1275         else if(G.f & (G_VERTEXPAINT|G_TEXTUREPAINT)) {
1276                 static float hsv[3], old[3];    // used as temp mem for picker
1277                 float *rgb= NULL;
1278                 ToolSettings *settings= scene->toolsettings;
1279
1280                 if(G.f & G_VERTEXPAINT) rgb= &settings->vpaint->r;
1281                 else if(settings->imapaint.brush) rgb= settings->imapaint.brush->rgb;
1282                 
1283                 uiNewPanelTitle(block, "Paint Properties");
1284                 if (rgb)
1285                         /* 'f' is for floating panel */
1286                         uiBlockPickerButtons(block, rgb, hsv, old, hexcol, 'f', B_REDR);
1287         }
1288         else if(G.f & G_SCULPTMODE) {
1289                 uiNewPanelTitle(block, "Sculpt Properties");
1290                 sculptmode_draw_interface_tools(scene, block, 10, 150);
1291         } 
1292         else if(G.f & G_PARTICLEEDIT){
1293                 uiNewPanelTitle(block, "Particle Edit Properties");
1294 // XXX          particle_edit_buttons(block);
1295         } 
1296         else {
1297                 BoundBox *bb = NULL;
1298
1299                 uiBlockBeginAlign(block);
1300                 uiDefIconButBitS(block, ICONTOG, OB_LOCK_LOCX, B_REDR, ICON_UNLOCKED,   10,150,20,19, &(ob->protectflag), 0, 0, 0, 0, "Protects this value from being Transformed");
1301                 uiDefButF(block, NUM, B_OBJECTPANEL, "LocX:",           30, 150, 120, 19, &(ob->loc[0]), -lim, lim, 100, 3, "");
1302                 uiDefIconButBitS(block, ICONTOG, OB_LOCK_LOCY, B_REDR, ICON_UNLOCKED,   10,130,20,19, &(ob->protectflag), 0, 0, 0, 0, "Protects this value from being Transformed");
1303                 uiDefButF(block, NUM, B_OBJECTPANEL, "LocY:",           30, 130, 120, 19, &(ob->loc[1]), -lim, lim, 100, 3, "");
1304                 uiDefIconButBitS(block, ICONTOG, OB_LOCK_LOCZ, B_REDR, ICON_UNLOCKED,   10,110,20,19, &(ob->protectflag), 0, 0, 0, 0, "Protects this value from being Transformed");
1305                 uiDefButF(block, NUM, B_OBJECTPANEL, "LocZ:",           30, 110, 120, 19, &(ob->loc[2]), -lim, lim, 100, 3, "");
1306                 
1307                 tfp->ob_eul[0]= 180.0*ob->rot[0]/M_PI;
1308                 tfp->ob_eul[1]= 180.0*ob->rot[1]/M_PI;
1309                 tfp->ob_eul[2]= 180.0*ob->rot[2]/M_PI;
1310                 
1311                 uiBlockBeginAlign(block);
1312                 if ((ob->parent) && (ob->partype == PARBONE)) {
1313                         uiDefIconButBitS(block, ICONTOG, OB_LOCK_ROTX, B_REDR, ICON_UNLOCKED,   160,130,20,19, &(ob->protectflag), 0, 0, 0, 0, "Protects this value from being Transformed");
1314                         uiDefButF(block, NUM, B_OBJECTPANELROT, "RotX:",        180, 130, 120, 19, &(tfp->ob_eul[0]), -lim, lim, 1000, 3, "");
1315                         uiDefIconButBitS(block, ICONTOG, OB_LOCK_ROTY, B_REDR, ICON_UNLOCKED,   160,110,20,19, &(ob->protectflag), 0, 0, 0, 0, "Protects this value from being Transformed");
1316                         uiDefButF(block, NUM, B_OBJECTPANELROT, "RotY:",        180, 110, 120, 19, &(tfp->ob_eul[1]), -lim, lim, 1000, 3, "");
1317                         uiDefIconButBitS(block, ICONTOG, OB_LOCK_ROTZ, B_REDR, ICON_UNLOCKED,   160,90,20,19, &(ob->protectflag), 0, 0, 0, 0, "Protects this value from being Transformed");
1318                         uiDefButF(block, NUM, B_OBJECTPANELROT, "RotZ:",        180, 90, 120, 19, &(tfp->ob_eul[2]), -lim, lim, 1000, 3, "");
1319
1320                 }
1321                 else {
1322                         uiDefIconButBitS(block, ICONTOG, OB_LOCK_ROTX, B_REDR, ICON_UNLOCKED,   160,150,20,19, &(ob->protectflag), 0, 0, 0, 0, "Protects this value from being Transformed");
1323                         uiDefButF(block, NUM, B_OBJECTPANELROT, "RotX:",        180, 150, 120, 19, &(tfp->ob_eul[0]), -lim, lim, 1000, 3, "");
1324                         uiDefIconButBitS(block, ICONTOG, OB_LOCK_ROTY, B_REDR, ICON_UNLOCKED,   160,130,20,19, &(ob->protectflag), 0, 0, 0, 0, "Protects this value from being Transformed");
1325                         uiDefButF(block, NUM, B_OBJECTPANELROT, "RotY:",        180, 130, 120, 19, &(tfp->ob_eul[1]), -lim, lim, 1000, 3, "");
1326                         uiDefIconButBitS(block, ICONTOG, OB_LOCK_ROTZ, B_REDR, ICON_UNLOCKED,   160,110,20,19, &(ob->protectflag), 0, 0, 0, 0, "Protects this value from being Transformed");
1327                         uiDefButF(block, NUM, B_OBJECTPANELROT, "RotZ:",        180, 110, 120, 19, &(tfp->ob_eul[2]), -lim, lim, 1000, 3, "");
1328                 }
1329
1330                 tfp->ob_scale[0]= ob->size[0];
1331                 tfp->ob_scale[1]= ob->size[1];
1332                 tfp->ob_scale[2]= ob->size[2];
1333
1334                 uiBlockBeginAlign(block);
1335                 uiDefIconButBitS(block, ICONTOG, OB_LOCK_SCALEX, B_REDR, ICON_UNLOCKED, 10,80,20,19, &(ob->protectflag), 0, 0, 0, 0, "Protects this value from being Transformed");
1336                 uiDefButF(block, NUM, B_OBJECTPANELSCALE, "ScaleX:",            30, 80, 120, 19, &(tfp->ob_scale[0]), -lim, lim, 10, 3, "");
1337                 uiDefIconButBitS(block, ICONTOG, OB_LOCK_SCALEY, B_REDR, ICON_UNLOCKED, 10,60,20,19, &(ob->protectflag), 0, 0, 0, 0, "Protects this value from being Transformed");
1338                 uiDefButF(block, NUM, B_OBJECTPANELSCALE, "ScaleY:",            30, 60, 120, 19, &(tfp->ob_scale[1]), -lim, lim, 10, 3, "");
1339                 uiDefIconButBitS(block, ICONTOG, OB_LOCK_SCALEZ, B_REDR, ICON_UNLOCKED, 10,40,20,19, &(ob->protectflag), 0, 0, 0, 0, "Protects this value from being Transformed");
1340                 uiDefButF(block, NUM, B_OBJECTPANELSCALE, "ScaleZ:",            30, 40, 120, 19, &(tfp->ob_scale[2]), -lim, lim, 10, 3, "");
1341                 uiBlockEndAlign(block);
1342                 
1343                 uiDefButS(block, TOG, B_REDR, "Link Scale",             10, 10, 140, 19, &(tfp->link_scale), 0, 1, 0, 0, "Scale values vary proportionally in all directions");
1344
1345                 bb= object_get_boundbox(ob);
1346                 if (bb) {
1347                         float scale[3];
1348
1349                         Mat4ToSize(ob->obmat, scale);
1350
1351                         tfp->ob_dims[0] = fabs(scale[0]) * (bb->vec[4][0] - bb->vec[0][0]);
1352                         tfp->ob_dims[1] = fabs(scale[1]) * (bb->vec[2][1] - bb->vec[0][1]);
1353                         tfp->ob_dims[2] = fabs(scale[2]) * (bb->vec[1][2] - bb->vec[0][2]);
1354
1355                         uiBlockBeginAlign(block);
1356                         if ((ob->parent) && (ob->partype == PARBONE)) {
1357                                 uiDefButF(block, NUM, B_OBJECTPANELDIMS, "DimX:",               160, 60, 140, 19, &(tfp->ob_dims[0]), 0.0, lim, 10, 3, "Manipulate bounding box size");
1358                                 uiDefButF(block, NUM, B_OBJECTPANELDIMS, "DimY:",               160, 40, 140, 19, &(tfp->ob_dims[1]), 0.0, lim, 10, 3, "Manipulate bounding box size");
1359                                 uiDefButF(block, NUM, B_OBJECTPANELDIMS, "DimZ:",               160, 20, 140, 19, &(tfp->ob_dims[2]), 0.0, lim, 10, 3, "Manipulate bounding box size");
1360
1361                         }
1362                         else {
1363                                 uiDefButF(block, NUM, B_OBJECTPANELDIMS, "DimX:",               160, 80, 140, 19, &(tfp->ob_dims[0]), 0.0, lim, 10, 3, "Manipulate bounding box size");
1364                                 uiDefButF(block, NUM, B_OBJECTPANELDIMS, "DimY:",               160, 60, 140, 19, &(tfp->ob_dims[1]), 0.0, lim, 10, 3, "Manipulate bounding box size");
1365                                 uiDefButF(block, NUM, B_OBJECTPANELDIMS, "DimZ:",               160, 40, 140, 19, &(tfp->ob_dims[2]), 0.0, lim, 10, 3, "Manipulate bounding box size");
1366                         }
1367
1368                         uiBlockEndAlign(block);
1369                 }
1370         }
1371 // XXX  uiClearButLock();
1372         uiEndBlock(C, block);
1373 }
1374
1375 static void view3d_panel_background(const bContext *C, ARegion *ar, short cntrl)        // VIEW3D_HANDLER_BACKGROUND
1376 {
1377         View3D *v3d= CTX_wm_view3d(C);
1378         uiBlock *block;
1379
1380         block= uiBeginBlock(C, ar, "view3d_panel_background", UI_EMBOSS, UI_HELV);
1381         if(uiNewPanel(C, ar, block, "Background Image", "View3d", 340, 10, 318, 204)==0) return;
1382         uiBlockSetHandleFunc(block, do_view3d_region_buttons, NULL);
1383
1384         if(v3d->flag & V3D_DISPBGPIC) {
1385                 if(v3d->bgpic==NULL) {
1386                         v3d->bgpic= MEM_callocN(sizeof(BGpic), "bgpic");
1387                         v3d->bgpic->size= 5.0;
1388                         v3d->bgpic->blend= 0.5;
1389                         v3d->bgpic->iuser.fie_ima= 2;
1390                         v3d->bgpic->iuser.ok= 1;
1391                 }
1392         }
1393         
1394         if(!(v3d->flag & V3D_DISPBGPIC)) {
1395                 uiDefButBitS(block, TOG, V3D_DISPBGPIC, B_REDR, "Use Background Image", 10, 180, 150, 20, &v3d->flag, 0, 0, 0, 0, "Display an image in the background of this 3D View");
1396                 uiDefBut(block, LABEL, 1, " ",  160, 180, 150, 20, NULL, 0.0, 0.0, 0, 0, "");
1397         }
1398         else {
1399                 uiBlockBeginAlign(block);
1400                 uiDefButBitS(block, TOG, V3D_DISPBGPIC, B_REDR, "Use", 10, 225, 50, 20, &v3d->flag, 0, 0, 0, 0, "Display an image in the background of this 3D View");
1401                 uiDefButF(block, NUMSLI, B_REDR, "Blend:",      60, 225, 150, 20, &v3d->bgpic->blend, 0.0,1.0, 0, 0, "Set the transparency of the background image");
1402                 uiDefButF(block, NUM, B_REDR, "Size:",          210, 225, 100, 20, &v3d->bgpic->size, 0.1, 250.0*v3d->grid, 100, 0, "Set the size (width) of the background image");
1403
1404                 uiDefButF(block, NUM, B_REDR, "X Offset:",      10, 205, 150, 20, &v3d->bgpic->xof, -250.0*v3d->grid,250.0*v3d->grid, 10, 2, "Set the horizontal offset of the background image");
1405                 uiDefButF(block, NUM, B_REDR, "Y Offset:",      160, 205, 150, 20, &v3d->bgpic->yof, -250.0*v3d->grid,250.0*v3d->grid, 10, 2, "Set the vertical offset of the background image");
1406                 
1407                 ED_image_uiblock_panel(C, block, &v3d->bgpic->ima, &v3d->bgpic->iuser, B_REDR, B_REDR);
1408                 uiBlockEndAlign(block);
1409         }
1410         uiEndBlock(C, block);
1411 }
1412
1413
1414 static void view3d_panel_properties(const bContext *C, ARegion *ar, short cntrl)        // VIEW3D_HANDLER_SETTINGS
1415 {
1416         ScrArea *sa= CTX_wm_area(C);
1417         ARegion *arlast;
1418         Scene *scene= CTX_data_scene(C);
1419         View3D *v3d= CTX_wm_view3d(C);
1420         RegionView3D *rv3d;
1421         uiBlock *block;
1422         float *curs;
1423
1424         block= uiBeginBlock(C, ar, "view3d_panel_properties", UI_EMBOSS, UI_HELV);
1425         if(uiNewPanel(C, ar, block, "View Properties", "View3d", 340, 30, 318, 254)==0) return;
1426         uiBlockSetHandleFunc(block, do_view3d_region_buttons, NULL);
1427
1428         /* to force height */
1429         uiNewPanelHeight(block, 264);
1430
1431         uiDefBut(block, LABEL, 1, "Grid:",                                      10, 220, 150, 19, NULL, 0.0, 0.0, 0, 0, "");
1432         uiBlockBeginAlign(block);
1433         uiDefButF(block, NUM, B_REDR, "Spacing:",               10, 200, 140, 19, &v3d->grid, 0.001, 100.0, 10, 0, "Set the distance between grid lines");
1434         uiDefButS(block, NUM, B_REDR, "Lines:",         10, 180, 140, 19, &v3d->gridlines, 0.0, 100.0, 100, 0, "Set the number of grid lines in perspective view");
1435         uiDefButS(block, NUM, B_REDR, "Divisions:",             10, 160, 140, 19, &v3d->gridsubdiv, 1.0, 100.0, 100, 0, "Set the number of grid lines");
1436         uiBlockEndAlign(block);
1437
1438         uiDefBut(block, LABEL, 1, "3D Display:",                                                        160, 220, 150, 19, NULL, 0.0, 0.0, 0, 0, "");
1439         uiDefButBitS(block, TOG, V3D_SHOW_FLOOR, B_REDR, "Grid Floor",160, 200, 150, 19, &v3d->gridflag, 0, 0, 0, 0, "Show the grid floor in free camera mode");
1440         uiDefButBitS(block, TOG, V3D_SHOW_X, B_REDR, "X Axis",          160, 176, 48, 19, &v3d->gridflag, 0, 0, 0, 0, "Show the X Axis line");
1441         uiDefButBitS(block, TOG, V3D_SHOW_Y, B_REDR, "Y Axis",          212, 176, 48, 19, &v3d->gridflag, 0, 0, 0, 0, "Show the Y Axis line");
1442         uiDefButBitS(block, TOG, V3D_SHOW_Z, B_REDR, "Z Axis",          262, 176, 48, 19, &v3d->gridflag, 0, 0, 0, 0, "Show the Z Axis line");
1443
1444         uiDefBut(block, LABEL, 1, "View Camera:",                       10, 140, 140, 19, NULL, 0.0, 0.0, 0, 0, "");
1445         
1446         uiDefButF(block, NUM, B_REDR, "Lens:",          10, 120, 140, 19, &v3d->lens, 10.0, 120.0, 100, 0, "The lens angle in perspective view");
1447         uiBlockBeginAlign(block);
1448         uiDefButF(block, NUM, B_REDR, "Clip Start:",    10, 96, 140, 19, &v3d->near, v3d->grid/100.0, 100.0, 10, 0, "Set the beginning of the range in which 3D objects are displayed (perspective view)");
1449         uiDefButF(block, NUM, B_REDR, "Clip End:",      10, 76, 140, 19, &v3d->far, 1.0, 10000.0*v3d->grid, 100, 0, "Set the end of the range in which 3D objects are displayed (perspective view)");
1450         uiBlockEndAlign(block);
1451
1452         uiDefBut(block, LABEL, 1, "3D Cursor:",                         160, 150, 140, 19, NULL, 0.0, 0.0, 0, 0, "");
1453
1454         uiBlockBeginAlign(block);
1455         curs= give_cursor(scene, v3d);
1456         uiDefButF(block, NUM, B_REDR, "X:",                     160, 130, 150, 22, curs, -10000.0*v3d->grid, 10000.0*v3d->grid, 10, 0, "X co-ordinate of the 3D cursor");
1457         uiDefButF(block, NUM, B_REDR, "Y:",                     160, 108, 150, 22, curs+1, -10000.0*v3d->grid, 10000.0*v3d->grid, 10, 0, "Y co-ordinate of the 3D cursor");
1458         uiDefButF(block, NUM, B_REDR, "Z:",                     160, 86, 150, 22, curs+2, -10000.0*v3d->grid, 10000.0*v3d->grid, 10, 0, "Z co-ordinate of the 3D cursor");
1459         uiBlockEndAlign(block);
1460
1461         uiDefBut(block, LABEL, 1, "Display:",                           10, 50, 150, 19, NULL, 0.0, 0.0, 0, 0, "");
1462         uiBlockBeginAlign(block);
1463         uiDefButBitS(block, TOG, V3D_SELECT_OUTLINE, B_REDR, "Outline Selected", 10, 30, 140, 19, &v3d->flag, 0, 0, 0, 0, "Highlight selected objects with an outline, in Solid, Shaded or Textured viewport shading modes");
1464         uiDefButBitS(block, TOG, V3D_DRAW_CENTERS, B_REDR, "All Object Centers", 10, 10, 140, 19, &v3d->flag, 0, 0, 0, 0, "Draw the center points on all objects");
1465         uiDefButBitS(block, TOGN, V3D_HIDE_HELPLINES, B_REDR, "Relationship Lines", 10, -10, 140, 19, &v3d->flag, 0, 0, 0, 0, "Draw dashed lines indicating Parent, Constraint, or Hook relationships");
1466         uiDefButBitS(block, TOG, V3D_SOLID_TEX, B_REDR, "Solid Tex", 10, -30, 140, 19, &v3d->flag2, 0, 0, 0, 0, "Display textures in Solid draw type (Shift T)");
1467         uiBlockEndAlign(block);
1468
1469         uiDefBut(block, LABEL, 1, "View Locking:",                              160, 60, 150, 19, NULL, 0.0, 0.0, 0, 0, "");
1470         uiBlockBeginAlign(block);
1471         uiDefIDPoinBut(block, test_obpoin_but, ID_OB, B_REDR, "Object:", 160, 40, 150, 19, &v3d->ob_centre, "Lock view to center to this Object"); 
1472         uiDefBut(block, TEX, B_REDR, "Bone:",                                           160, 20, 150, 19, v3d->ob_centre_bone, 1, 31, 0, 0, "If view locked to Object, use this Bone to lock to view to");
1473         uiBlockEndAlign(block); 
1474
1475         /* last region is always 3d... a bit weak */
1476         arlast= sa->regionbase.last;
1477         uiBlockBeginAlign(block);
1478         if(arlast->alignment==RGN_ALIGN_QSPLIT) {
1479                 arlast= arlast->prev;
1480                 rv3d= arlast->regiondata;
1481                 
1482                 uiDefButO(block, BUT, "SCREEN_OT_region_foursplit", WM_OP_EXEC_REGION_WIN, "End 4-Split View", 160, -10, 150, 19, "Join the 3D View");
1483                 uiDefButBitS(block, TOG, RV3D_LOCKED, B_RV3D_LOCKED, "Lock", 160, -30, 50, 19, &rv3d->viewlock, 0, 0, 0, 0, "");
1484                 uiDefButBitS(block, TOG, RV3D_BOXVIEW, B_RV3D_BOXVIEW, "Box", 210, -30, 50, 19, &rv3d->viewlock, 0, 0, 0, 0, "");
1485                 uiDefButBitS(block, TOG, RV3D_BOXCLIP, B_RV3D_BOXCLIP, "Clip", 260, -30, 50, 19, &rv3d->viewlock, 0, 0, 0, 0, "");
1486         }               
1487         else
1488                 uiDefButO(block, BUT, "SCREEN_OT_region_foursplit", WM_OP_EXEC_REGION_WIN, "4-Split View", 160, -10, 150, 19, "Split 3D View in 4 parts");
1489                 
1490         uiBlockEndAlign(block); 
1491                 
1492         
1493 // XXX
1494 //      uiDefBut(block, LABEL, 1, "Keyframe Display:",                          160, -2, 150, 19, NULL, 0.0, 0.0, 0, 0, "");
1495 //      uiBlockBeginAlign(block);
1496 //      uiDefButBitS(block, TOG, ANIMFILTER_ACTIVE, B_REDR, "Active",160, -22, 50, 19, &v3d->keyflags, 0, 0, 0, 0, "Show keyframes for active element only (i.e. active bone or active material)");
1497 //      uiDefButBitS(block, TOG, ANIMFILTER_MUTED, B_REDR, "Muted",210, -22, 50, 19, &v3d->keyflags, 0, 0, 0, 0, "Show keyframes in muted channels");
1498 //      uiDefButBitS(block, TOG, ANIMFILTER_LOCAL, B_REDR, "Local",260, -22, 50, 19, &v3d->keyflags, 0, 0, 0, 0, "Show keyframes directly connected to datablock");
1499 //      if ((v3d->keyflags & ANIMFILTER_LOCAL)==0) {
1500 //              uiDefButBitS(block, TOGN, ANIMFILTER_NOMAT, B_REDR, "Material",160, -42, 75, 19, &v3d->keyflags, 0, 0, 0, 0, "Show keyframes for any available Materials");
1501 //              uiDefButBitS(block, TOGN, ANIMFILTER_NOSKEY, B_REDR, "ShapeKey",235, -42, 75, 19, &v3d->keyflags, 0, 0, 0, 0, "Show keyframes for any available Shape Keys");
1502 //      }
1503         uiBlockEndAlign(block); 
1504         
1505         uiEndBlock(C, block);
1506 }
1507
1508 #if 0
1509 static void view3d_panel_preview(bContext *C, ARegion *ar, short cntrl) // VIEW3D_HANDLER_PREVIEW
1510 {
1511         uiBlock *block;
1512         View3D *v3d= sa->spacedata.first;
1513         int ofsx, ofsy;
1514         
1515         block= uiBeginBlock(C, ar, "view3d_panel_preview", UI_EMBOSS, UI_HELV);
1516         uiPanelControl(UI_PNL_SOLID | UI_PNL_CLOSE | UI_PNL_SCALE | cntrl);
1517         uiSetPanelHandler(VIEW3D_HANDLER_PREVIEW);  // for close and esc
1518         
1519         ofsx= -150+(sa->winx/2)/v3d->blockscale;
1520         ofsy= -100+(sa->winy/2)/v3d->blockscale;
1521         if(uiNewPanel(C, ar, block, "Preview", "View3d", ofsx, ofsy, 300, 200)==0) return;
1522
1523         uiBlockSetDrawExtraFunc(block, BIF_view3d_previewdraw);
1524         
1525         if(scene->recalc & SCE_PRV_CHANGED) {
1526                 scene->recalc &= ~SCE_PRV_CHANGED;
1527                 //printf("found recalc\n");
1528                 BIF_view3d_previewrender_free(sa->spacedata.first);
1529                 BIF_preview_changed(0);
1530         }
1531 }
1532 #endif
1533
1534 static void view3d_panel_gpencil(const bContext *C, ARegion *ar, short cntrl)   // VIEW3D_HANDLER_GREASEPENCIL
1535 {
1536         View3D *v3d= CTX_wm_view3d(C);
1537         uiBlock *block;
1538
1539         block= uiBeginBlock(C, ar, "view3d_panel_gpencil", UI_EMBOSS, UI_HELV);
1540         if (uiNewPanel(C, ar, block, "Grease Pencil", "View3d", 100, 30, 318, 204)==0) return;
1541
1542         /* allocate memory for gpd if drawing enabled (this must be done first or else we crash) */
1543         if (v3d->flag2 & V3D_DISPGP) {
1544 //              if (v3d->gpd == NULL)
1545 // XXX                  gpencil_data_setactive(ar, gpencil_data_addnew());
1546         }
1547         
1548         if (v3d->flag2 & V3D_DISPGP) {
1549 // XXX          bGPdata *gpd= v3d->gpd;
1550                 short newheight;
1551                 
1552                 /* this is a variable height panel, newpanel doesnt force new size on existing panels */
1553                 /* so first we make it default height */
1554                 uiNewPanelHeight(block, 204);
1555                 
1556                 /* draw button for showing gpencil settings and drawings */
1557                 uiDefButBitS(block, TOG, V3D_DISPGP, B_REDR, "Use Grease Pencil", 10, 225, 150, 20, &v3d->flag2, 0, 0, 0, 0, "Display freehand annotations overlay over this 3D View (draw using Shift-LMB)");
1558                 
1559                 /* extend the panel if the contents won't fit */
1560 //              newheight= draw_gpencil_panel(block, gpd, ar); 
1561                 uiNewPanelHeight(block, newheight);
1562         }
1563         else {
1564                 uiDefButBitS(block, TOG, V3D_DISPGP, B_REDR, "Use Grease Pencil", 10, 225, 150, 20, &v3d->flag2, 0, 0, 0, 0, "Display freehand annotations overlay over this 3D View");
1565                 uiDefBut(block, LABEL, 1, " ",  160, 180, 150, 20, NULL, 0.0, 0.0, 0, 0, "");
1566         }
1567         uiEndBlock(C, block);
1568 }
1569
1570
1571 void view3d_buttons_area_defbuts(const bContext *C, ARegion *ar)
1572 {
1573         
1574         view3d_panel_object(C, ar, 0);
1575         view3d_panel_properties(C, ar, 0);
1576         view3d_panel_background(C, ar, 0);
1577         if(G.f & (G_SCULPTMODE|G_TEXTUREPAINT))
1578                 view3d_panel_brush(C, ar, 0);
1579         // XXX view3d_panel_preview(C, ar, 0);
1580         view3d_panel_transform_spaces(C, ar, 0);
1581         if(0)
1582                 view3d_panel_gpencil(C, ar, 0);
1583         
1584         uiDrawPanels(C, 1);             /* 1 = align */
1585         uiMatchPanelsView2d(ar); /* sets v2d->totrct */
1586         
1587 }
1588
1589
1590 static int view3d_properties(bContext *C, wmOperator *op)
1591 {
1592         ScrArea *sa= CTX_wm_area(C);
1593         ARegion *ar= view3d_has_buttons_region(sa);
1594         
1595         if(ar) {
1596                 ar->flag ^= RGN_FLAG_HIDDEN;
1597                 ar->v2d.flag &= ~V2D_IS_INITIALISED; /* XXX should become hide/unhide api? */
1598                 
1599                 ED_area_initialize(CTX_wm_manager(C), CTX_wm_window(C), sa);
1600                 ED_area_tag_redraw(sa);
1601         }
1602         return OPERATOR_FINISHED;
1603 }
1604
1605 void VIEW3D_OT_properties(wmOperatorType *ot)
1606 {
1607         ot->name= "Properties";
1608         ot->idname= "VIEW3D_OT_properties";
1609         
1610         ot->exec= view3d_properties;
1611         ot->poll= ED_operator_view3d_active;
1612         
1613         /* flags */
1614         ot->flag= 0;
1615 }