~ubuntu-branches/ubuntu/intrepid/blender/intrepid-updates

« back to all changes in this revision

Viewing changes to source/blender/src/parametrizer.c

  • Committer: Bazaar Package Importer
  • Author(s): Cyril Brulebois
  • Date: 2008-08-08 02:45:40 UTC
  • mfrom: (12.1.14 intrepid)
  • Revision ID: james.westby@ubuntu.com-20080808024540-kkjp7ekfivzhuw3l
Tags: 2.46+dfsg-4
* Fix python syntax warning in import_dxf.py, which led to nasty output
  in installation/upgrade logs during byte-compilation, using a patch
  provided by the script author (Closes: #492280):
   - debian/patches/45_fix_python_syntax_warning

Show diffs side-by-side

added added

removed removed

Lines of Context:
5
5
#include "BLI_arithb.h"
6
6
#include "BLI_rand.h"
7
7
#include "BLI_heap.h"
 
8
#include "BLI_boxpack2d.h"
8
9
 
9
10
#include "BKE_utildefines.h"
10
11
 
144
145
        d2[1] = v3[1] - v2[1];
145
146
        d2[2] = v3[2] - v2[2];
146
147
 
147
 
        Normalise(d1);
148
 
        Normalise(d2);
 
148
        Normalize(d1);
 
149
        Normalize(d2);
149
150
 
150
151
        return d1[0]*d2[0] + d1[1]*d2[1] + d1[2]*d2[2];
151
152
}
211
212
                    ((v3->uv[0] - v1->uv[0])*(v2->uv[1] - v1->uv[1])));
212
213
}
213
214
 
214
 
static float p_face_uv_area(PFace *f)
215
 
{
216
 
        return fabs(p_face_uv_area_signed(f));
217
 
}
218
 
 
219
 
static void p_chart_area(PChart *chart, float *uv_area, float *area)
220
 
{
221
 
        PFace *f;
222
 
 
223
 
        *uv_area = *area = 0.0f;
224
 
 
225
 
        for (f=chart->faces; f; f=f->nextlink) {
226
 
                *uv_area += p_face_uv_area(f);
227
 
                *area += p_face_area(f);
228
 
        }
229
 
}
230
 
 
231
215
static float p_edge_length(PEdge *e)
232
216
{
233
217
    PVert *v1 = e->vert, *v2 = e->next->vert;
272
256
        }
273
257
}
274
258
 
 
259
static void p_chart_uv_scale_xy(PChart *chart, float x, float y)
 
260
{
 
261
        PVert *v;
 
262
 
 
263
        for (v=chart->verts; v; v=v->nextlink) {
 
264
                v->uv[0] *= x;
 
265
                v->uv[1] *= y;
 
266
        }
 
267
}
 
268
 
275
269
static void p_chart_uv_translate(PChart *chart, float trans[2])
276
270
{
277
271
        PVert *v;
395
389
 
396
390
/* Loading / Flushing */
397
391
 
398
 
static void p_vert_load_pin_select_uvs(PVert *v)
 
392
static void p_vert_load_pin_select_uvs(PHandle *handle, PVert *v)
399
393
{
400
394
        PEdge *e;
401
395
        int nedges = 0, npins = 0;
410
404
                                v->flag |= PVERT_SELECT;
411
405
 
412
406
                        if (e->flag & PEDGE_PIN) {
413
 
                                pinuv[0] += e->orig_uv[0];
414
 
                                pinuv[1] += e->orig_uv[1];
 
407
                                pinuv[0] += e->orig_uv[0]*handle->aspx;
 
408
                                pinuv[1] += e->orig_uv[1]*handle->aspy;
415
409
                                npins++;
416
410
                        }
417
411
                        else {
418
 
                                v->uv[0] += e->orig_uv[0];
419
 
                                v->uv[1] += e->orig_uv[1];
 
412
                                v->uv[0] += e->orig_uv[0]*handle->aspx;
 
413
                                v->uv[1] += e->orig_uv[1]*handle->aspy;
420
414
                        }
421
415
 
422
416
                        nedges++;
436
430
        }
437
431
}
438
432
 
439
 
static void p_flush_uvs(PChart *chart)
 
433
static void p_flush_uvs(PHandle *handle, PChart *chart)
440
434
{
441
435
        PEdge *e;
442
436
 
443
437
        for (e=chart->edges; e; e=e->nextlink) {
444
438
                if (e->orig_uv) {
445
 
                        e->orig_uv[0] = e->vert->uv[0];
446
 
                        e->orig_uv[1] = e->vert->uv[1];
 
439
                        e->orig_uv[0] = e->vert->uv[0]/handle->aspx;
 
440
                        e->orig_uv[1] = e->vert->uv[1]/handle->aspy;
447
441
                }
448
442
        }
449
443
}
450
444
 
