~siretart/ubuntu/utopic/blender/libav10

« back to all changes in this revision

Viewing changes to source/blender/modifiers/intern/MOD_screw.c

  • Committer: Reinhard Tartler
  • Date: 2014-05-31 01:50:05 UTC
  • mfrom: (14.2.27 sid)
  • Revision ID: siretart@tauware.de-20140531015005-ml6druahuj82nsav
mergeĀ fromĀ debian

Show diffs side-by-side

added added

removed removed

Lines of Context:
34
34
 
35
35
 
36
36
/* Screw modifier: revolves the edges about an axis */
 
37
#include <limits.h>
37
38
 
38
39
#include "DNA_meshdata_types.h"
39
40
#include "DNA_object_types.h"
40
41
 
41
42
#include "BLI_math.h"
 
43
#include "BLI_alloca.h"
42
44
#include "BLI_utildefines.h"
43
45
 
44
 
 
45
46
#include "BKE_cdderivedmesh.h"
46
47
 
47
48
#include "depsgraph_private.h"
48
49
#include "MOD_modifiertypes.h"
49
50
#include "MEM_guardedalloc.h"
50
51
 
 
52
#include "BLI_strict_flags.h"
 
53
 
51
54
/* used for gathering edge connectivity */
52
55
typedef struct ScrewVertConnect {
53
56
        float dist;  /* distance from the center axis */
54
57
        float co[3]; /* loaction relative to the transformed axis */
55
58
        float no[3]; /* calc normal of the vertex */
56
 
        int v[2]; /* 2  verts on either side of this one */
 
59
        unsigned int v[2]; /* 2  verts on either side of this one */
57
60
        MEdge *e[2]; /* edges on either side, a bit of a waste since each edge ref's 2 edges */
58
61
        char flag;
59
62
} ScrewVertConnect;
61
64
typedef struct ScrewVertIter {
62
65
        ScrewVertConnect *v_array;
63
66
        ScrewVertConnect *v_poin;
64
 
        int v;
65
 
        int v_other;
 
67
        unsigned int v, v_other;
66
68
        MEdge *e;
67
69
} ScrewVertIter;
68
70
 
 
71
#define SV_UNUSED (UINT_MAX)
 
72
#define SV_INVALID ((UINT_MAX) - 1)
 
73
#define SV_IS_VALID(v) (v < SV_INVALID)
69
74
 
70
 
static void screwvert_iter_init(ScrewVertIter *iter, ScrewVertConnect *array, int v_init, int dir)
 
