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