451
 
static void p_flush_uvs_blend(PChart *chart, float blend)
 
445
static void p_flush_uvs_blend(PHandle *handle, PChart *chart, float blend)
452
446
{
453
447
        PEdge *e;
454
448
        float invblend = 1.0f - blend;
455
449
 
456
450
        for (e=chart->edges; e; e=e->nextlink) {
457
451
                if (e->orig_uv) {
458
 
                        e->orig_uv[0] = blend*e->old_uv[0] + invblend*e->vert->uv[0];
459
 
                        e->orig_uv[1] = blend*e->old_uv[1] + invblend*e->vert->uv[1];
 
452
                        e->orig_uv[0] = blend*e->old_uv[0] + invblend*e->vert->uv[0]/handle->aspx;
 
453
                        e->orig_uv[1] = blend*e->old_uv[1] + invblend*e->vert->uv[1]/handle->aspy;
460
454
                }
461
455
        }
462
456
}
600
594
                uvp2 = ep->orig_uv;
601
595
        }
602
596
 
603
 
        if((fabs(uv1[0]-uvp1[0]) > limit[0]) && (fabs(uv1[1]-uvp1[1]) > limit[1])) {
 
597
        if((fabs(uv1[0]-uvp1[0]) > limit[0]) || (fabs(uv1[1]-uvp1[1]) > limit[1])) {
604
598
                e->flag |= PEDGE_SEAM;
605
599
                ep->flag |= PEDGE_SEAM;
606
600
                return P_TRUE;
607
601
        }
608
 
        if((fabs(uv2[0]-uvp2[0]) > limit[0]) && (fabs(uv2[1]-uvp2[1]) > limit[1])) {
 
602
        if((fabs(uv2[0]-uvp2[0]) > limit[0]) || (fabs(uv2[1]-uvp2[1]) > limit[1])) {
609
603
                e->flag |= PEDGE_SEAM;
610
604
                ep->flag |= PEDGE_SEAM;
611
605
                return P_TRUE;
2229
2223
        nlBegin(NL_MATRIX);
2230
2224
 
2231
2225
        for (i = 0; i < nvar; i++)
2232
 
                nlRightHandSideAdd(i, sys->bInterior[i]);
 
2226
                nlRightHandSideAdd(0, i, sys->bInterior[i]);
2233
2227
 
2234
2228
        for (f=chart->faces; f; f=f->nextlink) {
2235
2229
                float wi1, wi2, wi3, b, si, beta[3], j2[3][3], W[3][3];
2275
2269
                        sys->J2dt[e2->u.id][0] = j2[1][0] = p_abf_compute_sin_product(sys, v1, e2->u.id)*wi2;
2276
2270
                        sys->J2dt[e3->u.id][0] = j2[2][0] = p_abf_compute_sin_product(sys, v1, e3->u.id)*wi3;
2277
2271
 
2278
 
                        nlRightHandSideAdd(v1->u.id, j2[0][0]*beta[0]);
2279
 
                        nlRightHandSideAdd(ninterior + v1->u.id, j2[1][0]*beta[1] + j2[2][0]*beta[2]);
 
2272
                        nlRightHandSideAdd(0, v1->u.id, j2[0][0]*beta[0]);
 
2273
                        nlRightHandSideAdd(0, ninterior + v1->u.id, j2[1][0]*beta[1] + j2[2][0]*beta[2]);
2280
2274
 
2281
2275
                        row1[0] = j2[0][0]*W[0][0];
2282
2276
                        row2[0] = j2[0][0]*W[1][0];
2295
2289
                        sys->J2dt[e2->u.id][1] = j2[1][1] = 1.0*wi2;
2296
2290
                        sys->J2dt[e3->u.id][1] = j2[2][1] = p_abf_compute_sin_product(sys, v2, e3->u.id)*wi3;
2297
2291
 
2298
 
                        nlRightHandSideAdd(v2->u.id, j2[1][1]*beta[1]);
2299
 
                        nlRightHandSideAdd(ninterior + v2->u.id, j2[0][1]*beta[0] + j2[2][1]*beta[2]);
 
2292
                        nlRightHandSideAdd(0, v2->u.id, j2[1][1]*beta[1]);
 
2293
                        nlRightHandSideAdd(0, ninterior + v2->u.id, j2[0][1]*beta[0] + j2[2][1]*beta[2]);
2300
2294
 
2301
2295
                        row1[1] = j2[1][1]*W[0][1];
2302
2296
                        row2[1] = j2[1][1]*W[1][1];
2315
2309
                        sys->J2dt[e2->u.id][2] = j2[1][2] = p_abf_compute_sin_product(sys, v3, e2->u.id)*wi2;
2316
2310
                        sys->J2dt[e3->u.id][2] = j2[2][2] = 1.0*wi3;
2317
2311
 
2318
 
                        nlRightHandSideAdd(v3->u.id, j2[2][2]*beta[2]);
2319
 
                        nlRightHandSideAdd(ninterior + v3->u.id, j2[0][2]*beta[0] + j2[1][2]*beta[1]);
 
2312
                        nlRightHandSideAdd(0, v3->u.id, j2[2][2]*beta[2]);
 
2313
                        nlRightHandSideAdd(0, ninterior + v3->u.id, j2[0][2]*beta[0] + j2[1][2]*beta[1]);
2320
2314
 
2321
2315
                        row1[2] = j2[2][2]*W[0][2];
2322
2316
                        row2[2] = j2[2][2]*W[1][2];
2373
2367
                        pre[0] = pre[1] = pre[2] = 0.0;
2374
2368
 
2375
2369
                        if (v1->flag & PVERT_INTERIOR) {
2376
 
                                float x = nlGetVariable(v1->u.id);
2377
 
                                float x2 = nlGetVariable(ninterior + v1->u.id);
 
2370
                                float x = nlGetVariable(0, v1->u.id);
 
2371
                                float x2 = nlGetVariable(0, ninterior + v1->u.id);
2378
2372
                                pre[0] += sys->J2dt[e1->u.id][0]*x;
2379
2373
                                pre[1] += sys->J2dt[e2->u.id][0]*x2;
2380
2374
                                pre[2] += sys->J2dt[e3->u.id][0]*x2;
2381
2375
                        }
2382
2376
 
2383
2377
                        if (v2->flag & PVERT_INTERIOR) {
2384
 
                                float x = nlGetVariable(v2->u.id);
2385
 
                                float x2 = nlGetVariable(ninterior + v2->u.id);
 
2378
                                float x = nlGetVariable(0, v2->u.id);
 
2379
                                float x2 = nlGetVariable(0, ninterior + v2->u.id);
2386
2380
                                pre[0] += sys->J2dt[e1->u.id][1]*x2;
2387
2381
                                pre[1] += sys->J2dt[e2->u.id][1]*x;
2388
2382
                                pre[2] += sys->J2dt[e3->u.id][1]*x2;
2389
2383
                        }
2390
2384
 
2391
2385
                        if (v3->flag & PVERT_INTERIOR) {
2392
 
                                float x = nlGetVariable(v3->u.id);
2393
 
                                float x2 = nlGetVariable(ninterior + v3->u.id);
 
2386
                                float x = nlGetVariable(0, v3->u.id);
 
2387
                                float x2 = nlGetVariable(0, ninterior + v3->u.id);
2394
2388
                                pre[0] += sys->J2dt[e1->u.id][2]*x2;
2395
2389
                                pre[1] += sys->J2dt[e2->u.id][2]*x2;
2396
2390
                                pre[2] += sys->J2dt[e3->u.id][2]*x;
2421
2415
                }
2422
2416
 
2423
2417
                for (i = 0; i < ninterior; i++) {
2424
 
                        sys->lambdaPlanar[i] += nlGetVariable(i);
2425
 
                        sys->lambdaLength[i] += nlGetVariable(ninterior + i);
 
2418
                        sys->lambdaPlanar[i] += nlGetVariable(0, i);
 
2419
                        sys->lambdaLength[i] += nlGetVariable(0, ninterior + i);
2426
2420
                }
2427
2421
        }
2428
2422
 
2565
2559
                (*pin2)->uv[1] = 0.5f;
2566
2560
        }
2567
2561
        else {
2568
 
                int diru, dirv, dir;
 
2562
                int diru, dirv, dirx, diry;
2569
2563
                float sub[3];
2570
2564
 
2571
2565
                VecSubf(sub, (*pin1)->co, (*pin2)->co);
2573
2567
                sub[1] = fabs(sub[1]);
2574
2568
                sub[2] = fabs(sub[2]);
2575
2569
 
2576
 
                if ((sub[0] > sub[1]) && (sub[0] > sub[2]))
2577
 
                        dir = 0;
2578
 
                else if ((sub[1] > sub[0]) && (sub[1] > sub[2]))
2579
 
                        dir = 1;
2580
 
                else
2581
 
                        dir = 2;
 
2570
                if ((sub[0] > sub[1]) && (sub[0] > sub[2])) {
 
2571
                        dirx = 0;
 
2572
                        diry = (sub[1] > sub[2])? 1: 2;
 
2573
                }
 
2574
                else if ((sub[1] > sub[0]) && (sub[1] > sub[2])) {
 
2575
                        dirx = 1;
 
2576
                        diry = (sub[0] > sub[2])? 0: 2;
 
2577
                }
 
2578
                else {
 
2579
                        dirx = 2;
 
2580
                        diry = (sub[0] > sub[1])? 0: 1;
 
2581
                }
2582
2582
 
2583
 
                if (dir == 2) {
 
2583
                if (dirx == 2) {
2584
2584
                        diru = 1;
2585
2585
                        dirv = 0;
2586
2586
                }
2589
2589
                        dirv = 1;
2590
2590
                }
2591
2591
 
2592
 
                (*pin1)->uv[diru] = (*pin1)->co[dir];
2593
 
                (*pin1)->uv[dirv] = (*pin1)->co[(dir+1)%3];
2594
 
                (*pin2)->uv[diru] = (*pin2)->co[dir];
2595
 
                (*pin2)->uv[dirv] = (*pin2)->co[(dir+1)%3];
 
2592
                (*pin1)->uv[diru] = (*pin1)->co[dirx];
 
2593
                (*pin1)->uv[dirv] = (*pin1)->co[diry];
 
2594
                (*pin2)->uv[diru] = (*pin2)->co[dirx];
 
2595
                (*pin2)->uv[dirv] = (*pin2)->co[diry];
2596
2596
        }
2597
2597
}
2598
2598
 
2748
2748
        PVert *v;
2749
2749
 
2750
2750
        for (v=chart->verts; v; v=v->nextlink) {
2751
 
                v->uv[0] = nlGetVariable(2*v->u.id);
2752
 
                v->uv[1] = nlGetVariable(2*v->u.id + 1);
 
2751
                v->uv[0] = nlGetVariable(0, 2*v->u.id);
 
2752
                v->uv[1] = nlGetVariable(0, 2*v->u.id + 1);
2753
2753
        }
2754
2754
}
2755
2755
 
