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