Changeset View
Changeset View
Standalone View
Standalone View
source/blender/bmesh/intern/bmesh_core.c
| Show First 20 Lines • Show All 1,799 Lines • ▼ Show 20 Lines | |||||
| * faces with just 2 edges. It is up to the caller to decide what to do with | * faces with just 2 edges. It is up to the caller to decide what to do with | ||||
| * these faces. | * these faces. | ||||
| */ | */ | ||||
| BMEdge *bmesh_kernel_join_edge_kill_vert(BMesh *bm, | BMEdge *bmesh_kernel_join_edge_kill_vert(BMesh *bm, | ||||
| BMEdge *e_kill, | BMEdge *e_kill, | ||||
| BMVert *v_kill, | BMVert *v_kill, | ||||
| const bool do_del, | const bool do_del, | ||||
| const bool check_edge_exists, | const bool check_edge_exists, | ||||
| const bool kill_degenerate_faces) | const bool kill_degenerate_faces, | ||||
| const bool kill_duplicate_faces) | |||||
| { | { | ||||
| BMEdge *e_old; | BMEdge *e_old; | ||||
| BMVert *v_old, *v_target; | BMVert *v_old, *v_target; | ||||
| BMLoop *l_kill; | BMLoop *l_kill; | ||||
| #ifndef NDEBUG | #ifndef NDEBUG | ||||
| int radlen, i; | int radlen, i; | ||||
| bool edok; | bool edok; | ||||
| #endif | #endif | ||||
| Show All 18 Lines | #endif | ||||
| if (BM_verts_in_edge(v_kill, v_target, e_old)) { | if (BM_verts_in_edge(v_kill, v_target, e_old)) { | ||||
| return NULL; | return NULL; | ||||
| } | } | ||||
| BMEdge *e_splice; | BMEdge *e_splice; | ||||
| BLI_SMALLSTACK_DECLARE(faces_degenerate, BMFace *); | BLI_SMALLSTACK_DECLARE(faces_degenerate, BMFace *); | ||||
| BMLoop *l_kill_next; | BMLoop *l_kill_next; | ||||
| /* Candidates for being duplicate. */ | |||||
| BLI_SMALLSTACK_DECLARE(faces_duplicate_candidate, BMFace *); | |||||
| #ifndef NDEBUG | #ifndef NDEBUG | ||||
| /* For verification later, count valence of 'v_old' and 'v_target' */ | /* For verification later, count valence of 'v_old' and 'v_target' */ | ||||
| valence1 = bmesh_disk_count(v_old); | valence1 = bmesh_disk_count(v_old); | ||||
| valence2 = bmesh_disk_count(v_target); | valence2 = bmesh_disk_count(v_target); | ||||
| #endif | #endif | ||||
| if (check_edge_exists) { | if (check_edge_exists) { | ||||
| e_splice = BM_edge_exists(v_target, v_old); | e_splice = BM_edge_exists(v_target, v_old); | ||||
| Show All 21 Lines | if (e_kill->l) { | ||||
| l_kill->next->prev = l_kill->prev; | l_kill->next->prev = l_kill->prev; | ||||
| l_kill->prev->next = l_kill->next; | l_kill->prev->next = l_kill->next; | ||||
| if (BM_FACE_FIRST_LOOP(l_kill->f) == l_kill) { | if (BM_FACE_FIRST_LOOP(l_kill->f) == l_kill) { | ||||
| BM_FACE_FIRST_LOOP(l_kill->f) = l_kill->next; | BM_FACE_FIRST_LOOP(l_kill->f) = l_kill->next; | ||||
| } | } | ||||
| /* fix len attribute of face */ | /* fix len attribute of face */ | ||||
| l_kill->f->len--; | l_kill->f->len--; | ||||
| if (kill_degenerate_faces) { | if (kill_degenerate_faces && (l_kill->f->len < 3)) { | ||||
| if (l_kill->f->len < 3) { | |||||
| BLI_SMALLSTACK_PUSH(faces_degenerate, l_kill->f); | BLI_SMALLSTACK_PUSH(faces_degenerate, l_kill->f); | ||||
| } | } | ||||
| else { | |||||
| /* The duplicate test isn't reliable at this point as `e_splice` might be set, | |||||
| * so the duplicate test needs to run once the edge has been spliced. */ | |||||
| if (kill_duplicate_faces) { | |||||
| BLI_SMALLSTACK_PUSH(faces_duplicate_candidate, l_kill->f); | |||||
| } | |||||
| } | } | ||||
| l_kill_next = l_kill->radial_next; | l_kill_next = l_kill->radial_next; | ||||
| bm_kill_only_loop(bm, l_kill); | bm_kill_only_loop(bm, l_kill); | ||||
| } while ((l_kill = l_kill_next) != e_kill->l); | } while ((l_kill = l_kill_next) != e_kill->l); | ||||
| /* `e_kill->l` is invalid but the edge is freed next. */ | /* `e_kill->l` is invalid but the edge is freed next. */ | ||||
| #ifndef NDEBUG | #ifndef NDEBUG | ||||
| ▲ Show 20 Lines • Show All 43 Lines • ▼ Show 20 Lines | #endif | ||||
| if (kill_degenerate_faces) { | if (kill_degenerate_faces) { | ||||
| BMFace *f_kill; | BMFace *f_kill; | ||||
| while ((f_kill = BLI_SMALLSTACK_POP(faces_degenerate))) { | while ((f_kill = BLI_SMALLSTACK_POP(faces_degenerate))) { | ||||
| BM_face_kill(bm, f_kill); | BM_face_kill(bm, f_kill); | ||||
| } | } | ||||
| } | } | ||||
| if (kill_duplicate_faces) { | |||||
| BMFace *f_kill; | |||||
| while ((f_kill = BLI_SMALLSTACK_POP(faces_duplicate_candidate))) { | |||||
| if (BM_face_find_double(f_kill)) { | |||||
| BM_face_kill(bm, f_kill); | |||||
| } | |||||
| } | |||||
| } | |||||
| BM_CHECK_ELEMENT(v_old); | BM_CHECK_ELEMENT(v_old); | ||||
| BM_CHECK_ELEMENT(v_target); | BM_CHECK_ELEMENT(v_target); | ||||
| BM_CHECK_ELEMENT(e_old); | BM_CHECK_ELEMENT(e_old); | ||||
| return e_old; | return e_old; | ||||
| } | } | ||||
| return NULL; | return NULL; | ||||
| } | } | ||||
| ▲ Show 20 Lines • Show All 1,005 Lines • Show Last 20 Lines | |||||