Edit Mesh: pass Base array to picking functions
In some cases we need to use this array afterwards, so this gives control over which objects are used for picking. Also use an index argument as return argument so callers that need to know the index in the array don't need to calculate it afterwards.
This commit is contained in:
@@ -173,15 +173,17 @@ struct BMFace *EDBM_face_find_nearest(
|
|||||||
|
|
||||||
bool EDBM_unified_findnearest(
|
bool EDBM_unified_findnearest(
|
||||||
struct ViewContext *vc,
|
struct ViewContext *vc,
|
||||||
struct Base **r_base,
|
struct Base **bases, uint bases_len,
|
||||||
|
int *r_base_index,
|
||||||
struct BMVert **r_eve,
|
struct BMVert **r_eve,
|
||||||
struct BMEdge **r_eed,
|
struct BMEdge **r_eed,
|
||||||
struct BMFace **r_efa);
|
struct BMFace **r_efa);
|
||||||
|
|
||||||
bool EDBM_unified_findnearest_from_raycast(
|
bool EDBM_unified_findnearest_from_raycast(
|
||||||
struct ViewContext *vc,
|
struct ViewContext *vc,
|
||||||
|
struct Base **bases, uint bases_len,
|
||||||
bool use_boundary,
|
bool use_boundary,
|
||||||
struct Base **r_base,
|
int *r_base_index,
|
||||||
struct BMVert **r_eve,
|
struct BMVert **r_eve,
|
||||||
struct BMEdge **r_eed,
|
struct BMEdge **r_eed,
|
||||||
struct BMFace **r_efa);
|
struct BMFace **r_efa);
|
||||||
|
@@ -635,9 +635,16 @@ static int edbm_shortest_path_pick_invoke(bContext *C, wmOperator *op, const wmE
|
|||||||
|
|
||||||
view3d_operator_needs_opengl(C);
|
view3d_operator_needs_opengl(C);
|
||||||
|
|
||||||
if (EDBM_unified_findnearest(&vc, &basact, &eve, &eed, &efa)) {
|
{
|
||||||
ED_view3d_viewcontext_init_object(&vc, basact->object);
|
int base_index = -1;
|
||||||
em = vc.em;
|
uint bases_len = 0;
|
||||||
|
Base **bases = BKE_view_layer_array_from_bases_in_edit_mode(vc.view_layer, &bases_len);
|
||||||
|
if (EDBM_unified_findnearest(&vc, bases, bases_len, base_index, &eve, &eed, &efa)) {
|
||||||
|
basact = bases[base_index];
|
||||||
|
ED_view3d_viewcontext_init_object(&vc, basact->object);
|
||||||
|
em = vc.em;
|
||||||
|
}
|
||||||
|
MEM_freeN(bases);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If nothing is selected, let's select the picked vertex/edge/face. */
|
/* If nothing is selected, let's select the picked vertex/edge/face. */
|
||||||
|
@@ -940,8 +940,8 @@ BMFace *EDBM_face_find_nearest(ViewContext *vc, float *r_dist)
|
|||||||
* return 1 if found one
|
* return 1 if found one
|
||||||
*/
|
*/
|
||||||
static bool unified_findnearest(
|
static bool unified_findnearest(
|
||||||
ViewContext *vc,
|
ViewContext *vc, Base **bases, const uint bases_len,
|
||||||
Base **r_base, BMVert **r_eve, BMEdge **r_eed, BMFace **r_efa)
|
int *r_base_index, BMVert **r_eve, BMEdge **r_eed, BMFace **r_efa)
|
||||||
{
|
{
|
||||||
BMEditMesh *em = vc->em;
|
BMEditMesh *em = vc->em;
|
||||||
static short mval_prev[2] = {-1, -1};
|
static short mval_prev[2] = {-1, -1};
|
||||||
@@ -955,22 +955,20 @@ static bool unified_findnearest(
|
|||||||
struct {
|
struct {
|
||||||
struct {
|
struct {
|
||||||
BMVert *ele;
|
BMVert *ele;
|
||||||
Base *base;
|
int base_index;
|
||||||
} v;
|
} v;
|
||||||
struct {
|
struct {
|
||||||
BMEdge *ele;
|
BMEdge *ele;
|
||||||
Base *base;
|
int base_index;
|
||||||
} e, e_zbuf;
|
} e, e_zbuf;
|
||||||
struct {
|
struct {
|
||||||
BMFace *ele;
|
BMFace *ele;
|
||||||
Base *base;
|
int base_index;
|
||||||
} f, f_zbuf;
|
} f, f_zbuf;
|
||||||
} hit = {{NULL}};
|
} hit = {{NULL}};
|
||||||
|
|
||||||
/* TODO(campbell): perform selection as one pass
|
/* TODO(campbell): perform selection as one pass
|
||||||
* instead of many smaller passes (which doesn't work for zbuf occlusion). */
|
* instead of many smaller passes (which doesn't work for zbuf occlusion). */
|
||||||
uint bases_len = 0;
|
|
||||||
Base **bases = BKE_view_layer_array_from_bases_in_edit_mode(vc->view_layer, &bases_len);
|
|
||||||
|
|
||||||
/* no afterqueue (yet), so we check it now, otherwise the em_xxxofs indices are bad */
|
/* no afterqueue (yet), so we check it now, otherwise the em_xxxofs indices are bad */
|
||||||
|
|
||||||
@@ -989,11 +987,11 @@ static bool unified_findnearest(
|
|||||||
dist = min_ff(dist_margin, dist_center);
|
dist = min_ff(dist_margin, dist_center);
|
||||||
}
|
}
|
||||||
if (efa_test) {
|
if (efa_test) {
|
||||||
hit.f.base = base_iter;
|
hit.f.base_index = base_index;
|
||||||
hit.f.ele = efa_test;
|
hit.f.ele = efa_test;
|
||||||
}
|
}
|
||||||
if (efa_zbuf) {
|
if (efa_zbuf) {
|
||||||
hit.f_zbuf.base = base_iter;
|
hit.f_zbuf.base_index = base_index;
|
||||||
hit.f_zbuf.ele = efa_zbuf;
|
hit.f_zbuf.ele = efa_zbuf;
|
||||||
}
|
}
|
||||||
} /* bases */
|
} /* bases */
|
||||||
@@ -1014,11 +1012,11 @@ static bool unified_findnearest(
|
|||||||
dist = min_ff(dist_margin, dist_center);
|
dist = min_ff(dist_margin, dist_center);
|
||||||
}
|
}
|
||||||
if (eed_test) {
|
if (eed_test) {
|
||||||
hit.e.base = base_iter;
|
hit.e.base_index = base_index;
|
||||||
hit.e.ele = eed_test;
|
hit.e.ele = eed_test;
|
||||||
}
|
}
|
||||||
if (eed_zbuf) {
|
if (eed_zbuf) {
|
||||||
hit.e_zbuf.base = base_iter;
|
hit.e_zbuf.base_index = base_index;
|
||||||
hit.e_zbuf.ele = eed_zbuf;
|
hit.e_zbuf.ele = eed_zbuf;
|
||||||
}
|
}
|
||||||
} /* bases */
|
} /* bases */
|
||||||
@@ -1032,14 +1030,12 @@ static bool unified_findnearest(
|
|||||||
ED_view3d_backbuf_validate(vc);
|
ED_view3d_backbuf_validate(vc);
|
||||||
BMVert *eve_test = EDBM_vert_find_nearest_ex(vc, &dist, true, use_cycle);
|
BMVert *eve_test = EDBM_vert_find_nearest_ex(vc, &dist, true, use_cycle);
|
||||||
if (eve_test) {
|
if (eve_test) {
|
||||||
hit.v.base = base_iter;
|
hit.v.base_index = base_index;
|
||||||
hit.v.ele = eve_test;
|
hit.v.ele = eve_test;
|
||||||
}
|
}
|
||||||
} /* bases */
|
} /* bases */
|
||||||
}
|
}
|
||||||
|
|
||||||
MEM_SAFE_FREE(bases);
|
|
||||||
|
|
||||||
/* return only one of 3 pointers, for frontbuffer redraws */
|
/* return only one of 3 pointers, for frontbuffer redraws */
|
||||||
if (hit.v.ele) {
|
if (hit.v.ele) {
|
||||||
hit.f.ele = NULL;
|
hit.f.ele = NULL;
|
||||||
@@ -1053,11 +1049,11 @@ static bool unified_findnearest(
|
|||||||
* use this if all else fails, it makes sense to select this */
|
* use this if all else fails, it makes sense to select this */
|
||||||
if ((hit.v.ele || hit.e.ele || hit.f.ele) == 0) {
|
if ((hit.v.ele || hit.e.ele || hit.f.ele) == 0) {
|
||||||
if (hit.e_zbuf.ele) {
|
if (hit.e_zbuf.ele) {
|
||||||
hit.e.base = hit.e_zbuf.base;
|
hit.e.base_index = hit.e_zbuf.base_index;
|
||||||
hit.e.ele = hit.e_zbuf.ele;
|
hit.e.ele = hit.e_zbuf.ele;
|
||||||
}
|
}
|
||||||
else if (hit.f_zbuf.ele) {
|
else if (hit.f_zbuf.ele) {
|
||||||
hit.f.base = hit.f_zbuf.base;
|
hit.f.base_index = hit.f_zbuf.base_index;
|
||||||
hit.f.ele = hit.f_zbuf.ele;
|
hit.f.ele = hit.f_zbuf.ele;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1069,13 +1065,13 @@ static bool unified_findnearest(
|
|||||||
BLI_assert(((hit.v.ele != NULL) + (hit.e.ele != NULL) + (hit.f.ele != NULL)) <= 1);
|
BLI_assert(((hit.v.ele != NULL) + (hit.e.ele != NULL) + (hit.f.ele != NULL)) <= 1);
|
||||||
|
|
||||||
if (hit.v.ele) {
|
if (hit.v.ele) {
|
||||||
*r_base = hit.v.base;
|
*r_base_index = hit.v.base_index;
|
||||||
}
|
}
|
||||||
if (hit.e.ele) {
|
if (hit.e.ele) {
|
||||||
*r_base = hit.e.base;
|
*r_base_index = hit.e.base_index;
|
||||||
}
|
}
|
||||||
if (hit.f.ele) {
|
if (hit.f.ele) {
|
||||||
*r_base = hit.f.base;
|
*r_base_index = hit.f.base_index;
|
||||||
}
|
}
|
||||||
|
|
||||||
*r_eve = hit.v.ele;
|
*r_eve = hit.v.ele;
|
||||||
@@ -1089,10 +1085,10 @@ static bool unified_findnearest(
|
|||||||
#undef FAKE_SELECT_MODE_END
|
#undef FAKE_SELECT_MODE_END
|
||||||
|
|
||||||
bool EDBM_unified_findnearest(
|
bool EDBM_unified_findnearest(
|
||||||
ViewContext *vc,
|
ViewContext *vc, Base **bases, const uint bases_len,
|
||||||
Base **r_base, BMVert **r_eve, BMEdge **r_eed, BMFace **r_efa)
|
int *r_base_index, BMVert **r_eve, BMEdge **r_eed, BMFace **r_efa)
|
||||||
{
|
{
|
||||||
return unified_findnearest(vc, r_base, r_eve, r_eed, r_efa);
|
return unified_findnearest(vc, bases, bases_len, r_base_index, r_eve, r_eed, r_efa);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** \} */
|
/** \} */
|
||||||
@@ -1106,8 +1102,9 @@ bool EDBM_unified_findnearest(
|
|||||||
|
|
||||||
bool EDBM_unified_findnearest_from_raycast(
|
bool EDBM_unified_findnearest_from_raycast(
|
||||||
ViewContext *vc,
|
ViewContext *vc,
|
||||||
|
Base **bases, const uint bases_len,
|
||||||
bool use_boundary,
|
bool use_boundary,
|
||||||
Base **r_base,
|
int *r_base_index,
|
||||||
struct BMVert **r_eve,
|
struct BMVert **r_eve,
|
||||||
struct BMEdge **r_eed,
|
struct BMEdge **r_eed,
|
||||||
struct BMFace **r_efa)
|
struct BMFace **r_efa)
|
||||||
@@ -1117,9 +1114,9 @@ bool EDBM_unified_findnearest_from_raycast(
|
|||||||
float ray_origin[3], ray_direction[3];
|
float ray_origin[3], ray_direction[3];
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
Base *base;
|
uint base_index;
|
||||||
BMElem *ele;
|
BMElem *ele;
|
||||||
} best = {NULL};
|
} best = {0, NULL};
|
||||||
|
|
||||||
if (ED_view3d_win_to_ray(
|
if (ED_view3d_win_to_ray(
|
||||||
vc->depsgraph,
|
vc->depsgraph,
|
||||||
@@ -1132,8 +1129,6 @@ bool EDBM_unified_findnearest_from_raycast(
|
|||||||
const bool use_edge = (r_eed != NULL);
|
const bool use_edge = (r_eed != NULL);
|
||||||
const bool use_face = (r_efa != NULL);
|
const bool use_face = (r_efa != NULL);
|
||||||
|
|
||||||
uint bases_len;
|
|
||||||
Base **bases = BKE_view_layer_array_from_bases_in_edit_mode(vc->view_layer, &bases_len);
|
|
||||||
for (uint base_index = 0; base_index < bases_len; base_index++) {
|
for (uint base_index = 0; base_index < bases_len; base_index++) {
|
||||||
Base *base_iter = bases[base_index];
|
Base *base_iter = bases[base_index];
|
||||||
Object *obedit = base_iter->object;
|
Object *obedit = base_iter->object;
|
||||||
@@ -1177,7 +1172,7 @@ bool EDBM_unified_findnearest_from_raycast(
|
|||||||
point, &depth);
|
point, &depth);
|
||||||
if (dist_sq_test < dist_sq_best) {
|
if (dist_sq_test < dist_sq_best) {
|
||||||
dist_sq_best = dist_sq_test;
|
dist_sq_best = dist_sq_test;
|
||||||
best.base = base_iter;
|
best.base_index = base_index;
|
||||||
best.ele = (BMElem *)v;
|
best.ele = (BMElem *)v;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1203,7 +1198,7 @@ bool EDBM_unified_findnearest_from_raycast(
|
|||||||
point, &depth);
|
point, &depth);
|
||||||
if (dist_sq_test < dist_sq_best) {
|
if (dist_sq_test < dist_sq_best) {
|
||||||
dist_sq_best = dist_sq_test;
|
dist_sq_best = dist_sq_test;
|
||||||
best.base = base_iter;
|
best.base_index = base_index;
|
||||||
best.ele = (BMElem *)e;
|
best.ele = (BMElem *)e;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@@ -1226,7 +1221,7 @@ bool EDBM_unified_findnearest_from_raycast(
|
|||||||
v->co, &depth);
|
v->co, &depth);
|
||||||
if (dist_sq_test < dist_sq_best) {
|
if (dist_sq_test < dist_sq_best) {
|
||||||
dist_sq_best = dist_sq_test;
|
dist_sq_best = dist_sq_test;
|
||||||
best.base = base_iter;
|
best.base_index = base_index;
|
||||||
best.ele = (BMElem *)v;
|
best.ele = (BMElem *)v;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1251,7 +1246,7 @@ bool EDBM_unified_findnearest_from_raycast(
|
|||||||
point, &depth);
|
point, &depth);
|
||||||
if (dist_sq_test < dist_sq_best) {
|
if (dist_sq_test < dist_sq_best) {
|
||||||
dist_sq_best = dist_sq_test;
|
dist_sq_best = dist_sq_test;
|
||||||
best.base = base_iter;
|
best.base_index = base_index;
|
||||||
best.ele = (BMElem *)e;
|
best.ele = (BMElem *)e;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1278,7 +1273,7 @@ bool EDBM_unified_findnearest_from_raycast(
|
|||||||
point, &depth);
|
point, &depth);
|
||||||
if (dist_sq_test < dist_sq_best) {
|
if (dist_sq_test < dist_sq_best) {
|
||||||
dist_sq_best = dist_sq_test;
|
dist_sq_best = dist_sq_test;
|
||||||
best.base = base_iter;
|
best.base_index = base_index;
|
||||||
best.ele = (BMElem *)f;
|
best.ele = (BMElem *)f;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1287,7 +1282,7 @@ bool EDBM_unified_findnearest_from_raycast(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
*r_base = best.base;
|
*r_base_index = best.base_index;
|
||||||
if (r_eve) {
|
if (r_eve) {
|
||||||
*r_eve = NULL;
|
*r_eve = NULL;
|
||||||
}
|
}
|
||||||
@@ -1974,17 +1969,25 @@ static bool mouse_mesh_loop(bContext *C, const int mval[2], bool extend, bool de
|
|||||||
const short selectmode = em_original->selectmode;
|
const short selectmode = em_original->selectmode;
|
||||||
em_original->selectmode = SCE_SELECT_EDGE;
|
em_original->selectmode = SCE_SELECT_EDGE;
|
||||||
|
|
||||||
if (EDBM_unified_findnearest(&vc, &basact, &eve, &eed, &efa)) {
|
uint bases_len;
|
||||||
ED_view3d_viewcontext_init_object(&vc, basact->object);
|
Base **bases = BKE_view_layer_array_from_bases_in_edit_mode(vc.view_layer, &bases_len);
|
||||||
em = vc.em;
|
|
||||||
}
|
{
|
||||||
else {
|
int base_index = -1;
|
||||||
em = NULL;
|
if (EDBM_unified_findnearest(&vc, bases, bases_len, &base_index, &eve, &eed, &efa)) {
|
||||||
|
basact = bases[base_index];
|
||||||
|
ED_view3d_viewcontext_init_object(&vc, basact->object);
|
||||||
|
em = vc.em;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
em = NULL;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
em_original->selectmode = selectmode;
|
em_original->selectmode = selectmode;
|
||||||
|
|
||||||
if (em == NULL || eed == NULL) {
|
if (em == NULL || eed == NULL) {
|
||||||
|
MEM_freeN(bases);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2007,11 +2010,9 @@ static bool mouse_mesh_loop(bContext *C, const int mval[2], bool extend, bool de
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (select_clear) {
|
if (select_clear) {
|
||||||
ViewLayer *view_layer = CTX_data_view_layer(C);
|
for (uint base_index = 0; base_index < bases_len; base_index++) {
|
||||||
uint objects_len = 0;
|
Base *base_iter = bases[base_index];
|
||||||
Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(view_layer, &objects_len);
|
Object *ob_iter = base_iter->object;
|
||||||
for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
|
|
||||||
Object *ob_iter = objects[ob_index];
|
|
||||||
BMEditMesh *em_iter = BKE_editmesh_from_object(ob_iter);
|
BMEditMesh *em_iter = BKE_editmesh_from_object(ob_iter);
|
||||||
|
|
||||||
if (em_iter->bm->totvertsel == 0) {
|
if (em_iter->bm->totvertsel == 0) {
|
||||||
@@ -2025,7 +2026,6 @@ static bool mouse_mesh_loop(bContext *C, const int mval[2], bool extend, bool de
|
|||||||
EDBM_flag_disable_all(em_iter, BM_ELEM_SELECT);
|
EDBM_flag_disable_all(em_iter, BM_ELEM_SELECT);
|
||||||
DEG_id_tag_update(ob_iter->data, DEG_TAG_SELECT_UPDATE);
|
DEG_id_tag_update(ob_iter->data, DEG_TAG_SELECT_UPDATE);
|
||||||
}
|
}
|
||||||
MEM_freeN(objects);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (em->selectmode & SCE_SELECT_FACE) {
|
if (em->selectmode & SCE_SELECT_FACE) {
|
||||||
@@ -2109,6 +2109,8 @@ static bool mouse_mesh_loop(bContext *C, const int mval[2], bool extend, bool de
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
MEM_freeN(bases);
|
||||||
|
|
||||||
DEG_id_tag_update(vc.obedit->data, DEG_TAG_SELECT_UPDATE);
|
DEG_id_tag_update(vc.obedit->data, DEG_TAG_SELECT_UPDATE);
|
||||||
WM_event_add_notifier(C, NC_GEOM | ND_SELECT, vc.obedit->data);
|
WM_event_add_notifier(C, NC_GEOM | ND_SELECT, vc.obedit->data);
|
||||||
|
|
||||||
@@ -2298,7 +2300,7 @@ bool EDBM_select_pick(bContext *C, const int mval[2], bool extend, bool deselect
|
|||||||
{
|
{
|
||||||
ViewContext vc;
|
ViewContext vc;
|
||||||
|
|
||||||
Base *basact = NULL;
|
int base_index_active = -1;
|
||||||
BMVert *eve = NULL;
|
BMVert *eve = NULL;
|
||||||
BMEdge *eed = NULL;
|
BMEdge *eed = NULL;
|
||||||
BMFace *efa = NULL;
|
BMFace *efa = NULL;
|
||||||
@@ -2308,23 +2310,26 @@ bool EDBM_select_pick(bContext *C, const int mval[2], bool extend, bool deselect
|
|||||||
vc.mval[0] = mval[0];
|
vc.mval[0] = mval[0];
|
||||||
vc.mval[1] = mval[1];
|
vc.mval[1] = mval[1];
|
||||||
|
|
||||||
if (unified_findnearest(&vc, &basact, &eve, &eed, &efa)) {
|
uint bases_len = 0;
|
||||||
|
Base **bases = BKE_view_layer_array_from_bases_in_edit_mode(vc.view_layer, &bases_len);
|
||||||
|
|
||||||
|
bool ok = false;
|
||||||
|
|
||||||
|
if (unified_findnearest(&vc, bases, bases_len, &base_index_active, &eve, &eed, &efa)) {
|
||||||
|
Base *basact = bases[base_index_active];
|
||||||
ED_view3d_viewcontext_init_object(&vc, basact->object);
|
ED_view3d_viewcontext_init_object(&vc, basact->object);
|
||||||
|
|
||||||
/* Deselect everything */
|
/* Deselect everything */
|
||||||
if (extend == false && deselect == false && toggle == false) {
|
if (extend == false && deselect == false && toggle == false) {
|
||||||
uint objects_len = 0;
|
for (uint base_index = 0; base_index < bases_len; base_index++) {
|
||||||
Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(vc.view_layer, &objects_len);
|
Base *base_iter = bases[base_index];
|
||||||
|
Object *ob_iter = base_iter->object;
|
||||||
for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
|
|
||||||
Object *ob_iter = objects[ob_index];
|
|
||||||
EDBM_flag_disable_all(BKE_editmesh_from_object(ob_iter), BM_ELEM_SELECT);
|
EDBM_flag_disable_all(BKE_editmesh_from_object(ob_iter), BM_ELEM_SELECT);
|
||||||
if (basact->object != ob_iter) {
|
if (basact->object != ob_iter) {
|
||||||
DEG_id_tag_update(ob_iter->data, DEG_TAG_SELECT_UPDATE);
|
DEG_id_tag_update(ob_iter->data, DEG_TAG_SELECT_UPDATE);
|
||||||
WM_event_add_notifier(C, NC_GEOM | ND_SELECT, ob_iter->data);
|
WM_event_add_notifier(C, NC_GEOM | ND_SELECT, ob_iter->data);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
MEM_freeN(objects);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (efa) {
|
if (efa) {
|
||||||
@@ -2444,10 +2449,12 @@ bool EDBM_select_pick(bContext *C, const int mval[2], bool extend, bool deselect
|
|||||||
DEG_id_tag_update(vc.obedit->data, DEG_TAG_SELECT_UPDATE);
|
DEG_id_tag_update(vc.obedit->data, DEG_TAG_SELECT_UPDATE);
|
||||||
WM_event_add_notifier(C, NC_GEOM | ND_SELECT, vc.obedit->data);
|
WM_event_add_notifier(C, NC_GEOM | ND_SELECT, vc.obedit->data);
|
||||||
|
|
||||||
return true;
|
ok = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
MEM_freeN(bases);
|
||||||
|
|
||||||
|
return ok;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** \} */
|
/** \} */
|
||||||
@@ -3388,19 +3395,20 @@ static int edbm_select_linked_pick_invoke(bContext *C, wmOperator *op, const wmE
|
|||||||
/* setup view context for argument to callbacks */
|
/* setup view context for argument to callbacks */
|
||||||
em_setup_viewcontext(C, &vc);
|
em_setup_viewcontext(C, &vc);
|
||||||
|
|
||||||
|
uint bases_len;
|
||||||
|
Base **bases = BKE_view_layer_array_from_bases_in_edit_mode(vc.view_layer, &bases_len);
|
||||||
|
|
||||||
{
|
{
|
||||||
uint objects_len = 0;
|
|
||||||
Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(vc.view_layer, &objects_len);
|
|
||||||
bool has_edges = false;
|
bool has_edges = false;
|
||||||
for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
|
for (uint base_index = 0; base_index < bases_len; base_index++) {
|
||||||
Object *ob_iter = objects[ob_index];
|
Object *ob_iter = bases[base_index]->object;
|
||||||
ED_view3d_viewcontext_init_object(&vc, ob_iter);
|
ED_view3d_viewcontext_init_object(&vc, ob_iter);
|
||||||
if (vc.em->bm->totedge) {
|
if (vc.em->bm->totedge) {
|
||||||
has_edges = true;
|
has_edges = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
MEM_freeN(objects);
|
|
||||||
if (has_edges == false) {
|
if (has_edges == false) {
|
||||||
|
MEM_freeN(bases);
|
||||||
return OPERATOR_CANCELLED;
|
return OPERATOR_CANCELLED;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -3409,9 +3417,16 @@ static int edbm_select_linked_pick_invoke(bContext *C, wmOperator *op, const wmE
|
|||||||
vc.mval[1] = event->mval[1];
|
vc.mval[1] = event->mval[1];
|
||||||
|
|
||||||
/* return warning! */
|
/* return warning! */
|
||||||
if (unified_findnearest(&vc, &basact, &eve, &eed, &efa) == 0) {
|
{
|
||||||
return OPERATOR_CANCELLED;
|
int base_index = -1;
|
||||||
|
const bool ok = unified_findnearest(&vc, bases, bases_len, &base_index, &eve, &eed, &efa);
|
||||||
|
if (!ok) {
|
||||||
|
MEM_freeN(bases);
|
||||||
|
return OPERATOR_CANCELLED;
|
||||||
|
}
|
||||||
|
basact = bases[base_index];
|
||||||
}
|
}
|
||||||
|
|
||||||
ED_view3d_viewcontext_init_object(&vc, basact->object);
|
ED_view3d_viewcontext_init_object(&vc, basact->object);
|
||||||
BMEditMesh *em = vc.em;
|
BMEditMesh *em = vc.em;
|
||||||
BMesh *bm = em->bm;
|
BMesh *bm = em->bm;
|
||||||
|
@@ -62,9 +62,9 @@
|
|||||||
|
|
||||||
typedef struct MeshElemGizmo3D {
|
typedef struct MeshElemGizmo3D {
|
||||||
wmGizmo gizmo;
|
wmGizmo gizmo;
|
||||||
Object **objects;
|
Base **bases;
|
||||||
uint objects_len;
|
uint bases_len;
|
||||||
int object_index;
|
int base_index;
|
||||||
int vert_index;
|
int vert_index;
|
||||||
int edge_index;
|
int edge_index;
|
||||||
int face_index;
|
int face_index;
|
||||||
@@ -74,8 +74,8 @@ typedef struct MeshElemGizmo3D {
|
|||||||
static void gizmo_preselect_elem_draw(const bContext *UNUSED(C), wmGizmo *gz)
|
static void gizmo_preselect_elem_draw(const bContext *UNUSED(C), wmGizmo *gz)
|
||||||
{
|
{
|
||||||
MeshElemGizmo3D *gz_ele = (MeshElemGizmo3D *)gz;
|
MeshElemGizmo3D *gz_ele = (MeshElemGizmo3D *)gz;
|
||||||
if (gz_ele->object_index != -1) {
|
if (gz_ele->base_index != -1) {
|
||||||
Object *ob = gz_ele->objects[gz_ele->object_index];
|
Object *ob = gz_ele->bases[gz_ele->base_index]->object;
|
||||||
EDBM_preselect_elem_draw(gz_ele->psel, ob->obmat);
|
EDBM_preselect_elem_draw(gz_ele->psel, ob->obmat);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -88,18 +88,18 @@ static int gizmo_preselect_elem_test_select(
|
|||||||
Object *ob;
|
Object *ob;
|
||||||
BMElem *ele;
|
BMElem *ele;
|
||||||
float dist;
|
float dist;
|
||||||
int ob_index;
|
int base_index;
|
||||||
} best = {
|
} best = {
|
||||||
.dist = ED_view3d_select_dist_px(),
|
.dist = ED_view3d_select_dist_px(),
|
||||||
};
|
};
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
int object_index;
|
int base_index;
|
||||||
int vert_index;
|
int vert_index;
|
||||||
int edge_index;
|
int edge_index;
|
||||||
int face_index;
|
int face_index;
|
||||||
} prev = {
|
} prev = {
|
||||||
.object_index = gz_ele->object_index,
|
.base_index = gz_ele->base_index,
|
||||||
.vert_index = gz_ele->vert_index,
|
.vert_index = gz_ele->vert_index,
|
||||||
.edge_index = gz_ele->edge_index,
|
.edge_index = gz_ele->edge_index,
|
||||||
.face_index = gz_ele->face_index,
|
.face_index = gz_ele->face_index,
|
||||||
@@ -107,11 +107,12 @@ static int gizmo_preselect_elem_test_select(
|
|||||||
|
|
||||||
{
|
{
|
||||||
ViewLayer *view_layer = CTX_data_view_layer(C);
|
ViewLayer *view_layer = CTX_data_view_layer(C);
|
||||||
if (((gz_ele->objects)) == NULL ||
|
if (((gz_ele->bases)) == NULL ||
|
||||||
(gz_ele->objects[0] != OBEDIT_FROM_VIEW_LAYER(view_layer)))
|
(gz_ele->bases[0] != view_layer->basact))
|
||||||
{
|
{
|
||||||
gz_ele->objects = BKE_view_layer_array_from_objects_in_edit_mode(
|
MEM_SAFE_FREE(gz_ele->bases);
|
||||||
view_layer, &gz_ele->objects_len);
|
gz_ele->bases = BKE_view_layer_array_from_bases_in_edit_mode(
|
||||||
|
view_layer, &gz_ele->bases_len);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -121,11 +122,15 @@ static int gizmo_preselect_elem_test_select(
|
|||||||
|
|
||||||
{
|
{
|
||||||
/* TODO: support faces. */
|
/* TODO: support faces. */
|
||||||
Base *base = NULL;
|
int base_index = -1;
|
||||||
BMVert *eve_test;
|
BMVert *eve_test;
|
||||||
BMEdge *eed_test;
|
BMEdge *eed_test;
|
||||||
|
|
||||||
if (EDBM_unified_findnearest_from_raycast(&vc, true, &base, &eve_test, &eed_test, NULL)) {
|
if (EDBM_unified_findnearest_from_raycast(
|
||||||
|
&vc, gz_ele->bases, gz_ele->bases_len,
|
||||||
|
true, &base_index, &eve_test, &eed_test, NULL))
|
||||||
|
{
|
||||||
|
Base *base = gz_ele->bases[base_index];
|
||||||
best.ob = base->object;
|
best.ob = base->object;
|
||||||
if (eve_test) {
|
if (eve_test) {
|
||||||
best.ele = (BMElem *)eve_test;
|
best.ele = (BMElem *)eve_test;
|
||||||
@@ -136,30 +141,22 @@ static int gizmo_preselect_elem_test_select(
|
|||||||
else {
|
else {
|
||||||
BLI_assert(0);
|
BLI_assert(0);
|
||||||
}
|
}
|
||||||
best.ob_index = -1;
|
best.base_index = base_index;
|
||||||
/* weak, we could ensure the arrays are aligned,
|
|
||||||
* or allow EDBM_unified_findnearest_from_raycast to take an array arg. */
|
|
||||||
for (int ob_index = 0; ob_index < gz_ele->objects_len; ob_index++) {
|
|
||||||
if (best.ob == gz_ele->objects[ob_index]) {
|
|
||||||
best.ob_index = ob_index;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/* 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.ob_index != -1);
|
BLI_assert(best.base_index != -1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
BMesh *bm = NULL;
|
BMesh *bm = NULL;
|
||||||
|
|
||||||
gz_ele->object_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->object_index = best.ob_index;
|
gz_ele->base_index = best.base_index;
|
||||||
bm = BKE_editmesh_from_object(gz_ele->objects[gz_ele->object_index])->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) {
|
||||||
@@ -173,7 +170,7 @@ static int gizmo_preselect_elem_test_select(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((prev.object_index == gz_ele->object_index) &&
|
if ((prev.base_index == gz_ele->base_index) &&
|
||||||
(prev.vert_index == gz_ele->vert_index) &&
|
(prev.vert_index == gz_ele->vert_index) &&
|
||||||
(prev.edge_index == gz_ele->edge_index) &&
|
(prev.edge_index == gz_ele->edge_index) &&
|
||||||
(prev.face_index == gz_ele->face_index))
|
(prev.face_index == gz_ele->face_index))
|
||||||
@@ -184,7 +181,7 @@ static int gizmo_preselect_elem_test_select(
|
|||||||
if (best.ele) {
|
if (best.ele) {
|
||||||
const float (*coords)[3] = NULL;
|
const float (*coords)[3] = NULL;
|
||||||
{
|
{
|
||||||
Object *ob = gz_ele->objects[gz_ele->object_index];
|
Object *ob = gz_ele->bases[gz_ele->base_index]->object;
|
||||||
Depsgraph *depsgraph = CTX_data_depsgraph(C);
|
Depsgraph *depsgraph = CTX_data_depsgraph(C);
|
||||||
Mesh *me_eval = (Mesh *)DEG_get_evaluated_id(depsgraph, ob->data);
|
Mesh *me_eval = (Mesh *)DEG_get_evaluated_id(depsgraph, ob->data);
|
||||||
if (me_eval->runtime.edit_data) {
|
if (me_eval->runtime.edit_data) {
|
||||||
@@ -197,7 +194,7 @@ static int gizmo_preselect_elem_test_select(
|
|||||||
EDBM_preselect_elem_clear(gz_ele->psel);
|
EDBM_preselect_elem_clear(gz_ele->psel);
|
||||||
}
|
}
|
||||||
|
|
||||||
RNA_int_set(gz->ptr, "object_index", gz_ele->object_index);
|
RNA_int_set(gz->ptr, "object_index", gz_ele->base_index);
|
||||||
RNA_int_set(gz->ptr, "vert_index", gz_ele->vert_index);
|
RNA_int_set(gz->ptr, "vert_index", gz_ele->vert_index);
|
||||||
RNA_int_set(gz->ptr, "edge_index", gz_ele->edge_index);
|
RNA_int_set(gz->ptr, "edge_index", gz_ele->edge_index);
|
||||||
RNA_int_set(gz->ptr, "face_index", gz_ele->face_index);
|
RNA_int_set(gz->ptr, "face_index", gz_ele->face_index);
|
||||||
@@ -216,7 +213,7 @@ static void gizmo_preselect_elem_setup(wmGizmo *gz)
|
|||||||
if (gz_ele->psel == NULL) {
|
if (gz_ele->psel == NULL) {
|
||||||
gz_ele->psel = EDBM_preselect_elem_create();
|
gz_ele->psel = EDBM_preselect_elem_create();
|
||||||
}
|
}
|
||||||
gz_ele->object_index = -1;
|
gz_ele->base_index = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void gizmo_preselect_elem_free(wmGizmo *gz)
|
static void gizmo_preselect_elem_free(wmGizmo *gz)
|
||||||
@@ -224,7 +221,7 @@ 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 = NULL;
|
||||||
MEM_SAFE_FREE(gz_ele->objects);
|
MEM_SAFE_FREE(gz_ele->bases);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int gizmo_preselect_elem_invoke(
|
static int gizmo_preselect_elem_invoke(
|
||||||
@@ -262,9 +259,9 @@ static void GIZMO_GT_mesh_preselect_elem_3d(wmGizmoType *gzt)
|
|||||||
|
|
||||||
typedef struct MeshEdgeRingGizmo3D {
|
typedef struct MeshEdgeRingGizmo3D {
|
||||||
wmGizmo gizmo;
|
wmGizmo gizmo;
|
||||||
Object **objects;
|
Base **bases;
|
||||||
uint objects_len;
|
uint bases_len;
|
||||||
int object_index;
|
int base_index;
|
||||||
int edge_index;
|
int edge_index;
|
||||||
struct EditMesh_PreSelEdgeRing *psel;
|
struct EditMesh_PreSelEdgeRing *psel;
|
||||||
} MeshEdgeRingGizmo3D;
|
} MeshEdgeRingGizmo3D;
|
||||||
@@ -272,8 +269,8 @@ typedef struct MeshEdgeRingGizmo3D {
|
|||||||
static void gizmo_preselect_edgering_draw(const bContext *UNUSED(C), wmGizmo *gz)
|
static void gizmo_preselect_edgering_draw(const bContext *UNUSED(C), wmGizmo *gz)
|
||||||
{
|
{
|
||||||
MeshEdgeRingGizmo3D *gz_ring = (MeshEdgeRingGizmo3D *)gz;
|
MeshEdgeRingGizmo3D *gz_ring = (MeshEdgeRingGizmo3D *)gz;
|
||||||
if (gz_ring->object_index != -1) {
|
if (gz_ring->base_index != -1) {
|
||||||
Object *ob = gz_ring->objects[gz_ring->object_index];
|
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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -286,26 +283,27 @@ static int gizmo_preselect_edgering_test_select(
|
|||||||
Object *ob;
|
Object *ob;
|
||||||
BMEdge *eed;
|
BMEdge *eed;
|
||||||
float dist;
|
float dist;
|
||||||
int ob_index;
|
int base_index;
|
||||||
} best = {
|
} best = {
|
||||||
.dist = ED_view3d_select_dist_px(),
|
.dist = ED_view3d_select_dist_px(),
|
||||||
};
|
};
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
int object_index;
|
int base_index;
|
||||||
int edge_index;
|
int edge_index;
|
||||||
} prev = {
|
} prev = {
|
||||||
.object_index = gz_ring->object_index,
|
.base_index = gz_ring->base_index,
|
||||||
.edge_index = gz_ring->edge_index,
|
.edge_index = gz_ring->edge_index,
|
||||||
};
|
};
|
||||||
|
|
||||||
{
|
{
|
||||||
ViewLayer *view_layer = CTX_data_view_layer(C);
|
ViewLayer *view_layer = CTX_data_view_layer(C);
|
||||||
if (((gz_ring->objects)) == NULL ||
|
if (((gz_ring->bases)) == NULL ||
|
||||||
(gz_ring->objects[0] != OBEDIT_FROM_VIEW_LAYER(view_layer)))
|
(gz_ring->bases[0] != view_layer->basact))
|
||||||
{
|
{
|
||||||
gz_ring->objects = BKE_view_layer_array_from_objects_in_edit_mode(
|
MEM_SAFE_FREE(gz_ring->bases);
|
||||||
view_layer, &gz_ring->objects_len);
|
gz_ring->bases = BKE_view_layer_array_from_bases_in_edit_mode(
|
||||||
|
view_layer, &gz_ring->bases_len);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -313,31 +311,31 @@ static int gizmo_preselect_edgering_test_select(
|
|||||||
em_setup_viewcontext(C, &vc);
|
em_setup_viewcontext(C, &vc);
|
||||||
copy_v2_v2_int(vc.mval, mval);
|
copy_v2_v2_int(vc.mval, mval);
|
||||||
|
|
||||||
for (uint ob_index = 0; ob_index < gz_ring->objects_len; ob_index++) {
|
for (uint base_index = 0; base_index < gz_ring->bases_len; base_index++) {
|
||||||
Object *ob_iter = gz_ring->objects[ob_index];
|
Object *ob_iter = gz_ring->bases[base_index]->object;
|
||||||
ED_view3d_viewcontext_init_object(&vc, ob_iter);
|
ED_view3d_viewcontext_init_object(&vc, ob_iter);
|
||||||
BMEdge *eed_test = EDBM_edge_find_nearest_ex(&vc, &best.dist, NULL, false, false, NULL);
|
BMEdge *eed_test = EDBM_edge_find_nearest_ex(&vc, &best.dist, NULL, false, false, NULL);
|
||||||
if (eed_test) {
|
if (eed_test) {
|
||||||
best.ob = ob_iter;
|
best.ob = ob_iter;
|
||||||
best.eed = eed_test;
|
best.eed = eed_test;
|
||||||
best.ob_index = ob_index;
|
best.base_index = base_index;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
BMesh *bm = NULL;
|
BMesh *bm = NULL;
|
||||||
if (best.eed) {
|
if (best.eed) {
|
||||||
gz_ring->object_index = best.ob_index;
|
gz_ring->base_index = best.base_index;
|
||||||
bm = BKE_editmesh_from_object(gz_ring->objects[gz_ring->object_index])->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->object_index = -1;
|
gz_ring->base_index = -1;
|
||||||
gz_ring->edge_index = -1;
|
gz_ring->edge_index = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if ((prev.object_index == gz_ring->object_index) &&
|
if ((prev.base_index == gz_ring->base_index) &&
|
||||||
(prev.edge_index == gz_ring->edge_index))
|
(prev.edge_index == gz_ring->edge_index))
|
||||||
{
|
{
|
||||||
/* pass (only recalculate on change) */
|
/* pass (only recalculate on change) */
|
||||||
@@ -346,7 +344,7 @@ static int gizmo_preselect_edgering_test_select(
|
|||||||
if (best.eed) {
|
if (best.eed) {
|
||||||
const float (*coords)[3] = NULL;
|
const float (*coords)[3] = NULL;
|
||||||
{
|
{
|
||||||
Object *ob = gz_ring->objects[gz_ring->object_index];
|
Object *ob = gz_ring->bases[gz_ring->base_index]->object;
|
||||||
Depsgraph *depsgraph = CTX_data_depsgraph(C);
|
Depsgraph *depsgraph = CTX_data_depsgraph(C);
|
||||||
Mesh *me_eval = (Mesh *)DEG_get_evaluated_id(depsgraph, ob->data);
|
Mesh *me_eval = (Mesh *)DEG_get_evaluated_id(depsgraph, ob->data);
|
||||||
if (me_eval->runtime.edit_data) {
|
if (me_eval->runtime.edit_data) {
|
||||||
@@ -359,7 +357,7 @@ static int gizmo_preselect_edgering_test_select(
|
|||||||
EDBM_preselect_edgering_clear(gz_ring->psel);
|
EDBM_preselect_edgering_clear(gz_ring->psel);
|
||||||
}
|
}
|
||||||
|
|
||||||
RNA_int_set(gz->ptr, "object_index", gz_ring->object_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 *ar = CTX_wm_region(C);
|
ARegion *ar = CTX_wm_region(C);
|
||||||
@@ -376,7 +374,7 @@ static void gizmo_preselect_edgering_setup(wmGizmo *gz)
|
|||||||
if (gz_ring->psel == NULL) {
|
if (gz_ring->psel == NULL) {
|
||||||
gz_ring->psel = EDBM_preselect_edgering_create();
|
gz_ring->psel = EDBM_preselect_edgering_create();
|
||||||
}
|
}
|
||||||
gz_ring->object_index = -1;
|
gz_ring->base_index = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void gizmo_preselect_edgering_free(wmGizmo *gz)
|
static void gizmo_preselect_edgering_free(wmGizmo *gz)
|
||||||
@@ -384,7 +382,7 @@ 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 = NULL;
|
||||||
MEM_SAFE_FREE(gz_ring->objects);
|
MEM_SAFE_FREE(gz_ring->bases);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int gizmo_preselect_edgering_invoke(
|
static int gizmo_preselect_edgering_invoke(
|
||||||
|
Reference in New Issue
Block a user