145
144
int mpoly_index = 0;
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);
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;
151
const int quad_ord[4] = {
157
const int quad_ord_ofs[4] = {
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);
169
unsigned int *edge_poly_map = NULL; /* orig edge to orig poly */
170
unsigned int *vert_loop_map = NULL; /* orig vert to orig loop */
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);
176
float uv_v_minmax[2] = {FLT_MAX, -FLT_MAX};
177
float uv_v_range_inv;
178
float uv_axis_plane[4];
180
char axis_char = 'X';
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};
311
342
medge_new = result->getEdgeArray(result);
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);
317
348
origindex = CustomData_get_layer(&result->polyData, CD_ORIGINDEX);
319
DM_copy_vert_data(dm, result, 0, 0, totvert); /* copy first otherwise this overwrites our own vertex normals */
350
DM_copy_vert_data(dm, result, 0, 0, (int)totvert); /* copy first otherwise this overwrites our own vertex normals */
352
if (mloopuv_layers_tot) {
353
float zero_co[3] = {0};
354
plane_from_point_normal_v3(uv_axis_plane, zero_co, axis_vec);
357
if (mloopuv_layers_tot) {
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);
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]);
369
uv_v_minmax[0] = sqrtf_signed(uv_v_minmax[0]);
370
uv_v_minmax[1] = sqrtf_signed(uv_v_minmax[1]);
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;
321
377
/* Set the locations of the first set of verts */
323
379
mv_new = mvert_new;
333
389
med_new->flag = med_orig->flag & ~ME_LOOSEEDGE;
392
/* build polygon -> edge map */
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);
401
vert_loop_map = MEM_mallocN(sizeof(*vert_loop_map) * totvert, __func__);
402
memset(vert_loop_map, 0xff, sizeof(*vert_loop_map) * totvert);
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;
408
MLoop *ml_orig = &mloop_orig[loopstart];
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;
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);
336
422
if (ltmd->flag & MOD_SCREW_NORMAL_CALC) {
338
424
* Normal Calculation (for face flipping)
775
872
edge_offset = totedge + (totvert * (step_tot - (close ? 0 : 1)));
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;
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,
884
const bool has_mloop_orig = mloop_index_orig[0] != UINT_MAX;
778
888
/* for each edge, make a cylinder of quads */
779
889
i1 = med_new_firstloop->v1;
780
890
i2 = med_new_firstloop->v2;
782
for (step = 0; step < step_tot - 1; step++) {
788
ml_new[1].v = i2 + totvert;
789
ml_new[0].v = i1 + totvert;
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;
799
ml_new[2].v = i2 + totvert;
800
ml_new[3].v = i1 + totvert;
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;
809
mp_new->loopstart = mpoly_index * 4;
811
mp_new->flag = mpoly_flag;
812
origindex[mpoly_index] = ORIGINDEX_NONE;
817
/* new vertical edge */
818
if (step) { /* The first set is already dome */
821
med_new->flag = med_new_firstloop->flag;
822
med_new->crease = med_new_firstloop->crease;
834
ml_new[1].v = med_new_firstloop->v2;
835
ml_new[0].v = med_new_firstloop->v1;
837
ml_new[2].e = (edge_offset + step + (i * (step_tot - 1))) - 1;
838
ml_new[1].e = totedge + i2;
840
ml_new[3].e = totedge + i1;
845
ml_new[2].v = med_new_firstloop->v2;
846
ml_new[3].v = med_new_firstloop->v1;
848
ml_new[0].e = (edge_offset + step + (i * (step_tot - 1))) - 1;
849
ml_new[1].e = totedge + i2;
851
ml_new[3].e = totedge + i1;
854
mp_new->loopstart = mpoly_index * 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;
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);
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;
909
for (step = 0; step <= step_last; step++) {
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;
917
origindex[mpoly_index] = ORIGINDEX_NONE;
918
mp_new->flag = mpoly_flag;
919
mp_new->mat_nr = mat_nr;
921
mp_new->loopstart = mpoly_index * 4;
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);
933
if (mloopuv_layers_tot) {
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];
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;
948
if (mloopuv_layers_tot) {
949
int l_index = (int)(ml_new - mloop_new);
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];
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);
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;
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;
979
/* new vertical edge */
980
if (step) { /* The first set is already done */
983
med_new->flag = med_new_firstloop->flag;
984
med_new->crease = med_new_firstloop->crease;
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;
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;