Fix #33752: UV Orco coordinates were wrong for Cycles (and other external
authorBrecht Van Lommel <brechtvanlommel@pandora.be>
Thu, 10 Jan 2013 17:37:17 +0000 (17:37 +0000)
committerBrecht Van Lommel <brechtvanlommel@pandora.be>
Thu, 10 Jan 2013 17:37:17 +0000 (17:37 +0000)
render engines). Replaced generating orco_index by filling the UV loop data
directly which is easier and all that needed to be done anyway.

source/blender/blenkernel/BKE_cdderivedmesh.h
source/blender/blenkernel/BKE_mesh.h
source/blender/blenkernel/intern/cdderivedmesh.c
source/blender/blenkernel/intern/displist.c
source/blender/blenkernel/intern/mesh.c
source/blender/makesrna/intern/rna_object_api.c

index 2b2497f3f509358ed39f95bdd2aebd599cdca806..af5e925987d49e9054fd7f0870f2215c59adac5f 100644 (file)
@@ -63,14 +63,12 @@ DerivedMesh *CDDM_from_editbmesh(struct BMEditMesh *em, int use_mdisps, int use_
 /* merge verts  */
 DerivedMesh *CDDM_merge_verts(DerivedMesh *dm, const int *vtargetmap);
 
-DerivedMesh *CDDM_from_curve_orco(struct Scene *scene, struct Object *ob);
-
 /* creates a CDDerivedMesh from the given curve object */
 struct DerivedMesh *CDDM_from_curve(struct Object *ob);
 
 /* creates a CDDerivedMesh from the given curve object and specified dispbase */
 /* useful for OrcoDM creation for curves with constructive modifiers */
-DerivedMesh *CDDM_from_curve_displist(struct Object *ob, struct ListBase *dispbase, int **orco_index_ptr);
+DerivedMesh *CDDM_from_curve_displist(struct Object *ob, struct ListBase *dispbase);
 
 /* Copies the given DerivedMesh with verts, faces & edges stored as
  * custom element data.
index 5f4cc65ae7ed42fafd982f835e1348db4f365a50..3466a914bce8605752ac93a122e54a4fc410278a 100644 (file)
@@ -154,13 +154,9 @@ int  BKE_mesh_nurbs_to_mdata(struct Object *ob, struct MVert **allvert, int *tot
                              int *totloop, int *totpoly);
 int BKE_mesh_nurbs_displist_to_mdata(struct Object *ob, struct ListBase *dispbase, struct MVert **allvert, int *_totvert,
                                      struct MEdge **alledge, int *_totedge, struct MLoop **allloop, struct MPoly **allpoly,
-                                     int *_totloop, int *_totpoly, int **orco_index_ptr);
-void BKE_mesh_nurbs_to_mdata_orco(struct MPoly *mpoly, int totpoly,
-                                  struct MLoop *mloops, struct MLoopUV *mloopuvs,
-                                  float (*orco)[3], int (*orco_index)[4]);
+                                     struct MLoopUV **alluv, int *_totloop, int *_totpoly);
+void BKE_mesh_from_nurbs_displist(struct Object *ob, struct ListBase *dispbase, int use_orco_uv);
 void BKE_mesh_from_nurbs(struct Object *ob);
-void BKE_mesh_from_nurbs_displist(struct Object *ob, struct ListBase *dispbase,
-                                  int **orco_index_ptr);
 void BKE_mesh_from_curve(struct Scene *scene, struct Object *ob);
 void BKE_mesh_delete_material_index(struct Mesh *me, short index);
 void BKE_mesh_smooth_flag_set(struct Object *meshOb, int enableSmooth);
index 0321b96325640af18de059f0351d7cd91e0f8402..85dd4c67fdfdb9112b31922abdb43e4ff6c47f75 100644 (file)
@@ -1775,49 +1775,10 @@ DerivedMesh *CDDM_from_mesh(Mesh *mesh, Object *UNUSED(ob))
 
 DerivedMesh *CDDM_from_curve(Object *ob)
 {
-       return CDDM_from_curve_displist(ob, &ob->disp, NULL);
+       return CDDM_from_curve_displist(ob, &ob->disp);
 }
 
-DerivedMesh *CDDM_from_curve_orco(struct Scene *scene, Object *ob)
-{
-       int *orco_index_ptr = NULL;
-       int (*orco_index)[4] = NULL;
-       float (*orco)[3] = NULL;
-       DerivedMesh *dm = CDDM_from_curve_displist(ob, &ob->disp, &orco_index_ptr);
-
-       if (orco_index_ptr) {
-               orco = (float (*)[3])BKE_curve_make_orco(scene, ob);
-       }
-
-       if (orco && orco_index_ptr) {
-               const char *uvname = "Orco";
-
-               int totpoly = dm->getNumPolys(dm);
-
-               MPoly *mpolys = dm->getPolyArray(dm);
-               MLoop *mloops = dm->getLoopArray(dm);
-
-               MLoopUV *mloopuvs;
-
-               CustomData_add_layer_named(&dm->polyData, CD_MTEXPOLY, CD_DEFAULT, NULL, dm->numPolyData, uvname);
-               mloopuvs = CustomData_add_layer_named(&dm->loopData, CD_MLOOPUV,  CD_DEFAULT, NULL, dm->numLoopData, uvname);
-
-               BKE_mesh_nurbs_to_mdata_orco(mpolys, totpoly,
-                                            mloops, mloopuvs,
-                                            orco, orco_index);
-       }
-
-       if (orco_index) {
-               MEM_freeN(orco_index);
-       }
-       if (orco) {
-               MEM_freeN(orco);
-       }
-
-       return dm;
-}
-
-DerivedMesh *CDDM_from_curve_displist(Object *ob, ListBase *dispbase, int **orco_index_ptr)
+DerivedMesh *CDDM_from_curve_displist(Object *ob, ListBase *dispbase)
 {
        DerivedMesh *dm;
        CDDerivedMesh *cddm;
@@ -1828,7 +1789,8 @@ DerivedMesh *CDDM_from_curve_displist(Object *ob, ListBase *dispbase, int **orco
        int totvert, totedge, totloop, totpoly;
 
        if (BKE_mesh_nurbs_displist_to_mdata(ob, dispbase, &allvert, &totvert, &alledge,
-                                            &totedge, &allloop, &allpoly, &totloop, &totpoly, orco_index_ptr) != 0)
+                                            &totedge, &allloop, &allpoly, NULL,
+                                            &totloop, &totpoly) != 0)
        {
                /* Error initializing mdata. This often happens when curve is empty */
                return CDDM_new(0, 0, 0, 0, 0);
index daf0d571887d9c0d6df62357f4474892be7bfe50..643c7b1d9727f8ab091cc307c2c827aa605ab1ff 100644 (file)
@@ -975,7 +975,7 @@ static void curve_calc_modifiers_post(Scene *scene, Object *ob, ListBase *dispba
                                        curve_to_filledpoly(cu, nurb, dispbase);
                                }
 
-                               dm = CDDM_from_curve_displist(ob, dispbase, NULL);
+                               dm = CDDM_from_curve_displist(ob, dispbase);
 
                                CDDM_calc_normals_mapping(dm);
                        }
