Blender V2.61 - r43446

view3d_buttons.c

Go to the documentation of this file.
00001 /*
00002  * ***** BEGIN GPL LICENSE BLOCK *****
00003  *
00004  * This program is free software; you can redistribute it and/or
00005  * modify it under the terms of the GNU General Public License
00006  * as published by the Free Software Foundation; either version 2
00007  * of the License, or (at your option) any later version. 
00008  *
00009  * This program is distributed in the hope that it will be useful,
00010  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00011  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00012  * GNU General Public License for more details.
00013  *
00014  * You should have received a copy of the GNU General Public License
00015  * along with this program; if not, write to the Free Software Foundation,
00016  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
00017  *
00018  * The Original Code is Copyright (C) 2009 Blender Foundation.
00019  * All rights reserved.
00020  *
00021  * 
00022  * Contributor(s): Blender Foundation
00023  *
00024  * ***** END GPL LICENSE BLOCK *****
00025  */
00026 
00032 #include <string.h>
00033 #include <stdio.h>
00034 #include <math.h>
00035 #include <float.h>
00036 
00037 #include "DNA_armature_types.h"
00038 #include "DNA_curve_types.h"
00039 #include "DNA_lattice_types.h"
00040 #include "DNA_meta_types.h"
00041 #include "DNA_meshdata_types.h"
00042 #include "DNA_object_types.h"
00043 #include "DNA_scene_types.h"
00044 
00045 #include "MEM_guardedalloc.h"
00046 
00047 #include "BLI_math.h"
00048 #include "BLI_blenlib.h"
00049 #include "BLI_editVert.h"
00050 #include "BLI_rand.h"
00051 #include "BLI_utildefines.h"
00052 
00053 #include "BKE_action.h"
00054 #include "BKE_context.h"
00055 #include "BKE_curve.h"
00056 #include "BKE_customdata.h"
00057 #include "BKE_depsgraph.h"
00058 #include "BKE_main.h"
00059 #include "BKE_mesh.h"
00060 #include "BKE_screen.h"
00061 #include "BKE_deform.h"
00062 #include "BKE_object.h"
00063 
00064 #include "WM_api.h"
00065 #include "WM_types.h"
00066 
00067 #include "RNA_access.h"
00068 
00069 #include "ED_armature.h"
00070 #include "ED_gpencil.h"
00071 #include "ED_mesh.h"
00072 #include "ED_screen.h"
00073 #include "ED_transform.h"
00074 #include "ED_curve.h"
00075 
00076 #include "UI_interface.h"
00077 #include "UI_resources.h"
00078 
00079 #include "view3d_intern.h"  // own include
00080 
00081 
00082 /* ******************* view3d space & buttons ************** */
00083 #define B_NOP       1
00084 #define B_REDR      2
00085 #define B_OBJECTPANELROT    1007
00086 #define B_OBJECTPANELMEDIAN 1008
00087 #define B_ARMATUREPANEL1    1009
00088 #define B_ARMATUREPANEL2    1010
00089 #define B_OBJECTPANELPARENT 1011
00090 #define B_OBJECTPANEL       1012
00091 #define B_ARMATUREPANEL3    1013
00092 #define B_OBJECTPANELSCALE  1014
00093 #define B_OBJECTPANELDIMS   1015
00094 #define B_TRANSFORMSPACEADD 1016
00095 #define B_TRANSFORMSPACECLEAR   1017
00096 #define B_SETPT_AUTO    2125
00097 #define B_SETPT_VECTOR  2126
00098 #define B_SETPT_ALIGN   2127
00099 #define B_SETPT_FREE    2128
00100 #define B_RECALCMBALL   2501
00101 
00102 #define B_WEIGHT0_0     2840
00103 #define B_WEIGHT1_4     2841
00104 #define B_WEIGHT1_2     2842
00105 #define B_WEIGHT3_4     2843
00106 #define B_WEIGHT1_0     2844
00107 
00108 #define B_OPA1_8        2845
00109 #define B_OPA1_4        2846
00110 #define B_OPA1_2        2847
00111 #define B_OPA3_4        2848
00112 #define B_OPA1_0        2849
00113 
00114 #define B_CLR_WPAINT    2850
00115 
00116 #define B_RV3D_LOCKED   2900
00117 #define B_RV3D_BOXVIEW  2901
00118 #define B_RV3D_BOXCLIP  2902
00119 
00120 #define B_IDNAME        3000
00121 
00122 /* temporary struct for storing transform properties */
00123 typedef struct {
00124     float ob_eul[4];    // used for quat too....
00125     float ob_scale[3]; // need temp space due to linked values
00126     float ob_dims[3];
00127     short link_scale;
00128     float ve_median[7];
00129     int curdef;
00130     float *defweightp;
00131 } TransformProperties;
00132 
00133 
00134 /* is used for both read and write... */
00135 static void v3d_editvertex_buts(uiLayout *layout, View3D *v3d, Object *ob, float lim)
00136 {
00137     uiBlock *block= (layout)? uiLayoutAbsoluteBlock(layout): NULL;
00138     MDeformVert *dvert=NULL;
00139     TransformProperties *tfp;
00140     float median[7], ve_median[7];
00141     int tot, totw, totweight, totedge, totradius;
00142     char defstr[320];
00143     PointerRNA radius_ptr;
00144 
00145     median[0]= median[1]= median[2]= median[3]= median[4]= median[5]= median[6]= 0.0;
00146     tot= totw= totweight= totedge= totradius= 0;
00147     defstr[0]= 0;
00148 
00149     /* make sure we got storage */
00150     if(v3d->properties_storage==NULL)
00151         v3d->properties_storage= MEM_callocN(sizeof(TransformProperties), "TransformProperties");
00152     tfp= v3d->properties_storage;
00153     
00154     if(ob->type==OB_MESH) {
00155         Mesh *me= ob->data;
00156         EditMesh *em = BKE_mesh_get_editmesh(me);
00157         EditVert *eve, *evedef=NULL;
00158         EditEdge *eed;
00159         
00160         eve= em->verts.first;
00161         while(eve) {
00162             if(eve->f & SELECT) {
00163                 evedef= eve;
00164                 tot++;
00165                 add_v3_v3(median, eve->co);
00166             }
00167             eve= eve->next;
00168         }
00169         eed= em->edges.first;
00170         while(eed) {
00171             if((eed->f & SELECT)) {
00172                 totedge++;
00173                 median[3]+= eed->crease;
00174                 median[6]+= eed->bweight;
00175             }
00176             eed= eed->next;
00177         }
00178 
00179         /* check for defgroups */
00180         if(evedef)
00181             dvert= CustomData_em_get(&em->vdata, evedef->data, CD_MDEFORMVERT);
00182         if(tot==1 && dvert && dvert->totweight) {
00183             bDeformGroup *dg;
00184             int i, max=1, init=1;
00185             char str[320];
00186             
00187             for (i=0; i<dvert->totweight; i++){
00188                 dg = BLI_findlink (&ob->defbase, dvert->dw[i].def_nr);
00189                 if(dg) {
00190                     max+= BLI_snprintf(str, sizeof(str), "%s %%x%d|", dg->name, dvert->dw[i].def_nr); 
00191                     if (max < sizeof(str)) strcat(defstr, str);
00192                 }
00193 
00194                 if(tfp->curdef==dvert->dw[i].def_nr) {
00195                     init= 0;
00196                     tfp->defweightp= &dvert->dw[i].weight;
00197                 }
00198             }
00199             
00200             if(init) {  // needs new initialized 
00201                 tfp->curdef= dvert->dw[0].def_nr;
00202                 tfp->defweightp= &dvert->dw[0].weight;
00203             }
00204         }
00205 
00206         BKE_mesh_end_editmesh(me, em);
00207     }
00208     else if(ob->type==OB_CURVE || ob->type==OB_SURF) {
00209         Curve *cu= ob->data;
00210         Nurb *nu;
00211         BPoint *bp;
00212         BezTriple *bezt;
00213         int a;
00214         ListBase *nurbs= curve_editnurbs(cu);
00215         StructRNA *seltype= NULL;
00216         void *selp= NULL;
00217 
00218         nu= nurbs->first;
00219         while(nu) {
00220             if(nu->type == CU_BEZIER) {
00221                 bezt= nu->bezt;
00222                 a= nu->pntsu;
00223                 while(a--) {
00224                     if(bezt->f2 & SELECT) {
00225                         add_v3_v3(median, bezt->vec[1]);
00226                         tot++;
00227                         median[4]+= bezt->weight;
00228                         totweight++;
00229                         median[5]+= bezt->radius;
00230                         totradius++;
00231                         selp= bezt;
00232                         seltype= &RNA_BezierSplinePoint;
00233                     }
00234                     else {
00235                         if(bezt->f1 & SELECT) {
00236                             add_v3_v3(median, bezt->vec[0]);
00237                             tot++;
00238                         }
00239                         if(bezt->f3 & SELECT) {
00240                             add_v3_v3(median, bezt->vec[2]);
00241                             tot++;
00242                         }
00243                     }
00244                     bezt++;
00245                 }
00246             }
00247             else {
00248                 bp= nu->bp;
00249                 a= nu->pntsu*nu->pntsv;
00250                 while(a--) {
00251                     if(bp->f1 & SELECT) {
00252                         add_v3_v3(median, bp->vec);
00253                         median[3]+= bp->vec[3];
00254                         totw++;
00255                         tot++;
00256                         median[4]+= bp->weight;
00257                         totweight++;
00258                         median[5]+= bp->radius;
00259                         totradius++;
00260                         selp= bp;
00261                         seltype= &RNA_SplinePoint;
00262                     }
00263                     bp++;
00264                 }
00265             }
00266             nu= nu->next;
00267         }
00268 
00269         if(totradius==1)
00270             RNA_pointer_create(&cu->id, seltype, selp, &radius_ptr);
00271     }
00272     else if(ob->type==OB_LATTICE) {
00273         Lattice *lt= ob->data;
00274         BPoint *bp;
00275         int a;
00276         
00277         a= lt->editlatt->latt->pntsu*lt->editlatt->latt->pntsv*lt->editlatt->latt->pntsw;
00278         bp= lt->editlatt->latt->def;
00279         while(a--) {
00280             if(bp->f1 & SELECT) {
00281                 add_v3_v3(median, bp->vec);
00282                 tot++;
00283                 median[4]+= bp->weight;
00284                 totweight++;
00285             }
00286             bp++;
00287         }
00288     }
00289     
00290     if(tot==0) {
00291         uiDefBut(block, LABEL, 0, "Nothing selected",0, 130, 200, 20, NULL, 0, 0, 0, 0, "");
00292         return;
00293     }
00294     median[0] /= (float)tot;
00295     median[1] /= (float)tot;
00296     median[2] /= (float)tot;
00297     if (totedge) {
00298         median[3] /= (float)totedge;
00299         median[6] /= (float)totedge;
00300     }
00301     else if(totw) median[3] /= (float)totw;
00302     if(totweight) median[4] /= (float)totweight;
00303     if(totradius) median[5] /= (float)totradius;
00304     
00305     if(v3d->flag & V3D_GLOBAL_STATS)
00306         mul_m4_v3(ob->obmat, median);
00307     
00308     if(block) { // buttons
00309         uiBut *but;
00310 
00311         memcpy(tfp->ve_median, median, sizeof(tfp->ve_median));
00312         
00313         uiBlockBeginAlign(block);
00314         if(tot==1) {
00315             uiDefBut(block, LABEL, 0, "Vertex:",                    0, 150, 200, 20, NULL, 0, 0, 0, 0, "");
00316             uiBlockBeginAlign(block);
00317 
00318             but= uiDefButF(block, NUM, B_OBJECTPANELMEDIAN, "X:",       0, 130, 200, 20, &(tfp->ve_median[0]), -lim, lim, 10, 3, "");
00319             uiButSetUnitType(but, PROP_UNIT_LENGTH);
00320             but= uiDefButF(block, NUM, B_OBJECTPANELMEDIAN, "Y:",       0, 110, 200, 20, &(tfp->ve_median[1]), -lim, lim, 10, 3, "");
00321             uiButSetUnitType(but, PROP_UNIT_LENGTH);
00322             but= uiDefButF(block, NUM, B_OBJECTPANELMEDIAN, "Z:",       0, 90, 200, 20, &(tfp->ve_median[2]), -lim, lim, 10, 3, "");
00323             uiButSetUnitType(but, PROP_UNIT_LENGTH);
00324 
00325             if(totw==1) {
00326                 uiDefButF(block, NUM, B_OBJECTPANELMEDIAN, "W:",    0, 70, 200, 20, &(tfp->ve_median[3]), 0.01, 100.0, 1, 3, "");
00327                 uiBlockBeginAlign(block);
00328                 uiDefButBitS(block, TOG, V3D_GLOBAL_STATS, B_REDR, "Global",        0, 45, 100, 20, &v3d->flag, 0, 0, 0, 0, "Displays global values");
00329                 uiDefButBitS(block, TOGN, V3D_GLOBAL_STATS, B_REDR, "Local",        100, 45, 100, 20, &v3d->flag, 0, 0, 0, 0, "Displays local values");
00330                 uiBlockEndAlign(block);
00331                 if(totweight)
00332                     uiDefButF(block, NUM, B_OBJECTPANELMEDIAN, "Weight:",   0, 20, 200, 20, &(tfp->ve_median[4]), 0.0, 1.0, 1, 3, "");
00333                 if(totradius) {
00334                     if(totradius==1) uiDefButR(block, NUM, 0, "Radius", 0, 20, 200, 20, &radius_ptr, "radius", 0, 0.0, 100.0, 10, 3, NULL);
00335                     else uiDefButF(block, NUM, B_OBJECTPANELMEDIAN, "Radius:",  0, 20, 200, 20, &(tfp->ve_median[5]), 0.0, 100.0, 1, 3, "Radius of curve CPs");
00336                 }
00337             }
00338             else {
00339                 uiBlockBeginAlign(block);
00340                 uiDefButBitS(block, TOG, V3D_GLOBAL_STATS, B_REDR, "Global",        0, 65, 100, 20, &v3d->flag, 0, 0, 0, 0, "Displays global values");
00341                 uiDefButBitS(block, TOGN, V3D_GLOBAL_STATS, B_REDR, "Local",        100, 65, 100, 20, &v3d->flag, 0, 0, 0, 0, "Displays local values");
00342                 uiBlockEndAlign(block);
00343                 if(totweight)
00344                     uiDefButF(block, NUM, B_OBJECTPANELMEDIAN, "Weight:",   0, 40, 200, 20, &(tfp->ve_median[4]), 0.0, 1.0, 10, 3, "");
00345                 if(totradius) {
00346                     if(totradius==1) uiDefButR(block, NUM, 0, "Radius", 0, 40, 200, 20, &radius_ptr, "radius", 0, 0.0, 100.0, 10, 3, NULL);
00347                     else uiDefButF(block, NUM, B_OBJECTPANELMEDIAN, "Radius:",  0, 40, 200, 20, &(tfp->ve_median[5]), 0.0, 100.0, 10, 3, "Radius of curve CPs");
00348                 }
00349             }
00350         }
00351         else {
00352             uiDefBut(block, LABEL, 0, "Median:",                    0, 150, 200, 20, NULL, 0, 0, 0, 0, "");
00353             uiBlockBeginAlign(block);
00354             but= uiDefButF(block, NUM, B_OBJECTPANELMEDIAN, "X:",       0, 130, 200, 20, &(tfp->ve_median[0]), -lim, lim, 10, 3, "");
00355             uiButSetUnitType(but, PROP_UNIT_LENGTH);
00356             but= uiDefButF(block, NUM, B_OBJECTPANELMEDIAN, "Y:",       0, 110, 200, 20, &(tfp->ve_median[1]), -lim, lim, 10, 3, "");
00357             uiButSetUnitType(but, PROP_UNIT_LENGTH);
00358             but= uiDefButF(block, NUM, B_OBJECTPANELMEDIAN, "Z:",       0, 90, 200, 20, &(tfp->ve_median[2]), -lim, lim, 10, 3, "");
00359             uiButSetUnitType(but, PROP_UNIT_LENGTH);
00360             if(totw==tot) {
00361                 uiDefButF(block, NUM, B_OBJECTPANELMEDIAN, "W:",    0, 70, 200, 20, &(tfp->ve_median[3]), 0.01, 100.0, 1, 3, "");
00362                 uiBlockEndAlign(block);
00363                 uiBlockBeginAlign(block);
00364                 uiDefButBitS(block, TOG, V3D_GLOBAL_STATS, B_REDR, "Global",        0, 45, 100, 20, &v3d->flag, 0, 0, 0, 0, "Displays global values");
00365                 uiDefButBitS(block, TOGN, V3D_GLOBAL_STATS, B_REDR, "Local",        100, 45, 100, 20, &v3d->flag, 0, 0, 0, 0, "Displays local values");
00366                 uiBlockEndAlign(block);
00367                 if(totweight)
00368                     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");
00369                 if(totradius)
00370                     uiDefButF(block, NUM, B_OBJECTPANELMEDIAN, "Radius:",   0, 20, 200, 20, &(tfp->ve_median[5]), 0.0, 100.0, 10, 3, "Radius of curve CPs");
00371                 uiBlockEndAlign(block);
00372             }
00373             else {
00374                 uiBlockBeginAlign(block);
00375                 uiDefButBitS(block, TOG, V3D_GLOBAL_STATS, B_REDR, "Global",        0, 65, 100, 20, &v3d->flag, 0, 0, 0, 0, "Displays global values");
00376                 uiDefButBitS(block, TOGN, V3D_GLOBAL_STATS, B_REDR, "Local",        100, 65, 100, 20, &v3d->flag, 0, 0, 0, 0, "Displays local values");
00377                 uiBlockEndAlign(block);
00378                 if(totweight)
00379                     uiDefButF(block, NUM, B_OBJECTPANELMEDIAN, "Weight:",   0, 40, 200, 20, &(tfp->ve_median[4]), 0.0, 1.0, 1, 3, "Weight is used for SoftBody Goal");
00380                 if(totradius)
00381                     uiDefButF(block, NUM, B_OBJECTPANELMEDIAN, "Radius:",   0, 20, 200, 20, &(tfp->ve_median[5]), 0.0, 100.0, 1, 3, "Radius of curve CPs");
00382                 uiBlockEndAlign(block);
00383             }
00384         }
00385 
00386         if(totedge==1){
00387             uiDefButF(block, NUM, B_OBJECTPANELMEDIAN, "Crease:",   0, 40, 200, 20, &(tfp->ve_median[3]), 0.0, 1.0, 1, 3, "");
00388             uiDefButF(block, NUM, B_OBJECTPANELMEDIAN, "Bevel Weight:", 0, 20, 200, 20, &(tfp->ve_median[6]), 0.0, 1.0, 1, 3, "");
00389         }
00390         else if(totedge>1){
00391             uiDefButF(block, NUM, B_OBJECTPANELMEDIAN, "Mean Crease:",  0, 40, 200, 20, &(tfp->ve_median[3]), 0.0, 1.0, 1, 3, "");
00392             uiDefButF(block, NUM, B_OBJECTPANELMEDIAN, "Mean Bevel Weight:",    0, 20, 200, 20, &(tfp->ve_median[6]), 0.0, 1.0, 1, 3, "");
00393         }
00394 
00395     }
00396     else {  // apply
00397         memcpy(ve_median, tfp->ve_median, sizeof(tfp->ve_median));
00398         
00399         if(v3d->flag & V3D_GLOBAL_STATS) {
00400             invert_m4_m4(ob->imat, ob->obmat);
00401             mul_m4_v3(ob->imat, median);
00402             mul_m4_v3(ob->imat, ve_median);
00403         }
00404         sub_v3_v3v3(median, ve_median, median);
00405         median[3]= ve_median[3]-median[3];
00406         median[4]= ve_median[4]-median[4];
00407         median[5]= ve_median[5]-median[5];
00408         median[6]= ve_median[6]-median[6];
00409         
00410         if(ob->type==OB_MESH) {
00411             Mesh *me= ob->data;
00412             EditMesh *em = BKE_mesh_get_editmesh(me);
00413 
00414             /* allow for some rounding error becasue of matrix transform */
00415             if(len_v3(median) > 0.000001f) {
00416                 EditVert *eve;
00417 
00418                 for(eve= em->verts.first; eve; eve= eve->next) {
00419                     if(eve->f & SELECT) {
00420                         add_v3_v3(eve->co, median);
00421                     }
00422                 }
00423 
00424                 recalc_editnormals(em);
00425             }
00426 
00427             if(median[3] != 0.0f) {
00428                 EditEdge *eed;
00429                 const float fixed_crease= (ve_median[3] <= 0.0f ? 0.0f : (ve_median[3] >= 1.0f ? 1.0f : FLT_MAX));
00430 
00431                 if(fixed_crease != FLT_MAX) {
00432                     /* simple case */
00433 
00434                     for(eed= em->edges.first; eed; eed= eed->next) {
00435                         if(eed->f & SELECT) {
00436                             eed->crease= fixed_crease;
00437                         }
00438                     }
00439                 }
00440                 else {
00441                     /* scale crease to target median */
00442                     float median_new= ve_median[3];
00443                     float median_orig= ve_median[3] - median[3]; /* previous median value */
00444 
00445                     /* incase of floating point error */
00446                     CLAMP(median_orig, 0.0f, 1.0f);
00447                     CLAMP(median_new, 0.0f, 1.0f);
00448 
00449                     if(median_new < median_orig) {
00450                         /* scale down */
00451                         const float sca= median_new / median_orig;
00452                         
00453                         for(eed= em->edges.first; eed; eed= eed->next) {
00454                             if(eed->f & SELECT) {
00455                                 eed->crease *= sca;
00456                                 CLAMP(eed->crease, 0.0f, 1.0f);
00457                             }
00458                         }
00459                     }
00460                     else {
00461                         /* scale up */
00462                         const float sca= (1.0f - median_new) / (1.0f - median_orig);
00463 
00464                         for(eed= em->edges.first; eed; eed= eed->next) {
00465                             if(eed->f & SELECT) {
00466                                 eed->crease = 1.0f - ((1.0f - eed->crease) * sca);
00467                                 CLAMP(eed->crease, 0.0f, 1.0f);
00468                             }
00469                         }
00470                     }
00471                 }
00472             }
00473 
00474             if (median[6] != 0.0f) {
00475                 EditEdge *eed;
00476                 const float fixed_bweight= (ve_median[6] <= 0.0f ? 0.0f : (ve_median[6] >= 1.0f ? 1.0f : FLT_MAX));
00477 
00478                 if(fixed_bweight != FLT_MAX) {
00479                     /* simple case */
00480 
00481                     for(eed= em->edges.first; eed; eed= eed->next) {
00482                         if(eed->f & SELECT) {
00483                             eed->bweight= fixed_bweight;
00484                         }
00485                     }
00486                 }
00487                 else {
00488                     /* scale crease to target median */
00489                     float median_new= ve_median[6];
00490                     float median_orig= ve_median[6] - median[6]; /* previous median value */
00491 
00492                     /* incase of floating point error */
00493                     CLAMP(median_orig, 0.0f, 1.0f);
00494                     CLAMP(median_new, 0.0f, 1.0f);
00495 
00496                     if(median_new < median_orig) {
00497                         /* scale down */
00498                         const float sca= median_new / median_orig;
00499 
00500                         for(eed= em->edges.first; eed; eed= eed->next) {
00501                             if(eed->f & SELECT) {
00502                                 eed->bweight *= sca;
00503                                 CLAMP(eed->bweight, 0.0f, 1.0f);
00504                             }
00505                         }
00506                     }
00507                     else {
00508                         /* scale up */
00509                         const float sca= (1.0f - median_new) / (1.0f - median_orig);
00510 
00511                         for(eed= em->edges.first; eed; eed= eed->next) {
00512                             if(eed->f & SELECT) {
00513                                 eed->bweight = 1.0f - ((1.0f - eed->bweight) * sca);
00514                                 CLAMP(eed->bweight, 0.0f, 1.0f);
00515                             }
00516                         }
00517                     }
00518                 }
00519             }
00520             BKE_mesh_end_editmesh(me, em);
00521         }
00522         else if(ob->type==OB_CURVE || ob->type==OB_SURF) {
00523             Curve *cu= ob->data;
00524             Nurb *nu;
00525             BPoint *bp;
00526             BezTriple *bezt;
00527             int a;
00528             ListBase *nurbs= curve_editnurbs(cu);
00529 
00530             nu= nurbs->first;
00531             while(nu) {
00532                 if(nu->type == CU_BEZIER) {
00533                     bezt= nu->bezt;
00534                     a= nu->pntsu;
00535                     while(a--) {
00536                         if(bezt->f2 & SELECT) {
00537                             add_v3_v3(bezt->vec[0], median);
00538                             add_v3_v3(bezt->vec[1], median);
00539                             add_v3_v3(bezt->vec[2], median);
00540                             bezt->weight+= median[4];
00541                             bezt->radius+= median[5];
00542                         }
00543                         else {
00544                             if(bezt->f1 & SELECT) {
00545                                 add_v3_v3(bezt->vec[0], median);
00546                             }
00547                             if(bezt->f3 & SELECT) {
00548                                 add_v3_v3(bezt->vec[2], median);
00549                             }
00550                         }
00551                         bezt++;
00552                     }
00553                 }
00554                 else {
00555                     bp= nu->bp;
00556                     a= nu->pntsu*nu->pntsv;
00557                     while(a--) {
00558                         if(bp->f1 & SELECT) {
00559                             add_v3_v3(bp->vec, median);
00560                             bp->vec[3]+= median[3];
00561                             bp->weight+= median[4];
00562                             bp->radius+= median[5];
00563                         }
00564                         bp++;
00565                     }
00566                 }
00567                 test2DNurb(nu);
00568                 testhandlesNurb(nu); /* test for bezier too */
00569 
00570                 nu= nu->next;
00571             }
00572         }
00573         else if(ob->type==OB_LATTICE) {
00574             Lattice *lt= ob->data;
00575             BPoint *bp;
00576             int a;
00577             
00578             a= lt->editlatt->latt->pntsu*lt->editlatt->latt->pntsv*lt->editlatt->latt->pntsw;
00579             bp= lt->editlatt->latt->def;
00580             while(a--) {
00581                 if(bp->f1 & SELECT) {
00582                     add_v3_v3(bp->vec, median);
00583                     bp->weight+= median[4];
00584                 }
00585                 bp++;
00586             }
00587         }
00588         
00589 //      ED_undo_push(C, "Transform properties");
00590     }
00591 }
00592 #define B_VGRP_PNL_COPY 1
00593 #define B_VGRP_PNL_NORMALIZE 2
00594 #define B_VGRP_PNL_EDIT_SINGLE 8 /* or greater */
00595 #define B_VGRP_PNL_COPY_SINGLE 16384 /* or greater */
00596 
00597 static void act_vert_def(Object *ob, EditVert **eve, MDeformVert **dvert)
00598 {
00599     if(ob && ob->mode & OB_MODE_EDIT && ob->type==OB_MESH && ob->defbase.first) {
00600         Mesh *me= ob->data;
00601         EditMesh *em = BKE_mesh_get_editmesh(me);
00602         EditSelection *ese = ((EditSelection*)em->selected.last);
00603 
00604         if(ese && ese->type == EDITVERT) {
00605             *eve= (EditVert*)ese->data;
00606             *dvert= CustomData_em_get(&em->vdata, (*eve)->data, CD_MDEFORMVERT);
00607             return;
00608         }
00609 
00610         BKE_mesh_end_editmesh(me, em);
00611     }
00612 
00613     *eve= NULL;
00614     *dvert= NULL;
00615 }
00616 
00617 static void editvert_mirror_update(Object *ob, EditVert *eve, int def_nr, int index)
00618 {
00619     Mesh *me= ob->data;
00620     EditMesh *em = BKE_mesh_get_editmesh(me);
00621     EditVert *eve_mirr;
00622 
00623     eve_mirr= editmesh_get_x_mirror_vert(ob, em, eve, eve->co, index);
00624 
00625     if(eve_mirr && eve_mirr != eve) {
00626         MDeformVert *dvert_src= CustomData_em_get(&em->vdata, eve->data, CD_MDEFORMVERT);
00627         MDeformVert *dvert_dst= CustomData_em_get(&em->vdata, eve_mirr->data, CD_MDEFORMVERT);
00628         if(dvert_dst) {
00629             if(def_nr == -1) {
00630                 /* all vgroups, add groups where neded  */
00631                 int flip_map_len;
00632                 int *flip_map= defgroup_flip_map(ob, &flip_map_len, TRUE);
00633                 defvert_sync_mapped(dvert_dst, dvert_src, flip_map, flip_map_len, TRUE);
00634                 MEM_freeN(flip_map);
00635             }
00636             else {
00637                 /* single vgroup */
00638                 MDeformWeight *dw= defvert_verify_index(dvert_dst, defgroup_flip_index(ob, def_nr, 1));
00639                 if(dw) {
00640                     dw->weight= defvert_find_weight(dvert_src, def_nr);
00641                 }
00642             }
00643         }
00644     }
00645 }
00646 
00647 static void vgroup_adjust_active(Object *ob, int def_nr)
00648 {
00649     EditVert *eve_act;
00650     MDeformVert *dvert_act;
00651 
00652     act_vert_def(ob, &eve_act, &dvert_act);
00653 
00654     if(dvert_act) {
00655         if(((Mesh *)ob->data)->editflag & ME_EDIT_MIRROR_X)
00656             editvert_mirror_update(ob, eve_act, def_nr, -1);
00657     }
00658 }
00659 
00660 static void vgroup_copy_active_to_sel(Object *ob)
00661 {
00662     EditVert *eve_act;
00663     MDeformVert *dvert_act;
00664 
00665     act_vert_def(ob, &eve_act, &dvert_act);
00666 
00667     if(dvert_act==NULL) {
00668         return;
00669     }
00670     else {
00671         Mesh *me= ob->data;
00672         EditMesh *em = BKE_mesh_get_editmesh(me);
00673         EditVert *eve;
00674         MDeformVert *dvert;
00675         int index= 0;
00676 
00677         for(eve= em->verts.first; eve; eve= eve->next, index++) {
00678             if(eve->f & SELECT && eve != eve_act) {
00679                 dvert= CustomData_em_get(&em->vdata, eve->data, CD_MDEFORMVERT);
00680                 if(dvert) {
00681                     defvert_copy(dvert, dvert_act);
00682 
00683                     if(me->editflag & ME_EDIT_MIRROR_X)
00684                         editvert_mirror_update(ob, eve, -1, index);
00685 
00686                 }
00687             }
00688         }
00689     }
00690 }
00691 
00692 static void vgroup_copy_active_to_sel_single(Object *ob, const int def_nr)
00693 {
00694     EditVert *eve_act;
00695     MDeformVert *dv_act;
00696 
00697     act_vert_def(ob, &eve_act, &dv_act);
00698 
00699     if(dv_act==NULL) {
00700         return;
00701     }
00702     else {
00703         Mesh *me= ob->data;
00704         EditMesh *em = BKE_mesh_get_editmesh(me);
00705         EditVert *eve;
00706         MDeformVert *dv;
00707         MDeformWeight *dw;
00708         float weight_act;
00709         int index= 0;
00710 
00711         dw= defvert_find_index(dv_act, def_nr);
00712 
00713         if(dw == NULL)
00714             return;
00715 
00716         weight_act= dw->weight;
00717 
00718         for (eve= em->verts.first; eve; eve= eve->next, index++) {
00719             if (eve->f & SELECT && eve != eve_act) {
00720                 dv= CustomData_em_get(&em->vdata, eve->data, CD_MDEFORMVERT);
00721                 if(dv) {
00722                     dw= defvert_find_index(dv, def_nr);
00723                     if (dw) {
00724                         dw->weight= weight_act;
00725 
00726                         if (me->editflag & ME_EDIT_MIRROR_X) {
00727                             editvert_mirror_update(ob, eve, -1, index);
00728                         }
00729                     }
00730                 }
00731             }
00732         }
00733 
00734         if (me->editflag & ME_EDIT_MIRROR_X) {
00735             editvert_mirror_update(ob, eve_act, -1, -1);
00736         }
00737     }
00738 }
00739 
00740 static void vgroup_normalize_active(Object *ob)
00741 {
00742     EditVert *eve_act;
00743     MDeformVert *dvert_act;
00744 
00745     act_vert_def(ob, &eve_act, &dvert_act);
00746 
00747     if(dvert_act==NULL)
00748         return;
00749 
00750     defvert_normalize(dvert_act);
00751 
00752     if(((Mesh *)ob->data)->editflag & ME_EDIT_MIRROR_X)
00753         editvert_mirror_update(ob, eve_act, -1, -1);
00754 
00755 
00756 
00757 }
00758 
00759 static void do_view3d_vgroup_buttons(bContext *C, void *UNUSED(arg), int event)
00760 {
00761     Scene *scene= CTX_data_scene(C);
00762     Object *ob= OBACT;
00763 
00764     if(event==B_VGRP_PNL_NORMALIZE) {
00765         vgroup_normalize_active(ob);
00766     }
00767     else if(event == B_VGRP_PNL_COPY) {
00768         vgroup_copy_active_to_sel(ob);
00769     }
00770     else if(event >= B_VGRP_PNL_COPY_SINGLE) {
00771         vgroup_copy_active_to_sel_single(ob, event - B_VGRP_PNL_COPY_SINGLE);
00772     }
00773     else if(event >= B_VGRP_PNL_EDIT_SINGLE) {
00774         vgroup_adjust_active(ob, event - B_VGRP_PNL_EDIT_SINGLE);
00775     }
00776 
00777 //  todo
00778 //  if(((Mesh *)ob->data)->editflag & ME_EDIT_MIRROR_X)
00779 //      ED_vgroup_mirror(ob, 1, 1, 0);
00780 
00781     /* default for now */
00782     DAG_id_tag_update(&ob->id, OB_RECALC_DATA);
00783     WM_event_add_notifier(C, NC_GEOM|ND_DATA, ob->data);
00784 }
00785 
00786 static int view3d_panel_vgroup_poll(const bContext *C, PanelType *UNUSED(pt))
00787 {
00788     Scene *scene= CTX_data_scene(C);
00789     Object *ob= OBACT;
00790     EditVert *eve_act;
00791     MDeformVert *dvert_act;
00792 
00793     act_vert_def(ob, &eve_act, &dvert_act);
00794 
00795     return dvert_act ? dvert_act->totweight : 0;
00796 }
00797 
00798 
00799 static void view3d_panel_vgroup(const bContext *C, Panel *pa)
00800 {
00801     uiBlock *block= uiLayoutAbsoluteBlock(pa->layout);
00802     Scene *scene= CTX_data_scene(C);
00803     Object *ob= OBACT;
00804 
00805     EditVert *eve;
00806     MDeformVert *dv;
00807 
00808     act_vert_def(ob, &eve, &dv);
00809 
00810     if(dv && dv->totweight) {
00811         uiLayout *col;
00812         bDeformGroup *dg;
00813         MDeformWeight *dw = dv->dw;
00814         unsigned int i;
00815         int yco = 0;
00816 
00817         uiBlockSetHandleFunc(block, do_view3d_vgroup_buttons, NULL);
00818 
00819         col= uiLayoutColumn(pa->layout, 0);
00820         block= uiLayoutAbsoluteBlock(col);
00821 
00822         uiBlockBeginAlign(block);
00823 
00824         for (i= dv->totweight; i != 0; i--, dw++) {
00825             dg = BLI_findlink (&ob->defbase, dw->def_nr);
00826             if(dg) {
00827                 uiDefButF(block, NUM, B_VGRP_PNL_EDIT_SINGLE + dw->def_nr, dg->name,    0, yco, 180, 20, &dw->weight, 0.0, 1.0, 1, 3, "");
00828                 uiDefBut(block, BUT, B_VGRP_PNL_COPY_SINGLE + dw->def_nr, "C", 180,yco,20,20, NULL, 0, 0, 0, 0, "Copy this groups weight to other selected verts");
00829                 yco -= 20;
00830             }
00831         }
00832         yco-=2;
00833 
00834         uiBlockEndAlign(block);
00835         uiBlockBeginAlign(block);
00836         uiDefBut(block, BUT, B_VGRP_PNL_NORMALIZE, "Normalize", 0, yco,100,20, NULL, 0, 0, 0, 0, "Normalize active vertex weights");
00837         uiDefBut(block, BUT, B_VGRP_PNL_COPY, "Copy", 100,yco,100,20, NULL, 0, 0, 0, 0, "Copy active vertex to other seleted verts");
00838         uiBlockEndAlign(block);
00839     }
00840 }
00841 
00842 static void v3d_transform_butsR(uiLayout *layout, PointerRNA *ptr)
00843 {
00844     uiLayout *split, *colsub;
00845     
00846     split = uiLayoutSplit(layout, 0.8, 0);
00847     
00848     if (ptr->type == &RNA_PoseBone) {
00849         PointerRNA boneptr;
00850         Bone *bone;
00851         
00852         boneptr = RNA_pointer_get(ptr, "bone");
00853         bone = boneptr.data;
00854         uiLayoutSetActive(split, !(bone->parent && bone->flag & BONE_CONNECTED));
00855     }
00856     colsub = uiLayoutColumn(split, 1);
00857     uiItemR(colsub, ptr, "location", 0, "Location", ICON_NONE);
00858     colsub = uiLayoutColumn(split, 1);
00859     uiItemL(colsub, "", ICON_NONE);
00860     uiItemR(colsub, ptr, "lock_location", UI_ITEM_R_TOGGLE+UI_ITEM_R_ICON_ONLY, "", ICON_NONE);
00861     
00862     split = uiLayoutSplit(layout, 0.8, 0);
00863     
00864     switch(RNA_enum_get(ptr, "rotation_mode")) {
00865         case ROT_MODE_QUAT: /* quaternion */
00866             colsub = uiLayoutColumn(split, 1);
00867             uiItemR(colsub, ptr, "rotation_quaternion", 0, "Rotation", ICON_NONE);
00868             colsub = uiLayoutColumn(split, 1);
00869             uiItemR(colsub, ptr, "lock_rotations_4d", UI_ITEM_R_TOGGLE, "4L", ICON_NONE);
00870             if (RNA_boolean_get(ptr, "lock_rotations_4d"))
00871                 uiItemR(colsub, ptr, "lock_rotation_w", UI_ITEM_R_TOGGLE+UI_ITEM_R_ICON_ONLY, "", ICON_NONE);
00872             else
00873                 uiItemL(colsub, "", ICON_NONE);
00874             uiItemR(colsub, ptr, "lock_rotation", UI_ITEM_R_TOGGLE+UI_ITEM_R_ICON_ONLY, "", ICON_NONE);
00875             break;
00876         case ROT_MODE_AXISANGLE: /* axis angle */
00877             colsub = uiLayoutColumn(split, 1);
00878             uiItemR(colsub, ptr, "rotation_axis_angle", 0, "Rotation", ICON_NONE);
00879             colsub = uiLayoutColumn(split, 1);
00880             uiItemR(colsub, ptr, "lock_rotations_4d", UI_ITEM_R_TOGGLE, "4L", ICON_NONE);
00881             if (RNA_boolean_get(ptr, "lock_rotations_4d"))
00882                 uiItemR(colsub, ptr, "lock_rotation_w", UI_ITEM_R_TOGGLE+UI_ITEM_R_ICON_ONLY, "", ICON_NONE);
00883             else
00884                 uiItemL(colsub, "", ICON_NONE);
00885             uiItemR(colsub, ptr, "lock_rotation", UI_ITEM_R_TOGGLE+UI_ITEM_R_ICON_ONLY, "", ICON_NONE);
00886             break;
00887         default: /* euler rotations */
00888             colsub = uiLayoutColumn(split, 1);
00889             uiItemR(colsub, ptr, "rotation_euler", 0, "Rotation", ICON_NONE);
00890             colsub = uiLayoutColumn(split, 1);
00891             uiItemL(colsub, "", ICON_NONE);
00892             uiItemR(colsub, ptr, "lock_rotation", UI_ITEM_R_TOGGLE+UI_ITEM_R_ICON_ONLY, "", ICON_NONE);
00893             break;
00894     }
00895     uiItemR(layout, ptr, "rotation_mode", 0, "", ICON_NONE);
00896     
00897     split = uiLayoutSplit(layout, 0.8, 0);
00898     colsub = uiLayoutColumn(split, 1);
00899     uiItemR(colsub, ptr, "scale", 0, "Scale", ICON_NONE);
00900     colsub = uiLayoutColumn(split, 1);
00901     uiItemL(colsub, "", ICON_NONE);
00902     uiItemR(colsub, ptr, "lock_scale", UI_ITEM_R_TOGGLE+UI_ITEM_R_ICON_ONLY, "", ICON_NONE);
00903     
00904     if (ptr->type == &RNA_Object) {
00905         Object *ob = ptr->data;
00906         /* dimensions and material support just happen to be the same checks
00907          * later we may want to add dimensions for lattice, armature etc too */
00908         if (OB_TYPE_SUPPORT_MATERIAL(ob->type)) {
00909             uiItemR(layout, ptr, "dimensions", 0, "Dimensions", ICON_NONE);
00910         }
00911     }
00912 }
00913 
00914 static void v3d_posearmature_buts(uiLayout *layout, Object *ob)
00915 {
00916 //  uiBlock *block= uiLayoutGetBlock(layout);
00917 //  bArmature *arm;
00918     bPoseChannel *pchan;
00919 //  TransformProperties *tfp= v3d->properties_storage;
00920     PointerRNA pchanptr;
00921     uiLayout *col;
00922 //  uiLayout *row;
00923 //  uiBut *but;
00924 
00925     pchan= get_active_posechannel(ob);
00926 
00927 //  row= uiLayoutRow(layout, 0);
00928     
00929     if (!pchan) {
00930         uiItemL(layout, "No Bone Active", ICON_NONE);
00931         return; 
00932     }
00933 
00934     RNA_pointer_create(&ob->id, &RNA_PoseBone, pchan, &pchanptr);
00935 
00936     col= uiLayoutColumn(layout, 0);
00937     
00938     /* XXX: RNA buts show data in native types (i.e. quats, 4-component axis/angle, etc.)
00939      * but oldskool UI shows in eulers always. Do we want to be able to still display in Eulers?
00940      * Maybe needs RNA/ui options to display rotations as different types... */
00941     v3d_transform_butsR(col, &pchanptr);
00942 
00943 #if 0
00944     uiLayoutAbsoluteBlock(layout);
00945 
00946     if (pchan->rotmode == ROT_MODE_AXISANGLE) {
00947         float quat[4];
00948         /* convert to euler, passing through quats... */
00949         axis_angle_to_quat(quat, pchan->rotAxis, pchan->rotAngle);
00950         quat_to_eul( tfp->ob_eul,quat);
00951     }
00952     else if (pchan->rotmode == ROT_MODE_QUAT)
00953         quat_to_eul( tfp->ob_eul,pchan->quat);
00954     else
00955         copy_v3_v3(tfp->ob_eul, pchan->eul);
00956     tfp->ob_eul[0]*= RAD2DEGF(1.0f);
00957     tfp->ob_eul[1]*= RAD2DEGF(1.0f);
00958     tfp->ob_eul[2]*= RAD2DEGF(1.0f);
00959     
00960     uiDefBut(block, LABEL, 0, "Location:",          0, 240, 100, 20, 0, 0, 0, 0, 0, "");
00961     uiBlockBeginAlign(block);
00962     
00963     but= uiDefButF(block, NUM, B_ARMATUREPANEL2, "X:",  0, 220, 120, 19, pchan->loc, -lim, lim, 100, 3, "");
00964     uiButSetUnitType(but, PROP_UNIT_LENGTH);
00965     but= uiDefButF(block, NUM, B_ARMATUREPANEL2, "Y:",  0, 200, 120, 19, pchan->loc+1, -lim, lim, 100, 3, "");
00966     uiButSetUnitType(but, PROP_UNIT_LENGTH);
00967     but= uiDefButF(block, NUM, B_ARMATUREPANEL2, "Z:",  0, 180, 120, 19, pchan->loc+2, -lim, lim, 100, 3, "");
00968     uiButSetUnitType(but, PROP_UNIT_LENGTH);
00969     uiBlockEndAlign(block);
00970     
00971     uiBlockBeginAlign(block);
00972     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");
00973     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");
00974     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");
00975     uiBlockEndAlign(block);
00976     
00977     uiDefBut(block, LABEL, 0, "Rotation:",          0, 160, 100, 20, 0, 0, 0, 0, 0, "");
00978     uiBlockBeginAlign(block);
00979     uiDefButF(block, NUM, B_ARMATUREPANEL3, "X:",   0, 140, 120, 19, tfp->ob_eul, -1000.0, 1000.0, 100, 3, "");
00980     uiDefButF(block, NUM, B_ARMATUREPANEL3, "Y:",   0, 120, 120, 19, tfp->ob_eul+1, -1000.0, 1000.0, 100, 3, "");
00981     uiDefButF(block, NUM, B_ARMATUREPANEL3, "Z:",   0, 100, 120, 19, tfp->ob_eul+2, -1000.0, 1000.0, 100, 3, "");
00982     uiBlockEndAlign(block);
00983     
00984     uiBlockBeginAlign(block);
00985     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");
00986     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");
00987     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");
00988     uiBlockEndAlign(block);
00989     
00990     uiDefBut(block, LABEL, 0, "Scale:",             0, 80, 100, 20, 0, 0, 0, 0, 0, "");
00991     uiBlockBeginAlign(block);
00992     uiDefButF(block, NUM, B_ARMATUREPANEL2, "X:",   0, 60, 120, 19, pchan->size, -lim, lim, 10, 3, "");
00993     uiDefButF(block, NUM, B_ARMATUREPANEL2, "Y:",   0, 40, 120, 19, pchan->size+1, -lim, lim, 10, 3, "");
00994     uiDefButF(block, NUM, B_ARMATUREPANEL2, "Z:",   0, 20, 120, 19, pchan->size+2, -lim, lim, 10, 3, "");
00995     uiBlockEndAlign(block);
00996     
00997     uiBlockBeginAlign(block);
00998     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");
00999     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");
01000     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");
01001     uiBlockEndAlign(block);
01002 #endif
01003 }
01004 
01005 /* assumes armature editmode */
01006 #if 0
01007 static void validate_editbonebutton_cb(bContext *C, void *bonev, void *namev)
01008 {
01009     EditBone *eBone= bonev;
01010     char oldname[sizeof(eBone->name)], newname[sizeof(eBone->name)];
01011 
01012     /* need to be on the stack */
01013     BLI_strncpy(newname, eBone->name, sizeof(eBone->name));
01014     BLI_strncpy(oldname, (char *)namev, sizeof(eBone->name));
01015     /* restore */
01016     BLI_strncpy(eBone->name, oldname, sizeof(eBone->name));
01017 
01018     ED_armature_bone_rename(CTX_data_edit_object(C)->data, oldname, newname); // editarmature.c
01019     WM_event_add_notifier(C, NC_OBJECT|ND_BONE_SELECT, CTX_data_edit_object(C)); // XXX fix
01020 }
01021 #endif
01022 
01023 static void v3d_editarmature_buts(uiLayout *layout, Object *ob)
01024 {
01025 //  uiBlock *block= uiLayoutGetBlock(layout);
01026     bArmature *arm= ob->data;
01027     EditBone *ebone;
01028 //  TransformProperties *tfp= v3d->properties_storage;
01029 //  uiLayout *row;
01030     uiLayout *col;
01031     PointerRNA eboneptr;
01032     
01033     ebone= arm->act_edbone;
01034 
01035     if (!ebone || (ebone->layer & arm->layer)==0) {
01036         uiItemL(layout, "Nothing selected", ICON_NONE);
01037         return;
01038     }
01039 //  row= uiLayoutRow(layout, 0);
01040     RNA_pointer_create(&arm->id, &RNA_EditBone, ebone, &eboneptr);
01041 
01042     col= uiLayoutColumn(layout, 0);
01043     uiItemR(col, &eboneptr, "head", 0, "Head", ICON_NONE);
01044     if (ebone->parent && ebone->flag & BONE_CONNECTED ) {
01045         PointerRNA parptr = RNA_pointer_get(&eboneptr, "parent");
01046         uiItemR(col, &parptr, "tail_radius", 0, "Radius (Parent)", ICON_NONE);
01047     } else {
01048         uiItemR(col, &eboneptr, "head_radius", 0, "Radius", ICON_NONE);
01049     }
01050     
01051     uiItemR(col, &eboneptr, "tail", 0, "Tail", ICON_NONE);
01052     uiItemR(col, &eboneptr, "tail_radius", 0, "Radius", ICON_NONE);
01053     
01054     uiItemR(col, &eboneptr, "roll", 0, "Roll", ICON_NONE);
01055     uiItemR(col, &eboneptr, "envelope_distance", 0, "Envelope", ICON_NONE);
01056 }
01057 
01058 static void v3d_editmetaball_buts(uiLayout *layout, Object *ob)
01059 {
01060     PointerRNA mbptr, ptr;
01061     MetaBall *mball= ob->data;
01062 //  uiLayout *row;
01063     uiLayout *col;
01064     
01065     if (!mball || !(mball->lastelem)) return;
01066     
01067     RNA_pointer_create(&mball->id, &RNA_MetaBall, mball, &mbptr);
01068     
01069 //  row= uiLayoutRow(layout, 0);
01070 
01071     RNA_pointer_create(&mball->id, &RNA_MetaElement, mball->lastelem, &ptr);
01072     
01073     col= uiLayoutColumn(layout, 0);
01074     uiItemR(col, &ptr, "co", 0, "Location", ICON_NONE);
01075     
01076     uiItemR(col, &ptr, "radius", 0, "Radius", ICON_NONE);
01077     uiItemR(col, &ptr, "stiffness", 0, "Stiffness", ICON_NONE);
01078     
01079     uiItemR(col, &ptr, "type", 0, "Type", ICON_NONE);
01080     
01081     col= uiLayoutColumn(layout, 1);
01082     switch (RNA_enum_get(&ptr, "type")) {
01083         case MB_BALL:
01084             break;
01085         case MB_CUBE:
01086             uiItemL(col, "Size:", ICON_NONE);
01087             uiItemR(col, &ptr, "size_x", 0, "X", ICON_NONE);
01088             uiItemR(col, &ptr, "size_y", 0, "Y", ICON_NONE);
01089             uiItemR(col, &ptr, "size_z", 0, "Z", ICON_NONE);
01090             break;
01091         case MB_TUBE:
01092             uiItemL(col, "Size:", ICON_NONE);
01093             uiItemR(col, &ptr, "size_x", 0, "X", ICON_NONE);
01094             break;
01095         case MB_PLANE:
01096             uiItemL(col, "Size:", ICON_NONE);
01097             uiItemR(col, &ptr, "size_x", 0, "X", ICON_NONE);
01098             uiItemR(col, &ptr, "size_y", 0, "Y", ICON_NONE);
01099             break;
01100         case MB_ELIPSOID:
01101             uiItemL(col, "Size:", ICON_NONE);
01102             uiItemR(col, &ptr, "size_x", 0, "X", ICON_NONE);
01103             uiItemR(col, &ptr, "size_y", 0, "Y", ICON_NONE);
01104             uiItemR(col, &ptr, "size_z", 0, "Z", ICON_NONE);
01105             break;         
01106     }   
01107 }
01108 
01109 static void do_view3d_region_buttons(bContext *C, void *UNUSED(index), int event)
01110 {
01111     Main *bmain= CTX_data_main(C);
01112     Scene *scene= CTX_data_scene(C);
01113 //  Object *obedit= CTX_data_edit_object(C);
01114     View3D *v3d= CTX_wm_view3d(C);
01115 //  BoundBox *bb;
01116     Object *ob= OBACT;
01117     TransformProperties *tfp= v3d->properties_storage;
01118     
01119     switch(event) {
01120     
01121     case B_REDR:
01122         ED_area_tag_redraw(CTX_wm_area(C));
01123         return; /* no notifier! */
01124         
01125     case B_OBJECTPANEL:
01126         DAG_id_tag_update(&ob->id, OB_RECALC_OB);
01127         break;
01128 
01129     
01130     case B_OBJECTPANELMEDIAN:
01131         if(ob) {
01132             v3d_editvertex_buts(NULL, v3d, ob, 1.0);
01133             DAG_id_tag_update(&ob->id, OB_RECALC_DATA);
01134         }
01135         break;
01136         
01137         /* note; this case also used for parbone */
01138     case B_OBJECTPANELPARENT:
01139         if(ob) {
01140             if (ob->id.lib || BKE_object_parent_loop_check(ob->parent, ob))
01141                 ob->parent= NULL;
01142             else {
01143                 DAG_scene_sort(bmain, scene);
01144                 DAG_id_tag_update(&ob->id, OB_RECALC_OB);
01145             }
01146         }
01147         break;
01148         
01149 
01150     case B_ARMATUREPANEL3:  // rotate button on channel
01151         {
01152             bPoseChannel *pchan;
01153             float eul[3];
01154             
01155             pchan= get_active_posechannel(ob);
01156             if (!pchan) return;
01157             
01158             /* make a copy to eul[3], to allow TAB on buttons to work */
01159             eul[0]= DEG2RADF(tfp->ob_eul[0]);
01160             eul[1]= DEG2RADF(tfp->ob_eul[1]);
01161             eul[2]= DEG2RADF(tfp->ob_eul[2]);
01162             
01163             if (pchan->rotmode == ROT_MODE_AXISANGLE) {
01164                 float quat[4];
01165                 /* convert to axis-angle, passing through quats  */
01166                 eul_to_quat( quat,eul);
01167                 quat_to_axis_angle( pchan->rotAxis, &pchan->rotAngle,quat);
01168             }
01169             else if (pchan->rotmode == ROT_MODE_QUAT)
01170                 eul_to_quat( pchan->quat,eul);
01171             else
01172                 copy_v3_v3(pchan->eul, eul);
01173         }
01174         /* no break, pass on */
01175     case B_ARMATUREPANEL2:
01176         {
01177             ob->pose->flag |= (POSE_LOCKED|POSE_DO_UNLOCK);
01178             DAG_id_tag_update(&ob->id, OB_RECALC_DATA);
01179         }
01180         break;
01181     case B_TRANSFORMSPACEADD:
01182     {
01183         char names[sizeof(((TransformOrientation *)NULL)->name)]= "";
01184         BIF_createTransformOrientation(C, NULL, names, 1, 0);
01185         break;
01186     }
01187     case B_TRANSFORMSPACECLEAR:
01188         BIF_clearTransformOrientation(C);
01189         break;
01190         
01191 #if 0 // XXX
01192     case B_WEIGHT0_0:
01193         wpaint->weight = 0.0f;
01194         break;
01195         
01196     case B_WEIGHT1_4:
01197         wpaint->weight = 0.25f;
01198         break;
01199     case B_WEIGHT1_2:
01200         wpaint->weight = 0.5f;
01201         break;
01202     case B_WEIGHT3_4:
01203         wpaint->weight = 0.75f;
01204         break;
01205     case B_WEIGHT1_0:
01206         wpaint->weight = 1.0f;
01207         break;
01208         
01209     case B_OPA1_8:
01210         wpaint->a = 0.125f;
01211         break;
01212     case B_OPA1_4:
01213         wpaint->a = 0.25f;
01214         break;
01215     case B_OPA1_2:
01216         wpaint->a = 0.5f;
01217         break;
01218     case B_OPA3_4:
01219         wpaint->a = 0.75f;
01220         break;
01221     case B_OPA1_0:
01222         wpaint->a = 1.0f;
01223         break;
01224 #endif
01225     case B_CLR_WPAINT:
01226 //      if(!multires_level1_test()) {
01227         {
01228             bDeformGroup *defGroup = BLI_findlink(&ob->defbase, ob->actdef-1);
01229             if(defGroup) {
01230                 Mesh *me= ob->data;
01231                 int a;
01232                 for(a=0; a<me->totvert; a++)
01233                     ED_vgroup_vert_remove (ob, defGroup, a);
01234                 DAG_id_tag_update(&ob->id, OB_RECALC_DATA);
01235             }
01236         }
01237         break;
01238     case B_RV3D_LOCKED:
01239     case B_RV3D_BOXVIEW:
01240     case B_RV3D_BOXCLIP:
01241         {
01242             ScrArea *sa= CTX_wm_area(C);
01243             ARegion *ar= sa->regionbase.last;
01244             RegionView3D *rv3d;
01245             short viewlock;
01246             
01247             ar= ar->prev;
01248             rv3d= ar->regiondata;
01249             viewlock= rv3d->viewlock;
01250             
01251             if((viewlock & RV3D_LOCKED)==0)
01252                 viewlock= 0;
01253             else if((viewlock & RV3D_BOXVIEW)==0)
01254                 viewlock &= ~RV3D_BOXCLIP;
01255             
01256             for(; ar; ar= ar->prev) {
01257                 if(ar->alignment==RGN_ALIGN_QSPLIT) {
01258                     rv3d= ar->regiondata;
01259                     rv3d->viewlock= viewlock;
01260                 }
01261             }
01262             
01263             if(rv3d->viewlock & RV3D_BOXVIEW)
01264                 view3d_boxview_copy(sa, sa->regionbase.last);
01265             
01266             ED_area_tag_redraw(sa);
01267         }
01268         break;
01269     }
01270 
01271     /* default for now */
01272     WM_event_add_notifier(C, NC_SPACE|ND_SPACE_VIEW3D, ob);
01273 }
01274 
01275 static void view3d_panel_object(const bContext *C, Panel *pa)
01276 {
01277     uiBlock *block;
01278     Scene *scene= CTX_data_scene(C);
01279     Object *obedit= CTX_data_edit_object(C);
01280     View3D *v3d= CTX_wm_view3d(C);
01281     //uiBut *bt;
01282     Object *ob= OBACT;
01283     // TransformProperties *tfp; // UNUSED
01284     PointerRNA obptr;
01285     uiLayout *col /* , *row */ /* UNUSED */;
01286     float lim;
01287     
01288     if(ob==NULL) return;
01289 
01290     /* make sure we got storage */
01291     /*
01292     if(v3d->properties_storage==NULL)
01293         v3d->properties_storage= MEM_callocN(sizeof(TransformProperties), "TransformProperties");
01294     tfp= v3d->properties_storage;
01295     
01296 // XXX  uiSetButLock(object_is_libdata(ob), ERROR_LIBDATA_MESSAGE);
01297 
01298     if(ob->mode & (OB_MODE_VERTEX_PAINT|OB_MODE_WEIGHT_PAINT|OB_MODE_TEXTURE_PAINT)) {
01299     }
01300     else {
01301         if((ob->mode & OB_MODE_PARTICLE_EDIT)==0) {
01302             uiBlockEndAlign(block);
01303         }
01304     }
01305     */
01306 
01307     lim= 10000.0f * MAX2(1.0f, v3d->grid);
01308 
01309     block= uiLayoutGetBlock(pa->layout);
01310     uiBlockSetHandleFunc(block, do_view3d_region_buttons, NULL);
01311 
01312     col= uiLayoutColumn(pa->layout, 0);
01313     /* row= uiLayoutRow(col, 0); */ /* UNUSED */
01314     RNA_id_pointer_create(&ob->id, &obptr);
01315 
01316     if(ob==obedit) {
01317         if(ob->type==OB_ARMATURE) v3d_editarmature_buts(col, ob);
01318         else if(ob->type==OB_MBALL) v3d_editmetaball_buts(col, ob);
01319         else v3d_editvertex_buts(col, v3d, ob, lim);
01320     }
01321     else if(ob->mode & OB_MODE_POSE) {
01322         v3d_posearmature_buts(col, ob);
01323     }
01324     else {
01325 
01326         v3d_transform_butsR(col, &obptr);
01327     }
01328 }
01329 
01330 #if 0
01331 static void view3d_panel_preview(bContext *C, ARegion *ar, short cntrl) // VIEW3D_HANDLER_PREVIEW
01332 {
01333     uiBlock *block;
01334     View3D *v3d= sa->spacedata.first;
01335     int ofsx, ofsy;
01336     
01337     block= uiBeginBlock(C, ar, __func__, UI_EMBOSS);
01338     uiPanelControl(UI_PNL_SOLID | UI_PNL_CLOSE | UI_PNL_SCALE | cntrl);
01339     uiSetPanelHandler(VIEW3D_HANDLER_PREVIEW);  // for close and esc
01340     
01341     ofsx= -150+(sa->winx/2)/v3d->blockscale;
01342     ofsy= -100+(sa->winy/2)/v3d->blockscale;
01343     if(uiNewPanel(C, ar, block, "Preview", "View3d", ofsx, ofsy, 300, 200)==0) return;
01344 
01345     uiBlockSetDrawExtraFunc(block, BIF_view3d_previewdraw);
01346     
01347     if(scene->recalc & SCE_PRV_CHANGED) {
01348         scene->recalc &= ~SCE_PRV_CHANGED;
01349         //printf("found recalc\n");
01350         BIF_view3d_previewrender_free(sa->spacedata.first);
01351         BIF_preview_changed(0);
01352     }
01353 }
01354 #endif
01355 
01356 void view3d_buttons_register(ARegionType *art)
01357 {
01358     PanelType *pt;
01359 
01360     pt= MEM_callocN(sizeof(PanelType), "spacetype view3d panel object");
01361     strcpy(pt->idname, "VIEW3D_PT_object");
01362     strcpy(pt->label, "Transform");
01363     pt->draw= view3d_panel_object;
01364     BLI_addtail(&art->paneltypes, pt);
01365     
01366     pt= MEM_callocN(sizeof(PanelType), "spacetype view3d panel gpencil");
01367     strcpy(pt->idname, "VIEW3D_PT_gpencil");
01368     strcpy(pt->label, "Grease Pencil");
01369     pt->draw= gpencil_panel_standard;
01370     BLI_addtail(&art->paneltypes, pt);
01371 
01372     pt= MEM_callocN(sizeof(PanelType), "spacetype view3d panel vgroup");
01373     strcpy(pt->idname, "VIEW3D_PT_vgroup");
01374     strcpy(pt->label, "Vertex Groups");
01375     pt->draw= view3d_panel_vgroup;
01376     pt->poll= view3d_panel_vgroup_poll;
01377     BLI_addtail(&art->paneltypes, pt);
01378 
01379     // XXX view3d_panel_preview(C, ar, 0);
01380 }
01381 
01382 static int view3d_properties(bContext *C, wmOperator *UNUSED(op))
01383 {
01384     ScrArea *sa= CTX_wm_area(C);
01385     ARegion *ar= view3d_has_buttons_region(sa);
01386     
01387     if(ar)
01388         ED_region_toggle_hidden(C, ar);
01389 
01390     return OPERATOR_FINISHED;
01391 }
01392 
01393 void VIEW3D_OT_properties(wmOperatorType *ot)
01394 {
01395     ot->name= "Properties";
01396     ot->description= "Toggles the properties panel display";
01397     ot->idname= "VIEW3D_OT_properties";
01398     
01399     ot->exec= view3d_properties;
01400     ot->poll= ED_operator_view3d_active;
01401     
01402     /* flags */
01403     ot->flag= 0;
01404 }