void makeDispListSurf(Scene *scene, Object *ob, ListBase *dispbase, DerivedMesh **derivedFinal, int forRender, int forOrco) { ListBase *nubase; Nurb *nu; Curve *cu = ob->data; DispList *dl; float *data; int len; int numVerts; float (*originalVerts)[3]; float (*deformedVerts)[3]; if(!forRender && cu->editnurb) nubase= ED_curve_editnurbs(cu); else nubase= &cu->nurb; if(!forOrco) curve_calc_modifiers_pre(scene, ob, forRender, &originalVerts, &deformedVerts, &numVerts); for (nu=nubase->first; nu; nu=nu->next) { if(forRender || nu->hide==0) { int resolu= nu->resolu, resolv= nu->resolv; if(forRender){ if(cu->resolu_ren) resolu= cu->resolu_ren; if(cu->resolv_ren) resolv= cu->resolv_ren; } if(nu->pntsv==1) { len= SEGMENTSU(nu)*resolu; dl= MEM_callocN(sizeof(DispList), "makeDispListsurf"); dl->verts= MEM_callocN(len*3*sizeof(float), "dlverts"); BLI_addtail(dispbase, dl); dl->parts= 1; dl->nr= len; dl->col= nu->mat_nr; dl->charidx= nu->charidx; /* dl->rt will be used as flag for render face and */ /* CU_2D conflicts with R_NOPUNOFLIP */ dl->rt= nu->flag & ~CU_2D; data= dl->verts; if(nu->flagu & CU_NURB_CYCLIC) dl->type= DL_POLY; else dl->type= DL_SEGM; makeNurbcurve(nu, data, NULL, NULL, NULL, resolu, 3*sizeof(float)); } else { len= (nu->pntsu*resolu) * (nu->pntsv*resolv); dl= MEM_callocN(sizeof(DispList), "makeDispListsurf"); dl->verts= MEM_callocN(len*3*sizeof(float), "dlverts"); BLI_addtail(dispbase, dl); dl->col= nu->mat_nr; dl->charidx= nu->charidx; /* dl->rt will be used as flag for render face and */ /* CU_2D conflicts with R_NOPUNOFLIP */ dl->rt= nu->flag & ~CU_2D; data= dl->verts; dl->type= DL_SURF; dl->parts= (nu->pntsu*resolu); /* in reverse, because makeNurbfaces works that way */ dl->nr= (nu->pntsv*resolv); if(nu->flagv & CU_NURB_CYCLIC) dl->flag|= DL_CYCL_U; /* reverse too! */ if(nu->flagu & CU_NURB_CYCLIC) dl->flag|= DL_CYCL_V; makeNurbfaces(nu, data, 0, resolu, resolv); /* gl array drawing: using indices */ displist_surf_indices(dl); } } } /* make copy of 'undeformed" displist for texture space calculation actually, it's not totally undeformed -- pre-tesselation modifiers are already applied, thats how it worked for years, so keep for compatibility (sergey) */ copy_displist(&cu->disp, dispbase); if (!forRender) { tex_space_curve(cu); } if(!forOrco) curve_calc_modifiers_post(scene, ob, dispbase, derivedFinal, forRender, originalVerts, deformedVerts); }
/* 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"); } }