2781
2781
#endif
2782
2782
 
2783
2783
                if (abf) {
2784
 
                        PBool p_chart_abf_solve(PChart *chart);
2785
 
 
2786
2784
                        if (!p_chart_abf_solve(chart))
2787
2785
                                param_warning("ABF solving failed: falling back to LSCM.\n");
2788
2786
                }
2808
2806
 
2809
2807
                nlNewContext();
2810
2808
                nlSolverParameteri(NL_NB_VARIABLES, 2*chart->nverts);
 
2809
                nlSolverParameteri(NL_NB_ROWS, 2*chart->nfaces);
2811
2810
                nlSolverParameteri(NL_LEAST_SQUARES, NL_TRUE);
2812
2811
 
2813
2812
                chart->u.lscm.context = nlGetCurrent();
2814
2813
        }
2815
2814
}
2816
2815
 
2817
 
static PBool p_chart_lscm_solve(PChart *chart)
 
2816
static PBool p_chart_lscm_solve(PHandle *handle, PChart *chart)
2818
2817
{
2819
2818
        PVert *v, *pin1 = chart->u.lscm.pin1, *pin2 = chart->u.lscm.pin2;
2820
2819
        PFace *f;
2821
2820
        float *alpha = chart->u.lscm.abf_alpha;
 
2821
        int row;
2822
2822
 
2823
2823
        nlMakeCurrent(chart->u.lscm.context);
2824
2824
 
2830
2830
 
2831
2831
        for (v=chart->verts; v; v=v->nextlink)
2832
2832
                if (v->flag & PVERT_PIN)
2833
 
                        p_vert_load_pin_select_uvs(v); /* reload for live */
 
2833
                        p_vert_load_pin_select_uvs(handle, v); /* reload for live */
2834
2834
 
2835
2835
        if (chart->u.lscm.pin1) {
2836
2836
                nlLockVariable(2*pin1->u.id);
2838
2838
                nlLockVariable(2*pin2->u.id);
2839
2839
                nlLockVariable(2*pin2->u.id + 1);
2840
2840
        
2841
 
                nlSetVariable(2*pin1->u.id, pin1->uv[0]);
2842
 
                nlSetVariable(2*pin1->u.id + 1, pin1->uv[1]);
2843
 
                nlSetVariable(2*pin2->u.id, pin2->uv[0]);
2844
 
                nlSetVariable(2*pin2->u.id + 1, pin2->uv[1]);
 
2841
                nlSetVariable(0, 2*pin1->u.id, pin1->uv[0]);
 
2842
                nlSetVariable(0, 2*pin1->u.id + 1, pin1->uv[1]);
 
2843
                nlSetVariable(0, 2*pin2->u.id, pin2->uv[0]);
 
2844
                nlSetVariable(0, 2*pin2->u.id + 1, pin2->uv[1]);
2845
2845
        }
2846
2846
        else {
2847
2847
                /* set and lock the pins */
2850
2850
                                nlLockVariable(2*v->u.id);
2851
2851
                                nlLockVariable(2*v->u.id + 1);
2852
2852
 
2853
 
                                nlSetVariable(2*v->u.id, v->uv[0]);
2854
 
                                nlSetVariable(2*v->u.id + 1, v->uv[1]);
 
2853
                                nlSetVariable(0, 2*v->u.id, v->uv[0]);
 
2854
                                nlSetVariable(0, 2*v->u.id + 1, v->uv[1]);
2855
2855
                        }
2856
2856
                }
