static void rna_Curve_dimension_set(PointerRNA *ptr, int value) { Curve *cu= (Curve*)ptr->id.data; Nurb *nu= cu->editnurb ? cu->editnurb->first : cu->nurb.first; if(value==CU_3D) { cu->flag |= CU_3D; for( ; nu; nu= nu->next) { nu->flag &= ~CU_2D; } } else { cu->flag &= ~CU_3D; for( ; nu; nu= nu->next) { nu->flag |= CU_2D; test2DNurb(nu); /* since the handles are moved they need to be auto-located again */ if(nu->type == CU_BEZIER) calchandlesNurb(nu); } } }
/* is used for both read and write... */ static void v3d_editvertex_buts(uiLayout *layout, View3D *v3d, Object *ob, float lim) { uiBlock *block= (layout)? uiLayoutAbsoluteBlock(layout): NULL; MDeformVert *dvert=NULL; TransformProperties *tfp; float median[6], ve_median[6]; int tot, totw, totweight, totedge, totradius; char defstr[320]; median[0]= median[1]= median[2]= median[3]= median[4]= median[5]= 0.0; tot= totw= totweight= totedge= totradius= 0; defstr[0]= 0; /* make sure we got storage */ if(v3d->properties_storage==NULL) v3d->properties_storage= MEM_callocN(sizeof(TransformProperties), "TransformProperties"); tfp= v3d->properties_storage; if(ob->type==OB_MESH) { Mesh *me= ob->data; EditMesh *em = BKE_mesh_get_editmesh(me); EditVert *eve, *evedef=NULL; EditEdge *eed; eve= em->verts.first; while(eve) { if(eve->f & SELECT) { evedef= eve; tot++; add_v3_v3(median, eve->co); } eve= eve->next; } eed= em->edges.first; while(eed) { if((eed->f & SELECT)) { totedge++; median[3]+= eed->crease; } eed= eed->next; } /* check for defgroups */ if(evedef) dvert= CustomData_em_get(&em->vdata, evedef->data, CD_MDEFORMVERT); if(tot==1 && dvert && dvert->totweight) { bDeformGroup *dg; int i, max=1, init=1; char str[320]; for (i=0; i<dvert->totweight; i++){ dg = BLI_findlink (&ob->defbase, dvert->dw[i].def_nr); if(dg) { max+= BLI_snprintf(str, sizeof(str), "%s %%x%d|", dg->name, dvert->dw[i].def_nr); if(max<320) strcat(defstr, str); } if(tfp->curdef==dvert->dw[i].def_nr) { init= 0; tfp->defweightp= &dvert->dw[i].weight; } } if(init) { // needs new initialized tfp->curdef= dvert->dw[0].def_nr; tfp->defweightp= &dvert->dw[0].weight; } } BKE_mesh_end_editmesh(me, em); } else if(ob->type==OB_CURVE || ob->type==OB_SURF) { Curve *cu= ob->data; Nurb *nu; BPoint *bp; BezTriple *bezt; int a; ListBase *nurbs= ED_curve_editnurbs(cu); nu= nurbs->first; while(nu) { if(nu->type == CU_BEZIER) { bezt= nu->bezt; a= nu->pntsu; while(a--) { if(bezt->f2 & SELECT) { add_v3_v3(median, bezt->vec[1]); tot++; median[4]+= bezt->weight; totweight++; median[5]+= bezt->radius; totradius++; } else { if(bezt->f1 & SELECT) { add_v3_v3(median, bezt->vec[0]); tot++; } if(bezt->f3 & SELECT) { add_v3_v3(median, bezt->vec[2]); tot++; } } bezt++; } } else { bp= nu->bp; a= nu->pntsu*nu->pntsv; while(a--) { if(bp->f1 & SELECT) { add_v3_v3(median, bp->vec); median[3]+= bp->vec[3]; totw++; tot++; median[4]+= bp->weight; totweight++; median[5]+= bp->radius; totradius++; } bp++; } } nu= nu->next; } } else if(ob->type==OB_LATTICE) { Lattice *lt= ob->data; BPoint *bp; int a; a= lt->editlatt->latt->pntsu*lt->editlatt->latt->pntsv*lt->editlatt->latt->pntsw; bp= lt->editlatt->latt->def; while(a--) { if(bp->f1 & SELECT) { add_v3_v3(median, bp->vec); tot++; median[4]+= bp->weight; totweight++; } bp++; } } if(tot==0) { uiDefBut(block, LABEL, 0, "Nothing selected",0, 130, 200, 20, NULL, 0, 0, 0, 0, ""); return; } median[0] /= (float)tot; median[1] /= (float)tot; median[2] /= (float)tot; if(totedge) median[3] /= (float)totedge; else if(totw) median[3] /= (float)totw; if(totweight) median[4] /= (float)totweight; if(totradius) median[5] /= (float)totradius; if(v3d->flag & V3D_GLOBAL_STATS) mul_m4_v3(ob->obmat, median); if(block) { // buttons uiBut *but; memcpy(tfp->ve_median, median, sizeof(tfp->ve_median)); uiBlockBeginAlign(block); if(tot==1) { uiDefBut(block, LABEL, 0, "Vertex:", 0, 130, 200, 20, NULL, 0, 0, 0, 0, ""); uiBlockBeginAlign(block); but= uiDefButF(block, NUM, B_OBJECTPANELMEDIAN, "X:", 0, 110, 200, 20, &(tfp->ve_median[0]), -lim, lim, 10, 3, ""); uiButSetUnitType(but, PROP_UNIT_LENGTH); but= uiDefButF(block, NUM, B_OBJECTPANELMEDIAN, "Y:", 0, 90, 200, 20, &(tfp->ve_median[1]), -lim, lim, 10, 3, ""); uiButSetUnitType(but, PROP_UNIT_LENGTH); but= uiDefButF(block, NUM, B_OBJECTPANELMEDIAN, "Z:", 0, 70, 200, 20, &(tfp->ve_median[2]), -lim, lim, 10, 3, ""); uiButSetUnitType(but, PROP_UNIT_LENGTH); if(totw==1) { uiDefButF(block, NUM, B_OBJECTPANELMEDIAN, "W:", 0, 50, 200, 20, &(tfp->ve_median[3]), 0.01, 100.0, 1, 3, ""); uiBlockBeginAlign(block); uiDefButBitS(block, TOG, V3D_GLOBAL_STATS, B_REDR, "Global", 0, 25, 100, 20, &v3d->flag, 0, 0, 0, 0, "Displays global values"); uiDefButBitS(block, TOGN, V3D_GLOBAL_STATS, B_REDR, "Local", 100, 25, 100, 20, &v3d->flag, 0, 0, 0, 0, "Displays local values"); uiBlockEndAlign(block); if(totweight) uiDefButF(block, NUM, B_OBJECTPANELMEDIAN, "Weight:", 0, 0, 200, 20, &(tfp->ve_median[4]), 0.0, 1.0, 1, 3, ""); if(totradius) uiDefButF(block, NUM, B_OBJECTPANELMEDIAN, "Radius:", 0, 0, 200, 20, &(tfp->ve_median[5]), 0.0, 100.0, 1, 3, "Radius of curve CPs"); } else { uiBlockBeginAlign(block); uiDefButBitS(block, TOG, V3D_GLOBAL_STATS, B_REDR, "Global", 0, 45, 100, 20, &v3d->flag, 0, 0, 0, 0, "Displays global values"); uiDefButBitS(block, TOGN, V3D_GLOBAL_STATS, B_REDR, "Local", 100, 45, 100, 20, &v3d->flag, 0, 0, 0, 0, "Displays local values"); uiBlockEndAlign(block); if(totweight) uiDefButF(block, NUM, B_OBJECTPANELMEDIAN, "Weight:", 0, 20, 200, 20, &(tfp->ve_median[4]), 0.0, 1.0, 10, 3, ""); if(totradius) uiDefButF(block, NUM, B_OBJECTPANELMEDIAN, "Radius:", 0, 20, 200, 20, &(tfp->ve_median[5]), 0.0, 100.0, 10, 3, "Radius of curve CPs"); } } else { uiDefBut(block, LABEL, 0, "Median:", 0, 130, 200, 20, NULL, 0, 0, 0, 0, ""); uiBlockBeginAlign(block); but= uiDefButF(block, NUM, B_OBJECTPANELMEDIAN, "X:", 0, 110, 200, 20, &(tfp->ve_median[0]), -lim, lim, 10, 3, ""); uiButSetUnitType(but, PROP_UNIT_LENGTH); but= uiDefButF(block, NUM, B_OBJECTPANELMEDIAN, "Y:", 0, 90, 200, 20, &(tfp->ve_median[1]), -lim, lim, 10, 3, ""); uiButSetUnitType(but, PROP_UNIT_LENGTH); but= uiDefButF(block, NUM, B_OBJECTPANELMEDIAN, "Z:", 0, 70, 200, 20, &(tfp->ve_median[2]), -lim, lim, 10, 3, ""); uiButSetUnitType(but, PROP_UNIT_LENGTH); if(totw==tot) { uiDefButF(block, NUM, B_OBJECTPANELMEDIAN, "W:", 0, 50, 200, 20, &(tfp->ve_median[3]), 0.01, 100.0, 1, 3, ""); uiBlockEndAlign(block); uiBlockBeginAlign(block); uiDefButBitS(block, TOG, V3D_GLOBAL_STATS, B_REDR, "Global", 0, 25, 100, 20, &v3d->flag, 0, 0, 0, 0, "Displays global values"); uiDefButBitS(block, TOGN, V3D_GLOBAL_STATS, B_REDR, "Local", 100, 25, 100, 20, &v3d->flag, 0, 0, 0, 0, "Displays local values"); uiBlockEndAlign(block); if(totweight) 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"); if(totradius) uiDefButF(block, NUM, B_OBJECTPANELMEDIAN, "Radius:", 0, 0, 200, 20, &(tfp->ve_median[5]), 0.0, 100.0, 10, 3, "Radius of curve CPs"); uiBlockEndAlign(block); } else { uiBlockBeginAlign(block); uiDefButBitS(block, TOG, V3D_GLOBAL_STATS, B_REDR, "Global", 0, 45, 100, 20, &v3d->flag, 0, 0, 0, 0, "Displays global values"); uiDefButBitS(block, TOGN, V3D_GLOBAL_STATS, B_REDR, "Local", 100, 45, 100, 20, &v3d->flag, 0, 0, 0, 0, "Displays local values"); uiBlockEndAlign(block); if(totweight) 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"); if(totradius) uiDefButF(block, NUM, B_OBJECTPANELMEDIAN, "Radius:", 0, 0, 200, 20, &(tfp->ve_median[5]), 0.0, 100.0, 1, 3, "Radius of curve CPs"); uiBlockEndAlign(block); } } if(totedge==1) uiDefButF(block, NUM, B_OBJECTPANELMEDIAN, "Crease:", 0, 20, 200, 20, &(tfp->ve_median[3]), 0.0, 1.0, 1, 3, ""); else if(totedge>1) uiDefButF(block, NUM, B_OBJECTPANELMEDIAN, "Mean Crease:", 0, 20, 200, 20, &(tfp->ve_median[3]), 0.0, 1.0, 1, 3, ""); } else { // apply memcpy(ve_median, tfp->ve_median, sizeof(tfp->ve_median)); if(v3d->flag & V3D_GLOBAL_STATS) { invert_m4_m4(ob->imat, ob->obmat); mul_m4_v3(ob->imat, median); mul_m4_v3(ob->imat, ve_median); } sub_v3_v3v3(median, ve_median, median); median[3]= ve_median[3]-median[3]; median[4]= ve_median[4]-median[4]; median[5]= ve_median[5]-median[5]; if(ob->type==OB_MESH) { Mesh *me= ob->data; EditMesh *em = BKE_mesh_get_editmesh(me); /* allow for some rounding error becasue of matrix transform */ if(len_v3(median) > 0.000001f) { EditVert *eve; for(eve= em->verts.first; eve; eve= eve->next) { if(eve->f & SELECT) { add_v3_v3(eve->co, median); } } recalc_editnormals(em); } if(median[3] != 0.0f) { EditEdge *eed; const float fixed_crease= (ve_median[3] <= 0.0f ? 0.0f : (ve_median[3] >= 1.0f ? 1.0f : FLT_MAX)); if(fixed_crease != FLT_MAX) { /* simple case */ for(eed= em->edges.first; eed; eed= eed->next) { if(eed->f & SELECT) { eed->crease= fixed_crease; } } } else { /* scale crease to target median */ float median_new= ve_median[3]; float median_orig= ve_median[3] - median[3]; /* previous median value */ /* incase of floating point error */ CLAMP(median_orig, 0.0f, 1.0f); CLAMP(median_new, 0.0f, 1.0f); if(median_new < median_orig) { /* scale down */ const float sca= median_new / median_orig; for(eed= em->edges.first; eed; eed= eed->next) { if(eed->f & SELECT) { eed->crease *= sca; CLAMP(eed->crease, 0.0f, 1.0f); } } } else { /* scale up */ const float sca= (1.0f - median_new) / (1.0f - median_orig); for(eed= em->edges.first; eed; eed= eed->next) { if(eed->f & SELECT) { eed->crease = 1.0f - ((1.0f - eed->crease) * sca); CLAMP(eed->crease, 0.0f, 1.0f); } } } } } BKE_mesh_end_editmesh(me, em); } else if(ob->type==OB_CURVE || ob->type==OB_SURF) { Curve *cu= ob->data; Nurb *nu; BPoint *bp; BezTriple *bezt; int a; ListBase *nurbs= ED_curve_editnurbs(cu); nu= nurbs->first; while(nu) { if(nu->type == CU_BEZIER) { bezt= nu->bezt; a= nu->pntsu; while(a--) { if(bezt->f2 & SELECT) { add_v3_v3(bezt->vec[0], median); add_v3_v3(bezt->vec[1], median); add_v3_v3(bezt->vec[2], median); bezt->weight+= median[4]; bezt->radius+= median[5]; } else { if(bezt->f1 & SELECT) { add_v3_v3(bezt->vec[0], median); } if(bezt->f3 & SELECT) { add_v3_v3(bezt->vec[2], median); } } bezt++; } } else { bp= nu->bp; a= nu->pntsu*nu->pntsv; while(a--) { if(bp->f1 & SELECT) { add_v3_v3(bp->vec, median); bp->vec[3]+= median[3]; bp->weight+= median[4]; bp->radius+= median[5]; } bp++; } } test2DNurb(nu); testhandlesNurb(nu); /* test for bezier too */ nu= nu->next; } } else if(ob->type==OB_LATTICE) { Lattice *lt= ob->data; BPoint *bp; int a; a= lt->editlatt->latt->pntsu*lt->editlatt->latt->pntsv*lt->editlatt->latt->pntsw; bp= lt->editlatt->latt->def; while(a--) { if(bp->f1 & SELECT) { add_v3_v3(bp->vec, median); bp->weight+= median[4]; } bp++; } } // ED_undo_push(C, "Transform properties"); } }
/* copied from editobject.c, now uses (almost) proper depgraph */ static void special_transvert_update(Scene *scene, Object *obedit) { if(obedit) { DAG_id_flush_update(obedit->data, OB_RECALC_DATA); if(obedit->type==OB_MESH) { Mesh *me= obedit->data; recalc_editnormals(me->edit_mesh); // does face centers too } else if (ELEM(obedit->type, OB_CURVE, OB_SURF)) { Curve *cu= obedit->data; Nurb *nu= cu->editnurb->first; while(nu) { test2DNurb(nu); testhandlesNurb(nu); /* test for bezier too */ nu= nu->next; } } else if(obedit->type==OB_ARMATURE){ bArmature *arm= obedit->data; EditBone *ebo; TransVert *tv= transvmain; int a=0; /* Ensure all bone tails are correctly adjusted */ for (ebo= arm->edbo->first; ebo; ebo=ebo->next) { /* adjust tip if both ends selected */ if ((ebo->flag & BONE_ROOTSEL) && (ebo->flag & BONE_TIPSEL)) { if (tv) { float diffvec[3]; VecSubf(diffvec, tv->loc, tv->oldloc); VecAddf(ebo->tail, ebo->tail, diffvec); a++; if (a<tottrans) tv++; } } } /* Ensure all bones are correctly adjusted */ for (ebo= arm->edbo->first; ebo; ebo=ebo->next) { if ((ebo->flag & BONE_CONNECTED) && ebo->parent){ /* If this bone has a parent tip that has been moved */ if (ebo->parent->flag & BONE_TIPSEL){ VECCOPY (ebo->head, ebo->parent->tail); } /* If this bone has a parent tip that has NOT been moved */ else{ VECCOPY (ebo->parent->tail, ebo->head); } } } if(arm->flag & ARM_MIRROR_EDIT) transform_armature_mirror_update(obedit); } else if(obedit->type==OB_LATTICE) { Lattice *lt= obedit->data; if(lt->editlatt->flag & LT_OUTSIDE) outside_lattice(lt->editlatt); } } }