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