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
This commit is contained in:
Sergey Sharybin 2013-11-26 01:17:24 +06:00
parent a5c7b9202b
commit cc55913798
Notes: blender-bot 2023-02-14 11:40:24 +01:00
Referenced by issue #37225, UV map for closed curves incorrectly generated
4 changed files with 43 additions and 21 deletions

View File

@ -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) {

View File

@ -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);

View File

@ -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 */

View File

@ -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 (; b<dl->nr; b++) {
vlr= RE_findOrAddVlak(obr, obr->totvlak++);
/* important 1 offset in order is kept [#24913] */