75
static void screwvert_iter_init(ScrewVertIter *iter, ScrewVertConnect *array, unsigned int v_init, unsigned int dir)
71
76
{
72
77
        iter->v_array = array;
73
78
        iter->v = v_init;
74
79
 
75
 
        if (v_init >= 0) {
 
80
        if (SV_IS_VALID(v_init)) {
76
81
                iter->v_poin = &array[v_init];
77
82
                iter->v_other = iter->v_poin->v[dir];
78
83
                iter->e = iter->v_poin->e[!dir];
94
99
                iter->v_other = iter->v;
95
100
                iter->v = iter->v_poin->v[0];
96
101
        }
97
 
        if (iter->v >= 0) {
 
102
        if (SV_IS_VALID(iter->v)) {
98
103
                iter->v_poin = &iter->v_array[iter->v];
99
104
                iter->e = iter->v_poin->e[(iter->v_poin->e[0] == iter->e)];
100
105
        }
109
114
{
110
115
        ScrewModifierData *ltmd = (ScrewModifierData *) md;
111
116
        ltmd->ob_axis = NULL;
112
 
        ltmd->angle = M_PI * 2.0;
 
117
        ltmd->angle = (float)(M_PI * 2.0);
113
118
        ltmd->axis = 2;
114
119
        ltmd->flag = MOD_SCREW_SMOOTH_SHADING;
115
120
        ltmd->steps = 16;
119
124
 
120
125
static void copyData(ModifierData *md, ModifierData *target)
121
126
{
 
127
#if 0
122
128
        ScrewModifierData *sltmd = (ScrewModifierData *) md;
123
129
        ScrewModifierData *tltmd = (ScrewModifierData *) target;
124
 
        
125
 
        tltmd->ob_axis = sltmd->ob_axis;
126
 
        tltmd->angle = sltmd->angle;
127
 
        tltmd->axis = sltmd->axis;
128
 
        tltmd->flag = sltmd->flag;
129
 
        tltmd->steps = sltmd->steps;
130
 
        tltmd->render_steps = sltmd->render_steps;
131
 
        tltmd->screw_ofs = sltmd->screw_ofs;
132
 
        tltmd->iter = sltmd->iter;
 
130
#endif
 
131
        modifier_copyData_generic(md, target);
133
132
}
134
133
 
135
134
static DerivedMesh *applyModifier(ModifierData *md, Object *ob,
143
142
        
144
143
        int *origindex;
145
144
        int mpoly_index = 0;
146
 
        int step;
147
 
        int i, j;
 
145
        unsigned int step;
 
146
        unsigned int i, j;
148
147
        unsigned int i1, i2;
149
 
        int step_tot = useRenderParams ? ltmd->render_steps : ltmd->steps;
150
 
        const int do_flip = ltmd->flag & MOD_SCREW_NORMAL_FLIP ? 1 : 0;
151
 
        int maxVerts = 0, maxEdges = 0, maxPolys = 0;
152
 
        const unsigned int totvert = dm->getNumVerts(dm);
153
 
        const unsigned int totedge = dm->getNumEdges(dm);
154
 
 
155
 
        char axis_char = 'X', close;
 
148
        unsigned int step_tot = useRenderParams ? ltmd->render_steps : ltmd->steps;
 
149
        const bool do_flip = ltmd->flag & MOD_SCREW_NORMAL_FLIP ? 1 : 0;
 
150
 
 
151
        const int quad_ord[4] = {
 
152
            do_flip ? 3 : 0,
 
153
            do_flip ? 2 : 1,
 
154
            do_flip ? 1 : 2,
 
155
            do_flip ? 0 : 3,
 
156
        };
 
157
        const int quad_ord_ofs[4] = {
 
158
            do_flip ? 2 : 0,
 
159
            do_flip ? 1 : 1,
 
160
            do_flip ? 0 : 2,
 
161
            do_flip ? 3 : 3,
 
162
        };
 
163
 
 
164
        unsigned int maxVerts = 0, maxEdges = 0, maxPolys = 0;
 
165
        const unsigned int totvert = (unsigned int)dm->getNumVerts(dm);
 
166
        const unsigned int totedge = (unsigned int)dm->getNumEdges(dm);
 
167
        const unsigned int totpoly = (unsigned int)dm->getNumPolys(dm);
 
168
 
 
169
        unsigned int *edge_poly_map = NULL;  /* orig edge to orig poly */
 
170
        unsigned int *vert_loop_map = NULL;  /* orig vert to orig loop */
 
171
 
 
172
        /* UV Coords */
 
173
        const unsigned int mloopuv_layers_tot = (unsigned int)CustomData_number_of_layers(&dm->loopData, CD_MLOOPUV);
 
174
        MLoopUV **mloopuv_layers = BLI_array_alloca(mloopuv_layers, mloopuv_layers_tot);
 
175
        float uv_u_scale;
 
176
        float uv_v_minmax[2] = {FLT_MAX, -FLT_MAX};
 
177
        float uv_v_range_inv;
 
178
        float uv_axis_plane[4];
 
179
 
 
180
        char axis_char = 'X';
 
181
        bool close;
156
182
        float angle = ltmd->angle;
157
183
        float screw_ofs = ltmd->screw_ofs;
158
184
        float axis_vec[3] = {0.0f, 0.0f, 0.0f};
162
188
        float mtx_tx_inv[4][4]; /* inverted */
163
189
        float mtx_tmp_a[4][4];
164
190
        
165
 
        int vc_tot_linked = 0;
 
191
        unsigned int vc_tot_linked = 0;
166
192
        short other_axis_1, other_axis_2;
167
193
        float *tmpf1, *tmpf2;
168
194
 
169
 
        int edge_offset;
 
195
        unsigned int edge_offset;
170
196
        
171
 
        MPoly *mpoly_new, *mp_new;
172
 
        MLoop *mloop_new, *ml_new;
 
197
        MPoly *mpoly_orig, *mpoly_new, *mp_new;
 
198
        MLoop *mloop_orig, *mloop_new, *ml_new;
173
199
        MEdge *medge_orig, *med_orig, *med_new, *med_new_firstloop, *medge_new;
174
200
        MVert *mvert_new, *mvert_orig, *mv_orig, *mv_new, *mv_new_base;
175
201
 
259
285
        }
260
286
        else {
261
287
                /* exis char is used by i_rotate*/
262
 
                axis_char += ltmd->axis; /* 'X' + axis */
 
288
                axis_char = (char)(axis_char + ltmd->axis); /* 'X' + axis */
263
289
 
264
290
                /* useful to be able to use the axis vec in some cases still */
265
291
                zero_v3(axis_vec);
267
293
        }
268
294
 
269
295
        /* apply the multiplier */
270
 
        angle *= ltmd->iter;
271
 
        screw_ofs *= ltmd->iter;
 
296
        angle *= (float)ltmd->iter;
 
297
        screw_ofs *= (float)ltmd->iter;
 
298
        uv_u_scale = 1.0f / (float)(step_tot);
272
299
 
273
300
        /* multiplying the steps is a bit tricky, this works best */
274
301
        step_tot = ((step_tot + 1) * ltmd->iter) - (ltmd->iter - 1);
298
325
                           (totedge * step_tot);  /* -1 because vert edges join */
299
326
                maxPolys =  totedge * (step_tot - 1);
300
327
        }
 
328
 
 
329
        if ((ltmd->flag & MOD_SCREW_UV_STRETCH_U) == 0) {
 
330
                uv_u_scale = (uv_u_scale / (float)ltmd->iter) * (angle / ((float)M_PI * 2.0f));
 
331
        }
301
332
        
302
 
        result = CDDM_from_template(dm, maxVerts, maxEdges, 0, maxPolys * 4, maxPolys);
 
333
        result = CDDM_from_template(dm, (int)maxVerts, (int)maxEdges, 0, (int)maxPolys * 4, (int)maxPolys);
303
334
        
304
335
        /* copy verts from mesh */
305
336
        mvert_orig =    dm->getVertArray(dm);
311
342
        medge_new =     result->getEdgeArray(result);
312
343
 
313
344
        if (!CustomData_has_layer(&result->polyData, CD_ORIGINDEX)) {
314
 
                CustomData_add_layer(&result->polyData, CD_ORIGINDEX, CD_CALLOC, NULL, maxPolys);
 
345
                CustomData_add_layer(&result->polyData, CD_ORIGINDEX, CD_CALLOC, NULL, (int)maxPolys);
315
346
        }
316
347
 
317
348
        origindex = CustomData_get_layer(&result->polyData, CD_ORIGINDEX);
318
349
 
319
 
        DM_copy_vert_data(dm, result, 0, 0, totvert); /* copy first otherwise this overwrites our own vertex normals */
320
 
        
 
350
        DM_copy_vert_data(dm, result, 0, 0, (int)totvert); /* copy first otherwise this overwrites our own vertex normals */
 
351
 
 
352
        if (mloopuv_layers_tot) {
 
353
                float zero_co[3] = {0};
 
354
                plane_from_point_normal_v3(uv_axis_plane, zero_co, axis_vec);
 
355
        }
 
356
 
 
357
        if (mloopuv_layers_tot) {
 
358
                unsigned int uv_lay;
 
359
                for (uv_lay = 0; uv_lay < mloopuv_layers_tot; uv_lay++) {
 
360
                        mloopuv_layers[uv_lay] = CustomData_get_layer_n(&result->loopData, CD_MLOOPUV, (int)uv_lay);
 
361
                }
 
362
 
 
363
                if (ltmd->flag & MOD_SCREW_UV_STRETCH_V) {
 
364
                        for (i = 0, mv_orig = mvert_orig; i < totvert; i++, mv_orig++) {
 
365
                                const float v = dist_squared_to_plane_v3(mv_orig->co, uv_axis_plane);
 
366
                                uv_v_minmax[0] = min_ff(v, uv_v_minmax[0]);
 
367
                                uv_v_minmax[1] = max_ff(v, uv_v_minmax[1]);
 
368
                        }
 
369
                        uv_v_minmax[0] = sqrtf_signed(uv_v_minmax[0]);
 
370
                        uv_v_minmax[1] = sqrtf_signed(uv_v_minmax[1]);
 
371
                }
 
372
 
 
373
                uv_v_range_inv = uv_v_minmax[1] - uv_v_minmax[0];
 
374
                uv_v_range_inv = uv_v_range_inv ? 1.0f / uv_v_range_inv : 0.0f;
 
375
        }
 
376
 
321
377
        /* Set the locations of the first set of verts */
322
378
        
323
379
        mv_new = mvert_new;
333
389
                med_new->flag = med_orig->flag &  ~ME_LOOSEEDGE;
334
390
        }
335
391
        
 
392
        /* build polygon -> edge map */
 
393
        if (totpoly) {
 
394
                MPoly *mp_orig;
 
395
 
 
396
                mpoly_orig = dm->getPolyArray(dm);
 
397
                mloop_orig = dm->getLoopArray(dm);
 
398
                edge_poly_map = MEM_mallocN(sizeof(*edge_poly_map) * totedge, __func__);
 
399
                memset(edge_poly_map, 0xff, sizeof(*edge_poly_map) * totedge);
 
400
 
 
401
                vert_loop_map = MEM_mallocN(sizeof(*vert_loop_map) * totvert, __func__);
 
402
                memset(vert_loop_map, 0xff, sizeof(*vert_loop_map) * totvert);
 
403
 
 
404
                for (i = 0, mp_orig = mpoly_orig; i < totpoly; i++, mp_orig++) {
 
405
                        unsigned int loopstart = (unsigned int)mp_orig->loopstart;
 
406
                        unsigned int loopend = loopstart + (unsigned int)mp_orig->totloop;
 
407
 
 
408
                        MLoop *ml_orig = &mloop_orig[loopstart];
 
409
                        unsigned int k;
 
410
                        for (k = loopstart; k < loopend; k++, ml_orig++) {
 
411
                                edge_poly_map[ml_orig->e] = i;
 
412
                                vert_loop_map[ml_orig->v] = k;
 
413
 
 
414
                                /* also order edges based on faces */
 
415
                                if (medge_new[ml_orig->e].v1 != ml_orig->v) {
 
416
                                        SWAP(unsigned int, medge_new[ml_orig->e].v1, medge_new[ml_orig->e].v2);
 
417
                                }
 
418
                        }
 
419
                }
 
420
        }
 
421
 
336
422
        if (ltmd->flag & MOD_SCREW_NORMAL_CALC) {
337
423
                /*
338
424
                 * Normal Calculation (for face flipping)
385
471
 
386
472
                                        vc->flag = 0;
387
473
                                        vc->e[0] = vc->e[1] = NULL;
388
 
                                        vc->v[0] = vc->v[1] = -1;
 
474
                                        vc->v[0] = vc->v[1] = SV_UNUSED;
389
475
 
390
476
                                        mul_m4_v3(mtx_tx, vc->co);
391
477
                                        /* length in 2d, don't sqrt because this is only for comparison */
403
489
 
404
490
                                        vc->flag = 0;
405
491
                                        vc->e[0] = vc->e[1] = NULL;
406
 
                                        vc->v[0] = vc->v[1] = -1;
 
492
                                        vc->v[0] = vc->v[1] = SV_UNUSED;
407
493
 
408
494
                                        /* length in 2d, don't sqrt because this is only for comparison */
409
495
                                        vc->dist = vc->co[other_axis_1] * vc->co[other_axis_1] +
417
503
                        for (i = 0; i < totedge; i++, med_new++) {
418
504
                                vc = &vert_connect[med_new->v1];
419
505
 
420
 
                                if (vc->v[0] == -1) { /* unused */
 
506
                                if (vc->v[0] == SV_UNUSED) { /* unused */
421
507
                                        vc->v[0] = med_new->v2;
422
508
                                        vc->e[0] = med_new;
423
509
                                }
424
 
                                else if (vc->v[1] == -1) {
 
510
                                else if (vc->v[1] == SV_UNUSED) {
425
511
                                        vc->v[1] = med_new->v2;
426
512
                                        vc->e[1] = med_new;
427
513
                                }
428
514
                                else {
429
 
                                        vc->v[0] = vc->v[1] = -2; /* error value  - don't use, 3 edges on vert */
 
515
                                        vc->v[0] = vc->v[1] = SV_INVALID; /* error value  - don't use, 3 edges on vert */
430
516
                                }
431
517
 
432
518
                                vc = &vert_connect[med_new->v2];
433
519
 
434
520
                                /* same as above but swap v1/2 */
435
 
                                if (vc->v[0] == -1) { /* unused */
 
521
                                if (vc->v[0] == SV_UNUSED) { /* unused */
436
522
                                        vc->v[0] = med_new->v1;
437
523
                                        vc->e[0] = med_new;
438
524
                                }
439
 
                                else if (vc->v[1] == -1) {
 
525
                                else if (vc->v[1] == SV_UNUSED) {
440
526
                                        vc->v[1] = med_new->v1;
441
527
                                        vc->e[1] = med_new;
442
528
                                }
443
529
                                else {
444
 
                                        vc->v[0] = vc->v[1] = -2; /* error value  - don't use, 3 edges on vert */
 
530
                                        vc->v[0] = vc->v[1] = SV_INVALID; /* error value  - don't use, 3 edges on vert */
445
531
                                }
446
532
                        }
447
533
 
452
538
                                 * so resulting faces are flipped the right way */
453
539
                                vc_tot_linked = 0; /* count the number of linked verts for this loop */
454
540
                                if (vc->flag == 0) {
455
 
                                        int v_best = -1, ed_loop_closed = 0; /* vert and vert new */
 
541
                                        unsigned int v_best = SV_UNUSED, ed_loop_closed = 0; /* vert and vert new */
456
542
                                        ScrewVertIter lt_iter;
457
543
                                        float fl = -1.0f;
458
544
 
459
545
                                        /* compiler complains if not initialized, but it should be initialized below */
460
 
                                        int ed_loop_flip = 0;
 
546
                                        bool ed_loop_flip = false;
461
547
 
462
548
                                        /*printf("Loop on connected vert: %i\n", i);*/
463
549
 
471
557
                                                        /*printf("\t\tVERT: %i\n", lt_iter.v);*/
472
558
                                                        if (lt_iter.v_poin->flag) {
473
559
                                                                /*printf("\t\t\tBreaking Found end\n");*/
474
 
                                                                //endpoints[0] = endpoints[1] = -1;
 
560
                                                                //endpoints[0] = endpoints[1] = SV_UNUSED;
475
561
                                                                ed_loop_closed = 1; /* circle */
476
562
                                                                break;
477
563
                                                        }
493
579
                                        }
494
580
 
495
581
                                        /* now we have a collection of used edges. flip their edges the right way*/
496
 
                                        /*if (v_best != -1) - */
 
582
                                        /*if (v_best != SV_UNUSED) - */
497
583
 
498
584
                                        /*printf("Done Looking - vc_tot_linked: %i\n", vc_tot_linked);*/
499
585
 
507
593
 
508
594
 
509
595
                                                /* edge connects on each side! */
510
 
                                                if ((vc_tmp->v[0] > -1) && (vc_tmp->v[1] > -1)) {
 
596
                                                if (SV_IS_VALID(vc_tmp->v[0]) && SV_IS_VALID(vc_tmp->v[1])) {
511
597
                                                        /*printf("Verts on each side (%i %i)\n", vc_tmp->v[0], vc_tmp->v[1]);*/
512
598
                                                        /* find out which is higher */
513
599
 
536
622
                                                                }
537
623
                                                        }
538
624
                                                }
539
 
                                                else if (vc_tmp->v[0] >= 0) { /*vertex only connected on 1 side */
 
625
                                                else if (SV_IS_VALID(vc_tmp->v[0])) { /*vertex only connected on 1 side */
540
626
                                                        /*printf("Verts on ONE side (%i %i)\n", vc_tmp->v[0], vc_tmp->v[1]);*/
541
627
                                                        if (tmpf1[ltmd->axis] < vc_tmp->co[ltmd->axis]) { /* best is above */
542
628
                                                                ed_loop_flip = 1;
577
663
                                                        /* If this is the vert off the best vert and
578
664
                                                         * the best vert has 2 edges connected too it
579
665
                                                         * then swap the flip direction */
580
 
                                                        if (j == 1 && (vc_tmp->v[0] > -1) && (vc_tmp->v[1] > -1))
 
666
                                                        if (j == 1 && SV_IS_VALID(vc_tmp->v[0]) && SV_IS_VALID(vc_tmp->v[1]))
581
667
                                                                ed_loop_flip = !ed_loop_flip;
582
668
 
583
669
                                                        while (lt_iter.v_poin && lt_iter.v_poin->flag != 2) {
622
708
                                 *
623
709
                                 * calculate vertex normals that can be propagated on lathing
624
710
                                 * use edge connectivity work this out */
625
 
                                if (vc->v[0] >= 0) {
626
 
                                        if (vc->v[1] >= 0) {
 
711
                                if (SV_IS_VALID(vc->v[0])) {
 
712
                                        if (SV_IS_VALID(vc->v[1])) {
627
713
                                                /* 2 edges connedted */
628
714
                                                /* make 2 connecting vert locations relative to the middle vert */
629
715
                                                sub_v3_v3v3(tmp_vec1, mvert_new[vc->v[0]].co, mvert_new[i].co);
654
740
                                                }
655
741
                                        }
656
742
 
657
 
                                        /* vc_no_tmp2 - is a line 90d from the pivot to the vec
 
743
                                        /* tmp_vec2 - is a line 90d from the pivot to the vec
658
744
                                         * This is used so the resulting normal points directly away from the middle */
659
745
                                        cross_v3_v3v3(tmp_vec2, axis_vec, vc->co);
660
746
 
661
 
                                        /* edge average vector and right angle to the pivot make the normal */
662
 
                                        cross_v3_v3v3(vc->no, tmp_vec1, tmp_vec2);
 
747
                                        if (UNLIKELY(is_zero_v3(tmp_vec2))) {
 
748
                                                /* we're _on_ the axis, so copy it based on our winding */
 
749
                                                if (vc->e[0]->v2 == i) {
 
750
                                                        negate_v3_v3(vc->no, axis_vec);
 
751
                                                }
 
752
                                                else {
 
753
                                                        copy_v3_v3(vc->no, axis_vec);
 
754
                                                }
 
755
                                        }
 
756
                                        else {
 
757
                                                /* edge average vector and right angle to the pivot make the normal */
 
758
                                                cross_v3_v3v3(vc->no, tmp_vec1, tmp_vec2);
 
759
                                        }
663
760
 
664
761
                                }
665
762
                                else {
689
786
        
690
787
        /* Add Faces */
691
788
        for (step = 1; step < step_tot; step++) {
692
 
                const int varray_stride = totvert * step;
 
789
                const unsigned int varray_stride = totvert * step;
693
790
                float step_angle;
694
791
                float nor_tx[3];
695
792
                float mat[4][4];
696
793
                /* Rotation Matrix */
697
 
                step_angle = (angle / (step_tot - (!close))) * step;
 
794
                step_angle = (angle / (float)(step_tot - (!close))) * (float)step;
698
795
 
699
796
                if (ltmd->ob_axis) {
700
797
                        axis_angle_normalized_to_mat3(mat3, axis_vec, step_angle);
710
807
                        madd_v3_v3fl(mat[3], axis_vec, screw_ofs * ((float)step / (float)(step_tot - 1)));
711
808
 
712
809
                /* copy a slice */
713
 
                DM_copy_vert_data(dm, result, 0, varray_stride, totvert);
 
810
                DM_copy_vert_data(dm, result, 0, (int)varray_stride, (int)totvert);
714
811
                
715
812
                mv_new_base = mvert_new;
716
813
                mv_new = &mvert_new[varray_stride]; /* advance to the next slice */
757
854
 
758
855
        if (close) {
759
856
                /* last loop of edges, previous loop dosnt account for the last set of edges */
760
 
                const int varray_stride = (step_tot - 1) * totvert;
 
857
                const unsigned int varray_stride = (step_tot - 1) * totvert;
761
858
 
762
859
                for (i = 0; i < totvert; i++) {
763
860
                        med_new->v1 = i;
775
872
        edge_offset = totedge + (totvert * (step_tot - (close ? 0 : 1)));
776
873
 
777
874
        for (i = 0; i < totedge; i++, med_new_firstloop++) {
 
875
                const unsigned int step_last = step_tot - (close ? 1 : 2);
 
876
                const unsigned int mpoly_index_orig = totpoly ? edge_poly_map[i] : UINT_MAX;
 
877
                const bool has_mpoly_orig = (mpoly_index_orig != UINT_MAX);
 
878
                float uv_v_offset_a, uv_v_offset_b;
 
879
 
 
880
                const unsigned int mloop_index_orig[2] = {
 
881
                    vert_loop_map ? vert_loop_map[medge_new[i].v1] : UINT_MAX,
 
882
                    vert_loop_map ? vert_loop_map[medge_new[i].v2] : UINT_MAX,
 
883
                };
 
884
                const bool has_mloop_orig = mloop_index_orig[0] != UINT_MAX;
 
885
 
 
886
                short mat_nr;
 
887
 
778
888
                /* for each edge, make a cylinder of quads */
779
889
                i1 = med_new_firstloop->v1;
780
890
                i2 = med_new_firstloop->v2;
781
891
 
782
 
                for (step = 0; step < step_tot - 1; step++) {
783
 
                        
784
 
                        /* new face */
785
 
                        if (do_flip) {
786
 
                                ml_new[3].v = i1;
787
 
                                ml_new[2].v = i2;
788
 
                                ml_new[1].v = i2 + totvert;
789
 
                                ml_new[0].v = i1 + totvert;
790
 
 
791
 
                                ml_new[2].e = step == 0 ? i : (edge_offset + step + (i * (step_tot - 1))) - 1;
792
 
                                ml_new[1].e = totedge + i2;
793
 
                                ml_new[0].e = edge_offset + step + (i * (step_tot - 1));
794
 
                                ml_new[3].e = totedge + i1;
795
 
                        }
796
 
                        else {
797
 
                                ml_new[0].v = i1;
798
 
                                ml_new[1].v = i2;
799
 
                                ml_new[2].v = i2 + totvert;
800
 
                                ml_new[3].v = i1 + totvert;
801
 
 
802
 
                                ml_new[0].e = step == 0 ? i : (edge_offset + step + (i * (step_tot - 1))) - 1;
803
 
                                ml_new[1].e = totedge + i2;
804
 
                                ml_new[2].e = edge_offset + step + (i * (step_tot - 1));
805
 
                                ml_new[3].e = totedge + i1;
806
 
                        }
807
 
 
808
 
 
809
 
                        mp_new->loopstart = mpoly_index * 4;
810
 
                        mp_new->totloop = 4;
811
 
                        mp_new->flag = mpoly_flag;
812
 
                        origindex[mpoly_index] = ORIGINDEX_NONE;
813
 
                        mp_new++;
814
 
                        ml_new += 4;
815
 
                        mpoly_index++;
816
 
                        
817
 
                        /* new vertical edge */
818
 
                        if (step) { /* The first set is already dome */
819
 
                                med_new->v1 = i1;
820
 
                                med_new->v2 = i2;
821
 
                                med_new->flag = med_new_firstloop->flag;
822
 
                                med_new->crease = med_new_firstloop->crease;
823
 
                                med_new++;
824
 
                        }
825
 
                        i1 += totvert;
826
 
                        i2 += totvert;
827
 
                }
828
 
                
829
 
                /* close the loop*/
830
 
                if (close) {
831
 
                        if (do_flip) {
832
 
                                ml_new[3].v = i1;
833
 
                                ml_new[2].v = i2;
834
 
                                ml_new[1].v = med_new_firstloop->v2;
835
 
                                ml_new[0].v = med_new_firstloop->v1;
836
 
 
837
 
                                ml_new[2].e = (edge_offset + step + (i * (step_tot - 1))) - 1;
838
 
                                ml_new[1].e = totedge + i2;
839
 
                                ml_new[0].e = i;
840
 
                                ml_new[3].e = totedge + i1;
841
 
                        }
842
 
                        else {
843
 
                                ml_new[0].v = i1;
844
 
                                ml_new[1].v = i2;
845
 
                                ml_new[2].v = med_new_firstloop->v2;
846
 
                                ml_new[3].v = med_new_firstloop->v1;
847
 
 
848
 
                                ml_new[0].e = (edge_offset + step + (i * (step_tot - 1))) - 1;
849
 
                                ml_new[1].e = totedge + i2;
850
 
                                ml_new[2].e = i;
851
 
                                ml_new[3].e = totedge + i1;
852
 
                        }
853
 
 
854
 
                        mp_new->loopstart = mpoly_index * 4;
855
 
                        mp_new->totloop = 4;
856
 
                        mp_new->flag = mpoly_flag;
857
 
                        origindex[mpoly_index] = ORIGINDEX_NONE;
 
892
                if (has_mpoly_orig) {
 
893
                        mat_nr = mpoly_orig[mpoly_index_orig].mat_nr;
 
894
                }
 
895
                else {
 
896
                        mat_nr = 0;
 
897
                }
 
898
 
 
899
                if (has_mloop_orig == false && mloopuv_layers_tot) {
 
900
                        uv_v_offset_a = dist_to_plane_v3(mvert_new[medge_new[i].v1].co, uv_axis_plane);
 
901
                        uv_v_offset_b = dist_to_plane_v3(mvert_new[medge_new[i].v2].co, uv_axis_plane);
 
902
 
 
903
                        if (ltmd->flag & MOD_SCREW_UV_STRETCH_V) {
 
904
                                uv_v_offset_a = (uv_v_offset_a - uv_v_minmax[0]) * uv_v_range_inv;
 
905
                                uv_v_offset_b = (uv_v_offset_b - uv_v_minmax[0]) * uv_v_range_inv;
 
906
                        }
 
907
                }
 
908
 
 
909
                for (step = 0; step <= step_last; step++) {
 
910
 
 
911
                        /* Polygon */
 
912
                        if (has_mpoly_orig) {
 
913
                                DM_copy_poly_data(dm, result, (int)mpoly_index_orig, (int)mpoly_index, 1);
 
914
                                origindex[mpoly_index] = (int)mpoly_index_orig;
 
915
                        }
 
916
                        else {
 
917
                                origindex[mpoly_index] = ORIGINDEX_NONE;
 
918
                                mp_new->flag = mpoly_flag;
 
919
                                mp_new->mat_nr = mat_nr;
 
920
                        }
 
921
                        mp_new->loopstart = mpoly_index * 4;
 
922
                        mp_new->totloop = 4;
 
923
 
 
924
 
 
925
                        /* Loop-Custom-Data */
 
926
                        if (has_mloop_orig) {
 
927
                                int l_index = (int)(ml_new - mloop_new);
 
928
                                DM_copy_loop_data(dm, result, (int)mloop_index_orig[0], l_index + 0, 1);
 
929
                                DM_copy_loop_data(dm, result, (int)mloop_index_orig[1], l_index + 1, 1);
 
930
                                DM_copy_loop_data(dm, result, (int)mloop_index_orig[1], l_index + 2, 1);
 
931
                                DM_copy_loop_data(dm, result, (int)mloop_index_orig[0], l_index + 3, 1);
 
932
 
 
933
                                if (mloopuv_layers_tot) {
 
934
                                        unsigned int uv_lay;
 
935
                                        const float uv_u_offset_a = (float)(step)     * uv_u_scale;
 
936
                                        const float uv_u_offset_b = (float)(step + 1) * uv_u_scale;
 
937
                                        for (uv_lay = 0; uv_lay < mloopuv_layers_tot; uv_lay++) {
 
938
                                                MLoopUV *mluv = &mloopuv_layers[uv_lay][l_index];
 
939
 
 
940
                                                mluv[quad_ord[0]].uv[0] += uv_u_offset_a;
 
941
                                                mluv[quad_ord[1]].uv[0] += uv_u_offset_a;
 
942
                                                mluv[quad_ord[2]].uv[0] += uv_u_offset_b;
 
943
                                                mluv[quad_ord[3]].uv[0] += uv_u_offset_b;
 
944
                                        }
 
945
                                }
 
946
                        }
 
947
                        else {
 
948
                                if (mloopuv_layers_tot) {
 
949
                                        int l_index = (int)(ml_new - mloop_new);
 
950
 
 
951
                                        unsigned int uv_lay;
 
952
                                        const float uv_u_offset_a = (float)(step)     * uv_u_scale;
 
953
                                        const float uv_u_offset_b = (float)(step + 1) * uv_u_scale;
 
954
                                        for (uv_lay = 0; uv_lay < mloopuv_layers_tot; uv_lay++) {
 
955
                                                MLoopUV *mluv = &mloopuv_layers[uv_lay][l_index];
 
956
 
 
957
                                                copy_v2_fl2(mluv[quad_ord[0]].uv, uv_u_offset_a, uv_v_offset_a);
 
958
                                                copy_v2_fl2(mluv[quad_ord[1]].uv, uv_u_offset_a, uv_v_offset_b);
 
959
                                                copy_v2_fl2(mluv[quad_ord[2]].uv, uv_u_offset_b, uv_v_offset_b);
 
960
                                                copy_v2_fl2(mluv[quad_ord[3]].uv, uv_u_offset_b, uv_v_offset_a);
 
961
                                        }
 
962
                                }
 
963
                        }
 
964
 
 
965
                        /* Loop-Data */
 
966
                        if (!(close && step == step_last)) {
 
967
                                /* regular segments */
 
968
                                ml_new[quad_ord[0]].v = i1;
 
969
                                ml_new[quad_ord[1]].v = i2;
 
970
                                ml_new[quad_ord[2]].v = i2 + totvert;
 
971
                                ml_new[quad_ord[3]].v = i1 + totvert;
 
972
 
 
973
                                ml_new[quad_ord_ofs[0]].e = step == 0 ? i : (edge_offset + step + (i * (step_tot - 1))) - 1;
 
974
                                ml_new[quad_ord_ofs[1]].e = totedge + i2;
 
975
                                ml_new[quad_ord_ofs[2]].e = edge_offset + step + (i * (step_tot - 1));
 
976
                                ml_new[quad_ord_ofs[3]].e = totedge + i1;
 
977
 
 
978
 
 
979
                                /* new vertical edge */
 
980
                                if (step) { /* The first set is already done */
 
981
                                        med_new->v1 = i1;
 
982
                                        med_new->v2 = i2;
 
983
                                        med_new->flag = med_new_firstloop->flag;
 
984
                                        med_new->crease = med_new_firstloop->crease;
 
985
                                        med_new++;
 
986
                                }
 
987
                                i1 += totvert;
 
988
                                i2 += totvert;
 
989
                        }
 
990
                        else {
 
991
                                /* last segment */
 
992
                                ml_new[quad_ord[0]].v = i1;
 
993
                                ml_new[quad_ord[1]].v = i2;
 
994
                                ml_new[quad_ord[2]].v = med_new_firstloop->v2;
 
995
                                ml_new[quad_ord[3]].v = med_new_firstloop->v1;
 
996
 
 
997
                                ml_new[quad_ord_ofs[0]].e = (edge_offset + step + (i * (step_tot - 1))) - 1;
 
998
                                ml_new[quad_ord_ofs[1]].e = totedge + i2;
 
999
                                ml_new[quad_ord_ofs[2]].e = i;
 
1000
                                ml_new[quad_ord_ofs[3]].e = totedge + i1;
 
1001
                        }
 
1002
 
858
1003
                        mp_new++;
859
1004
                        ml_new += 4;
860
1005
                        mpoly_index++;
871
1016
        /* validate loop edges */
872
1017
#if 0
873
1018
        {
874
 
                i = 0;
 
1019
                unsigned i = 0;
875
1020
                printf("\n");
876
1021
                for (; i < maxPolys * 4; i += 4) {
877
 
                        int ii;
 
1022
                        unsigned int ii;
878
1023
                        ml_new = mloop_new + i;
879
1024
                        ii = findEd(medge_new, maxEdges, ml_new[0].v, ml_new[1].v);
880
1025
                        printf("%d %d -- ", ii, ml_new[0].e);
896
1041
        }
897
1042
#endif
898
1043
 
 
1044
        if (edge_poly_map) {
 
1045
                MEM_freeN(edge_poly_map);
 
1046
        }
 
1047
 
 
1048
        if (vert_loop_map) {
 
1049
                MEM_freeN(vert_loop_map);
 
1050
        }
 
1051
 
899
1052
        if ((ltmd->flag & MOD_SCREW_NORMAL_CALC) == 0) {
900
1053
                result->dirty |= DM_DIRTY_NORMALS;
901
1054
        }