From cc55913798aecbdeb3fc6e49c16a26ccbddebd9b Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Tue, 26 Nov 2013 01:17:24 +0600 Subject: [PATCH] Fix T37225: UV map for closed curves incorrectly generated Summary: Curve ORCO was not calculating properly for cyclic 2D curves. - Needed to split vertices for blender internal renderer. Otherwise it's not possible to map last face to a proper texture location. - Needed to tweak curve->mesh conversion to respect cyclic flag along U direction. - Removed check for orcodm in curve.c:add_orco_dm since this code is only called if there're enabled constructive modifiers on the curve. Reviewers: brecht Maniphest Tasks: T37225 Differential Revision: http://developer.blender.org/D45 --- source/blender/blenkernel/intern/curve.c | 6 +++ source/blender/blenkernel/intern/displist.c | 37 ++++++++----------- source/blender/blenkernel/intern/mesh.c | 3 ++ .../render/intern/source/convertblender.c | 18 +++++++++ 4 files changed, 43 insertions(+), 21 deletions(-) diff --git a/source/blender/blenkernel/intern/curve.c b/source/blender/blenkernel/intern/curve.c index bdc70ed2afe..d57b5149538 100644 --- a/source/blender/blenkernel/intern/curve.c +++ b/source/blender/blenkernel/intern/curve.c @@ -1518,6 +1518,9 @@ float *BKE_curve_make_orco(Scene *scene, Object *ob, int *r_numVerts) else numVerts += dl->parts * (dl->nr + 1); } + else if (dl->flag & DL_CYCL_V) { + numVerts += (dl->parts + 1) * dl->nr; + } else numVerts += dl->parts * dl->nr; } @@ -1553,6 +1556,9 @@ float *BKE_curve_make_orco(Scene *scene, Object *ob, int *r_numVerts) if (dl->flag & DL_CYCL_V) sizev++; } + else if (dl->flag & DL_CYCL_V) { + sizev++; + } for (u = 0; u < sizev; u++) { for (v = 0; v < sizeu; v++, fp += 3) { diff --git a/source/blender/blenkernel/intern/displist.c b/source/blender/blenkernel/intern/displist.c index 6a89ca2cb84..3f35ced3550 100644 --- a/source/blender/blenkernel/intern/displist.c +++ b/source/blender/blenkernel/intern/displist.c @@ -1086,7 +1086,7 @@ static DerivedMesh *create_orco_dm(Scene *scene, Object *ob) return dm; } -static void add_orco_dm(Scene *scene, Object *ob, DerivedMesh *dm, DerivedMesh *orcodm) +static void add_orco_dm(Object *ob, DerivedMesh *dm, DerivedMesh *orcodm) { float (*orco)[3], (*layerorco)[3]; int totvert, a; @@ -1094,23 +1094,12 @@ static void add_orco_dm(Scene *scene, Object *ob, DerivedMesh *dm, DerivedMesh * totvert = dm->getNumVerts(dm); - if (orcodm) { - orco = MEM_callocN(sizeof(float) * 3 * totvert, "dm orco"); + orco = MEM_callocN(sizeof(float) * 3 * totvert, "dm orco"); - if (orcodm->getNumVerts(orcodm) == totvert) - orcodm->getVertCos(orcodm, orco); - else - dm->getVertCos(dm, orco); - } - else { - int totvert_curve; - orco = (float(*)[3])BKE_curve_make_orco(scene, ob, &totvert_curve); - if (totvert != totvert_curve) { - MEM_freeN(orco); - orco = MEM_callocN(sizeof(float) * 3 * totvert, "dm orco"); - dm->getVertCos(dm, orco); - } - } + if (orcodm->getNumVerts(orcodm) == totvert) + orcodm->getVertCos(orcodm, orco); + else + dm->getVertCos(dm, orco); for (a = 0; a < totvert; a++) { float *co = orco[a]; @@ -1157,6 +1146,15 @@ static void curve_calc_orcodm(Scene *scene, Object *ob, DerivedMesh *derivedFina md = pretessellatePoint->next; } + /* If modifiers are disabled, we wouldn't be here because + * this function is only called if there're enabled constructive + * modifiers applied on the curve. + * + * This means we can create ORCO DM in advance and assume it's + * never NULL. + */ + orcodm = create_orco_dm(scene, ob); + for (; md; md = md->next) { ModifierTypeInfo *mti = modifierType_getInfo(md->type); @@ -1167,9 +1165,6 @@ static void curve_calc_orcodm(Scene *scene, Object *ob, DerivedMesh *derivedFina if (mti->type != eModifierTypeType_Constructive) continue; - if (!orcodm) - orcodm = create_orco_dm(scene, ob); - ndm = modwrap_applyModifier(md, ob, orcodm, app_flag); if (ndm) { @@ -1182,7 +1177,7 @@ static void curve_calc_orcodm(Scene *scene, Object *ob, DerivedMesh *derivedFina } /* add an orco layer if needed */ - add_orco_dm(scene, ob, derivedFinal, orcodm); + add_orco_dm(ob, derivedFinal, orcodm); if (orcodm) orcodm->release(orcodm); diff --git a/source/blender/blenkernel/intern/mesh.c b/source/blender/blenkernel/intern/mesh.c index e6fca21f2af..ee25b0a72df 100644 --- a/source/blender/blenkernel/intern/mesh.c +++ b/source/blender/blenkernel/intern/mesh.c @@ -1342,6 +1342,9 @@ int BKE_mesh_nurbs_displist_to_mdata(Object *ob, ListBase *dispbase, if (dl->flag & DL_CYCL_V) orco_sizev++; } + else if (dl->flag & DL_CYCL_V) { + orco_sizev++; + } for (i = 0; i < 4; i++, mloopuv++) { /* find uv based on vertex index into grid array */ diff --git a/source/blender/render/intern/source/convertblender.c b/source/blender/render/intern/source/convertblender.c index fb9f96b0ef7..0dc0f7d74f3 100644 --- a/source/blender/render/intern/source/convertblender.c +++ b/source/blender/render/intern/source/convertblender.c @@ -2819,6 +2819,19 @@ static void init_render_curve(Render *re, ObjectRen *obr, int timeoffset) } } + if (dl->flag & DL_CYCL_V && orco) { + fp = dl->verts; + nr = dl->nr; + while (nr--) { + ver = RE_findOrAddVert(obr, obr->totvert++); + copy_v3_v3(ver->co, fp); + mul_m4_v3(mat, ver->co); + ver->orco = orco; + fp += 3; + orco += 3; + } + } + if (dl->bevelSplitFlag || timeoffset==0) { const int startvlak= obr->totvlak; @@ -2832,6 +2845,11 @@ static void init_render_curve(Render *re, ObjectRen *obr, int timeoffset) p3+= startvert; p4+= startvert; + if (dl->flag & DL_CYCL_V && orco && a == dl->parts - 1) { + p3 = p1 + dl->nr; + p4 = p2 + dl->nr; + } + for (; bnr; b++) { vlr= RE_findOrAddVlak(obr, obr->totvlak++); /* important 1 offset in order is kept [#24913] */