Changeset View
Changeset View
Standalone View
Standalone View
source/blender/bmesh/operators/bmo_connect_pair.c
| Show All 15 Lines | |||||
| /** \file | /** \file | ||||
| * \ingroup bmesh | * \ingroup bmesh | ||||
| * | * | ||||
| * Connect vertex pair across multiple faces (splits faces). | * Connect vertex pair across multiple faces (splits faces). | ||||
| */ | */ | ||||
| #include "MEM_guardedalloc.h" | #include "MEM_guardedalloc.h" | ||||
| #include <CLG_log.h> | |||||
| #include "BLI_heap_simple.h" | #include "BLI_heap_simple.h" | ||||
| #include "BLI_math.h" | #include "BLI_math.h" | ||||
| #include "BLI_utildefines.h" | #include "BLI_utildefines.h" | ||||
| #include "bmesh.h" | #include "bmesh.h" | ||||
| #include "intern/bmesh_operators_private.h" /* own include */ | #include "intern/bmesh_operators_private.h" /* own include */ | ||||
| ▲ Show 20 Lines • Show All 50 Lines • ▼ Show 20 Lines | |||||
| // #define ELE_TOUCH_MARK_VERT(v) BMO_vert_flag_enable(pc->bm_bmoflag, (BMElemF *)v, ELE_TOUCHED) | // #define ELE_TOUCH_MARK_VERT(v) BMO_vert_flag_enable(pc->bm_bmoflag, (BMElemF *)v, ELE_TOUCHED) | ||||
| #define ELE_TOUCH_TEST_EDGE(e) BMO_edge_flag_test(pc->bm_bmoflag, e, ELE_TOUCHED) | #define ELE_TOUCH_TEST_EDGE(e) BMO_edge_flag_test(pc->bm_bmoflag, e, ELE_TOUCHED) | ||||
| // #define ELE_TOUCH_MARK_EDGE(e) BMO_edge_flag_enable(pc->bm_bmoflag, (BMElemF *)e, ELE_TOUCHED) | // #define ELE_TOUCH_MARK_EDGE(e) BMO_edge_flag_enable(pc->bm_bmoflag, (BMElemF *)e, ELE_TOUCHED) | ||||
| // #define ELE_TOUCH_TEST_FACE(f) BMO_face_flag_test(pc->bm_bmoflag, f, ELE_TOUCHED) | // #define ELE_TOUCH_TEST_FACE(f) BMO_face_flag_test(pc->bm_bmoflag, f, ELE_TOUCHED) | ||||
| // #define ELE_TOUCH_MARK_FACE(f) BMO_face_flag_enable(pc->bm_bmoflag, (BMElemF *)f, ELE_TOUCHED) | // #define ELE_TOUCH_MARK_FACE(f) BMO_face_flag_enable(pc->bm_bmoflag, (BMElemF *)f, ELE_TOUCHED) | ||||
| // #define DEBUG_PRINT | static CLG_LogRef LOG = {"bmesh.bmo_connect_pair"}; | ||||
| typedef struct PathContext { | typedef struct PathContext { | ||||
| HeapSimple *states; | HeapSimple *states; | ||||
| float matrix[3][3]; | float matrix[3][3]; | ||||
| float axis_sep; | float axis_sep; | ||||
| /* only to access BMO flags */ | /* only to access BMO flags */ | ||||
| BMesh *bm_bmoflag; | BMesh *bm_bmoflag; | ||||
| ▲ Show 20 Lines • Show All 144 Lines • ▼ Show 20 Lines | |||||
| { | { | ||||
| PathLink *step_new = BLI_mempool_alloc(pc->link_pool); | PathLink *step_new = BLI_mempool_alloc(pc->link_pool); | ||||
| BLI_assert(ele != ele_from); | BLI_assert(ele != ele_from); | ||||
| BLI_assert(state_link_find(state, ele) == false); | BLI_assert(state_link_find(state, ele) == false); | ||||
| /* never walk onto this again */ | /* never walk onto this again */ | ||||
| ELE_TOUCH_MARK(ele); | ELE_TOUCH_MARK(ele); | ||||
| #ifdef DEBUG_PRINT | CLOG_DEBUG(&LOG, 1, "adding to state %p, %.4f - ", state, state->dist); | ||||
| printf("%s: adding to state %p, %.4f - ", __func__, state, state->dist); | |||||
| if (ele->head.htype == BM_VERT) { | if (ele->head.htype == BM_VERT) { | ||||
| printf("vert %d, ", BM_elem_index_get(ele)); | CLOG_DEBUG(&LOG, 1, "vert %d, ", BM_elem_index_get(ele)); | ||||
| } | } | ||||
| else if (ele->head.htype == BM_EDGE) { | else if (ele->head.htype == BM_EDGE) { | ||||
| printf("edge %d, ", BM_elem_index_get(ele)); | CLOG_DEBUG(&LOG, 1, "edge %d, ", BM_elem_index_get(ele)); | ||||
| } | } | ||||
| else { | else { | ||||
| BLI_assert(0); | BLI_assert(0); | ||||
| } | } | ||||
| if (ele_from == NULL) { | if (ele_from == NULL) { | ||||
| printf("from NULL\n"); | CLOG_STR_DEBUG(&LOG, 1, "from NULL"); | ||||
| } | } | ||||
| else if (ele_from->head.htype == BM_EDGE) { | else if (ele_from->head.htype == BM_EDGE) { | ||||
| printf("from edge %d\n", BM_elem_index_get(ele_from)); | CLOG_DEBUG(&LOG, 1, "from edge %d", BM_elem_index_get(ele_from)); | ||||
| } | } | ||||
| else if (ele_from->head.htype == BM_FACE) { | else if (ele_from->head.htype == BM_FACE) { | ||||
| printf("from face %d\n", BM_elem_index_get(ele_from)); | CLOG_DEBUG(&LOG, 1, "from face %d", BM_elem_index_get(ele_from)); | ||||
| } | } | ||||
| else { | else { | ||||
| BLI_assert(0); | BLI_assert(0); | ||||
| } | } | ||||
| #endif | |||||
| /* track distance */ | /* track distance */ | ||||
| { | { | ||||
| float co[3]; | float co[3]; | ||||
| if (ele->head.htype == BM_VERT) { | if (ele->head.htype == BM_VERT) { | ||||
| copy_v3_v3(co, ((BMVert *)ele)->co); | copy_v3_v3(co, ((BMVert *)ele)->co); | ||||
| } | } | ||||
| else if (ele->head.htype == BM_EDGE) { | else if (ele->head.htype == BM_EDGE) { | ||||
| ▲ Show 20 Lines • Show All 327 Lines • ▼ Show 20 Lines | void bmo_connect_vert_pair_exec(BMesh *bm, BMOperator *op) | ||||
| pc.v_a = ((BMVert **)op_verts_slot->data.p)[0]; | pc.v_a = ((BMVert **)op_verts_slot->data.p)[0]; | ||||
| pc.v_b = ((BMVert **)op_verts_slot->data.p)[1]; | pc.v_b = ((BMVert **)op_verts_slot->data.p)[1]; | ||||
| /* fail! */ | /* fail! */ | ||||
| if (!(pc.v_a && pc.v_b)) { | if (!(pc.v_a && pc.v_b)) { | ||||
| return; | return; | ||||
| } | } | ||||
| #ifdef DEBUG_PRINT | CLOG_DEBUG(&LOG, 6, "v_a: %d", BM_elem_index_get(pc.v_a)); | ||||
| printf("%s: v_a: %d\n", __func__, BM_elem_index_get(pc.v_a)); | CLOG_DEBUG(&LOG, 6, "v_b: %d", BM_elem_index_get(pc.v_b)); | ||||
| printf("%s: v_b: %d\n", __func__, BM_elem_index_get(pc.v_b)); | |||||
| #endif | |||||
| /* tag so we won't touch ever (typically hidden faces) */ | /* tag so we won't touch ever (typically hidden faces) */ | ||||
| BMO_slot_buffer_flag_enable(bm, op->slots_in, "faces_exclude", BM_FACE, FACE_EXCLUDE); | BMO_slot_buffer_flag_enable(bm, op->slots_in, "faces_exclude", BM_FACE, FACE_EXCLUDE); | ||||
| BMO_slot_buffer_flag_enable(bm, op->slots_in, "verts_exclude", BM_VERT, VERT_EXCLUDE); | BMO_slot_buffer_flag_enable(bm, op->slots_in, "verts_exclude", BM_VERT, VERT_EXCLUDE); | ||||
| /* setup context */ | /* setup context */ | ||||
| { | { | ||||
| pc.states = BLI_heapsimple_new(); | pc.states = BLI_heapsimple_new(); | ||||
| Show All 11 Lines | /* add first vertex */ | ||||
| PathLinkState *state; | PathLinkState *state; | ||||
| state = MEM_callocN(sizeof(*state), __func__); | state = MEM_callocN(sizeof(*state), __func__); | ||||
| state_link_add(&pc, state, (BMElem *)pc.v_a, NULL); | state_link_add(&pc, state, (BMElem *)pc.v_a, NULL); | ||||
| BLI_heapsimple_insert(pc.states, state->dist, state); | BLI_heapsimple_insert(pc.states, state->dist, state); | ||||
| } | } | ||||
| while (!BLI_heapsimple_is_empty(pc.states)) { | while (!BLI_heapsimple_is_empty(pc.states)) { | ||||
| #ifdef DEBUG_PRINT | CLOG_DEBUG(&LOG, 3, "stepping %u", BLI_heapsimple_len(pc.states)); | ||||
| printf("\n%s: stepping %u\n", __func__, BLI_heapsimple_len(pc.states)); | |||||
| #endif | |||||
| while (!BLI_heapsimple_is_empty(pc.states)) { | while (!BLI_heapsimple_is_empty(pc.states)) { | ||||
| PathLinkState *state = BLI_heapsimple_pop_min(pc.states); | PathLinkState *state = BLI_heapsimple_pop_min(pc.states); | ||||
| /* either we insert this into 'pc.states' or its freed */ | /* either we insert this into 'pc.states' or its freed */ | ||||
| bool continue_search; | bool continue_search; | ||||
| if (state->link_last->ele == (BMElem *)pc.v_b) { | if (state->link_last->ele == (BMElem *)pc.v_b) { | ||||
| /* pass, wait until all are found */ | /* pass, wait until all are found */ | ||||
| #ifdef DEBUG_PRINT | CLOG_DEBUG(&LOG, 3, "state %p loop found %.4f", state, state->dist); | ||||
| printf("%s: state %p loop found %.4f\n", __func__, state, state->dist); | |||||
| #endif | |||||
| state_best = *state; | state_best = *state; | ||||
| /* we're done, exit all loops */ | /* we're done, exit all loops */ | ||||
| BLI_heapsimple_clear(pc.states, MEM_freeN); | BLI_heapsimple_clear(pc.states, MEM_freeN); | ||||
| continue_search = false; | continue_search = false; | ||||
| } | } | ||||
| else if (state_step(&pc, state)) { | else if (state_step(&pc, state)) { | ||||
| continue_search = true; | continue_search = true; | ||||
| } | } | ||||
| else { | else { | ||||
| /* didn't reach the end, remove it, | /* didn't reach the end, remove it, | ||||
| * links are shared between states so just free the link_pool at the end */ | * links are shared between states so just free the link_pool at the end */ | ||||
| CLOG_DEBUG(&LOG, 3, "state %p removed", state); | |||||
| #ifdef DEBUG_PRINT | |||||
| printf("%s: state %p removed\n", __func__, state); | |||||
| #endif | |||||
| continue_search = false; | continue_search = false; | ||||
| } | } | ||||
| if (continue_search) { | if (continue_search) { | ||||
| BLI_heapsimple_insert(pc.states, state->dist, state); | BLI_heapsimple_insert(pc.states, state->dist, state); | ||||
| } | } | ||||
| else { | else { | ||||
| MEM_freeN(state); | MEM_freeN(state); | ||||
| ▲ Show 20 Lines • Show All 51 Lines • Show Last 20 Lines | |||||