2857
2857
        }
2860
2860
 
2861
2861
        nlBegin(NL_MATRIX);
2862
2862
 
 
2863
        row = 0;
2863
2864
        for (f=chart->faces; f; f=f->nextlink) {
2864
2865
                PEdge *e1 = f->edge, *e2 = e1->next, *e3 = e2->next;
2865
2866
                PVert *v1 = e1->vert, *v2 = e2->vert, *v3 = e3->vert;
2882
2883
                sinmax = MAX3(sina1, sina2, sina3);
2883
2884
 
2884
2885
                /* shift vertices to find most stable order */
2885
 
                #define SHIFT3(type, a, b, c) \
2886
 
                        { type tmp; tmp = a; a = c; c = b; b = tmp; }
2887
 
 
2888
2886
                if (sina3 != sinmax) {
2889
2887
                        SHIFT3(PVert*, v1, v2, v3);
2890
2888
                        SHIFT3(float, a1, a2, a3);
2902
2900
                cosine = cos(a1)*ratio;
2903
2901
                sine = sina1*ratio;
2904
2902
 
 
2903
#if 0
2905
2904
                nlBegin(NL_ROW);
2906
2905
                nlCoefficient(2*v1->u.id,   cosine - 1.0);
2907
2906
                nlCoefficient(2*v1->u.id+1, -sine);
2917
2916
                nlCoefficient(2*v2->u.id+1, -cosine);
2918
2917
                nlCoefficient(2*v3->u.id+1, 1.0);
2919
2918
                nlEnd(NL_ROW);
 
2919
#else
 
2920
                nlMatrixAdd(row, 2*v1->u.id,   cosine - 1.0);
 
2921
                nlMatrixAdd(row, 2*v1->u.id+1, -sine);
 
2922
                nlMatrixAdd(row, 2*v2->u.id,   -cosine);
 
2923
                nlMatrixAdd(row, 2*v2->u.id+1, sine);
 
2924
                nlMatrixAdd(row, 2*v3->u.id,   1.0);
 
2925
                row++;
 
2926
 
 
2927
                nlMatrixAdd(row, 2*v1->u.id,   sine);
 
2928
                nlMatrixAdd(row, 2*v1->u.id+1, cosine - 1.0);
 
2929
                nlMatrixAdd(row, 2*v2->u.id,   -sine);
 
2930
                nlMatrixAdd(row, 2*v2->u.id+1, -cosine);
 
2931
                nlMatrixAdd(row, 2*v3->u.id+1, 1.0);
 
2932
                row++;
 
2933
#endif
2920
2934
        }
2921
2935
 
2922
2936
        nlEnd(NL_MATRIX);
3098
3112
        }
