More work on the new unwrapper code (orange branch):
authorBrecht Van Lommel <brechtvanlommel@pandora.be>
Sat, 3 Dec 2005 23:22:31 +0000 (23:22 +0000)
committerBrecht Van Lommel <brechtvanlommel@pandora.be>
Sat, 3 Dec 2005 23:22:31 +0000 (23:22 +0000)
- There is now a (temporary) dropdown box in the image window header for
  switching between the old an new unwrapper code. So to test the changes
  described below you need to enable the new unwrapper code.
- Pinning is now more predictable, if one uv is pinned, the others belonging
  to the same vertex are pinned also.
- Live LSCM is much faster, since the LU factorization, the most expensive
  part of the computation, is now stored and reused (was Jens' idea).
- Packing multiple uv charts is slightly improved, by doing a binary search
  over the texture width. This fixes the case where all the charts are
  packed at the bottom of the image.
- LSCM now uses an angle based formulation, and the results seem somewhat
  different (maybe slightly better?), didn't find out why yet.

intern/opennl/intern/opennl.c
source/blender/include/BDR_unwrapper.h
source/blender/src/header_image.c
source/blender/src/parametrizer.c
source/blender/src/parametrizer.h
source/blender/src/parametrizer_intern.h
source/blender/src/transform_conversions.c
source/blender/src/transform_generics.c
source/blender/src/unwrapper.c

index ad40f45c73a7d36e41bb4a24b0883250b11f66b4..c5518731c6bccf3e106cebbde1ad36d9715ad2f8 100644 (file)
@@ -808,7 +808,7 @@ static void __nlBeginMatrix() {
        }
        else {
                /* need to recompute b only, A is not constructed anymore */
-               __NL_CLEAR_ARRAY(NLfloat, __nlCurrentContext->b, n);
+               __NL_CLEAR_ARRAY(NLfloat, __nlCurrentContext->b, __nlCurrentContext->n);
        }
 
        __nlVariablesToVector();
@@ -871,12 +871,11 @@ static void __nlEndRow() {
                }
 
                S = -__nlCurrentContext->right_hand_side;
-               for(j=0; j<nl; j++) {
+               for(j=0; j<nl; j++)
                        S += al->coeff[j].value;
-               }
-               for(i=0; i<nf; i++) {
+
+               for(i=0; i<nf; i++)
                        b[ af->coeff[i].index ] -= af->coeff[i].value * S;
-               }
        } else {
                if (!__nlCurrentContext->solve_again) {
                        for(i=0; i<nf; i++) {
@@ -1110,12 +1109,13 @@ static void __nlFree_SUPERLU(__NLContext *context) {
 
 void nlPrintMatrix(void) {
        __NLSparseMatrix* M  = &(__nlCurrentContext->M);
+       float *b = __nlCurrentContext->b;
        NLuint i, jj, k;
        NLuint n = __nlCurrentContext->n;
        __NLRowColumn* Ri = NULL;
        float *value = malloc(sizeof(*value)*n);
 
-       printf("M:\n");
+       printf("A:\n");
        for(i=0; i<n; i++) {
                Ri = &(M->row[i]);
 
@@ -1127,6 +1127,13 @@ void nlPrintMatrix(void) {
                        printf("%.3f ", value[k]);
                printf("\n");
        }
+
+       printf("b:\n");
+       for(i=0; i<n; i++)
+               printf("%f ", b[i]);
+       printf("\n");
+
+       free(value);
 }
 
 /************************************************************************/
index e853b48bc9d08907fce9f74a5a0295addc54b8cd..f8c73dfdea2a67f6b2c5720ab163a1a80e7a94da 100644 (file)
 #define BDR_UNWRAPPER_H
 
 void set_seamtface(void); /* set TF_SEAM flags in tfaces */
-void unwrap_lscm(void); /* unwrap selected tfaces */
-void unwrap_lscm_live(void); /* unwrap selected tfaces (for live mode, with no undo pushes) */
 void select_linked_tfaces_with_seams(int mode, Mesh *me, unsigned int index);
-void minimize_stretch_tface_uv(void);
+
+void unwrap_lscm(void); /* unwrap faces selected in 3d view */
+void unwrap_lscm_new(void);
+void minimize_stretch_tface_uv(void); /* optimize faces selected in uv editor */
+
+/* for live mode: no undo pushes, caching for quicky re-unwrap */
+void unwrap_lscm_live_begin(void);
+void unwrap_lscm_live_re_solve(void);
+void unwrap_lscm_live_end(void);
 
 #endif /* BDR_UNWRAPPER_H */
 
index 9d12e417d020f1d2da649c0e28c53c97de6df658..35e7c8e577f610643ac36864415431f477435544 100644 (file)
@@ -1103,6 +1103,7 @@ void image_buttons(void)
        char naam[256];
        /* This should not be a static var */
        static int headerbuttons_packdummy;
+       extern short CurrentUnwrapper;
 
        headerbuttons_packdummy = 0;
                
@@ -1180,6 +1181,9 @@ void image_buttons(void)
 
        /* draw LOCK */
        uiDefIconButS(block, ICONTOG, 0, ICON_UNLOCKED, xco,0,XIC,YIC, &(G.sima->lock), 0, 0, 0, 0, "Updates other affected window spaces automatically to reflect changes in real time");
+
+       xco += 2*XIC;
+       uiDefButS(block, MENU, B_NOP, "Unwrapper%t|Old LSCM%x0|New LSCM%x1",xco,0,85,YIC, &CurrentUnwrapper, 0, 0, 0, 0, "Unwrapper");
        
        /* Always do this last */
        curarea->headbutlen= xco+2*XIC;
index 32e8f6ac18736b90618f82a11e7568588171d875..9ee7d3f5daf085e0cb7ec759bd69206c04649c8d 100644 (file)
@@ -359,7 +359,7 @@ static void p_face_flip(PFace *f)
        e3->flag = (f3 & ~PEDGE_VERTEX_FLAGS) | (f1 & PEDGE_VERTEX_FLAGS);
 }
 
-static void p_vert_load_pin_uvs(PVert *v)
+static void p_vert_load_pin_select_uvs(PVert *v)
 {
        PEdge *e;
        int nedges = 0;
@@ -369,6 +369,9 @@ static void p_vert_load_pin_uvs(PVert *v)
        e = v->edge;
        do {
                if (e->orig_uv && (e->flag & PEDGE_PIN)) {
+                       if (e->flag & PEDGE_SELECT)
+                               v->flag |= PVERT_SELECT;
+
                        v->flag |= PVERT_PIN;
                        v->uv[0] += e->orig_uv[0];
                        v->uv[1] += e->orig_uv[1];
@@ -451,10 +454,20 @@ static void p_extrema_verts(PChart *chart, PVert **v1, PVert **v2)
                PFace *f = (PFace*)chart->faces->first;
                *v1 = f->edge->vert;
                *v2 = f->edge->next->vert;
+
+               (*v1)->uv[0] = 0.0f;
+               (*v1)->uv[1] = 0.5f;
+               (*v2)->uv[0] = 1.0f;
+               (*v2)->uv[1] = 0.5f;
        }
        else {
                *v1 = minvert[dir];
                *v2 = maxvert[dir];
+
+               (*v1)->uv[0] = (*v1)->co[dir];
+               (*v1)->uv[1] = (*v1)->co[(dir+1)%3];
+               (*v2)->uv[0] = (*v2)->co[dir];
+               (*v2)->uv[1] = (*v2)->co[(dir+1)%3];
        }
 }
 
@@ -1193,7 +1206,7 @@ void param_face_add(ParamHandle *handle, ParamKey key, int nverts,
        param_assert((nverts == 3) || (nverts == 4));
 
        if (nverts == 4) {
-               if (p_quad_split_direction(co)) {
+               if (!p_quad_split_direction(co)) {
                        p_face_add(chart, key, vkeys, co, uv, 0, 1, 2, pin, select);
                        p_face_add(chart, key, vkeys, co, uv, 0, 2, 3, pin, select);
                }
@@ -1237,15 +1250,18 @@ void param_construct_end(ParamHandle *handle, ParamBool fill, ParamBool impl)
        for (i = j = 0; i < phandle->ncharts; i++) {
                p_chart_boundaries(phandle->charts[i], &nboundaries, &outer);
 
-               if (nboundaries > 0) {
-                       phandle->charts[j] = phandle->charts[i];
-                       j++;
-
-                       if (fill && (nboundaries > 1))
-                               p_chart_fill_boundaries(phandle->charts[i], outer);
-               }
-               else
+               if (nboundaries == 0) {
                        p_chart_delete(phandle->charts[i]);
+                       continue;
+               }
+
+               phandle->charts[j] = phandle->charts[i];
+               j++;
+
+#if 0
+               if (fill && (nboundaries > 1))
+                       p_chart_fill_boundaries(phandle->charts[i], outer);
+#endif
        }
 
        phandle->ncharts = j;
@@ -1257,54 +1273,54 @@ void param_construct_end(ParamHandle *handle, ParamBool fill, ParamBool impl)
 
 static void p_chart_lscm_load_solution(PChart *chart)
 {
-       PVert *pin = chart->u.lscm.singlepin, *v;
-       float translation[2];
-
-       if (pin) {
-               translation[0] = pin->uv[0] - nlGetVariable(2*pin->u.index);
-               translation[1] = pin->uv[1] - nlGetVariable(2*pin->u.index + 1);
-       }
-       else
-               translation[0] = translation[1] = 0.0f;
+       PVert *v;
 
        for (v=(PVert*)chart->verts->first; v; v=v->link.next) {
-               v->uv[0] = nlGetVariable(2*v->u.index) + translation[0];
-               v->uv[1] = nlGetVariable(2*v->u.index + 1) + translation[1];
+               v->uv[0] = nlGetVariable(2*v->u.index);
+               v->uv[1] = nlGetVariable(2*v->u.index + 1);
        }
 }
 
-static void p_chart_lscm_begin(PChart *chart)
+static void p_chart_lscm_begin(PChart *chart, PBool live)
 {
        PVert *v, *pin1, *pin2;
+       PBool select = P_FALSE;
        int npins = 0, id = 0;
 
-       nlNewContext();
-       nlSolverParameteri(NL_NB_VARIABLES, 2*phash_size(chart->verts));
-       nlSolverParameteri(NL_LEAST_SQUARES, NL_TRUE);
-
        /* give vertices matrix indices and count pins */
        for (v=(PVert*)chart->verts->first; v; v=v->link.next) {
-               p_vert_load_pin_uvs(v);
+               p_vert_load_pin_select_uvs(v);
 
-               if (v->flag & PVERT_PIN) {
+               if (v->flag & PVERT_PIN)
                        npins++;
-                       chart->u.lscm.singlepin = v;
-               }
+
+               if (v->flag & PVERT_SELECT)
+                       select = P_TRUE;
 
                v->u.index = id++;
        }
 
-       if (npins <= 1) {
-               /* not enough pins, lets find some ourself */
-               p_extrema_verts(chart, &pin1, &pin2);
-
-               chart->u.lscm.pin1 = pin1;
-               chart->u.lscm.pin2 = pin2;
+       if ((live && !select) || (npins == 1)) {
+               chart->u.lscm.context = NULL;
        }
-       else
-               chart->u.lscm.singlepin = NULL;
+       else {
+               if (npins <= 1) {
+                       /* not enough pins, lets find some ourself */
+                       p_extrema_verts(chart, &pin1, &pin2);
 
-       chart->u.lscm.context = nlGetCurrent();
+                       chart->u.lscm.pin1 = pin1;
+                       chart->u.lscm.pin2 = pin2;
+               }
+               else {
+                       chart->flag |= PCHART_NOPACK;
+               }
+
+               nlNewContext();
+               nlSolverParameteri(NL_NB_VARIABLES, 2*phash_size(chart->verts));
+               nlSolverParameteri(NL_LEAST_SQUARES, NL_TRUE);
+
+               chart->u.lscm.context = nlGetCurrent();
+       }
 }
 
 static PBool p_chart_lscm_solve(PChart *chart)
@@ -1316,16 +1332,20 @@ static PBool p_chart_lscm_solve(PChart *chart)
 
        nlBegin(NL_SYSTEM);
 
+       for (v=(PVert*)chart->verts->first; v; v=v->link.next)
+               if (v->flag & PVERT_PIN)
+                       p_vert_load_pin_select_uvs(v);
+
        if (chart->u.lscm.pin1) {
                nlLockVariable(2*pin1->u.index);
                nlLockVariable(2*pin1->u.index + 1);
                nlLockVariable(2*pin2->u.index);
                nlLockVariable(2*pin2->u.index + 1);
        
-               nlSetVariable(2*pin1->u.index, 0.0f);
-               nlSetVariable(2*pin1->u.index + 1, 0.5f);
-               nlSetVariable(2*pin2->u.index, 1.0f);
-               nlSetVariable(2*pin2->u.index + 1, 0.5f);
+               nlSetVariable(2*pin1->u.index, pin1->uv[0]);
+               nlSetVariable(2*pin1->u.index + 1, pin1->uv[1]);
+               nlSetVariable(2*pin2->u.index, pin2->uv[0]);
+               nlSetVariable(2*pin2->u.index + 1, pin2->uv[1]);
        }
        else {
                /* set and lock the pins */
@@ -1382,7 +1402,7 @@ static PBool p_chart_lscm_solve(PChart *chart)
                }
 
                /* angle based lscm formulation */
-               ratio = sina2/sina3;
+               ratio = (sina3 == 0.0f)? 0.0f: sina2/sina3;
                cosine = cos(a1)*ratio;
                sine = sina1*ratio;
 
@@ -1409,8 +1429,6 @@ static PBool p_chart_lscm_solve(PChart *chart)
 
        if (nlSolveAdvanced(NULL, NL_TRUE)) {
                p_chart_lscm_load_solution(chart);
-               p_flush_uvs(chart);
-
                return P_TRUE;
        }
 
@@ -1423,12 +1441,11 @@ static void p_chart_lscm_end(PChart *chart)
                nlDeleteContext(chart->u.lscm.context);
 
        chart->u.lscm.context = NULL;
-       chart->u.lscm.singlepin = NULL;
        chart->u.lscm.pin1 = NULL;
        chart->u.lscm.pin2 = NULL;
 }
 
-void param_lscm_begin(ParamHandle *handle)
+void param_lscm_begin(ParamHandle *handle, ParamBool live)
 {
        PHandle *phandle = (PHandle*)handle;
        int i;
@@ -1437,7 +1454,7 @@ void param_lscm_begin(ParamHandle *handle)
        phandle->state = PHANDLE_STATE_LSCM;
 
        for (i = 0; i < phandle->ncharts; i++)
-               p_chart_lscm_begin(phandle->charts[i]);
+               p_chart_lscm_begin(phandle->charts[i], live);
 }
 
 void param_lscm_solve(ParamHandle *handle)
@@ -1651,6 +1668,14 @@ void param_stretch_begin(ParamHandle *handle)
 }
 
 void param_stretch_blend(ParamHandle *handle, float blend)
+{
+       PHandle *phandle = (PHandle*)handle;
+
+       param_assert(phandle->state == PHANDLE_STATE_STRETCH);
+       phandle->blend = blend;
+}
+
+void param_stretch_iter(ParamHandle *handle)
 {
        PHandle *phandle = (PHandle*)handle;
        PChart *chart;
@@ -1658,32 +1683,36 @@ void param_stretch_blend(ParamHandle *handle, float blend)
 
        param_assert(phandle->state == PHANDLE_STATE_STRETCH);
 
-       if (phandle->blend != blend) {
-               phandle->blend = blend;
+       for (i = 0; i < phandle->ncharts; i++) {
+               chart = phandle->charts[i];
+               p_chart_stretch_minimize(chart, phandle->rng);
+       }
+}
+
+void param_stretch_end(ParamHandle *handle)
+{
+       PHandle *phandle = (PHandle*)handle;
 
-               for (i = 0; i < phandle->ncharts; i++) {
-                       chart = phandle->charts[i];
+       param_assert(phandle->state == PHANDLE_STATE_STRETCH);
+       phandle->state = PHANDLE_STATE_CONSTRUCTED;
 
-                       if (blend == 0.0f)
-                               p_flush_uvs(chart);
-                       else
-                               p_flush_uvs_blend(chart, blend);
-               }
-       }
+       rng_free(phandle->rng);
+       phandle->rng = NULL;
 }
 
-void param_stretch_iter(ParamHandle *handle)
+/* Flushing */
+
+void param_flush(ParamHandle *handle)
 {
        PHandle *phandle = (PHandle*)handle;
        PChart *chart;
        int i;
 
-       param_assert(phandle->state == PHANDLE_STATE_STRETCH);
-
        for (i = 0; i < phandle->ncharts; i++) {
                chart = phandle->charts[i];
 
-               p_chart_stretch_minimize(chart, phandle->rng);
+               if ((phandle->state == PHANDLE_STATE_LSCM) && !chart->u.lscm.context)
+                       continue;
 
                if (phandle->blend == 0.0f)
                        p_flush_uvs(chart);
@@ -1692,31 +1721,36 @@ void param_stretch_iter(ParamHandle *handle)
        }
 }
 
-void param_stretch_end(ParamHandle *handle, ParamBool restore)
+void param_flush_restore(ParamHandle *handle)
 {
        PHandle *phandle = (PHandle*)handle;
        PChart *chart;
        PFace *f;
        int i;
 
-       param_assert(phandle->state == PHANDLE_STATE_STRETCH);
-       phandle->state = PHANDLE_STATE_CONSTRUCTED;
-
-       rng_free(phandle->rng);
-       phandle->rng = NULL;
-
-       if (restore) {
-               for (i = 0; i < phandle->ncharts; i++) {
-                       chart = phandle->charts[i];
+       for (i = 0; i < phandle->ncharts; i++) {
+               chart = phandle->charts[i];
 
-                       for (f=(PFace*)chart->faces->first; f; f=f->link.next)
-                               p_face_restore_uvs(f);
-               }
+               for (f=(PFace*)chart->faces->first; f; f=f->link.next)
+                       p_face_restore_uvs(f);
        }
 }
 
 /* Packing */
 
+static int compare_chart_area(const void *a, const void *b)
+{
+       PChart *ca = *((PChart**)a);
+       PChart *cb = *((PChart**)b);
+
+    if (ca->u.pack.area > cb->u.pack.area)
+               return -1;
+       else if (ca->u.pack.area == cb->u.pack.area)
+               return 0;
+       else
+               return 1;
+}
+
 static PBool p_pack_try(PHandle *handle, float side)
 {
        PChart *chart;
@@ -1729,10 +1763,14 @@ static PBool p_pack_try(PHandle *handle, float side)
 
        for (i = 0; i < handle->ncharts; i++) {
                chart = handle->charts[i];
+
+               if (chart->flag & PCHART_NOPACK)
+                       continue;
+
                w = chart->u.pack.size[0];
                h = chart->u.pack.size[1];
 
-               if(w <= (1.0-packx)) {
+               if(w <= (side-packx)) {
                        chart->u.pack.trans[0] = packx;
                        chart->u.pack.trans[1] = packy;
 
@@ -1748,14 +1786,14 @@ static PBool p_pack_try(PHandle *handle, float side)
                        chart->u.pack.trans[1] = packy;
                }
 
-               if (rowh > side)
+               if (packy+rowh > side)
                        return P_FALSE;
        }
 
        return P_TRUE;
 }
 
-#define PACK_SEARCH_DEPTH 7
+#define PACK_SEARCH_DEPTH 15
 
 void param_pack(ParamHandle *handle)
 {
@@ -1775,48 +1813,62 @@ void param_pack(ParamHandle *handle)
        for (i = 0; i < phandle->ncharts; i++) {
                chart = phandle->charts[i];
 
-               p_chart_area(chart, &uv_area, &area);
-               chart->u.pack.rescale = (uv_area > 0.0f)? area/uv_area: 0.0f;
-               totarea += uv_area*chart->u.pack.rescale;
+               if (chart->flag & PCHART_NOPACK) {
+                       chart->u.pack.area = 0.0f;
+                       continue;
+               }
 
+               p_chart_area(chart, &uv_area, &area);
                p_chart_uv_bbox(chart, trans, chart->u.pack.size);
+
+               /* translate to origin and make area equal to 3d area */
+               chart->u.pack.rescale = (uv_area > 0.0f)? sqrt(area)/sqrt(uv_area): 0.0f;
+               chart->u.pack.area = area;
+               totarea += area;
+
                trans[0] = -trans[0];
                trans[1] = -trans[1];
                p_chart_uv_translate(chart, trans);
                p_chart_uv_scale(chart, chart->u.pack.rescale);
 
-               chart->u.pack.size[0] -= trans[0];
-               chart->u.pack.size[1] -= trans[1];
+               /* compute new dimensions for packing */
+               chart->u.pack.size[0] += trans[0];
+               chart->u.pack.size[1] += trans[1];
                chart->u.pack.size[0] *= chart->u.pack.rescale;
                chart->u.pack.size[1] *= chart->u.pack.rescale;
 
                maxside = MAX3(maxside, chart->u.pack.size[0], chart->u.pack.size[1]);
        }
 
-       return;
-
-       printf("%f\n", maxside);
+       /* sort by chart area, largest first */
+       qsort(phandle->charts, phandle->ncharts, sizeof(PChart*), compare_chart_area);
 
        /* binary search over pack region size */
-       minside = sqrt(totarea);
+       minside = MAX2(sqrt(totarea), maxside);
        maxside = (((int)sqrt(phandle->ncharts-1))+1)*maxside;
 
-       for (i = 0; i < PACK_SEARCH_DEPTH; i++) {
-               printf("%f %f\n", minside, maxside);
-               if (p_pack_try(phandle, (minside+maxside)*0.5f))
-                       minside = (minside+maxside)*0.5f;
-               else
-                       maxside = (minside+maxside)*0.5f;
+       if (minside < maxside) { /* should always be true */
+
+               for (i = 0; i < PACK_SEARCH_DEPTH; i++) {
+                       if (p_pack_try(phandle, (minside+maxside)*0.5f + 1e-5))
+                               maxside = (minside+maxside)*0.5f;
+                       else
+                               minside = (minside+maxside)*0.5f;
+               }
        }
 
-       side = maxside + 1e-5; /* prevent floating point errors */
+       /* do the actual packing */
+       side = maxside + 1e-5;
        if (!p_pack_try(phandle, side))
-               printf("impossible\n");
+               param_warning("packing failed.\n");
 
        for (i = 0; i < phandle->ncharts; i++) {
                chart = phandle->charts[i];
 
-               p_chart_uv_scale(chart, chart->u.pack.rescale/side);
+               if (chart->flag & PCHART_NOPACK)
+                       continue;
+
+               p_chart_uv_scale(chart, 1.0f/side);
                trans[0] = chart->u.pack.trans[0]/side;
                trans[1] = chart->u.pack.trans[1]/side;
                p_chart_uv_translate(chart, trans);
index 614eef2fbf78d4d97d74804287af5154bc57ac68..38bad0e60927388f9ade9737d14b241bd6479ee1 100644 (file)
@@ -52,7 +52,7 @@ void param_delete(ParamHandle *chart);
          quick re-solving
 */
 
-void param_lscm_begin(ParamHandle *handle);
+void param_lscm_begin(ParamHandle *handle, ParamBool live);
 void param_lscm_solve(ParamHandle *handle);
 void param_lscm_end(ParamHandle *handle);
 
@@ -61,11 +61,17 @@ void param_lscm_end(ParamHandle *handle);
 void param_stretch_begin(ParamHandle *handle);
 void param_stretch_blend(ParamHandle *handle, float blend);
 void param_stretch_iter(ParamHandle *handle);
-void param_stretch_end(ParamHandle *handle, ParamBool restore);
+void param_stretch_end(ParamHandle *handle);
 
 /* Packing */
+
 void param_pack(ParamHandle *handle);
 
+/* Flushing */
+
+void param_flush(ParamHandle *handle);
+void param_flush_restore(ParamHandle *handle);
+
 #ifdef __cplusplus
 }
 #endif
index d873c1dab47232d17622eb9ab08b0b81bcad744a..f22a7e4ab66110a4c8bd01a941c3e29cdf85f648 100644 (file)
@@ -39,7 +39,7 @@ PHashLink *phash_next(PHash *ph, PHashKey key, PHashLink *link);
                if (!(condition)) \
                        { printf("Assertion %s:%d\n", __FILE__, __LINE__); abort(); }
        #define param_warning(message) \
-               { printf("Warning %s:%d: %s\n", __FILE__, __LINE__, message);
+               { printf("Warning %s:%d: %s\n", __FILE__, __LINE__, message); }
 #endif
 
 typedef enum PBool {
@@ -153,18 +153,22 @@ typedef struct PChart {
                struct PChartLscm {
                        NLContext context;
                        float *abf_alpha;
-                       PVert *singlepin;
                        PVert *pin1, *pin2;
                } lscm;
                struct PChartPack {
-                       float rescale;
+                       float rescale, area;
                        float size[2], trans[2];
                } pack;
        } u;
 
+       int flag;
        struct PHandle *handle;
 } PChart;
 
+enum PChartFlag {
+       PCHART_NOPACK = 1
+};
+
 enum PHandleState {
        PHANDLE_STATE_ALLOCATED,
        PHANDLE_STATE_CONSTRUCTED,
index 6d834129c67bca6722185df45b55a394cb50c352..9720bdceebeead472420615c6898a009d3e6764d 100755 (executable)
@@ -1733,6 +1733,9 @@ static void createTransUVs(TransInfo *t)
                                UVsToTransData(td++, td2d++, tf->uv[3], (tf->flag & TF_SEL4));
                }
        }
+
+       if (G.sima->flag & SI_LSCM_LIVE)
+               unwrap_lscm_live_begin();
 }
 
 void flushTransUVs(TransInfo *t)
index 78aa7fe6122de5a60c124836511b5bf52c022c4b..3352a95ab77ad3362e089dd832df68bc0e9ee12f 100755 (executable)
@@ -300,7 +300,8 @@ void recalcData(TransInfo *t)
        }
        else if(t->spacetype==SPACE_IMAGE) {
                flushTransUVs(t);
-               if (G.sima->flag & SI_LSCM_LIVE) unwrap_lscm_live();
+               if (G.sima->flag & SI_LSCM_LIVE)
+                       unwrap_lscm_live_re_solve();
        }
        else {
                for(base= FIRSTBASE; base; base= base->next) {
@@ -481,6 +482,9 @@ void postTrans (TransInfo *t)
                MEM_freeN(t->data2d);
                t->data2d= NULL;
        }
+
+       if (G.sima->flag & SI_LSCM_LIVE)
+               unwrap_lscm_live_end();
 }
 
 static void apply_grid3(TransInfo *t, float *val, int max_index, float fac1, float fac2, float fac3)
index b74181cb385148746d48e048de8be5d728fd4d45..52f3fcc77f18e8438617fbb50dcadb8dd854d674 100644 (file)
@@ -67,6 +67,8 @@
 
 #include "parametrizer.h"
 
+short CurrentUnwrapper = 0;
+
 /* Implementation Least Squares Conformal Maps parameterization, based on
  * chapter 2 of:
  * Bruno Levy, Sylvain Petitjean, Nicolas Ray, Jerome Maillot. Least Squares
@@ -1140,6 +1142,11 @@ void unwrap_lscm(void)
        int res;
        Mesh *me;
        int totgroup, *groups=NULL, a;
+
+       if (CurrentUnwrapper == 1) {
+               unwrap_lscm_new();
+               return;
+       }
        
        me= get_mesh(OBACT);
        if(me==0 || me->tface==0) return;
@@ -1385,9 +1392,9 @@ ParamHandle *construct_param_handle(Mesh *me, short implicit, short fill)
                uv[1] = tf->uv[1];
                uv[2] = tf->uv[2];
 
-               pin[0] = ((tf->flag & TF_PIN1) != 0);
-               pin[1] = ((tf->flag & TF_PIN2) != 0);
-               pin[2] = ((tf->flag & TF_PIN3) != 0);
+               pin[0] = ((tf->unwrap & TF_PIN1) != 0);
+               pin[1] = ((tf->unwrap & TF_PIN2) != 0);
+               pin[2] = ((tf->unwrap & TF_PIN3) != 0);
 
                select[0] = ((tf->flag & TF_SEL1) != 0);
                select[1] = ((tf->flag & TF_SEL2) != 0);
@@ -1397,7 +1404,7 @@ ParamHandle *construct_param_handle(Mesh *me, short implicit, short fill)
                        vkeys[3] = (ParamKey)mf->v4;
                        co[3] = (mv+mf->v4)->co;
                        uv[3] = tf->uv[3];
-                       pin[3] = ((tf->flag & TF_PIN4) != 0);
+                       pin[3] = ((tf->unwrap & TF_PIN4) != 0);
                        select[3] = ((tf->flag & TF_SEL4) != 0);
                        nverts = 4;
                }
@@ -1424,8 +1431,7 @@ ParamHandle *construct_param_handle(Mesh *me, short implicit, short fill)
        return handle;
 }
 
-#if 0
-void unwrap_lscm(void)
+void unwrap_lscm_new(void)
 {
        Mesh *me;
        ParamHandle *handle;
@@ -1435,11 +1441,12 @@ void unwrap_lscm(void)
 
        handle = construct_param_handle(me, 0, 1);
 
-       param_lscm_begin(handle);
+       param_lscm_begin(handle, PARAM_FALSE);
        param_lscm_solve(handle);
        param_lscm_end(handle);
 
        param_pack(handle);
+       param_flush(handle);
 
        param_delete(handle);
 
@@ -1450,7 +1457,6 @@ void unwrap_lscm(void)
        allqueue(REDRAWVIEW3D, 0);
        allqueue(REDRAWIMAGE, 0);
 }
-#endif
 
 void minimize_stretch_tface_uv(void)
 {
@@ -1488,6 +1494,7 @@ void minimize_stretch_tface_uv(void)
                                                if (blend < 10) {
                                                        blend++;
                                                        param_stretch_blend(handle, blend*0.1f);
+                                                       param_flush(handle);
                                                        lasttime = 0.0f;
                                                }
                                                break;
@@ -1496,6 +1503,7 @@ void minimize_stretch_tface_uv(void)
                                                if (blend > 0) {
                                                        blend--;
                                                        param_stretch_blend(handle, blend*0.1f);
+                                                       param_flush(handle);
                                                        lasttime = 0.0f;
                                                }
                                                break;
@@ -1513,6 +1521,8 @@ void minimize_stretch_tface_uv(void)
                if (PIL_check_seconds_timer() - lasttime > 0.5) {
                        char str[100];
 
+                       param_flush(handle);
+
                        sprintf(str, "Stretch minimize. Blend %.2f.", blend*0.1f);
                        headerprint(str);
 
@@ -1522,7 +1532,12 @@ void minimize_stretch_tface_uv(void)
                }
        }
 
-       param_stretch_end(handle, escape);
+       if (escape)
+               param_flush_restore(handle);
+       else
+               param_flush(handle);
+
+       param_stretch_end(handle);
 
        param_delete(handle);
 
@@ -1534,3 +1549,47 @@ void minimize_stretch_tface_uv(void)
        allqueue(REDRAWIMAGE, 0);
 }
 
+/* LSCM live mode */
+
+static ParamHandle *liveHandle = NULL;
+
+void unwrap_lscm_live_begin(void)
+{
+       Mesh *me;
+
+       if (CurrentUnwrapper == 0)
+               return;
+       
+       me= get_mesh(OBACT);
+       if(me==0 || me->tface==0) return;
+
+       liveHandle = construct_param_handle(me, 0, 0);
+
+       param_lscm_begin(liveHandle, PARAM_TRUE);
+}
+
+void unwrap_lscm_live_re_solve(void)
+{
+       if (CurrentUnwrapper == 0) {
+               unwrap_lscm();
+               return;
+       }
+
+       if (liveHandle) {
+               param_lscm_solve(liveHandle);
+               param_flush(liveHandle);
+       }
+}
+       
+void unwrap_lscm_live_end(void)
+{
+       if (CurrentUnwrapper == 0)
+               return;
+
+       if (liveHandle) {
+               param_lscm_end(liveHandle);
+               param_delete(liveHandle);
+               liveHandle = NULL;
+       }
+}
+