Changeset View
Changeset View
Standalone View
Standalone View
source/blender/editors/space_view3d/view3d_gizmo_preselect_type.cc
- This file was moved from source/blender/editors/space_view3d/view3d_gizmo_preselect_type.c.
| /* SPDX-License-Identifier: GPL-2.0-or-later */ | /* SPDX-License-Identifier: GPL-2.0-or-later */ | ||||
| /** \file | /** \file | ||||
| * \ingroup wm | * \ingroup wm | ||||
| * | * | ||||
| * \name Preselection Gizmo | * \name Pre-selection Gizmo | ||||
| * | * | ||||
| * Use for tools to hover over data before activation. | * Use for tools to hover over data before activation. | ||||
| * | * | ||||
| * \note This is a slight misuse of gizmo's, since clicking performs no action. | * \note This is a slight misuse of gizmo's, since clicking performs no action. | ||||
| */ | */ | ||||
| #include "MEM_guardedalloc.h" | #include "MEM_guardedalloc.h" | ||||
| ▲ Show 20 Lines • Show All 55 Lines • ▼ Show 20 Lines | |||||
| } | } | ||||
| /** \} */ | /** \} */ | ||||
| /* -------------------------------------------------------------------- */ | /* -------------------------------------------------------------------- */ | ||||
| /** \name Mesh Element (Vert/Edge/Face) Pre-Select Gizmo API | /** \name Mesh Element (Vert/Edge/Face) Pre-Select Gizmo API | ||||
| * \{ */ | * \{ */ | ||||
| typedef struct MeshElemGizmo3D { | struct MeshElemGizmo3D { | ||||
| wmGizmo gizmo; | wmGizmo gizmo; | ||||
| Base **bases; | Base **bases; | ||||
| uint bases_len; | uint bases_len; | ||||
| int base_index; | int base_index; | ||||
| int vert_index; | int vert_index; | ||||
| int edge_index; | int edge_index; | ||||
| int face_index; | int face_index; | ||||
| struct EditMesh_PreSelElem *psel; | EditMesh_PreSelElem *psel; | ||||
| } MeshElemGizmo3D; | }; | ||||
| static void gizmo_preselect_elem_draw(const bContext *C, wmGizmo *gz) | static void gizmo_preselect_elem_draw(const bContext *C, wmGizmo *gz) | ||||
| { | { | ||||
| if (!gizmo_preselect_poll_for_draw(C, gz)) { | if (!gizmo_preselect_poll_for_draw(C, gz)) { | ||||
| return; | return; | ||||
| } | } | ||||
| MeshElemGizmo3D *gz_ele = (MeshElemGizmo3D *)gz; | MeshElemGizmo3D *gz_ele = (MeshElemGizmo3D *)gz; | ||||
| Show All 14 Lines | static int gizmo_preselect_elem_test_select(bContext *C, wmGizmo *gz, const int mval[2]) | ||||
| EDBM_preselect_action_set(gz_ele->psel, PRESELECT_ACTION_TRANSFORM); | EDBM_preselect_action_set(gz_ele->psel, PRESELECT_ACTION_TRANSFORM); | ||||
| if (is_ctrl_pressed && !is_shift_pressed) { | if (is_ctrl_pressed && !is_shift_pressed) { | ||||
| EDBM_preselect_action_set(gz_ele->psel, PRESELECT_ACTION_CREATE); | EDBM_preselect_action_set(gz_ele->psel, PRESELECT_ACTION_CREATE); | ||||
| } | } | ||||
| if (!is_ctrl_pressed && is_shift_pressed) { | if (!is_ctrl_pressed && is_shift_pressed) { | ||||
| EDBM_preselect_action_set(gz_ele->psel, PRESELECT_ACTION_DELETE); | EDBM_preselect_action_set(gz_ele->psel, PRESELECT_ACTION_DELETE); | ||||
| } | } | ||||
| struct { | struct Best { | ||||
| Object *ob; | Object *ob; | ||||
| BMElem *ele; | BMElem *ele; | ||||
| float dist; | float dist; | ||||
| int base_index; | int base_index; | ||||
| } best = { | } best{}; | ||||
| .dist = ED_view3d_select_dist_px(), | best.dist = ED_view3d_select_dist_px(); | ||||
| }; | |||||
| { | { | ||||
| const Scene *scene = CTX_data_scene(C); | const Scene *scene = CTX_data_scene(C); | ||||
| ViewLayer *view_layer = CTX_data_view_layer(C); | ViewLayer *view_layer = CTX_data_view_layer(C); | ||||
| View3D *v3d = CTX_wm_view3d(C); | View3D *v3d = CTX_wm_view3d(C); | ||||
| BKE_view_layer_synced_ensure(scene, view_layer); | BKE_view_layer_synced_ensure(scene, view_layer); | ||||
| if ((gz_ele->bases) == NULL || | if ((gz_ele->bases) == nullptr || | ||||
| (gz_ele->bases[0] != BKE_view_layer_active_base_get(view_layer))) { | (gz_ele->bases[0] != BKE_view_layer_active_base_get(view_layer))) { | ||||
| MEM_SAFE_FREE(gz_ele->bases); | MEM_SAFE_FREE(gz_ele->bases); | ||||
| gz_ele->bases = BKE_view_layer_array_from_bases_in_edit_mode( | gz_ele->bases = BKE_view_layer_array_from_bases_in_edit_mode( | ||||
| scene, view_layer, v3d, &gz_ele->bases_len); | scene, view_layer, v3d, &gz_ele->bases_len); | ||||
| } | } | ||||
| } | } | ||||
| ViewContext vc; | ViewContext vc; | ||||
| Show All 37 Lines | if (EDBM_unified_findnearest_from_raycast(&vc, | ||||
| } | } | ||||
| /* All actions use same vertex pre-selection. */ | /* All actions use same vertex pre-selection. */ | ||||
| /* Re-topology should always prioritize edge pre-selection. | /* Re-topology should always prioritize edge pre-selection. | ||||
| * Only pre-select a vertex when the cursor is really close to it. */ | * Only pre-select a vertex when the cursor is really close to it. */ | ||||
| if (eve_test) { | if (eve_test) { | ||||
| BMVert *vert = (BMVert *)eve_test; | BMVert *vert = (BMVert *)eve_test; | ||||
| float vert_p_co[2], vert_co[3]; | float vert_p_co[2], vert_co[3]; | ||||
| const float mval_f[2] = {UNPACK2(vc.mval)}; | const float mval_f[2] = {float(vc.mval[0]), float(vc.mval[1])}; | ||||
| mul_v3_m4v3(vert_co, gz_ele->bases[base_index_vert]->object->obmat, vert->co); | mul_v3_m4v3(vert_co, gz_ele->bases[base_index_vert]->object->obmat, vert->co); | ||||
| ED_view3d_project_v2(vc.region, vert_co, vert_p_co); | ED_view3d_project_v2(vc.region, vert_co, vert_p_co); | ||||
| float len = len_v2v2(vert_p_co, mval_f); | float len = len_v2v2(vert_p_co, mval_f); | ||||
| if (len < 35) { | if (len < 35) { | ||||
| best.ele = (BMElem *)eve_test; | best.ele = (BMElem *)eve_test; | ||||
| best.base_index = base_index_vert; | best.base_index = base_index_vert; | ||||
| } | } | ||||
| if (!BM_vert_is_boundary(vert) && | if (!BM_vert_is_boundary(vert) && | ||||
| EDBM_preselect_action_get(gz_ele->psel) != PRESELECT_ACTION_DELETE) { | EDBM_preselect_action_get(gz_ele->psel) != PRESELECT_ACTION_DELETE) { | ||||
| best.ele = (BMElem *)eve_test; | best.ele = (BMElem *)eve_test; | ||||
| best.base_index = base_index_vert; | best.base_index = base_index_vert; | ||||
| } | } | ||||
| } | } | ||||
| /* Check above should never fail, if it does it's an internal error. */ | /* Check above should never fail, if it does it's an internal error. */ | ||||
| BLI_assert(best.base_index != -1); | BLI_assert(best.base_index != -1); | ||||
| Base *base = gz_ele->bases[best.base_index]; | Base *base = gz_ele->bases[best.base_index]; | ||||
| best.ob = base->object; | best.ob = base->object; | ||||
| } | } | ||||
| } | } | ||||
| BMesh *bm = NULL; | BMesh *bm = nullptr; | ||||
| gz_ele->base_index = -1; | gz_ele->base_index = -1; | ||||
| gz_ele->vert_index = -1; | gz_ele->vert_index = -1; | ||||
| gz_ele->edge_index = -1; | gz_ele->edge_index = -1; | ||||
| gz_ele->face_index = -1; | gz_ele->face_index = -1; | ||||
| if (best.ele) { | if (best.ele) { | ||||
| gz_ele->base_index = best.base_index; | gz_ele->base_index = best.base_index; | ||||
| bm = BKE_editmesh_from_object(gz_ele->bases[gz_ele->base_index]->object)->bm; | bm = BKE_editmesh_from_object(gz_ele->bases[gz_ele->base_index]->object)->bm; | ||||
| BM_mesh_elem_index_ensure(bm, best.ele->head.htype); | BM_mesh_elem_index_ensure(bm, best.ele->head.htype); | ||||
| if (best.ele->head.htype == BM_VERT) { | if (best.ele->head.htype == BM_VERT) { | ||||
| gz_ele->vert_index = BM_elem_index_get(best.ele); | gz_ele->vert_index = BM_elem_index_get(best.ele); | ||||
| } | } | ||||
| else if (best.ele->head.htype == BM_EDGE) { | else if (best.ele->head.htype == BM_EDGE) { | ||||
| gz_ele->edge_index = BM_elem_index_get(best.ele); | gz_ele->edge_index = BM_elem_index_get(best.ele); | ||||
| } | } | ||||
| else if (best.ele->head.htype == BM_FACE) { | else if (best.ele->head.htype == BM_FACE) { | ||||
| gz_ele->face_index = BM_elem_index_get(best.ele); | gz_ele->face_index = BM_elem_index_get(best.ele); | ||||
| } | } | ||||
| } | } | ||||
| if (best.ele) { | if (best.ele) { | ||||
| const float(*coords)[3] = NULL; | const float(*coords)[3] = nullptr; | ||||
| { | { | ||||
| Object *ob = gz_ele->bases[gz_ele->base_index]->object; | Object *ob = gz_ele->bases[gz_ele->base_index]->object; | ||||
| Depsgraph *depsgraph = CTX_data_ensure_evaluated_depsgraph(C); | Depsgraph *depsgraph = CTX_data_ensure_evaluated_depsgraph(C); | ||||
| Mesh *me_eval = (Mesh *)DEG_get_evaluated_id(depsgraph, ob->data); | Mesh *me_eval = (Mesh *)DEG_get_evaluated_id(depsgraph, static_cast<ID *>(ob->data)); | ||||
| if (me_eval->runtime.edit_data) { | if (me_eval->runtime.edit_data) { | ||||
| coords = me_eval->runtime.edit_data->vertexCos; | coords = me_eval->runtime.edit_data->vertexCos; | ||||
| } | } | ||||
| } | } | ||||
| EDBM_preselect_elem_update_from_single(gz_ele->psel, bm, best.ele, coords); | EDBM_preselect_elem_update_from_single(gz_ele->psel, bm, best.ele, coords); | ||||
| EDBM_preselect_elem_update_preview(gz_ele->psel, &vc, bm, best.ele, mval); | EDBM_preselect_elem_update_preview(gz_ele->psel, &vc, bm, best.ele, mval); | ||||
| } | } | ||||
| else { | else { | ||||
| Show All 13 Lines | static int gizmo_preselect_elem_test_select(bContext *C, wmGizmo *gz, const int mval[2]) | ||||
| // return best.eed ? 0 : -1; | // return best.eed ? 0 : -1; | ||||
| return -1; | return -1; | ||||
| } | } | ||||
| static void gizmo_preselect_elem_setup(wmGizmo *gz) | static void gizmo_preselect_elem_setup(wmGizmo *gz) | ||||
| { | { | ||||
| MeshElemGizmo3D *gz_ele = (MeshElemGizmo3D *)gz; | MeshElemGizmo3D *gz_ele = (MeshElemGizmo3D *)gz; | ||||
| if (gz_ele->psel == NULL) { | if (gz_ele->psel == nullptr) { | ||||
| gz_ele->psel = EDBM_preselect_elem_create(); | gz_ele->psel = EDBM_preselect_elem_create(); | ||||
| } | } | ||||
| gz_ele->base_index = -1; | gz_ele->base_index = -1; | ||||
| } | } | ||||
| static void gizmo_preselect_elem_free(wmGizmo *gz) | static void gizmo_preselect_elem_free(wmGizmo *gz) | ||||
| { | { | ||||
| MeshElemGizmo3D *gz_ele = (MeshElemGizmo3D *)gz; | MeshElemGizmo3D *gz_ele = (MeshElemGizmo3D *)gz; | ||||
| EDBM_preselect_elem_destroy(gz_ele->psel); | EDBM_preselect_elem_destroy(gz_ele->psel); | ||||
| gz_ele->psel = NULL; | gz_ele->psel = nullptr; | ||||
| MEM_SAFE_FREE(gz_ele->bases); | MEM_SAFE_FREE(gz_ele->bases); | ||||
| } | } | ||||
| static int gizmo_preselect_elem_invoke(bContext *UNUSED(C), | static int gizmo_preselect_elem_invoke(bContext *UNUSED(C), | ||||
| wmGizmo *UNUSED(gz), | wmGizmo *UNUSED(gz), | ||||
| const wmEvent *UNUSED(event)) | const wmEvent *UNUSED(event)) | ||||
| { | { | ||||
| return OPERATOR_PASS_THROUGH; | return OPERATOR_PASS_THROUGH; | ||||
| Show All 20 Lines | |||||
| } | } | ||||
| /** \} */ | /** \} */ | ||||
| /* -------------------------------------------------------------------- */ | /* -------------------------------------------------------------------- */ | ||||
| /** \name Mesh Edge-Ring Pre-Select Gizmo API | /** \name Mesh Edge-Ring Pre-Select Gizmo API | ||||
| * \{ */ | * \{ */ | ||||
| typedef struct MeshEdgeRingGizmo3D { | struct MeshEdgeRingGizmo3D { | ||||
| wmGizmo gizmo; | wmGizmo gizmo; | ||||
| Base **bases; | Base **bases; | ||||
| uint bases_len; | uint bases_len; | ||||
| int base_index; | int base_index; | ||||
| int edge_index; | int edge_index; | ||||
| struct EditMesh_PreSelEdgeRing *psel; | EditMesh_PreSelEdgeRing *psel; | ||||
| } MeshEdgeRingGizmo3D; | }; | ||||
| static void gizmo_preselect_edgering_draw(const bContext *C, wmGizmo *gz) | static void gizmo_preselect_edgering_draw(const bContext *C, wmGizmo *gz) | ||||
| { | { | ||||
| if (!gizmo_preselect_poll_for_draw(C, gz)) { | if (!gizmo_preselect_poll_for_draw(C, gz)) { | ||||
| return; | return; | ||||
| } | } | ||||
| MeshEdgeRingGizmo3D *gz_ring = (MeshEdgeRingGizmo3D *)gz; | MeshEdgeRingGizmo3D *gz_ring = (MeshEdgeRingGizmo3D *)gz; | ||||
| if (gz_ring->base_index != -1) { | if (gz_ring->base_index != -1) { | ||||
| Object *ob = gz_ring->bases[gz_ring->base_index]->object; | Object *ob = gz_ring->bases[gz_ring->base_index]->object; | ||||
| EDBM_preselect_edgering_draw(gz_ring->psel, ob->obmat); | EDBM_preselect_edgering_draw(gz_ring->psel, ob->obmat); | ||||
| } | } | ||||
| } | } | ||||
| static int gizmo_preselect_edgering_test_select(bContext *C, wmGizmo *gz, const int mval[2]) | static int gizmo_preselect_edgering_test_select(bContext *C, wmGizmo *gz, const int mval[2]) | ||||
| { | { | ||||
| MeshEdgeRingGizmo3D *gz_ring = (MeshEdgeRingGizmo3D *)gz; | MeshEdgeRingGizmo3D *gz_ring = (MeshEdgeRingGizmo3D *)gz; | ||||
| struct { | struct Best { | ||||
| Object *ob; | Object *ob; | ||||
| BMEdge *eed; | BMEdge *eed; | ||||
| float dist; | float dist; | ||||
| int base_index; | int base_index; | ||||
| } best = { | } best{}; | ||||
| .dist = ED_view3d_select_dist_px(), | best.dist = ED_view3d_select_dist_px(); | ||||
| }; | |||||
| struct { | struct Prev { | ||||
| int base_index; | int base_index; | ||||
| int edge_index; | int edge_index; | ||||
| } prev = { | } prev{}; | ||||
| .base_index = gz_ring->base_index, | prev.base_index = gz_ring->base_index; | ||||
| .edge_index = gz_ring->edge_index, | prev.edge_index = gz_ring->edge_index; | ||||
| }; | |||||
| { | { | ||||
| const Scene *scene = CTX_data_scene(C); | const Scene *scene = CTX_data_scene(C); | ||||
| ViewLayer *view_layer = CTX_data_view_layer(C); | ViewLayer *view_layer = CTX_data_view_layer(C); | ||||
| View3D *v3d = CTX_wm_view3d(C); | View3D *v3d = CTX_wm_view3d(C); | ||||
| BKE_view_layer_synced_ensure(scene, view_layer); | BKE_view_layer_synced_ensure(scene, view_layer); | ||||
| if ((gz_ring->bases) == NULL || | if ((gz_ring->bases) == nullptr || | ||||
| (gz_ring->bases[0] != BKE_view_layer_active_base_get(view_layer))) { | (gz_ring->bases[0] != BKE_view_layer_active_base_get(view_layer))) { | ||||
| MEM_SAFE_FREE(gz_ring->bases); | MEM_SAFE_FREE(gz_ring->bases); | ||||
| gz_ring->bases = BKE_view_layer_array_from_bases_in_edit_mode( | gz_ring->bases = BKE_view_layer_array_from_bases_in_edit_mode( | ||||
| scene, view_layer, v3d, &gz_ring->bases_len); | scene, view_layer, v3d, &gz_ring->bases_len); | ||||
| } | } | ||||
| } | } | ||||
| ViewContext vc; | ViewContext vc; | ||||
| em_setup_viewcontext(C, &vc); | em_setup_viewcontext(C, &vc); | ||||
| copy_v2_v2_int(vc.mval, mval); | copy_v2_v2_int(vc.mval, mval); | ||||
| uint base_index; | uint base_index; | ||||
| BMEdge *eed_test = EDBM_edge_find_nearest_ex( | BMEdge *eed_test = EDBM_edge_find_nearest_ex(&vc, | ||||
| &vc, &best.dist, NULL, false, false, NULL, gz_ring->bases, gz_ring->bases_len, &base_index); | &best.dist, | ||||
| nullptr, | |||||
| false, | |||||
| false, | |||||
| nullptr, | |||||
| gz_ring->bases, | |||||
| gz_ring->bases_len, | |||||
| &base_index); | |||||
| if (eed_test) { | if (eed_test) { | ||||
| best.ob = gz_ring->bases[base_index]->object; | best.ob = gz_ring->bases[base_index]->object; | ||||
| best.eed = eed_test; | best.eed = eed_test; | ||||
| best.base_index = base_index; | best.base_index = base_index; | ||||
| } | } | ||||
| BMesh *bm = NULL; | BMesh *bm = nullptr; | ||||
| if (best.eed) { | if (best.eed) { | ||||
| gz_ring->base_index = best.base_index; | gz_ring->base_index = best.base_index; | ||||
| bm = BKE_editmesh_from_object(gz_ring->bases[gz_ring->base_index]->object)->bm; | bm = BKE_editmesh_from_object(gz_ring->bases[gz_ring->base_index]->object)->bm; | ||||
| BM_mesh_elem_index_ensure(bm, BM_EDGE); | BM_mesh_elem_index_ensure(bm, BM_EDGE); | ||||
| gz_ring->edge_index = BM_elem_index_get(best.eed); | gz_ring->edge_index = BM_elem_index_get(best.eed); | ||||
| } | } | ||||
| else { | else { | ||||
| gz_ring->base_index = -1; | gz_ring->base_index = -1; | ||||
| gz_ring->edge_index = -1; | gz_ring->edge_index = -1; | ||||
| } | } | ||||
| if ((prev.base_index == gz_ring->base_index) && (prev.edge_index == gz_ring->edge_index)) { | if ((prev.base_index == gz_ring->base_index) && (prev.edge_index == gz_ring->edge_index)) { | ||||
| /* pass (only recalculate on change) */ | /* pass (only recalculate on change) */ | ||||
| } | } | ||||
| else { | else { | ||||
| if (best.eed) { | if (best.eed) { | ||||
| Object *ob = gz_ring->bases[gz_ring->base_index]->object; | Object *ob = gz_ring->bases[gz_ring->base_index]->object; | ||||
| Scene *scene_eval = (Scene *)DEG_get_evaluated_id(vc.depsgraph, &vc.scene->id); | Scene *scene_eval = (Scene *)DEG_get_evaluated_id(vc.depsgraph, &vc.scene->id); | ||||
| Object *ob_eval = DEG_get_evaluated_object(vc.depsgraph, ob); | Object *ob_eval = DEG_get_evaluated_object(vc.depsgraph, ob); | ||||
| BMEditMesh *em_eval = BKE_editmesh_from_object(ob_eval); | BMEditMesh *em_eval = BKE_editmesh_from_object(ob_eval); | ||||
| /* Re-allocate coords each update isn't ideal, however we can't be sure | /* Re-allocate coords each update isn't ideal, however we can't be sure | ||||
| * the mesh hasn't been edited since last update. */ | * the mesh hasn't been edited since last update. */ | ||||
| bool is_alloc = false; | bool is_alloc = false; | ||||
| const float(*coords)[3] = BKE_editmesh_vert_coords_when_deformed( | const float(*coords)[3] = BKE_editmesh_vert_coords_when_deformed( | ||||
| vc.depsgraph, em_eval, scene_eval, ob_eval, NULL, &is_alloc); | vc.depsgraph, em_eval, scene_eval, ob_eval, nullptr, &is_alloc); | ||||
| EDBM_preselect_edgering_update_from_edge(gz_ring->psel, bm, best.eed, 1, coords); | EDBM_preselect_edgering_update_from_edge(gz_ring->psel, bm, best.eed, 1, coords); | ||||
| if (is_alloc) { | if (is_alloc) { | ||||
| MEM_freeN((void *)coords); | MEM_freeN((void *)coords); | ||||
| } | } | ||||
| } | } | ||||
| else { | else { | ||||
| EDBM_preselect_edgering_clear(gz_ring->psel); | EDBM_preselect_edgering_clear(gz_ring->psel); | ||||
| } | } | ||||
| RNA_int_set(gz->ptr, "object_index", gz_ring->base_index); | RNA_int_set(gz->ptr, "object_index", gz_ring->base_index); | ||||
| RNA_int_set(gz->ptr, "edge_index", gz_ring->edge_index); | RNA_int_set(gz->ptr, "edge_index", gz_ring->edge_index); | ||||
| ARegion *region = CTX_wm_region(C); | ARegion *region = CTX_wm_region(C); | ||||
| ED_region_tag_redraw_editor_overlays(region); | ED_region_tag_redraw_editor_overlays(region); | ||||
| } | } | ||||
| // return best.eed ? 0 : -1; | // return best.eed ? 0 : -1; | ||||
| return -1; | return -1; | ||||
| } | } | ||||
| static void gizmo_preselect_edgering_setup(wmGizmo *gz) | static void gizmo_preselect_edgering_setup(wmGizmo *gz) | ||||
| { | { | ||||
| MeshEdgeRingGizmo3D *gz_ring = (MeshEdgeRingGizmo3D *)gz; | MeshEdgeRingGizmo3D *gz_ring = (MeshEdgeRingGizmo3D *)gz; | ||||
| if (gz_ring->psel == NULL) { | if (gz_ring->psel == nullptr) { | ||||
| gz_ring->psel = EDBM_preselect_edgering_create(); | gz_ring->psel = EDBM_preselect_edgering_create(); | ||||
| } | } | ||||
| gz_ring->base_index = -1; | gz_ring->base_index = -1; | ||||
| } | } | ||||
| static void gizmo_preselect_edgering_free(wmGizmo *gz) | static void gizmo_preselect_edgering_free(wmGizmo *gz) | ||||
| { | { | ||||
| MeshEdgeRingGizmo3D *gz_ring = (MeshEdgeRingGizmo3D *)gz; | MeshEdgeRingGizmo3D *gz_ring = (MeshEdgeRingGizmo3D *)gz; | ||||
| EDBM_preselect_edgering_destroy(gz_ring->psel); | EDBM_preselect_edgering_destroy(gz_ring->psel); | ||||
| gz_ring->psel = NULL; | gz_ring->psel = nullptr; | ||||
| MEM_SAFE_FREE(gz_ring->bases); | MEM_SAFE_FREE(gz_ring->bases); | ||||
| } | } | ||||
| static int gizmo_preselect_edgering_invoke(bContext *UNUSED(C), | static int gizmo_preselect_edgering_invoke(bContext *UNUSED(C), | ||||
| wmGizmo *UNUSED(gz), | wmGizmo *UNUSED(gz), | ||||
| const wmEvent *UNUSED(event)) | const wmEvent *UNUSED(event)) | ||||
| { | { | ||||
| return OPERATOR_PASS_THROUGH; | return OPERATOR_PASS_THROUGH; | ||||
| ▲ Show 20 Lines • Show All 44 Lines • ▼ Show 20 Lines | void ED_view3d_gizmo_mesh_preselect_get_active(bContext *C, | ||||
| BMElem **r_ele) | BMElem **r_ele) | ||||
| { | { | ||||
| const Scene *scene = CTX_data_scene(C); | const Scene *scene = CTX_data_scene(C); | ||||
| ViewLayer *view_layer = CTX_data_view_layer(C); | ViewLayer *view_layer = CTX_data_view_layer(C); | ||||
| const int object_index = RNA_int_get(gz->ptr, "object_index"); | const int object_index = RNA_int_get(gz->ptr, "object_index"); | ||||
| /* weak, allocate an array just to access the index. */ | /* weak, allocate an array just to access the index. */ | ||||
| Base *base = NULL; | Base *base = nullptr; | ||||
| Object *obedit = NULL; | Object *obedit = nullptr; | ||||
| { | { | ||||
| uint bases_len; | uint bases_len; | ||||
| Base **bases = BKE_view_layer_array_from_bases_in_edit_mode( | Base **bases = BKE_view_layer_array_from_bases_in_edit_mode( | ||||
| scene, view_layer, CTX_wm_view3d(C), &bases_len); | scene, view_layer, CTX_wm_view3d(C), &bases_len); | ||||
| if (object_index < bases_len) { | if (object_index < bases_len) { | ||||
| base = bases[object_index]; | base = bases[object_index]; | ||||
| obedit = base->object; | obedit = base->object; | ||||
| } | } | ||||
| MEM_freeN(bases); | MEM_freeN(bases); | ||||
| } | } | ||||
| *r_base = base; | *r_base = base; | ||||
| *r_ele = NULL; | *r_ele = nullptr; | ||||
| if (obedit) { | if (obedit) { | ||||
| BMEditMesh *em = BKE_editmesh_from_object(obedit); | BMEditMesh *em = BKE_editmesh_from_object(obedit); | ||||
| BMesh *bm = em->bm; | BMesh *bm = em->bm; | ||||
| PropertyRNA *prop; | PropertyRNA *prop; | ||||
| /* Ring select only defines edge, check properties exist first. */ | /* Ring select only defines edge, check properties exist first. */ | ||||
| prop = RNA_struct_find_property(gz->ptr, "vert_index"); | prop = RNA_struct_find_property(gz->ptr, "vert_index"); | ||||
| Show All 31 Lines | void ED_view3d_gizmo_mesh_preselect_clear(wmGizmo *gz) | ||||
| } | } | ||||
| else { | else { | ||||
| BLI_assert_unreachable(); | BLI_assert_unreachable(); | ||||
| } | } | ||||
| const char *prop_ids[] = {"object_index", "vert_index", "edge_index", "face_index"}; | const char *prop_ids[] = {"object_index", "vert_index", "edge_index", "face_index"}; | ||||
| for (int i = 0; i < ARRAY_SIZE(prop_ids); i++) { | for (int i = 0; i < ARRAY_SIZE(prop_ids); i++) { | ||||
| PropertyRNA *prop = RNA_struct_find_property(gz->ptr, prop_ids[i]); | PropertyRNA *prop = RNA_struct_find_property(gz->ptr, prop_ids[i]); | ||||
| if (prop == NULL) { | if (prop == nullptr) { | ||||
| continue; | continue; | ||||
| } | } | ||||
| RNA_property_int_set(gz->ptr, prop, -1); | RNA_property_int_set(gz->ptr, prop, -1); | ||||
| } | } | ||||
| } | } | ||||
| /** \} */ | /** \} */ | ||||