3099
3113
}
3100
3114
 
3101
 
/* Packing */
3102
 
 
3103
 
static int p_compare_chart_area(const void *a, const void *b)
3104
 
{
3105
 
        PChart *ca = *((PChart**)a);
3106
 
        PChart *cb = *((PChart**)b);
3107
 
 
3108
 
    if (ca->u.pack.area > cb->u.pack.area)
3109
 
                return -1;
3110
 
        else if (ca->u.pack.area == cb->u.pack.area)
3111
 
                return 0;
3112
 
        else
3113
 
                return 1;
3114
 
}
3115
 
 
3116
 
static PBool p_pack_try(PHandle *handle, float side)
3117
 
{
3118
 
        PChart *chart;
3119
 
        float packx, packy, rowh, groupw, w, h;
3120
 
        int i;
3121
 
 
3122
 
        packx= packy= 0.0;
3123
 
        rowh= 0.0;
3124
 
        groupw= 1.0/sqrt(handle->ncharts);
3125
 
 
3126
 
        for (i = 0; i < handle->ncharts; i++) {
3127
 
                chart = handle->charts[i];
3128
 
 
3129
 
                if (chart->flag & PCHART_NOPACK)
3130
 
                        continue;
3131
 
 
3132
 
                w = chart->u.pack.size[0];
3133
 
                h = chart->u.pack.size[1];
3134
 
 
3135
 
                if(w <= (side-packx)) {
3136
 
                        chart->u.pack.trans[0] = packx;
3137
 
                        chart->u.pack.trans[1] = packy;
3138
 
 
3139
 
                        packx += w;
3140
 
                        rowh= MAX2(rowh, h);
3141
 
                }
3142
 
                else {
3143
 
                        packy += rowh;
3144
 
                        packx = w;
3145
 
                        rowh = h;
3146
 
 
3147
 
                        chart->u.pack.trans[0] = 0.0;
3148
 
                        chart->u.pack.trans[1] = packy;
3149
 
                }
3150
 
 
3151
 
                if (packy+rowh > side)
3152
 
                        return P_FALSE;
3153
 
        }
3154
 
 
3155
 
        return P_TRUE;
3156
 
}
3157
 
 
3158
 
