Changeset View
Changeset View
Standalone View
Standalone View
source/blender/bmesh/operators/bmo_inset.c
| Show First 20 Lines • Show All 490 Lines • ▼ Show 20 Lines | if (LIKELY(l != NULL)) { | ||||
| return ((tot_tag == 1) && (tot_untag >= 1)) ? l_tag : NULL; | return ((tot_tag == 1) && (tot_untag >= 1)) ? l_tag : NULL; | ||||
| } | } | ||||
| else { | else { | ||||
| return NULL; | return NULL; | ||||
| } | } | ||||
| } | } | ||||
| static float bm_edge_info_average_length(BMVert *v, SplitEdgeInfo *edge_info) | static float bm_edge_info_average_length(BMesh *bm, BMVert *v, SplitEdgeInfo *edge_info) | ||||
| { | { | ||||
| BMIter iter; | BMIter iter; | ||||
| BMEdge *e; | BMEdge *e; | ||||
| float len = 0.0f; | float len = 0.0f; | ||||
| int tot = 0; | int tot = 0; | ||||
| BM_ITER_ELEM (e, &iter, v, BM_EDGES_OF_VERT) { | BM_ITER_ELEM (e, &iter, v, BM_EDGES_OF_VERT) { | ||||
| const int i = BM_elem_index_get(e); | const int i = BM_elem_index_get(e); | ||||
| if (i != -1) { | if (i != -1) { | ||||
| len += edge_info[i].length; | len += edge_info[i].length; | ||||
| tot++; | tot++; | ||||
| } | } | ||||
| } | } | ||||
| BLI_assert(tot != 0); | if (tot) { | ||||
| return len / (float)tot; | return len / (float)tot; | ||||
| } | } | ||||
| /* If we are stilll here we are looking at interior verts of the selection | |||||
| * that have no edge tagged. In this case we look for neighboring verts we can find | |||||
| * and use its average edge length instead. */ | |||||
| BMWalker walker; | |||||
| BMW_init(&walker, | |||||
| bm, | |||||
| BMW_CONNECTED_VERTEX, | |||||
| 0, | |||||
| 0, | |||||
| 0, | |||||
| BMW_FLAG_NOP, | |||||
| BMW_NIL_LAY); | |||||
| BMVert *v_found = NULL; | |||||
| BMVert *v_iter = NULL; | |||||
| for (v_iter = BMW_begin(&walker, v); v_iter != NULL; v_iter = BMW_step(&walker)) { | |||||
| BM_ITER_ELEM (e, &iter, v_iter, BM_EDGES_OF_VERT) { | |||||
| const int i = BM_elem_index_get(e); | |||||
| if (i != -1) { | |||||
| /* ok, this vert can be used */ | |||||
| v_found = v_iter; | |||||
| break; | |||||
| } | |||||
| } | |||||
| if (v_found != NULL) { | |||||
| break; | |||||
| } | |||||
| } | |||||
| BMW_end(&walker); | |||||
| if (v_found != NULL) { | |||||
| BM_ITER_ELEM (e, &iter, v_found, BM_EDGES_OF_VERT) { | |||||
| const int i = BM_elem_index_get(e); | |||||
| if (i != -1) { | |||||
| len += edge_info[i].length; | |||||
| tot++; | |||||
| } | |||||
| } | |||||
| if (tot) { | |||||
| return len / (float)tot; | |||||
| } | |||||
| } | |||||
| /* if finding neighboring verts also failed at least dont return NANs ;) */ | |||||
| return 0.0f; | |||||
| } | |||||
| /** | /** | ||||
| * implementation is as follows... | * implementation is as follows... | ||||
| * | * | ||||
| * - set all faces as tagged/untagged based on selection. | * - set all faces as tagged/untagged based on selection. | ||||
| * - find all edges that have 1 tagged, 1 untagged face. | * - find all edges that have 1 tagged, 1 untagged face. | ||||
| * - separate these edges and tag vertices, set their index to point to the original edge. | * - separate these edges and tag vertices, set their index to point to the original edge. | ||||
| * - build faces between old/new edges. | * - build faces between old/new edges. | ||||
| * - inset the new edges into their faces. | * - inset the new edges into their faces. | ||||
| ▲ Show 20 Lines • Show All 675 Lines • ▼ Show 20 Lines | if (depth != 0.0f) { | ||||
| * which BM_vert_calc_shell_factor uses. */ | * which BM_vert_calc_shell_factor uses. */ | ||||
| /* over allocate */ | /* over allocate */ | ||||
| varr_co = MEM_callocN(sizeof(*varr_co) * bm->totvert, __func__); | varr_co = MEM_callocN(sizeof(*varr_co) * bm->totvert, __func__); | ||||
| BM_ITER_MESH_INDEX (v, &iter, bm, BM_VERTS_OF_MESH, i) { | BM_ITER_MESH_INDEX (v, &iter, bm, BM_VERTS_OF_MESH, i) { | ||||
| if (BM_elem_flag_test(v, BM_ELEM_TAG)) { | if (BM_elem_flag_test(v, BM_ELEM_TAG)) { | ||||
| const float fac = (depth * | const float fac = (depth * | ||||
| (use_relative_offset ? bm_edge_info_average_length(v, edge_info) : | (use_relative_offset ? bm_edge_info_average_length(bm, v, edge_info) : | ||||
| 1.0f) * | 1.0f) * | ||||
| (use_even_boundary ? BM_vert_calc_shell_factor(v) : 1.0f)); | (use_even_boundary ? BM_vert_calc_shell_factor(v) : 1.0f)); | ||||
| madd_v3_v3v3fl(varr_co[i], v->co, v->no, fac); | madd_v3_v3v3fl(varr_co[i], v->co, v->no, fac); | ||||
| } | } | ||||
| } | } | ||||
| BM_ITER_MESH_INDEX (v, &iter, bm, BM_VERTS_OF_MESH, i) { | BM_ITER_MESH_INDEX (v, &iter, bm, BM_VERTS_OF_MESH, i) { | ||||
| if (BM_elem_flag_test(v, BM_ELEM_TAG)) { | if (BM_elem_flag_test(v, BM_ELEM_TAG)) { | ||||
| copy_v3_v3(v->co, varr_co[i]); | copy_v3_v3(v->co, varr_co[i]); | ||||
| } | } | ||||
| } | } | ||||
| MEM_freeN(varr_co); | MEM_freeN(varr_co); | ||||
| } | } | ||||
| MEM_freeN(edge_info); | MEM_freeN(edge_info); | ||||
| } | } | ||||