2.5: Various
[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_ID.h"
35 #include "DNA_action_types.h"
36 #include "DNA_armature_types.h"
37 #include "DNA_curve_types.h"
38 #include "DNA_camera_types.h"
39 #include "DNA_lamp_types.h"
40 #include "DNA_lattice_types.h"
41 #include "DNA_meta_types.h"
42 #include "DNA_mesh_types.h"
43 #include "DNA_meshdata_types.h"
44 #include "DNA_object_types.h"
45 #include "DNA_space_types.h"
46 #include "DNA_scene_types.h"
47 #include "DNA_screen_types.h"
48 #include "DNA_userdef_types.h"
49 #include "DNA_view3d_types.h"
50 #include "DNA_world_types.h"
51
52 #include "MEM_guardedalloc.h"
53
54 #include "BLI_arithb.h"
55 #include "BLI_blenlib.h"
56 #include "BLI_editVert.h"
57 #include "BLI_rand.h"
58
59 #include "BKE_action.h"
60 #include "BKE_brush.h"
61 #include "BKE_context.h"
62 #include "BKE_curve.h"
63 #include "BKE_customdata.h"
64 #include "BKE_depsgraph.h"
65 #include "BKE_idprop.h"
66 #include "BKE_mesh.h"
67 #include "BKE_object.h"
68 #include "BKE_global.h"
69 #include "BKE_scene.h"
70 #include "BKE_screen.h"
71 #include "BKE_utildefines.h"
72
73 #include "BIF_gl.h"
74
75 #include "WM_api.h"
76 #include "WM_types.h"
77
78 #include "RNA_access.h"
79 #include "RNA_define.h"
80
81 #include "ED_armature.h"
82 #include "ED_curve.h"
83 #include "ED_image.h"
84 #include "ED_keyframing.h"
85 #include "ED_mesh.h"
86 #include "ED_object.h"
87 #include "ED_particle.h"
88 #include "ED_screen.h"
89 #include "ED_transform.h"
90 #include "ED_types.h"
91 #include "ED_util.h"
92
93 #include "UI_interface.h"
94 #include "UI_resources.h"
95 #include "UI_view2d.h"
96
97 #include "view3d_intern.h"      // own include
98
99
100 /* ******************* view3d space & buttons ************** */
101 #define B_NOP           1
102 #define B_REDR          2
103 #define B_OBJECTPANELROT        1007
104 #define B_OBJECTPANELMEDIAN 1008
105 #define B_ARMATUREPANEL1        1009
106 #define B_ARMATUREPANEL2        1010
107 #define B_OBJECTPANELPARENT 1011
108 #define B_OBJECTPANEL           1012
109 #define B_ARMATUREPANEL3        1013
110 #define B_OBJECTPANELSCALE      1014
111 #define B_OBJECTPANELDIMS       1015
112 #define B_TRANSFORMSPACEADD     1016
113 #define B_TRANSFORMSPACECLEAR   1017
114 #define B_SETPT_AUTO    2125
115 #define B_SETPT_VECTOR  2126
116 #define B_SETPT_ALIGN   2127
117 #define B_SETPT_FREE    2128
118 #define B_RECALCMBALL   2501
119
120 #define B_WEIGHT0_0             2840
121 #define B_WEIGHT1_4             2841
122 #define B_WEIGHT1_2             2842
123 #define B_WEIGHT3_4             2843
124 #define B_WEIGHT1_0             2844
125
126 #define B_OPA1_8                2845
127 #define B_OPA1_4                2846
128 #define B_OPA1_2                2847
129 #define B_OPA3_4                2848
130 #define B_OPA1_0                2849
131
132 #define B_CLR_WPAINT    2850
133
134 #define B_RV3D_LOCKED   2900
135 #define B_RV3D_BOXVIEW  2901
136 #define B_RV3D_BOXCLIP  2902
137
138 #define B_IDNAME                3000
139
140 /* temporary struct for storing transform properties */
141 typedef struct {
142         float ob_eul[4];        // used for quat too....
143         float ob_scale[3]; // need temp space due to linked values
144         float ob_dims[3];
145         short link_scale;
146         float ve_median[5];
147         int curdef;
148         float *defweightp;
149 } TransformProperties;
150
151
152 /* is used for both read and write... */
153 static void v3d_editvertex_buts(const bContext *C, uiBlock *block, View3D *v3d, Object *ob, float lim)
154 {
155         MDeformVert *dvert=NULL;
156         TransformProperties *tfp= v3d->properties_storage;
157         float median[5], ve_median[5];
158         int tot, totw, totweight, totedge;
159         char defstr[320];
160         
161         median[0]= median[1]= median[2]= median[3]= median[4]= 0.0;
162         tot= totw= totweight= totedge= 0;
163         defstr[0]= 0;
164
165         if(ob->type==OB_MESH) {
166                 Mesh *me= ob->data;
167                 EditMesh *em = BKE_mesh_get_editmesh(me);
168                 EditVert *eve, *evedef=NULL;
169                 EditEdge *eed;
170                 
171                 eve= em->verts.first;
172                 while(eve) {
173                         if(eve->f & SELECT) {
174                                 evedef= eve;
175                                 tot++;
176                                 VecAddf(median, median, eve->co);
177                         }
178                         eve= eve->next;
179                 }
180                 eed= em->edges.first;
181                 while(eed) {
182                         if((eed->f & SELECT)) {
183                                 totedge++;
184                                 median[3]+= eed->crease;
185                         }
186                         eed= eed->next;
187                 }
188
189                 /* check for defgroups */
190                 if(evedef)
191                         dvert= CustomData_em_get(&em->vdata, evedef->data, CD_MDEFORMVERT);
192                 if(tot==1 && dvert && dvert->totweight) {
193                         bDeformGroup *dg;
194                         int i, max=1, init=1;
195                         char str[320];
196                         
197                         for (i=0; i<dvert->totweight; i++){
198                                 dg = BLI_findlink (&ob->defbase, dvert->dw[i].def_nr);
199                                 if(dg) {
200                                         max+= BLI_snprintf(str, sizeof(str), "%s %%x%d|", dg->name, dvert->dw[i].def_nr); 
201                                         if(max<320) strcat(defstr, str);
202                                 }
203                                 else printf("oh no!\n");
204                                 if(tfp->curdef==dvert->dw[i].def_nr) {
205                                         init= 0;
206                                         tfp->defweightp= &dvert->dw[i].weight;
207                                 }
208                         }
209                         
210                         if(init) {      // needs new initialized 
211                                 tfp->curdef= dvert->dw[0].def_nr;
212                                 tfp->defweightp= &dvert->dw[0].weight;
213                         }
214                 }
215
216                 BKE_mesh_end_editmesh(me, em);
217         }
218         else if(ob->type==OB_CURVE || ob->type==OB_SURF) {
219                 Curve *cu= ob->data;
220                 Nurb *nu;
221                 BPoint *bp;
222                 BezTriple *bezt;
223                 int a;
224                 
225                 nu= cu->editnurb->first;
226                 while(nu) {
227                         if((nu->type & 7)==CU_BEZIER) {
228                                 bezt= nu->bezt;
229                                 a= nu->pntsu;
230                                 while(a--) {
231                                         if(bezt->f2 & SELECT) {
232                                                 VecAddf(median, median, bezt->vec[1]);
233                                                 tot++;
234                                                 median[4]+= bezt->weight;
235                                                 totweight++;
236                                         }
237                                         else {
238                                                 if(bezt->f1 & SELECT) {
239                                                         VecAddf(median, median, bezt->vec[0]);
240                                                         tot++;
241                                                 }
242                                                 if(bezt->f3 & SELECT) {
243                                                         VecAddf(median, median, bezt->vec[2]);
244                                                         tot++;
245                                                 }
246                                         }
247                                         bezt++;
248                                 }
249                         }
250                         else {
251                                 bp= nu->bp;
252                                 a= nu->pntsu*nu->pntsv;
253                                 while(a--) {
254                                         if(bp->f1 & SELECT) {
255                                                 VecAddf(median, median, bp->vec);
256                                                 median[3]+= bp->vec[3];
257                                                 totw++;
258                                                 tot++;
259                                                 median[4]+= bp->weight;
260                                                 totweight++;
261                                         }
262                                         bp++;
263                                 }
264                         }
265                         nu= nu->next;
266                 }
267         }
268         else if(ob->type==OB_LATTICE) {
269                 Lattice *lt= ob->data;
270                 BPoint *bp;
271                 int a;
272                 
273                 a= lt->editlatt->pntsu*lt->editlatt->pntsv*lt->editlatt->pntsw;
274                 bp= lt->editlatt->def;
275                 while(a--) {
276                         if(bp->f1 & SELECT) {
277                                 VecAddf(median, median, bp->vec);
278                                 tot++;
279                                 median[4]+= bp->weight;
280                                 totweight++;
281                         }
282                         bp++;
283                 }
284         }
285         
286         if(tot==0) return;
287
288         median[0] /= (float)tot;
289         median[1] /= (float)tot;
290         median[2] /= (float)tot;
291         if(totedge) median[3] /= (float)totedge;
292         else if(totw) median[3] /= (float)totw;
293         if(totweight) median[4] /= (float)totweight;
294         
295         if(v3d->flag & V3D_GLOBAL_STATS)
296                 Mat4MulVecfl(ob->obmat, median);
297         
298         if(block) {     // buttons
299                 int but_y;
300                 if((ob->parent) && (ob->partype == PARBONE))    but_y = 135;
301                 else                                                                                    but_y = 150;
302                 
303                 uiBlockBeginAlign(block);
304                 uiDefButBitS(block, TOG, V3D_GLOBAL_STATS, B_REDR, "Global",            160, but_y, 70, 19, &v3d->flag, 0, 0, 0, 0, "Displays global values");
305                 uiDefButBitS(block, TOGN, V3D_GLOBAL_STATS, B_REDR, "Local",            230, but_y, 70, 19, &v3d->flag, 0, 0, 0, 0, "Displays local values");
306                 uiBlockEndAlign(block);
307                 
308                 memcpy(tfp->ve_median, median, sizeof(tfp->ve_median));
309                 
310                 uiBlockBeginAlign(block);
311                 if(tot==1) {
312                         uiDefButF(block, NUM, B_OBJECTPANELMEDIAN, "Vertex X:", 10, 110, 290, 19, &(tfp->ve_median[0]), -lim, lim, 10, 3, "");
313                         uiDefButF(block, NUM, B_OBJECTPANELMEDIAN, "Vertex Y:", 10, 90, 290, 19, &(tfp->ve_median[1]), -lim, lim, 10, 3, "");
314                         uiDefButF(block, NUM, B_OBJECTPANELMEDIAN, "Vertex Z:", 10, 70, 290, 19, &(tfp->ve_median[2]), -lim, lim, 10, 3, "");
315                         if(totw==1)
316                                 uiDefButF(block, NUM, B_OBJECTPANELMEDIAN, "Vertex W:", 10, 50, 290, 19, &(tfp->ve_median[3]), 0.01, 100.0, 10, 3, "");
317                         uiBlockEndAlign(block);
318         
319                         if(defstr[0]) {
320                                 uiDefBut(block, LABEL, 1, "Vertex Deform Groups",               10, 40, 290, 20, NULL, 0.0, 0.0, 0, 0, "");
321
322                                 uiBlockBeginAlign(block);
323                                 uiDefButF(block, NUM, B_NOP, "Weight:",                 10, 20, 150, 19, tfp->defweightp, 0.0f, 1.0f, 10, 3, "Weight value");
324                                 uiDefButI(block, MENU, B_REDR, defstr,  160, 20, 140, 19, &tfp->curdef, 0.0, 0.0, 0, 0, "Current Vertex Group");
325                                 uiBlockEndAlign(block);
326                         }
327                         else if(totweight)
328                                 uiDefButF(block, NUM, B_OBJECTPANELMEDIAN, "Weight:",   10, 20, 290, 19, &(tfp->ve_median[4]), 0.0, 1.0, 10, 3, "");
329
330                 }
331                 else {
332                         uiDefButF(block, NUM, B_OBJECTPANELMEDIAN, "Median X:", 10, 110, 290, 19, &(tfp->ve_median[0]), -lim, lim, 10, 3, "");
333                         uiDefButF(block, NUM, B_OBJECTPANELMEDIAN, "Median Y:", 10, 90, 290, 19, &(tfp->ve_median[1]), -lim, lim, 10, 3, "");
334                         uiDefButF(block, NUM, B_OBJECTPANELMEDIAN, "Median Z:", 10, 70, 290, 19, &(tfp->ve_median[2]), -lim, lim, 10, 3, "");
335                         if(totw==tot)
336                                 uiDefButF(block, NUM, B_OBJECTPANELMEDIAN, "Median W:", 10, 50, 290, 19, &(tfp->ve_median[3]), 0.01, 100.0, 10, 3, "");
337                         uiBlockEndAlign(block);
338                         if(totweight)
339                                 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");
340                 }
341                 
342                 if(ob->type==OB_CURVE && (totw==0)) { /* bez curves have no w */
343                         uiBlockBeginAlign(block);
344                         uiDefBut(block, BUT,B_SETPT_AUTO,"Auto",        10, 44, 72, 19, 0, 0, 0, 0, 0, "Auto handles (Shift H)");
345                         uiDefBut(block, BUT,B_SETPT_VECTOR,"Vector",82, 44, 73, 19, 0, 0, 0, 0, 0, "Vector handles (V)");
346                         uiDefBut(block, BUT,B_SETPT_ALIGN,"Align",155, 44, 73, 19, 0, 0, 0, 0, 0, "Align handles (H Toggles)");
347                         uiDefBut(block, BUT,B_SETPT_FREE,"Free",        227, 44, 72, 19, 0, 0, 0, 0, 0, "Align handles (H Toggles)");
348                         uiBlockEndAlign(block);
349                 }
350                 
351                 if(totedge==1)
352                         uiDefButF(block, NUM, B_OBJECTPANELMEDIAN, "Crease W:", 10, 30, 290, 19, &(tfp->ve_median[3]), 0.0, 1.0, 10, 3, "");
353                 else if(totedge>1)
354                         uiDefButF(block, NUM, B_OBJECTPANELMEDIAN, "Median Crease W:",  10, 30, 290, 19, &(tfp->ve_median[3]), 0.0, 1.0, 10, 3, "");
355                 
356         }
357         else {  // apply
358                 memcpy(ve_median, tfp->ve_median, sizeof(tfp->ve_median));
359                 
360                 if(v3d->flag & V3D_GLOBAL_STATS) {
361                         Mat4Invert(ob->imat, ob->obmat);
362                         Mat4MulVecfl(ob->imat, median);
363                         Mat4MulVecfl(ob->imat, ve_median);
364                 }
365                 VecSubf(median, ve_median, median);
366                 median[3]= ve_median[3]-median[3];
367                 median[4]= ve_median[4]-median[4];
368                 
369                 if(ob->type==OB_MESH) {
370                         Mesh *me= ob->data;
371                         EditMesh *em = BKE_mesh_get_editmesh(me);
372                         EditVert *eve;
373                         EditEdge *eed;
374                         
375                         eve= em->verts.first;
376                         while(eve) {
377                                 if(eve->f & SELECT) {
378                                         VecAddf(eve->co, eve->co, median);
379                                 }
380                                 eve= eve->next;
381                         }
382                         
383                         for(eed= em->edges.first; eed; eed= eed->next) {
384                                 if(eed->f & SELECT) {
385                                         /* ensure the median can be set to zero or one */
386                                         if(ve_median[3]==0.0f) eed->crease= 0.0f;
387                                         else if(ve_median[3]==1.0f) eed->crease= 1.0f;
388                                         else {
389                                                 eed->crease+= median[3];
390                                                 CLAMP(eed->crease, 0.0, 1.0);
391                                         }
392                                 }
393                         }
394                         
395                         recalc_editnormals(em);
396
397                         BKE_mesh_end_editmesh(me, em);
398                 }
399                 else if(ob->type==OB_CURVE || ob->type==OB_SURF) {
400                         Curve *cu= ob->data;
401                         Nurb *nu;
402                         BPoint *bp;
403                         BezTriple *bezt;
404                         int a;
405                         
406                         nu= cu->editnurb->first;
407                         while(nu) {
408                                 if((nu->type & 7)==CU_BEZIER) {
409                                         bezt= nu->bezt;
410                                         a= nu->pntsu;
411                                         while(a--) {
412                                                 if(bezt->f2 & SELECT) {
413                                                         VecAddf(bezt->vec[0], bezt->vec[0], median);
414                                                         VecAddf(bezt->vec[1], bezt->vec[1], median);
415                                                         VecAddf(bezt->vec[2], bezt->vec[2], median);
416                                                         bezt->weight+= median[4];
417                                                 }
418                                                 else {
419                                                         if(bezt->f1 & SELECT) {
420                                                                 VecAddf(bezt->vec[0], bezt->vec[0], median);
421                                                         }
422                                                         if(bezt->f3 & SELECT) {
423                                                                 VecAddf(bezt->vec[2], bezt->vec[2], median);
424                                                         }
425                                                 }
426                                                 bezt++;
427                                         }
428                                 }
429                                 else {
430                                         bp= nu->bp;
431                                         a= nu->pntsu*nu->pntsv;
432                                         while(a--) {
433                                                 if(bp->f1 & SELECT) {
434                                                         VecAddf(bp->vec, bp->vec, median);
435                                                         bp->vec[3]+= median[3];
436                                                         bp->weight+= median[4];
437                                                 }
438                                                 bp++;
439                                         }
440                                 }
441                                 test2DNurb(nu);
442                                 testhandlesNurb(nu); /* test for bezier too */
443
444                                 nu= nu->next;
445                         }
446                 }
447                 else if(ob->type==OB_LATTICE) {
448                         Lattice *lt= ob->data;
449                         BPoint *bp;
450                         int a;
451                         
452                         a= lt->editlatt->pntsu*lt->editlatt->pntsv*lt->editlatt->pntsw;
453                         bp= lt->editlatt->def;
454                         while(a--) {
455                                 if(bp->f1 & SELECT) {
456                                         VecAddf(bp->vec, bp->vec, median);
457                                         bp->weight+= median[4];
458                                 }
459                                 bp++;
460                         }
461                 }
462                 
463 //              ED_undo_push(C, "Transform properties");
464         }
465 }
466
467 /* assumes armature active */
468 static void validate_bonebutton_cb(bContext *C, void *bonev, void *namev)
469 {
470         Object *ob= CTX_data_active_object(C);
471         
472         if(ob && ob->type==OB_ARMATURE) {
473                 Bone *bone= bonev;
474                 char oldname[32], newname[32];
475                 
476                 /* need to be on the stack */
477                 BLI_strncpy(newname, bone->name, 32);
478                 BLI_strncpy(oldname, (char *)namev, 32);
479                 /* restore */
480                 BLI_strncpy(bone->name, oldname, 32);
481                 
482                 armature_bone_rename(ob, oldname, newname); // editarmature.c
483         }
484 }
485
486 static void v3d_posearmature_buts(uiBlock *block, View3D *v3d, Object *ob, float lim)
487 {
488         uiBut *but;
489         bArmature *arm;
490         bPoseChannel *pchan;
491         Bone *bone= NULL;
492         TransformProperties *tfp= v3d->properties_storage;
493
494         arm = ob->data;
495         if (!arm || !ob->pose) return;
496
497         for(pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) {
498                 bone = pchan->bone;
499                 if(bone && (bone->flag & BONE_ACTIVE) && (bone->layer & arm->layer))
500                         break;
501         }
502         if (!pchan || !bone) return;
503
504         if((ob->parent) && (ob->partype == PARBONE))
505                 but= uiDefBut (block, TEX, B_NOP, "Bone:",                              160, 130, 140, 19, bone->name, 1, 31, 0, 0, "");
506         else
507                 but= uiDefBut(block, TEX, B_NOP, "Bone:",                               160, 140, 140, 19, bone->name, 1, 31, 0, 0, "");
508         uiButSetFunc(but, validate_bonebutton_cb, bone, NULL);
509         uiButSetCompleteFunc(but, autocomplete_bone, (void *)ob);
510
511         QuatToEul(pchan->quat, tfp->ob_eul);
512         tfp->ob_eul[0]*= 180.0/M_PI;
513         tfp->ob_eul[1]*= 180.0/M_PI;
514         tfp->ob_eul[2]*= 180.0/M_PI;
515         
516         uiBlockBeginAlign(block);
517         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");
518         uiDefButF(block, NUM, B_ARMATUREPANEL2, "LocX:",        30, 140, 120, 19, pchan->loc, -lim, lim, 100, 3, "");
519         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");
520         uiDefButF(block, NUM, B_ARMATUREPANEL2, "LocY:",        30, 120, 120, 19, pchan->loc+1, -lim, lim, 100, 3, "");
521         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");
522         uiDefButF(block, NUM, B_ARMATUREPANEL2, "LocZ:",        30, 100, 120, 19, pchan->loc+2, -lim, lim, 100, 3, "");
523
524         uiBlockBeginAlign(block);
525         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");
526         uiDefButF(block, NUM, B_ARMATUREPANEL3, "RotX:",        30, 70, 120, 19, tfp->ob_eul, -1000.0, 1000.0, 100, 3, "");
527         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");
528         uiDefButF(block, NUM, B_ARMATUREPANEL3, "RotY:",        30, 50, 120, 19, tfp->ob_eul+1, -1000.0, 1000.0, 100, 3, "");
529         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");
530         uiDefButF(block, NUM, B_ARMATUREPANEL3, "RotZ:",        30, 30, 120, 19, tfp->ob_eul+2, -1000.0, 1000.0, 100, 3, "");
531         
532         uiBlockBeginAlign(block);
533         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");
534         uiDefButF(block, NUM, B_ARMATUREPANEL2, "ScaleX:",      180, 70, 120, 19, pchan->size, -lim, lim, 10, 3, "");
535         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");
536         uiDefButF(block, NUM, B_ARMATUREPANEL2, "ScaleY:",      180, 50, 120, 19, pchan->size+1, -lim, lim, 10, 3, "");
537         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");
538         uiDefButF(block, NUM, B_ARMATUREPANEL2, "ScaleZ:",      180, 30, 120, 19, pchan->size+2, -lim, lim, 10, 3, "");
539         uiBlockEndAlign(block);
540 }
541
542 /* assumes armature editmode */
543 void validate_editbonebutton_cb(bContext *C, void *bonev, void *namev)
544 {
545         EditBone *eBone= bonev;
546         char oldname[32], newname[32];
547         
548         /* need to be on the stack */
549         BLI_strncpy(newname, eBone->name, 32);
550         BLI_strncpy(oldname, (char *)namev, 32);
551         /* restore */
552         BLI_strncpy(eBone->name, oldname, 32);
553         
554         armature_bone_rename(CTX_data_edit_object(C), oldname, newname); // editarmature.c
555         WM_event_add_notifier(C, NC_OBJECT|ND_BONE_SELECT, CTX_data_edit_object(C)); // XXX fix
556 }
557
558 static void v3d_editarmature_buts(uiBlock *block, View3D *v3d, Object *ob, float lim)
559 {
560         bArmature *arm= ob->data;
561         EditBone *ebone;
562         uiBut *but;
563         TransformProperties *tfp= v3d->properties_storage;
564         
565         ebone= arm->edbo->first;
566
567         for (ebone = arm->edbo->first; ebone; ebone=ebone->next){
568                 if ((ebone->flag & BONE_ACTIVE) && (ebone->layer & arm->layer))
569                         break;
570         }
571
572         if (!ebone)
573                 return;
574         
575         if((ob->parent) && (ob->partype == PARBONE))
576                 but= uiDefBut(block, TEX, B_NOP, "Bone:", 160, 130, 140, 19, ebone->name, 1, 31, 0, 0, "");
577         else
578                 but= uiDefBut(block, TEX, B_NOP, "Bone:",                       160, 150, 140, 19, ebone->name, 1, 31, 0, 0, "");
579         uiButSetFunc(but, validate_editbonebutton_cb, ebone, NULL);
580
581         uiBlockBeginAlign(block);
582         uiDefButF(block, NUM, B_ARMATUREPANEL1, "HeadX:",       10, 70, 140, 19, ebone->head, -lim, lim, 10, 3, "");
583         uiDefButF(block, NUM, B_ARMATUREPANEL1, "HeadY:",       10, 50, 140, 19, ebone->head+1, -lim, lim, 10, 3, "");
584         uiDefButF(block, NUM, B_ARMATUREPANEL1, "HeadZ:",       10, 30, 140, 19, ebone->head+2, -lim, lim, 10, 3, "");
585         uiBlockBeginAlign(block);
586         uiDefButF(block, NUM, B_ARMATUREPANEL1, "TailX:",       160, 70, 140, 19, ebone->tail, -lim, lim, 10, 3, "");
587         uiDefButF(block, NUM, B_ARMATUREPANEL1, "TailY:",       160, 50, 140, 19, ebone->tail+1, -lim, lim, 10, 3, "");
588         uiDefButF(block, NUM, B_ARMATUREPANEL1, "TailZ:",       160, 30, 140, 19, ebone->tail+2, -lim, lim, 10, 3, "");
589         uiBlockEndAlign(block);
590         
591         tfp->ob_eul[0]= 180.0*ebone->roll/M_PI;
592         uiDefButF(block, NUM, B_ARMATUREPANEL1, "Roll:",        10, 100, 140, 19, tfp->ob_eul, -lim, lim, 1000, 3, "");
593
594         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");
595         
596         uiBlockBeginAlign(block);
597         uiDefButF(block, NUM, B_ARMATUREPANEL1, "TailRadius:",  10, 150, 140, 19, &ebone->rad_tail, 0, lim, 10, 3, "");
598         if (ebone->parent && ebone->flag & BONE_CONNECTED )
599                 uiDefButF(block, NUM, B_ARMATUREPANEL1, "HeadRadius:",  10, 130, 140, 19, &ebone->parent->rad_tail, 0, lim, 10, 3, "");
600         else
601                 uiDefButF(block, NUM, B_ARMATUREPANEL1, "HeadRadius:",  10, 130, 140, 19, &ebone->rad_head, 0, lim, 10, 3, "");
602         uiBlockEndAlign(block);
603 }
604
605 static void v3d_editmetaball_buts(uiBlock *block, Object *ob, float lim)
606 {
607         MetaElem *lastelem= NULL; // XXX
608
609         if(lastelem) {
610                 uiBlockBeginAlign(block);
611                 uiDefButF(block, NUM, B_RECALCMBALL, "LocX:", 10, 70, 140, 19, &lastelem->x, -lim, lim, 100, 3, "");
612                 uiDefButF(block, NUM, B_RECALCMBALL, "LocY:", 10, 50, 140, 19, &lastelem->y, -lim, lim, 100, 3, "");
613                 uiDefButF(block, NUM, B_RECALCMBALL, "LocZ:", 10, 30, 140, 19, &lastelem->z, -lim, lim, 100, 3, "");
614
615                 uiBlockBeginAlign(block);
616                 if(lastelem->type!=MB_BALL)
617                         uiDefButF(block, NUM, B_RECALCMBALL, "dx:", 160, 70, 140, 19, &lastelem->expx, 0, lim, 100, 3, "");
618                 if((lastelem->type!=MB_BALL) && (lastelem->type!=MB_TUBE))
619                         uiDefButF(block, NUM, B_RECALCMBALL, "dy:", 160, 50, 140, 19, &lastelem->expy, 0, lim, 100, 3, "");
620                 if((lastelem->type==MB_ELIPSOID) || (lastelem->type==MB_CUBE))
621                         uiDefButF(block, NUM, B_RECALCMBALL, "dz:", 160, 30, 140, 19, &lastelem->expz, 0, lim, 100, 3, "");
622
623                 uiBlockEndAlign(block); 
624
625                 uiBlockBeginAlign(block);
626                 uiDefButF(block, NUM, B_RECALCMBALL, "Radius:", 10, 120, 140, 19, &lastelem->rad, 0, lim, 100, 3, "Size of the active metaball");
627                 uiDefButF(block, NUM, B_RECALCMBALL, "Stiffness:", 10, 100, 140, 19, &lastelem->s, 0, 10, 100, 3, "Stiffness of the active metaball");
628                 uiBlockEndAlign(block);
629                 
630                 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");
631                 
632         }
633 }
634
635 /* test if 'ob' is a parent somewhere in par's parents */
636 static int test_parent_loop(Object *par, Object *ob)
637 {
638         if(par == NULL) return 0;
639         if(ob == par) return 1;
640         return test_parent_loop(par->parent, ob);
641 }
642
643 static void do_view3d_region_buttons(bContext *C, void *arg, int event)
644 {
645         Scene *scene= CTX_data_scene(C);
646         Object *obedit= CTX_data_edit_object(C);
647         View3D *v3d= CTX_wm_view3d(C);
648         BoundBox *bb;
649         Object *ob= OBACT;
650         TransformProperties *tfp= v3d->properties_storage;
651         
652         switch(event) {
653         
654         case B_REDR:
655                 ED_area_tag_redraw(CTX_wm_area(C));
656                 return; /* no notifier! */
657                 
658         case B_OBJECTPANEL:
659                 DAG_object_flush_update(scene, ob, OB_RECALC_OB);
660                 break;
661                 
662         case B_OBJECTPANELROT:
663                 if(ob) {
664                         ob->rot[0]= M_PI*tfp->ob_eul[0]/180.0;
665                         ob->rot[1]= M_PI*tfp->ob_eul[1]/180.0;
666                         ob->rot[2]= M_PI*tfp->ob_eul[2]/180.0;
667                         DAG_object_flush_update(scene, ob, OB_RECALC_OB);
668                 }
669                 break;
670
671         case B_OBJECTPANELSCALE:
672                 if(ob) {
673
674                         /* link scale; figure out which axis changed */
675                         if (tfp->link_scale) {
676                                 float ratio, tmp, max = 0.0;
677                                 int axis;
678                                 
679                                 axis = 0;
680                                 max = fabs(tfp->ob_scale[0] - ob->size[0]);
681                                 tmp = fabs(tfp->ob_scale[1] - ob->size[1]);
682                                 if (tmp > max) {
683                                         axis = 1;
684                                         max = tmp;
685                                 }
686                                 tmp = fabs(tfp->ob_scale[2] - ob->size[2]);
687                                 if (tmp > max) {
688                                         axis = 2;
689                                         max = tmp;
690                                 }
691                         
692                                 if (ob->size[axis] != tfp->ob_scale[axis]) {
693                                         if (fabs(ob->size[axis]) > FLT_EPSILON) {
694                                                 ratio = tfp->ob_scale[axis] / ob->size[axis];
695                                                 ob->size[0] *= ratio;
696                                                 ob->size[1] *= ratio;
697                                                 ob->size[2] *= ratio;
698                                         }
699                                 }
700                         }
701                         else {
702                                 VECCOPY(ob->size, tfp->ob_scale);
703                                 
704                         }
705                         DAG_object_flush_update(scene, ob, OB_RECALC_OB);
706                 }
707                 break;
708
709         case B_OBJECTPANELDIMS:
710                 bb= object_get_boundbox(ob);
711                 if(bb) {
712                         float old_dims[3], scale[3], ratio, len[3];
713                         int axis;
714
715                         Mat4ToSize(ob->obmat, scale);
716
717                         len[0] = bb->vec[4][0] - bb->vec[0][0];
718                         len[1] = bb->vec[2][1] - bb->vec[0][1];
719                         len[2] = bb->vec[1][2] - bb->vec[0][2];
720
721                         old_dims[0] = fabs(scale[0]) * len[0];
722                         old_dims[1] = fabs(scale[1]) * len[1];
723                         old_dims[2] = fabs(scale[2]) * len[2];
724
725                         /* for each axis changed */
726                         for (axis = 0; axis<3; axis++) {
727                                 if (fabs(old_dims[axis] - tfp->ob_dims[axis]) > 0.0001) {
728                                         if (old_dims[axis] > 0.0) {
729                                                 ratio = tfp->ob_dims[axis] / old_dims[axis]; 
730                                                 if (tfp->link_scale) {
731                                                         ob->size[0] *= ratio;
732                                                         ob->size[1] *= ratio;
733                                                         ob->size[2] *= ratio;
734                                                         break;
735                                                 }
736                                                 else {
737                                                         ob->size[axis] *= ratio;
738                                                 }
739                                         }
740                                         else {
741                                                 if (len[axis] > 0) {
742                                                         ob->size[axis] = tfp->ob_dims[axis] / len[axis];
743                                                 }
744                                         }
745                                 }
746                         }
747                         
748                         /* prevent multiple B_OBJECTPANELDIMS events to keep scaling, cycling with TAB on buttons can cause that */
749                         VECCOPY(tfp->ob_dims, old_dims);
750                         
751                         DAG_object_flush_update(scene, ob, OB_RECALC_OB);
752                 }
753                 break;
754         
755         case B_OBJECTPANELMEDIAN:
756                 if(ob) {
757                         v3d_editvertex_buts(C, NULL, v3d, ob, 1.0);
758                         DAG_object_flush_update(scene, ob, OB_RECALC_DATA);
759                 }
760                 break;
761                 
762                 /* note; this case also used for parbone */
763         case B_OBJECTPANELPARENT:
764                 if(ob) {
765                         if(ob->id.lib || test_parent_loop(ob->parent, ob) ) 
766                                 ob->parent= NULL;
767                         else {
768                                 DAG_scene_sort(scene);
769                                 DAG_object_flush_update(scene, ob, OB_RECALC_OB);
770                         }
771                 }
772                 break;
773                 
774         case B_ARMATUREPANEL1:
775                 {
776                         bArmature *arm= obedit->data;
777                         EditBone *ebone, *child;
778                         
779                         for (ebone = arm->edbo->first; ebone; ebone=ebone->next){
780                                 if ((ebone->flag & BONE_ACTIVE) && (ebone->layer & arm->layer))
781                                         break;
782                         }
783                         if (ebone) {
784                                 ebone->roll= M_PI*tfp->ob_eul[0]/180.0;
785                                 //      Update our parent
786                                 if (ebone->parent && ebone->flag & BONE_CONNECTED){
787                                         VECCOPY (ebone->parent->tail, ebone->head);
788                                 }
789                         
790                                 //      Update our children if necessary
791                                 for (child = arm->edbo->first; child; child=child->next){
792                                         if (child->parent == ebone && (child->flag & BONE_CONNECTED)){
793                                                 VECCOPY (child->head, ebone->tail);
794                                         }
795                                 }
796                                 if(arm->flag & ARM_MIRROR_EDIT) {
797                                         EditBone *eboflip= ED_armature_bone_get_mirrored(arm->edbo, ebone);
798                                         if(eboflip) {
799                                                 eboflip->roll= -ebone->roll;
800                                                 eboflip->head[0]= -ebone->head[0];
801                                                 eboflip->tail[0]= -ebone->tail[0];
802                                                 
803                                                 //      Update our parent
804                                                 if (eboflip->parent && eboflip->flag & BONE_CONNECTED){
805                                                         VECCOPY (eboflip->parent->tail, eboflip->head);
806                                                 }
807                                                 
808                                                 //      Update our children if necessary
809                                                 for (child = arm->edbo->first; child; child=child->next){
810                                                         if (child->parent == eboflip && (child->flag & BONE_CONNECTED)){
811                                                                 VECCOPY (child->head, eboflip->tail);
812                                                         }
813                                                 }
814                                         }
815                                 }
816                         }
817                 }
818                 break;
819         case B_ARMATUREPANEL3:  // rotate button on channel
820                 {
821                         bArmature *arm;
822                         bPoseChannel *pchan;
823                         Bone *bone;
824                         float eul[3];
825                         
826                         arm = ob->data;
827                         if (!arm || !ob->pose) return;
828                                 
829                         for(pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) {
830                                 bone = pchan->bone;
831                                 if(bone && (bone->flag & BONE_ACTIVE) && (bone->layer & arm->layer))
832                                         break;
833                         }
834                         if (!pchan) return;
835                         
836                         /* make a copy to eul[3], to allow TAB on buttons to work */
837                         eul[0]= M_PI*tfp->ob_eul[0]/180.0;
838                         eul[1]= M_PI*tfp->ob_eul[1]/180.0;
839                         eul[2]= M_PI*tfp->ob_eul[2]/180.0;
840                         EulToQuat(eul, pchan->quat);
841                 }
842                 /* no break, pass on */
843         case B_ARMATUREPANEL2:
844                 {
845                         ob->pose->flag |= (POSE_LOCKED|POSE_DO_UNLOCK);
846                         DAG_object_flush_update(scene, ob, OB_RECALC_DATA);
847                 }
848                 break;
849         case B_TRANSFORMSPACEADD:
850                 BIF_manageTransformOrientation(C, 1, 0);
851                 break;
852         case B_TRANSFORMSPACECLEAR:
853                 BIF_clearTransformOrientation(C);
854                 break;
855                 
856 #if 0 // XXX
857         case B_WEIGHT0_0:
858                 wpaint->weight = 0.0f;
859                 break;
860                 
861         case B_WEIGHT1_4:
862                 wpaint->weight = 0.25f;
863                 break;
864         case B_WEIGHT1_2:
865                 wpaint->weight = 0.5f;
866                 break;
867         case B_WEIGHT3_4:
868                 wpaint->weight = 0.75f;
869                 break;
870         case B_WEIGHT1_0:
871                 wpaint->weight = 1.0f;
872                 break;
873                 
874         case B_OPA1_8:
875                 wpaint->a = 0.125f;
876                 break;
877         case B_OPA1_4:
878                 wpaint->a = 0.25f;
879                 break;
880         case B_OPA1_2:
881                 wpaint->a = 0.5f;
882                 break;
883         case B_OPA3_4:
884                 wpaint->a = 0.75f;
885                 break;
886         case B_OPA1_0:
887                 wpaint->a = 1.0f;
888                 break;
889 #endif
890         case B_CLR_WPAINT:
891 //              if(!multires_level1_test()) {
892                 {
893                         bDeformGroup *defGroup = BLI_findlink(&ob->defbase, ob->actdef-1);
894                         if(defGroup) {
895                                 Mesh *me= ob->data;
896                                 int a;
897                                 for(a=0; a<me->totvert; a++)
898                                         remove_vert_defgroup (ob, defGroup, a);
899                                 DAG_object_flush_update(scene, ob, OB_RECALC_DATA);
900                         }
901                 }
902                 break;
903         case B_RV3D_LOCKED:
904         case B_RV3D_BOXVIEW:
905         case B_RV3D_BOXCLIP:
906                 {
907                         ScrArea *sa= CTX_wm_area(C);
908                         ARegion *ar= sa->regionbase.last;
909                         RegionView3D *rv3d;
910                         short viewlock;
911                         
912                         ar= ar->prev;
913                         rv3d= ar->regiondata;
914                         viewlock= rv3d->viewlock;
915                         
916                         if((viewlock & RV3D_LOCKED)==0)
917                                 viewlock= 0;
918                         else if((viewlock & RV3D_BOXVIEW)==0)
919                                 viewlock &= ~RV3D_BOXCLIP;
920                         
921                         for(; ar; ar= ar->prev) {
922                                 if(ar->alignment==RGN_ALIGN_QSPLIT) {
923                                         rv3d= ar->regiondata;
924                                         rv3d->viewlock= viewlock;
925                                 }
926                         }
927                         
928                         if(rv3d->viewlock & RV3D_BOXVIEW)
929                                 view3d_boxview_copy(sa, sa->regionbase.last);
930                         
931                         ED_area_tag_redraw(sa);
932                 }
933                 break;
934         }
935
936         /* default for now */
937         WM_event_add_notifier(C, NC_OBJECT|ND_TRANSFORM, ob);
938 }
939
940 void removeTransformOrientation_func(bContext *C, void *target, void *unused)
941 {
942         BIF_removeTransformOrientation(C, (TransformOrientation *) target);
943 }
944
945 void selectTransformOrientation_func(bContext *C, void *target, void *unused)
946 {
947         BIF_selectTransformOrientation(C, (TransformOrientation *) target);
948 }
949
950 static void view3d_panel_transform_spaces(const bContext *C, Panel *pa)
951 {
952         Scene *scene= CTX_data_scene(C);
953         Object *obedit= CTX_data_edit_object(C);
954         View3D *v3d= CTX_wm_view3d(C);
955         ListBase *transform_spaces = &scene->transform_spaces;
956         TransformOrientation *ts = transform_spaces->first;
957         uiBlock *block;
958         uiBut *but;
959         int xco = 20, yco = 70;
960         int index;
961
962         block= uiLayoutFreeBlock(pa->layout);
963
964         uiBlockBeginAlign(block);
965         
966         if (obedit)
967                 uiDefBut(block, BUT, B_TRANSFORMSPACEADD, "Add", xco,120,80,20, 0, 0, 0, 0, 0, "Add the selected element as a Transform Orientation");
968         else
969                 uiDefBut(block, BUT, B_TRANSFORMSPACEADD, "Add", xco,120,80,20, 0, 0, 0, 0, 0, "Add the active object as a Transform Orientation");
970
971         uiDefBut(block, BUT, B_TRANSFORMSPACECLEAR, "Clear", xco + 80,120,80,20, 0, 0, 0, 0, 0, "Removal all Transform Orientations");
972         
973         uiBlockEndAlign(block);
974         
975         uiBlockBeginAlign(block);
976         
977         uiDefButS(block, ROW, B_REDR, "Global", xco,            90, 40,20, &v3d->twmode, 5.0, (float)V3D_MANIP_GLOBAL,0, 0, "Global Transform Orientation");
978         uiDefButS(block, ROW, B_REDR, "Local",  xco + 40,       90, 40,20, &v3d->twmode, 5.0, (float)V3D_MANIP_LOCAL, 0, 0, "Local Transform Orientation");
979         uiDefButS(block, ROW, B_REDR, "Normal", xco + 80,       90, 40,20, &v3d->twmode, 5.0, (float)V3D_MANIP_NORMAL,0, 0, "Normal Transform Orientation");
980         uiDefButS(block, ROW, B_REDR, "View",           xco + 120,      90, 40,20, &v3d->twmode, 5.0, (float)V3D_MANIP_VIEW,    0, 0, "View Transform Orientation");
981         
982         for (index = V3D_MANIP_CUSTOM, ts = transform_spaces->first ; ts ; ts = ts->next, index++) {
983
984                 if (v3d->twmode == index) {
985                         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");
986                 }
987                 else {
988                         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");
989                 }
990                 uiButSetFunc(but, selectTransformOrientation_func, ts, NULL);
991                 uiDefBut(block, TEX, 0, "", xco+=XIC, yco,100+XIC,20, &ts->name, 0, 30, 0, 0, "Edits the name of this Transform Orientation");
992                 but = uiDefIconBut(block, BUT, B_REDR, ICON_X, xco+=100+XIC,yco,XIC,YIC, 0, 0, 0, 0, 0, "Deletes this Transform Orientation");
993                 uiButSetFunc(but, removeTransformOrientation_func, ts, NULL);
994
995                 xco = 20;
996                 yco -= 25;
997         }
998         uiBlockEndAlign(block);
999 }
1000
1001 static void weight_paint_buttons(Scene *scene, uiBlock *block)
1002 {
1003         VPaint *wpaint= scene->toolsettings->wpaint;
1004         Object *ob;
1005         ob= OBACT;
1006         
1007         if(ob==NULL || ob->type!=OB_MESH) return;
1008
1009         /* XXX  
1010         uiBlockBeginAlign(block);
1011         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");
1012         
1013         uiDefBut(block, BUT, B_WEIGHT0_0 , "0",                  10,150,45,19, 0, 0, 0, 0, 0, "");
1014         uiDefBut(block, BUT, B_WEIGHT1_4 , "1/4",                55,150,45,19, 0, 0, 0, 0, 0, "");
1015         uiDefBut(block, BUT, B_WEIGHT1_2 , "1/2",                100,150,45,19, 0, 0, 0, 0, 0, "");
1016         uiDefBut(block, BUT, B_WEIGHT3_4 , "3/4",                145,150,45,19, 0, 0, 0, 0, 0, "");
1017         uiDefBut(block, BUT, B_WEIGHT1_0 , "1",                  190,150,45,19, 0, 0, 0, 0, 0, "");
1018         
1019         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");
1020         
1021         uiDefBut(block, BUT, B_OPA1_8 , "1/8",          10,110,45,19, 0, 0, 0, 0, 0, "");
1022         uiDefBut(block, BUT, B_OPA1_4 , "1/4",          55,110,45,19, 0, 0, 0, 0, 0, "");
1023         uiDefBut(block, BUT, B_OPA1_2 , "1/2",          100,110,45,19, 0, 0, 0, 0, 0, "");
1024         uiDefBut(block, BUT, B_OPA3_4 , "3/4",          145,110,45,19, 0, 0, 0, 0, 0, "");
1025         uiDefBut(block, BUT, B_OPA1_0 , "1",            190,110,45,19, 0, 0, 0, 0, 0, "");
1026         
1027         uiDefButF(block, NUMSLI, B_NOP, "Size ",        10,90,225,19, &wpaint->size, 2.0, 64.0, 0, 0, "The size of the brush");
1028         
1029         uiBlockBeginAlign(block);
1030         uiDefButS(block, ROW, B_NOP, "Mix",             250,170,60,17, &wpaint->mode, 1.0, 0.0, 0, 0, "Mix the vertex colors");
1031         uiDefButS(block, ROW, B_NOP, "Add",             250,152,60,17, &wpaint->mode, 1.0, 1.0, 0, 0, "Add the vertex colors");
1032         uiDefButS(block, ROW, B_NOP, "Sub",             250,134,60,17, &wpaint->mode, 1.0, 2.0, 0, 0, "Subtract from the vertex color");
1033         uiDefButS(block, ROW, B_NOP, "Mul",             250,116,60,17, &wpaint->mode, 1.0, 3.0, 0, 0, "Multiply the vertex color");
1034         uiDefButS(block, ROW, B_NOP, "Blur",            250, 98,60,17, &wpaint->mode, 1.0, 4.0, 0, 0, "Blur the weight with surrounding values");
1035         uiDefButS(block, ROW, B_NOP, "Lighter", 250, 80,60,17, &wpaint->mode, 1.0, 5.0, 0, 0, "Paint over darker areas only");
1036         uiDefButS(block, ROW, B_NOP, "Darker",          250, 62,60,17, &wpaint->mode, 1.0, 6.0, 0, 0, "Paint over lighter areas only");
1037         uiBlockEndAlign(block);
1038         */
1039         
1040         /* draw options same as below */
1041         uiBlockBeginAlign(block);
1042         if (FACESEL_PAINT_TEST) {
1043                 Mesh *me= ob->data;
1044                 uiDefButBitI(block, TOG, ME_DRAWFACES, B_REDR, "Faces", 10,45,60,19, &me->drawflag, 0, 0, 0, 0, "Displays all faces as shades");
1045                 uiDefButBitI(block,TOG, ME_DRAWEDGES, B_REDR,"Edges",70,45,60,19, &me->drawflag, 2.0, 0, 0, 0,  "Displays edges of visible faces");
1046                 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");
1047         } else{ 
1048                 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");
1049         }
1050         uiBlockEndAlign(block);
1051         
1052         uiBlockBeginAlign(block);
1053         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)");
1054         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)");
1055         uiDefButBitS(block, TOGN, VP_HARD, 0, "Soft",           130,20,60,19, &wpaint->flag, 0, 0, 0, 0, "Use a soft brush");
1056         uiDefButBitS(block, TOG, VP_NORMALS, 0, "Normals",      190,20,60,19, &wpaint->flag, 0, 0, 0, 0, "Applies the vertex normal before painting");
1057         uiDefButBitS(block, TOG, VP_SPRAY, 0, "Spray",          250,20,55,19, &wpaint->flag, 0, 0, 0, 0, "Keep applying paint effect while holding mouse");
1058         uiBlockEndAlign(block);
1059         
1060         if(ob) {
1061                 uiBlockBeginAlign(block);
1062                 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.");
1063                 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");
1064                 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");
1065                 uiBlockEndAlign(block);
1066         }
1067 }
1068
1069 static void brush_idpoin_handle(bContext *C, ID *id, int event)
1070 {
1071         Brush **br = current_brush_source(CTX_data_scene(C));
1072
1073         if(!br)
1074                 return;
1075
1076         switch(event) {
1077         case UI_ID_BROWSE:
1078                 (*br) = (Brush*)id;
1079                 break;
1080         case UI_ID_DELETE:
1081                 brush_delete(br);
1082                 break;
1083         case UI_ID_RENAME:
1084                 /* XXX ? */
1085                 break;
1086         case UI_ID_ADD_NEW:
1087                 if(id) {
1088                         (*br) = copy_brush((Brush*)id);
1089                         id->us--;
1090                 }
1091                 else
1092                         (*br) = add_brush("Brush");
1093                 break;
1094         case UI_ID_OPEN:
1095                 /* XXX not implemented */
1096                 break;
1097         }
1098 }
1099
1100 static int view3d_panel_brush_poll(const bContext *C, PanelType *pt)
1101 {
1102         Brush **brp = current_brush_source(CTX_data_scene(C));
1103
1104         return ((G.f & (G_SCULPTMODE|G_TEXTUREPAINT|G_VERTEXPAINT|G_WEIGHTPAINT)) && brp);
1105 }
1106
1107 static void view3d_panel_brush(const bContext *C, Panel *pa)
1108 {
1109         uiBlock *block;
1110         ToolSettings *ts= CTX_data_tool_settings(C);
1111         Brush **brp = current_brush_source(CTX_data_scene(C)), *br;
1112         short w = 268, h = 400, cx = 10, cy = h;
1113         rctf rect;
1114
1115         br = *brp;
1116
1117         block= uiLayoutFreeBlock(pa->layout);
1118         uiBlockSetHandleFunc(block, do_view3d_region_buttons, NULL);
1119
1120         uiBlockBeginAlign(block);
1121         uiDefIDPoinButs(block, CTX_data_main(C), NULL, &br->id, ID_BR, NULL, cx, cy,
1122                         brush_idpoin_handle, UI_ID_BROWSE|UI_ID_RENAME|UI_ID_ADD_NEW|UI_ID_OPEN|UI_ID_DELETE|UI_ID_ALONE);
1123         cy-= 25;
1124         uiBlockEndAlign(block);
1125
1126         if(!br)
1127                 return;
1128
1129         if(G.f & G_SCULPTMODE) {
1130                 uiBlockBeginAlign(block);       
1131                 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");
1132                 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");
1133                 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");
1134                 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");
1135                 cy-= 20;
1136                 uiDefButC(block,ROW,B_REDR,"Grab", cx,cy,67,19,&br->sculpt_tool,14,SCULPT_TOOL_GRAB,0,0,"Grabs a group of vertices and moves them with the mouse");
1137                 uiDefButC(block,ROW,B_REDR,"Layer", cx+67,cy,67,19,&br->sculpt_tool,14, SCULPT_TOOL_LAYER,0,0,"Adds a layer of depth");
1138                 uiDefButC(block,ROW,B_REDR,"Flatten", cx+134,cy,67,19,&br->sculpt_tool,14, SCULPT_TOOL_FLATTEN,0,0,"Interactively flatten areas of the model");
1139                 uiDefButC(block,ROW,B_REDR,"Clay", cx+201,cy,67,19,&br->sculpt_tool,14, SCULPT_TOOL_CLAY,0,0,"Build up depth quickly");
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         if(G.f & G_WEIGHTPAINT) {
1148                 uiDefButF(block,NUMSLI,B_NOP,"Weight: ",cx,cy,w,19,&ts->vgroup_weight,0,1.0,0,0,"Set vertex weight");
1149                 cy-= 20;
1150         }
1151         uiDefButF(block,NUMSLI,B_NOP,"Strength: ",cx,cy,w,19,&br->alpha,0,1.0,0,0,"Set brush strength");
1152         cy-= 25;
1153         uiBlockEndAlign(block);
1154
1155         uiBlockBeginAlign(block);
1156
1157         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");
1158         uiDefButBitS(block, TOG, BRUSH_RAKE, B_NOP, "Rake", cx+w/3,cy,w/3,19, &br->flag,0,0,0,0, "");
1159         uiDefButBitS(block, TOG, BRUSH_ANCHORED, B_NOP, "Anchored", cx+w*2.0/3,cy,w/3,19, &br->flag,0,0,0,0, "");
1160         cy-= 20;
1161         uiDefButBitS(block, TOG, BRUSH_SPACE, B_NOP, "Space", cx,cy,w/3,19, &br->flag,0,0,0,0, "");
1162         uiDefButF(block,NUMSLI,B_NOP,"Spacing: ",cx+w/3,cy,w*2.0/3,19,&br->spacing,1.0,500,0,0,"");
1163         cy-= 20;
1164         uiBlockEndAlign(block);
1165
1166         if(br->curve) {
1167                 rect.xmin= cx; rect.xmax= cx + w;
1168                 rect.ymin= cy - 200; rect.ymax= cy;
1169                 uiBlockBeginAlign(block);
1170                 curvemap_buttons(block, br->curve, (char)0, B_NOP, 0, &rect);
1171                 uiBlockEndAlign(block);
1172         }
1173 }
1174
1175 static void sculptmode_draw_interface_tools(Scene *scene, uiBlock *block, unsigned short cx, unsigned short cy)
1176 {
1177         Sculpt *s = scene->toolsettings->sculpt;
1178         
1179         //XXX if(sd->brush_type != SMOOTH_BRUSH && sd->brush_type != GRAB_BRUSH && sd->brush_type != FLATTEN_BRUSH) {
1180         {
1181                 /*uiDefButBitS(block,ROW,B_NOP,"Add",cx,cy,89,19,&br->dir,15.0,1.0,0, 0,"Add depth to model [Shift]");
1182                 uiDefButBitS(block,ROW,B_NOP,"Sub",cx+89,cy,89,19,&br->dir,15.0,2.0,0, 0,"Subtract depth from model [Shift]");
1183                 */}
1184         //XXX if(sd->brush_type!=GRAB_BRUSH)
1185         
1186         uiBlockBeginAlign(block);
1187         uiDefBut( block,LABEL,B_NOP,"Symmetry",cx,cy,90,19,NULL,0,0,0,0,"");
1188         cy-= 20;
1189         uiBlockBeginAlign(block);
1190         uiDefButBitI(block, TOG, SCULPT_SYMM_X, B_NOP, "X", cx,cy,40,19, &s->flags, 0,0,0,0, "Mirror brush across X axis");
1191         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");
1192         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");
1193         uiBlockEndAlign(block);
1194         
1195         
1196         cy+= 20;
1197         uiBlockBeginAlign(block);
1198         uiDefBut( block,LABEL,B_NOP,"LockAxis",cx+140,cy,90,19,NULL,0,0,0,0,"");
1199         cy-= 20;
1200         uiBlockBeginAlign(block);
1201         uiDefButBitI(block, TOG, SCULPT_LOCK_X, B_NOP, "X", cx+140,cy,40,19, &s->flags, 0,0,0,0, "Constrain X axis");
1202         uiDefButBitI(block, TOG, SCULPT_LOCK_Y, B_NOP, "Y", cx+180,cy,40,19, &s->flags, 0,0,0,0, "Constrain Y axis");
1203         uiDefButBitI(block, TOG, SCULPT_LOCK_Z, B_NOP, "Z", cx+220,cy,40,19, &s->flags, 0,0,0,0, "Constrain Z axis");
1204         uiBlockEndAlign(block);
1205                 
1206         cx+= 210;
1207 }
1208
1209
1210 static void view3d_panel_object(const bContext *C, Panel *pa)
1211 {
1212         uiBlock *block;
1213         Scene *scene= CTX_data_scene(C);
1214         Object *obedit= CTX_data_edit_object(C);
1215         View3D *v3d= CTX_wm_view3d(C);
1216         uiBut *bt;
1217         Object *ob= OBACT;
1218         TransformProperties *tfp;
1219         float lim;
1220         static char hexcol[128];
1221         
1222         if(ob==NULL) return;
1223
1224         /* make sure we got storage */
1225         if(v3d->properties_storage==NULL)
1226                 v3d->properties_storage= MEM_callocN(sizeof(TransformProperties), "TransformProperties");
1227         tfp= v3d->properties_storage;
1228         
1229         block= uiLayoutFreeBlock(pa->layout);
1230         uiBlockSetHandleFunc(block, do_view3d_region_buttons, NULL);
1231
1232 // XXX  uiSetButLock(object_is_libdata(ob), ERROR_LIBDATA_MESSAGE);
1233         
1234         if(G.f & (G_VERTEXPAINT|G_TEXTUREPAINT|G_WEIGHTPAINT)) {
1235         }
1236         else {
1237                 bt= uiDefBut(block, TEX, B_IDNAME, "OB: ",      10,180,140,20, ob->id.name+2, 0.0, 21.0, 0, 0, "");
1238                 uiButSetFunc(bt, test_idbutton_cb, ob->id.name, NULL);
1239
1240                 if((G.f & G_PARTICLEEDIT)==0) {
1241                         uiBlockBeginAlign(block);
1242                         uiDefIDPoinBut(block, test_obpoin_but, ID_OB, B_OBJECTPANELPARENT, "Par:", 160, 180, 140, 20, &ob->parent, "Parent Object"); 
1243                         if((ob->parent) && (ob->partype == PARBONE)) {
1244                                 bt= uiDefBut(block, TEX, B_OBJECTPANELPARENT, "ParBone:", 160, 160, 140, 20, ob->parsubstr, 0, 30, 0, 0, "");
1245                                 uiButSetCompleteFunc(bt, autocomplete_bone, (void *)ob->parent);
1246                         }
1247                         else {
1248                                 strcpy(ob->parsubstr, "");
1249                         }
1250                         uiBlockEndAlign(block);
1251                 }
1252         }
1253
1254         lim= 10000.0f*MAX2(1.0, v3d->grid);
1255
1256         if(ob==obedit) {
1257                 if(ob->type==OB_ARMATURE) v3d_editarmature_buts(block, v3d, ob, lim);
1258                 if(ob->type==OB_MBALL) v3d_editmetaball_buts(block, ob, lim);
1259                 else v3d_editvertex_buts(C, block, v3d, ob, lim);
1260         }
1261         else if(ob->flag & OB_POSEMODE) {
1262                 v3d_posearmature_buts(block, v3d, ob, lim);
1263         }
1264         else if(G.f & G_WEIGHTPAINT) {
1265                 BLI_strncpy(pa->drawname, "Weight Paint Properties", sizeof(pa->drawname));
1266                 weight_paint_buttons(scene, block);
1267         }
1268         else if(G.f & (G_VERTEXPAINT|G_TEXTUREPAINT)) {
1269                 static float hsv[3], old[3];    // used as temp mem for picker
1270                 Brush **br = current_brush_source(scene);
1271
1272                 BLI_strncpy(pa->drawname, "Paint Properties", sizeof(pa->drawname));
1273                 if(br && *br)
1274                         /* 'f' is for floating panel */
1275                         uiBlockPickerButtons(block, (*br)->rgb, hsv, old, hexcol, 'f', B_REDR);
1276         }
1277         else if(G.f & G_SCULPTMODE) {
1278                 BLI_strncpy(pa->drawname, "Sculpt Properties", sizeof(pa->drawname));
1279                 sculptmode_draw_interface_tools(scene, block, 10, 150);
1280         } 
1281         else if(G.f & G_PARTICLEEDIT){
1282                 BLI_strncpy(pa->drawname, "Particle Edit Properties", sizeof(pa->drawname));
1283 // XXX          particle_edit_buttons(block);
1284         } 
1285         else {
1286                 BoundBox *bb = NULL;
1287
1288                 uiBlockBeginAlign(block);
1289                 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");
1290                 uiDefButF(block, NUM, B_OBJECTPANEL, "LocX:",           30, 150, 120, 19, &(ob->loc[0]), -lim, lim, 100, 3, "");
1291                 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");
1292                 uiDefButF(block, NUM, B_OBJECTPANEL, "LocY:",           30, 130, 120, 19, &(ob->loc[1]), -lim, lim, 100, 3, "");
1293                 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");
1294                 uiDefButF(block, NUM, B_OBJECTPANEL, "LocZ:",           30, 110, 120, 19, &(ob->loc[2]), -lim, lim, 100, 3, "");
1295                 
1296                 tfp->ob_eul[0]= 180.0*ob->rot[0]/M_PI;
1297                 tfp->ob_eul[1]= 180.0*ob->rot[1]/M_PI;
1298                 tfp->ob_eul[2]= 180.0*ob->rot[2]/M_PI;
1299                 
1300                 uiBlockBeginAlign(block);
1301                 if ((ob->parent) && (ob->partype == PARBONE)) {
1302                         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");
1303                         uiDefButF(block, NUM, B_OBJECTPANELROT, "RotX:",        180, 130, 120, 19, &(tfp->ob_eul[0]), -lim, lim, 1000, 3, "");
1304                         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");
1305                         uiDefButF(block, NUM, B_OBJECTPANELROT, "RotY:",        180, 110, 120, 19, &(tfp->ob_eul[1]), -lim, lim, 1000, 3, "");
1306                         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");
1307                         uiDefButF(block, NUM, B_OBJECTPANELROT, "RotZ:",        180, 90, 120, 19, &(tfp->ob_eul[2]), -lim, lim, 1000, 3, "");
1308
1309                 }
1310                 else {
1311                         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");
1312                         uiDefButF(block, NUM, B_OBJECTPANELROT, "RotX:",        180, 150, 120, 19, &(tfp->ob_eul[0]), -lim, lim, 1000, 3, "");
1313                         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");
1314                         uiDefButF(block, NUM, B_OBJECTPANELROT, "RotY:",        180, 130, 120, 19, &(tfp->ob_eul[1]), -lim, lim, 1000, 3, "");
1315                         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");
1316                         uiDefButF(block, NUM, B_OBJECTPANELROT, "RotZ:",        180, 110, 120, 19, &(tfp->ob_eul[2]), -lim, lim, 1000, 3, "");
1317                 }
1318
1319                 tfp->ob_scale[0]= ob->size[0];
1320                 tfp->ob_scale[1]= ob->size[1];
1321                 tfp->ob_scale[2]= ob->size[2];
1322
1323                 uiBlockBeginAlign(block);
1324                 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");
1325                 uiDefButF(block, NUM, B_OBJECTPANELSCALE, "ScaleX:",            30, 80, 120, 19, &(tfp->ob_scale[0]), -lim, lim, 10, 3, "");
1326                 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");
1327                 uiDefButF(block, NUM, B_OBJECTPANELSCALE, "ScaleY:",            30, 60, 120, 19, &(tfp->ob_scale[1]), -lim, lim, 10, 3, "");
1328                 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");
1329                 uiDefButF(block, NUM, B_OBJECTPANELSCALE, "ScaleZ:",            30, 40, 120, 19, &(tfp->ob_scale[2]), -lim, lim, 10, 3, "");
1330                 uiBlockEndAlign(block);
1331                 
1332                 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");
1333
1334                 bb= object_get_boundbox(ob);
1335                 if (bb) {
1336                         float scale[3];
1337
1338                         Mat4ToSize(ob->obmat, scale);
1339
1340                         tfp->ob_dims[0] = fabs(scale[0]) * (bb->vec[4][0] - bb->vec[0][0]);
1341                         tfp->ob_dims[1] = fabs(scale[1]) * (bb->vec[2][1] - bb->vec[0][1]);
1342                         tfp->ob_dims[2] = fabs(scale[2]) * (bb->vec[1][2] - bb->vec[0][2]);
1343
1344                         uiBlockBeginAlign(block);
1345                         if ((ob->parent) && (ob->partype == PARBONE)) {
1346                                 uiDefButF(block, NUM, B_OBJECTPANELDIMS, "DimX:",               160, 60, 140, 19, &(tfp->ob_dims[0]), 0.0, lim, 10, 3, "Manipulate bounding box size");
1347                                 uiDefButF(block, NUM, B_OBJECTPANELDIMS, "DimY:",               160, 40, 140, 19, &(tfp->ob_dims[1]), 0.0, lim, 10, 3, "Manipulate bounding box size");
1348                                 uiDefButF(block, NUM, B_OBJECTPANELDIMS, "DimZ:",               160, 20, 140, 19, &(tfp->ob_dims[2]), 0.0, lim, 10, 3, "Manipulate bounding box size");
1349
1350                         }
1351                         else {
1352                                 uiDefButF(block, NUM, B_OBJECTPANELDIMS, "DimX:",               160, 80, 140, 19, &(tfp->ob_dims[0]), 0.0, lim, 10, 3, "Manipulate bounding box size");
1353                                 uiDefButF(block, NUM, B_OBJECTPANELDIMS, "DimY:",               160, 60, 140, 19, &(tfp->ob_dims[1]), 0.0, lim, 10, 3, "Manipulate bounding box size");
1354                                 uiDefButF(block, NUM, B_OBJECTPANELDIMS, "DimZ:",               160, 40, 140, 19, &(tfp->ob_dims[2]), 0.0, lim, 10, 3, "Manipulate bounding box size");
1355                         }
1356
1357                         uiBlockEndAlign(block);
1358                 }
1359         }
1360 }
1361
1362 static void view3d_panel_background(const bContext *C, Panel *pa)
1363 {
1364         View3D *v3d= CTX_wm_view3d(C);
1365         uiBlock *block;
1366
1367         block= uiLayoutFreeBlock(pa->layout);
1368         uiBlockSetHandleFunc(block, do_view3d_region_buttons, NULL);
1369
1370         if(v3d->flag & V3D_DISPBGPIC) {
1371                 if(v3d->bgpic==NULL) {
1372                         v3d->bgpic= MEM_callocN(sizeof(BGpic), "bgpic");
1373                         v3d->bgpic->size= 5.0;
1374                         v3d->bgpic->blend= 0.5;
1375                         v3d->bgpic->iuser.fie_ima= 2;
1376                         v3d->bgpic->iuser.ok= 1;
1377                 }
1378         }
1379         
1380         if(!(v3d->flag & V3D_DISPBGPIC)) {
1381                 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");
1382                 uiDefBut(block, LABEL, 1, " ",  160, 180, 150, 20, NULL, 0.0, 0.0, 0, 0, "");
1383         }
1384         else {
1385                 uiBlockBeginAlign(block);
1386                 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");
1387                 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");
1388                 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");
1389
1390                 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");
1391                 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");
1392                 
1393                 ED_image_uiblock_panel(C, block, &v3d->bgpic->ima, &v3d->bgpic->iuser, B_REDR, B_REDR);
1394                 uiBlockEndAlign(block);
1395         }
1396 }
1397
1398
1399 static void view3d_panel_properties(const bContext *C, Panel *pa)
1400 {
1401         ScrArea *sa= CTX_wm_area(C);
1402         ARegion *arlast;
1403         Scene *scene= CTX_data_scene(C);
1404         View3D *v3d= CTX_wm_view3d(C);
1405         RegionView3D *rv3d;
1406         uiBlock *block;
1407         float *curs;
1408
1409         block= uiLayoutFreeBlock(pa->layout);
1410         uiBlockSetHandleFunc(block, do_view3d_region_buttons, NULL);
1411
1412         uiDefBut(block, LABEL, 1, "Grid:",                                      10, 220, 150, 19, NULL, 0.0, 0.0, 0, 0, "");
1413         uiBlockBeginAlign(block);
1414         uiDefButF(block, NUM, B_REDR, "Spacing:",               10, 200, 140, 19, &v3d->grid, 0.001, 100.0, 10, 0, "Set the distance between grid lines");
1415         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");
1416         uiDefButS(block, NUM, B_REDR, "Divisions:",             10, 160, 140, 19, &v3d->gridsubdiv, 1.0, 100.0, 100, 0, "Set the number of grid lines");
1417         uiBlockEndAlign(block);
1418
1419         uiDefBut(block, LABEL, 1, "3D Display:",                                                        160, 220, 150, 19, NULL, 0.0, 0.0, 0, 0, "");
1420         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");
1421         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");
1422         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");
1423         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");
1424
1425         uiDefBut(block, LABEL, 1, "View Camera:",                       10, 140, 140, 19, NULL, 0.0, 0.0, 0, 0, "");
1426         
1427         uiDefButF(block, NUM, B_REDR, "Lens:",          10, 120, 140, 19, &v3d->lens, 10.0, 120.0, 100, 0, "The lens angle in perspective view");
1428         uiBlockBeginAlign(block);
1429         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)");
1430         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)");
1431         uiBlockEndAlign(block);
1432
1433         uiDefBut(block, LABEL, 1, "3D Cursor:",                         160, 150, 140, 19, NULL, 0.0, 0.0, 0, 0, "");
1434
1435         uiBlockBeginAlign(block);
1436         curs= give_cursor(scene, v3d);
1437         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");
1438         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");
1439         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");
1440         uiBlockEndAlign(block);
1441
1442         uiDefBut(block, LABEL, 1, "Display:",                           10, 50, 150, 19, NULL, 0.0, 0.0, 0, 0, "");
1443         uiBlockBeginAlign(block);
1444         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");
1445         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");
1446         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");
1447         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)");
1448         uiBlockEndAlign(block);
1449
1450         uiDefBut(block, LABEL, 1, "View Locking:",                              160, 60, 150, 19, NULL, 0.0, 0.0, 0, 0, "");
1451         uiBlockBeginAlign(block);
1452         uiDefIDPoinBut(block, test_obpoin_but, ID_OB, B_REDR, "Object:", 160, 40, 150, 19, &v3d->ob_centre, "Lock view to center to this Object"); 
1453         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");
1454         uiBlockEndAlign(block); 
1455
1456         /* last region is always 3d... a bit weak */
1457         arlast= sa->regionbase.last;
1458         uiBlockBeginAlign(block);
1459         if(arlast->alignment==RGN_ALIGN_QSPLIT) {
1460                 arlast= arlast->prev;
1461                 rv3d= arlast->regiondata;
1462                 
1463                 uiDefButO(block, BUT, "SCREEN_OT_region_foursplit", WM_OP_EXEC_REGION_WIN, "End 4-Split View", 160, -10, 150, 19, "Join the 3D View");
1464                 uiDefButBitS(block, TOG, RV3D_LOCKED, B_RV3D_LOCKED, "Lock", 160, -30, 50, 19, &rv3d->viewlock, 0, 0, 0, 0, "");
1465                 uiDefButBitS(block, TOG, RV3D_BOXVIEW, B_RV3D_BOXVIEW, "Box", 210, -30, 50, 19, &rv3d->viewlock, 0, 0, 0, 0, "");
1466                 uiDefButBitS(block, TOG, RV3D_BOXCLIP, B_RV3D_BOXCLIP, "Clip", 260, -30, 50, 19, &rv3d->viewlock, 0, 0, 0, 0, "");
1467         }               
1468         else
1469                 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");
1470                 
1471         uiBlockEndAlign(block); 
1472                 
1473         
1474 // XXX
1475 //      uiDefBut(block, LABEL, 1, "Keyframe Display:",                          160, -2, 150, 19, NULL, 0.0, 0.0, 0, 0, "");
1476 //      uiBlockBeginAlign(block);
1477 //      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)");
1478 //      uiDefButBitS(block, TOG, ANIMFILTER_MUTED, B_REDR, "Muted",210, -22, 50, 19, &v3d->keyflags, 0, 0, 0, 0, "Show keyframes in muted channels");
1479 //      uiDefButBitS(block, TOG, ANIMFILTER_LOCAL, B_REDR, "Local",260, -22, 50, 19, &v3d->keyflags, 0, 0, 0, 0, "Show keyframes directly connected to datablock");
1480 //      if ((v3d->keyflags & ANIMFILTER_LOCAL)==0) {
1481 //              uiDefButBitS(block, TOGN, ANIMFILTER_NOMAT, B_REDR, "Material",160, -42, 75, 19, &v3d->keyflags, 0, 0, 0, 0, "Show keyframes for any available Materials");
1482 //              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");
1483 //      }
1484         uiBlockEndAlign(block); 
1485 }
1486
1487 #if 0
1488 static void view3d_panel_preview(bContext *C, ARegion *ar, short cntrl) // VIEW3D_HANDLER_PREVIEW
1489 {
1490         uiBlock *block;
1491         View3D *v3d= sa->spacedata.first;
1492         int ofsx, ofsy;
1493         
1494         block= uiBeginBlock(C, ar, "view3d_panel_preview", UI_EMBOSS);
1495         uiPanelControl(UI_PNL_SOLID | UI_PNL_CLOSE | UI_PNL_SCALE | cntrl);
1496         uiSetPanelHandler(VIEW3D_HANDLER_PREVIEW);  // for close and esc
1497         
1498         ofsx= -150+(sa->winx/2)/v3d->blockscale;
1499         ofsy= -100+(sa->winy/2)/v3d->blockscale;
1500         if(uiNewPanel(C, ar, block, "Preview", "View3d", ofsx, ofsy, 300, 200)==0) return;
1501
1502         uiBlockSetDrawExtraFunc(block, BIF_view3d_previewdraw);
1503         
1504         if(scene->recalc & SCE_PRV_CHANGED) {
1505                 scene->recalc &= ~SCE_PRV_CHANGED;
1506                 //printf("found recalc\n");
1507                 BIF_view3d_previewrender_free(sa->spacedata.first);
1508                 BIF_preview_changed(0);
1509         }
1510 }
1511 #endif
1512
1513 #if 0
1514 static void view3d_panel_gpencil(const bContext *C, Panel *pa)
1515 {
1516         View3D *v3d= CTX_wm_view3d(C);
1517         uiBlock *block;
1518
1519         block= uiLayoutFreeBlock(pa->layout);
1520
1521         /* allocate memory for gpd if drawing enabled (this must be done first or else we crash) */
1522         if (v3d->flag2 & V3D_DISPGP) {
1523 //              if (v3d->gpd == NULL)
1524 // XXX                  gpencil_data_setactive(ar, gpencil_data_addnew());
1525         }
1526         
1527         if (v3d->flag2 & V3D_DISPGP) {
1528 // XXX          bGPdata *gpd= v3d->gpd;
1529                 
1530                 /* draw button for showing gpencil settings and drawings */
1531                 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)");
1532         }
1533         else {
1534                 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");
1535                 uiDefBut(block, LABEL, 1, " ",  160, 180, 150, 20, NULL, 0.0, 0.0, 0, 0, "");
1536         }
1537 }
1538 #endif
1539
1540 static void delete_sketch_armature(bContext *C, void *arg1, void *arg2)
1541 {
1542         BIF_deleteSketch(C);
1543 }
1544
1545 static void convert_sketch_armature(bContext *C, void *arg1, void *arg2)
1546 {
1547         BIF_convertSketch(C);
1548 }
1549
1550 static void assign_template_sketch_armature(bContext *C, void *arg1, void *arg2)
1551 {
1552         int index = *(int*)arg1;
1553         BIF_setTemplate(C, index);
1554 }
1555
1556 static int view3d_panel_bonesketch_spaces_poll(const bContext *C, PanelType *pt)
1557 {
1558         Object *obedit = CTX_data_edit_object(C);
1559
1560         /* replace with check call to sketching lib */
1561         return (obedit && obedit->type == OB_ARMATURE);
1562 }
1563 static void view3d_panel_bonesketch_spaces(const bContext *C, Panel *pa)
1564 {
1565         Scene *scene = CTX_data_scene(C);
1566         static int template_index;
1567         static char joint_label[128];
1568         uiBlock *block;
1569         uiBut *but;
1570         char *bone_name;
1571         int yco = 130;
1572         int nb_joints;
1573         static char subdiv_tooltip[4][64] = {
1574                 "Subdivide arcs based on a fixed number of bones",
1575                 "Subdivide arcs in bones of equal length",
1576                 "Subdivide arcs based on correlation",
1577                 "Retarget template to stroke"
1578                 };
1579
1580         
1581         block= uiLayoutFreeBlock(pa->layout);
1582         uiBlockSetHandleFunc(block, do_view3d_region_buttons, NULL);
1583
1584         uiBlockBeginAlign(block);
1585         
1586         /* use real flag instead of 1 */
1587         uiDefButBitC(block, TOG, BONE_SKETCHING, B_REDR, "Use Bone Sketching", 10, yco, 160, 20, &scene->toolsettings->bone_sketching, 0, 0, 0, 0, "Use sketching to create and edit bones, (Ctrl snaps to mesh volume)");
1588         uiDefButBitC(block, TOG, BONE_SKETCHING_ADJUST, B_REDR, "A", 170, yco, 20, 20, &scene->toolsettings->bone_sketching, 0, 0, 0, 0, "Adjust strokes by drawing near them");
1589         uiDefButBitC(block, TOG, BONE_SKETCHING_QUICK, B_REDR, "Q", 190, yco, 20, 20, &scene->toolsettings->bone_sketching, 0, 0, 0, 0, "Automatically convert and delete on stroke end");
1590         yco -= 20;
1591         
1592         but = uiDefBut(block, BUT, B_REDR, "Convert", 10,yco,100,20, 0, 0, 0, 0, 0, "Convert sketch to armature");
1593         uiButSetFunc(but, convert_sketch_armature, NULL, NULL);
1594
1595         but = uiDefBut(block, BUT, B_REDR, "Delete", 110,yco,100,20, 0, 0, 0, 0, 0, "Delete sketch");
1596         uiButSetFunc(but, delete_sketch_armature, NULL, NULL);
1597         yco -= 20;
1598         
1599         uiBlockEndAlign(block);
1600
1601         uiBlockBeginAlign(block);
1602         
1603         uiDefButC(block, MENU, B_REDR, "Subdivision Method%t|Length%x1|Adaptative%x2|Fixed%x0|Template%x3", 10,yco,60,19, &scene->toolsettings->bone_sketching_convert, 0, 0, 0, 0, subdiv_tooltip[(unsigned char)scene->toolsettings->bone_sketching_convert]);
1604
1605         switch(scene->toolsettings->bone_sketching_convert)
1606         {
1607         case SK_CONVERT_CUT_LENGTH:
1608                 uiDefButF(block, NUM, B_REDR,                                   "Lim:",         70, yco, 140, 19, &scene->toolsettings->skgen_length_limit,0.1,50.0, 10, 0,             "Maximum length of the subdivided bones");
1609                 yco -= 20;
1610                 break;
1611         case SK_CONVERT_CUT_ADAPTATIVE:
1612                 uiDefButF(block, NUM, B_REDR,                                   "Thres:",                       70, yco, 140, 19, &scene->toolsettings->skgen_correlation_limit,0.0, 1.0, 0.01, 0,      "Correlation threshold for subdivision");
1613                 yco -= 20;
1614                 break;
1615         default:
1616         case SK_CONVERT_CUT_FIXED:
1617                 uiDefButC(block, NUM, B_REDR,                                   "Num:",         70, yco, 140, 19, &scene->toolsettings->skgen_subdivision_number,1, 100, 1, 5,  "Number of subdivided bones");
1618                 yco -= 20;
1619                 break;
1620         case SK_CONVERT_RETARGET:
1621                 uiDefButC(block, ROW, B_NOP, "No",                      70,  yco, 40,19, &scene->toolsettings->skgen_retarget_roll, 0, 0, 0, 0,                                                                 "No special roll treatment");
1622                 uiDefButC(block, ROW, B_NOP, "View",            110,  yco, 50,19, &scene->toolsettings->skgen_retarget_roll, 0, SK_RETARGET_ROLL_VIEW, 0, 0,                            "Roll bones perpendicular to view");
1623                 uiDefButC(block, ROW, B_NOP, "Joint",           160, yco, 50,19, &scene->toolsettings->skgen_retarget_roll, 0, SK_RETARGET_ROLL_JOINT, 0, 0,                            "Roll bones relative to joint bend");
1624                 yco -= 30;
1625
1626                 uiBlockEndAlign(block);
1627
1628                 uiBlockBeginAlign(block);
1629                 /* button here to select what to do (copy or not), template, ...*/
1630
1631                 BIF_makeListTemplates(C);
1632                 template_index = BIF_currentTemplate(C);
1633                 
1634                 but = uiDefButI(block, MENU, B_REDR, BIF_listTemplates(C), 10,yco,200,19, &template_index, 0, 0, 0, 0, "Template");
1635                 uiButSetFunc(but, assign_template_sketch_armature, &template_index, NULL);
1636                 
1637                 yco -= 20;
1638                 
1639                 uiDefButF(block, NUM, B_NOP,                                                    "A:",                   10, yco, 66,19, &scene->toolsettings->skgen_retarget_angle_weight, 0, 10, 1, 0,         "Angle Weight");
1640                 uiDefButF(block, NUM, B_NOP,                                                    "L:",                   76, yco, 67,19, &scene->toolsettings->skgen_retarget_length_weight, 0, 10, 1, 0,                "Length Weight");
1641                 uiDefButF(block, NUM, B_NOP,                                                    "D:",           143,yco, 67,19, &scene->toolsettings->skgen_retarget_distance_weight, 0, 10, 1, 0,              "Distance Weight");
1642                 yco -= 20;
1643                 
1644                 uiDefBut(block, TEX,B_REDR,"S:",                                                        10,  yco, 90, 20, scene->toolsettings->skgen_side_string, 0.0, 8.0, 0, 0, "Text to replace &S with");
1645                 uiDefBut(block, TEX,B_REDR,"N:",                                                        100, yco, 90, 20, scene->toolsettings->skgen_num_string, 0.0, 8.0, 0, 0, "Text to replace &N with");
1646                 uiDefIconButBitC(block, TOG, SK_RETARGET_AUTONAME, B_NOP, ICON_AUTO,190,yco,20,20, &scene->toolsettings->skgen_retarget_options, 0, 0, 0, 0, "Use Auto Naming");        
1647                 yco -= 20;
1648
1649                 /* auto renaming magic */
1650                 uiBlockEndAlign(block);
1651                 
1652                 nb_joints = BIF_nbJointsTemplate(C);
1653
1654                 if (nb_joints == -1)
1655                 {
1656                         //XXX
1657                         //nb_joints = G.totvertsel;
1658                 }
1659                 
1660                 bone_name = BIF_nameBoneTemplate(C);
1661                 
1662                 BLI_snprintf(joint_label, 32, "%i joints: %s", nb_joints, bone_name);
1663                 
1664                 uiDefBut(block, LABEL, 1, joint_label,                                  10, yco, 200, 20, NULL, 0.0, 0.0, 0, 0, "");
1665                 yco -= 20;
1666                 break;
1667         }
1668
1669         uiBlockEndAlign(block);
1670         
1671         uiDefButBitS(block, TOG, SCE_SNAP_PEEL_OBJECT, B_NOP, "Peel Objects", 10, yco, 200, 20, &scene->toolsettings->snap_flag, 0, 0, 0, 0, "Peel whole objects as one");
1672 }
1673
1674
1675 /* op->invoke */
1676 static void redo_cb(bContext *C, void *arg_op, void *arg2)
1677 {
1678         wmOperator *lastop= arg_op;
1679         
1680         if(lastop) {
1681                 int retval;
1682                 
1683                 printf("operator redo %s\n", lastop->type->name);
1684                 ED_undo_pop(C);
1685                 retval= WM_operator_repeat(C, lastop);
1686                 if((retval & OPERATOR_FINISHED)==0) {
1687                         printf("operator redo failed %s\n", lastop->type->name);
1688                         ED_undo_redo(C);
1689                 }
1690         }
1691 }
1692
1693 static void view3d_panel_operator_redo(const bContext *C, Panel *pa)
1694 {
1695         wmWindowManager *wm= CTX_wm_manager(C);
1696         wmOperator *op;
1697         PointerRNA ptr;
1698         uiBlock *block;
1699         
1700         block= uiLayoutGetBlock(pa->layout);
1701
1702         /* only for operators that are registered and did an undo push */
1703         for(op= wm->operators.last; op; op= op->prev)
1704                 if((op->type->flag & OPTYPE_REGISTER) && (op->type->flag & OPTYPE_UNDO))
1705                         break;
1706         
1707         if(op==NULL)
1708                 return;
1709         
1710         uiBlockSetFunc(block, redo_cb, op, NULL);
1711         
1712         if(!op->properties) {
1713                 IDPropertyTemplate val = {0};
1714                 op->properties= IDP_New(IDP_GROUP, val, "wmOperatorProperties");
1715         }
1716         
1717         RNA_pointer_create(&wm->id, op->type->srna, op->properties, &ptr);
1718         uiDefAutoButsRNA(C, pa->layout, &ptr, 2);
1719 }
1720
1721 void view3d_buttons_register(ARegionType *art)
1722 {
1723         PanelType *pt;
1724
1725         pt= MEM_callocN(sizeof(PanelType), "spacetype view3d panel object");
1726         strcpy(pt->idname, "VIEW3D_PT_object");
1727         strcpy(pt->label, "Transform Properties");
1728         pt->draw= view3d_panel_object;
1729         BLI_addtail(&art->paneltypes, pt);
1730
1731         pt= MEM_callocN(sizeof(PanelType), "spacetype view3d panel properties");
1732         strcpy(pt->idname, "VIEW3D_PT_properties");
1733         strcpy(pt->label, "View Properties");
1734         pt->draw= view3d_panel_properties;
1735         BLI_addtail(&art->paneltypes, pt);
1736
1737         pt= MEM_callocN(sizeof(PanelType), "spacetype view3d panel background");
1738         strcpy(pt->idname, "VIEW3D_PT_background");
1739         strcpy(pt->label, "Background Image");
1740         pt->draw= view3d_panel_background;
1741         BLI_addtail(&art->paneltypes, pt);
1742
1743         pt= MEM_callocN(sizeof(PanelType), "spacetype view3d panel brush");
1744         strcpy(pt->idname, "VIEW3D_PT_brush");
1745         strcpy(pt->label, "Brush");
1746         pt->draw= view3d_panel_brush;
1747         pt->poll= view3d_panel_brush_poll;
1748         BLI_addtail(&art->paneltypes, pt);
1749
1750         pt= MEM_callocN(sizeof(PanelType), "spacetype view3d panel transform spaces");
1751         strcpy(pt->idname, "VIEW3D_PT_transform spaces");
1752         strcpy(pt->label, "Transform Orientations");
1753         pt->draw= view3d_panel_transform_spaces;
1754         BLI_addtail(&art->paneltypes, pt);
1755
1756         /*pt= MEM_callocN(sizeof(PanelType), "spacetype view3d panel gpencil");
1757         strcpy(pt->idname, "VIEW3D_PT_gpencil");
1758         strcpy(pt->label, "Greas Pencil");
1759         pt->draw= view3d_panel_gpencil;
1760         BLI_addtail(&art->paneltypes, pt);*/
1761
1762         pt= MEM_callocN(sizeof(PanelType), "spacetype view3d panel bonesketch spaces");
1763         strcpy(pt->idname, "VIEW3D_PT_bonesketch_spaces");
1764         strcpy(pt->label, "Bone Sketching");
1765         pt->draw= view3d_panel_bonesketch_spaces;
1766         pt->poll= view3d_panel_bonesketch_spaces_poll;
1767         BLI_addtail(&art->paneltypes, pt);
1768
1769         pt= MEM_callocN(sizeof(PanelType), "spacetype view3d panel redo");
1770         strcpy(pt->idname, "VIEW3D_PT_redo");
1771         strcpy(pt->label, "Last Operator");
1772         pt->draw= view3d_panel_operator_redo;
1773         BLI_addtail(&art->paneltypes, pt);
1774
1775         // XXX view3d_panel_preview(C, ar, 0);
1776 }
1777
1778 static int view3d_properties(bContext *C, wmOperator *op)
1779 {
1780         ScrArea *sa= CTX_wm_area(C);
1781         ARegion *ar= view3d_has_buttons_region(sa);
1782         
1783         if(ar) {
1784                 ar->flag ^= RGN_FLAG_HIDDEN;
1785                 ar->v2d.flag &= ~V2D_IS_INITIALISED; /* XXX should become hide/unhide api? */
1786                 
1787                 ED_area_initialize(CTX_wm_manager(C), CTX_wm_window(C), sa);
1788                 ED_area_tag_redraw(sa);
1789         }
1790         return OPERATOR_FINISHED;
1791 }
1792
1793 void VIEW3D_OT_properties(wmOperatorType *ot)
1794 {
1795         ot->name= "Properties";
1796         ot->idname= "VIEW3D_OT_properties";
1797         
1798         ot->exec= view3d_properties;
1799         ot->poll= ED_operator_view3d_active;
1800         
1801         /* flags */
1802         ot->flag= 0;
1803 }