#define PACK_SEARCH_DEPTH 15
3159
 
 
3160
 
void p_charts_pack(PHandle *handle)
3161
 
{
3162
 
        PChart *chart;
3163
 
        float uv_area, area, trans[2], minside, maxside, totarea, side;
3164
 
        int i;
3165
 
 
3166
 
        /* very simple rectangle packing */
3167
 
 
3168
 
        if (handle->ncharts == 0)
3169
 
                return;
3170
 
 
3171
 
        totarea = 0.0f;
3172
 
        maxside = 0.0f;
3173
 
 
3174
 
        for (i = 0; i < handle->ncharts; i++) {
3175
 
                chart = handle->charts[i];
3176
 
 
3177
 
                if (chart->flag & PCHART_NOPACK) {
3178
 
                        chart->u.pack.area = 0.0f;
3179
 
                        continue;
3180
 
                }
3181
 
 
3182
 
                p_chart_area(chart, &uv_area, &area);
3183
 
                p_chart_uv_bbox(chart, trans, chart->u.pack.size);
3184
 
 
3185
 
                /* translate to origin and make area equal to 3d area */
3186
 
                chart->u.pack.rescale = (uv_area > 0.0f)? sqrt(area)/sqrt(uv_area): 0.0f;
3187
 
                chart->u.pack.area = area;
3188
 
                totarea += area;
3189
 
 
3190
 
                trans[0] = -trans[0];
3191
 
                trans[1] = -trans[1];
3192
 
                p_chart_uv_translate(chart, trans);
3193
 
                p_chart_uv_scale(chart, chart->u.pack.rescale);
3194
 
 
3195
 
                /* compute new dimensions for packing */
3196
 
                chart->u.pack.size[0] += trans[0];
3197
 
                chart->u.pack.size[1] += trans[1];
3198
 
                chart->u.pack.size[0] *= chart->u.pack.rescale;
3199
 
                chart->u.pack.size[1] *= chart->u.pack.rescale;
3200
 
 
3201
 
                maxside = MAX3(maxside, chart->u.pack.size[0], chart->u.pack.size[1]);
3202
 
        }
3203
 
 
3204
 
        /* sort by chart area, largest first */
3205
 
        qsort(handle->charts, handle->ncharts, sizeof(PChart*), p_compare_chart_area);
3206
 
 
3207
 
        /* binary search over pack region size */
3208
 
        minside = MAX2(sqrt(totarea), maxside);
3209
 
        maxside = (((int)sqrt(handle->ncharts-1))+1)*maxside;
3210
 
 
3211
 
        if (minside < maxside) { /* should always be true */
3212
 
 
3213
 
                for (i = 0; i < PACK_SEARCH_DEPTH; i++) {
3214
 
                        if (p_pack_try(handle, (minside+maxside)*0.5f + 1e-5))
3215
 
                                maxside = (minside+maxside)*0.5f;
3216
 
                        else
3217
 
                                minside = (minside+maxside)*0.5f;
3218
 
                }
3219
 
        }
3220
 
 
3221
 
        /* do the actual packing */
3222
 
        side = maxside + 1e-5;
3223
 
        if (!p_pack_try(handle, side))
3224
 
                param_warning("packing failed.\n");
3225
 
 
3226
 
        for (i = 0; i < handle->ncharts; i++) {
3227
 
                chart = handle->charts[i];
3228
 
 
3229
 
                if (chart->flag & PCHART_NOPACK)
3230
 
                        continue;
3231
 
 
3232
 
                p_chart_uv_scale(chart, 1.0f/side);
3233
 
                trans[0] = chart->u.pack.trans[0]/side;
3234
 
                trans[1] = chart->u.pack.trans[1]/side;
3235
 
                p_chart_uv_translate(chart, trans);
3236
 
        }
3237
 
}
3238
 
 
3239
3115
/* Minimum area enclosing rectangle for packing */
3240
3116
 
