diff options
Diffstat (limited to 'source/blender/blenkernel/intern/displist.c')
-rw-r--r-- | source/blender/blenkernel/intern/displist.c | 554 |
1 files changed, 406 insertions, 148 deletions
diff --git a/source/blender/blenkernel/intern/displist.c b/source/blender/blenkernel/intern/displist.c index c1fcf4f13f4..15e561cfc45 100644 --- a/source/blender/blenkernel/intern/displist.c +++ b/source/blender/blenkernel/intern/displist.c @@ -35,54 +35,28 @@ #include "MEM_guardedalloc.h" -#include "IMB_imbuf_types.h" -#include "DNA_texture_types.h" -#include "DNA_meta_types.h" #include "DNA_curve_types.h" -#include "DNA_effect_types.h" -#include "DNA_listBase.h" -#include "DNA_lamp_types.h" -#include "DNA_object_types.h" -#include "DNA_object_force.h" -#include "DNA_mesh_types.h" #include "DNA_meshdata_types.h" -#include "DNA_modifier_types.h" #include "DNA_scene_types.h" -#include "DNA_image_types.h" #include "DNA_material_types.h" -#include "DNA_view3d_types.h" -#include "DNA_lattice_types.h" -#include "DNA_key_types.h" #include "BLI_blenlib.h" #include "BLI_math.h" #include "BLI_editVert.h" -#include "BLI_edgehash.h" -#include "BKE_utildefines.h" #include "BKE_global.h" #include "BKE_displist.h" -#include "BKE_deform.h" -#include "BKE_DerivedMesh.h" +#include "BKE_cdderivedmesh.h" #include "BKE_object.h" -#include "BKE_world.h" -#include "BKE_mesh.h" -#include "BKE_effect.h" #include "BKE_mball.h" #include "BKE_material.h" #include "BKE_curve.h" #include "BKE_key.h" #include "BKE_anim.h" -#include "BKE_screen.h" -#include "BKE_texture.h" -#include "BKE_library.h" #include "BKE_font.h" #include "BKE_lattice.h" -#include "BKE_scene.h" -#include "BKE_subsurf.h" #include "BKE_modifier.h" -#include "BKE_customdata.h" #include "RE_pipeline.h" #include "RE_shader_ext.h" @@ -222,10 +196,10 @@ void addnormalsDispList(Object *ob, ListBase *lb) normal_quad_v3( nor,v1, v3, v4, v2); - add_v3_v3v3(n1, n1, nor); - add_v3_v3v3(n2, n2, nor); - add_v3_v3v3(n3, n3, nor); - add_v3_v3v3(n4, n4, nor); + add_v3_v3(n1, nor); + add_v3_v3(n2, nor); + add_v3_v3(n3, nor); + add_v3_v3(n4, nor); v2= v1; v1+= 3; v4= v3; v3+= 3; @@ -321,9 +295,9 @@ static Render *fastshade_get_render(Scene *scene) /* XXX ugly global still, but we can't do preview while rendering */ if(G.rendering==0) { - Render *re= RE_GetRender("_Shade View_", RE_SLOT_DEFAULT); + Render *re= RE_GetRender("_Shade View_"); if(re==NULL) { - re= RE_NewRender("_Shade View_", RE_SLOT_DEFAULT); + re= RE_NewRender("_Shade View_"); RE_Database_Baking(re, scene, 0, 0); /* 0= no faces */ } @@ -337,7 +311,7 @@ static Render *fastshade_get_render(Scene *scene) /* called on file reading */ void fastshade_free_render(void) { - Render *re= RE_GetRender("_Shade View_", RE_SLOT_DEFAULT); + Render *re= RE_GetRender("_Shade View_"); if(re) { RE_Database_Free(re); @@ -516,7 +490,7 @@ static void mesh_create_shadedColors(Render *re, Object *ob, int onlyForMesh, un float *orco, *vnors, *nors, imat[3][3], mat[4][4], vec[3]; int a, i, need_orco, totface, totvert; CustomDataMask dataMask = CD_MASK_BAREMESH | CD_MASK_MCOL - | CD_MASK_MTFACE | CD_MASK_NORMAL; + | CD_MASK_MTFACE | CD_MASK_NORMAL; init_fastshade_for_ob(re, ob, &need_orco, mat, imat); @@ -601,9 +575,9 @@ static void mesh_create_shadedColors(Render *re, Object *ob, int onlyForMesh, un char *col1= (char*)&col1base[j*4]; char *col2= (char*)(col2base?&col2base[j*4]:NULL); float *vn = (mf->flag & ME_SMOOTH)?&vnors[3*vidx[j]]:n1; - - VECCOPY(vec, mv->co); - mul_m4_v3(mat, vec); + + mul_v3_m4v3(vec, mat, mv->co); + vec[0]+= 0.001*vn[0]; vec[1]+= 0.001*vn[1]; vec[2]+= 0.001*vn[2]; @@ -714,8 +688,7 @@ void shadeDispList(Scene *scene, Base *base) a= dl->nr; while(a--) { - VECCOPY(vec, fp); - mul_m4_v3(mat, vec); + mul_v3_m4v3(vec, mat, fp); fastshade(vec, n1, fp, ma, (char *)col1, NULL); @@ -730,8 +703,7 @@ void shadeDispList(Scene *scene, Base *base) nor= dl->nors; while(a--) { - VECCOPY(vec, fp); - mul_m4_v3(mat, vec); + mul_v3_m4v3(vec, mat, fp); n1[0]= imat[0][0]*nor[0]+imat[0][1]*nor[1]+imat[0][2]*nor[2]; n1[1]= imat[1][0]*nor[0]+imat[1][1]*nor[1]+imat[1][2]*nor[2]; @@ -768,8 +740,7 @@ void shadeDispList(Scene *scene, Base *base) a= dl->nr; while(a--) { - VECCOPY(vec, fp); - mul_m4_v3(mat, vec); + mul_v3_m4v3(vec, mat, fp); /* transpose ! */ n1[0]= imat[0][0]*nor[0]+imat[0][1]*nor[1]+imat[0][2]*nor[2]; @@ -839,17 +810,17 @@ static void curve_to_displist(Curve *cu, ListBase *nubase, ListBase *dispbase) /* count */ len= 0; a= nu->pntsu-1; - if(nu->flagu & CU_CYCLIC) a++; + if(nu->flagu & CU_NURB_CYCLIC) a++; prevbezt= nu->bezt; bezt= prevbezt+1; while(a--) { - if(a==0 && (nu->flagu & CU_CYCLIC)) bezt= nu->bezt; + if(a==0 && (nu->flagu & CU_NURB_CYCLIC)) bezt= nu->bezt; if(prevbezt->h2==HD_VECT && bezt->h1==HD_VECT) len++; else len+= resolu; - if(a==0 && (nu->flagu & CU_CYCLIC)==0) len++; + if(a==0 && (nu->flagu & CU_NURB_CYCLIC)==0) len++; prevbezt= bezt; bezt++; @@ -866,7 +837,7 @@ static void curve_to_displist(Curve *cu, ListBase *nubase, ListBase *dispbase) data= dl->verts; - if(nu->flagu & CU_CYCLIC) { + if(nu->flagu & CU_NURB_CYCLIC) { dl->type= DL_POLY; a= nu->pntsu; } @@ -919,9 +890,9 @@ static void curve_to_displist(Curve *cu, ListBase *nubase, ListBase *dispbase) dl->charidx = nu->charidx; data= dl->verts; - if(nu->flagu & CU_CYCLIC) dl->type= DL_POLY; + if(nu->flagu & CU_NURB_CYCLIC) dl->type= DL_POLY; else dl->type= DL_SEGM; - makeNurbcurve(nu, data, NULL, NULL, resolu, 3*sizeof(float)); + makeNurbcurve(nu, data, NULL, NULL, NULL, resolu, 3*sizeof(float)); } else if(nu->type == CU_POLY) { len= nu->pntsu; @@ -934,7 +905,7 @@ static void curve_to_displist(Curve *cu, ListBase *nubase, ListBase *dispbase) dl->charidx = nu->charidx; data= dl->verts; - if(nu->flagu & CU_CYCLIC) dl->type= DL_POLY; + if(nu->flagu & CU_NURB_CYCLIC) dl->type= DL_POLY; else dl->type= DL_SEGM; a= len; @@ -951,7 +922,7 @@ static void curve_to_displist(Curve *cu, ListBase *nubase, ListBase *dispbase) } -void filldisplist(ListBase *dispbase, ListBase *to) +void filldisplist(ListBase *dispbase, ListBase *to, int flipnormal) { EditVert *eve, *v1, *vlast; EditFace *efa; @@ -1045,6 +1016,9 @@ void filldisplist(ListBase *dispbase, ListBase *to) index[0]= (intptr_t)efa->v1->tmp.l; index[1]= (intptr_t)efa->v2->tmp.l; index[2]= (intptr_t)efa->v3->tmp.l; + + if(flipnormal) + SWAP(int, index[0], index[2]); index+= 3; efa= efa->next; @@ -1121,13 +1095,13 @@ static void bevels_to_filledpoly(Curve *cu, ListBase *dispbase) dl= dl->next; } - filldisplist(&front, dispbase); - filldisplist(&back, dispbase); + filldisplist(&front, dispbase, 1); + filldisplist(&back, dispbase, 0); freedisplist(&front); freedisplist(&back); - filldisplist(dispbase, dispbase); + filldisplist(dispbase, dispbase, 0); } @@ -1139,7 +1113,7 @@ static void curve_to_filledpoly(Curve *cu, ListBase *nurb, ListBase *dispbase) bevels_to_filledpoly(cu, dispbase); } else { - filldisplist(dispbase, dispbase); + filldisplist(dispbase, dispbase, 0); } } @@ -1195,21 +1169,31 @@ void makeDispListMBall(Scene *scene, Object *ob) { if(!ob || ob->type!=OB_MBALL) return; + // XXX: mball stuff uses plenty of global variables + // while this is unchanged updating during render is unsafe + if(G.rendering) return; + freedisplist(&(ob->disp)); - + if(ob->type==OB_MBALL) { if(ob==find_basis_mball(scene, ob)) { - metaball_polygonize(scene, ob); + metaball_polygonize(scene, ob, &ob->disp); tex_space_mball(ob); - object_deform_mball(ob); + object_deform_mball(ob, &ob->disp); } } boundbox_displist(ob); } -static ModifierData *curve_get_tesselate_point(Object *ob, int forRender, int editmode) +void makeDispListMBall_forRender(Scene *scene, Object *ob, ListBase *dispbase) +{ + metaball_polygonize(scene, ob, dispbase); + object_deform_mball(ob, dispbase); +} + +static ModifierData *curve_get_tesselate_point(Scene *scene, Object *ob, int forRender, int editmode) { ModifierData *md = modifiers_getVirtualModifierList(ob); ModifierData *preTesselatePoint; @@ -1222,10 +1206,7 @@ static ModifierData *curve_get_tesselate_point(Object *ob, int forRender, int ed preTesselatePoint = NULL; for (; md; md=md->next) { - ModifierTypeInfo *mti = modifierType_getInfo(md->type); - - if ((md->mode & required_mode) != required_mode) continue; - if (mti->isDisabled && mti->isDisabled(md, forRender)) continue; + if (!modifier_isEnabled(scene, md, required_mode)) continue; if (ELEM3(md->type, eModifierType_Hook, eModifierType_Softbody, eModifierType_MeshDeform)) { preTesselatePoint = md; @@ -1251,7 +1232,7 @@ static void curve_calc_modifiers_pre(Scene *scene, Object *ob, int forRender, fl if(forRender) required_mode = eModifierMode_Render; else required_mode = eModifierMode_Realtime; - preTesselatePoint = curve_get_tesselate_point(ob, forRender, editmode); + preTesselatePoint = curve_get_tesselate_point(scene, ob, forRender, editmode); if(editmode) required_mode |= eModifierMode_Editmode; @@ -1282,7 +1263,7 @@ static void curve_calc_modifiers_pre(Scene *scene, Object *ob, int forRender, fl deformedVerts = curve_getVertexCos(cu, nurb, &numVerts); originalVerts = MEM_dupallocN(deformedVerts); } - + mti->deformVerts(md, ob, NULL, deformedVerts, numVerts, forRender, editmode); if (md==preTesselatePoint) @@ -1294,7 +1275,7 @@ static void curve_calc_modifiers_pre(Scene *scene, Object *ob, int forRender, fl curve_applyVertexCos(cu, nurb, deformedVerts); if (keyVerts) /* these are not passed through modifier stack */ curve_applyKeyVertexTilts(cu, nurb, keyVerts); - + if(keyVerts) MEM_freeN(keyVerts); @@ -1303,20 +1284,56 @@ static void curve_calc_modifiers_pre(Scene *scene, Object *ob, int forRender, fl *numVerts_r = numVerts; } -static void curve_calc_modifiers_post(Scene *scene, Object *ob, ListBase *dispbase, int forRender, float (*originalVerts)[3], float (*deformedVerts)[3]) +static float (*displist_get_allverts (ListBase *dispbase, int *totvert))[3] +{ + DispList *dl; + float (*allverts)[3], *fp; + + *totvert= 0; + + for (dl=dispbase->first; dl; dl=dl->next) + *totvert+= (dl->type==DL_INDEX3)?dl->nr:dl->parts*dl->nr; + + allverts= MEM_mallocN((*totvert)*sizeof(float)*3, "displist_get_allverts allverts"); + fp= (float*)allverts; + for (dl=dispbase->first; dl; dl=dl->next) { + int offs= 3 * ((dl->type==DL_INDEX3)?dl->nr:dl->parts*dl->nr); + memcpy(fp, dl->verts, sizeof(float) * offs); + fp+= offs; + } + + return allverts; +} + +static void displist_apply_allverts(ListBase *dispbase, float (*allverts)[3]) +{ + DispList *dl; + float *fp; + + fp= (float*)allverts; + for (dl=dispbase->first; dl; dl=dl->next) { + int offs= 3 * ((dl->type==DL_INDEX3)?dl->nr:dl->parts*dl->nr); + memcpy(dl->verts, fp, sizeof(float) * offs); + fp+= offs; + } +} + +static void curve_calc_modifiers_post(Scene *scene, Object *ob, ListBase *dispbase, + DerivedMesh **derivedFinal, int forRender, float (*originalVerts)[3], float (*deformedVerts)[3]) { ModifierData *md = modifiers_getVirtualModifierList(ob); ModifierData *preTesselatePoint; Curve *cu= ob->data; ListBase *nurb= cu->editnurb?cu->editnurb:&cu->nurb; - DispList *dl; - int required_mode; + int required_mode, totvert = 0; int editmode = (!forRender && cu->editnurb); + DerivedMesh *dm= NULL, *ndm; + float (*vertCos)[3] = NULL; if(forRender) required_mode = eModifierMode_Render; else required_mode = eModifierMode_Realtime; - preTesselatePoint = curve_get_tesselate_point(ob, forRender, editmode); + preTesselatePoint = curve_get_tesselate_point(scene, ob, forRender, editmode); if(editmode) required_mode |= eModifierMode_Editmode; @@ -1324,47 +1341,104 @@ static void curve_calc_modifiers_post(Scene *scene, Object *ob, ListBase *dispba md = preTesselatePoint->next; } + if (derivedFinal && *derivedFinal) { + (*derivedFinal)->release (*derivedFinal); + } + for (; md; md=md->next) { ModifierTypeInfo *mti = modifierType_getInfo(md->type); - + md->scene= scene; - + if ((md->mode & required_mode) != required_mode) continue; if (mti->isDisabled && mti->isDisabled(md, forRender)) continue; - if (mti->type!=eModifierTypeType_OnlyDeform && mti->type!=eModifierTypeType_DeformOrConstruct) continue; - /* need to put all verts in 1 block for curve deform */ - if(md->type==eModifierType_Curve) { - float *allverts, *fp; - int totvert= 0; - - for (dl=dispbase->first; dl; dl=dl->next) - totvert+= (dl->type==DL_INDEX3)?dl->nr:dl->parts*dl->nr; - - fp= allverts= MEM_mallocN(totvert*sizeof(float)*3, "temp vert"); - for (dl=dispbase->first; dl; dl=dl->next) { - int offs= 3 * ((dl->type==DL_INDEX3)?dl->nr:dl->parts*dl->nr); - memcpy(fp, dl->verts, sizeof(float) * offs); - fp+= offs; + if (mti->type == eModifierTypeType_OnlyDeform || + (mti->type == eModifierTypeType_DeformOrConstruct && !dm)) { + if (dm) { + if (!vertCos) { + totvert = dm->getNumVerts(dm); + vertCos = MEM_mallocN(sizeof(*vertCos) * totvert, "dfmv"); + dm->getVertCos(dm, vertCos); + } + + mti->deformVerts(md, ob, dm, vertCos, totvert, forRender, editmode); + } else { + if (!vertCos) { + vertCos= displist_get_allverts(dispbase, &totvert); + } + + mti->deformVerts(md, ob, NULL, vertCos, totvert, forRender, editmode); } - - mti->deformVerts(md, ob, NULL, (float(*)[3]) allverts, totvert, forRender, editmode); - - fp= allverts; - for (dl=dispbase->first; dl; dl=dl->next) { - int offs= 3 * ((dl->type==DL_INDEX3)?dl->nr:dl->parts*dl->nr); - memcpy(dl->verts, fp, sizeof(float) * offs); - fp+= offs; + } else { + if (!derivedFinal) { + /* makeDisplistCurveTypes could be used for beveling, where derived mesh */ + /* is totally unnecessary, so we could stop modifiers applying */ + /* when we found constructive modifier but derived mesh is unwanted result */ + break; } - MEM_freeN(allverts); - } - else { - for (dl=dispbase->first; dl; dl=dl->next) { - mti->deformVerts(md, ob, NULL, (float(*)[3]) dl->verts, (dl->type==DL_INDEX3)?dl->nr:dl->parts*dl->nr, forRender, editmode); + + if (dm) { + if (vertCos) { + DerivedMesh *tdm = CDDM_copy(dm, 0); + dm->release(dm); + dm = tdm; + + CDDM_apply_vert_coords(dm, vertCos); + CDDM_calc_normals(dm); + } + } else { + if (vertCos) { + displist_apply_allverts(dispbase, vertCos); + } + + if (ELEM(ob->type, OB_CURVE, OB_FONT) && (cu->flag & CU_DEFORM_FILL)) { + curve_to_filledpoly(cu, nurb, dispbase); + } + + dm= CDDM_from_curve_customDB(ob, dispbase); + + CDDM_calc_normals(dm); + } + + if (vertCos) { + /* Vertex coordinates were applied to necessary data, could free it */ + MEM_freeN(vertCos); + vertCos= NULL; + } + + ndm = mti->applyModifier(md, ob, dm, forRender, editmode); + + if (ndm) { + /* Modifier returned a new derived mesh */ + + if (dm && dm != ndm) /* Modifier */ + dm->release (dm); + dm = ndm; } } } + if (vertCos) { + if (dm) { + DerivedMesh *tdm = CDDM_copy(dm, 0); + dm->release(dm); + dm = tdm; + + CDDM_apply_vert_coords(dm, vertCos); + CDDM_calc_normals(dm); + MEM_freeN(vertCos); + } else { + displist_apply_allverts(dispbase, vertCos); + MEM_freeN(vertCos); + vertCos= NULL; + } + } + + if (derivedFinal) { + (*derivedFinal) = dm; + } + if (deformedVerts) { curve_applyVertexCos(ob->data, nurb, originalVerts); MEM_freeN(originalVerts); @@ -1402,7 +1476,110 @@ static void displist_surf_indices(DispList *dl) } -void makeDispListSurf(Scene *scene, Object *ob, ListBase *dispbase, int forRender, int forOrco) +static DerivedMesh *create_orco_dm(Scene *scene, Object *ob) +{ + DerivedMesh *dm; + ListBase disp= {NULL, NULL}; + + /* OrcoDM should be created from underformed disp lists */ + makeDispListCurveTypes_forOrco(scene, ob, &disp); + dm= CDDM_from_curve_customDB(ob, &disp); + + freedisplist(&disp); + + return dm; +} + +static void add_orco_dm(Scene *scene, Object *ob, DerivedMesh *dm, DerivedMesh *orcodm) +{ + float (*orco)[3], (*layerorco)[3]; + int totvert, a; + Curve *cu= ob->data; + + totvert= dm->getNumVerts(dm); + + if(orcodm) { + orco= MEM_callocN(sizeof(float)*3*totvert, "dm orco"); + + if(orcodm->getNumVerts(orcodm) == totvert) + orcodm->getVertCos(orcodm, orco); + else + dm->getVertCos(dm, orco); + } + else { + orco= (float(*)[3])make_orco_curve(scene, ob); + } + + for(a=0; a<totvert; a++) { + float *co = orco[a]; + co[0] = (co[0]-cu->loc[0])/cu->size[0]; + co[1] = (co[1]-cu->loc[1])/cu->size[1]; + co[2] = (co[2]-cu->loc[2])/cu->size[2]; + } + + if((layerorco = DM_get_vert_data_layer(dm, CD_ORCO))) { + memcpy(layerorco, orco, sizeof(float)*totvert); + MEM_freeN(orco); + } + else + DM_add_vert_layer(dm, CD_ORCO, CD_ASSIGN, orco); +} + +static void curve_calc_orcodm(Scene *scene, Object *ob, DerivedMesh *derivedFinal, int forRender) +{ + /* this function represents logic of mesh's orcodm calculation */ + /* for displist-based objects */ + + ModifierData *md = modifiers_getVirtualModifierList(ob); + ModifierData *preTesselatePoint; + Curve *cu= ob->data; + int required_mode; + int editmode = (!forRender && cu->editnurb); + DerivedMesh *ndm, *orcodm= NULL; + + if(forRender) required_mode = eModifierMode_Render; + else required_mode = eModifierMode_Realtime; + + preTesselatePoint = curve_get_tesselate_point(scene, ob, forRender, editmode); + + if(editmode) required_mode |= eModifierMode_Editmode; + + if (preTesselatePoint) { + md = preTesselatePoint->next; + } + + for (; md; md=md->next) { + ModifierTypeInfo *mti = modifierType_getInfo(md->type); + + md->scene= scene; + + if ((md->mode & required_mode) != required_mode) continue; + if (mti->isDisabled && mti->isDisabled(md, forRender)) continue; + if (mti->type!=eModifierTypeType_Constructive) continue; + + if(!orcodm) + orcodm= create_orco_dm(scene, ob); + + ndm = mti->applyModifier(md, ob, orcodm, forRender, 0); + + if(ndm) { + /* if the modifier returned a new dm, release the old one */ + if(orcodm && orcodm != ndm) { + orcodm->release(orcodm); + } + orcodm = ndm; + } + } + + /* add an orco layer if needed */ + add_orco_dm(scene, ob, derivedFinal, orcodm); + + if(orcodm) + orcodm->release(orcodm); +} + +void makeDispListSurf(Scene *scene, Object *ob, ListBase *dispbase, + DerivedMesh **derivedFinal, int forRender, int forOrco) { ListBase *nubase; Nurb *nu; @@ -1426,22 +1603,25 @@ void makeDispListSurf(Scene *scene, Object *ob, ListBase *dispbase, int forRende if(forRender || nu->hide==0) { if(nu->pntsv==1) { len= SEGMENTSU(nu)*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= nu->flag; - + + /* 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_CYCLIC) dl->type= DL_POLY; + if(nu->flagu & CU_NURB_CYCLIC) dl->type= DL_POLY; else dl->type= DL_SEGM; - - makeNurbcurve(nu, data, NULL, NULL, nu->resolu, 3*sizeof(float)); + + makeNurbcurve(nu, data, NULL, NULL, NULL, nu->resolu, 3*sizeof(float)); } else { len= (nu->pntsu*nu->resolu) * (nu->pntsv*nu->resolv); @@ -1452,15 +1632,18 @@ void makeDispListSurf(Scene *scene, Object *ob, ListBase *dispbase, int forRende dl->col= nu->mat_nr; dl->charidx= nu->charidx; - dl->rt= nu->flag; - + + /* 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*nu->resolu); /* in reverse, because makeNurbfaces works that way */ dl->nr= (nu->pntsv*nu->resolv); - if(nu->flagv & CU_CYCLIC) dl->flag|= DL_CYCL_U; /* reverse too! */ - if(nu->flagu & CU_CYCLIC) dl->flag|= DL_CYCL_V; + 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); @@ -1475,23 +1658,20 @@ void makeDispListSurf(Scene *scene, Object *ob, ListBase *dispbase, int forRende } if(!forOrco) - curve_calc_modifiers_post(scene, ob, dispbase, forRender, originalVerts, deformedVerts); + curve_calc_modifiers_post(scene, ob, dispbase, derivedFinal, + forRender, originalVerts, deformedVerts); } -void makeDispListCurveTypes(Scene *scene, Object *ob, int forOrco) +static void do_makeDispListCurveTypes(Scene *scene, Object *ob, ListBase *dispbase, + DerivedMesh **derivedFinal, int forRender, int forOrco) { Curve *cu = ob->data; - ListBase *dispbase; - + /* we do allow duplis... this is only displist on curve level */ if(!ELEM3(ob->type, OB_SURF, OB_CURVE, OB_FONT)) return; - freedisplist(&(ob->disp)); - dispbase= &(cu->disp); - freedisplist(dispbase); - if(ob->type==OB_SURF) { - makeDispListSurf(scene, ob, dispbase, 0, forOrco); + makeDispListSurf(scene, ob, dispbase, derivedFinal, forRender, forOrco); } else if (ELEM(ob->type, OB_CURVE, OB_FONT)) { ListBase dlbev; @@ -1500,24 +1680,33 @@ void makeDispListCurveTypes(Scene *scene, Object *ob, int forOrco) float (*deformedVerts)[3]; int numVerts; + /* Bevel and taper objects should always be curves */ + if (cu->bevobj && cu->bevobj->type != OB_CURVE) { + cu->bevobj = NULL; + } + + if (cu->taperobj && cu->taperobj->type != OB_CURVE) { + cu->taperobj = NULL; + } + if(cu->editnurb) nubase= cu->editnurb; else nubase= &cu->nurb; - + BLI_freelistN(&(cu->bev)); - + if(cu->path) free_path(cu->path); cu->path= NULL; - + if(ob->type==OB_FONT) BKE_text_to_curve(scene, ob, 0); - - if(!forOrco) curve_calc_modifiers_pre(scene, ob, 0, &originalVerts, &deformedVerts, &numVerts); + + if(!forOrco) curve_calc_modifiers_pre(scene, ob, forRender, &originalVerts, &deformedVerts, &numVerts); makeBevelList(ob); /* If curve has no bevel will return nothing */ - makebevelcurve(scene, ob, &dlbev); + makebevelcurve(scene, ob, &dlbev, forRender); /* no bevel or extrude, and no width correction? */ if (!dlbev.first && cu->width==1.0f) { @@ -1532,26 +1721,29 @@ void makeDispListCurveTypes(Scene *scene, Object *ob, int forOrco) float *fp1, *data; BevPoint *bevp; int a,b; - + if (bl->nr) { /* blank bevel lists can happen */ - + /* exception handling; curve without bevel or extrude, with width correction */ if(dlbev.first==NULL) { dl= MEM_callocN(sizeof(DispList), "makeDispListbev"); dl->verts= MEM_callocN(3*sizeof(float)*bl->nr, "dlverts"); BLI_addtail(dispbase, dl); - + if(bl->poly!= -1) dl->type= DL_POLY; else dl->type= DL_SEGM; - + if(dl->type==DL_SEGM) dl->flag = (DL_FRONT_CURVE|DL_BACK_CURVE); - + dl->parts= 1; dl->nr= bl->nr; dl->col= nu->mat_nr; dl->charidx= nu->charidx; - dl->rt= nu->flag; - + + /* dl->rt will be used as flag for render face and */ + /* CU_2D conflicts with R_NOPUNOFLIP */ + dl->rt= nu->flag & ~CU_2D; + a= dl->nr; bevp= (BevPoint *)(bl+1); data= dl->verts; @@ -1565,10 +1757,10 @@ void makeDispListCurveTypes(Scene *scene, Object *ob, int forOrco) } else { DispList *dlb; - + for (dlb=dlbev.first; dlb; dlb=dlb->next) { - /* for each part of the bevel use a separate displblock */ + /* for each part of the bevel use a separate displblock */ dl= MEM_callocN(sizeof(DispList), "makeDispListbev1"); dl->verts= data= MEM_callocN(3*sizeof(float)*dlb->nr*bl->nr, "dlverts"); BLI_addtail(dispbase, dl); @@ -1583,11 +1775,15 @@ void makeDispListCurveTypes(Scene *scene, Object *ob, int forOrco) dl->nr= dlb->nr; dl->col= nu->mat_nr; dl->charidx= nu->charidx; - dl->rt= nu->flag; + + /* dl->rt will be used as flag for render face and */ + /* CU_2D conflicts with R_NOPUNOFLIP */ + dl->rt= nu->flag & ~CU_2D; + dl->bevelSplitFlag= MEM_callocN(sizeof(*dl->col2)*((bl->nr+0x1F)>>5), "col2"); bevp= (BevPoint *)(bl+1); - /* for each point of poly make a bevel piece */ + /* for each point of poly make a bevel piece */ bevp= (BevPoint *)(bl+1); for(a=0; a<bl->nr; a++,bevp++) { float fac=1.0; @@ -1597,7 +1793,7 @@ void makeDispListCurveTypes(Scene *scene, Object *ob, int forOrco) } else { fac = calc_taper(scene, cu->taperobj, a, bl->nr); } - + if (bevp->split_tag) { dl->bevelSplitFlag[a>>5] |= 1<<(a&0x1F); } @@ -1611,9 +1807,9 @@ void makeDispListCurveTypes(Scene *scene, Object *ob, int forOrco) vec[0]= fp1[1]+widfac; vec[1]= fp1[2]; vec[2]= 0.0; - + mul_qt_v3(bevp->quat, vec); - + data[0]= bevp->vec[0] + fac*vec[0]; data[1]= bevp->vec[1] + fac*vec[1]; data[2]= bevp->vec[2] + fac*vec[2]; @@ -1636,15 +1832,77 @@ void makeDispListCurveTypes(Scene *scene, Object *ob, int forOrco) freedisplist(&dlbev); } - curve_to_filledpoly(cu, nubase, dispbase); + if (!(cu->flag & CU_DEFORM_FILL)) { + curve_to_filledpoly(cu, nubase, dispbase); + } if(cu->flag & CU_PATH) calc_curvepath(ob); - if(!forOrco) curve_calc_modifiers_post(scene, ob, &cu->disp, 0, originalVerts, deformedVerts); - tex_space_curve(cu); + if (!forRender) { + tex_space_curve(cu); + } + + if(!forOrco) curve_calc_modifiers_post(scene, ob, dispbase, derivedFinal, forRender, originalVerts, deformedVerts); + + if (cu->flag & CU_DEFORM_FILL && !ob->derivedFinal) { + curve_to_filledpoly(cu, nubase, dispbase); + } } - - boundbox_displist(ob); +} + +void makeDispListCurveTypes(Scene *scene, Object *ob, int forOrco) +{ + Curve *cu = ob->data; + ListBase *dispbase; + + freedisplist(&(ob->disp)); + dispbase= &(cu->disp); + freedisplist(dispbase); + + do_makeDispListCurveTypes(scene, ob, dispbase, &ob->derivedFinal, 0, forOrco); + + if (ob->derivedFinal) { + DM_set_object_boundbox (ob, ob->derivedFinal); + } else { + boundbox_displist (ob); + + /* if there is no derivedMesh, object's boundbox is unneeded */ + if (ob->bb) { + MEM_freeN(ob->bb); + ob->bb= NULL; + } + } +} + +void makeDispListCurveTypes_forRender(Scene *scene, Object *ob, ListBase *dispbase, + DerivedMesh **derivedFinal, int forOrco) +{ + do_makeDispListCurveTypes(scene, ob, dispbase, derivedFinal, 1, forOrco); +} + +void makeDispListCurveTypes_forOrco(struct Scene *scene, struct Object *ob, struct ListBase *dispbase) +{ + do_makeDispListCurveTypes(scene, ob, dispbase, NULL, 1, 1); +} + +/* add Orco layer to the displist object which has got derived mesh and return orco */ +float *makeOrcoDispList(Scene *scene, Object *ob, DerivedMesh *derivedFinal, int forRender) { + float *orco; + + if (derivedFinal == NULL) + derivedFinal= ob->derivedFinal; + + if (!derivedFinal->getVertDataArray(derivedFinal, CD_ORCO)) { + curve_calc_orcodm(scene, ob, derivedFinal, forRender); + } + + orco= derivedFinal->getVertDataArray(derivedFinal, CD_ORCO); + + if(orco) { + orco= MEM_dupallocN(orco); + } + + return orco; } void imagestodisplist(void) @@ -1667,7 +1925,7 @@ static void boundbox_displist(Object *ob) Curve *cu= ob->data; int doit= 0; - if(cu->bb==0) cu->bb= MEM_callocN(sizeof(BoundBox), "boundbox"); + if(cu->bb==0) cu->bb= MEM_callocN(sizeof(BoundBox), "boundbox"); bb= cu->bb; dl= cu->disp.first; |