cecb99eb72bdaf8b7a02b44602505c147d68ce11
[blender-staging.git] / source / blender / editors / space_view3d / view3d_buttons.c
1 /**
2  * $Id:
3  *
4  * ***** BEGIN GPL LICENSE BLOCK *****
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License
8  * as published by the Free Software Foundation; either version 2
9  * of the License, or (at your option) any later version. 
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software Foundation,
18  * Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
19  *
20  * The Original Code is Copyright (C) 2009 Blender Foundation.
21  * All rights reserved.
22  *
23  * 
24  * Contributor(s): Blender Foundation
25  *
26  * ***** END GPL LICENSE BLOCK *****
27  */
28
29 #include <string.h>
30 #include <stdio.h>
31 #include <math.h>
32 #include <float.h>
33
34 #include "DNA_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",            0, 20, 100, 20, &v3d->flag, 0, 0, 0, 0, "Displays global values");
305                 uiDefButBitS(block, TOGN, V3D_GLOBAL_STATS, B_REDR, "Local",            100, 20, 100, 20, &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                         uiDefBut(block, LABEL, 0, "Vertex:",                                    0, 130, 200, 20, 0, 0, 0, 0, 0, "");
313                         uiDefButF(block, NUM, B_OBJECTPANELMEDIAN, "X:",                0, 110, 200, 20, &(tfp->ve_median[0]), -lim, lim, 10, 3, "");
314                         uiDefButF(block, NUM, B_OBJECTPANELMEDIAN, "Y:",                0, 90, 200, 20, &(tfp->ve_median[1]), -lim, lim, 10, 3, "");
315                         uiDefButF(block, NUM, B_OBJECTPANELMEDIAN, "Z:",                0, 70, 200, 20, &(tfp->ve_median[2]), -lim, lim, 10, 3, "");
316                         if(totw==1)
317                                 uiDefButF(block, NUM, B_OBJECTPANELMEDIAN, "Vertex W:", 0, 50, 200, 19, &(tfp->ve_median[3]), 0.01, 100.0, 10, 3, "");
318                         uiBlockEndAlign(block);
319         
320                         if(defstr[0]) {
321                                 uiDefBut(block, LABEL, 1, "Vertex Deform Groups",               0, 40, 200, 20, NULL, 0.0, 0.0, 0, 0, "");
322
323                                 uiBlockBeginAlign(block);
324                                 uiDefButF(block, NUM, B_NOP, "Weight:",                                 10, 20, 150, 20, tfp->defweightp, 0.0f, 1.0f, 10, 3, "Weight value");
325                                 uiDefButI(block, MENU, B_REDR, defstr,                                  160, 20, 140, 20, &tfp->curdef, 0.0, 0.0, 0, 0, "Current Vertex Group");
326                                 uiBlockEndAlign(block);
327                         }
328                         else if(totweight)
329                                 uiDefButF(block, NUM, B_OBJECTPANELMEDIAN, "Weight:",   0, 20, 200, 20, &(tfp->ve_median[4]), 0.0, 1.0, 10, 3, "");
330
331                 }
332                 else {
333                         uiDefBut(block, LABEL, 0, "Median:",                                            0, 130, 200, 20, 0, 0, 0, 0, 0, "");
334                         uiDefButF(block, NUM, B_OBJECTPANELMEDIAN, "X:",                0, 110, 200, 20, &(tfp->ve_median[0]), -lim, lim, 10, 3, "");
335                         uiDefButF(block, NUM, B_OBJECTPANELMEDIAN, "Y:",                0, 90, 200, 20, &(tfp->ve_median[1]), -lim, lim, 10, 3, "");
336                         uiDefButF(block, NUM, B_OBJECTPANELMEDIAN, "Z:",                0, 70, 200, 20, &(tfp->ve_median[2]), -lim, lim, 10, 3, "");
337                         if(totw==tot)
338                                 uiDefButF(block, NUM, B_OBJECTPANELMEDIAN, "W:",        0, 50, 200, 20, &(tfp->ve_median[3]), 0.01, 100.0, 10, 3, "");
339                         uiBlockEndAlign(block);
340                         if(totweight)
341                                 uiDefButF(block, NUM, B_OBJECTPANELMEDIAN, "Weight:",   0, 20, 200, 20, &(tfp->ve_median[4]), 0.0, 1.0, 10, 3, "Weight is used for SoftBody Goal");
342                 }
343                 
344                 if(ob->type==OB_CURVE && (totw==0)) { /* bez curves have no w */
345                         uiBlockBeginAlign(block);
346                         uiDefBut(block, BUT,B_SETPT_AUTO,"Auto",        10, 44, 72, 19, 0, 0, 0, 0, 0, "Auto handles (Shift H)");
347                         uiDefBut(block, BUT,B_SETPT_VECTOR,"Vector",82, 44, 73, 19, 0, 0, 0, 0, 0, "Vector handles (V)");
348                         uiDefBut(block, BUT,B_SETPT_ALIGN,"Align",155, 44, 73, 19, 0, 0, 0, 0, 0, "Align handles (H Toggles)");
349                         uiDefBut(block, BUT,B_SETPT_FREE,"Free",        227, 44, 72, 19, 0, 0, 0, 0, 0, "Align handles (H Toggles)");
350                         uiBlockEndAlign(block);
351                 }
352                 
353                 if(totedge==1)
354                         uiDefButF(block, NUM, B_OBJECTPANELMEDIAN, "Crease W:", 0, 45, 200, 20, &(tfp->ve_median[3]), 0.0, 1.0, 10, 3, "");
355                 else if(totedge>1)
356                         uiDefButF(block, NUM, B_OBJECTPANELMEDIAN, "Median Crease W:",  0, 45, 200, 20, &(tfp->ve_median[3]), 0.0, 1.0, 10, 3, "");
357                 
358         }
359         else {  // apply
360                 memcpy(ve_median, tfp->ve_median, sizeof(tfp->ve_median));
361                 
362                 if(v3d->flag & V3D_GLOBAL_STATS) {
363                         Mat4Invert(ob->imat, ob->obmat);
364                         Mat4MulVecfl(ob->imat, median);
365                         Mat4MulVecfl(ob->imat, ve_median);
366                 }
367                 VecSubf(median, ve_median, median);
368                 median[3]= ve_median[3]-median[3];
369                 median[4]= ve_median[4]-median[4];
370                 
371                 if(ob->type==OB_MESH) {
372                         Mesh *me= ob->data;
373                         EditMesh *em = BKE_mesh_get_editmesh(me);
374                         EditVert *eve;
375                         EditEdge *eed;
376                         
377                         eve= em->verts.first;
378                         while(eve) {
379                                 if(eve->f & SELECT) {
380                                         VecAddf(eve->co, eve->co, median);
381                                 }
382                                 eve= eve->next;
383                         }
384                         
385                         for(eed= em->edges.first; eed; eed= eed->next) {
386                                 if(eed->f & SELECT) {
387                                         /* ensure the median can be set to zero or one */
388                                         if(ve_median[3]==0.0f) eed->crease= 0.0f;
389                                         else if(ve_median[3]==1.0f) eed->crease= 1.0f;
390                                         else {
391                                                 eed->crease+= median[3];
392                                                 CLAMP(eed->crease, 0.0, 1.0);
393                                         }
394                                 }
395                         }
396                         
397                         recalc_editnormals(em);
398
399                         BKE_mesh_end_editmesh(me, em);
400                 }
401                 else if(ob->type==OB_CURVE || ob->type==OB_SURF) {
402                         Curve *cu= ob->data;
403                         Nurb *nu;
404                         BPoint *bp;
405                         BezTriple *bezt;
406                         int a;
407                         
408                         nu= cu->editnurb->first;
409                         while(nu) {
410                                 if((nu->type & 7)==CU_BEZIER) {
411                                         bezt= nu->bezt;
412                                         a= nu->pntsu;
413                                         while(a--) {
414                                                 if(bezt->f2 & SELECT) {
415                                                         VecAddf(bezt->vec[0], bezt->vec[0], median);
416                                                         VecAddf(bezt->vec[1], bezt->vec[1], median);
417                                                         VecAddf(bezt->vec[2], bezt->vec[2], median);
418                                                         bezt->weight+= median[4];
419                                                 }
420                                                 else {
421                                                         if(bezt->f1 & SELECT) {
422                                                                 VecAddf(bezt->vec[0], bezt->vec[0], median);
423                                                         }
424                                                         if(bezt->f3 & SELECT) {
425                                                                 VecAddf(bezt->vec[2], bezt->vec[2], median);
426                                                         }
427                                                 }
428                                                 bezt++;
429                                         }
430                                 }
431                                 else {
432                                         bp= nu->bp;
433                                         a= nu->pntsu*nu->pntsv;
434                                         while(a--) {
435                                                 if(bp->f1 & SELECT) {
436                                                         VecAddf(bp->vec, bp->vec, median);
437                                                         bp->vec[3]+= median[3];
438                                                         bp->weight+= median[4];
439                                                 }
440                                                 bp++;
441                                         }
442                                 }
443                                 test2DNurb(nu);
444                                 testhandlesNurb(nu); /* test for bezier too */
445
446                                 nu= nu->next;
447                         }
448                 }
449                 else if(ob->type==OB_LATTICE) {
450                         Lattice *lt= ob->data;
451                         BPoint *bp;
452                         int a;
453                         
454                         a= lt->editlatt->pntsu*lt->editlatt->pntsv*lt->editlatt->pntsw;
455                         bp= lt->editlatt->def;
456                         while(a--) {
457                                 if(bp->f1 & SELECT) {
458                                         VecAddf(bp->vec, bp->vec, median);
459                                         bp->weight+= median[4];
460                                 }
461                                 bp++;
462                         }
463                 }
464                 
465 //              ED_undo_push(C, "Transform properties");
466         }
467 }
468
469 /* assumes armature active */
470 static void validate_bonebutton_cb(bContext *C, void *bonev, void *namev)
471 {
472         Object *ob= CTX_data_active_object(C);
473         
474         if(ob && ob->type==OB_ARMATURE) {
475                 Bone *bone= bonev;
476                 char oldname[32], newname[32];
477                 
478                 /* need to be on the stack */
479                 BLI_strncpy(newname, bone->name, 32);
480                 BLI_strncpy(oldname, (char *)namev, 32);
481                 /* restore */
482                 BLI_strncpy(bone->name, oldname, 32);
483                 
484                 ED_armature_bone_rename(ob->data, oldname, newname); // editarmature.c
485         }
486 }
487
488 static void v3d_posearmature_buts(uiBlock *block, View3D *v3d, Object *ob, float lim)
489 {
490         uiBut *but;
491         bArmature *arm;
492         bPoseChannel *pchan;
493         Bone *bone= NULL;
494         TransformProperties *tfp= v3d->properties_storage;
495
496         arm = ob->data;
497         if (!arm || !ob->pose) return;
498
499         for(pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) {
500                 bone = pchan->bone;
501                 if(bone && (bone->flag & BONE_ACTIVE) && (bone->layer & arm->layer))
502                         break;
503         }
504         if (!pchan || !bone) return;
505
506         if((ob->parent) && (ob->partype == PARBONE))
507                 but= uiDefBut (block, TEX, B_NOP, "Bone:",                              160, 130, 140, 19, bone->name, 1, 31, 0, 0, "");
508         else
509                 but= uiDefBut(block, TEX, B_NOP, "Bone:",                               160, 140, 140, 19, bone->name, 1, 31, 0, 0, "");
510         uiButSetFunc(but, validate_bonebutton_cb, bone, NULL);
511         uiButSetCompleteFunc(but, autocomplete_bone, (void *)ob);
512
513         QuatToEul(pchan->quat, tfp->ob_eul);
514         tfp->ob_eul[0]*= 180.0/M_PI;
515         tfp->ob_eul[1]*= 180.0/M_PI;
516         tfp->ob_eul[2]*= 180.0/M_PI;
517         
518         uiBlockBeginAlign(block);
519         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");
520         uiDefButF(block, NUM, B_ARMATUREPANEL2, "LocX:",        30, 140, 120, 19, pchan->loc, -lim, lim, 100, 3, "");
521         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");
522         uiDefButF(block, NUM, B_ARMATUREPANEL2, "LocY:",        30, 120, 120, 19, pchan->loc+1, -lim, lim, 100, 3, "");
523         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");
524         uiDefButF(block, NUM, B_ARMATUREPANEL2, "LocZ:",        30, 100, 120, 19, pchan->loc+2, -lim, lim, 100, 3, "");
525
526         uiBlockBeginAlign(block);
527         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");
528         uiDefButF(block, NUM, B_ARMATUREPANEL3, "RotX:",        30, 70, 120, 19, tfp->ob_eul, -1000.0, 1000.0, 100, 3, "");
529         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");
530         uiDefButF(block, NUM, B_ARMATUREPANEL3, "RotY:",        30, 50, 120, 19, tfp->ob_eul+1, -1000.0, 1000.0, 100, 3, "");
531         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");
532         uiDefButF(block, NUM, B_ARMATUREPANEL3, "RotZ:",        30, 30, 120, 19, tfp->ob_eul+2, -1000.0, 1000.0, 100, 3, "");
533         
534         uiBlockBeginAlign(block);
535         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");
536         uiDefButF(block, NUM, B_ARMATUREPANEL2, "ScaleX:",      180, 70, 120, 19, pchan->size, -lim, lim, 10, 3, "");
537         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");
538         uiDefButF(block, NUM, B_ARMATUREPANEL2, "ScaleY:",      180, 50, 120, 19, pchan->size+1, -lim, lim, 10, 3, "");
539         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");
540         uiDefButF(block, NUM, B_ARMATUREPANEL2, "ScaleZ:",      180, 30, 120, 19, pchan->size+2, -lim, lim, 10, 3, "");
541         uiBlockEndAlign(block);
542 }
543
544 /* assumes armature editmode */
545 void validate_editbonebutton_cb(bContext *C, void *bonev, void *namev)
546 {
547         EditBone *eBone= bonev;
548         char oldname[32], newname[32];
549         
550         /* need to be on the stack */
551         BLI_strncpy(newname, eBone->name, 32);
552         BLI_strncpy(oldname, (char *)namev, 32);
553         /* restore */
554         BLI_strncpy(eBone->name, oldname, 32);
555         
556         ED_armature_bone_rename(CTX_data_edit_object(C)->data, oldname, newname); // editarmature.c
557         WM_event_add_notifier(C, NC_OBJECT|ND_BONE_SELECT, CTX_data_edit_object(C)); // XXX fix
558 }
559
560 static void v3d_editarmature_buts(uiBlock *block, View3D *v3d, Object *ob, float lim)
561 {
562         bArmature *arm= ob->data;
563         EditBone *ebone;
564         uiBut *but;
565         TransformProperties *tfp= v3d->properties_storage;
566         
567         ebone= arm->edbo->first;
568
569         for (ebone = arm->edbo->first; ebone; ebone=ebone->next){
570                 if ((ebone->flag & BONE_ACTIVE) && (ebone->layer & arm->layer))
571                         break;
572         }
573
574         if (!ebone)
575                 return;
576         
577         if((ob->parent) && (ob->partype == PARBONE))
578                 but= uiDefBut(block, TEX, B_NOP, "Bone:", 160, 130, 140, 19, ebone->name, 1, 31, 0, 0, "");
579         else
580                 but= uiDefBut(block, TEX, B_NOP, "Bone:",                       160, 150, 140, 19, ebone->name, 1, 31, 0, 0, "");
581         uiButSetFunc(but, validate_editbonebutton_cb, ebone, NULL);
582
583         uiBlockBeginAlign(block);
584         uiDefButF(block, NUM, B_ARMATUREPANEL1, "HeadX:",       10, 70, 140, 19, ebone->head, -lim, lim, 10, 3, "");
585         uiDefButF(block, NUM, B_ARMATUREPANEL1, "HeadY:",       10, 50, 140, 19, ebone->head+1, -lim, lim, 10, 3, "");
586         uiDefButF(block, NUM, B_ARMATUREPANEL1, "HeadZ:",       10, 30, 140, 19, ebone->head+2, -lim, lim, 10, 3, "");
587         uiBlockBeginAlign(block);
588         uiDefButF(block, NUM, B_ARMATUREPANEL1, "TailX:",       160, 70, 140, 19, ebone->tail, -lim, lim, 10, 3, "");
589         uiDefButF(block, NUM, B_ARMATUREPANEL1, "TailY:",       160, 50, 140, 19, ebone->tail+1, -lim, lim, 10, 3, "");
590         uiDefButF(block, NUM, B_ARMATUREPANEL1, "TailZ:",       160, 30, 140, 19, ebone->tail+2, -lim, lim, 10, 3, "");
591         uiBlockEndAlign(block);
592         
593         tfp->ob_eul[0]= 180.0*ebone->roll/M_PI;
594         uiDefButF(block, NUM, B_ARMATUREPANEL1, "Roll:",        10, 100, 140, 19, tfp->ob_eul, -lim, lim, 1000, 3, "");
595
596         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");
597         
598         uiBlockBeginAlign(block);
599         uiDefButF(block, NUM, B_ARMATUREPANEL1, "TailRadius:",  10, 150, 140, 19, &ebone->rad_tail, 0, lim, 10, 3, "");
600         if (ebone->parent && ebone->flag & BONE_CONNECTED )
601                 uiDefButF(block, NUM, B_ARMATUREPANEL1, "HeadRadius:",  10, 130, 140, 19, &ebone->parent->rad_tail, 0, lim, 10, 3, "");
602         else
603                 uiDefButF(block, NUM, B_ARMATUREPANEL1, "HeadRadius:",  10, 130, 140, 19, &ebone->rad_head, 0, lim, 10, 3, "");
604         uiBlockEndAlign(block);
605 }
606
607 static void v3d_editmetaball_buts(uiBlock *block, Object *ob, float lim)
608 {
609         MetaElem *lastelem= NULL; // XXX
610
611         if(lastelem) {
612                 uiBlockBeginAlign(block);
613                 uiDefButF(block, NUM, B_RECALCMBALL, "LocX:", 10, 70, 140, 19, &lastelem->x, -lim, lim, 100, 3, "");
614                 uiDefButF(block, NUM, B_RECALCMBALL, "LocY:", 10, 50, 140, 19, &lastelem->y, -lim, lim, 100, 3, "");
615                 uiDefButF(block, NUM, B_RECALCMBALL, "LocZ:", 10, 30, 140, 19, &lastelem->z, -lim, lim, 100, 3, "");
616
617                 uiBlockBeginAlign(block);
618                 if(lastelem->type!=MB_BALL)
619                         uiDefButF(block, NUM, B_RECALCMBALL, "dx:", 160, 70, 140, 19, &lastelem->expx, 0, lim, 100, 3, "");
620                 if((lastelem->type!=MB_BALL) && (lastelem->type!=MB_TUBE))
621                         uiDefButF(block, NUM, B_RECALCMBALL, "dy:", 160, 50, 140, 19, &lastelem->expy, 0, lim, 100, 3, "");
622                 if((lastelem->type==MB_ELIPSOID) || (lastelem->type==MB_CUBE))
623                         uiDefButF(block, NUM, B_RECALCMBALL, "dz:", 160, 30, 140, 19, &lastelem->expz, 0, lim, 100, 3, "");
624
625                 uiBlockEndAlign(block); 
626
627                 uiBlockBeginAlign(block);
628                 uiDefButF(block, NUM, B_RECALCMBALL, "Radius:", 10, 120, 140, 19, &lastelem->rad, 0, lim, 100, 3, "Size of the active metaball");
629                 uiDefButF(block, NUM, B_RECALCMBALL, "Stiffness:", 10, 100, 140, 19, &lastelem->s, 0, 10, 100, 3, "Stiffness of the active metaball");
630                 uiBlockEndAlign(block);
631                 
632                 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");
633                 
634         }
635 }
636
637 /* test if 'ob' is a parent somewhere in par's parents */
638 static int test_parent_loop(Object *par, Object *ob)
639 {
640         if(par == NULL) return 0;
641         if(ob == par) return 1;
642         return test_parent_loop(par->parent, ob);
643 }
644
645 static void do_view3d_region_buttons(bContext *C, void *arg, int event)
646 {
647         Scene *scene= CTX_data_scene(C);
648         Object *obedit= CTX_data_edit_object(C);
649         View3D *v3d= CTX_wm_view3d(C);
650         BoundBox *bb;
651         Object *ob= OBACT;
652         TransformProperties *tfp= v3d->properties_storage;
653         
654         switch(event) {
655         
656         case B_REDR:
657                 ED_area_tag_redraw(CTX_wm_area(C));
658                 return; /* no notifier! */
659                 
660         case B_OBJECTPANEL:
661                 DAG_object_flush_update(scene, ob, OB_RECALC_OB);
662                 break;
663                 
664         case B_OBJECTPANELROT:
665                 if(ob) {
666                         ob->rot[0]= M_PI*tfp->ob_eul[0]/180.0;
667                         ob->rot[1]= M_PI*tfp->ob_eul[1]/180.0;
668                         ob->rot[2]= M_PI*tfp->ob_eul[2]/180.0;
669                         DAG_object_flush_update(scene, ob, OB_RECALC_OB);
670                 }
671                 break;
672
673         case B_OBJECTPANELSCALE:
674                 if(ob) {
675
676                         /* link scale; figure out which axis changed */
677                         if (tfp->link_scale) {
678                                 float ratio, tmp, max = 0.0;
679                                 int axis;
680                                 
681                                 axis = 0;
682                                 max = fabs(tfp->ob_scale[0] - ob->size[0]);
683                                 tmp = fabs(tfp->ob_scale[1] - ob->size[1]);
684                                 if (tmp > max) {
685                                         axis = 1;
686                                         max = tmp;
687                                 }
688                                 tmp = fabs(tfp->ob_scale[2] - ob->size[2]);
689                                 if (tmp > max) {
690                                         axis = 2;
691                                         max = tmp;
692                                 }
693                         
694                                 if (ob->size[axis] != tfp->ob_scale[axis]) {
695                                         if (fabs(ob->size[axis]) > FLT_EPSILON) {
696                                                 ratio = tfp->ob_scale[axis] / ob->size[axis];
697                                                 ob->size[0] *= ratio;
698                                                 ob->size[1] *= ratio;
699                                                 ob->size[2] *= ratio;
700                                         }
701                                 }
702                         }
703                         else {
704                                 VECCOPY(ob->size, tfp->ob_scale);
705                                 
706                         }
707                         DAG_object_flush_update(scene, ob, OB_RECALC_OB);
708                 }
709                 break;
710
711         case B_OBJECTPANELDIMS:
712                 bb= object_get_boundbox(ob);
713                 if(bb) {
714                         float old_dims[3], scale[3], ratio, len[3];
715                         int axis;
716
717                         Mat4ToSize(ob->obmat, scale);
718
719                         len[0] = bb->vec[4][0] - bb->vec[0][0];
720                         len[1] = bb->vec[2][1] - bb->vec[0][1];
721                         len[2] = bb->vec[1][2] - bb->vec[0][2];
722
723                         old_dims[0] = fabs(scale[0]) * len[0];
724                         old_dims[1] = fabs(scale[1]) * len[1];
725                         old_dims[2] = fabs(scale[2]) * len[2];
726
727                         /* for each axis changed */
728                         for (axis = 0; axis<3; axis++) {
729                                 if (fabs(old_dims[axis] - tfp->ob_dims[axis]) > 0.0001) {
730                                         if (old_dims[axis] > 0.0) {
731                                                 ratio = tfp->ob_dims[axis] / old_dims[axis]; 
732                                                 if (tfp->link_scale) {
733                                                         ob->size[0] *= ratio;
734                                                         ob->size[1] *= ratio;
735                                                         ob->size[2] *= ratio;
736                                                         break;
737                                                 }
738                                                 else {
739                                                         ob->size[axis] *= ratio;
740                                                 }
741                                         }
742                                         else {
743                                                 if (len[axis] > 0) {
744                                                         ob->size[axis] = tfp->ob_dims[axis] / len[axis];
745                                                 }
746                                         }
747                                 }
748                         }
749                         
750                         /* prevent multiple B_OBJECTPANELDIMS events to keep scaling, cycling with TAB on buttons can cause that */
751                         VECCOPY(tfp->ob_dims, old_dims);
752                         
753                         DAG_object_flush_update(scene, ob, OB_RECALC_OB);
754                 }
755                 break;
756         
757         case B_OBJECTPANELMEDIAN:
758                 if(ob) {
759                         v3d_editvertex_buts(C, NULL, v3d, ob, 1.0);
760                         DAG_object_flush_update(scene, ob, OB_RECALC_DATA);
761                 }
762                 break;
763                 
764                 /* note; this case also used for parbone */
765         case B_OBJECTPANELPARENT:
766                 if(ob) {
767                         if(ob->id.lib || test_parent_loop(ob->parent, ob) ) 
768                                 ob->parent= NULL;
769                         else {
770                                 DAG_scene_sort(scene);
771                                 DAG_object_flush_update(scene, ob, OB_RECALC_OB);
772                         }
773                 }
774                 break;
775                 
776         case B_ARMATUREPANEL1:
777                 {
778                         bArmature *arm= obedit->data;
779                         EditBone *ebone, *child;
780                         
781                         for (ebone = arm->edbo->first; ebone; ebone=ebone->next){
782                                 if ((ebone->flag & BONE_ACTIVE) && (ebone->layer & arm->layer))
783                                         break;
784                         }
785                         if (ebone) {
786                                 ebone->roll= M_PI*tfp->ob_eul[0]/180.0;
787                                 //      Update our parent
788                                 if (ebone->parent && ebone->flag & BONE_CONNECTED){
789                                         VECCOPY (ebone->parent->tail, ebone->head);
790                                 }
791                         
792                                 //      Update our children if necessary
793                                 for (child = arm->edbo->first; child; child=child->next){
794                                         if (child->parent == ebone && (child->flag & BONE_CONNECTED)){
795                                                 VECCOPY (child->head, ebone->tail);
796                                         }
797                                 }
798                                 if(arm->flag & ARM_MIRROR_EDIT) {
799                                         EditBone *eboflip= ED_armature_bone_get_mirrored(arm->edbo, ebone);
800                                         if(eboflip) {
801                                                 eboflip->roll= -ebone->roll;
802                                                 eboflip->head[0]= -ebone->head[0];
803                                                 eboflip->tail[0]= -ebone->tail[0];
804                                                 
805                                                 //      Update our parent
806                                                 if (eboflip->parent && eboflip->flag & BONE_CONNECTED){
807                                                         VECCOPY (eboflip->parent->tail, eboflip->head);
808                                                 }
809                                                 
810                                                 //      Update our children if necessary
811                                                 for (child = arm->edbo->first; child; child=child->next){
812                                                         if (child->parent == eboflip && (child->flag & BONE_CONNECTED)){
813                                                                 VECCOPY (child->head, eboflip->tail);
814                                                         }
815                                                 }
816                                         }
817                                 }
818                         }
819                 }
820                 break;
821         case B_ARMATUREPANEL3:  // rotate button on channel
822                 {
823                         bArmature *arm;
824                         bPoseChannel *pchan;
825                         Bone *bone;
826                         float eul[3];
827                         
828                         arm = ob->data;
829                         if (!arm || !ob->pose) return;
830                                 
831                         for(pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) {
832                                 bone = pchan->bone;
833                                 if(bone && (bone->flag & BONE_ACTIVE) && (bone->layer & arm->layer))
834                                         break;
835                         }
836                         if (!pchan) return;
837                         
838                         /* make a copy to eul[3], to allow TAB on buttons to work */
839                         eul[0]= M_PI*tfp->ob_eul[0]/180.0;
840                         eul[1]= M_PI*tfp->ob_eul[1]/180.0;
841                         eul[2]= M_PI*tfp->ob_eul[2]/180.0;
842                         EulToQuat(eul, pchan->quat);
843                 }
844                 /* no break, pass on */
845         case B_ARMATUREPANEL2:
846                 {
847                         ob->pose->flag |= (POSE_LOCKED|POSE_DO_UNLOCK);
848                         DAG_object_flush_update(scene, ob, OB_RECALC_DATA);
849                 }
850                 break;
851         case B_TRANSFORMSPACEADD:
852                 BIF_manageTransformOrientation(C, 1, 0);
853                 break;
854         case B_TRANSFORMSPACECLEAR:
855                 BIF_clearTransformOrientation(C);
856                 break;
857                 
858 #if 0 // XXX
859         case B_WEIGHT0_0:
860                 wpaint->weight = 0.0f;
861                 break;
862                 
863         case B_WEIGHT1_4:
864                 wpaint->weight = 0.25f;
865                 break;
866         case B_WEIGHT1_2:
867                 wpaint->weight = 0.5f;
868                 break;
869         case B_WEIGHT3_4:
870                 wpaint->weight = 0.75f;
871                 break;
872         case B_WEIGHT1_0:
873                 wpaint->weight = 1.0f;
874                 break;
875                 
876         case B_OPA1_8:
877                 wpaint->a = 0.125f;
878                 break;
879         case B_OPA1_4:
880                 wpaint->a = 0.25f;
881                 break;
882         case B_OPA1_2:
883                 wpaint->a = 0.5f;
884                 break;
885         case B_OPA3_4:
886                 wpaint->a = 0.75f;
887                 break;
888         case B_OPA1_0:
889                 wpaint->a = 1.0f;
890                 break;
891 #endif
892         case B_CLR_WPAINT:
893 //              if(!multires_level1_test()) {
894                 {
895                         bDeformGroup *defGroup = BLI_findlink(&ob->defbase, ob->actdef-1);
896                         if(defGroup) {
897                                 Mesh *me= ob->data;
898                                 int a;
899                                 for(a=0; a<me->totvert; a++)
900                                         remove_vert_defgroup (ob, defGroup, a);
901                                 DAG_object_flush_update(scene, ob, OB_RECALC_DATA);
902                         }
903                 }
904                 break;
905         case B_RV3D_LOCKED:
906         case B_RV3D_BOXVIEW:
907         case B_RV3D_BOXCLIP:
908                 {
909                         ScrArea *sa= CTX_wm_area(C);
910                         ARegion *ar= sa->regionbase.last;
911                         RegionView3D *rv3d;
912                         short viewlock;
913                         
914                         ar= ar->prev;
915                         rv3d= ar->regiondata;
916                         viewlock= rv3d->viewlock;
917                         
918                         if((viewlock & RV3D_LOCKED)==0)
919                                 viewlock= 0;
920                         else if((viewlock & RV3D_BOXVIEW)==0)
921                                 viewlock &= ~RV3D_BOXCLIP;
922                         
923                         for(; ar; ar= ar->prev) {
924                                 if(ar->alignment==RGN_ALIGN_QSPLIT) {
925                                         rv3d= ar->regiondata;
926                                         rv3d->viewlock= viewlock;
927                                 }
928                         }
929                         
930                         if(rv3d->viewlock & RV3D_BOXVIEW)
931                                 view3d_boxview_copy(sa, sa->regionbase.last);
932                         
933                         ED_area_tag_redraw(sa);
934                 }
935                 break;
936         }
937
938         /* default for now */
939         WM_event_add_notifier(C, NC_OBJECT|ND_TRANSFORM, ob);
940 }
941
942 void removeTransformOrientation_func(bContext *C, void *target, void *unused)
943 {
944         BIF_removeTransformOrientation(C, (TransformOrientation *) target);
945 }
946
947 void selectTransformOrientation_func(bContext *C, void *target, void *unused)
948 {
949         BIF_selectTransformOrientation(C, (TransformOrientation *) target);
950 }
951
952 #if 0 // XXX not used
953 static void view3d_panel_transform_spaces(const bContext *C, Panel *pa)
954 {
955         Scene *scene= CTX_data_scene(C);
956         Object *obedit= CTX_data_edit_object(C);
957         View3D *v3d= CTX_wm_view3d(C);
958         ListBase *transform_spaces = &scene->transform_spaces;
959         TransformOrientation *ts = transform_spaces->first;
960         uiBlock *block;
961         uiBut *but;
962         int xco = 20, yco = 70;
963         int index;
964
965         block= uiLayoutFreeBlock(pa->layout);
966
967         uiBlockBeginAlign(block);
968         
969         if (obedit)
970                 uiDefBut(block, BUT, B_TRANSFORMSPACEADD, "Add", xco,120,80,20, 0, 0, 0, 0, 0, "Add the selected element as a Transform Orientation");
971         else
972                 uiDefBut(block, BUT, B_TRANSFORMSPACEADD, "Add", xco,120,80,20, 0, 0, 0, 0, 0, "Add the active object as a Transform Orientation");
973
974         uiDefBut(block, BUT, B_TRANSFORMSPACECLEAR, "Clear", xco + 80,120,80,20, 0, 0, 0, 0, 0, "Removal all Transform Orientations");
975         
976         uiBlockEndAlign(block);
977         
978         uiBlockBeginAlign(block);
979         
980         uiDefButS(block, ROW, B_REDR, "Global", xco,            90, 40,20, &v3d->twmode, 5.0, (float)V3D_MANIP_GLOBAL,0, 0, "Global Transform Orientation");
981         uiDefButS(block, ROW, B_REDR, "Local",  xco + 40,       90, 40,20, &v3d->twmode, 5.0, (float)V3D_MANIP_LOCAL, 0, 0, "Local Transform Orientation");
982         uiDefButS(block, ROW, B_REDR, "Normal", xco + 80,       90, 40,20, &v3d->twmode, 5.0, (float)V3D_MANIP_NORMAL,0, 0, "Normal Transform Orientation");
983         uiDefButS(block, ROW, B_REDR, "View",           xco + 120,      90, 40,20, &v3d->twmode, 5.0, (float)V3D_MANIP_VIEW,    0, 0, "View Transform Orientation");
984         
985         for (index = V3D_MANIP_CUSTOM, ts = transform_spaces->first ; ts ; ts = ts->next, index++) {
986
987                 if (v3d->twmode == index) {
988                         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");
989                 }
990                 else {
991                         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");
992                 }
993                 uiButSetFunc(but, selectTransformOrientation_func, ts, NULL);
994                 uiDefBut(block, TEX, 0, "", xco+=XIC, yco,100+XIC,20, &ts->name, 0, 30, 0, 0, "Edits the name of this Transform Orientation");
995                 but = uiDefIconBut(block, BUT, B_REDR, ICON_X, xco+=100+XIC,yco,XIC,YIC, 0, 0, 0, 0, 0, "Deletes this Transform Orientation");
996                 uiButSetFunc(but, removeTransformOrientation_func, ts, NULL);
997
998                 xco = 20;
999                 yco -= 25;
1000         }
1001         uiBlockEndAlign(block);
1002 }
1003 #endif // XXX not used
1004
1005 #if 0
1006 static void brush_idpoin_handle(bContext *C, ID *id, int event)
1007 {
1008         Brush **br = current_brush_source(CTX_data_scene(C));
1009
1010         if(!br)
1011                 return;
1012
1013         switch(event) {
1014         case UI_ID_BROWSE:
1015                 (*br) = (Brush*)id;
1016                 break;
1017         case UI_ID_DELETE:
1018                 brush_delete(br);
1019                 break;
1020         case UI_ID_RENAME:
1021                 /* XXX ? */
1022                 break;
1023         case UI_ID_ADD_NEW:
1024                 if(id) {
1025                         (*br) = copy_brush((Brush*)id);
1026                         id->us--;
1027                 }
1028                 else
1029                         (*br) = add_brush("Brush");
1030                 break;
1031         case UI_ID_OPEN:
1032                 /* XXX not implemented */
1033                 break;
1034         }
1035 }
1036 #endif
1037
1038 static void view3d_panel_object(const bContext *C, Panel *pa)
1039 {
1040         uiBlock *block;
1041         Scene *scene= CTX_data_scene(C);
1042         Object *obedit= CTX_data_edit_object(C);
1043         View3D *v3d= CTX_wm_view3d(C);
1044         //uiBut *bt;
1045         Object *ob= OBACT;
1046         TransformProperties *tfp;
1047         float lim;
1048         
1049         if(ob==NULL) return;
1050
1051         /* make sure we got storage */
1052         if(v3d->properties_storage==NULL)
1053                 v3d->properties_storage= MEM_callocN(sizeof(TransformProperties), "TransformProperties");
1054         tfp= v3d->properties_storage;
1055         
1056         block= uiLayoutFreeBlock(pa->layout);
1057         uiBlockSetHandleFunc(block, do_view3d_region_buttons, NULL);
1058
1059 // XXX  uiSetButLock(object_is_libdata(ob), ERROR_LIBDATA_MESSAGE);
1060         
1061         if(ob->mode & (OB_MODE_VERTEX_PAINT|OB_MODE_WEIGHT_PAINT|OB_MODE_TEXTURE_PAINT)) {
1062         }
1063         else {
1064                 //bt= uiDefBut(block, TEX, B_IDNAME, "OB: ",    10,180,140,20, ob->id.name+2, 0.0, 21.0, 0, 0, "");
1065                 //uiButSetFunc(bt, test_idbutton_cb, ob->id.name, NULL);
1066
1067                 if((ob->mode & OB_MODE_PARTICLE_EDIT)==0) {
1068                 //      uiBlockBeginAlign(block);
1069                 //      uiDefIDPoinBut(block, test_obpoin_but, ID_OB, B_OBJECTPANELPARENT, "Par:", 160, 180, 140, 20, &ob->parent, "Parent Object"); 
1070                         if((ob->parent) && (ob->partype == PARBONE)) {
1071                 //              bt= uiDefBut(block, TEX, B_OBJECTPANELPARENT, "ParBone:", 160, 160, 140, 20, ob->parsubstr, 0, 30, 0, 0, "");
1072                 //              uiButSetCompleteFunc(bt, autocomplete_bone, (void *)ob->parent);
1073                         }
1074                         else {
1075                                 strcpy(ob->parsubstr, "");
1076                         }
1077                         uiBlockEndAlign(block);
1078                 }
1079         }
1080
1081         lim= 10000.0f*MAX2(1.0, v3d->grid);
1082
1083         if(ob==obedit) {
1084                 if(ob->type==OB_ARMATURE) v3d_editarmature_buts(block, v3d, ob, lim);
1085                 if(ob->type==OB_MBALL) v3d_editmetaball_buts(block, ob, lim);
1086                 else v3d_editvertex_buts(C, block, v3d, ob, lim);
1087         }
1088         else if(ob->flag & OB_POSEMODE) {
1089                 v3d_posearmature_buts(block, v3d, ob, lim);
1090         }
1091         else {
1092                 BoundBox *bb = NULL;
1093                 
1094                 uiDefBut(block, LABEL, 0, "Location:",                                  10, 170, 100, 20, 0, 0, 0, 0, 0, "");
1095                 uiBlockBeginAlign(block);
1096                 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");
1097                 uiDefButF(block, NUM, B_OBJECTPANEL, "X:",              30, 150, 120, 19, &(ob->loc[0]), -lim, lim, 100, 3, "");
1098                 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");
1099                 uiDefButF(block, NUM, B_OBJECTPANEL, "Y:",              30, 130, 120, 19, &(ob->loc[1]), -lim, lim, 100, 3, "");
1100                 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");
1101                 uiDefButF(block, NUM, B_OBJECTPANEL, "Z:",              30, 110, 120, 19, &(ob->loc[2]), -lim, lim, 100, 3, "");
1102                 
1103                 tfp->ob_eul[0]= 180.0*ob->rot[0]/M_PI;
1104                 tfp->ob_eul[1]= 180.0*ob->rot[1]/M_PI;
1105                 tfp->ob_eul[2]= 180.0*ob->rot[2]/M_PI;
1106                 
1107                 uiBlockBeginAlign(block);
1108                 if ((ob->parent) && (ob->partype == PARBONE)) {
1109                         uiDefBut(block, LABEL, 0, "Rotation:",                                  160, 170, 100, 20, 0, 0, 0, 0, 0, "");
1110                         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");
1111                         uiDefButF(block, NUM, B_OBJECTPANELROT, "X:",   180, 130, 120, 19, &(tfp->ob_eul[0]), -lim, lim, 1000, 3, "");
1112                         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");
1113                         uiDefButF(block, NUM, B_OBJECTPANELROT, "Y:",   180, 110, 120, 19, &(tfp->ob_eul[1]), -lim, lim, 1000, 3, "");
1114                         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");
1115                         uiDefButF(block, NUM, B_OBJECTPANELROT, "Z:",   180, 90, 120, 19, &(tfp->ob_eul[2]), -lim, lim, 1000, 3, "");
1116
1117                 }
1118                 else {
1119                         uiDefBut(block, LABEL, 0, "Rotation:",                                  160, 170, 100, 20, 0, 0, 0, 0, 0, "");
1120                         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");
1121                         uiDefButF(block, NUM, B_OBJECTPANELROT, "X:",   180, 150, 120, 19, &(tfp->ob_eul[0]), -lim, lim, 1000, 3, "");
1122                         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");
1123                         uiDefButF(block, NUM, B_OBJECTPANELROT, "Y:",   180, 130, 120, 19, &(tfp->ob_eul[1]), -lim, lim, 1000, 3, "");
1124                         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");
1125                         uiDefButF(block, NUM, B_OBJECTPANELROT, "Z:",   180, 110, 120, 19, &(tfp->ob_eul[2]), -lim, lim, 1000, 3, "");
1126                 }
1127
1128                 tfp->ob_scale[0]= ob->size[0];
1129                 tfp->ob_scale[1]= ob->size[1];
1130                 tfp->ob_scale[2]= ob->size[2];
1131
1132                 uiDefBut(block, LABEL, 0, "Scale:",                                     10, 90, 100, 20, 0, 0, 0, 0, 0, "");
1133                 uiBlockBeginAlign(block);
1134                 uiDefIconButBitS(block, ICONTOG, OB_LOCK_SCALEX, B_REDR, ICON_UNLOCKED, 10, 70, 20, 19, &(ob->protectflag), 0, 0, 0, 0, "Protects this value from being Transformed");
1135                 uiDefButF(block, NUM, B_OBJECTPANELSCALE, "X:",                                                 30, 70, 120, 19, &(tfp->ob_scale[0]), -lim, lim, 10, 3, "");
1136                 uiDefIconButBitS(block, ICONTOG, OB_LOCK_SCALEY, B_REDR, ICON_UNLOCKED, 10, 50, 20, 19, &(ob->protectflag), 0, 0, 0, 0, "Protects this value from being Transformed");
1137                 uiDefButF(block, NUM, B_OBJECTPANELSCALE, "Y:",                                                 30, 50, 120, 19, &(tfp->ob_scale[1]), -lim, lim, 10, 3, "");
1138                 uiDefIconButBitS(block, ICONTOG, OB_LOCK_SCALEZ, B_REDR, ICON_UNLOCKED, 10, 30, 20, 19, &(ob->protectflag), 0, 0, 0, 0, "Protects this value from being Transformed");
1139                 uiDefButF(block, NUM, B_OBJECTPANELSCALE, "Z:",                                                 30, 30, 120, 19, &(tfp->ob_scale[2]), -lim, lim, 10, 3, "");
1140                 uiBlockEndAlign(block);
1141                 
1142                 uiDefButS(block, TOG, B_REDR, "Link Scale",             10, 0, 140, 19, &(tfp->link_scale), 0, 1, 0, 0, "Scale values vary proportionally in all directions");
1143
1144                 bb= object_get_boundbox(ob);
1145                 if (bb) {
1146                         float scale[3];
1147
1148                         Mat4ToSize(ob->obmat, scale);
1149
1150                         tfp->ob_dims[0] = fabs(scale[0]) * (bb->vec[4][0] - bb->vec[0][0]);
1151                         tfp->ob_dims[1] = fabs(scale[1]) * (bb->vec[2][1] - bb->vec[0][1]);
1152                         tfp->ob_dims[2] = fabs(scale[2]) * (bb->vec[1][2] - bb->vec[0][2]);
1153
1154                         
1155                         if ((ob->parent) && (ob->partype == PARBONE)) {
1156                                 uiDefBut(block, LABEL, 0, "Dimensions:",                        160, 90, 100, 20, 0, 0, 0, 0, 0, "");
1157                                 uiBlockBeginAlign(block);
1158                                 uiDefButF(block, NUM, B_OBJECTPANELDIMS, "X:",          160, 70, 140, 19, &(tfp->ob_dims[0]), 0.0, lim, 10, 3, "Manipulate bounding box size");
1159                                 uiDefButF(block, NUM, B_OBJECTPANELDIMS, "Y:",          160, 50, 140, 19, &(tfp->ob_dims[1]), 0.0, lim, 10, 3, "Manipulate bounding box size");
1160                                 uiDefButF(block, NUM, B_OBJECTPANELDIMS, "Z:",          160, 30, 140, 19, &(tfp->ob_dims[2]), 0.0, lim, 10, 3, "Manipulate bounding box size");
1161
1162                         }
1163                         else {
1164                                 uiDefBut(block, LABEL, 0, "Dimensions:",                        160, 90, 100, 20, 0, 0, 0, 0, 0, "");
1165                                 uiBlockBeginAlign(block);
1166                                 uiDefButF(block, NUM, B_OBJECTPANELDIMS, "X:",          160, 70, 140, 19, &(tfp->ob_dims[0]), 0.0, lim, 10, 3, "Manipulate bounding box size");
1167                                 uiDefButF(block, NUM, B_OBJECTPANELDIMS, "Y:",          160, 50, 140, 19, &(tfp->ob_dims[1]), 0.0, lim, 10, 3, "Manipulate bounding box size");
1168                                 uiDefButF(block, NUM, B_OBJECTPANELDIMS, "Z:",          160, 30, 140, 19, &(tfp->ob_dims[2]), 0.0, lim, 10, 3, "Manipulate bounding box size");
1169                         }
1170
1171                         uiBlockEndAlign(block);
1172                 }
1173         }
1174 }
1175
1176 #if 0
1177 static void view3d_panel_preview(bContext *C, ARegion *ar, short cntrl) // VIEW3D_HANDLER_PREVIEW
1178 {
1179         uiBlock *block;
1180         View3D *v3d= sa->spacedata.first;
1181         int ofsx, ofsy;
1182         
1183         block= uiBeginBlock(C, ar, "view3d_panel_preview", UI_EMBOSS);
1184         uiPanelControl(UI_PNL_SOLID | UI_PNL_CLOSE | UI_PNL_SCALE | cntrl);
1185         uiSetPanelHandler(VIEW3D_HANDLER_PREVIEW);  // for close and esc
1186         
1187         ofsx= -150+(sa->winx/2)/v3d->blockscale;
1188         ofsy= -100+(sa->winy/2)/v3d->blockscale;
1189         if(uiNewPanel(C, ar, block, "Preview", "View3d", ofsx, ofsy, 300, 200)==0) return;
1190
1191         uiBlockSetDrawExtraFunc(block, BIF_view3d_previewdraw);
1192         
1193         if(scene->recalc & SCE_PRV_CHANGED) {
1194                 scene->recalc &= ~SCE_PRV_CHANGED;
1195                 //printf("found recalc\n");
1196                 BIF_view3d_previewrender_free(sa->spacedata.first);
1197                 BIF_preview_changed(0);
1198         }
1199 }
1200 #endif
1201
1202 #if 0
1203 static void view3d_panel_gpencil(const bContext *C, Panel *pa)
1204 {
1205         View3D *v3d= CTX_wm_view3d(C);
1206         uiBlock *block;
1207
1208         block= uiLayoutFreeBlock(pa->layout);
1209
1210         /* allocate memory for gpd if drawing enabled (this must be done first or else we crash) */
1211         if (v3d->flag2 & V3D_DISPGP) {
1212 //              if (v3d->gpd == NULL)
1213 // XXX                  gpencil_data_setactive(ar, gpencil_data_addnew());
1214         }
1215         
1216         if (v3d->flag2 & V3D_DISPGP) {
1217 // XXX          bGPdata *gpd= v3d->gpd;
1218                 
1219                 /* draw button for showing gpencil settings and drawings */
1220                 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)");
1221         }
1222         else {
1223                 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");
1224                 uiDefBut(block, LABEL, 1, " ",  160, 180, 150, 20, NULL, 0.0, 0.0, 0, 0, "");
1225         }
1226 }
1227 #endif
1228
1229 static void delete_sketch_armature(bContext *C, void *arg1, void *arg2)
1230 {
1231         BIF_deleteSketch(C);
1232 }
1233
1234 static void convert_sketch_armature(bContext *C, void *arg1, void *arg2)
1235 {
1236         BIF_convertSketch(C);
1237 }
1238
1239 static void assign_template_sketch_armature(bContext *C, void *arg1, void *arg2)
1240 {
1241         int index = *(int*)arg1;
1242         BIF_setTemplate(C, index);
1243 }
1244
1245 static int view3d_panel_bonesketch_spaces_poll(const bContext *C, PanelType *pt)
1246 {
1247         Object *obedit = CTX_data_edit_object(C);
1248
1249         /* replace with check call to sketching lib */
1250         return (obedit && obedit->type == OB_ARMATURE);
1251 }
1252 static void view3d_panel_bonesketch_spaces(const bContext *C, Panel *pa)
1253 {
1254         Scene *scene = CTX_data_scene(C);
1255         static int template_index;
1256         static char joint_label[128];
1257         uiBlock *block;
1258         uiBut *but;
1259         char *bone_name;
1260         int yco = 130;
1261         int nb_joints;
1262         static char subdiv_tooltip[4][64] = {
1263                 "Subdivide arcs based on a fixed number of bones",
1264                 "Subdivide arcs in bones of equal length",
1265                 "Subdivide arcs based on correlation",
1266                 "Retarget template to stroke"
1267                 };
1268
1269         
1270         block= uiLayoutFreeBlock(pa->layout);
1271         uiBlockSetHandleFunc(block, do_view3d_region_buttons, NULL);
1272
1273         uiBlockBeginAlign(block);
1274         
1275         /* use real flag instead of 1 */
1276         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)");
1277         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");
1278         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");
1279         yco -= 20;
1280         
1281         but = uiDefBut(block, BUT, B_REDR, "Convert", 10,yco,100,20, 0, 0, 0, 0, 0, "Convert sketch to armature");
1282         uiButSetFunc(but, convert_sketch_armature, NULL, NULL);
1283
1284         but = uiDefBut(block, BUT, B_REDR, "Delete", 110,yco,100,20, 0, 0, 0, 0, 0, "Delete sketch");
1285         uiButSetFunc(but, delete_sketch_armature, NULL, NULL);
1286         yco -= 20;
1287         
1288         uiBlockEndAlign(block);
1289
1290         uiBlockBeginAlign(block);
1291         
1292         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]);
1293
1294         switch(scene->toolsettings->bone_sketching_convert)
1295         {
1296         case SK_CONVERT_CUT_LENGTH:
1297                 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");
1298                 yco -= 20;
1299                 break;
1300         case SK_CONVERT_CUT_ADAPTATIVE:
1301                 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");
1302                 yco -= 20;
1303                 break;
1304         default:
1305         case SK_CONVERT_CUT_FIXED:
1306                 uiDefButC(block, NUM, B_REDR,                                   "Num:",         70, yco, 140, 19, &scene->toolsettings->skgen_subdivision_number,1, 100, 1, 5,  "Number of subdivided bones");
1307                 yco -= 20;
1308                 break;
1309         case SK_CONVERT_RETARGET:
1310                 uiDefButC(block, ROW, B_NOP, "No",                      70,  yco, 40,19, &scene->toolsettings->skgen_retarget_roll, 0, 0, 0, 0,                                                                 "No special roll treatment");
1311                 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");
1312                 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");
1313                 yco -= 30;
1314
1315                 uiBlockEndAlign(block);
1316
1317                 uiBlockBeginAlign(block);
1318                 /* button here to select what to do (copy or not), template, ...*/
1319
1320                 BIF_makeListTemplates(C);
1321                 template_index = BIF_currentTemplate(C);
1322                 
1323                 but = uiDefButI(block, MENU, B_REDR, BIF_listTemplates(C), 10,yco,200,19, &template_index, 0, 0, 0, 0, "Template");
1324                 uiButSetFunc(but, assign_template_sketch_armature, &template_index, NULL);
1325                 
1326                 yco -= 20;
1327                 
1328                 uiDefButF(block, NUM, B_NOP,                                                    "A:",                   10, yco, 66,19, &scene->toolsettings->skgen_retarget_angle_weight, 0, 10, 1, 0,         "Angle Weight");
1329                 uiDefButF(block, NUM, B_NOP,                                                    "L:",                   76, yco, 67,19, &scene->toolsettings->skgen_retarget_length_weight, 0, 10, 1, 0,                "Length Weight");
1330                 uiDefButF(block, NUM, B_NOP,                                                    "D:",           143,yco, 67,19, &scene->toolsettings->skgen_retarget_distance_weight, 0, 10, 1, 0,              "Distance Weight");
1331                 yco -= 20;
1332                 
1333                 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");
1334                 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");
1335                 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");        
1336                 yco -= 20;
1337
1338                 /* auto renaming magic */
1339                 uiBlockEndAlign(block);
1340                 
1341                 nb_joints = BIF_nbJointsTemplate(C);
1342
1343                 if (nb_joints == -1)
1344                 {
1345                         //XXX
1346                         //nb_joints = G.totvertsel;
1347                 }
1348                 
1349                 bone_name = BIF_nameBoneTemplate(C);
1350                 
1351                 BLI_snprintf(joint_label, 32, "%i joints: %s", nb_joints, bone_name);
1352                 
1353                 uiDefBut(block, LABEL, 1, joint_label,                                  10, yco, 200, 20, NULL, 0.0, 0.0, 0, 0, "");
1354                 yco -= 20;
1355                 break;
1356         }
1357
1358         uiBlockEndAlign(block);
1359 }
1360
1361 #if 0 // XXX not used
1362
1363 /* op->invoke */
1364 static void redo_cb(bContext *C, void *arg_op, void *arg2)
1365 {
1366         wmOperator *lastop= arg_op;
1367         
1368         if(lastop) {
1369                 int retval;
1370                 
1371                 printf("operator redo %s\n", lastop->type->name);
1372                 ED_undo_pop(C);
1373                 retval= WM_operator_repeat(C, lastop);
1374                 if((retval & OPERATOR_FINISHED)==0) {
1375                         printf("operator redo failed %s\n", lastop->type->name);
1376                         ED_undo_redo(C);
1377                 }
1378         }
1379 }
1380
1381 static void view3d_panel_operator_redo(const bContext *C, Panel *pa)
1382 {
1383         wmWindowManager *wm= CTX_wm_manager(C);
1384         wmOperator *op;
1385         PointerRNA ptr;
1386         uiBlock *block;
1387         
1388         block= uiLayoutGetBlock(pa->layout);
1389
1390         /* only for operators that are registered and did an undo push */
1391         for(op= wm->operators.last; op; op= op->prev)
1392                 if((op->type->flag & OPTYPE_REGISTER) && (op->type->flag & OPTYPE_UNDO))
1393                         break;
1394         
1395         if(op==NULL)
1396                 return;
1397         
1398         uiBlockSetFunc(block, redo_cb, op, NULL);
1399         
1400         if(!op->properties) {
1401                 IDPropertyTemplate val = {0};
1402                 op->properties= IDP_New(IDP_GROUP, val, "wmOperatorProperties");
1403         }
1404         
1405         RNA_pointer_create(&wm->id, op->type->srna, op->properties, &ptr);
1406         uiDefAutoButsRNA(C, pa->layout, &ptr, 2);
1407 }
1408 #endif // XXX not used
1409
1410 void view3d_buttons_register(ARegionType *art)
1411 {
1412         PanelType *pt;
1413
1414         pt= MEM_callocN(sizeof(PanelType), "spacetype view3d panel object");
1415         strcpy(pt->idname, "VIEW3D_PT_object");
1416         strcpy(pt->label, "Transform");
1417         pt->draw= view3d_panel_object;
1418         BLI_addtail(&art->paneltypes, pt);
1419 /*
1420         pt= MEM_callocN(sizeof(PanelType), "spacetype view3d panel properties");
1421         strcpy(pt->idname, "VIEW3D_PT_properties");
1422         strcpy(pt->label, "View Properties");
1423         pt->draw= view3d_panel_properties;
1424         BLI_addtail(&art->paneltypes, pt);
1425
1426         pt= MEM_callocN(sizeof(PanelType), "spacetype view3d panel transform spaces");
1427         strcpy(pt->idname, "VIEW3D_PT_transform spaces");
1428         strcpy(pt->label, "Transform Orientations");
1429         pt->draw= view3d_panel_transform_spaces;
1430         BLI_addtail(&art->paneltypes, pt);
1431
1432         pt= MEM_callocN(sizeof(PanelType), "spacetype view3d panel gpencil");
1433         strcpy(pt->idname, "VIEW3D_PT_gpencil");
1434         strcpy(pt->label, "Greas Pencil");
1435         pt->draw= view3d_panel_gpencil;
1436         BLI_addtail(&art->paneltypes, pt);*/
1437
1438         pt= MEM_callocN(sizeof(PanelType), "spacetype view3d panel bonesketch spaces");
1439         strcpy(pt->idname, "VIEW3D_PT_bonesketch_spaces");
1440         strcpy(pt->label, "Bone Sketching");
1441         pt->draw= view3d_panel_bonesketch_spaces;
1442         pt->poll= view3d_panel_bonesketch_spaces_poll;
1443         BLI_addtail(&art->paneltypes, pt);
1444
1445         /*
1446         pt= MEM_callocN(sizeof(PanelType), "spacetype view3d panel redo");
1447         strcpy(pt->idname, "VIEW3D_PT_redo");
1448         strcpy(pt->label, "Last Operator");
1449         pt->draw= view3d_panel_operator_redo;
1450         BLI_addtail(&art->paneltypes, pt);
1451 */
1452         // XXX view3d_panel_preview(C, ar, 0);
1453 }
1454
1455 static int view3d_properties(bContext *C, wmOperator *op)
1456 {
1457         ScrArea *sa= CTX_wm_area(C);
1458         ARegion *ar= view3d_has_buttons_region(sa);
1459         
1460         if(ar) {
1461                 ar->flag ^= RGN_FLAG_HIDDEN;
1462                 ar->v2d.flag &= ~V2D_IS_INITIALISED; /* XXX should become hide/unhide api? */
1463                 
1464                 ED_area_initialize(CTX_wm_manager(C), CTX_wm_window(C), sa);
1465                 ED_area_tag_redraw(sa);
1466         }
1467         return OPERATOR_FINISHED;
1468 }
1469
1470 void VIEW3D_OT_properties(wmOperatorType *ot)
1471 {
1472         ot->name= "Properties";
1473         ot->idname= "VIEW3D_OT_properties";
1474         
1475         ot->exec= view3d_properties;
1476         ot->poll= ED_operator_view3d_active;
1477         
1478         /* flags */
1479         ot->flag= 0;
1480 }