3241
3117
static int p_compare_geometric_uv(const void *a, const void *b)
3984
3860
        handle->construction_chart = p_chart_new(handle);
3985
3861
        handle->state = PHANDLE_STATE_ALLOCATED;
3986
3862
        handle->arena = BLI_memarena_new((1<<16));
 
3863
        handle->aspx = 1.0f;
 
3864
        handle->aspy = 1.0f;
3987
3865
 
3988
3866
        handle->hash_verts = phash_new((PHashLink**)&handle->construction_chart->verts, 1);
3989
3867
        handle->hash_edges = phash_new((PHashLink**)&handle->construction_chart->edges, 1);
3992
3870
        return (ParamHandle*)handle;
3993
3871
}
3994
3872
 
 
3873
void param_aspect_ratio(ParamHandle *handle, float aspx, float aspy)
 
3874
{
 
3875
        PHandle *phandle = (PHandle*)handle;
 
3876
 
 
3877
        phandle->aspx = aspx;
 
3878
        phandle->aspy = aspy;
 
3879
}
 
3880
 
3995
3881
void param_delete(ParamHandle *handle)
3996
3882
{
3997
3883
        PHandle *phandle = (PHandle*)handle;
4080
3966
 
4081
3967
                p_chart_boundaries(chart, &nboundaries, &outer);
4082
3968
 
4083
 
                if (nboundaries == 0) {
 
3969
                if (!impl && nboundaries == 0) {
4084
3970
                        p_chart_delete(chart);
4085
3971
                        continue;
4086
3972
                }
4092
3978
                        p_chart_fill_boundaries(chart, outer);
4093
3979
 
4094
3980
                for (v=chart->verts; v; v=v->nextlink)
4095
 
                        p_vert_load_pin_select_uvs(v);
 
3981
                        p_vert_load_pin_select_uvs(handle, v);
4096
3982
        }
4097
3983
 
4098
3984
        phandle->ncharts = j;
4129
4015
                chart = phandle->charts[i];
4130
4016
 
4131
4017
                if (chart->u.lscm.context) {
4132
 
                        result = p_chart_lscm_solve(chart);
 
4018
                        result = p_chart_lscm_solve(phandle, chart);
4133
4019
 
4134
 
                        /*if (result)
4135
 
                                p_chart_rotate_minimum_area(chart);*/
 
4020
                        if (result && !(chart->flag & PCHART_NOPACK))
 
4021
                                p_chart_rotate_minimum_area(chart);
4136
4022
 
4137
4023
                        if (!result || (chart->u.lscm.pin1))
4138
4024
                                p_chart_lscm_end(chart);
4236
4122
                p_smooth(chart);
4237
4123
        }
4238
4124
}
4239
 
 
 
4125
 
4240
4126
void param_pack(ParamHandle *handle)
4241
4127
{
4242
 
        p_charts_pack((PHandle*)handle);
 
4128
        /* box packing variables */
 
4129
        boxPack *boxarray, *box;
 
4130
        float tot_width, tot_height, scale;
 
4131
         
 
4132
        PChart *chart;
 
4133
        int i, unpacked=0;
 
4134
        float trans[2];
 
4135
        
 
4136
        PHandle *phandle = (PHandle*)handle;
 
4137
        
 
4138
        if (phandle->ncharts == 0)
 
4139
                return;
 
4140
        
 
4141
        if(phandle->aspx != phandle->aspy)
 
4142
                param_scale(handle, 1.0f/phandle->aspx, 1.0f/phandle->aspy);
 
4143
        
 
4144
        /* we may not use all these boxes */
 
4145
        boxarray = MEM_mallocN( phandle->ncharts*sizeof(boxPack), "boxPack box");
 
4146
        
 
4147
        for (i = 0; i < phandle->ncharts; i++) {
 
4148
                chart = phandle->charts[i];
 
4149
                
 
4150
                if (chart->flag & PCHART_NOPACK) {
 
4151
                        unpacked++;
 
4152
                        continue;
 
4153
                }
 
4154
                
 
4155
                box = boxarray+(i-unpacked);
 
4156
                
 
4157
                p_chart_uv_bbox(chart, trans, chart->u.pack.size);
 
4158
                
 
4159
                trans[0] = -trans[0];
 
4160
                trans[1] = -trans[1];
 
4161
                
 
4162
                p_chart_uv_translate(chart, trans);
 
4163
                
 
4164
                box->w =  chart->u.pack.size[0] + trans[0];
 
4165
                box->h =  chart->u.pack.size[1] + trans[1];
 
4166
                box->index = i; /* warning this index skips PCHART_NOPACK boxes */
 
4167
        }
 
4168
        
 
4169
        boxPack2D(boxarray, phandle->ncharts-unpacked, &tot_width, &tot_height);
 
4170
        
 
4171
        if (tot_height>tot_width)
 
4172
                scale = 1.0/tot_height;
 
4173
        else
 
4174
                scale = 1.0/tot_width;
 
4175
        
 
4176
        for (i = 0; i < phandle->ncharts-unpacked; i++) {
 
4177
                box = boxarray+i;
 
4178
                trans[0] = box->x;
 
4179
                trans[1] = box->y;
 
4180
                
 
4181
                chart = phandle->charts[box->index];
 
4182
                p_chart_uv_translate(chart, trans);
 
4183
                p_chart_uv_scale(chart, scale);
 
4184
        }
 
4185
        MEM_freeN(boxarray);
 
4186
 
 
4187
        if(phandle->aspx != phandle->aspy)
 
4188
                param_scale(handle, phandle->aspx, phandle->aspy);
 
4189
}
 