@@ -1065,7 +1065,7 @@ static DerivedMesh *create_orco_dm(Scene *scene, Object *ob)
 
        /* OrcoDM should be created from underformed disp lists */
        BKE_displist_make_curveTypes_forOrco(scene, ob, &disp);
-       dm = CDDM_from_curve_displist(ob, &disp, NULL);
+       dm = CDDM_from_curve_displist(ob, &disp);
 
        BKE_displist_free(&disp);
 
index 806df92a4cb60d6e5ceacaf57dc0d0fb385df536..dec7556392f3856cad588c58b0e20c8c8440d4b8 100644 (file)
@@ -1204,8 +1204,8 @@ int BKE_mesh_nurbs_to_mdata(Object *ob, MVert **allvert, int *totvert,
        return BKE_mesh_nurbs_displist_to_mdata(ob, &ob->disp,
                                                allvert, totvert,
                                                alledge, totedge,
-                                               allloop, allpoly,
-                                               totloop, totpoly, NULL);
+                                               allloop, allpoly, NULL,
+                                               totloop, totpoly);
 }
 
 /* BMESH: this doesn't calculate all edges from polygons,
@@ -1213,25 +1213,24 @@ int BKE_mesh_nurbs_to_mdata(Object *ob, MVert **allvert, int *totvert,
 
 /* Initialize mverts, medges and, faces for converting nurbs to mesh and derived mesh */
 /* use specified dispbase */
