Fix for #31962, changes image ignores correct aspect ratio. Made
authorAntony Riakiotakis <kalast@gmail.com>
Mon, 9 Jul 2012 16:12:57 +0000 (16:12 +0000)
committerAntony Riakiotakis <kalast@gmail.com>
Mon, 9 Jul 2012 16:12:57 +0000 (16:12 +0000)
unwrapper flush the correct aspect flag to mtpoly after unwrap. Faces
that have been unwrapped with correct aspect option will fix their
aspect each time a different image is assigned to them. I hope fix works
100%, I can't say that I really understood the bizarre aspect ratio
system.

source/blender/editors/uvedit/uvedit_ops.c
source/blender/editors/uvedit/uvedit_parametrizer.c
source/blender/editors/uvedit/uvedit_parametrizer.h
source/blender/editors/uvedit/uvedit_unwrap_ops.c
source/blender/makesdna/DNA_meshdata_types.h

index 216ac61b628b4c90ebc857008ed78a9dc1e690e0..05bfc8d4a2e3785c6c5a1e47a60ad1c2d7c7b212 100644 (file)
@@ -196,7 +196,15 @@ void ED_uvedit_assign_image(Main *bmain, Scene *scene, Object *obedit, Image *im
        }
        else {
                /* old shading system, assign image to selected faces */
-               
+               float prev_aspect[2], fprev_aspect;
+               float aspect[2], faspect;
+
+               ED_image_uv_aspect(previma, prev_aspect, prev_aspect + 1);
+               ED_image_uv_aspect(ima, aspect, aspect + 1);
+
+               fprev_aspect = prev_aspect[0]/prev_aspect[1];
+               faspect = aspect[0]/aspect[1];
+
                /* ensure we have a uv map */
                if (!CustomData_has_layer(&em->bm->pdata, CD_MTEXPOLY)) {
                        BM_data_layer_add(em->bm, &em->bm->pdata, CD_MTEXPOLY);
@@ -214,6 +222,19 @@ void ED_uvedit_assign_image(Main *bmain, Scene *scene, Object *obedit, Image *im
                                        
                                        if (ima->id.us == 0) id_us_plus(&ima->id);
                                        else id_lib_extern(&ima->id);
+
+                                       /* we also need to correct the aspect of uvs */
+                                       if(tf->unwrap & TF_CORRECT_ASPECT) {
+                                               BMIter liter;
+                                               BMLoop *l;
+
+                                               BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
+                                                       MLoopUV *luv = CustomData_bmesh_get(&em->bm->ldata, l->head.data, CD_MLOOPUV);
+
+                                                       luv->uv[0] *= fprev_aspect;
+                                                       luv->uv[0] /= faspect;
+                                               }
+                                       }
                                }
                                else {
                                        tf->tpage = NULL;
index 87ff36ebf27eac513d86d3b2d7bbc287bb8a25f0..a2e276c09e36f4c448336ab14cef68269837427b 100644 (file)
@@ -145,6 +145,7 @@ typedef struct PFace {
 
        struct PEdge *edge;
        unsigned char flag;
+       short *unwrap_flag;
 
 } PFace;
 
@@ -232,8 +233,11 @@ typedef struct PHandle {
 
        RNG *rng;
        float blend;
+       char do_aspect;
 } PHandle;
 
+/* duplicate, to avoid including DNA_mesh_types.h */
+#define TF_CORRECT_ASPECT  256
 
 /* PHash
  * - special purpose hash that keeps all its elements in a single linked list.
@@ -646,6 +650,7 @@ static void p_vert_load_pin_select_uvs(PHandle *handle, PVert *v)
 static void p_flush_uvs(PHandle *handle, PChart *chart)
 {
        PEdge *e;
+       PFace *f;
 
        for (e = chart->edges; e; e = e->nextlink) {
                if (e->orig_uv) {
@@ -653,6 +658,16 @@ static void p_flush_uvs(PHandle *handle, PChart *chart)
                        e->orig_uv[1] = e->vert->uv[1] / handle->aspy;
                }
        }
+
+       for (f = chart->faces; f; f = f->nextlink) {
+               if(f->unwrap_flag) {
+                       if (handle->do_aspect) {
+                               *f->unwrap_flag |= TF_CORRECT_ASPECT;
+                       } else {
+                               *f->unwrap_flag &= ~TF_CORRECT_ASPECT;
+                       }
+               }
+       }
 }
 
 static void p_flush_uvs_blend(PHandle *handle, PChart *chart, float blend)
@@ -1042,6 +1057,7 @@ static PFace *p_face_add(PHandle *handle)
        /* allocate */
        f = (PFace *)BLI_memarena_alloc(handle->arena, sizeof *f);
        f->flag = 0; // init !
+       f->unwrap_flag = NULL;
 
        e1 = (PEdge *)BLI_memarena_alloc(handle->arena, sizeof *e1);
        e2 = (PEdge *)BLI_memarena_alloc(handle->arena, sizeof *e2);
@@ -1068,7 +1084,7 @@ static PFace *p_face_add(PHandle *handle)
 
 static PFace *p_face_add_construct(PHandle *handle, ParamKey key, ParamKey *vkeys,
                                    float *co[3], float *uv[3], int i1, int i2, int i3,
-                                   ParamBool *pin, ParamBool *select)
+                                   ParamBool *pin, ParamBool *select, short *unwrap_flag)
 {
        PFace *f = p_face_add(handle);
        PEdge *e1 = f->edge, *e2 = e1->next, *e3 = e2->next;
@@ -1095,6 +1111,7 @@ static PFace *p_face_add_construct(PHandle *handle, ParamKey key, ParamKey *vkey
 
        /* insert into hash */
        f->u.key = key;
+       f->unwrap_flag = unwrap_flag;
        phash_insert(handle->hash_faces, (PHashLink *)f);
 
        e1->u.key = PHASH_edge(vkeys[i1], vkeys[i2]);
@@ -4087,6 +4104,7 @@ ParamHandle *param_construct_begin(void)
        handle->arena = BLI_memarena_new((1 << 16), "param construct arena");
        handle->aspx = 1.0f;
        handle->aspy = 1.0f;
+       handle->do_aspect = FALSE;
 
        handle->hash_verts = phash_new((PHashLink **)&handle->construction_chart->verts, 1);
        handle->hash_edges = phash_new((PHashLink **)&handle->construction_chart->edges, 1);
@@ -4101,6 +4119,7 @@ void param_aspect_ratio(ParamHandle *handle, float aspx, float aspy)
 
        phandle->aspx = aspx;
        phandle->aspy = aspy;
+       phandle->do_aspect = TRUE;
 }
 
 void param_delete(ParamHandle *handle)
@@ -4131,7 +4150,7 @@ void param_delete(ParamHandle *handle)
 
 void param_face_add(ParamHandle *handle, ParamKey key, int nverts,
                     ParamKey *vkeys, float **co, float **uv,
-                    ParamBool *pin, ParamBool *select)
+                    ParamBool *pin, ParamBool *select, short *unwrap_flag)
 {
        PHandle *phandle = (PHandle *)handle;
 
@@ -4141,16 +4160,16 @@ void param_face_add(ParamHandle *handle, ParamKey key, int nverts,
 
        if (nverts == 4) {
                if (p_quad_split_direction(phandle, co, vkeys)) {
-                       p_face_add_construct(phandle, key, vkeys, co, uv, 0, 1, 2, pin, select);
-                       p_face_add_construct(phandle, key, vkeys, co, uv, 0, 2, 3, pin, select);
+                       p_face_add_construct(phandle, key, vkeys, co, uv, 0, 1, 2, pin, select, unwrap_flag);
+                       p_face_add_construct(phandle, key, vkeys, co, uv, 0, 2, 3, pin, select, unwrap_flag);
                }
                else {
-                       p_face_add_construct(phandle, key, vkeys, co, uv, 0, 1, 3, pin, select);
-                       p_face_add_construct(phandle, key, vkeys, co, uv, 1, 2, 3, pin, select);
+                       p_face_add_construct(phandle, key, vkeys, co, uv, 0, 1, 3, pin, select, unwrap_flag);
+                       p_face_add_construct(phandle, key, vkeys, co, uv, 1, 2, 3, pin, select, unwrap_flag);
                }
        }
        else if (!p_face_exists(phandle, vkeys, 0, 1, 2)) {
-               p_face_add_construct(phandle, key, vkeys, co, uv, 0, 1, 2, pin, select);
+               p_face_add_construct(phandle, key, vkeys, co, uv, 0, 1, 2, pin, select, unwrap_flag);
        }
 }
 
index 3c8863671911f419f5775f7b42e18bf3cb14e553..9a2fea0d7f9827505205dd293b6bcb908cf51b47 100644 (file)
@@ -62,7 +62,7 @@ void param_face_add(ParamHandle *handle,
                                        float **co,
                                        float **uv,
                                        ParamBool *pin,
-                                       ParamBool *select);
+                                       ParamBool *select, short *unwrap_flag);
 
 void param_edge_set_seam(ParamHandle *handle,
                                                 ParamKey *vkeys);
index 0930edbe46d3e5edb8dc200b66230528e4c97ce9..1def5caad87f1a73e5b10aa624a7e6fc6ae38684 100644 (file)
@@ -202,6 +202,8 @@ static ParamHandle *construct_param_handle(Scene *scene, BMEditMesh *em,
                
                        if (aspx != aspy)
                                param_aspect_ratio(handle, aspx, aspy);
+                       else
+                               param_aspect_ratio(handle, 1.0, 1.0);
                }
        }
        
