2.5 - Rotation work (axis angle bugfixes + cleanups)
[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_gpencil_types.h"
40 #include "DNA_lamp_types.h"
41 #include "DNA_lattice_types.h"
42 #include "DNA_meta_types.h"
43 #include "DNA_mesh_types.h"
44 #include "DNA_meshdata_types.h"
45 #include "DNA_object_types.h"
46 #include "DNA_space_types.h"
47 #include "DNA_scene_types.h"
48 #include "DNA_screen_types.h"
49 #include "DNA_userdef_types.h"
50 #include "DNA_view3d_types.h"
51 #include "DNA_world_types.h"
52
53 #include "MEM_guardedalloc.h"
54
55 #include "BLI_arithb.h"
56 #include "BLI_blenlib.h"
57 #include "BLI_editVert.h"
58 #include "BLI_rand.h"
59
60 #include "BKE_action.h"
61 #include "BKE_brush.h"
62 #include "BKE_context.h"
63 #include "BKE_curve.h"
64 #include "BKE_customdata.h"
65 #include "BKE_depsgraph.h"
66 #include "BKE_idprop.h"
67 #include "BKE_mesh.h"
68 #include "BKE_object.h"
69 #include "BKE_global.h"
70 #include "BKE_scene.h"
71 #include "BKE_screen.h"
72 #include "BKE_utildefines.h"
73
74 #include "BIF_gl.h"
75
76 #include "WM_api.h"
77 #include "WM_types.h"
78
79 #include "RNA_access.h"
80 #include "RNA_define.h"
81
82 #include "ED_armature.h"
83 #include "ED_curve.h"
84 #include "ED_image.h"
85 #include "ED_gpencil.h"
86 #include "ED_keyframing.h"
87 #include "ED_mesh.h"
88 #include "ED_object.h"
89 #include "ED_particle.h"
90 #include "ED_screen.h"
91 #include "ED_transform.h"
92 #include "ED_types.h"
93 #include "ED_util.h"
94
95 #include "UI_interface.h"
96 #include "UI_resources.h"
97 #include "UI_view2d.h"
98
99 #include "view3d_intern.h"      // own include
100
101
102 /* ******************* view3d space & buttons ************** */
103 #define B_NOP           1
104 #define B_REDR          2
105 #define B_OBJECTPANELROT        1007
106 #define B_OBJECTPANELMEDIAN 1008
107 #define B_ARMATUREPANEL1        1009
108 #define B_ARMATUREPANEL2        1010
109 #define B_OBJECTPANELPARENT 1011
110 #define B_OBJECTPANEL           1012
111 #define B_ARMATUREPANEL3        1013
112 #define B_OBJECTPANELSCALE      1014
113 #define B_OBJECTPANELDIMS       1015
114 #define B_TRANSFORMSPACEADD     1016
115 #define B_TRANSFORMSPACECLEAR   1017
116 #define B_SETPT_AUTO    2125
117 #define B_SETPT_VECTOR  2126
118 #define B_SETPT_ALIGN   2127
119 #define B_SETPT_FREE    2128
120 #define B_RECALCMBALL   2501
121
122 #define B_WEIGHT0_0             2840
123 #define B_WEIGHT1_4             2841
124 #define B_WEIGHT1_2             2842
125 #define B_WEIGHT3_4             2843
126 #define B_WEIGHT1_0             2844
127
128 #define B_OPA1_8                2845
129 #define B_OPA1_4                2846
130 #define B_OPA1_2                2847
131 #define B_OPA3_4                2848
132 #define B_OPA1_0                2849
133
134 #define B_CLR_WPAINT    2850
135
136 #define B_RV3D_LOCKED   2900
137 #define B_RV3D_BOXVIEW  2901
138 #define B_RV3D_BOXCLIP  2902
139
140 #define B_IDNAME                3000
141
142 /* temporary struct for storing transform properties */
143 typedef struct {
144         float ob_eul[4];        // used for quat too....
145         float ob_scale[3]; // need temp space due to linked values
146         float ob_dims[3];
147         short link_scale;
148         float ve_median[5];
149         int curdef;
150         float *defweightp;
151 } TransformProperties;
152
153
154 /* is used for both read and write... */
155 static void v3d_editvertex_buts(const bContext *C, uiBlock *block, View3D *v3d, Object *ob, float lim)
156 {
157         MDeformVert *dvert=NULL;
158         TransformProperties *tfp= v3d->properties_storage;
159         float median[5], ve_median[5];
160         int tot, totw, totweight, totedge;
161         char defstr[320];
162         
163         median[0]= median[1]= median[2]= median[3]= median[4]= 0.0;
164         tot= totw= totweight= totedge= 0;
165         defstr[0]= 0;
166
167         if(ob->type==OB_MESH) {
168                 Mesh *me= ob->data;
169                 EditMesh *em = BKE_mesh_get_editmesh(me);
170                 EditVert *eve, *evedef=NULL;
171                 EditEdge *eed;
172                 
173                 eve= em->verts.first;
174                 while(eve) {
175                         if(eve->f & SELECT) {
176                                 evedef= eve;
177                                 tot++;
178                                 VecAddf(median, median, eve->co);
179                         }
180                         eve= eve->next;
181                 }
182                 eed= em->edges.first;
183                 while(eed) {
184                         if((eed->f & SELECT)) {
185                                 totedge++;
186                                 median[3]+= eed->crease;
187                         }
188                         eed= eed->next;
189                 }
190
191                 /* check for defgroups */
192                 if(evedef)
193                         dvert= CustomData_em_get(&em->vdata, evedef->data, CD_MDEFORMVERT);
194                 if(tot==1 && dvert && dvert->totweight) {
195                         bDeformGroup *dg;
196                         int i, max=1, init=1;
197                         char str[320];
198                         
199                         for (i=0; i<dvert->totweight; i++){
200                                 dg = BLI_findlink (&ob->defbase, dvert->dw[i].def_nr);
201                                 if(dg) {
202                                         max+= BLI_snprintf(str, sizeof(str), "%s %%x%d|", dg->name, dvert->dw[i].def_nr); 
203                                         if(max<320) strcat(defstr, str);
204                                 }
205                                 else printf("oh no!\n");
206                                 if(tfp->curdef==dvert->dw[i].def_nr) {
207                                         init= 0;
208                                         tfp->defweightp= &dvert->dw[i].weight;
209                                 }
210                         }
211                         
212                         if(init) {      // needs new initialized 
213                                 tfp->curdef= dvert->dw[0].def_nr;
214                                 tfp->defweightp= &dvert->dw[0].weight;
215                         }
216                 }
217
218                 BKE_mesh_end_editmesh(me, em);
219         }
220         else if(ob->type==OB_CURVE || ob->type==OB_SURF) {
221                 Curve *cu= ob->data;
222                 Nurb *nu;
223                 BPoint *bp;
224                 BezTriple *bezt;
225                 int a;
226                 
227                 nu= cu->editnurb->first;
228                 while(nu) {
229                         if(nu->type == CU_BEZIER) {
230                                 bezt= nu->bezt;
231                                 a= nu->pntsu;
232                                 while(a--) {
233                                         if(bezt->f2 & SELECT) {
234                                                 VecAddf(median, median, bezt->vec[1]);
235                                                 tot++;
236                                                 median[4]+= bezt->weight;
237                                                 totweight++;
238                                         }
239                                         else {
240                                                 if(bezt->f1 & SELECT) {
241                                                         VecAddf(median, median, bezt->vec[0]);
242                                                         tot++;
243                                                 }
244                                                 if(bezt->f3 & SELECT) {
245                                                         VecAddf(median, median, bezt->vec[2]);
246                                                         tot++;
247                                                 }
248                                         }
249                                         bezt++;
250                                 }
251                         }
252                         else {
253                                 bp= nu->bp;
254                                 a= nu->pntsu*nu->pntsv;
255                                 while(a--) {
256                                         if(bp->f1 & SELECT) {
257                                                 VecAddf(median, median, bp->vec);
258                                                 median[3]+= bp->vec[3];
259                                                 totw++;
260                                                 tot++;
261                                                 median[4]+= bp->weight;
262                                                 totweight++;
263                                         }
264                                         bp++;
265                                 }
266                         }
267                         nu= nu->next;
268                 }
269         }
270         else if(ob->type==OB_LATTICE) {
271                 Lattice *lt= ob->data;
272                 BPoint *bp;
273                 int a;
274                 
275                 a= lt->editlatt->pntsu*lt->editlatt->pntsv*lt->editlatt->pntsw;
276                 bp= lt->editlatt->def;
277                 while(a--) {
278                         if(bp->f1 & SELECT) {
279                                 VecAddf(median, median, bp->vec);
280                                 tot++;
281                                 median[4]+= bp->weight;
282                                 totweight++;
283                         }
284                         bp++;
285                 }
286         }
287         
288         if(tot==0) return;
289
290         median[0] /= (float)tot;
291         median[1] /= (float)tot;
292         median[2] /= (float)tot;
293         if(totedge) median[3] /= (float)totedge;
294         else if(totw) median[3] /= (float)totw;
295         if(totweight) median[4] /= (float)totweight;
296         
297         if(v3d->flag & V3D_GLOBAL_STATS)
298                 Mat4MulVecfl(ob->obmat, median);
299         
300         if(block) {     // buttons
301                 int but_y;
302                 if((ob->parent) && (ob->partype == PARBONE))    but_y = 135;
303                 else                                                                                    but_y = 150;
304                 
305                 uiBlockBeginAlign(block);
306                 uiDefButBitS(block, TOG, V3D_GLOBAL_STATS, B_REDR, "Global",            0, 20, 100, 20, &v3d->flag, 0, 0, 0, 0, "Displays global values");
307                 uiDefButBitS(block, TOGN, V3D_GLOBAL_STATS, B_REDR, "Local",            100, 20, 100, 20, &v3d->flag, 0, 0, 0, 0, "Displays local values");
308                 uiBlockEndAlign(block);
309                 
310                 memcpy(tfp->ve_median, median, sizeof(tfp->ve_median));
311                 
312                 uiBlockBeginAlign(block);
313                 if(tot==1) {
314                         uiDefBut(block, LABEL, 0, "Vertex:",                                    0, 130, 200, 20, 0, 0, 0, 0, 0, "");
315                         uiDefButF(block, NUM, B_OBJECTPANELMEDIAN, "X:",                0, 110, 200, 20, &(tfp->ve_median[0]), -lim, lim, 10, 3, "");
316                         uiDefButF(block, NUM, B_OBJECTPANELMEDIAN, "Y:",                0, 90, 200, 20, &(tfp->ve_median[1]), -lim, lim, 10, 3, "");
317                         uiDefButF(block, NUM, B_OBJECTPANELMEDIAN, "Z:",                0, 70, 200, 20, &(tfp->ve_median[2]), -lim, lim, 10, 3, "");
318                         if(totw==1)
319                                 uiDefButF(block, NUM, B_OBJECTPANELMEDIAN, "Vertex W:", 0, 50, 200, 19, &(tfp->ve_median[3]), 0.01, 100.0, 10, 3, "");
320                         uiBlockEndAlign(block);
321         
322                         if(defstr[0]) {
323                                 uiDefBut(block, LABEL, 1, "Vertex Deform Groups",               0, 40, 200, 20, NULL, 0.0, 0.0, 0, 0, "");
324
325                                 uiBlockBeginAlign(block);
326                                 uiDefButF(block, NUM, B_NOP, "Weight:",                                 10, 20, 150, 20, tfp->defweightp, 0.0f, 1.0f, 10, 3, "Weight value");
327                                 uiDefButI(block, MENU, B_REDR, defstr,                                  160, 20, 140, 20, &tfp->curdef, 0.0, 0.0, 0, 0, "Current Vertex Group");
328                                 uiBlockEndAlign(block);
329                         }
330                         else if(totweight)
331                                 uiDefButF(block, NUM, B_OBJECTPANELMEDIAN, "Weight:",   0, 20, 200, 20, &(tfp->ve_median[4]), 0.0, 1.0, 10, 3, "");
332
333                 }
334                 else {
335                         uiDefBut(block, LABEL, 0, "Median:",                                            0, 130, 200, 20, 0, 0, 0, 0, 0, "");
336                         uiDefButF(block, NUM, B_OBJECTPANELMEDIAN, "X:",                0, 110, 200, 20, &(tfp->ve_median[0]), -lim, lim, 10, 3, "");
337                         uiDefButF(block, NUM, B_OBJECTPANELMEDIAN, "Y:",                0, 90, 200, 20, &(tfp->ve_median[1]), -lim, lim, 10, 3, "");
338                         uiDefButF(block, NUM, B_OBJECTPANELMEDIAN, "Z:",                0, 70, 200, 20, &(tfp->ve_median[2]), -lim, lim, 10, 3, "");
339                         if(totw==tot)
340                                 uiDefButF(block, NUM, B_OBJECTPANELMEDIAN, "W:",        0, 50, 200, 20, &(tfp->ve_median[3]), 0.01, 100.0, 10, 3, "");
341                         uiBlockEndAlign(block);
342                         if(totweight)
343                                 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");
344                 }
345                 
346                 if(ob->type==OB_CURVE && (totw==0)) { /* bez curves have no w */
347                         uiBlockBeginAlign(block);
348                         uiDefBut(block, BUT,B_SETPT_AUTO,"Auto",        10, 44, 72, 19, 0, 0, 0, 0, 0, "Auto handles (Shift H)");
349                         uiDefBut(block, BUT,B_SETPT_VECTOR,"Vector",82, 44, 73, 19, 0, 0, 0, 0, 0, "Vector handles (V)");
350                         uiDefBut(block, BUT,B_SETPT_ALIGN,"Align",155, 44, 73, 19, 0, 0, 0, 0, 0, "Align handles (H Toggles)");
351                         uiDefBut(block, BUT,B_SETPT_FREE,"Free",        227, 44, 72, 19, 0, 0, 0, 0, 0, "Align handles (H Toggles)");
352                         uiBlockEndAlign(block);
353                 }
354                 
355                 if(totedge==1)
356                         uiDefButF(block, NUM, B_OBJECTPANELMEDIAN, "Crease W:", 0, 45, 200, 20, &(tfp->ve_median[3]), 0.0, 1.0, 10, 3, "");
357                 else if(totedge>1)
358                         uiDefButF(block, NUM, B_OBJECTPANELMEDIAN, "Median Crease W:",  0, 45, 200, 20, &(tfp->ve_median[3]), 0.0, 1.0, 10, 3, "");
359                 
360         }
361         else {  // apply
362                 memcpy(ve_median, tfp->ve_median, sizeof(tfp->ve_median));
363                 
364                 if(v3d->flag & V3D_GLOBAL_STATS) {
365                         Mat4Invert(ob->imat, ob->obmat);
366                         Mat4MulVecfl(ob->imat, median);
367                         Mat4MulVecfl(ob->imat, ve_median);
368                 }
369                 VecSubf(median, ve_median, median);
370                 median[3]= ve_median[3]-median[3];
371                 median[4]= ve_median[4]-median[4];
372                 
373                 if(ob->type==OB_MESH) {
374                         Mesh *me= ob->data;
375                         EditMesh *em = BKE_mesh_get_editmesh(me);
376                         EditVert *eve;
377                         EditEdge *eed;
378                         
379                         eve= em->verts.first;
380                         while(eve) {
381                                 if(eve->f & SELECT) {
382                                         VecAddf(eve->co, eve->co, median);
383                                 }
384                                 eve= eve->next;
385                         }
386                         
387                         for(eed= em->edges.first; eed; eed= eed->next) {
388                                 if(eed->f & SELECT) {
389                                         /* ensure the median can be set to zero or one */
390                                         if(ve_median[3]==0.0f) eed->crease= 0.0f;
391                                         else if(ve_median[3]==1.0f) eed->crease= 1.0f;
392                                         else {
393                                                 eed->crease+= median[3];
394                                                 CLAMP(eed->crease, 0.0, 1.0);
395                                         }
396                                 }
397                         }
398                         
399                         recalc_editnormals(em);
400
401                         BKE_mesh_end_editmesh(me, em);
402                 }
403                 else if(ob->type==OB_CURVE || ob->type==OB_SURF) {
404                         Curve *cu= ob->data;
405                         Nurb *nu;
406                         BPoint *bp;
407                         BezTriple *bezt;
408                         int a;
409                         
410                         nu= cu->editnurb->first;
411                         while(nu) {
412                                 if(nu->type == CU_BEZIER) {
413                                         bezt= nu->bezt;
414                                         a= nu->pntsu;
415                                         while(a--) {
416                                                 if(bezt->f2 & SELECT) {
417                                                         VecAddf(bezt->vec[0], bezt->vec[0], median);
418                                                         VecAddf(bezt->vec[1], bezt->vec[1], median);
419                                                         VecAddf(bezt->vec[2], bezt->vec[2], median);
420                                                         bezt->weight+= median[4];
421                                                 }
422                                                 else {
423                                                         if(bezt->f1 & SELECT) {
424                                                                 VecAddf(bezt->vec[0], bezt->vec[0], median);
425                                                         }
426                                                         if(bezt->f3 & SELECT) {
427                                                                 VecAddf(bezt->vec[2], bezt->vec[2], median);
428                                                         }
429                                                 }
430                                                 bezt++;
431                                         }
432                                 }
433                                 else {
434                                         bp= nu->bp;
435                                         a= nu->pntsu*nu->pntsv;
436                                         while(a--) {
437                                                 if(bp->f1 & SELECT) {
438                                                         VecAddf(bp->vec, bp->vec, median);
439                                                         bp->vec[3]+= median[3];
440                                                         bp->weight+= median[4];
441                                                 }
442                                                 bp++;
443                                         }
444                                 }
445                                 test2DNurb(nu);
446                                 testhandlesNurb(nu); /* test for bezier too */
447
448                                 nu= nu->next;
449                         }
450                 }
451                 else if(ob->type==OB_LATTICE) {
452                         Lattice *lt= ob->data;
453                         BPoint *bp;
454                         int a;
455                         
456                         a= lt->editlatt->pntsu*lt->editlatt->pntsv*lt->editlatt->pntsw;
457                         bp= lt->editlatt->def;
458                         while(a--) {
459                                 if(bp->f1 & SELECT) {
460                                         VecAddf(bp->vec, bp->vec, median);
461                                         bp->weight+= median[4];
462                                 }
463                                 bp++;
464                         }
465                 }
466                 
467 //              ED_undo_push(C, "Transform properties");
468         }
469 }
470
471 /* assumes armature active */
472 static void validate_bonebutton_cb(bContext *C, void *bonev, void *namev)
473 {
474         Object *ob= CTX_data_active_object(C);
475         
476         if(ob && ob->type==OB_ARMATURE) {
477                 Bone *bone= bonev;
478                 char oldname[32], newname[32];
479                 
480                 /* need to be on the stack */
481                 BLI_strncpy(newname, bone->name, 32);
482                 BLI_strncpy(oldname, (char *)namev, 32);
483                 /* restore */
484                 BLI_strncpy(bone->name, oldname, 32);
485                 
486                 ED_armature_bone_rename(ob->data, oldname, newname); // editarmature.c
487         }
488 }
489
490 static void v3d_posearmature_buts(uiBlock *block, View3D *v3d, Object *ob, float lim)
491 {
492         uiBut *but;
493         bArmature *arm;
494         bPoseChannel *pchan;
495         Bone *bone= NULL;
496         TransformProperties *tfp= v3d->properties_storage;
497
498         arm = ob->data;
499         if (!arm || !ob->pose) return;
500
501         for(pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) {
502                 bone = pchan->bone;
503                 if(bone && (bone->flag & BONE_ACTIVE) && (bone->layer & arm->layer))
504                         break;
505         }
506         if (!pchan || !bone) return;
507
508         if((ob->parent) && (ob->partype == PARBONE))
509                 but= uiDefBut (block, TEX, B_NOP, "Bone:",                              160, 130, 140, 19, bone->name, 1, 31, 0, 0, "");
510         else
511                 but= uiDefBut(block, TEX, B_NOP, "Bone:",                               160, 140, 140, 19, bone->name, 1, 31, 0, 0, "");
512         uiButSetFunc(but, validate_bonebutton_cb, bone, NULL);
513         uiButSetCompleteFunc(but, autocomplete_bone, (void *)ob);
514         
515         if (pchan->rotmode == PCHAN_ROT_AXISANGLE) {
516                 float quat[4];
517                 /* convert to euler, passing through quats... */
518                 AxisAngleToQuat(quat, &pchan->quat[1], pchan->quat[0]);
519                 QuatToEul(quat, tfp->ob_eul);
520         }
521         else if (pchan->rotmode == PCHAN_ROT_QUAT)
522                 QuatToEul(pchan->quat, tfp->ob_eul);
523         else
524                 VecCopyf(tfp->ob_eul, pchan->eul);
525         tfp->ob_eul[0]*= 180.0/M_PI;
526         tfp->ob_eul[1]*= 180.0/M_PI;
527         tfp->ob_eul[2]*= 180.0/M_PI;
528         
529         uiBlockBeginAlign(block);
530         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");
531         uiDefButF(block, NUM, B_ARMATUREPANEL2, "LocX:",        30, 140, 120, 19, pchan->loc, -lim, lim, 100, 3, "");
532         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");
533         uiDefButF(block, NUM, B_ARMATUREPANEL2, "LocY:",        30, 120, 120, 19, pchan->loc+1, -lim, lim, 100, 3, "");
534         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");
535         uiDefButF(block, NUM, B_ARMATUREPANEL2, "LocZ:",        30, 100, 120, 19, pchan->loc+2, -lim, lim, 100, 3, "");
536
537         uiBlockBeginAlign(block);
538         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");
539         uiDefButF(block, NUM, B_ARMATUREPANEL3, "RotX:",        30, 70, 120, 19, tfp->ob_eul, -1000.0, 1000.0, 100, 3, "");
540         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");
541         uiDefButF(block, NUM, B_ARMATUREPANEL3, "RotY:",        30, 50, 120, 19, tfp->ob_eul+1, -1000.0, 1000.0, 100, 3, "");
542         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");
543         uiDefButF(block, NUM, B_ARMATUREPANEL3, "RotZ:",        30, 30, 120, 19, tfp->ob_eul+2, -1000.0, 1000.0, 100, 3, "");
544         
545         uiBlockBeginAlign(block);
546         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");
547         uiDefButF(block, NUM, B_ARMATUREPANEL2, "ScaleX:",      180, 70, 120, 19, pchan->size, -lim, lim, 10, 3, "");
548         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");
549         uiDefButF(block, NUM, B_ARMATUREPANEL2, "ScaleY:",      180, 50, 120, 19, pchan->size+1, -lim, lim, 10, 3, "");
550         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");
551         uiDefButF(block, NUM, B_ARMATUREPANEL2, "ScaleZ:",      180, 30, 120, 19, pchan->size+2, -lim, lim, 10, 3, "");
552         uiBlockEndAlign(block);
553 }
554
555 /* assumes armature editmode */
556 void validate_editbonebutton_cb(bContext *C, void *bonev, void *namev)
557 {
558         EditBone *eBone= bonev;
559         char oldname[32], newname[32];
560         
561         /* need to be on the stack */
562         BLI_strncpy(newname, eBone->name, 32);
563         BLI_strncpy(oldname, (char *)namev, 32);
564         /* restore */
565         BLI_strncpy(eBone->name, oldname, 32);
566         
567         ED_armature_bone_rename(CTX_data_edit_object(C)->data, oldname, newname); // editarmature.c
568         WM_event_add_notifier(C, NC_OBJECT|ND_BONE_SELECT, CTX_data_edit_object(C)); // XXX fix
569 }
570
571 static void v3d_editarmature_buts(uiBlock *block, View3D *v3d, Object *ob, float lim)
572 {
573         bArmature *arm= ob->data;
574         EditBone *ebone;
575         uiBut *but;
576         TransformProperties *tfp= v3d->properties_storage;
577         
578         ebone= arm->edbo->first;
579
580         for (ebone = arm->edbo->first; ebone; ebone=ebone->next){
581                 if ((ebone->flag & BONE_ACTIVE) && (ebone->layer & arm->layer))
582                         break;
583         }
584
585         if (!ebone)
586                 return;
587         
588         if((ob->parent) && (ob->partype == PARBONE))
589                 but= uiDefBut(block, TEX, B_NOP, "Bone:", 160, 130, 140, 19, ebone->name, 1, 31, 0, 0, "");
590         else
591                 but= uiDefBut(block, TEX, B_NOP, "Bone:",                       160, 150, 140, 19, ebone->name, 1, 31, 0, 0, "");
592         uiButSetFunc(but, validate_editbonebutton_cb, ebone, NULL);
593
594         uiBlockBeginAlign(block);
595         uiDefButF(block, NUM, B_ARMATUREPANEL1, "HeadX:",       10, 70, 140, 19, ebone->head, -lim, lim, 10, 3, "");
596         uiDefButF(block, NUM, B_ARMATUREPANEL1, "HeadY:",       10, 50, 140, 19, ebone->head+1, -lim, lim, 10, 3, "");
597         uiDefButF(block, NUM, B_ARMATUREPANEL1, "HeadZ:",       10, 30, 140, 19, ebone->head+2, -lim, lim, 10, 3, "");
598         uiBlockBeginAlign(block);
599         uiDefButF(block, NUM, B_ARMATUREPANEL1, "TailX:",       160, 70, 140, 19, ebone->tail, -lim, lim, 10, 3, "");
600         uiDefButF(block, NUM, B_ARMATUREPANEL1, "TailY:",       160, 50, 140, 19, ebone->tail+1, -lim, lim, 10, 3, "");
601         uiDefButF(block, NUM, B_ARMATUREPANEL1, "TailZ:",       160, 30, 140, 19, ebone->tail+2, -lim, lim, 10, 3, "");
602         uiBlockEndAlign(block);
603         
604         tfp->ob_eul[0]= 180.0*ebone->roll/M_PI;
605         uiDefButF(block, NUM, B_ARMATUREPANEL1, "Roll:",        10, 100, 140, 19, tfp->ob_eul, -lim, lim, 1000, 3, "");
606
607         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");
608         
609         uiBlockBeginAlign(block);
610         uiDefButF(block, NUM, B_ARMATUREPANEL1, "TailRadius:",  10, 150, 140, 19, &ebone->rad_tail, 0, lim, 10, 3, "");
611         if (ebone->parent && ebone->flag & BONE_CONNECTED )
612                 uiDefButF(block, NUM, B_ARMATUREPANEL1, "HeadRadius:",  10, 130, 140, 19, &ebone->parent->rad_tail, 0, lim, 10, 3, "");
613         else
614                 uiDefButF(block, NUM, B_ARMATUREPANEL1, "HeadRadius:",  10, 130, 140, 19, &ebone->rad_head, 0, lim, 10, 3, "");
615         uiBlockEndAlign(block);
616 }
617
618 static void v3d_editmetaball_buts(uiBlock *block, Object *ob, float lim)
619 {
620         MetaElem *lastelem= NULL; // XXX
621
622         if(lastelem) {
623                 uiBlockBeginAlign(block);
624                 uiDefButF(block, NUM, B_RECALCMBALL, "LocX:", 10, 70, 140, 19, &lastelem->x, -lim, lim, 100, 3, "");
625                 uiDefButF(block, NUM, B_RECALCMBALL, "LocY:", 10, 50, 140, 19, &lastelem->y, -lim, lim, 100, 3, "");
626                 uiDefButF(block, NUM, B_RECALCMBALL, "LocZ:", 10, 30, 140, 19, &lastelem->z, -lim, lim, 100, 3, "");
627
628                 uiBlockBeginAlign(block);
629                 if(lastelem->type!=MB_BALL)
630                         uiDefButF(block, NUM, B_RECALCMBALL, "dx:", 160, 70, 140, 19, &lastelem->expx, 0, lim, 100, 3, "");
631                 if((lastelem->type!=MB_BALL) && (lastelem->type!=MB_TUBE))
632                         uiDefButF(block, NUM, B_RECALCMBALL, "dy:", 160, 50, 140, 19, &lastelem->expy, 0, lim, 100, 3, "");
633                 if((lastelem->type==MB_ELIPSOID) || (lastelem->type==MB_CUBE))
634                         uiDefButF(block, NUM, B_RECALCMBALL, "dz:", 160, 30, 140, 19, &lastelem->expz, 0, lim, 100, 3, "");
635
636                 uiBlockEndAlign(block); 
637
638                 uiBlockBeginAlign(block);
639                 uiDefButF(block, NUM, B_RECALCMBALL, "Radius:", 10, 120, 140, 19, &lastelem->rad, 0, lim, 100, 3, "Size of the active metaball");
640                 uiDefButF(block, NUM, B_RECALCMBALL, "Stiffness:", 10, 100, 140, 19, &lastelem->s, 0, 10, 100, 3, "Stiffness of the active metaball");
641                 uiBlockEndAlign(block);
642                 
643                 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");
644                 
645         }
646 }
647
648 /* test if 'ob' is a parent somewhere in par's parents */
649 static int test_parent_loop(Object *par, Object *ob)
650 {
651         if(par == NULL) return 0;
652         if(ob == par) return 1;
653         return test_parent_loop(par->parent, ob);
654 }
655
656 static void do_view3d_region_buttons(bContext *C, void *arg, int event)
657 {
658         Scene *scene= CTX_data_scene(C);
659         Object *obedit= CTX_data_edit_object(C);
660         View3D *v3d= CTX_wm_view3d(C);
661         BoundBox *bb;
662         Object *ob= OBACT;
663         TransformProperties *tfp= v3d->properties_storage;
664         
665         switch(event) {
666         
667         case B_REDR:
668                 ED_area_tag_redraw(CTX_wm_area(C));
669                 return; /* no notifier! */
670                 
671         case B_OBJECTPANEL:
672                 DAG_id_flush_update(&ob->id, OB_RECALC_OB);
673                 break;
674                 
675         case B_OBJECTPANELROT:
676                 if(ob) {
677                         ob->rot[0]= M_PI*tfp->ob_eul[0]/180.0;
678                         ob->rot[1]= M_PI*tfp->ob_eul[1]/180.0;
679                         ob->rot[2]= M_PI*tfp->ob_eul[2]/180.0;
680                         DAG_id_flush_update(&ob->id, OB_RECALC_OB);
681                 }
682                 break;
683
684         case B_OBJECTPANELSCALE:
685                 if(ob) {
686
687                         /* link scale; figure out which axis changed */
688                         if (tfp->link_scale) {
689                                 float ratio, tmp, max = 0.0;
690                                 int axis;
691                                 
692                                 axis = 0;
693                                 max = fabs(tfp->ob_scale[0] - ob->size[0]);
694                                 tmp = fabs(tfp->ob_scale[1] - ob->size[1]);
695                                 if (tmp > max) {
696                                         axis = 1;
697                                         max = tmp;
698                                 }
699                                 tmp = fabs(tfp->ob_scale[2] - ob->size[2]);
700                                 if (tmp > max) {
701                                         axis = 2;
702                                         max = tmp;
703                                 }
704                         
705                                 if (ob->size[axis] != tfp->ob_scale[axis]) {
706                                         if (fabs(ob->size[axis]) > FLT_EPSILON) {
707                                                 ratio = tfp->ob_scale[axis] / ob->size[axis];
708                                                 ob->size[0] *= ratio;
709                                                 ob->size[1] *= ratio;
710                                                 ob->size[2] *= ratio;
711                                         }
712                                 }
713                         }
714                         else {
715                                 VECCOPY(ob->size, tfp->ob_scale);
716                                 
717                         }
718                         DAG_id_flush_update(&ob->id, OB_RECALC_OB);
719                 }
720                 break;
721
722         case B_OBJECTPANELDIMS:
723                 bb= object_get_boundbox(ob);
724                 if(bb) {
725                         float old_dims[3], scale[3], ratio, len[3];
726                         int axis;
727
728                         Mat4ToSize(ob->obmat, scale);
729
730                         len[0] = bb->vec[4][0] - bb->vec[0][0];
731                         len[1] = bb->vec[2][1] - bb->vec[0][1];
732                         len[2] = bb->vec[1][2] - bb->vec[0][2];
733
734                         old_dims[0] = fabs(scale[0]) * len[0];
735                         old_dims[1] = fabs(scale[1]) * len[1];
736                         old_dims[2] = fabs(scale[2]) * len[2];
737
738                         /* for each axis changed */
739                         for (axis = 0; axis<3; axis++) {
740                                 if (fabs(old_dims[axis] - tfp->ob_dims[axis]) > 0.0001) {
741                                         if (old_dims[axis] > 0.0) {
742                                                 ratio = tfp->ob_dims[axis] / old_dims[axis]; 
743                                                 if (tfp->link_scale) {
744                                                         ob->size[0] *= ratio;
745                                                         ob->size[1] *= ratio;
746                                                         ob->size[2] *= ratio;
747                                                         break;
748                                                 }
749                                                 else {
750                                                         ob->size[axis] *= ratio;
751                                                 }
752                                         }
753                                         else {
754                                                 if (len[axis] > 0) {
755                                                         ob->size[axis] = tfp->ob_dims[axis] / len[axis];
756                                                 }
757                                         }
758                                 }
759                         }
760                         
761                         /* prevent multiple B_OBJECTPANELDIMS events to keep scaling, cycling with TAB on buttons can cause that */
762                         VECCOPY(tfp->ob_dims, old_dims);
763                         
764                         DAG_id_flush_update(&ob->id, OB_RECALC_OB);
765                 }
766                 break;
767         
768         case B_OBJECTPANELMEDIAN:
769                 if(ob) {
770                         v3d_editvertex_buts(C, NULL, v3d, ob, 1.0);
771                         DAG_id_flush_update(&ob->id, OB_RECALC_DATA);
772                 }
773                 break;
774                 
775                 /* note; this case also used for parbone */
776         case B_OBJECTPANELPARENT:
777                 if(ob) {
778                         if(ob->id.lib || test_parent_loop(ob->parent, ob) ) 
779                                 ob->parent= NULL;
780                         else {
781                                 DAG_scene_sort(scene);
782                                 DAG_id_flush_update(&ob->id, OB_RECALC_OB);
783                         }
784                 }
785                 break;
786                 
787         case B_ARMATUREPANEL1:
788                 {
789                         bArmature *arm= obedit->data;
790                         EditBone *ebone, *child;
791                         
792                         for (ebone = arm->edbo->first; ebone; ebone=ebone->next){
793                                 if ((ebone->flag & BONE_ACTIVE) && (ebone->layer & arm->layer))
794                                         break;
795                         }
796                         if (ebone) {
797                                 ebone->roll= M_PI*tfp->ob_eul[0]/180.0;
798                                 //      Update our parent
799                                 if (ebone->parent && ebone->flag & BONE_CONNECTED){
800                                         VECCOPY (ebone->parent->tail, ebone->head);
801                                 }
802                         
803                                 //      Update our children if necessary
804                                 for (child = arm->edbo->first; child; child=child->next){
805                                         if (child->parent == ebone && (child->flag & BONE_CONNECTED)){
806                                                 VECCOPY (child->head, ebone->tail);
807                                         }
808                                 }
809                                 if(arm->flag & ARM_MIRROR_EDIT) {
810                                         EditBone *eboflip= ED_armature_bone_get_mirrored(arm->edbo, ebone);
811                                         if(eboflip) {
812                                                 eboflip->roll= -ebone->roll;
813                                                 eboflip->head[0]= -ebone->head[0];
814                                                 eboflip->tail[0]= -ebone->tail[0];
815                                                 
816                                                 //      Update our parent
817                                                 if (eboflip->parent && eboflip->flag & BONE_CONNECTED){
818                                                         VECCOPY (eboflip->parent->tail, eboflip->head);
819                                                 }
820                                                 
821                                                 //      Update our children if necessary
822                                                 for (child = arm->edbo->first; child; child=child->next){
823                                                         if (child->parent == eboflip && (child->flag & BONE_CONNECTED)){
824                                                                 VECCOPY (child->head, eboflip->tail);
825                                                         }
826                                                 }
827                                         }
828                                 }
829                         }
830                 }
831                 break;
832         case B_ARMATUREPANEL3:  // rotate button on channel
833                 {
834                         bArmature *arm;
835                         bPoseChannel *pchan;
836                         Bone *bone;
837                         float eul[3];
838                         
839                         arm = ob->data;
840                         if (!arm || !ob->pose) return;
841                                 
842                         for(pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) {
843                                 bone = pchan->bone;
844                                 if(bone && (bone->flag & BONE_ACTIVE) && (bone->layer & arm->layer))
845                                         break;
846                         }
847                         if (!pchan) return;
848                         
849                         /* make a copy to eul[3], to allow TAB on buttons to work */
850                         eul[0]= M_PI*tfp->ob_eul[0]/180.0;
851                         eul[1]= M_PI*tfp->ob_eul[1]/180.0;
852                         eul[2]= M_PI*tfp->ob_eul[2]/180.0;
853                         
854                         if (pchan->rotmode == PCHAN_ROT_AXISANGLE) {
855                                 float quat[4];
856                                 /* convert to axis-angle, passing through quats  */
857                                 EulToQuat(eul, quat);
858                                 QuatToAxisAngle(quat, &pchan->quat[1], &pchan->quat[0]);
859                         }
860                         else if (pchan->rotmode == PCHAN_ROT_QUAT)
861                                 EulToQuat(eul, pchan->quat);
862                         else
863                                 VecCopyf(pchan->eul, eul);
864                         
865                 }
866                 /* no break, pass on */
867         case B_ARMATUREPANEL2:
868                 {
869                         ob->pose->flag |= (POSE_LOCKED|POSE_DO_UNLOCK);
870                         DAG_id_flush_update(&ob->id, OB_RECALC_DATA);
871                 }
872                 break;
873         case B_TRANSFORMSPACEADD:
874                 BIF_manageTransformOrientation(C, 1, 0);
875                 break;
876         case B_TRANSFORMSPACECLEAR:
877                 BIF_clearTransformOrientation(C);
878                 break;
879                 
880 #if 0 // XXX
881         case B_WEIGHT0_0:
882                 wpaint->weight = 0.0f;
883                 break;
884                 
885         case B_WEIGHT1_4:
886                 wpaint->weight = 0.25f;
887                 break;
888         case B_WEIGHT1_2:
889                 wpaint->weight = 0.5f;
890                 break;
891         case B_WEIGHT3_4:
892                 wpaint->weight = 0.75f;
893                 break;
894         case B_WEIGHT1_0:
895                 wpaint->weight = 1.0f;
896                 break;
897                 
898         case B_OPA1_8:
899                 wpaint->a = 0.125f;
900                 break;
901         case B_OPA1_4:
902                 wpaint->a = 0.25f;
903                 break;
904         case B_OPA1_2:
905                 wpaint->a = 0.5f;
906                 break;
907         case B_OPA3_4:
908                 wpaint->a = 0.75f;
909                 break;
910         case B_OPA1_0:
911                 wpaint->a = 1.0f;
912                 break;
913 #endif
914         case B_CLR_WPAINT:
915 //              if(!multires_level1_test()) {
916                 {
917                         bDeformGroup *defGroup = BLI_findlink(&ob->defbase, ob->actdef-1);
918                         if(defGroup) {
919                                 Mesh *me= ob->data;
920                                 int a;
921                                 for(a=0; a<me->totvert; a++)
922                                         ED_vgroup_vert_remove (ob, defGroup, a);
923                                 DAG_id_flush_update(&ob->id, OB_RECALC_DATA);
924                         }
925                 }
926                 break;
927         case B_RV3D_LOCKED:
928         case B_RV3D_BOXVIEW:
929         case B_RV3D_BOXCLIP:
930                 {
931                         ScrArea *sa= CTX_wm_area(C);
932                         ARegion *ar= sa->regionbase.last;
933                         RegionView3D *rv3d;
934                         short viewlock;
935                         
936                         ar= ar->prev;
937                         rv3d= ar->regiondata;
938                         viewlock= rv3d->viewlock;
939                         
940                         if((viewlock & RV3D_LOCKED)==0)
941                                 viewlock= 0;
942                         else if((viewlock & RV3D_BOXVIEW)==0)
943                                 viewlock &= ~RV3D_BOXCLIP;
944                         
945                         for(; ar; ar= ar->prev) {
946                                 if(ar->alignment==RGN_ALIGN_QSPLIT) {
947                                         rv3d= ar->regiondata;
948                                         rv3d->viewlock= viewlock;
949                                 }
950                         }
951                         
952                         if(rv3d->viewlock & RV3D_BOXVIEW)
953                                 view3d_boxview_copy(sa, sa->regionbase.last);
954                         
955                         ED_area_tag_redraw(sa);
956                 }
957                 break;
958         }
959
960         /* default for now */
961         WM_event_add_notifier(C, NC_OBJECT|ND_TRANSFORM, ob);
962 }
963
964 void removeTransformOrientation_func(bContext *C, void *target, void *unused)
965 {
966         BIF_removeTransformOrientation(C, (TransformOrientation *) target);
967 }
968
969 void selectTransformOrientation_func(bContext *C, void *target, void *unused)
970 {
971         BIF_selectTransformOrientation(C, (TransformOrientation *) target);
972 }
973
974 #if 0 // XXX not used
975 static void view3d_panel_transform_spaces(const bContext *C, Panel *pa)
976 {
977         Scene *scene= CTX_data_scene(C);
978         Object *obedit= CTX_data_edit_object(C);
979         View3D *v3d= CTX_wm_view3d(C);
980         ListBase *transform_spaces = &scene->transform_spaces;
981         TransformOrientation *ts = transform_spaces->first;
982         uiBlock *block;
983         uiBut *but;
984         int xco = 20, yco = 70;
985         int index;
986
987         block= uiLayoutFreeBlock(pa->layout);
988
989         uiBlockBeginAlign(block);
990         
991         if (obedit)
992                 uiDefBut(block, BUT, B_TRANSFORMSPACEADD, "Add", xco,120,80,20, 0, 0, 0, 0, 0, "Add the selected element as a Transform Orientation");
993         else
994                 uiDefBut(block, BUT, B_TRANSFORMSPACEADD, "Add", xco,120,80,20, 0, 0, 0, 0, 0, "Add the active object as a Transform Orientation");
995
996         uiDefBut(block, BUT, B_TRANSFORMSPACECLEAR, "Clear", xco + 80,120,80,20, 0, 0, 0, 0, 0, "Removal all Transform Orientations");
997         
998         uiBlockEndAlign(block);
999         
1000         uiBlockBeginAlign(block);
1001         
1002         uiDefButS(block, ROW, B_REDR, "Global", xco,            90, 40,20, &v3d->twmode, 5.0, (float)V3D_MANIP_GLOBAL,0, 0, "Global Transform Orientation");
1003         uiDefButS(block, ROW, B_REDR, "Local",  xco + 40,       90, 40,20, &v3d->twmode, 5.0, (float)V3D_MANIP_LOCAL, 0, 0, "Local Transform Orientation");
1004         uiDefButS(block, ROW, B_REDR, "Normal", xco + 80,       90, 40,20, &v3d->twmode, 5.0, (float)V3D_MANIP_NORMAL,0, 0, "Normal Transform Orientation");
1005         uiDefButS(block, ROW, B_REDR, "View",           xco + 120,      90, 40,20, &v3d->twmode, 5.0, (float)V3D_MANIP_VIEW,    0, 0, "View Transform Orientation");
1006         
1007         for (index = V3D_MANIP_CUSTOM, ts = transform_spaces->first ; ts ; ts = ts->next, index++) {
1008
1009                 if (v3d->twmode == index) {
1010                         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");
1011                 }
1012                 else {
1013                         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");
1014                 }
1015                 uiButSetFunc(but, selectTransformOrientation_func, ts, NULL);
1016                 uiDefBut(block, TEX, 0, "", xco+=XIC, yco,100+XIC,20, &ts->name, 0, 30, 0, 0, "Edits the name of this Transform Orientation");
1017                 but = uiDefIconBut(block, BUT, B_REDR, ICON_X, xco+=100+XIC,yco,XIC,YIC, 0, 0, 0, 0, 0, "Deletes this Transform Orientation");
1018                 uiButSetFunc(but, removeTransformOrientation_func, ts, NULL);
1019
1020                 xco = 20;
1021                 yco -= 25;
1022         }
1023         uiBlockEndAlign(block);
1024 }
1025 #endif // XXX not used
1026
1027 #if 0
1028 static void brush_idpoin_handle(bContext *C, ID *id, int event)
1029 {
1030         Brush **br = current_brush_source(CTX_data_scene(C));
1031
1032         if(!br)
1033                 return;
1034
1035         switch(event) {
1036         case UI_ID_BROWSE:
1037                 (*br) = (Brush*)id;
1038                 break;
1039         case UI_ID_DELETE:
1040                 brush_delete(br);
1041                 break;
1042         case UI_ID_RENAME:
1043                 /* XXX ? */
1044                 break;
1045         case UI_ID_ADD_NEW:
1046                 if(id) {
1047                         (*br) = copy_brush((Brush*)id);
1048                         id->us--;
1049                 }
1050                 else
1051                         (*br) = add_brush("Brush");
1052                 break;
1053         case UI_ID_OPEN:
1054                 /* XXX not implemented */
1055                 break;
1056         }
1057 }
1058 #endif
1059
1060 static void view3d_panel_object(const bContext *C, Panel *pa)
1061 {
1062         uiBlock *block;
1063         Scene *scene= CTX_data_scene(C);
1064         Object *obedit= CTX_data_edit_object(C);
1065         View3D *v3d= CTX_wm_view3d(C);
1066         //uiBut *bt;
1067         Object *ob= OBACT;
1068         TransformProperties *tfp;
1069         float lim;
1070         
1071         if(ob==NULL) return;
1072
1073         /* make sure we got storage */
1074         if(v3d->properties_storage==NULL)
1075                 v3d->properties_storage= MEM_callocN(sizeof(TransformProperties), "TransformProperties");
1076         tfp= v3d->properties_storage;
1077         
1078         block= uiLayoutFreeBlock(pa->layout);
1079         uiBlockSetHandleFunc(block, do_view3d_region_buttons, NULL);
1080
1081 // XXX  uiSetButLock(object_is_libdata(ob), ERROR_LIBDATA_MESSAGE);
1082         
1083         if(ob->mode & (OB_MODE_VERTEX_PAINT|OB_MODE_WEIGHT_PAINT|OB_MODE_TEXTURE_PAINT)) {
1084         }
1085         else {
1086                 //bt= uiDefBut(block, TEX, B_IDNAME, "OB: ",    10,180,140,20, ob->id.name+2, 0.0, 21.0, 0, 0, "");
1087                 //uiButSetFunc(bt, test_idbutton_cb, ob->id.name, NULL);
1088
1089                 if((ob->mode & OB_MODE_PARTICLE_EDIT)==0) {
1090                 //      uiBlockBeginAlign(block);
1091                 //      uiDefIDPoinBut(block, test_obpoin_but, ID_OB, B_OBJECTPANELPARENT, "Par:", 160, 180, 140, 20, &ob->parent, "Parent Object"); 
1092                         if((ob->parent) && (ob->partype == PARBONE)) {
1093                 //              bt= uiDefBut(block, TEX, B_OBJECTPANELPARENT, "ParBone:", 160, 160, 140, 20, ob->parsubstr, 0, 30, 0, 0, "");
1094                 //              uiButSetCompleteFunc(bt, autocomplete_bone, (void *)ob->parent);
1095                         }
1096                         else {
1097                                 strcpy(ob->parsubstr, "");
1098                         }
1099                         uiBlockEndAlign(block);
1100                 }
1101         }
1102
1103         lim= 10000.0f*MAX2(1.0, v3d->grid);
1104
1105         if(ob==obedit) {
1106                 if(ob->type==OB_ARMATURE) v3d_editarmature_buts(block, v3d, ob, lim);
1107                 if(ob->type==OB_MBALL) v3d_editmetaball_buts(block, ob, lim);
1108                 else v3d_editvertex_buts(C, block, v3d, ob, lim);
1109         }
1110         else if(ob->mode & OB_MODE_POSE) {
1111                 v3d_posearmature_buts(block, v3d, ob, lim);
1112         }
1113         else {
1114                 BoundBox *bb = NULL;
1115                 
1116                 uiDefBut(block, LABEL, 0, "Location:",                                  10, 170, 100, 20, 0, 0, 0, 0, 0, "");
1117                 uiBlockBeginAlign(block);
1118                 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");
1119                 uiDefButF(block, NUM, B_OBJECTPANEL, "X:",              30, 150, 120, 19, &(ob->loc[0]), -lim, lim, 100, 3, "");
1120                 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");
1121                 uiDefButF(block, NUM, B_OBJECTPANEL, "Y:",              30, 130, 120, 19, &(ob->loc[1]), -lim, lim, 100, 3, "");
1122                 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");
1123                 uiDefButF(block, NUM, B_OBJECTPANEL, "Z:",              30, 110, 120, 19, &(ob->loc[2]), -lim, lim, 100, 3, "");
1124                 
1125                 tfp->ob_eul[0]= 180.0*ob->rot[0]/M_PI;
1126                 tfp->ob_eul[1]= 180.0*ob->rot[1]/M_PI;
1127                 tfp->ob_eul[2]= 180.0*ob->rot[2]/M_PI;
1128                 
1129                 uiBlockBeginAlign(block);
1130                 if ((ob->parent) && (ob->partype == PARBONE)) {
1131                         uiDefBut(block, LABEL, 0, "Rotation:",                                  160, 170, 100, 20, 0, 0, 0, 0, 0, "");
1132                         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");
1133                         uiDefButF(block, NUM, B_OBJECTPANELROT, "X:",   180, 130, 120, 19, &(tfp->ob_eul[0]), -lim, lim, 1000, 3, "");
1134                         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");
1135                         uiDefButF(block, NUM, B_OBJECTPANELROT, "Y:",   180, 110, 120, 19, &(tfp->ob_eul[1]), -lim, lim, 1000, 3, "");
1136                         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");
1137                         uiDefButF(block, NUM, B_OBJECTPANELROT, "Z:",   180, 90, 120, 19, &(tfp->ob_eul[2]), -lim, lim, 1000, 3, "");
1138
1139                 }
1140                 else {
1141                         uiDefBut(block, LABEL, 0, "Rotation:",                                  160, 170, 100, 20, 0, 0, 0, 0, 0, "");
1142                         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");
1143                         uiDefButF(block, NUM, B_OBJECTPANELROT, "X:",   180, 150, 120, 19, &(tfp->ob_eul[0]), -lim, lim, 1000, 3, "");
1144                         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");
1145                         uiDefButF(block, NUM, B_OBJECTPANELROT, "Y:",   180, 130, 120, 19, &(tfp->ob_eul[1]), -lim, lim, 1000, 3, "");
1146                         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");
1147                         uiDefButF(block, NUM, B_OBJECTPANELROT, "Z:",   180, 110, 120, 19, &(tfp->ob_eul[2]), -lim, lim, 1000, 3, "");
1148                 }
1149
1150                 tfp->ob_scale[0]= ob->size[0];
1151                 tfp->ob_scale[1]= ob->size[1];
1152                 tfp->ob_scale[2]= ob->size[2];
1153
1154                 uiDefBut(block, LABEL, 0, "Scale:",                                     10, 90, 100, 20, 0, 0, 0, 0, 0, "");
1155                 uiBlockBeginAlign(block);
1156                 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");
1157                 uiDefButF(block, NUM, B_OBJECTPANELSCALE, "X:",                                                 30, 70, 120, 19, &(tfp->ob_scale[0]), -lim, lim, 10, 3, "");
1158                 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");
1159                 uiDefButF(block, NUM, B_OBJECTPANELSCALE, "Y:",                                                 30, 50, 120, 19, &(tfp->ob_scale[1]), -lim, lim, 10, 3, "");
1160                 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");
1161                 uiDefButF(block, NUM, B_OBJECTPANELSCALE, "Z:",                                                 30, 30, 120, 19, &(tfp->ob_scale[2]), -lim, lim, 10, 3, "");
1162                 uiBlockEndAlign(block);
1163                 
1164                 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");
1165
1166                 bb= object_get_boundbox(ob);
1167                 if (bb) {
1168                         float scale[3];
1169
1170                         Mat4ToSize(ob->obmat, scale);
1171
1172                         tfp->ob_dims[0] = fabs(scale[0]) * (bb->vec[4][0] - bb->vec[0][0]);
1173                         tfp->ob_dims[1] = fabs(scale[1]) * (bb->vec[2][1] - bb->vec[0][1]);
1174                         tfp->ob_dims[2] = fabs(scale[2]) * (bb->vec[1][2] - bb->vec[0][2]);
1175
1176                         
1177                         if ((ob->parent) && (ob->partype == PARBONE)) {
1178                                 uiDefBut(block, LABEL, 0, "Dimensions:",                        160, 90, 100, 20, 0, 0, 0, 0, 0, "");
1179                                 uiBlockBeginAlign(block);
1180                                 uiDefButF(block, NUM, B_OBJECTPANELDIMS, "X:",          160, 70, 140, 19, &(tfp->ob_dims[0]), 0.0, lim, 10, 3, "Manipulate bounding box size");
1181                                 uiDefButF(block, NUM, B_OBJECTPANELDIMS, "Y:",          160, 50, 140, 19, &(tfp->ob_dims[1]), 0.0, lim, 10, 3, "Manipulate bounding box size");
1182                                 uiDefButF(block, NUM, B_OBJECTPANELDIMS, "Z:",          160, 30, 140, 19, &(tfp->ob_dims[2]), 0.0, lim, 10, 3, "Manipulate bounding box size");
1183
1184                         }
1185                         else {
1186                                 uiDefBut(block, LABEL, 0, "Dimensions:",                        160, 90, 100, 20, 0, 0, 0, 0, 0, "");
1187                                 uiBlockBeginAlign(block);
1188                                 uiDefButF(block, NUM, B_OBJECTPANELDIMS, "X:",          160, 70, 140, 19, &(tfp->ob_dims[0]), 0.0, lim, 10, 3, "Manipulate bounding box size");
1189                                 uiDefButF(block, NUM, B_OBJECTPANELDIMS, "Y:",          160, 50, 140, 19, &(tfp->ob_dims[1]), 0.0, lim, 10, 3, "Manipulate bounding box size");
1190                                 uiDefButF(block, NUM, B_OBJECTPANELDIMS, "Z:",          160, 30, 140, 19, &(tfp->ob_dims[2]), 0.0, lim, 10, 3, "Manipulate bounding box size");
1191                         }
1192
1193                         uiBlockEndAlign(block);
1194                 }
1195         }
1196 }
1197
1198 #if 0
1199 static void view3d_panel_preview(bContext *C, ARegion *ar, short cntrl) // VIEW3D_HANDLER_PREVIEW
1200 {
1201         uiBlock *block;
1202         View3D *v3d= sa->spacedata.first;
1203         int ofsx, ofsy;
1204         
1205         block= uiBeginBlock(C, ar, "view3d_panel_preview", UI_EMBOSS);
1206         uiPanelControl(UI_PNL_SOLID | UI_PNL_CLOSE | UI_PNL_SCALE | cntrl);
1207         uiSetPanelHandler(VIEW3D_HANDLER_PREVIEW);  // for close and esc
1208         
1209         ofsx= -150+(sa->winx/2)/v3d->blockscale;
1210         ofsy= -100+(sa->winy/2)/v3d->blockscale;
1211         if(uiNewPanel(C, ar, block, "Preview", "View3d", ofsx, ofsy, 300, 200)==0) return;
1212
1213         uiBlockSetDrawExtraFunc(block, BIF_view3d_previewdraw);
1214         
1215         if(scene->recalc & SCE_PRV_CHANGED) {
1216                 scene->recalc &= ~SCE_PRV_CHANGED;
1217                 //printf("found recalc\n");
1218                 BIF_view3d_previewrender_free(sa->spacedata.first);
1219                 BIF_preview_changed(0);
1220         }
1221 }
1222 #endif
1223
1224 static void delete_sketch_armature(bContext *C, void *arg1, void *arg2)
1225 {
1226         BIF_deleteSketch(C);
1227 }
1228
1229 static void convert_sketch_armature(bContext *C, void *arg1, void *arg2)
1230 {
1231         BIF_convertSketch(C);
1232 }
1233
1234 static void assign_template_sketch_armature(bContext *C, void *arg1, void *arg2)
1235 {
1236         int index = *(int*)arg1;
1237         BIF_setTemplate(C, index);
1238 }
1239
1240 static int view3d_panel_bonesketch_spaces_poll(const bContext *C, PanelType *pt)
1241 {
1242         Object *obedit = CTX_data_edit_object(C);
1243
1244         /* replace with check call to sketching lib */
1245         return (obedit && obedit->type == OB_ARMATURE);
1246 }
1247 static void view3d_panel_bonesketch_spaces(const bContext *C, Panel *pa)
1248 {
1249         Scene *scene = CTX_data_scene(C);
1250         static int template_index;
1251         static char joint_label[128];
1252         uiBlock *block;
1253         uiBut *but;
1254         char *bone_name;
1255         int yco = 130;
1256         int nb_joints;
1257         static char subdiv_tooltip[4][64] = {
1258                 "Subdivide arcs based on a fixed number of bones",
1259                 "Subdivide arcs in bones of equal length",
1260                 "Subdivide arcs based on correlation",
1261                 "Retarget template to stroke"
1262                 };
1263
1264         
1265         block= uiLayoutFreeBlock(pa->layout);
1266         uiBlockSetHandleFunc(block, do_view3d_region_buttons, NULL);
1267
1268         uiBlockBeginAlign(block);
1269         
1270         /* use real flag instead of 1 */
1271         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)");
1272         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");
1273         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");
1274         yco -= 20;
1275         
1276         but = uiDefBut(block, BUT, B_REDR, "Convert", 10,yco,100,20, 0, 0, 0, 0, 0, "Convert sketch to armature");
1277         uiButSetFunc(but, convert_sketch_armature, NULL, NULL);
1278
1279         but = uiDefBut(block, BUT, B_REDR, "Delete", 110,yco,100,20, 0, 0, 0, 0, 0, "Delete sketch");
1280         uiButSetFunc(but, delete_sketch_armature, NULL, NULL);
1281         yco -= 20;
1282         
1283         uiBlockEndAlign(block);
1284
1285         uiBlockBeginAlign(block);
1286         
1287         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]);
1288
1289         switch(scene->toolsettings->bone_sketching_convert)
1290         {
1291         case SK_CONVERT_CUT_LENGTH:
1292                 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");
1293                 yco -= 20;
1294                 break;
1295         case SK_CONVERT_CUT_ADAPTATIVE:
1296                 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");
1297                 yco -= 20;
1298                 break;
1299         default:
1300         case SK_CONVERT_CUT_FIXED:
1301                 uiDefButC(block, NUM, B_REDR,                                   "Num:",         70, yco, 140, 19, &scene->toolsettings->skgen_subdivision_number,1, 100, 1, 5,  "Number of subdivided bones");
1302                 yco -= 20;
1303                 break;
1304         case SK_CONVERT_RETARGET:
1305                 uiDefButC(block, ROW, B_NOP, "No",                      70,  yco, 40,19, &scene->toolsettings->skgen_retarget_roll, 0, 0, 0, 0,                                                                 "No special roll treatment");
1306                 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");
1307                 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");
1308                 yco -= 30;
1309
1310                 uiBlockEndAlign(block);
1311
1312                 uiBlockBeginAlign(block);
1313                 /* button here to select what to do (copy or not), template, ...*/
1314
1315                 BIF_makeListTemplates(C);
1316                 template_index = BIF_currentTemplate(C);
1317                 
1318                 but = uiDefButI(block, MENU, B_REDR, BIF_listTemplates(C), 10,yco,200,19, &template_index, 0, 0, 0, 0, "Template");
1319                 uiButSetFunc(but, assign_template_sketch_armature, &template_index, NULL);
1320                 
1321                 yco -= 20;
1322                 
1323                 uiDefButF(block, NUM, B_NOP,                                                    "A:",                   10, yco, 66,19, &scene->toolsettings->skgen_retarget_angle_weight, 0, 10, 1, 0,         "Angle Weight");
1324                 uiDefButF(block, NUM, B_NOP,                                                    "L:",                   76, yco, 67,19, &scene->toolsettings->skgen_retarget_length_weight, 0, 10, 1, 0,                "Length Weight");
1325                 uiDefButF(block, NUM, B_NOP,                                                    "D:",           143,yco, 67,19, &scene->toolsettings->skgen_retarget_distance_weight, 0, 10, 1, 0,              "Distance Weight");
1326                 yco -= 20;
1327                 
1328                 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");
1329                 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");
1330                 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");        
1331                 yco -= 20;
1332
1333                 /* auto renaming magic */
1334                 uiBlockEndAlign(block);
1335                 
1336                 nb_joints = BIF_nbJointsTemplate(C);
1337
1338                 if (nb_joints == -1)
1339                 {
1340                         //XXX
1341                         //nb_joints = G.totvertsel;
1342                 }
1343                 
1344                 bone_name = BIF_nameBoneTemplate(C);
1345                 
1346                 BLI_snprintf(joint_label, 32, "%i joints: %s", nb_joints, bone_name);
1347                 
1348                 uiDefBut(block, LABEL, 1, joint_label,                                  10, yco, 200, 20, NULL, 0.0, 0.0, 0, 0, "");
1349                 yco -= 20;
1350                 break;
1351         }
1352
1353         uiBlockEndAlign(block);
1354 }
1355
1356 #if 0 // XXX not used
1357
1358 /* op->invoke */
1359 static void redo_cb(bContext *C, void *arg_op, void *arg2)
1360 {
1361         wmOperator *lastop= arg_op;
1362         
1363         if(lastop) {
1364                 int retval;
1365                 
1366                 printf("operator redo %s\n", lastop->type->name);
1367                 ED_undo_pop(C);
1368                 retval= WM_operator_repeat(C, lastop);
1369                 if((retval & OPERATOR_FINISHED)==0) {
1370                         printf("operator redo failed %s\n", lastop->type->name);
1371                         ED_undo_redo(C);
1372                 }
1373         }
1374 }
1375
1376 static void view3d_panel_operator_redo(const bContext *C, Panel *pa)
1377 {
1378         wmWindowManager *wm= CTX_wm_manager(C);
1379         wmOperator *op;
1380         PointerRNA ptr;
1381         uiBlock *block;
1382         
1383         block= uiLayoutGetBlock(pa->layout);
1384
1385         /* only for operators that are registered and did an undo push */
1386         for(op= wm->operators.last; op; op= op->prev)
1387                 if((op->type->flag & OPTYPE_REGISTER) && (op->type->flag & OPTYPE_UNDO))
1388                         break;
1389         
1390         if(op==NULL)
1391                 return;
1392         
1393         uiBlockSetFunc(block, redo_cb, op, NULL);
1394         
1395         if(!op->properties) {
1396                 IDPropertyTemplate val = {0};
1397                 op->properties= IDP_New(IDP_GROUP, val, "wmOperatorProperties");
1398         }
1399         
1400         RNA_pointer_create(&wm->id, op->type->srna, op->properties, &ptr);
1401         uiDefAutoButsRNA(C, pa->layout, &ptr, 2);
1402 }
1403 #endif // XXX not used
1404
1405 void view3d_buttons_register(ARegionType *art)
1406 {
1407         PanelType *pt;
1408
1409         pt= MEM_callocN(sizeof(PanelType), "spacetype view3d panel object");
1410         strcpy(pt->idname, "VIEW3D_PT_object");
1411         strcpy(pt->label, "Transform");
1412         pt->draw= view3d_panel_object;
1413         BLI_addtail(&art->paneltypes, pt);
1414         
1415         pt= MEM_callocN(sizeof(PanelType), "spacetype view3d panel gpencil");
1416         strcpy(pt->idname, "VIEW3D_PT_gpencil");
1417         strcpy(pt->label, "Grease Pencil");
1418         pt->draw= gpencil_panel_standard;
1419         BLI_addtail(&art->paneltypes, pt);
1420 /*
1421         pt= MEM_callocN(sizeof(PanelType), "spacetype view3d panel properties");
1422         strcpy(pt->idname, "VIEW3D_PT_properties");
1423         strcpy(pt->label, "View Properties");
1424         pt->draw= view3d_panel_properties;
1425         BLI_addtail(&art->paneltypes, pt);
1426
1427         pt= MEM_callocN(sizeof(PanelType), "spacetype view3d panel transform spaces");
1428         strcpy(pt->idname, "VIEW3D_PT_transform spaces");
1429         strcpy(pt->label, "Transform Orientations");
1430         pt->draw= view3d_panel_transform_spaces;
1431         BLI_addtail(&art->paneltypes, pt);
1432
1433         pt= MEM_callocN(sizeof(PanelType), "spacetype view3d panel gpencil");
1434         strcpy(pt->idname, "VIEW3D_PT_gpencil");
1435         strcpy(pt->label, "Greas Pencil");
1436         pt->draw= view3d_panel_gpencil;
1437         BLI_addtail(&art->paneltypes, pt);*/
1438
1439         pt= MEM_callocN(sizeof(PanelType), "spacetype view3d panel bonesketch spaces");
1440         strcpy(pt->idname, "VIEW3D_PT_bonesketch_spaces");
1441         strcpy(pt->label, "Bone Sketching");
1442         pt->draw= view3d_panel_bonesketch_spaces;
1443         pt->poll= view3d_panel_bonesketch_spaces_poll;
1444         BLI_addtail(&art->paneltypes, pt);
1445
1446         /*
1447         pt= MEM_callocN(sizeof(PanelType), "spacetype view3d panel redo");
1448         strcpy(pt->idname, "VIEW3D_PT_redo");
1449         strcpy(pt->label, "Last Operator");
1450         pt->draw= view3d_panel_operator_redo;
1451         BLI_addtail(&art->paneltypes, pt);
1452 */
1453         // XXX view3d_panel_preview(C, ar, 0);
1454 }
1455
1456 static int view3d_properties(bContext *C, wmOperator *op)
1457 {
1458         ScrArea *sa= CTX_wm_area(C);
1459         ARegion *ar= view3d_has_buttons_region(sa);
1460         
1461         if(ar) {
1462                 ar->flag ^= RGN_FLAG_HIDDEN;
1463                 ar->v2d.flag &= ~V2D_IS_INITIALISED; /* XXX should become hide/unhide api? */
1464                 
1465                 ED_area_initialize(CTX_wm_manager(C), CTX_wm_window(C), sa);
1466                 ED_area_tag_redraw(sa);
1467         }
1468         return OPERATOR_FINISHED;
1469 }
1470
1471 void VIEW3D_OT_properties(wmOperatorType *ot)
1472 {
1473         ot->name= "Properties";
1474         ot->description= "Display the properties panel.";
1475         ot->idname= "VIEW3D_OT_properties";
1476         
1477         ot->exec= view3d_properties;
1478         ot->poll= ED_operator_view3d_active;
1479         
1480         /* flags */
1481         ot->flag= 0;
1482 }