Changeset View
Changeset View
Standalone View
Standalone View
source/blender/modifiers/intern/MOD_screw.c
| Show First 20 Lines • Show All 50 Lines • ▼ Show 20 Lines | |||||
| } | } | ||||
| #include "BLI_strict_flags.h" | #include "BLI_strict_flags.h" | ||||
| /* used for gathering edge connectivity */ | /* used for gathering edge connectivity */ | ||||
| typedef struct ScrewVertConnect { | typedef struct ScrewVertConnect { | ||||
| float dist; /* distance from the center axis */ | float dist; /* distance from the center axis */ | ||||
| float co[3]; /* location relative to the transformed axis */ | float co[3]; /* location relative to the transformed axis */ | ||||
| float no[3]; /* calc normal of the vertex */ | |||||
| uint v[2]; /* 2 verts on either side of this one */ | uint 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 */ | MEdge *e[2]; /* edges on either side, a bit of a waste since each edge ref's 2 edges */ | ||||
| char flag; | char flag; | ||||
| } ScrewVertConnect; | } ScrewVertConnect; | ||||
| typedef struct ScrewVertIter { | typedef struct ScrewVertIter { | ||||
| ScrewVertConnect *v_array; | ScrewVertConnect *v_array; | ||||
| ScrewVertConnect *v_poin; | ScrewVertConnect *v_poin; | ||||
| ▲ Show 20 Lines • Show All 303 Lines • ▼ Show 20 Lines | #endif | ||||
| } | } | ||||
| if ((ltmd->flag & MOD_SCREW_UV_STRETCH_U) == 0) { | if ((ltmd->flag & MOD_SCREW_UV_STRETCH_U) == 0) { | ||||
| uv_u_scale = (uv_u_scale / (float)ltmd->iter) * (angle / ((float)M_PI * 2.0f)); | uv_u_scale = (uv_u_scale / (float)ltmd->iter) * (angle / ((float)M_PI * 2.0f)); | ||||
| } | } | ||||
| /* The `screw_ofs` cannot change from now on. */ | /* The `screw_ofs` cannot change from now on. */ | ||||
| const bool do_remove_doubles = (ltmd->flag & MOD_SCREW_MERGE) && (screw_ofs == 0.0f); | const bool do_remove_doubles = (ltmd->flag & MOD_SCREW_MERGE) && (screw_ofs == 0.0f); | ||||
| /* Only calculate normals if `do_remove_doubles` since removing doubles frees the normals. */ | |||||
| const bool do_normal_create = (ltmd->flag & MOD_SCREW_NORMAL_CALC) && | |||||
| (do_remove_doubles == false); | |||||
| result = BKE_mesh_new_nomain_from_template( | result = BKE_mesh_new_nomain_from_template( | ||||
| mesh, (int)maxVerts, (int)maxEdges, 0, (int)maxPolys * 4, (int)maxPolys); | mesh, (int)maxVerts, (int)maxEdges, 0, (int)maxPolys * 4, (int)maxPolys); | ||||
| /* copy verts from mesh */ | /* copy verts from mesh */ | ||||
| mvert_orig = mesh->mvert; | mvert_orig = mesh->mvert; | ||||
| medge_orig = mesh->medge; | medge_orig = mesh->medge; | ||||
| ▲ Show 20 Lines • Show All 81 Lines • ▼ Show 20 Lines | for (i = 0, mp_orig = mpoly_orig; i < totpoly; i++, mp_orig++) { | ||||
| /* also order edges based on faces */ | /* also order edges based on faces */ | ||||
| if (medge_new[ml_orig->e].v1 != ml_orig->v) { | if (medge_new[ml_orig->e].v1 != ml_orig->v) { | ||||
| SWAP(uint, medge_new[ml_orig->e].v1, medge_new[ml_orig->e].v2); | SWAP(uint, medge_new[ml_orig->e].v1, medge_new[ml_orig->e].v2); | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| float(*vert_normals_new)[3] = do_normal_create ? BKE_mesh_vertex_normals_for_write(result) : | |||||
| NULL; | |||||
| if (ltmd->flag & MOD_SCREW_NORMAL_CALC) { | if (ltmd->flag & MOD_SCREW_NORMAL_CALC) { | ||||
| /* | /* | ||||
| * Normal Calculation (for face flipping) | * Normal Calculation (for face flipping) | ||||
| * Sort edge verts for correct face flipping | * Sort edge verts for correct face flipping | ||||
| * NOT REALLY NEEDED but face flipping is nice. */ | * NOT REALLY NEEDED but face flipping is nice. */ | ||||
| /* Notice! | /* Notice! | ||||
| Show All 13 Lines | if (ltmd->flag & MOD_SCREW_NORMAL_CALC) { | ||||
| */ | */ | ||||
| vert_connect = MEM_malloc_arrayN(totvert, sizeof(ScrewVertConnect), "ScrewVertConnect"); | vert_connect = MEM_malloc_arrayN(totvert, sizeof(ScrewVertConnect), "ScrewVertConnect"); | ||||
| /* skip the first slice of verts. */ | /* skip the first slice of verts. */ | ||||
| // vert_connect = (ScrewVertConnect *) &medge_new[totvert]; | // vert_connect = (ScrewVertConnect *) &medge_new[totvert]; | ||||
| vc = vert_connect; | vc = vert_connect; | ||||
| /* Copy Vert Locations */ | /* Copy Vert Locations */ | ||||
| /* - We can do this in a later loop - only do here if no normal calc */ | if (totedge != 0) { | ||||
| 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"); | // printf("\n\n\n\n\nStarting Modifier\n"); | ||||
| /* set edge users */ | /* set edge users */ | ||||
| med_new = medge_new; | med_new = medge_new; | ||||
| mv_new = mvert_new; | mv_new = mvert_new; | ||||
| if (ob_axis != NULL) { | if (ob_axis != NULL) { | ||||
| /* `mtx_tx` is initialized early on. */ | /* `mtx_tx` is initialized early on. */ | ||||
| for (i = 0; i < totvert; i++, mv_new++, mv_orig++, vc++) { | for (i = 0; i < totvert; i++, mv_new++, mv_orig++, vc++) { | ||||
| ▲ Show 20 Lines • Show All 235 Lines • ▼ Show 20 Lines | #if 0 | ||||
| printf("\t\tNo Edge at this point\n"); | printf("\t\tNo Edge at this point\n"); | ||||
| } | } | ||||
| #endif | #endif | ||||
| screwvert_iter_step(<_iter); | 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 (do_normal_create) { | |||||
| if (SV_IS_VALID(vc->v[0])) { | |||||
| if (SV_IS_VALID(vc->v[1])) { | |||||
| /* 2 edges connected. */ | |||||
| /* 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); | |||||
| copy_v3_v3(vert_normals_new[i], vc->no); | |||||
| } | |||||
| /* Done with normals */ | |||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| else { | else { | ||||
| mv_orig = mvert_orig; | mv_orig = mvert_orig; | ||||
| mv_new = mvert_new; | mv_new = mvert_new; | ||||
| for (i = 0; i < totvert; i++, mv_new++, mv_orig++) { | for (i = 0; i < totvert; i++, mv_new++, mv_orig++) { | ||||
| Show All 24 Lines | for (step = 1; step < step_tot; step++) { | ||||
| /* copy a slice */ | /* copy a slice */ | ||||
| CustomData_copy_data(&mesh->vdata, &result->vdata, 0, (int)varray_stride, (int)totvert); | CustomData_copy_data(&mesh->vdata, &result->vdata, 0, (int)varray_stride, (int)totvert); | ||||
| mv_new_base = mvert_new; | mv_new_base = mvert_new; | ||||
| mv_new = &mvert_new[varray_stride]; /* advance to the next slice */ | mv_new = &mvert_new[varray_stride]; /* advance to the next slice */ | ||||
| for (j = 0; j < totvert; j++, mv_new_base++, mv_new++) { | for (j = 0; j < totvert; j++, mv_new_base++, mv_new++) { | ||||
| /* set normal */ | |||||
| if (vert_connect) { | |||||
| if (do_normal_create) { | |||||
| /* Set the normal now its transformed. */ | |||||
| mul_v3_m3v3(vert_normals_new[mv_new - mvert_new], mat3, vert_connect[j].no); | |||||
| } | |||||
| } | |||||
| /* set location */ | /* set location */ | ||||
| copy_v3_v3(mv_new->co, mv_new_base->co); | copy_v3_v3(mv_new->co, mv_new_base->co); | ||||
| /* only need to set these if using non cleared memory */ | /* only need to set these if using non cleared memory */ | ||||
| // mv_new->mat_nr = mv_new->flag = 0; | // mv_new->mat_nr = mv_new->flag = 0; | ||||
| if (ob_axis != NULL) { | if (ob_axis != NULL) { | ||||
| sub_v3_v3(mv_new->co, mtx_tx[3]); | sub_v3_v3(mv_new->co, mtx_tx[3]); | ||||
| ▲ Show 20 Lines • Show All 224 Lines • ▼ Show 20 Lines | #endif | ||||
| if (edge_poly_map) { | if (edge_poly_map) { | ||||
| MEM_freeN(edge_poly_map); | MEM_freeN(edge_poly_map); | ||||
| } | } | ||||
| if (vert_loop_map) { | if (vert_loop_map) { | ||||
| MEM_freeN(vert_loop_map); | MEM_freeN(vert_loop_map); | ||||
| } | } | ||||
| if (do_normal_create) { | |||||
| BKE_mesh_vertex_normals_clear_dirty(result); | |||||
| } | |||||
| if (do_remove_doubles) { | if (do_remove_doubles) { | ||||
| result = mesh_remove_doubles_on_axis(result, | result = mesh_remove_doubles_on_axis(result, | ||||
| mvert_new, | mvert_new, | ||||
| totvert, | totvert, | ||||
| step_tot, | step_tot, | ||||
| axis_vec, | axis_vec, | ||||
| ob_axis != NULL ? mtx_tx[3] : NULL, | ob_axis != NULL ? mtx_tx[3] : NULL, | ||||
| ltmd->merge_dist); | ltmd->merge_dist); | ||||
| ▲ Show 20 Lines • Show All 130 Lines • Show Last 20 Lines | |||||