4190
 
 
4191
void param_average(ParamHandle *handle)
 
4192
{
 
4193
        PChart *chart;
 
4194
        int i;
 
4195
        float tot_uvarea = 0.0f, tot_facearea = 0.0f;
 
4196
        float tot_fac, fac;
 
4197
        float minv[2], maxv[2], trans[2];
 
4198
        PHandle *phandle = (PHandle*)handle;
 
4199
        
 
4200
        if (phandle->ncharts == 0)
 
4201
                return;
 
4202
        
 
4203
        for (i = 0; i < phandle->ncharts; i++) {
 
4204
                PFace *f;
 
4205
                chart = phandle->charts[i];
 
4206
                
 
4207
                chart->u.pack.area = 0.0f; /* 3d area */
 
4208
                chart->u.pack.rescale = 0.0f; /* UV area, abusing rescale for tmp storage, oh well :/ */
 
4209
                
 
4210
                for (f=chart->faces; f; f=f->nextlink) {
 
4211
                        chart->u.pack.area += p_face_area(f);
 
4212
                        chart->u.pack.rescale += fabs(p_face_uv_area_signed(f));
 
4213
                }
 
4214
                
 
4215
                tot_facearea += chart->u.pack.area;
 
4216
                tot_uvarea += chart->u.pack.rescale;
 
4217
        }
 
4218
        
 
4219
        if (tot_facearea == tot_uvarea || tot_facearea==0.0f || tot_uvarea==0.0f) {
 
4220
                /* nothing to do */
 
4221
                return;
 
4222
        }
 
4223
        
 
4224
        tot_fac = tot_facearea/tot_uvarea;
 
4225
        
 
4226
        for (i = 0; i < phandle->ncharts; i++) {
 
4227
                chart = phandle->charts[i];
 
4228
                if (chart->u.pack.area != 0.0f && chart->u.pack.rescale != 0.0f) {
 
4229
                        fac = chart->u.pack.area / chart->u.pack.rescale;
 
4230
                        
 
4231
                        /* Get the island center */
 
4232
                        p_chart_uv_bbox(chart, minv, maxv);
 
4233
                        trans[0] = (minv[0] + maxv[0]) /-2.0f;
 
4234
                        trans[1] = (minv[1] + maxv[1]) /-2.0f;
 
4235
                        
 
4236
                        /* Move center to 0,0 */
 
4237
                        p_chart_uv_translate(chart, trans);
 
4238
                        p_chart_uv_scale(chart, sqrt(fac / tot_fac));
 
4239
                        
 
4240
                        /* Move to original center */
 
4241
                        trans[0] = -trans[0];
 
4242
                        trans[1] = -trans[1];
 
4243
                        p_chart_uv_translate(chart, trans);
 
4244
                }
 
4245
        }
 
4246
}
 
4247
 
 
4248
void param_scale(ParamHandle *handle, float x, float y)
 
4249
{
 
4250
        PHandle *phandle = (PHandle*)handle;
 
4251
        PChart *chart;
 
4252
        int i;
 
4253
 
 
4254
        for (i = 0; i < phandle->ncharts; i++) {
 
4255
                chart = phandle->charts[i];
 
4256
                p_chart_uv_scale_xy(chart, x, y);
 
4257
        }
4243
4258
}
4244
4259
 
4245
4260
void param_flush(ParamHandle *handle)
4255
4270
                        continue;
4256
4271
 
4257
4272
                if (phandle->blend == 0.0f)
4258
 
                        p_flush_uvs(chart);
 
4273
                        p_flush_uvs(phandle, chart);
4259
4274
                else
4260
 
                        p_flush_uvs_blend(chart, phandle->blend);
 
4275
                        p_flush_uvs_blend(phandle, chart, phandle->blend);
4261
4276
        }
4262
4277
}
4263
4278