-/* TODO: orco values for non DL_SURF types */
 int BKE_mesh_nurbs_displist_to_mdata(Object *ob, ListBase *dispbase,
                                      MVert **allvert, int *_totvert,
                                      MEdge **alledge, int *_totedge,
                                      MLoop **allloop, MPoly **allpoly,
-                                     int *_totloop, int *_totpoly,
-                                     int **orco_index_ptr)
+                                     MLoopUV **alluv,
+                                     int *_totloop, int *_totpoly)
 {
        DispList *dl;
        Curve *cu;
        MVert *mvert;
        MPoly *mpoly;
        MLoop *mloop;
+       MLoopUV *mloopuv = NULL;
        MEdge *medge;
        float *data;
        int a, b, ofs, vertcount, startvert, totvert = 0, totedge = 0, totloop = 0, totvlak = 0;
        int p1, p2, p3, p4, *index;
        int conv_polys = 0;
-       int (*orco_index)[4] = NULL;
 
        cu = ob->data;
 
@@ -1278,15 +1277,13 @@ int BKE_mesh_nurbs_displist_to_mdata(Object *ob, ListBase *dispbase,
        *alledge = medge = MEM_callocN(sizeof(MEdge) * totedge, "nurbs_init medge");
        *allloop = mloop = MEM_callocN(sizeof(MLoop) * totvlak * 4, "nurbs_init mloop"); // totloop
        *allpoly = mpoly = MEM_callocN(sizeof(MPoly) * totvlak, "nurbs_init mloop");
+
+       if (alluv)
+               *alluv = mloopuv = MEM_callocN(sizeof(MLoopUV) * totvlak * 4, "nurbs_init mloopuv");
        
        /* verts and faces */
        vertcount = 0;
 
-       if (orco_index_ptr) {
-               *orco_index_ptr = MEM_callocN(sizeof(int) * totvlak * 4, "nurbs_init orco");
-               orco_index = (int (*)[4]) *orco_index_ptr;
-       }
-
        dl = dispbase->first;
        while (dl) {
                int smooth = dl->rt & CU_SMOOTH ? 1 : 0;
@@ -1359,6 +1356,15 @@ int BKE_mesh_nurbs_displist_to_mdata(Object *ob, ListBase *dispbase,
                                mpoly->totloop = 3;
                                mpoly->mat_nr = dl->col;
 
+                               if (mloopuv) {
+                                       int i;
+
+                                       for (i = 0; i < 3; i++, mloopuv++) {
+                                               mloopuv->uv[0] = (mloop[i].v - startvert)/(float)(dl->nr - 1);
+                                               mloopuv->uv[1] = 0.0f;
+                                       }
+                               }
+
                                if (smooth) mpoly->flag |= ME_SMOOTH;
                                mpoly++;
                                mloop += 3;
@@ -1408,13 +1414,29 @@ int BKE_mesh_nurbs_displist_to_mdata(Object *ob, ListBase *dispbase,
                                        mpoly->totloop = 4;
                                        mpoly->mat_nr = dl->col;
 
-                                       if (orco_index) {
-                                               const int poly_index = mpoly - *allpoly;
-                                               const int p_orco_base = startvert + ((dl->nr + 1) * a) + b;
-                                               orco_index[poly_index][0] = p_orco_base + 1;
-                                               orco_index[poly_index][1] = p_orco_base + dl->nr + 2;
-                                               orco_index[poly_index][2] = p_orco_base + dl->nr + 1;
-                                               orco_index[poly_index][3] = p_orco_base;
+                                       if (mloopuv) {
+                                               int orco_sizeu = dl->nr - 1;
+                                               int orco_sizev = dl->parts - 1;
+                                               int i;
+
+                                               /* exception as handled in convertblender.c too */
+                                               if (dl->flag & DL_CYCL_U) {
+                                                       orco_sizeu++;
+                                                       if (dl->flag & DL_CYCL_V)
+                                                               orco_sizev++;
+                                               }
+
+                                               for (i = 0; i < 4; i++, mloopuv++) {
+                                                       /* find uv based on vertex index into grid array */
+                                                       int v = mloop[i].v - startvert;
+
+                                                       mloopuv->uv[0] = (v / dl->nr)/(float)orco_sizev;
+                                                       mloopuv->uv[1] = (v % dl->nr)/(float)orco_sizeu;
+
+                                                       /* cyclic correction */
+                                                       if ((i == 0 || i == 1) && mloopuv->uv[1] == 0.0f)
+                                                               mloopuv->uv[1] = 1.0f;
+                                               }
                                        }
 
                                        if (smooth) mpoly->flag |= ME_SMOOTH;
@@ -1427,7 +1449,6 @@ int BKE_mesh_nurbs_displist_to_mdata(Object *ob, ListBase *dispbase,
                                        p1++;
                                }
                        }
-
                }
 
                dl = dl->next;
@@ -1448,33 +1469,8 @@ int BKE_mesh_nurbs_displist_to_mdata(Object *ob, ListBase *dispbase,
 }
 
 
-MINLINE void copy_uv_orco_v2_v2(float r[2], const float a[2])
-{
-       r[0] = 0.5f + a[0] * 0.5f;
-       r[1] = 0.5f + a[1] * 0.5f;
-}
-
-/**
- * orco is normally from #BKE_curve_make_orco
- */
-void BKE_mesh_nurbs_to_mdata_orco(MPoly *mpoly, int totpoly,
-                                  MLoop *mloops, MLoopUV *mloopuvs,
-                                  float (*orco)[3], int (*orco_index)[4])
-{
-       MPoly *mp;
-
-       int i, j;
-       for (i = 0, mp = mpoly; i < totpoly; i++, mp++) {
-               MLoop *ml = mloops + mp->loopstart;
-               MLoopUV *mluv = mloopuvs + mp->loopstart;
-               for (j = 0; j < mp->totloop; j++, ml++, mluv++) {
-                       copy_uv_orco_v2_v2(mluv->uv, orco[orco_index[i][j]]);
-               }
-       }
-}
-
 /* this may fail replacing ob->data, be sure to check ob->type */
-void BKE_mesh_from_nurbs_displist(Object *ob, ListBase *dispbase, int **orco_index_ptr)
+void BKE_mesh_from_nurbs_displist(Object *ob, ListBase *dispbase, int use_orco_uv)
 {
        Main *bmain = G.main;
        Object *ob1;
@@ -1484,6 +1480,7 @@ void BKE_mesh_from_nurbs_displist(Object *ob, ListBase *dispbase, int **orco_ind
        MVert *allvert = NULL;
        MEdge *alledge = NULL;
        MLoop *allloop = NULL;
+       MLoopUV *alluv = NULL;
        MPoly *allpoly = NULL;
        int totvert, totedge, totloop, totpoly;
 
@@ -1492,7 +1489,8 @@ void BKE_mesh_from_nurbs_displist(Object *ob, ListBase *dispbase, int **orco_ind
        if (dm == NULL) {
                if (BKE_mesh_nurbs_displist_to_mdata(ob, dispbase, &allvert, &totvert,
                                                     &alledge, &totedge, &allloop,
-                                                    &allpoly, &totloop, &totpoly, orco_index_ptr) != 0)
+                                                    &allpoly, (use_orco_uv)? &alluv: NULL,
+                                                    &totloop, &totpoly) != 0)
                {
                        /* Error initializing */
                        return;
@@ -1510,6 +1508,12 @@ void BKE_mesh_from_nurbs_displist(Object *ob, ListBase *dispbase, int **orco_ind
                me->mloop = CustomData_add_layer(&me->ldata, CD_MLOOP, CD_ASSIGN, allloop, me->totloop);
                me->mpoly = CustomData_add_layer(&me->pdata, CD_MPOLY, CD_ASSIGN, allpoly, me->totpoly);
 
+               if (alluv) {
+                       const char *uvname = "Orco";
+                       me->mtpoly = CustomData_add_layer_named(&me->pdata, CD_MTEXPOLY, CD_DEFAULT, NULL, me->totpoly, uvname);
+                       me->mloopuv = CustomData_add_layer_named(&me->ldata, CD_MLOOPUV, CD_ASSIGN, alluv, me->totloop, uvname);
+               }
+
                BKE_mesh_calc_normals(me->mvert, me->totvert, me->mloop, me->mpoly, me->totloop, me->totpoly, NULL);
 
                BKE_mesh_calc_edges(me, TRUE);
@@ -1548,7 +1552,7 @@ void BKE_mesh_from_nurbs_displist(Object *ob, ListBase *dispbase, int **orco_ind
 
 void BKE_mesh_from_nurbs(Object *ob)
 {
-       BKE_mesh_from_nurbs_displist(ob, &ob->disp, NULL);
+       BKE_mesh_from_nurbs_displist(ob, &ob->disp, false);
 }
 
 typedef struct EdgeLink {
index d7115256fe52fe8d16697ae819a8af9dfe0d4c9e..40b8d4cce6671f2f8daf7c86211ae0dc59ab4f5d 100644 (file)
@@ -129,9 +129,6 @@ static Mesh *rna_Object_to_mesh(Object *ob, ReportList *reports, Scene *sce, int
                        DerivedMesh *derivedFinal = NULL;
                        int uv_from_orco;
 
-                       int (*orco_index)[4] = NULL;
-                       float (*orco)[3] = NULL;
-
                        /* copies object and modifiers (but not the data) */
                        tmpobj = BKE_object_copy_with_caches(ob);
                        tmpcu = (Curve *)tmpobj->data;
@@ -158,38 +155,12 @@ static Mesh *rna_Object_to_mesh(Object *ob, ReportList *reports, Scene *sce, int
 
                        tmpobj->derivedFinal = derivedFinal;
 
-                       uv_from_orco = (tmpcu->flag & CU_UV_ORCO) != 0;
-
-                       if (uv_from_orco) {
-                               /* before curve conversion */
-                               orco = (float (*)[3])BKE_curve_make_orco(sce, tmpobj);
-                       }
-
                        /* convert object type to mesh */
-                       BKE_mesh_from_nurbs_displist(tmpobj, &dispbase, uv_from_orco ? (int **)&orco_index : NULL);
+                       uv_from_orco = (tmpcu->flag & CU_UV_ORCO) != 0;
+                       BKE_mesh_from_nurbs_displist(tmpobj, &dispbase, uv_from_orco);
 
                        tmpmesh = tmpobj->data;
 
-                       if (uv_from_orco && orco && orco_index) {
-                               const char *uvname = "Orco";
-                               /* add UV's */
-                               MTexPoly *mtpoly  = CustomData_add_layer_named(&tmpmesh->pdata, CD_MTEXPOLY, CD_DEFAULT, NULL, tmpmesh->totpoly, uvname);
-                               MLoopUV *mloopuvs = CustomData_add_layer_named(&tmpmesh->ldata, CD_MLOOPUV,  CD_DEFAULT, NULL, tmpmesh->totloop, uvname);
-
-                               BKE_mesh_nurbs_to_mdata_orco(tmpmesh->mpoly, tmpmesh->totpoly,
-                                                            tmpmesh->mloop, mloopuvs,
-                                                            orco, orco_index);
-
-                               (void)mtpoly;
-                       }
-
-                       if (orco_index) {
-                               MEM_freeN(orco_index);
-                       }
-                       if (orco) {
-                               MEM_freeN(orco);
-                       }
-
                        BKE_displist_free(&dispbase);
 
                        /* BKE_mesh_from_nurbs changes the type to a mesh, check it worked */