From e12c08e8d170b7ca40f204a5b0423c23a9fbc2c1 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Wed, 17 Apr 2019 06:17:24 +0200 Subject: ClangFormat: apply to source, most of intern Apply clang format as proposed in T53211. For details on usage and instructions for migrating branches without conflicts, see: https://wiki.blender.org/wiki/Tools/ClangFormat --- source/blender/modifiers/intern/MOD_screw.c | 2129 ++++++++++++++------------- 1 file changed, 1068 insertions(+), 1061 deletions(-) (limited to 'source/blender/modifiers/intern/MOD_screw.c') diff --git a/source/blender/modifiers/intern/MOD_screw.c b/source/blender/modifiers/intern/MOD_screw.c index 8e881fd09f0..e2917e2f82a 100644 --- a/source/blender/modifiers/intern/MOD_screw.c +++ b/source/blender/modifiers/intern/MOD_screw.c @@ -21,7 +21,6 @@ * \ingroup modifiers */ - /* Screw modifier: revolves the edges about an axis */ #include @@ -47,1109 +46,1117 @@ /* used for gathering edge connectivity */ typedef struct ScrewVertConnect { - float dist; /* distance from the center axis */ - float co[3]; /* location relative to the transformed axis */ - float no[3]; /* calc normal of the vertex */ - unsigned int v[2]; /* 2 verts on either side of this one */ - MEdge *e[2]; /* edges on either side, a bit of a waste since each edge ref's 2 edges */ - char flag; + float dist; /* distance from the center axis */ + float co[3]; /* location relative to the transformed axis */ + float no[3]; /* calc normal of the vertex */ + unsigned int v[2]; /* 2 verts on either side of this one */ + MEdge *e[2]; /* edges on either side, a bit of a waste since each edge ref's 2 edges */ + char flag; } ScrewVertConnect; typedef struct ScrewVertIter { - ScrewVertConnect *v_array; - ScrewVertConnect *v_poin; - unsigned int v, v_other; - MEdge *e; + ScrewVertConnect *v_array; + ScrewVertConnect *v_poin; + unsigned int v, v_other; + MEdge *e; } ScrewVertIter; #define SV_UNUSED (UINT_MAX) -#define SV_INVALID ((UINT_MAX) - 1) +#define SV_INVALID ((UINT_MAX)-1) #define SV_IS_VALID(v) ((v) < SV_INVALID) -static void screwvert_iter_init(ScrewVertIter *iter, ScrewVertConnect *array, unsigned int v_init, unsigned int dir) +static void screwvert_iter_init(ScrewVertIter *iter, + ScrewVertConnect *array, + unsigned int v_init, + unsigned int dir) { - iter->v_array = array; - iter->v = v_init; - - if (SV_IS_VALID(v_init)) { - iter->v_poin = &array[v_init]; - iter->v_other = iter->v_poin->v[dir]; - iter->e = iter->v_poin->e[!dir]; - } - else { - iter->v_poin = NULL; - iter->e = NULL; - } + iter->v_array = array; + iter->v = v_init; + + if (SV_IS_VALID(v_init)) { + iter->v_poin = &array[v_init]; + iter->v_other = iter->v_poin->v[dir]; + iter->e = iter->v_poin->e[!dir]; + } + else { + iter->v_poin = NULL; + iter->e = NULL; + } } - static void screwvert_iter_step(ScrewVertIter *iter) { - if (iter->v_poin->v[0] == iter->v_other) { - iter->v_other = iter->v; - iter->v = iter->v_poin->v[1]; - } - else if (iter->v_poin->v[1] == iter->v_other) { - iter->v_other = iter->v; - iter->v = iter->v_poin->v[0]; - } - if (SV_IS_VALID(iter->v)) { - iter->v_poin = &iter->v_array[iter->v]; - iter->e = iter->v_poin->e[(iter->v_poin->e[0] == iter->e)]; - } - else { - iter->e = NULL; - iter->v_poin = NULL; - } + if (iter->v_poin->v[0] == iter->v_other) { + iter->v_other = iter->v; + iter->v = iter->v_poin->v[1]; + } + else if (iter->v_poin->v[1] == iter->v_other) { + iter->v_other = iter->v; + iter->v = iter->v_poin->v[0]; + } + if (SV_IS_VALID(iter->v)) { + iter->v_poin = &iter->v_array[iter->v]; + iter->e = iter->v_poin->e[(iter->v_poin->e[0] == iter->e)]; + } + else { + iter->e = NULL; + iter->v_poin = NULL; + } } -static Mesh *mesh_remove_doubles_on_axis( - Mesh *result, MVert *mvert_new, const uint totvert, const uint step_tot, - const float axis_vec[3], const float axis_offset[3], const float merge_threshold) +static Mesh *mesh_remove_doubles_on_axis(Mesh *result, + MVert *mvert_new, + const uint totvert, + const uint step_tot, + const float axis_vec[3], + const float axis_offset[3], + const float merge_threshold) { - const float merge_threshold_sq = SQUARE(merge_threshold); - const bool use_offset = axis_offset != NULL; - uint tot_doubles = 0; - for (uint i = 0; i < totvert; i += 1) { - float axis_co[3]; - if (use_offset) { - float offset_co[3]; - sub_v3_v3v3(offset_co, mvert_new[i].co, axis_offset); - project_v3_v3v3_normalized(axis_co, offset_co, axis_vec); - add_v3_v3(axis_co, axis_offset); - } - else { - project_v3_v3v3_normalized(axis_co, mvert_new[i].co, axis_vec); - } - const float dist_sq = len_squared_v3v3(axis_co, mvert_new[i].co); - if (dist_sq <= merge_threshold_sq) { - mvert_new[i].flag |= ME_VERT_TMP_TAG; - tot_doubles += 1; - copy_v3_v3(mvert_new[i].co, axis_co); - } - } - - if (tot_doubles != 0) { - uint tot = totvert * step_tot; - int *full_doubles_map = MEM_malloc_arrayN(tot, sizeof(int), __func__); - copy_vn_i(full_doubles_map, (int)tot, -1); - - uint tot_doubles_left = tot_doubles; - for (uint i = 0; i < totvert; i += 1) { - if (mvert_new[i].flag & ME_VERT_TMP_TAG) { - int *doubles_map = &full_doubles_map[totvert + i] ; - for (uint step = 1; step < step_tot; step += 1) { - *doubles_map = (int)i; - doubles_map += totvert; - } - tot_doubles_left -= 1; - if (tot_doubles_left == 0) { - break; - } - } - } - result = BKE_mesh_merge_verts(result, full_doubles_map, (int)(tot_doubles * (step_tot - 1)), MESH_MERGE_VERTS_DUMP_IF_MAPPED); - MEM_freeN(full_doubles_map); - } - return result; + const float merge_threshold_sq = SQUARE(merge_threshold); + const bool use_offset = axis_offset != NULL; + uint tot_doubles = 0; + for (uint i = 0; i < totvert; i += 1) { + float axis_co[3]; + if (use_offset) { + float offset_co[3]; + sub_v3_v3v3(offset_co, mvert_new[i].co, axis_offset); + project_v3_v3v3_normalized(axis_co, offset_co, axis_vec); + add_v3_v3(axis_co, axis_offset); + } + else { + project_v3_v3v3_normalized(axis_co, mvert_new[i].co, axis_vec); + } + const float dist_sq = len_squared_v3v3(axis_co, mvert_new[i].co); + if (dist_sq <= merge_threshold_sq) { + mvert_new[i].flag |= ME_VERT_TMP_TAG; + tot_doubles += 1; + copy_v3_v3(mvert_new[i].co, axis_co); + } + } + + if (tot_doubles != 0) { + uint tot = totvert * step_tot; + int *full_doubles_map = MEM_malloc_arrayN(tot, sizeof(int), __func__); + copy_vn_i(full_doubles_map, (int)tot, -1); + + uint tot_doubles_left = tot_doubles; + for (uint i = 0; i < totvert; i += 1) { + if (mvert_new[i].flag & ME_VERT_TMP_TAG) { + int *doubles_map = &full_doubles_map[totvert + i]; + for (uint step = 1; step < step_tot; step += 1) { + *doubles_map = (int)i; + doubles_map += totvert; + } + tot_doubles_left -= 1; + if (tot_doubles_left == 0) { + break; + } + } + } + result = BKE_mesh_merge_verts(result, + full_doubles_map, + (int)(tot_doubles * (step_tot - 1)), + MESH_MERGE_VERTS_DUMP_IF_MAPPED); + MEM_freeN(full_doubles_map); + } + return result; } static void initData(ModifierData *md) { - ScrewModifierData *ltmd = (ScrewModifierData *) md; - ltmd->ob_axis = NULL; - ltmd->angle = (float)(M_PI * 2.0); - ltmd->axis = 2; - ltmd->flag = MOD_SCREW_SMOOTH_SHADING; - ltmd->steps = 16; - ltmd->render_steps = 16; - ltmd->iter = 1; - ltmd->merge_dist = 0.01f; + ScrewModifierData *ltmd = (ScrewModifierData *)md; + ltmd->ob_axis = NULL; + ltmd->angle = (float)(M_PI * 2.0); + ltmd->axis = 2; + ltmd->flag = MOD_SCREW_SMOOTH_SHADING; + ltmd->steps = 16; + ltmd->render_steps = 16; + ltmd->iter = 1; + ltmd->merge_dist = 0.01f; } -static Mesh *applyModifier( - ModifierData *md, const ModifierEvalContext *ctx, - Mesh *meshData) +static Mesh *applyModifier(ModifierData *md, const ModifierEvalContext *ctx, Mesh *meshData) { - Mesh *mesh = meshData; - Mesh *result; - ScrewModifierData *ltmd = (ScrewModifierData *) md; - const bool use_render_params = (ctx->flag & MOD_APPLY_RENDER) != 0; - - int *origindex; - int mpoly_index = 0; - unsigned int step; - unsigned int i, j; - unsigned int i1, i2; - unsigned int step_tot = use_render_params ? ltmd->render_steps : ltmd->steps; - const bool do_flip = (ltmd->flag & MOD_SCREW_NORMAL_FLIP) != 0; - - const int quad_ord[4] = { - do_flip ? 3 : 0, - do_flip ? 2 : 1, - do_flip ? 1 : 2, - do_flip ? 0 : 3, - }; - const int quad_ord_ofs[4] = { - do_flip ? 2 : 0, - 1, - do_flip ? 0 : 2, - 3, - }; - - unsigned int maxVerts = 0, maxEdges = 0, maxPolys = 0; - const unsigned int totvert = (unsigned int)mesh->totvert; - const unsigned int totedge = (unsigned int)mesh->totedge; - const unsigned int totpoly = (unsigned int)mesh->totpoly; - - unsigned int *edge_poly_map = NULL; /* orig edge to orig poly */ - unsigned int *vert_loop_map = NULL; /* orig vert to orig loop */ - - /* UV Coords */ - const unsigned int mloopuv_layers_tot = (unsigned int)CustomData_number_of_layers(&mesh->ldata, CD_MLOOPUV); - MLoopUV **mloopuv_layers = BLI_array_alloca(mloopuv_layers, mloopuv_layers_tot); - float uv_u_scale; - float uv_v_minmax[2] = {FLT_MAX, -FLT_MAX}; - float uv_v_range_inv; - float uv_axis_plane[4]; - - char axis_char = 'X'; - bool close; - float angle = ltmd->angle; - float screw_ofs = ltmd->screw_ofs; - float axis_vec[3] = {0.0f, 0.0f, 0.0f}; - float tmp_vec1[3], tmp_vec2[3]; - float mat3[3][3]; - /* transform the coords by an object relative to this objects transformation */ - float mtx_tx[4][4]; - float mtx_tx_inv[4][4]; /* inverted */ - float mtx_tmp_a[4][4]; - - unsigned int vc_tot_linked = 0; - short other_axis_1, other_axis_2; - const float *tmpf1, *tmpf2; - - unsigned int edge_offset; - - MPoly *mpoly_orig, *mpoly_new, *mp_new; - MLoop *mloop_orig, *mloop_new, *ml_new; - MEdge *medge_orig, *med_orig, *med_new, *med_new_firstloop, *medge_new; - MVert *mvert_new, *mvert_orig, *mv_orig, *mv_new, *mv_new_base; - - Object *ob_axis = ltmd->ob_axis; - - ScrewVertConnect *vc, *vc_tmp, *vert_connect = NULL; - - const char mpoly_flag = (ltmd->flag & MOD_SCREW_SMOOTH_SHADING) ? ME_SMOOTH : 0; - - /* don't do anything? */ - if (!totvert) - return BKE_mesh_new_nomain_from_template(mesh, 0, 0, 0, 0, 0); - - switch (ltmd->axis) { - case 0: - other_axis_1 = 1; - other_axis_2 = 2; - break; - case 1: - other_axis_1 = 0; - other_axis_2 = 2; - break; - default: /* 2, use default to quiet warnings */ - other_axis_1 = 0; - other_axis_2 = 1; - break; - } - - axis_vec[ltmd->axis] = 1.0f; - - if (ob_axis != NULL) { - /* calc the matrix relative to the axis object */ - invert_m4_m4(mtx_tmp_a, ctx->object->obmat); - copy_m4_m4(mtx_tx_inv, ob_axis->obmat); - mul_m4_m4m4(mtx_tx, mtx_tmp_a, mtx_tx_inv); - - /* calc the axis vec */ - mul_mat3_m4_v3(mtx_tx, axis_vec); /* only rotation component */ - normalize_v3(axis_vec); - - /* screw */ - if (ltmd->flag & MOD_SCREW_OBJECT_OFFSET) { - /* find the offset along this axis relative to this objects matrix */ - float totlen = len_v3(mtx_tx[3]); - - if (totlen != 0.0f) { - float zero[3] = {0.0f, 0.0f, 0.0f}; - float cp[3]; - screw_ofs = closest_to_line_v3(cp, mtx_tx[3], zero, axis_vec); - } - else { - screw_ofs = 0.0f; - } - } - - /* angle */ - -#if 0 /* can't include this, not predictable enough, though quite fun. */ - if (ltmd->flag & MOD_SCREW_OBJECT_ANGLE) { - float mtx3_tx[3][3]; - copy_m3_m4(mtx3_tx, mtx_tx); - - float vec[3] = {0, 1, 0}; - float cross1[3]; - float cross2[3]; - cross_v3_v3v3(cross1, vec, axis_vec); - - mul_v3_m3v3(cross2, mtx3_tx, cross1); - { - float c1[3]; - float c2[3]; - float axis_tmp[3]; - - cross_v3_v3v3(c1, cross2, axis_vec); - cross_v3_v3v3(c2, axis_vec, c1); - - - angle = angle_v3v3(cross1, c2); - - cross_v3_v3v3(axis_tmp, cross1, c2); - normalize_v3(axis_tmp); - - if (len_v3v3(axis_tmp, axis_vec) > 1.0f) - angle = -angle; - - } - } + Mesh *mesh = meshData; + Mesh *result; + ScrewModifierData *ltmd = (ScrewModifierData *)md; + const bool use_render_params = (ctx->flag & MOD_APPLY_RENDER) != 0; + + int *origindex; + int mpoly_index = 0; + unsigned int step; + unsigned int i, j; + unsigned int i1, i2; + unsigned int step_tot = use_render_params ? ltmd->render_steps : ltmd->steps; + const bool do_flip = (ltmd->flag & MOD_SCREW_NORMAL_FLIP) != 0; + + const int quad_ord[4] = { + do_flip ? 3 : 0, + do_flip ? 2 : 1, + do_flip ? 1 : 2, + do_flip ? 0 : 3, + }; + const int quad_ord_ofs[4] = { + do_flip ? 2 : 0, + 1, + do_flip ? 0 : 2, + 3, + }; + + unsigned int maxVerts = 0, maxEdges = 0, maxPolys = 0; + const unsigned int totvert = (unsigned int)mesh->totvert; + const unsigned int totedge = (unsigned int)mesh->totedge; + const unsigned int totpoly = (unsigned int)mesh->totpoly; + + unsigned int *edge_poly_map = NULL; /* orig edge to orig poly */ + unsigned int *vert_loop_map = NULL; /* orig vert to orig loop */ + + /* UV Coords */ + const unsigned int mloopuv_layers_tot = (unsigned int)CustomData_number_of_layers(&mesh->ldata, + CD_MLOOPUV); + MLoopUV **mloopuv_layers = BLI_array_alloca(mloopuv_layers, mloopuv_layers_tot); + float uv_u_scale; + float uv_v_minmax[2] = {FLT_MAX, -FLT_MAX}; + float uv_v_range_inv; + float uv_axis_plane[4]; + + char axis_char = 'X'; + bool close; + float angle = ltmd->angle; + float screw_ofs = ltmd->screw_ofs; + float axis_vec[3] = {0.0f, 0.0f, 0.0f}; + float tmp_vec1[3], tmp_vec2[3]; + float mat3[3][3]; + /* transform the coords by an object relative to this objects transformation */ + float mtx_tx[4][4]; + float mtx_tx_inv[4][4]; /* inverted */ + float mtx_tmp_a[4][4]; + + unsigned int vc_tot_linked = 0; + short other_axis_1, other_axis_2; + const float *tmpf1, *tmpf2; + + unsigned int edge_offset; + + MPoly *mpoly_orig, *mpoly_new, *mp_new; + MLoop *mloop_orig, *mloop_new, *ml_new; + MEdge *medge_orig, *med_orig, *med_new, *med_new_firstloop, *medge_new; + MVert *mvert_new, *mvert_orig, *mv_orig, *mv_new, *mv_new_base; + + Object *ob_axis = ltmd->ob_axis; + + ScrewVertConnect *vc, *vc_tmp, *vert_connect = NULL; + + const char mpoly_flag = (ltmd->flag & MOD_SCREW_SMOOTH_SHADING) ? ME_SMOOTH : 0; + + /* don't do anything? */ + if (!totvert) + return BKE_mesh_new_nomain_from_template(mesh, 0, 0, 0, 0, 0); + + switch (ltmd->axis) { + case 0: + other_axis_1 = 1; + other_axis_2 = 2; + break; + case 1: + other_axis_1 = 0; + other_axis_2 = 2; + break; + default: /* 2, use default to quiet warnings */ + other_axis_1 = 0; + other_axis_2 = 1; + break; + } + + axis_vec[ltmd->axis] = 1.0f; + + if (ob_axis != NULL) { + /* calc the matrix relative to the axis object */ + invert_m4_m4(mtx_tmp_a, ctx->object->obmat); + copy_m4_m4(mtx_tx_inv, ob_axis->obmat); + mul_m4_m4m4(mtx_tx, mtx_tmp_a, mtx_tx_inv); + + /* calc the axis vec */ + mul_mat3_m4_v3(mtx_tx, axis_vec); /* only rotation component */ + normalize_v3(axis_vec); + + /* screw */ + if (ltmd->flag & MOD_SCREW_OBJECT_OFFSET) { + /* find the offset along this axis relative to this objects matrix */ + float totlen = len_v3(mtx_tx[3]); + + if (totlen != 0.0f) { + float zero[3] = {0.0f, 0.0f, 0.0f}; + float cp[3]; + screw_ofs = closest_to_line_v3(cp, mtx_tx[3], zero, axis_vec); + } + else { + screw_ofs = 0.0f; + } + } + + /* angle */ + +#if 0 /* can't include this, not predictable enough, though quite fun. */ + if (ltmd->flag & MOD_SCREW_OBJECT_ANGLE) { + float mtx3_tx[3][3]; + copy_m3_m4(mtx3_tx, mtx_tx); + + float vec[3] = {0, 1, 0}; + float cross1[3]; + float cross2[3]; + cross_v3_v3v3(cross1, vec, axis_vec); + + mul_v3_m3v3(cross2, mtx3_tx, cross1); + { + float c1[3]; + float c2[3]; + float axis_tmp[3]; + + cross_v3_v3v3(c1, cross2, axis_vec); + cross_v3_v3v3(c2, axis_vec, c1); + + + angle = angle_v3v3(cross1, c2); + + cross_v3_v3v3(axis_tmp, cross1, c2); + normalize_v3(axis_tmp); + + if (len_v3v3(axis_tmp, axis_vec) > 1.0f) + angle = -angle; + + } + } #endif - } - else { - /* exis char is used by i_rotate*/ - axis_char = (char)(axis_char + ltmd->axis); /* 'X' + axis */ - - /* useful to be able to use the axis vec in some cases still */ - zero_v3(axis_vec); - axis_vec[ltmd->axis] = 1.0f; - } - - /* apply the multiplier */ - angle *= (float)ltmd->iter; - screw_ofs *= (float)ltmd->iter; - uv_u_scale = 1.0f / (float)(step_tot); - - /* multiplying the steps is a bit tricky, this works best */ - step_tot = ((step_tot + 1) * ltmd->iter) - (ltmd->iter - 1); - - /* will the screw be closed? - * Note! smaller then FLT_EPSILON * 100 gives problems with float precision so its never closed. */ - if (fabsf(screw_ofs) <= (FLT_EPSILON * 100.0f) && - fabsf(fabsf(angle) - ((float)M_PI * 2.0f)) <= (FLT_EPSILON * 100.0f)) - { - close = 1; - step_tot--; - if (step_tot < 3) step_tot = 3; - - maxVerts = totvert * step_tot; /* -1 because we're joining back up */ - maxEdges = (totvert * step_tot) + /* these are the edges between new verts */ - (totedge * step_tot); /* -1 because vert edges join */ - maxPolys = totedge * step_tot; - - screw_ofs = 0.0f; - } - else { - close = 0; - if (step_tot < 3) step_tot = 3; - - maxVerts = totvert * step_tot; /* -1 because we're joining back up */ - maxEdges = (totvert * (step_tot - 1)) + /* these are the edges between new verts */ - (totedge * step_tot); /* -1 because vert edges join */ - maxPolys = totedge * (step_tot - 1); - } - - if ((ltmd->flag & MOD_SCREW_UV_STRETCH_U) == 0) { - uv_u_scale = (uv_u_scale / (float)ltmd->iter) * (angle / ((float)M_PI * 2.0f)); - } - - result = BKE_mesh_new_nomain_from_template(mesh, (int)maxVerts, (int)maxEdges, 0, (int)maxPolys * 4, (int)maxPolys); - - /* copy verts from mesh */ - mvert_orig = mesh->mvert; - medge_orig = mesh->medge; - - mvert_new = result->mvert; - mpoly_new = result->mpoly; - mloop_new = result->mloop; - medge_new = result->medge; - - if (!CustomData_has_layer(&result->pdata, CD_ORIGINDEX)) { - CustomData_add_layer(&result->pdata, CD_ORIGINDEX, CD_CALLOC, NULL, (int)maxPolys); - } - - origindex = CustomData_get_layer(&result->pdata, CD_ORIGINDEX); - - CustomData_copy_data(&mesh->vdata, &result->vdata, 0, 0, (int)totvert); - - if (mloopuv_layers_tot) { - float zero_co[3] = {0}; - plane_from_point_normal_v3(uv_axis_plane, zero_co, axis_vec); - } - - if (mloopuv_layers_tot) { - unsigned int uv_lay; - for (uv_lay = 0; uv_lay < mloopuv_layers_tot; uv_lay++) { - mloopuv_layers[uv_lay] = CustomData_get_layer_n(&result->ldata, CD_MLOOPUV, (int)uv_lay); - } - - if (ltmd->flag & MOD_SCREW_UV_STRETCH_V) { - for (i = 0, mv_orig = mvert_orig; i < totvert; i++, mv_orig++) { - const float v = dist_signed_squared_to_plane_v3(mv_orig->co, uv_axis_plane); - uv_v_minmax[0] = min_ff(v, uv_v_minmax[0]); - uv_v_minmax[1] = max_ff(v, uv_v_minmax[1]); - } - uv_v_minmax[0] = sqrtf_signed(uv_v_minmax[0]); - uv_v_minmax[1] = sqrtf_signed(uv_v_minmax[1]); - } - - uv_v_range_inv = uv_v_minmax[1] - uv_v_minmax[0]; - uv_v_range_inv = uv_v_range_inv ? 1.0f / uv_v_range_inv : 0.0f; - } - - /* Set the locations of the first set of verts */ - - mv_new = mvert_new; - mv_orig = mvert_orig; - - /* Copy the first set of edges */ - med_orig = medge_orig; - med_new = medge_new; - for (i = 0; i < totedge; i++, med_orig++, med_new++) { - med_new->v1 = med_orig->v1; - med_new->v2 = med_orig->v2; - med_new->crease = med_orig->crease; - med_new->flag = med_orig->flag & ~ME_LOOSEEDGE; - } - - /* build polygon -> edge map */ - if (totpoly) { - MPoly *mp_orig; - - mpoly_orig = mesh->mpoly; - mloop_orig = mesh->mloop; - edge_poly_map = MEM_malloc_arrayN(totedge, sizeof(*edge_poly_map), __func__); - memset(edge_poly_map, 0xff, sizeof(*edge_poly_map) * totedge); - - vert_loop_map = MEM_malloc_arrayN(totvert, sizeof(*vert_loop_map), __func__); - memset(vert_loop_map, 0xff, sizeof(*vert_loop_map) * totvert); - - for (i = 0, mp_orig = mpoly_orig; i < totpoly; i++, mp_orig++) { - unsigned int loopstart = (unsigned int)mp_orig->loopstart; - unsigned int loopend = loopstart + (unsigned int)mp_orig->totloop; - - MLoop *ml_orig = &mloop_orig[loopstart]; - unsigned int k; - for (k = loopstart; k < loopend; k++, ml_orig++) { - edge_poly_map[ml_orig->e] = i; - vert_loop_map[ml_orig->v] = k; - - /* also order edges based on faces */ - if (medge_new[ml_orig->e].v1 != ml_orig->v) { - SWAP(unsigned int, medge_new[ml_orig->e].v1, medge_new[ml_orig->e].v2); - } - } - } - } - - if (ltmd->flag & MOD_SCREW_NORMAL_CALC) { - /* - * Normal Calculation (for face flipping) - * Sort edge verts for correct face flipping - * NOT REALLY NEEDED but face flipping is nice. - * - * */ - - - /* Notice! - * - * Since we are only ordering the edges here it can avoid mallocing the - * extra space by abusing the vert array before its filled with new verts. - * The new array for vert_connect must be at least sizeof(ScrewVertConnect) * totvert - * and the size of our resulting meshes array is sizeof(MVert) * totvert * 3 - * so its safe to use the second 2 thrids of MVert the array for vert_connect, - * just make sure ScrewVertConnect struct is no more than twice as big as MVert, - * at the moment there is no chance of that being a problem, - * unless MVert becomes half its current size. - * - * once the edges are ordered, vert_connect is not needed and it can be used for verts - * - * This makes the modifier faster with one less alloc. - */ - - vert_connect = MEM_malloc_arrayN(totvert, sizeof(ScrewVertConnect), "ScrewVertConnect"); - //vert_connect = (ScrewVertConnect *) &medge_new[totvert]; /* skip the first slice of verts */ - vc = vert_connect; - - /* Copy Vert Locations */ - /* - We can do this in a later loop - only do here if no normal calc */ - if (!totedge) { - for (i = 0; i < totvert; i++, mv_orig++, mv_new++) { - copy_v3_v3(mv_new->co, mv_orig->co); - normalize_v3_v3(vc->no, mv_new->co); /* no edges- this is really a dummy normal */ - } - } - else { - /*printf("\n\n\n\n\nStarting Modifier\n");*/ - /* set edge users */ - med_new = medge_new; - mv_new = mvert_new; - - if (ob_axis != NULL) { - /*mtx_tx is initialized early on */ - for (i = 0; i < totvert; i++, mv_new++, mv_orig++, vc++) { - vc->co[0] = mv_new->co[0] = mv_orig->co[0]; - vc->co[1] = mv_new->co[1] = mv_orig->co[1]; - vc->co[2] = mv_new->co[2] = mv_orig->co[2]; - - vc->flag = 0; - vc->e[0] = vc->e[1] = NULL; - vc->v[0] = vc->v[1] = SV_UNUSED; - - mul_m4_v3(mtx_tx, vc->co); - /* length in 2d, don't sqrt because this is only for comparison */ - vc->dist = vc->co[other_axis_1] * vc->co[other_axis_1] + - vc->co[other_axis_2] * vc->co[other_axis_2]; - - /* printf("location %f %f %f -- %f\n", vc->co[0], vc->co[1], vc->co[2], vc->dist);*/ - } - } - else { - for (i = 0; i < totvert; i++, mv_new++, mv_orig++, vc++) { - vc->co[0] = mv_new->co[0] = mv_orig->co[0]; - vc->co[1] = mv_new->co[1] = mv_orig->co[1]; - vc->co[2] = mv_new->co[2] = mv_orig->co[2]; - - vc->flag = 0; - vc->e[0] = vc->e[1] = NULL; - vc->v[0] = vc->v[1] = SV_UNUSED; - - /* length in 2d, don't sqrt because this is only for comparison */ - vc->dist = vc->co[other_axis_1] * vc->co[other_axis_1] + - vc->co[other_axis_2] * vc->co[other_axis_2]; - - /* printf("location %f %f %f -- %f\n", vc->co[0], vc->co[1], vc->co[2], vc->dist);*/ - } - } - - /* this loop builds connectivity info for verts */ - for (i = 0; i < totedge; i++, med_new++) { - vc = &vert_connect[med_new->v1]; - - if (vc->v[0] == SV_UNUSED) { /* unused */ - vc->v[0] = med_new->v2; - vc->e[0] = med_new; - } - else if (vc->v[1] == SV_UNUSED) { - vc->v[1] = med_new->v2; - vc->e[1] = med_new; - } - else { - vc->v[0] = vc->v[1] = SV_INVALID; /* error value - don't use, 3 edges on vert */ - } - - vc = &vert_connect[med_new->v2]; - - /* same as above but swap v1/2 */ - if (vc->v[0] == SV_UNUSED) { /* unused */ - vc->v[0] = med_new->v1; - vc->e[0] = med_new; - } - else if (vc->v[1] == SV_UNUSED) { - vc->v[1] = med_new->v1; - vc->e[1] = med_new; - } - else { - vc->v[0] = vc->v[1] = SV_INVALID; /* error value - don't use, 3 edges on vert */ - } - } - - /* find the first vert */ - vc = vert_connect; - for (i = 0; i < totvert; i++, vc++) { - /* Now do search for connected verts, order all edges and flip them - * so resulting faces are flipped the right way */ - vc_tot_linked = 0; /* count the number of linked verts for this loop */ - if (vc->flag == 0) { - unsigned int v_best = SV_UNUSED, ed_loop_closed = 0; /* vert and vert new */ - ScrewVertIter lt_iter; - float fl = -1.0f; - - /* compiler complains if not initialized, but it should be initialized below */ - bool ed_loop_flip = false; - - /*printf("Loop on connected vert: %i\n", i);*/ - - for (j = 0; j < 2; j++) { - /*printf("\tSide: %i\n", j);*/ - screwvert_iter_init(<_iter, vert_connect, i, j); - if (j == 1) { - screwvert_iter_step(<_iter); - } - while (lt_iter.v_poin) { - /*printf("\t\tVERT: %i\n", lt_iter.v);*/ - if (lt_iter.v_poin->flag) { - /*printf("\t\t\tBreaking Found end\n");*/ - //endpoints[0] = endpoints[1] = SV_UNUSED; - ed_loop_closed = 1; /* circle */ - break; - } - lt_iter.v_poin->flag = 1; - vc_tot_linked++; - /*printf("Testing 2 floats %f : %f\n", fl, lt_iter.v_poin->dist);*/ - if (fl <= lt_iter.v_poin->dist) { - fl = lt_iter.v_poin->dist; - v_best = lt_iter.v; - /*printf("\t\t\tVERT BEST: %i\n", v_best);*/ - } - screwvert_iter_step(<_iter); - if (!lt_iter.v_poin) { - /*printf("\t\t\tFound End Also Num %i\n", j);*/ - /*endpoints[j] = lt_iter.v_other;*/ /* other is still valid */ - break; - } - } - } - - /* now we have a collection of used edges. flip their edges the right way*/ - /*if (v_best != SV_UNUSED) - */ - - /*printf("Done Looking - vc_tot_linked: %i\n", vc_tot_linked);*/ - - if (vc_tot_linked > 1) { - float vf_1, vf_2, vf_best; - - vc_tmp = &vert_connect[v_best]; - - tmpf1 = vert_connect[vc_tmp->v[0]].co; - tmpf2 = vert_connect[vc_tmp->v[1]].co; - - - /* edge connects on each side! */ - if (SV_IS_VALID(vc_tmp->v[0]) && SV_IS_VALID(vc_tmp->v[1])) { - /*printf("Verts on each side (%i %i)\n", vc_tmp->v[0], vc_tmp->v[1]);*/ - /* find out which is higher */ - - vf_1 = tmpf1[ltmd->axis]; - vf_2 = tmpf2[ltmd->axis]; - vf_best = vc_tmp->co[ltmd->axis]; - - if (vf_1 < vf_best && vf_best < vf_2) { - ed_loop_flip = 0; - } - else if (vf_1 > vf_best && vf_best > vf_2) { - ed_loop_flip = 1; - } - else { - /* not so simple to work out which edge is higher */ - sub_v3_v3v3(tmp_vec1, tmpf1, vc_tmp->co); - sub_v3_v3v3(tmp_vec2, tmpf2, vc_tmp->co); - normalize_v3(tmp_vec1); - normalize_v3(tmp_vec2); - - if (tmp_vec1[ltmd->axis] < tmp_vec2[ltmd->axis]) { - ed_loop_flip = 1; - } - else { - ed_loop_flip = 0; - } - } - } - else if (SV_IS_VALID(vc_tmp->v[0])) { /*vertex only connected on 1 side */ - /*printf("Verts on ONE side (%i %i)\n", vc_tmp->v[0], vc_tmp->v[1]);*/ - if (tmpf1[ltmd->axis] < vc_tmp->co[ltmd->axis]) { /* best is above */ - ed_loop_flip = 1; - } - else { /* best is below or even... in even case we can't know what to do. */ - ed_loop_flip = 0; - } - - } + } + else { + /* exis char is used by i_rotate*/ + axis_char = (char)(axis_char + ltmd->axis); /* 'X' + axis */ + + /* useful to be able to use the axis vec in some cases still */ + zero_v3(axis_vec); + axis_vec[ltmd->axis] = 1.0f; + } + + /* apply the multiplier */ + angle *= (float)ltmd->iter; + screw_ofs *= (float)ltmd->iter; + uv_u_scale = 1.0f / (float)(step_tot); + + /* multiplying the steps is a bit tricky, this works best */ + step_tot = ((step_tot + 1) * ltmd->iter) - (ltmd->iter - 1); + + /* will the screw be closed? + * Note! smaller then FLT_EPSILON * 100 gives problems with float precision so its never closed. */ + if (fabsf(screw_ofs) <= (FLT_EPSILON * 100.0f) && + fabsf(fabsf(angle) - ((float)M_PI * 2.0f)) <= (FLT_EPSILON * 100.0f)) { + close = 1; + step_tot--; + if (step_tot < 3) + step_tot = 3; + + maxVerts = totvert * step_tot; /* -1 because we're joining back up */ + maxEdges = (totvert * step_tot) + /* these are the edges between new verts */ + (totedge * step_tot); /* -1 because vert edges join */ + maxPolys = totedge * step_tot; + + screw_ofs = 0.0f; + } + else { + close = 0; + if (step_tot < 3) + step_tot = 3; + + maxVerts = totvert * step_tot; /* -1 because we're joining back up */ + maxEdges = (totvert * (step_tot - 1)) + /* these are the edges between new verts */ + (totedge * step_tot); /* -1 because vert edges join */ + maxPolys = totedge * (step_tot - 1); + } + + if ((ltmd->flag & MOD_SCREW_UV_STRETCH_U) == 0) { + uv_u_scale = (uv_u_scale / (float)ltmd->iter) * (angle / ((float)M_PI * 2.0f)); + } + + result = BKE_mesh_new_nomain_from_template( + mesh, (int)maxVerts, (int)maxEdges, 0, (int)maxPolys * 4, (int)maxPolys); + + /* copy verts from mesh */ + mvert_orig = mesh->mvert; + medge_orig = mesh->medge; + + mvert_new = result->mvert; + mpoly_new = result->mpoly; + mloop_new = result->mloop; + medge_new = result->medge; + + if (!CustomData_has_layer(&result->pdata, CD_ORIGINDEX)) { + CustomData_add_layer(&result->pdata, CD_ORIGINDEX, CD_CALLOC, NULL, (int)maxPolys); + } + + origindex = CustomData_get_layer(&result->pdata, CD_ORIGINDEX); + + CustomData_copy_data(&mesh->vdata, &result->vdata, 0, 0, (int)totvert); + + if (mloopuv_layers_tot) { + float zero_co[3] = {0}; + plane_from_point_normal_v3(uv_axis_plane, zero_co, axis_vec); + } + + if (mloopuv_layers_tot) { + unsigned int uv_lay; + for (uv_lay = 0; uv_lay < mloopuv_layers_tot; uv_lay++) { + mloopuv_layers[uv_lay] = CustomData_get_layer_n(&result->ldata, CD_MLOOPUV, (int)uv_lay); + } + + if (ltmd->flag & MOD_SCREW_UV_STRETCH_V) { + for (i = 0, mv_orig = mvert_orig; i < totvert; i++, mv_orig++) { + const float v = dist_signed_squared_to_plane_v3(mv_orig->co, uv_axis_plane); + uv_v_minmax[0] = min_ff(v, uv_v_minmax[0]); + uv_v_minmax[1] = max_ff(v, uv_v_minmax[1]); + } + uv_v_minmax[0] = sqrtf_signed(uv_v_minmax[0]); + uv_v_minmax[1] = sqrtf_signed(uv_v_minmax[1]); + } + + uv_v_range_inv = uv_v_minmax[1] - uv_v_minmax[0]; + uv_v_range_inv = uv_v_range_inv ? 1.0f / uv_v_range_inv : 0.0f; + } + + /* Set the locations of the first set of verts */ + + mv_new = mvert_new; + mv_orig = mvert_orig; + + /* Copy the first set of edges */ + med_orig = medge_orig; + med_new = medge_new; + for (i = 0; i < totedge; i++, med_orig++, med_new++) { + med_new->v1 = med_orig->v1; + med_new->v2 = med_orig->v2; + med_new->crease = med_orig->crease; + med_new->flag = med_orig->flag & ~ME_LOOSEEDGE; + } + + /* build polygon -> edge map */ + if (totpoly) { + MPoly *mp_orig; + + mpoly_orig = mesh->mpoly; + mloop_orig = mesh->mloop; + edge_poly_map = MEM_malloc_arrayN(totedge, sizeof(*edge_poly_map), __func__); + memset(edge_poly_map, 0xff, sizeof(*edge_poly_map) * totedge); + + vert_loop_map = MEM_malloc_arrayN(totvert, sizeof(*vert_loop_map), __func__); + memset(vert_loop_map, 0xff, sizeof(*vert_loop_map) * totvert); + + for (i = 0, mp_orig = mpoly_orig; i < totpoly; i++, mp_orig++) { + unsigned int loopstart = (unsigned int)mp_orig->loopstart; + unsigned int loopend = loopstart + (unsigned int)mp_orig->totloop; + + MLoop *ml_orig = &mloop_orig[loopstart]; + unsigned int k; + for (k = loopstart; k < loopend; k++, ml_orig++) { + edge_poly_map[ml_orig->e] = i; + vert_loop_map[ml_orig->v] = k; + + /* also order edges based on faces */ + if (medge_new[ml_orig->e].v1 != ml_orig->v) { + SWAP(unsigned int, medge_new[ml_orig->e].v1, medge_new[ml_orig->e].v2); + } + } + } + } + + if (ltmd->flag & MOD_SCREW_NORMAL_CALC) { + /* + * Normal Calculation (for face flipping) + * Sort edge verts for correct face flipping + * NOT REALLY NEEDED but face flipping is nice. + * + * */ + + /* Notice! + * + * Since we are only ordering the edges here it can avoid mallocing the + * extra space by abusing the vert array before its filled with new verts. + * The new array for vert_connect must be at least sizeof(ScrewVertConnect) * totvert + * and the size of our resulting meshes array is sizeof(MVert) * totvert * 3 + * so its safe to use the second 2 thrids of MVert the array for vert_connect, + * just make sure ScrewVertConnect struct is no more than twice as big as MVert, + * at the moment there is no chance of that being a problem, + * unless MVert becomes half its current size. + * + * once the edges are ordered, vert_connect is not needed and it can be used for verts + * + * This makes the modifier faster with one less alloc. + */ + + vert_connect = MEM_malloc_arrayN(totvert, sizeof(ScrewVertConnect), "ScrewVertConnect"); + //vert_connect = (ScrewVertConnect *) &medge_new[totvert]; /* skip the first slice of verts */ + vc = vert_connect; + + /* Copy Vert Locations */ + /* - We can do this in a later loop - only do here if no normal calc */ + if (!totedge) { + for (i = 0; i < totvert; i++, mv_orig++, mv_new++) { + copy_v3_v3(mv_new->co, mv_orig->co); + normalize_v3_v3(vc->no, mv_new->co); /* no edges- this is really a dummy normal */ + } + } + else { + /*printf("\n\n\n\n\nStarting Modifier\n");*/ + /* set edge users */ + med_new = medge_new; + mv_new = mvert_new; + + if (ob_axis != NULL) { + /*mtx_tx is initialized early on */ + for (i = 0; i < totvert; i++, mv_new++, mv_orig++, vc++) { + vc->co[0] = mv_new->co[0] = mv_orig->co[0]; + vc->co[1] = mv_new->co[1] = mv_orig->co[1]; + vc->co[2] = mv_new->co[2] = mv_orig->co[2]; + + vc->flag = 0; + vc->e[0] = vc->e[1] = NULL; + vc->v[0] = vc->v[1] = SV_UNUSED; + + mul_m4_v3(mtx_tx, vc->co); + /* length in 2d, don't sqrt because this is only for comparison */ + vc->dist = vc->co[other_axis_1] * vc->co[other_axis_1] + + vc->co[other_axis_2] * vc->co[other_axis_2]; + + /* printf("location %f %f %f -- %f\n", vc->co[0], vc->co[1], vc->co[2], vc->dist);*/ + } + } + else { + for (i = 0; i < totvert; i++, mv_new++, mv_orig++, vc++) { + vc->co[0] = mv_new->co[0] = mv_orig->co[0]; + vc->co[1] = mv_new->co[1] = mv_orig->co[1]; + vc->co[2] = mv_new->co[2] = mv_orig->co[2]; + + vc->flag = 0; + vc->e[0] = vc->e[1] = NULL; + vc->v[0] = vc->v[1] = SV_UNUSED; + + /* length in 2d, don't sqrt because this is only for comparison */ + vc->dist = vc->co[other_axis_1] * vc->co[other_axis_1] + + vc->co[other_axis_2] * vc->co[other_axis_2]; + + /* printf("location %f %f %f -- %f\n", vc->co[0], vc->co[1], vc->co[2], vc->dist);*/ + } + } + + /* this loop builds connectivity info for verts */ + for (i = 0; i < totedge; i++, med_new++) { + vc = &vert_connect[med_new->v1]; + + if (vc->v[0] == SV_UNUSED) { /* unused */ + vc->v[0] = med_new->v2; + vc->e[0] = med_new; + } + else if (vc->v[1] == SV_UNUSED) { + vc->v[1] = med_new->v2; + vc->e[1] = med_new; + } + else { + vc->v[0] = vc->v[1] = SV_INVALID; /* error value - don't use, 3 edges on vert */ + } + + vc = &vert_connect[med_new->v2]; + + /* same as above but swap v1/2 */ + if (vc->v[0] == SV_UNUSED) { /* unused */ + vc->v[0] = med_new->v1; + vc->e[0] = med_new; + } + else if (vc->v[1] == SV_UNUSED) { + vc->v[1] = med_new->v1; + vc->e[1] = med_new; + } + else { + vc->v[0] = vc->v[1] = SV_INVALID; /* error value - don't use, 3 edges on vert */ + } + } + + /* find the first vert */ + vc = vert_connect; + for (i = 0; i < totvert; i++, vc++) { + /* Now do search for connected verts, order all edges and flip them + * so resulting faces are flipped the right way */ + vc_tot_linked = 0; /* count the number of linked verts for this loop */ + if (vc->flag == 0) { + unsigned int v_best = SV_UNUSED, ed_loop_closed = 0; /* vert and vert new */ + ScrewVertIter lt_iter; + float fl = -1.0f; + + /* compiler complains if not initialized, but it should be initialized below */ + bool ed_loop_flip = false; + + /*printf("Loop on connected vert: %i\n", i);*/ + + for (j = 0; j < 2; j++) { + /*printf("\tSide: %i\n", j);*/ + screwvert_iter_init(<_iter, vert_connect, i, j); + if (j == 1) { + screwvert_iter_step(<_iter); + } + while (lt_iter.v_poin) { + /*printf("\t\tVERT: %i\n", lt_iter.v);*/ + if (lt_iter.v_poin->flag) { + /*printf("\t\t\tBreaking Found end\n");*/ + //endpoints[0] = endpoints[1] = SV_UNUSED; + ed_loop_closed = 1; /* circle */ + break; + } + lt_iter.v_poin->flag = 1; + vc_tot_linked++; + /*printf("Testing 2 floats %f : %f\n", fl, lt_iter.v_poin->dist);*/ + if (fl <= lt_iter.v_poin->dist) { + fl = lt_iter.v_poin->dist; + v_best = lt_iter.v; + /*printf("\t\t\tVERT BEST: %i\n", v_best);*/ + } + screwvert_iter_step(<_iter); + if (!lt_iter.v_poin) { + /*printf("\t\t\tFound End Also Num %i\n", j);*/ + /*endpoints[j] = lt_iter.v_other;*/ /* other is still valid */ + break; + } + } + } + + /* now we have a collection of used edges. flip their edges the right way*/ + /*if (v_best != SV_UNUSED) - */ + + /*printf("Done Looking - vc_tot_linked: %i\n", vc_tot_linked);*/ + + if (vc_tot_linked > 1) { + float vf_1, vf_2, vf_best; + + vc_tmp = &vert_connect[v_best]; + + tmpf1 = vert_connect[vc_tmp->v[0]].co; + tmpf2 = vert_connect[vc_tmp->v[1]].co; + + /* edge connects on each side! */ + if (SV_IS_VALID(vc_tmp->v[0]) && SV_IS_VALID(vc_tmp->v[1])) { + /*printf("Verts on each side (%i %i)\n", vc_tmp->v[0], vc_tmp->v[1]);*/ + /* find out which is higher */ + + vf_1 = tmpf1[ltmd->axis]; + vf_2 = tmpf2[ltmd->axis]; + vf_best = vc_tmp->co[ltmd->axis]; + + if (vf_1 < vf_best && vf_best < vf_2) { + ed_loop_flip = 0; + } + else if (vf_1 > vf_best && vf_best > vf_2) { + ed_loop_flip = 1; + } + else { + /* not so simple to work out which edge is higher */ + sub_v3_v3v3(tmp_vec1, tmpf1, vc_tmp->co); + sub_v3_v3v3(tmp_vec2, tmpf2, vc_tmp->co); + normalize_v3(tmp_vec1); + normalize_v3(tmp_vec2); + + if (tmp_vec1[ltmd->axis] < tmp_vec2[ltmd->axis]) { + ed_loop_flip = 1; + } + else { + ed_loop_flip = 0; + } + } + } + else if (SV_IS_VALID(vc_tmp->v[0])) { /*vertex only connected on 1 side */ + /*printf("Verts on ONE side (%i %i)\n", vc_tmp->v[0], vc_tmp->v[1]);*/ + if (tmpf1[ltmd->axis] < vc_tmp->co[ltmd->axis]) { /* best is above */ + ed_loop_flip = 1; + } + else { /* best is below or even... in even case we can't know what to do. */ + ed_loop_flip = 0; + } + } #if 0 - else { - printf("No Connected ___\n"); - } + else { + printf("No Connected ___\n"); + } #endif - /*printf("flip direction %i\n", ed_loop_flip);*/ - + /*printf("flip direction %i\n", ed_loop_flip);*/ - /* switch the flip option if set - * note: flip is now done at face level so copying vgroup slizes is easier */ + /* switch the flip option if set + * note: flip is now done at face level so copying vgroup slizes is easier */ #if 0 - if (do_flip) - ed_loop_flip = !ed_loop_flip; + if (do_flip) + ed_loop_flip = !ed_loop_flip; #endif - if (angle < 0.0f) - ed_loop_flip = !ed_loop_flip; - - /* if its closed, we only need 1 loop */ - for (j = ed_loop_closed; j < 2; j++) { - /*printf("Ordering Side J %i\n", j);*/ - - screwvert_iter_init(<_iter, vert_connect, v_best, j); - /*printf("\n\nStarting - Loop\n");*/ - lt_iter.v_poin->flag = 1; /* so a non loop will traverse the other side */ - - - /* If this is the vert off the best vert and - * the best vert has 2 edges connected too it - * then swap the flip direction */ - if (j == 1 && SV_IS_VALID(vc_tmp->v[0]) && SV_IS_VALID(vc_tmp->v[1])) - ed_loop_flip = !ed_loop_flip; - - while (lt_iter.v_poin && lt_iter.v_poin->flag != 2) { - /*printf("\tOrdering Vert V %i\n", lt_iter.v);*/ - - lt_iter.v_poin->flag = 2; - if (lt_iter.e) { - if (lt_iter.v == lt_iter.e->v1) { - if (ed_loop_flip == 0) { - /*printf("\t\t\tFlipping 0\n");*/ - SWAP(unsigned int, lt_iter.e->v1, lt_iter.e->v2); - } - /* else { - printf("\t\t\tFlipping Not 0\n"); - }*/ - } - else if (lt_iter.v == lt_iter.e->v2) { - if (ed_loop_flip == 1) { - /*printf("\t\t\tFlipping 1\n");*/ - SWAP(unsigned int, lt_iter.e->v1, lt_iter.e->v2); - } - /* else { - printf("\t\t\tFlipping Not 1\n"); - }*/ - } - /* else { - printf("\t\tIncorrect edge topology"); - }*/ - } - /* else { - printf("\t\tNo Edge at this point\n"); - }*/ - screwvert_iter_step(<_iter); - } - } - } - } - - /* *VERTEX NORMALS* - * we know the surrounding edges are ordered correctly now - * so its safe to create vertex normals. - * - * calculate vertex normals that can be propagated on lathing - * use edge connectivity work this out */ - if (SV_IS_VALID(vc->v[0])) { - if (SV_IS_VALID(vc->v[1])) { - /* 2 edges connedted */ - /* make 2 connecting vert locations relative to the middle vert */ - sub_v3_v3v3(tmp_vec1, mvert_new[vc->v[0]].co, mvert_new[i].co); - sub_v3_v3v3(tmp_vec2, mvert_new[vc->v[1]].co, mvert_new[i].co); - /* normalize so both edges have the same influence, no matter their length */ - normalize_v3(tmp_vec1); - normalize_v3(tmp_vec2); - - /* vc_no_tmp1 - this line is the average direction of both connecting edges - * - * Use the edge order to make the subtraction, flip the normal the right way - * edge should be there but check just in case... */ - if (vc->e[0]->v1 == i) { - sub_v3_v3(tmp_vec1, tmp_vec2); - } - else { - sub_v3_v3v3(tmp_vec1, tmp_vec2, tmp_vec1); - } - } - else { - /* only 1 edge connected - same as above except - * don't need to average edge direction */ - if (vc->e[0]->v2 == i) { - sub_v3_v3v3(tmp_vec1, mvert_new[i].co, mvert_new[vc->v[0]].co); - } - else { - sub_v3_v3v3(tmp_vec1, mvert_new[vc->v[0]].co, mvert_new[i].co); - } - } - - /* tmp_vec2 - is a line 90d from the pivot to the vec - * This is used so the resulting normal points directly away from the middle */ - cross_v3_v3v3(tmp_vec2, axis_vec, vc->co); - - if (UNLIKELY(is_zero_v3(tmp_vec2))) { - /* we're _on_ the axis, so copy it based on our winding */ - if (vc->e[0]->v2 == i) { - negate_v3_v3(vc->no, axis_vec); - } - else { - copy_v3_v3(vc->no, axis_vec); - } - } - else { - /* edge average vector and right angle to the pivot make the normal */ - cross_v3_v3v3(vc->no, tmp_vec1, tmp_vec2); - } - - } - else { - copy_v3_v3(vc->no, vc->co); - } - - /* we won't be looping on this data again so copy normals here */ - if ((angle < 0.0f) != do_flip) - negate_v3(vc->no); - - normalize_v3(vc->no); - normal_float_to_short_v3(mvert_new[i].no, vc->no); - - /* Done with normals */ - } - } - } - else { - mv_orig = mvert_orig; - mv_new = mvert_new; - - for (i = 0; i < totvert; i++, mv_new++, mv_orig++) { - copy_v3_v3(mv_new->co, mv_orig->co); - } - } - /* done with edge connectivity based normal flipping */ - - /* Add Faces */ - for (step = 1; step < step_tot; step++) { - const unsigned int varray_stride = totvert * step; - float step_angle; - float nor_tx[3]; - float mat[4][4]; - /* Rotation Matrix */ - step_angle = (angle / (float)(step_tot - (!close))) * (float)step; - - if (ob_axis != NULL) { - axis_angle_normalized_to_mat3(mat3, axis_vec, step_angle); - } - else { - axis_angle_to_mat3_single(mat3, axis_char, step_angle); - } - copy_m4_m3(mat, mat3); - - if (screw_ofs) - madd_v3_v3fl(mat[3], axis_vec, screw_ofs * ((float)step / (float)(step_tot - 1))); - - /* copy a slice */ - CustomData_copy_data(&mesh->vdata, &result->vdata, 0, (int)varray_stride, (int)totvert); - - mv_new_base = mvert_new; - mv_new = &mvert_new[varray_stride]; /* advance to the next slice */ - - for (j = 0; j < totvert; j++, mv_new_base++, mv_new++) { - /* set normal */ - if (vert_connect) { - mul_v3_m3v3(nor_tx, mat3, vert_connect[j].no); - - /* set the normal now its transformed */ - normal_float_to_short_v3(mv_new->no, nor_tx); - } - - /* set location */ - copy_v3_v3(mv_new->co, mv_new_base->co); - - /* only need to set these if using non cleared memory */ - /*mv_new->mat_nr = mv_new->flag = 0;*/ - - if (ob_axis != NULL) { - sub_v3_v3(mv_new->co, mtx_tx[3]); - - mul_m4_v3(mat, mv_new->co); - - add_v3_v3(mv_new->co, mtx_tx[3]); - } - else { - mul_m4_v3(mat, mv_new->co); - } - - /* add the new edge */ - med_new->v1 = varray_stride + j; - med_new->v2 = med_new->v1 - totvert; - med_new->flag = ME_EDGEDRAW | ME_EDGERENDER; - med_new++; - } - } - - /* we can avoid if using vert alloc trick */ - if (vert_connect) { - MEM_freeN(vert_connect); - vert_connect = NULL; - } - - if (close) { - /* last loop of edges, previous loop doesn't account for the last set of edges */ - const unsigned int varray_stride = (step_tot - 1) * totvert; - - for (i = 0; i < totvert; i++) { - med_new->v1 = i; - med_new->v2 = varray_stride + i; - med_new->flag = ME_EDGEDRAW | ME_EDGERENDER; - med_new++; - } - } - - mp_new = mpoly_new; - ml_new = mloop_new; - med_new_firstloop = medge_new; - - /* more of an offset in this case */ - edge_offset = totedge + (totvert * (step_tot - (close ? 0 : 1))); - - for (i = 0; i < totedge; i++, med_new_firstloop++) { - const unsigned int step_last = step_tot - (close ? 1 : 2); - const unsigned int mpoly_index_orig = totpoly ? edge_poly_map[i] : UINT_MAX; - const bool has_mpoly_orig = (mpoly_index_orig != UINT_MAX); - float uv_v_offset_a, uv_v_offset_b; - - const unsigned int mloop_index_orig[2] = { - vert_loop_map ? vert_loop_map[medge_new[i].v1] : UINT_MAX, - vert_loop_map ? vert_loop_map[medge_new[i].v2] : UINT_MAX, - }; - const bool has_mloop_orig = mloop_index_orig[0] != UINT_MAX; - - short mat_nr; - - /* for each edge, make a cylinder of quads */ - i1 = med_new_firstloop->v1; - i2 = med_new_firstloop->v2; - - if (has_mpoly_orig) { - mat_nr = mpoly_orig[mpoly_index_orig].mat_nr; - } - else { - mat_nr = 0; - } - - if (has_mloop_orig == false && mloopuv_layers_tot) { - uv_v_offset_a = dist_signed_to_plane_v3(mvert_new[medge_new[i].v1].co, uv_axis_plane); - uv_v_offset_b = dist_signed_to_plane_v3(mvert_new[medge_new[i].v2].co, uv_axis_plane); - - if (ltmd->flag & MOD_SCREW_UV_STRETCH_V) { - uv_v_offset_a = (uv_v_offset_a - uv_v_minmax[0]) * uv_v_range_inv; - uv_v_offset_b = (uv_v_offset_b - uv_v_minmax[0]) * uv_v_range_inv; - } - } - - for (step = 0; step <= step_last; step++) { - - /* Polygon */ - if (has_mpoly_orig) { - CustomData_copy_data(&mesh->pdata, &result->pdata, (int)mpoly_index_orig, (int)mpoly_index, 1); - origindex[mpoly_index] = (int)mpoly_index_orig; - } - else { - origindex[mpoly_index] = ORIGINDEX_NONE; - mp_new->flag = mpoly_flag; - mp_new->mat_nr = mat_nr; - } - mp_new->loopstart = mpoly_index * 4; - mp_new->totloop = 4; - - - /* Loop-Custom-Data */ - if (has_mloop_orig) { - int l_index = (int)(ml_new - mloop_new); - - CustomData_copy_data(&mesh->ldata, &result->ldata, (int)mloop_index_orig[0], l_index + 0, 1); - CustomData_copy_data(&mesh->ldata, &result->ldata, (int)mloop_index_orig[1], l_index + 1, 1); - CustomData_copy_data(&mesh->ldata, &result->ldata, (int)mloop_index_orig[1], l_index + 2, 1); - CustomData_copy_data(&mesh->ldata, &result->ldata, (int)mloop_index_orig[0], l_index + 3, 1); - - if (mloopuv_layers_tot) { - unsigned int uv_lay; - const float uv_u_offset_a = (float)(step) * uv_u_scale; - const float uv_u_offset_b = (float)(step + 1) * uv_u_scale; - for (uv_lay = 0; uv_lay < mloopuv_layers_tot; uv_lay++) { - MLoopUV *mluv = &mloopuv_layers[uv_lay][l_index]; - - mluv[quad_ord[0]].uv[0] += uv_u_offset_a; - mluv[quad_ord[1]].uv[0] += uv_u_offset_a; - mluv[quad_ord[2]].uv[0] += uv_u_offset_b; - mluv[quad_ord[3]].uv[0] += uv_u_offset_b; - } - } - } - else { - if (mloopuv_layers_tot) { - int l_index = (int)(ml_new - mloop_new); - - unsigned int uv_lay; - const float uv_u_offset_a = (float)(step) * uv_u_scale; - const float uv_u_offset_b = (float)(step + 1) * uv_u_scale; - for (uv_lay = 0; uv_lay < mloopuv_layers_tot; uv_lay++) { - MLoopUV *mluv = &mloopuv_layers[uv_lay][l_index]; - - copy_v2_fl2(mluv[quad_ord[0]].uv, uv_u_offset_a, uv_v_offset_a); - copy_v2_fl2(mluv[quad_ord[1]].uv, uv_u_offset_a, uv_v_offset_b); - copy_v2_fl2(mluv[quad_ord[2]].uv, uv_u_offset_b, uv_v_offset_b); - copy_v2_fl2(mluv[quad_ord[3]].uv, uv_u_offset_b, uv_v_offset_a); - } - } - } - - /* Loop-Data */ - if (!(close && step == step_last)) { - /* regular segments */ - ml_new[quad_ord[0]].v = i1; - ml_new[quad_ord[1]].v = i2; - ml_new[quad_ord[2]].v = i2 + totvert; - ml_new[quad_ord[3]].v = i1 + totvert; - - ml_new[quad_ord_ofs[0]].e = step == 0 ? i : (edge_offset + step + (i * (step_tot - 1))) - 1; - ml_new[quad_ord_ofs[1]].e = totedge + i2; - ml_new[quad_ord_ofs[2]].e = edge_offset + step + (i * (step_tot - 1)); - ml_new[quad_ord_ofs[3]].e = totedge + i1; - - - /* new vertical edge */ - if (step) { /* The first set is already done */ - med_new->v1 = i1; - med_new->v2 = i2; - med_new->flag = med_new_firstloop->flag; - med_new->crease = med_new_firstloop->crease; - med_new++; - } - i1 += totvert; - i2 += totvert; - } - else { - /* last segment */ - ml_new[quad_ord[0]].v = i1; - ml_new[quad_ord[1]].v = i2; - ml_new[quad_ord[2]].v = med_new_firstloop->v2; - ml_new[quad_ord[3]].v = med_new_firstloop->v1; - - ml_new[quad_ord_ofs[0]].e = (edge_offset + step + (i * (step_tot - 1))) - 1; - ml_new[quad_ord_ofs[1]].e = totedge + i2; - ml_new[quad_ord_ofs[2]].e = i; - ml_new[quad_ord_ofs[3]].e = totedge + i1; - } - - mp_new++; - ml_new += 4; - mpoly_index++; - } - - /* new vertical edge */ - med_new->v1 = i1; - med_new->v2 = i2; - med_new->flag = med_new_firstloop->flag & ~ME_LOOSEEDGE; - med_new->crease = med_new_firstloop->crease; - med_new++; - } - - /* validate loop edges */ + if (angle < 0.0f) + ed_loop_flip = !ed_loop_flip; + + /* if its closed, we only need 1 loop */ + for (j = ed_loop_closed; j < 2; j++) { + /*printf("Ordering Side J %i\n", j);*/ + + screwvert_iter_init(<_iter, vert_connect, v_best, j); + /*printf("\n\nStarting - Loop\n");*/ + lt_iter.v_poin->flag = 1; /* so a non loop will traverse the other side */ + + /* If this is the vert off the best vert and + * the best vert has 2 edges connected too it + * then swap the flip direction */ + if (j == 1 && SV_IS_VALID(vc_tmp->v[0]) && SV_IS_VALID(vc_tmp->v[1])) + ed_loop_flip = !ed_loop_flip; + + while (lt_iter.v_poin && lt_iter.v_poin->flag != 2) { + /*printf("\tOrdering Vert V %i\n", lt_iter.v);*/ + + lt_iter.v_poin->flag = 2; + if (lt_iter.e) { + if (lt_iter.v == lt_iter.e->v1) { + if (ed_loop_flip == 0) { + /*printf("\t\t\tFlipping 0\n");*/ + SWAP(unsigned int, lt_iter.e->v1, lt_iter.e->v2); + } + /* else { + printf("\t\t\tFlipping Not 0\n"); + }*/ + } + else if (lt_iter.v == lt_iter.e->v2) { + if (ed_loop_flip == 1) { + /*printf("\t\t\tFlipping 1\n");*/ + SWAP(unsigned int, lt_iter.e->v1, lt_iter.e->v2); + } + /* else { + printf("\t\t\tFlipping Not 1\n"); + }*/ + } + /* else { + printf("\t\tIncorrect edge topology"); + }*/ + } + /* else { + printf("\t\tNo Edge at this point\n"); + }*/ + screwvert_iter_step(<_iter); + } + } + } + } + + /* *VERTEX NORMALS* + * we know the surrounding edges are ordered correctly now + * so its safe to create vertex normals. + * + * calculate vertex normals that can be propagated on lathing + * use edge connectivity work this out */ + if (SV_IS_VALID(vc->v[0])) { + if (SV_IS_VALID(vc->v[1])) { + /* 2 edges connedted */ + /* make 2 connecting vert locations relative to the middle vert */ + sub_v3_v3v3(tmp_vec1, mvert_new[vc->v[0]].co, mvert_new[i].co); + sub_v3_v3v3(tmp_vec2, mvert_new[vc->v[1]].co, mvert_new[i].co); + /* normalize so both edges have the same influence, no matter their length */ + normalize_v3(tmp_vec1); + normalize_v3(tmp_vec2); + + /* vc_no_tmp1 - this line is the average direction of both connecting edges + * + * Use the edge order to make the subtraction, flip the normal the right way + * edge should be there but check just in case... */ + if (vc->e[0]->v1 == i) { + sub_v3_v3(tmp_vec1, tmp_vec2); + } + else { + sub_v3_v3v3(tmp_vec1, tmp_vec2, tmp_vec1); + } + } + else { + /* only 1 edge connected - same as above except + * don't need to average edge direction */ + if (vc->e[0]->v2 == i) { + sub_v3_v3v3(tmp_vec1, mvert_new[i].co, mvert_new[vc->v[0]].co); + } + else { + sub_v3_v3v3(tmp_vec1, mvert_new[vc->v[0]].co, mvert_new[i].co); + } + } + + /* tmp_vec2 - is a line 90d from the pivot to the vec + * This is used so the resulting normal points directly away from the middle */ + cross_v3_v3v3(tmp_vec2, axis_vec, vc->co); + + if (UNLIKELY(is_zero_v3(tmp_vec2))) { + /* we're _on_ the axis, so copy it based on our winding */ + if (vc->e[0]->v2 == i) { + negate_v3_v3(vc->no, axis_vec); + } + else { + copy_v3_v3(vc->no, axis_vec); + } + } + else { + /* edge average vector and right angle to the pivot make the normal */ + cross_v3_v3v3(vc->no, tmp_vec1, tmp_vec2); + } + } + else { + copy_v3_v3(vc->no, vc->co); + } + + /* we won't be looping on this data again so copy normals here */ + if ((angle < 0.0f) != do_flip) + negate_v3(vc->no); + + normalize_v3(vc->no); + normal_float_to_short_v3(mvert_new[i].no, vc->no); + + /* Done with normals */ + } + } + } + else { + mv_orig = mvert_orig; + mv_new = mvert_new; + + for (i = 0; i < totvert; i++, mv_new++, mv_orig++) { + copy_v3_v3(mv_new->co, mv_orig->co); + } + } + /* done with edge connectivity based normal flipping */ + + /* Add Faces */ + for (step = 1; step < step_tot; step++) { + const unsigned int varray_stride = totvert * step; + float step_angle; + float nor_tx[3]; + float mat[4][4]; + /* Rotation Matrix */ + step_angle = (angle / (float)(step_tot - (!close))) * (float)step; + + if (ob_axis != NULL) { + axis_angle_normalized_to_mat3(mat3, axis_vec, step_angle); + } + else { + axis_angle_to_mat3_single(mat3, axis_char, step_angle); + } + copy_m4_m3(mat, mat3); + + if (screw_ofs) + madd_v3_v3fl(mat[3], axis_vec, screw_ofs * ((float)step / (float)(step_tot - 1))); + + /* copy a slice */ + CustomData_copy_data(&mesh->vdata, &result->vdata, 0, (int)varray_stride, (int)totvert); + + mv_new_base = mvert_new; + mv_new = &mvert_new[varray_stride]; /* advance to the next slice */ + + for (j = 0; j < totvert; j++, mv_new_base++, mv_new++) { + /* set normal */ + if (vert_connect) { + mul_v3_m3v3(nor_tx, mat3, vert_connect[j].no); + + /* set the normal now its transformed */ + normal_float_to_short_v3(mv_new->no, nor_tx); + } + + /* set location */ + copy_v3_v3(mv_new->co, mv_new_base->co); + + /* only need to set these if using non cleared memory */ + /*mv_new->mat_nr = mv_new->flag = 0;*/ + + if (ob_axis != NULL) { + sub_v3_v3(mv_new->co, mtx_tx[3]); + + mul_m4_v3(mat, mv_new->co); + + add_v3_v3(mv_new->co, mtx_tx[3]); + } + else { + mul_m4_v3(mat, mv_new->co); + } + + /* add the new edge */ + med_new->v1 = varray_stride + j; + med_new->v2 = med_new->v1 - totvert; + med_new->flag = ME_EDGEDRAW | ME_EDGERENDER; + med_new++; + } + } + + /* we can avoid if using vert alloc trick */ + if (vert_connect) { + MEM_freeN(vert_connect); + vert_connect = NULL; + } + + if (close) { + /* last loop of edges, previous loop doesn't account for the last set of edges */ + const unsigned int varray_stride = (step_tot - 1) * totvert; + + for (i = 0; i < totvert; i++) { + med_new->v1 = i; + med_new->v2 = varray_stride + i; + med_new->flag = ME_EDGEDRAW | ME_EDGERENDER; + med_new++; + } + } + + mp_new = mpoly_new; + ml_new = mloop_new; + med_new_firstloop = medge_new; + + /* more of an offset in this case */ + edge_offset = totedge + (totvert * (step_tot - (close ? 0 : 1))); + + for (i = 0; i < totedge; i++, med_new_firstloop++) { + const unsigned int step_last = step_tot - (close ? 1 : 2); + const unsigned int mpoly_index_orig = totpoly ? edge_poly_map[i] : UINT_MAX; + const bool has_mpoly_orig = (mpoly_index_orig != UINT_MAX); + float uv_v_offset_a, uv_v_offset_b; + + const unsigned int mloop_index_orig[2] = { + vert_loop_map ? vert_loop_map[medge_new[i].v1] : UINT_MAX, + vert_loop_map ? vert_loop_map[medge_new[i].v2] : UINT_MAX, + }; + const bool has_mloop_orig = mloop_index_orig[0] != UINT_MAX; + + short mat_nr; + + /* for each edge, make a cylinder of quads */ + i1 = med_new_firstloop->v1; + i2 = med_new_firstloop->v2; + + if (has_mpoly_orig) { + mat_nr = mpoly_orig[mpoly_index_orig].mat_nr; + } + else { + mat_nr = 0; + } + + if (has_mloop_orig == false && mloopuv_layers_tot) { + uv_v_offset_a = dist_signed_to_plane_v3(mvert_new[medge_new[i].v1].co, uv_axis_plane); + uv_v_offset_b = dist_signed_to_plane_v3(mvert_new[medge_new[i].v2].co, uv_axis_plane); + + if (ltmd->flag & MOD_SCREW_UV_STRETCH_V) { + uv_v_offset_a = (uv_v_offset_a - uv_v_minmax[0]) * uv_v_range_inv; + uv_v_offset_b = (uv_v_offset_b - uv_v_minmax[0]) * uv_v_range_inv; + } + } + + for (step = 0; step <= step_last; step++) { + + /* Polygon */ + if (has_mpoly_orig) { + CustomData_copy_data( + &mesh->pdata, &result->pdata, (int)mpoly_index_orig, (int)mpoly_index, 1); + origindex[mpoly_index] = (int)mpoly_index_orig; + } + else { + origindex[mpoly_index] = ORIGINDEX_NONE; + mp_new->flag = mpoly_flag; + mp_new->mat_nr = mat_nr; + } + mp_new->loopstart = mpoly_index * 4; + mp_new->totloop = 4; + + /* Loop-Custom-Data */ + if (has_mloop_orig) { + int l_index = (int)(ml_new - mloop_new); + + CustomData_copy_data( + &mesh->ldata, &result->ldata, (int)mloop_index_orig[0], l_index + 0, 1); + CustomData_copy_data( + &mesh->ldata, &result->ldata, (int)mloop_index_orig[1], l_index + 1, 1); + CustomData_copy_data( + &mesh->ldata, &result->ldata, (int)mloop_index_orig[1], l_index + 2, 1); + CustomData_copy_data( + &mesh->ldata, &result->ldata, (int)mloop_index_orig[0], l_index + 3, 1); + + if (mloopuv_layers_tot) { + unsigned int uv_lay; + const float uv_u_offset_a = (float)(step)*uv_u_scale; + const float uv_u_offset_b = (float)(step + 1) * uv_u_scale; + for (uv_lay = 0; uv_lay < mloopuv_layers_tot; uv_lay++) { + MLoopUV *mluv = &mloopuv_layers[uv_lay][l_index]; + + mluv[quad_ord[0]].uv[0] += uv_u_offset_a; + mluv[quad_ord[1]].uv[0] += uv_u_offset_a; + mluv[quad_ord[2]].uv[0] += uv_u_offset_b; + mluv[quad_ord[3]].uv[0] += uv_u_offset_b; + } + } + } + else { + if (mloopuv_layers_tot) { + int l_index = (int)(ml_new - mloop_new); + + unsigned int uv_lay; + const float uv_u_offset_a = (float)(step)*uv_u_scale; + const float uv_u_offset_b = (float)(step + 1) * uv_u_scale; + for (uv_lay = 0; uv_lay < mloopuv_layers_tot; uv_lay++) { + MLoopUV *mluv = &mloopuv_layers[uv_lay][l_index]; + + copy_v2_fl2(mluv[quad_ord[0]].uv, uv_u_offset_a, uv_v_offset_a); + copy_v2_fl2(mluv[quad_ord[1]].uv, uv_u_offset_a, uv_v_offset_b); + copy_v2_fl2(mluv[quad_ord[2]].uv, uv_u_offset_b, uv_v_offset_b); + copy_v2_fl2(mluv[quad_ord[3]].uv, uv_u_offset_b, uv_v_offset_a); + } + } + } + + /* Loop-Data */ + if (!(close && step == step_last)) { + /* regular segments */ + ml_new[quad_ord[0]].v = i1; + ml_new[quad_ord[1]].v = i2; + ml_new[quad_ord[2]].v = i2 + totvert; + ml_new[quad_ord[3]].v = i1 + totvert; + + ml_new[quad_ord_ofs[0]].e = step == 0 ? i : + (edge_offset + step + (i * (step_tot - 1))) - 1; + ml_new[quad_ord_ofs[1]].e = totedge + i2; + ml_new[quad_ord_ofs[2]].e = edge_offset + step + (i * (step_tot - 1)); + ml_new[quad_ord_ofs[3]].e = totedge + i1; + + /* new vertical edge */ + if (step) { /* The first set is already done */ + med_new->v1 = i1; + med_new->v2 = i2; + med_new->flag = med_new_firstloop->flag; + med_new->crease = med_new_firstloop->crease; + med_new++; + } + i1 += totvert; + i2 += totvert; + } + else { + /* last segment */ + ml_new[quad_ord[0]].v = i1; + ml_new[quad_ord[1]].v = i2; + ml_new[quad_ord[2]].v = med_new_firstloop->v2; + ml_new[quad_ord[3]].v = med_new_firstloop->v1; + + ml_new[quad_ord_ofs[0]].e = (edge_offset + step + (i * (step_tot - 1))) - 1; + ml_new[quad_ord_ofs[1]].e = totedge + i2; + ml_new[quad_ord_ofs[2]].e = i; + ml_new[quad_ord_ofs[3]].e = totedge + i1; + } + + mp_new++; + ml_new += 4; + mpoly_index++; + } + + /* new vertical edge */ + med_new->v1 = i1; + med_new->v2 = i2; + med_new->flag = med_new_firstloop->flag & ~ME_LOOSEEDGE; + med_new->crease = med_new_firstloop->crease; + med_new++; + } + + /* validate loop edges */ #if 0 - { - unsigned i = 0; - printf("\n"); - for (; i < maxPolys * 4; i += 4) { - unsigned int ii; - ml_new = mloop_new + i; - ii = findEd(medge_new, maxEdges, ml_new[0].v, ml_new[1].v); - printf("%d %d -- ", ii, ml_new[0].e); - ml_new[0].e = ii; - - ii = findEd(medge_new, maxEdges, ml_new[1].v, ml_new[2].v); - printf("%d %d -- ", ii, ml_new[1].e); - ml_new[1].e = ii; - - ii = findEd(medge_new, maxEdges, ml_new[2].v, ml_new[3].v); - printf("%d %d -- ", ii, ml_new[2].e); - ml_new[2].e = ii; - - ii = findEd(medge_new, maxEdges, ml_new[3].v, ml_new[0].v); - printf("%d %d\n", ii, ml_new[3].e); - ml_new[3].e = ii; - - } - } + { + unsigned i = 0; + printf("\n"); + for (; i < maxPolys * 4; i += 4) { + unsigned int ii; + ml_new = mloop_new + i; + ii = findEd(medge_new, maxEdges, ml_new[0].v, ml_new[1].v); + printf("%d %d -- ", ii, ml_new[0].e); + ml_new[0].e = ii; + + ii = findEd(medge_new, maxEdges, ml_new[1].v, ml_new[2].v); + printf("%d %d -- ", ii, ml_new[1].e); + ml_new[1].e = ii; + + ii = findEd(medge_new, maxEdges, ml_new[2].v, ml_new[3].v); + printf("%d %d -- ", ii, ml_new[2].e); + ml_new[2].e = ii; + + ii = findEd(medge_new, maxEdges, ml_new[3].v, ml_new[0].v); + printf("%d %d\n", ii, ml_new[3].e); + ml_new[3].e = ii; + + } + } #endif - if (edge_poly_map) { - MEM_freeN(edge_poly_map); - } - - if (vert_loop_map) { - MEM_freeN(vert_loop_map); - } - - if ((ltmd->flag & MOD_SCREW_MERGE) && (screw_ofs == 0.0f)) { - Mesh *result_prev = result; - result = mesh_remove_doubles_on_axis( - result, mvert_new, totvert, step_tot, - axis_vec, ob_axis != NULL ? mtx_tx[3] : NULL, ltmd->merge_dist); - if (result != result_prev) { - result->runtime.cd_dirty_vert |= CD_MASK_NORMAL; - } - } - - if ((ltmd->flag & MOD_SCREW_NORMAL_CALC) == 0) { - result->runtime.cd_dirty_vert |= CD_MASK_NORMAL; - } - - return result; + if (edge_poly_map) { + MEM_freeN(edge_poly_map); + } + + if (vert_loop_map) { + MEM_freeN(vert_loop_map); + } + + if ((ltmd->flag & MOD_SCREW_MERGE) && (screw_ofs == 0.0f)) { + Mesh *result_prev = result; + result = mesh_remove_doubles_on_axis(result, + mvert_new, + totvert, + step_tot, + axis_vec, + ob_axis != NULL ? mtx_tx[3] : NULL, + ltmd->merge_dist); + if (result != result_prev) { + result->runtime.cd_dirty_vert |= CD_MASK_NORMAL; + } + } + + if ((ltmd->flag & MOD_SCREW_NORMAL_CALC) == 0) { + result->runtime.cd_dirty_vert |= CD_MASK_NORMAL; + } + + return result; } static void updateDepsgraph(ModifierData *md, const ModifierUpdateDepsgraphContext *ctx) { - ScrewModifierData *ltmd = (ScrewModifierData *)md; - if (ltmd->ob_axis != NULL) { - DEG_add_object_relation(ctx->node, ltmd->ob_axis, DEG_OB_COMP_TRANSFORM, "Screw Modifier"); - DEG_add_modifier_to_transform_relation(ctx->node, "Screw Modifier"); - } + ScrewModifierData *ltmd = (ScrewModifierData *)md; + if (ltmd->ob_axis != NULL) { + DEG_add_object_relation(ctx->node, ltmd->ob_axis, DEG_OB_COMP_TRANSFORM, "Screw Modifier"); + DEG_add_modifier_to_transform_relation(ctx->node, "Screw Modifier"); + } } -static void foreachObjectLink( - ModifierData *md, Object *ob, - ObjectWalkFunc walk, void *userData) +static void foreachObjectLink(ModifierData *md, Object *ob, ObjectWalkFunc walk, void *userData) { - ScrewModifierData *ltmd = (ScrewModifierData *) md; + ScrewModifierData *ltmd = (ScrewModifierData *)md; - walk(userData, ob, <md->ob_axis, IDWALK_CB_NOP); + walk(userData, ob, <md->ob_axis, IDWALK_CB_NOP); } ModifierTypeInfo modifierType_Screw = { - /* name */ "Screw", - /* structName */ "ScrewModifierData", - /* structSize */ sizeof(ScrewModifierData), - /* type */ eModifierTypeType_Constructive, - - /* flags */ eModifierTypeFlag_AcceptsMesh | - eModifierTypeFlag_AcceptsCVs | - eModifierTypeFlag_SupportsEditmode | - eModifierTypeFlag_EnableInEditmode, - - /* copyData */ modifier_copyData_generic, - - /* deformVerts */ NULL, - /* deformMatrices */ NULL, - /* deformVertsEM */ NULL, - /* deformMatricesEM */ NULL, - /* applyModifier */ applyModifier, - - /* initData */ initData, - /* requiredDataMask */ NULL, - /* freeData */ NULL, - /* isDisabled */ NULL, - /* updateDepsgraph */ updateDepsgraph, - /* dependsOnTime */ NULL, - /* dependsOnNormals */ NULL, - /* foreachObjectLink */ foreachObjectLink, - /* foreachIDLink */ NULL, - /* foreachTexLink */ NULL, - /* freeRuntimeData */ NULL, + /* name */ "Screw", + /* structName */ "ScrewModifierData", + /* structSize */ sizeof(ScrewModifierData), + /* type */ eModifierTypeType_Constructive, + + /* flags */ eModifierTypeFlag_AcceptsMesh | eModifierTypeFlag_AcceptsCVs | + eModifierTypeFlag_SupportsEditmode | eModifierTypeFlag_EnableInEditmode, + + /* copyData */ modifier_copyData_generic, + + /* deformVerts */ NULL, + /* deformMatrices */ NULL, + /* deformVertsEM */ NULL, + /* deformMatricesEM */ NULL, + /* applyModifier */ applyModifier, + + /* initData */ initData, + /* requiredDataMask */ NULL, + /* freeData */ NULL, + /* isDisabled */ NULL, + /* updateDepsgraph */ updateDepsgraph, + /* dependsOnTime */ NULL, + /* dependsOnNormals */ NULL, + /* foreachObjectLink */ foreachObjectLink, + /* foreachIDLink */ NULL, + /* foreachTexLink */ NULL, + /* freeRuntimeData */ NULL, }; -- cgit v1.2.3