@@ -211,6 +213,7 @@ static ParamHandle *construct_param_handle(Scene *scene, BMEditMesh *em,
        BLI_srand(0);
        
        BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
+               MTexPoly *tf;
                ScanFillVert *sf_vert, *sf_vert_last, *sf_vert_first;
                ScanFillFace *sf_tri;
                ParamKey key, vkeys[4];
@@ -237,6 +240,7 @@ static ParamHandle *construct_param_handle(Scene *scene, BMEditMesh *em,
 
                key = (ParamKey)efa;
 
+               tf = CustomData_bmesh_get(&em->bm->pdata, efa->head.data, CD_MTEXPOLY);
 
                if (efa->len == 3 || efa->len == 4) {
                        /* for quads let parametrize split, it can make better decisions
@@ -253,7 +257,7 @@ static ParamHandle *construct_param_handle(Scene *scene, BMEditMesh *em,
                                i++;
                        }
 
-                       param_face_add(handle, key, i, vkeys, co, uv, pin, select);
+                       param_face_add(handle, key, i, vkeys, co, uv, pin, select, &tf->unwrap);
                }
                else {
                        /* ngon - scanfill time! */
@@ -298,7 +302,7 @@ static ParamHandle *construct_param_handle(Scene *scene, BMEditMesh *em,
                                        select[i] = uvedit_uv_select_test(em, scene, ls[i]) != 0;
                                }
 
-                               param_face_add(handle, key, 3, vkeys, co, uv, pin, select);
+                               param_face_add(handle, key, 3, vkeys, co, uv, pin, select, &tf->unwrap);
                        }
 
                        BLI_scanfill_end(&sf_ctx);
@@ -388,6 +392,8 @@ static ParamHandle *construct_param_handle_subsurfed(Scene *scene, BMEditMesh *e
 
                        if (aspx != aspy)
                                param_aspect_ratio(handle, aspx, aspy);
+                       else
+                               param_aspect_ratio(handle, 1.0, 1.0);
                }
        }
 
@@ -440,7 +446,8 @@ static ParamHandle *construct_param_handle_subsurfed(Scene *scene, BMEditMesh *e
                float *co[4];
                float *uv[4];
                BMFace *origFace = faceMap[i];
-               
+               MTexPoly *tf;
+
                face = subsurfedFaces + i;
 
                if (scene->toolsettings->uv_flag & UV_SYNC_SELECTION) {
@@ -452,6 +459,8 @@ static ParamHandle *construct_param_handle_subsurfed(Scene *scene, BMEditMesh *e
                                continue;
                }
 
+               tf = CustomData_bmesh_get(&em->bm->pdata, origFace->head.data, CD_MTEXPOLY);
+
                /* We will not check for v4 here. Subsurfed mfaces always have 4 vertices. */
                key = (ParamKey)face;
                vkeys[0] = (ParamKey)face->v1;
@@ -471,7 +480,7 @@ static ParamHandle *construct_param_handle_subsurfed(Scene *scene, BMEditMesh *e
                texface_from_original_index(origFace, origVertIndices[face->v3], &uv[2], &pin[2], &select[2], scene, em);
                texface_from_original_index(origFace, origVertIndices[face->v4], &uv[3], &pin[3], &select[3], scene, em);
 
-               param_face_add(handle, key, 4, vkeys, co, uv, pin, select);
+               param_face_add(handle, key, 4, vkeys, co, uv, pin, select, &tf->unwrap);
        }
 
        /* these are calculated from original mesh too */
index 5806d9a394779f04b35cce8dff09dc198a69f116..9ae2bec583dfb22ccad51d21b3dae33609d32923 100644 (file)
@@ -360,13 +360,14 @@ typedef struct MVertSkin {
 
 
 /* mtface->unwrap */
-#define TF_DEPRECATED1 1
-#define TF_DEPRECATED2 2
-#define TF_DEPRECATED3 4
-#define TF_DEPRECATED4 8
-#define TF_PIN1                    16
-#define TF_PIN2                    32
-#define TF_PIN3                        64
-#define TF_PIN4                128
+#define TF_DEPRECATED1     1
+#define TF_DEPRECATED2     2
+#define TF_DEPRECATED3     4
+#define TF_DEPRECATED4     8
+#define TF_PIN1            16
+#define TF_PIN2                   32
+#define TF_PIN3                       64
+#define TF_PIN4                   128
+#define TF_CORRECT_ASPECT  256
 
 #endif