116 *r_totmirr = *r_totfail = 0;
192 *r_totmirr = totmirr;
193 *r_totfail = totfail;
211 Object *obedit = bases[*r_base_index]->object;
243#define FIND_NEAR_SELECT_BIAS 5
244#define FIND_NEAR_CYCLE_THRESHOLD_MIN 3
265 const float screen_co[2],
269 float dist_test, dist_test_bias;
277 if (dist_test_bias < data->hit.dist_bias) {
278 data->hit.dist_bias = dist_test_bias;
279 data->hit.dist = dist_test;
280 data->hit.index = index;
281 data->hit.vert = eve;
284 if (data->use_cycle) {
285 if ((data->hit_cycle.vert ==
nullptr) && (index > data->cycle_index_prev) &&
288 data->hit_cycle.dist_bias = dist_test_bias;
289 data->hit_cycle.dist = dist_test;
290 data->hit_cycle.index = index;
291 data->hit_cycle.vert = eve;
297 float *dist_px_manhattan_p,
298 const bool use_select_bias,
327 if (dist_px_manhattan_test < *dist_px_manhattan_p) {
329 *r_base_index = base_index;
331 *dist_px_manhattan_p = dist_px_manhattan_test;
343 BMesh *prev_select_bm =
nullptr;
351 data.mval_fl[0] = vc->
mval[0];
352 data.mval_fl[1] = vc->
mval[1];
353 data.use_select_bias = use_select_bias;
354 data.use_cycle = use_cycle;
356 for (; base_index < bases.
size(); base_index++) {
357 Base *base_iter = bases[base_index];
359 if (use_cycle && prev_select.bm == vc->
em->
bm &&
362 data.cycle_index_prev = prev_select.index;
367 data.cycle_index_prev = 0;
370 data.hit.dist = data.hit_cycle.dist = data.hit.dist_bias = data.hit_cycle.dist_bias =
371 *dist_px_manhattan_p;
376 hit = (data.use_cycle && data.hit_cycle.vert) ? &data.hit_cycle : &data.hit;
378 if (hit->dist < *dist_px_manhattan_p) {
380 *r_base_index = base_index;
382 *dist_px_manhattan_p = hit->dist;
383 prev_select_bm = vc->
em->
bm;
387 if (hit ==
nullptr) {
391 prev_select.index = hit->index;
392 prev_select.elem = hit->vert;
393 prev_select.bm = prev_select_bm;
414 const float screen_co_a[2],
415 const float screen_co_b[2],
420 if (eed == data->edge_test) {
422 float screen_co_mid[2];
424 mid_v2_v2v2(screen_co_mid, screen_co_a, screen_co_b);
427 if (dist_test < data->dist) {
428 data->dist = dist_test;
458 const float screen_co_a[2],
459 const float screen_co_b[2],
463 float dist_test, dist_test_bias;
472 else if (fac >= 1.0f) {
495 if (dist_test_bias < data->hit.dist_bias) {
496 float screen_co_mid[2];
498 data->hit.dist_bias = dist_test_bias;
499 data->hit.dist = dist_test;
500 data->hit.index = index;
501 data->hit.edge = eed;
503 mid_v2_v2v2(screen_co_mid, screen_co_a, screen_co_b);
504 data->hit.dist_center_px_manhattan =
len_manhattan_v2v2(data->mval_fl, screen_co_mid);
507 if (data->use_cycle) {
508 if ((data->hit_cycle.edge ==
nullptr) && (index > data->cycle_index_prev) &&
511 float screen_co_mid[2];
513 data->hit_cycle.dist_bias = dist_test_bias;
514 data->hit_cycle.dist = dist_test;
515 data->hit_cycle.index = index;
516 data->hit_cycle.edge = eed;
518 mid_v2_v2v2(screen_co_mid, screen_co_a, screen_co_b);
519 data->hit_cycle.dist_center_px_manhattan =
len_manhattan_v2v2(data->mval_fl, screen_co_mid);
525 float *dist_px_manhattan_p,
526 float *r_dist_center_px_manhattan,
527 const bool use_select_bias,
561 if (r_dist_center_px_manhattan && eed) {
565 data.mval_fl[1] = vc->
mval[1];
567 data.edge_test = eed;
576 *r_dist_center_px_manhattan = data.dist;
581 if (dist_px_manhattan_test < *dist_px_manhattan_p) {
583 *r_base_index = base_index;
585 *dist_px_manhattan_p = dist_px_manhattan_test;
596 BMesh *prev_select_bm =
nullptr;
605 data.mval_fl[0] = vc->
mval[0];
606 data.mval_fl[1] = vc->
mval[1];
607 data.use_select_bias = use_select_bias;
608 data.use_cycle = use_cycle;
610 for (; base_index < bases.
size(); base_index++) {
611 Base *base_iter = bases[base_index];
613 if (use_cycle && prev_select.bm == vc->
em->
bm &&
616 data.cycle_index_prev = prev_select.index;
621 data.cycle_index_prev = 0;
624 data.hit.dist = data.hit_cycle.dist = data.hit.dist_bias = data.hit_cycle.dist_bias =
625 *dist_px_manhattan_p;
631 hit = (data.use_cycle && data.hit_cycle.edge) ? &data.hit_cycle : &data.hit;
633 if (hit->dist < *dist_px_manhattan_p) {
635 *r_base_index = base_index;
637 *dist_px_manhattan_p = hit->dist;
638 prev_select_bm = vc->
em->
bm;
642 if (hit ==
nullptr) {
646 if (r_dist_center_px_manhattan) {
647 *r_dist_center_px_manhattan = hit->dist_center_px_manhattan;
650 prev_select.index = hit->index;
651 prev_select.elem = hit->edge;
652 prev_select.bm = prev_select_bm;
662 vc, dist_px_manhattan_p,
nullptr,
false,
false,
nullptr, {base},
nullptr);
674 const float screen_co[2],
679 if (efa == data->face_test) {
682 if (dist_test < data->dist_px_manhattan) {
683 data->dist_px_manhattan = dist_test;
707 const float screen_co[2],
711 float dist_test, dist_test_bias;
719 if (dist_test_bias < data->hit.dist_bias) {
720 data->hit.dist_bias = dist_test_bias;
721 data->hit.dist = dist_test;
722 data->hit.index = index;
723 data->hit.face = efa;
726 if (data->use_cycle) {
727 if ((data->hit_cycle.face ==
nullptr) && (index > data->cycle_index_prev) &&
730 data->hit_cycle.dist_bias = dist_test_bias;
731 data->hit_cycle.dist = dist_test;
732 data->hit_cycle.index = index;
733 data->hit_cycle.face = efa;
739 float *dist_px_manhattan_p,
740 float *r_dist_center,
741 const bool use_zbuf_single_px,
742 const bool use_select_bias,
756 uint dist_px_manhattan_test = 0;
757 if (*dist_px_manhattan_p != 0.0f && (use_zbuf_single_px ==
false)) {
758 dist_px_manhattan_test =
uint(
764 if (dist_px_manhattan_test == 0) {
771 dist_test = dist_px_manhattan_test;
787 if (r_dist_center && efa) {
791 data.mval_fl[1] = vc->
mval[1];
792 data.dist_px_manhattan =
FLT_MAX;
793 data.face_test = efa;
800 *r_dist_center = data.dist_px_manhattan;
805 if (dist_test < *dist_px_manhattan_p) {
807 *r_base_index = base_index;
809 *dist_px_manhattan_p = dist_test;
819 BMesh *prev_select_bm =
nullptr;
827 data.mval_fl[0] = vc->
mval[0];
828 data.mval_fl[1] = vc->
mval[1];
829 data.use_select_bias = use_select_bias;
830 data.use_cycle = use_cycle;
832 for (; base_index < bases.
size(); base_index++) {
833 Base *base_iter = bases[base_index];
835 if (use_cycle && prev_select.bm == vc->
em->
bm &&
838 data.cycle_index_prev = prev_select.index;
843 data.cycle_index_prev = 0;
846 data.hit.dist = data.hit_cycle.dist = data.hit.dist_bias = data.hit_cycle.dist_bias =
847 *dist_px_manhattan_p;
852 hit = (data.use_cycle && data.hit_cycle.face) ? &data.hit_cycle : &data.hit;
854 if (hit->dist < *dist_px_manhattan_p) {
856 *r_base_index = base_index;
858 *dist_px_manhattan_p = hit->dist;
859 prev_select_bm = vc->
em->
bm;
863 if (hit ==
nullptr) {
868 *r_dist_center = hit->dist;
871 prev_select.index = hit->index;
872 prev_select.elem = hit->face;
873 prev_select.bm = prev_select_bm;
883 vc, dist_px_manhattan_p,
nullptr,
false,
false,
false,
nullptr, {base},
nullptr);
886#undef FIND_NEAR_SELECT_BIAS
887#undef FIND_NEAR_CYCLE_THRESHOLD_MIN
906 const float dist_margin = (dist_init / 2);
907 float dist = dist_init;
927 float dist_center = 0.0f;
933 BMFace *efa_zbuf =
nullptr;
935 vc, &dist, dist_center_p,
true,
true, use_cycle, &efa_zbuf, bases, &base_index);
937 if (efa_test && dist_center_p) {
938 dist =
min_ff(dist_margin, dist_center);
941 hit.f.base_index = base_index;
942 hit.f.ele = efa_test;
945 hit.f_zbuf.base_index = base_index;
946 hit.f_zbuf.ele = efa_zbuf;
951 float dist_center = 0.0f;
955 BMEdge *eed_zbuf =
nullptr;
957 vc, &dist, dist_center_p,
true, use_cycle, &eed_zbuf, bases, &base_index);
959 if (eed_test && dist_center_p) {
960 dist =
min_ff(dist_margin, dist_center);
963 hit.e.base_index = base_index;
964 hit.e.ele = eed_test;
967 hit.e_zbuf.base_index = base_index;
968 hit.e_zbuf.ele = eed_zbuf;
977 hit.v.base_index = base_index;
978 hit.v.ele = eve_test;
987 else if (hit.e.ele) {
993 if ((hit.v.ele || hit.e.ele || hit.f.ele) == 0) {
994 if (hit.e_zbuf.ele) {
995 hit.e.base_index = hit.e_zbuf.base_index;
996 hit.e.ele = hit.e_zbuf.ele;
998 else if (hit.f_zbuf.ele) {
999 hit.f.base_index = hit.f_zbuf.base_index;
1000 hit.f.ele = hit.f_zbuf.ele;
1005 BLI_assert(((hit.v.ele !=
nullptr) + (hit.e.ele !=
nullptr) + (hit.f.ele !=
nullptr)) <= 1);
1008 *r_base_index = hit.v.base_index;
1011 *r_base_index = hit.e.base_index;
1014 *r_base_index = hit.f.base_index;
1021 return (hit.v.ele || hit.e.ele || hit.f.ele);
1024#undef FAKE_SELECT_MODE_BEGIN
1025#undef FAKE_SELECT_MODE_END
1048 bool use_boundary_vertices,
1049 bool use_boundary_edges,
1050 int *r_base_index_vert,
1051 int *r_base_index_edge,
1052 int *r_base_index_face,
1058 float ray_origin[3], ray_direction[3];
1063 } best = {0,
nullptr};
1070 } best_vert = {0,
nullptr};
1075 } best_edge = {0,
nullptr};
1080 } best_face = {0,
nullptr};
1086 float dist_sq_best_vert =
FLT_MAX;
1087 float dist_sq_best_edge =
FLT_MAX;
1088 float dist_sq_best_face =
FLT_MAX;
1090 const bool use_vert = (r_eve !=
nullptr);
1091 const bool use_edge = (r_eed !=
nullptr);
1092 const bool use_face = (r_efa !=
nullptr);
1094 for (
const int base_index : bases.
index_range()) {
1095 Base *base_iter = bases[base_index];
1103 copy_m3_m4(imat3, obedit->object_to_world().ptr());
1119 if ((use_boundary_vertices || use_boundary_edges) && (use_vert || use_edge)) {
1124 if (use_vert && use_boundary_vertices) {
1125 for (
uint j = 0; j < 2; j++) {
1129 obedit->object_to_world().ptr(),
1133 ray_origin, ray_direction, point);
1134 if (dist_sq_test < dist_sq_best_vert) {
1135 dist_sq_best_vert = dist_sq_test;
1136 best_vert.base_index = base_index;
1139 if (dist_sq_test < dist_sq_best) {
1140 dist_sq_best = dist_sq_test;
1141 best.base_index = base_index;
1147 if (use_edge && use_boundary_edges) {
1151 ray_origin, ray_direction,
e->v1->
co,
e->v2->
co, point, &depth);
1161 mul_m4_v3(obedit->object_to_world().ptr(), point);
1163 ray_origin, ray_direction, point);
1164 if (dist_sq_test < dist_sq_best_edge) {
1165 dist_sq_best_edge = dist_sq_test;
1166 best_edge.base_index = base_index;
1169 if (dist_sq_test < dist_sq_best) {
1170 dist_sq_best = dist_sq_test;
1171 best.base_index = base_index;
1180 if (use_vert && !use_boundary_vertices) {
1187 obedit->object_to_world().ptr(),
1190 ray_origin, ray_direction, point);
1191 if (dist_sq_test < dist_sq_best_vert) {
1192 dist_sq_best_vert = dist_sq_test;
1193 best_vert.base_index = base_index;
1196 if (dist_sq_test < dist_sq_best) {
1197 dist_sq_best = dist_sq_test;
1198 best.base_index = base_index;
1205 if (use_edge && !use_boundary_edges) {
1219 mul_m4_v3(obedit->object_to_world().ptr(), point);
1221 ray_origin, ray_direction, point);
1222 if (dist_sq_test < dist_sq_best_edge) {
1223 dist_sq_best_edge = dist_sq_test;
1224 best_edge.base_index = base_index;
1227 if (dist_sq_test < dist_sq_best) {
1228 dist_sq_best = dist_sq_test;
1229 best.base_index = base_index;
1248 mul_m4_v3(obedit->object_to_world().ptr(), point);
1250 ray_origin, ray_direction, point);
1251 if (dist_sq_test < dist_sq_best_face) {
1252 dist_sq_best_face = dist_sq_test;
1253 best_face.base_index = base_index;
1254 best_face.ele = (
BMElem *)f;
1256 if (dist_sq_test < dist_sq_best) {
1257 dist_sq_best = dist_sq_test;
1258 best.base_index = base_index;
1267 *r_base_index_vert = best_vert.base_index;
1268 *r_base_index_edge = best_edge.base_index;
1269 *r_base_index_face = best_face.base_index;
1281 if (best_vert.ele) {
1282 *r_eve = (
BMVert *)best_vert.ele;
1284 if (best_edge.ele) {
1285 *r_eed = (
BMEdge *)best_edge.ele;
1287 if (best_face.ele) {
1288 *r_efa = (
BMFace *)best_face.ele;
1291 return (best_vert.ele !=
nullptr || best_edge.ele !=
nullptr || best_face.ele !=
nullptr);
1305 bool changed =
false;
1308 int(*group_index)[2];
1317 int *groups_array =
static_cast<int *
>(
1324 for (i = 0; i < group_tot; i++) {
1328 const int fg_sta = group_index[i][0];
1329 const int fg_len = group_index[i][1];
1333 for (j = 0; j < fg_len; j++) {
1344 while (
BMFace *f = *(faces++)) {
1372 ot->
name =
"Select Similar Regions";
1373 ot->
idname =
"MESH_OT_select_similar_region";
1374 ot->
description =
"Select similar face regions to the current selection";
1445 "Vertex select - Shift-Click for multiple modes, Ctrl-Click contracts selection");
1448 "Edge select - Shift-Click for multiple modes, "
1449 "Ctrl-Click expands/contracts selection depending on the current mode");
1451 return TIP_(
"Face select - Shift-Click for multiple modes, Ctrl-Click expands selection");
1463 {0,
"DISABLE",
false,
"Disable",
"Disable selected markers"},
1464 {1,
"ENABLE",
false,
"Enable",
"Enable selected markers"},
1465 {2,
"TOGGLE",
false,
"Toggle",
"Toggle disabled flag for selected markers"},
1466 {0,
nullptr, 0,
nullptr,
nullptr},
1470 ot->
name =
"Select Mode";
1471 ot->
idname =
"MESH_OT_select_mode";
1493 ot->
srna,
"action", actions_items, 2,
"Action",
"Selection action to execute");
1506 int r_count_by_select[2])
1512 r_count_by_select[0] = r_count_by_select[1] = 0;
1529 if (r_count_by_select[0] && r_count_by_select[1]) {
1530 r_count_by_select[0] = r_count_by_select[1] = -1;
1571 for (
Object *obedit : objects) {
1595 edarray[edindex] = eed;
1601 for (edindex = 0; edindex < totedgesel; edindex += 1) {
1602 eed = edarray[edindex];
1608 for (edindex = 0; edindex < totedgesel; edindex += 1) {
1609 eed = edarray[edindex];
1633 ot->
name =
"Multi Select Loops";
1634 ot->
idname =
"MESH_OT_loop_multi_select";
1635 ot->
description =
"Select a loop of connected edges by connection type";
1675 bool edge_boundary =
false;
1680 int count_by_select[2];
1684 if (count_by_select[!
select] == 0) {
1685 edge_boundary =
true;
1689 if (count_by_select[!
select] == 0) {
1690 edge_boundary =
false;
1699 if (edge_boundary) {
1702 else if (non_manifold) {
1711 bContext *C,
const int mval[2],
bool extend,
bool deselect,
bool toggle,
bool ring)
1713 Base *basact =
nullptr;
1720 bool select_clear =
false;
1721 bool select_cycle =
true;
1729 const short selectmode = em_original->
selectmode;
1736 int base_index = -1;
1738 basact = bases[base_index];
1749 if (em ==
nullptr || eed ==
nullptr) {
1753 if (extend ==
false && deselect ==
false && toggle ==
false) {
1754 select_clear =
true;
1760 else if (deselect) {
1768 select_cycle =
false;
1772 for (
Base *base_iter : bases) {
1773 Object *ob_iter = base_iter->object;
1780 if (em_iter == em) {
1808 float v1_co[2], v2_co[2];
1827 printf(
"mouse to v1: %f\nmouse to v2: %f\n",
1856 if (tdist < best_dist) {
1897 ot->
name =
"Loop Select";
1898 ot->
idname =
"MESH_OT_loop_select";
1924 ot->
name =
"Edge Ring Select";
1925 ot->
idname =
"MESH_OT_edgering_select";
1964 for (
Object *obedit : objects) {
1973 for (
Object *obedit : objects) {
1997 ot->
name =
"(De)select All";
1999 ot->
description =
"(De)select all vertices, edges or faces";
2024 for (
Object *obedit : objects) {
2041 ot->
name =
"Select Interior Faces";
2042 ot->
idname =
"MESH_OT_select_interior_faces";
2043 ot->
description =
"Select faces where all edges have more than 2 face users";
2064 int base_index_active = -1;
2071 vc.
mval[0] = mval[0];
2072 vc.
mval[1] = mval[1];
2077 bool changed =
false;
2085 else if (found ||
params->deselect_all) {
2087 for (
Base *base_iter : bases) {
2088 Object *ob_iter = base_iter->object;
2098 Base *basact = bases[base_index_active];
2102 switch (
params->sel_op) {
2147 switch (
params->sel_op) {
2187 switch (
params->sel_op) {
2267 nextese = ese->
next;
2277 nextese = ese->
next;
2287 nextese = ese->
next;
2351 const short selectmode_old,
2352 const short selectmode_new)
2457 const short selectmode_new,
2459 const bool use_extend,
2460 const bool use_expand)
2473 if (em ==
nullptr) {
2477 bool only_update =
false;
2484 if ((em->
selectmode & selectmode_new) == 0) {
2492 if ((em->
selectmode & selectmode_new) != 0) {
2514 for (
Object *ob_iter : objects) {
2516 if (em_iter != em) {
2525 if (use_extend == 0 || em->
selectmode == 0) {
2528 for (
Object *ob_iter : objects) {
2535 switch (selectmode_new) {
2537 if (use_extend == 0 || em->
selectmode == 0) {
2543 if (use_extend == 0 || em->
selectmode == 0) {
2549 if (use_extend == 0 || em->
selectmode == 0) {
2562 for (
Object *ob_iter : objects) {
2580 bool changed =
false;
2588 if (em ==
nullptr) {
2605 for (
Object *ob_iter : objects) {
2638 if (objects.size() <= 1) {
2642 bool changed =
false;
2644 for (
Object *obedit : objects) {
2662 const short selectmode_disable,
2663 const short selectmode_fallback)
2674 scene->toolsettings->selectmode = em->
selectmode;
2694 bool changed =
false;
2700 if (efa->
mat_nr == index) {
2753 bool changed_multi =
false;
2754 for (
Base *base_iter : bases) {
2755 Object *ob_iter = base_iter->object;
2764 changed_multi =
true;
2766 return changed_multi;
2780 const short selectmode_disable,
2781 const short selectmode_fallback)
2783 bool changed_multi =
false;
2784 for (
Base *base_iter : bases) {
2785 Object *ob_iter = base_iter->object;
2789 changed_multi =
true;
2792 return changed_multi;
2796 const short selectmode_disable,
2797 const short selectmode_fallback)
2844 if (!
ELEM(i, -1, face_index)) {
2845 if (loop_index == 2) {
2848 r_l_pair[loop_index++] = l_iter;
2851 return (loop_index == 2);
2866 BMFace *f = f_link->face;
2867 area += f_link->area;
2870 BMLoop *l_iter, *l_first;
2874 float cost_test = 0.0f;
2877 BMLoop *l_radial_iter = l_iter;
2880 if (!
ELEM(i_other, -1, i)) {
2896 }
while ((l_radial_iter = l_radial_iter->
radial_next) != l_iter);
2898 if (cost_count >= 2) {
2903 }
while ((l_iter = l_iter->
next) != l_first);
2905 return found ? cost / area :
FLT_MAX;
2912 bool changed =
false;
2914 float *edge_lengths =
static_cast<float *
>(
2918 bool has_nonmanifold =
false;
2925 has_nonmanifold =
true;
2930 edge_lengths[i] = -1.0;
2937 if (has_nonmanifold ==
false) {
2944 int(*fgroup_index)[2];
2947 int *fgroup_array =
static_cast<int *
>(
2952 int *fgroup_recalc_stack =
static_cast<int *
>(
2953 MEM_mallocN(
sizeof(*fgroup_recalc_stack) * fgroup_len, __func__));
2968 MEM_callocN(
sizeof(*fgroup_listbase) * fgroup_len, __func__));
2972 for (
int i = 0; i < fgroup_len; i++) {
2973 const int fg_sta = fgroup_index[i][0];
2974 const int fg_len = fgroup_index[i][1];
2975 for (
int j = 0; j < fg_len; j++) {
2976 const int face_index = fgroup_array[fg_sta + j];
2980 BMFaceLink *f_link = &f_link_array[face_index];
2992 MEM_mallocN(
sizeof(*fgroup_table) * fgroup_len, __func__));
2993 bool *fgroup_dirty =
static_cast<bool *
>(
2994 MEM_callocN(
sizeof(*fgroup_dirty) * fgroup_len, __func__));
2996 for (
int i = 0; i < fgroup_len; i++) {
3002 fgroup_table[i] =
nullptr;
3014#define USE_DELAY_FACE_GROUP_COST_CALC
3018#if defined(USE_DELAY_FACE_GROUP_COST_CALC)
3022 if (fgroup_dirty[i]) {
3032 fgroup_table[i] =
nullptr;
3034 fgroup_dirty[i] =
false;
3049 fgroup_table[i_min] =
nullptr;
3053 BMFace *f = f_link->face;
3057 BMLoop *l_iter, *l_first;
3073 std::swap(i_a, i_b);
3086 fgroup_table[i_b] =
nullptr;
3091 if (fgroup_dirty[i_a] ==
false) {
3094 fgroup_dirty[i_a] =
true;
3101 if (l_radial_iter != l_iter) {
3104 if (!
ELEM(i_other, -1, i_min)) {
3105 if ((fgroup_table[i_other] !=
nullptr) && (fgroup_dirty[i_other] ==
false)) {
3106#if !defined(USE_DELAY_FACE_GROUP_COST_CALC)
3109 fgroup_dirty[i_other] =
true;
3112 }
while ((l_radial_iter = l_radial_iter->
radial_next) != l_iter);
3115 }
while ((l_iter = l_iter->
next) != l_first);
3118 for (
int index = 0; index <
STACK_SIZE(fgroup_recalc_stack); index++) {
3119 const int i = fgroup_recalc_stack[index];
3120 if (fgroup_table[i] !=
nullptr && fgroup_dirty[i] ==
true) {
3128 fgroup_table[i] =
nullptr;
3131 fgroup_dirty[i] =
false;
3157#define USE_LINKED_SELECT_DEFAULT_HACK
3187 if (
e->l &&
e->l->radial_next !=
e->l) {
3188 const short mat_nr =
e->l->f->mat_nr;
3189 BMLoop *l_iter =
e->l->radial_next;
3191 if (l_iter->
f->
mat_nr != mat_nr) {
3209#ifdef USE_LINKED_SELECT_DEFAULT_HACK
3218 char *delimit_last = &delimit_last_store[delimit_last_index];
3224 *delimit_last = delimit;
3227 delimit = *delimit_last;
3238 (*delimit) &= ~BMO_DELIM_UV;
3250 if (delimit_data.cd_loop_offset == -1) {
3251 delimit &= ~BMO_DELIM_UV;
3282#ifdef USE_LINKED_SELECT_DEFAULT_HACK
3284 scene->toolsettings->selectmode);
3292 for (
Object *obedit : objects) {
3299 int delimit = delimit_init;
3486 ot->
name =
"Select Linked All";
3487 ot->
idname =
"MESH_OT_select_linked";
3488 ot->
description =
"Select all vertices connected to the current selection";
3502 "Delimit selected region");
3503#ifdef USE_LINKED_SELECT_DEFAULT_HACK
3545 BMW_ITER (ele_walk, &walker, eve) {
3582 BMW_ITER (ele_walk, &walker, eed) {
3635 Base *basact =
nullptr;
3656 bool has_edges =
false;
3657 for (
Base *base : bases) {
3658 Object *ob_iter = base->object;
3664 if (has_edges ==
false) {
3669 vc.
mval[0] =
event->mval[0];
3670 vc.
mval[1] =
event->mval[1];
3674 int base_index = -1;
3679 basact = bases[base_index];
3686#ifdef USE_LINKED_SELECT_DEFAULT_HACK
3716 Object *obedit =
nullptr;
3728 if (ele ==
nullptr) {
3735#ifdef USE_LINKED_SELECT_DEFAULT_HACK
3754 ot->
name =
"Select Linked";
3755 ot->
idname =
"MESH_OT_select_linked_pick";
3756 ot->
description =
"(De)select all vertices linked to the edge under the mouse cursor";
3772 "Delimit selected region");
3773#ifdef USE_LINKED_SELECT_DEFAULT_HACK
3778 prop =
RNA_def_int(
ot->
srna,
"object_index", -1, -1, INT_MAX,
"",
"", 0, INT_MAX);
3800 for (
Object *obedit : objects) {
3848 {0,
"LESS",
false,
"Less Than",
""},
3849 {1,
"EQUAL",
false,
"Equal To",
""},
3850 {2,
"GREATER",
false,
"Greater Than",
""},
3851 {3,
"NOTEQUAL",
false,
"Not Equal To",
""},
3852 {0,
nullptr, 0,
nullptr,
nullptr},
3856 ot->
name =
"Select Faces by Sides";
3857 ot->
description =
"Select vertices or faces by the number of face sides";
3858 ot->
idname =
"MESH_OT_select_face_by_sides";
3868 RNA_def_int(
ot->
srna,
"number", 4, 3, INT_MAX,
"Number of Vertices",
"", 3, INT_MAX);
3888 for (
Object *obedit : objects) {
3920 bool is_loose =
true;
3945 ot->
name =
"Select Loose Geometry";
3946 ot->
description =
"Select loose geometry based on the selection mode";
3947 ot->
idname =
"MESH_OT_select_loose";
3975 int tot_mirr = 0, tot_fail = 0;
3980 for (
Object *obedit : objects) {
3987 int tot_mirr_iter = 0, tot_fail_iter = 0;
3989 for (
int axis = 0; axis < 3; axis++) {
3990 if ((1 << axis) & axis_flag) {
3992 static_cast<const Mesh *
>(obedit->data),
4000 if (tot_mirr_iter) {
4007 tot_fail += tot_fail_iter;
4008 tot_mirr += tot_mirr_iter;
4011 if (tot_mirr || tot_fail) {
4020 ot->
name =
"Select Mirror";
4021 ot->
description =
"Select mesh items at mirrored locations";
4022 ot->
idname =
"MESH_OT_select_mirror";
4051 for (
Object *obedit : objects) {
4070 ot->
name =
"Select More";
4071 ot->
idname =
"MESH_OT_select_more";
4072 ot->
description =
"Select more vertices, edges or faces connected to initial selection";
4082 ot->
srna,
"use_face_step",
true,
"Face Step",
"Connected faces (instead of edges)");
4099 for (
Object *obedit : objects) {
4118 ot->
name =
"Select Less";
4119 ot->
idname =
"MESH_OT_select_less";
4120 ot->
description =
"Deselect vertices, edges or faces at the boundary of each selection region";
4130 ot->
srna,
"use_face_step",
true,
"Face Step",
"Connected faces (instead of edges)");
4171 int walktype = 0, itertype = 0, flushtype = 0;
4172 short mask_vert = 0, mask_edge = 0, mask_face = 0;
4175 if (h_act ==
nullptr) {
4181 switch (h_act->
htype) {
4232 for (ele =
static_cast<BMElem *
>(
BMW_begin(&walker, h_act)); ele !=
nullptr;
4335 bool found_active_elt =
false;
4340 for (
Object *obedit : objects) {
4348 found_active_elt =
true;
4350 params.calc_looptris =
false;
4351 params.calc_normals =
false;
4352 params.is_destructive =
false;
4357 if (!found_active_elt) {
4368 ot->
name =
"Checker Deselect";
4370 ot->
description =
"Deselect every Nth element starting from the active vertex, edge or face";
4412 for (
Object *obedit : objects) {
4423 if (angle_cos < angle_limit_cos) {
4448 ot->
name =
"Select Sharp Edges";
4450 ot->
idname =
"MESH_OT_edges_select_sharp";
4487 for (
Object *obedit : objects) {
4497 BMIter iter, liter, liter2;
4528 if (angle_cos > angle_limit_cos) {
4548 ot->
name =
"Select Linked Flat Faces";
4550 ot->
idname =
"MESH_OT_faces_select_linked_flat";
4595 for (
Object *obedit : objects) {
4616 if (use_wire || use_boundary || use_multi_face || use_non_contiguous) {
4644 ot->
name =
"Select Non-Manifold";
4645 ot->
description =
"Select all non-manifold vertices or edges";
4646 ot->
idname =
"MESH_OT_select_non_manifold";
4661 ot->
srna,
"use_multi_face",
true,
"Multiple Faces",
"Edges shared by more than two faces");
4663 "use_non_contiguous",
4666 "Edges between faces pointing in alternate directions");
4669 ot->
srna,
"use_verts",
true,
"Vertices",
"Vertices connecting multiple face regions");
4689 for (
const int ob_index : objects.index_range()) {
4690 Object *obedit = objects[ob_index];
4693 int seed_iter =
seed;
4701 int elem_map_len = 0;
4707 elem_map[elem_map_len++] = eve;
4712 const int count_select = elem_map_len * randfac;
4713 for (
int i = 0; i < count_select; i++) {
4719 int elem_map_len = 0;
4725 elem_map[elem_map_len++] = eed;
4729 const int count_select = elem_map_len * randfac;
4730 for (
int i = 0; i < count_select; i++) {
4736 int elem_map_len = 0;
4742 elem_map[elem_map_len++] = efa;
4746 const int count_select = elem_map_len * randfac;
4747 for (
int i = 0; i < count_select; i++) {
4771 ot->
name =
"Select Random";
4773 ot->
idname =
"MESH_OT_select_random";
4822 for (
Object *obedit : objects) {
4827 if (cd_dvert_offset == -1) {
4834 bool changed =
false;
4847 if (
ELEM(
nullptr, dv, dv->
dw)) {
4866 ot->
name =
"Select Ungrouped";
4867 ot->
idname =
"MESH_OT_select_ungrouped";
4903 if (v_act ==
nullptr) {
4905 op->
reports,
RPT_WARNING,
"This operator requires an active vertex (last selected)");
4912 float axis_mat[3][3];
4925 const float *axis_vector = axis_mat[axis];
4928 float vertex_world[3];
4929 mul_v3_m4v3(vertex_world, obedit->object_to_world().ptr(), v_act->
co);
4930 value =
dot_v3v3(axis_vector, vertex_world);
4942 for (
Object *obedit_iter : objects) {
4952 bool changed =
false;
4956 float v_iter_world[3];
4957 mul_v3_m4v3(v_iter_world, obedit_iter->object_to_world().ptr(),
v->
co);
4958 const float value_iter =
dot_v3v3(axis_vector, v_iter_world);
4961 if (
fabsf(value_iter - value) < limit) {
4967 if (value_iter < value) {
4973 if (value_iter > value) {
4996 {0,
nullptr, 0,
nullptr,
nullptr},
5000 ot->
name =
"Select Axis";
5001 ot->
description =
"Select all data in the mesh on a single axis";
5002 ot->
idname =
"MESH_OT_select_axis";
5017 "Axis orientation");
5024 "Select the axis to compare each vertex on");
5026 ot->
srna,
"threshold", 0.0001f, 0.000001f, 50.0f,
"Threshold",
"", 0.00001f, 10.0f);
5041 for (
Object *obedit : objects) {
5058 int tot = 0, totsel = 0;
5065 if ((tot != totsel && totsel > 0) || (totsel == 1 && tot == 1)) {
5097 ot->
name =
"Select Boundary Loop";
5098 ot->
idname =
"MESH_OT_region_to_loop";
5099 ot->
description =
"Select boundary edges around the selected faces";
5151 memcpy(region_alloc, region.data(), region.as_span().size_in_bytes());
5152 *region_out = region_alloc;
5153 return region.size();
5181 GSet *visit_face_set;
5202 qsort(edges, edges_len,
sizeof(*edges),
verg_radial);
5204 for (i = 0; i < edges_len; i++) {
5207 BMFace **region =
nullptr, **region_out;
5223 if (!region || (selbigger ? c >= tot : c < tot)) {
5231 region = region_out;
5242 for (j = 0; j < tot; j++) {
5269 for (
Object *obedit : objects) {
5307 ot->
name =
"Select Loop Inner-Region";
5308 ot->
idname =
"MESH_OT_loop_to_region";
5309 ot->
description =
"Select region of faces inside of a selected loop of edges";
5322 "Select bigger regions instead of smaller ones");
5332 const Mesh *mesh =
static_cast<const Mesh *
>(obedit->
data);
5345 C,
"The active attribute must be on the vertex, edge, or face domain");
5355 case bke::AttrDomain::Point:
5357 case bke::AttrDomain::Edge:
5359 case bke::AttrDomain::Face:
5362 return std::nullopt;
5373 for (
Object *obedit : objects) {
5374 Mesh *mesh =
static_cast<Mesh *
>(obedit->data);
5394 bool changed =
false;
5420 ot->
name =
"Select by Attribute";
5421 ot->
idname =
"MESH_OT_select_by_attribute";
5422 ot->
description =
"Select elements based on the active boolean attribute";
blender::bke::AttrDomain BKE_attribute_domain(const AttributeOwner &owner, const struct CustomDataLayer *layer)
struct CustomDataLayer * BKE_attributes_active_get(AttributeOwner &owner)
SpaceImage * CTX_wm_space_image(const bContext *C)
void CTX_wm_operator_poll_msg_set(bContext *C, const char *msg)
Depsgraph * CTX_data_ensure_evaluated_depsgraph(const bContext *C)
Scene * CTX_data_scene(const bContext *C)
Object * CTX_data_edit_object(const bContext *C)
ToolSettings * CTX_data_tool_settings(const bContext *C)
RegionView3D * CTX_wm_region_view3d(const bContext *C)
View3D * CTX_wm_view3d(const bContext *C)
ViewLayer * CTX_data_view_layer(const bContext *C)
CustomData interface, see also DNA_customdata_types.h.
int CustomData_get_offset(const CustomData *data, eCustomDataType type)
bool CustomData_has_layer(const CustomData *data, eCustomDataType type)
BMEditMesh * BKE_editmesh_from_object(Object *ob)
Return the BMEditMesh for a given object.
void BKE_view_layer_synced_ensure(const Scene *scene, ViewLayer *view_layer)
blender::Vector< Base * > BKE_view_layer_array_from_bases_in_edit_mode(const Scene *scene, ViewLayer *view_layer, const View3D *v3d)
Base * BKE_view_layer_active_base_get(ViewLayer *view_layer)
blender::Vector< Object * > BKE_view_layer_array_from_objects_in_edit_mode(const Scene *scene, ViewLayer *view_layer, const View3D *v3d)
Base * BKE_view_layer_base_find(ViewLayer *view_layer, Object *ob)
blender::Vector< Base * > BKE_view_layer_array_from_bases_in_edit_mode_unique_data(const Scene *scene, ViewLayer *view_layer, const View3D *v3d)
blender::Vector< Object * > BKE_view_layer_array_from_objects_in_edit_mode_unique_data(const Scene *scene, ViewLayer *view_layer, const View3D *v3d)
blender::Span< blender::float3 > BKE_mesh_wrapper_vert_coords(const Mesh *mesh)
int BKE_mesh_wrapper_vert_len(const Mesh *mesh)
General operations, lookup, etc. for blender objects.
const Mesh * BKE_object_get_editmesh_eval_cage(const Object *object)
void BKE_report(ReportList *reports, eReportType type, const char *message)
#define BLI_assert_unreachable()
bool BLI_gset_haskey(const GSet *gs, const void *key) ATTR_WARN_UNUSED_RESULT
unsigned int BLI_ghashutil_strhash_p(const void *ptr)
void BLI_gset_insert(GSet *gs, void *key)
void BLI_gset_free(GSet *gs, GSetKeyFreeFP keyfreefp)
GSet * BLI_gset_ptr_new_ex(const char *info, unsigned int nentries_reserve) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT
bool BLI_gset_add(GSet *gs, void *key)
A min-heap / priority queue ADT.
HeapNode * BLI_heap_top(const Heap *heap) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
void BLI_heap_free(Heap *heap, HeapFreeFP ptrfreefp) ATTR_NONNULL(1)
void void float BLI_heap_node_value(const HeapNode *heap) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
Heap * BLI_heap_new_ex(unsigned int reserve_num) ATTR_WARN_UNUSED_RESULT
void void bool BLI_heap_is_empty(const Heap *heap) ATTR_NONNULL(1)
void BLI_heap_node_value_update(Heap *heap, HeapNode *node, float value) ATTR_NONNULL(1
void * BLI_heap_pop_min(Heap *heap) ATTR_NONNULL(1)
void * BLI_heap_node_ptr(const HeapNode *heap) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
HeapNode * BLI_heap_insert(Heap *heap, float value, void *ptr) ATTR_NONNULL(1)
void void BLI_heap_remove(Heap *heap, HeapNode *node) ATTR_NONNULL(1
BLI_INLINE bool BLI_listbase_is_empty(const struct ListBase *lb)
#define LISTBASE_FOREACH(type, var, list)
void BLI_freelinkN(struct ListBase *listbase, void *vlink) ATTR_NONNULL(1)
void void void BLI_movelisttolist(struct ListBase *dst, struct ListBase *src) ATTR_NONNULL(1
void BLI_addtail(struct ListBase *listbase, void *vlink) ATTR_NONNULL(1)
void * BLI_pophead(ListBase *listbase) ATTR_NONNULL(1)
MINLINE float min_ff(float a, float b)
MINLINE unsigned short highest_order_bit_s(unsigned short n)
float line_point_factor_v2(const float p[2], const float l1[2], const float l2[2])
float dist_squared_ray_to_seg_v3(const float ray_origin[3], const float ray_direction[3], const float v0[3], const float v1[3], float r_point[3], float *r_depth)
float dist_squared_to_ray_v3_normalized(const float ray_origin[3], const float ray_direction[3], const float co[3])
void copy_m3_m4(float m1[3][3], const float m2[4][4])
void mul_m4_v3(const float M[4][4], float r[3])
void mul_v3_m4v3(float r[3], const float mat[4][4], const float vec[3])
bool invert_m3(float mat[3][3])
MINLINE float len_squared_v2v2(const float a[2], const float b[2]) ATTR_WARN_UNUSED_RESULT
void interp_v2_v2v2(float r[2], const float a[2], const float b[2], float t)
MINLINE void copy_v2_v2(float r[2], const float a[2])
MINLINE float dot_v3v3(const float a[3], const float b[3]) ATTR_WARN_UNUSED_RESULT
void interp_v3_v3v3(float r[3], const float a[3], const float b[3], float t)
void mid_v2_v2v2(float r[2], const float a[2], const float b[2])
MINLINE float len_manhattan_v2v2(const float a[2], const float b[2]) ATTR_WARN_UNUSED_RESULT
void mid_v3_v3v3(float r[3], const float a[3], const float b[3])
float angle_normalized_v3v3(const float v1[3], const float v2[3]) ATTR_WARN_UNUSED_RESULT
void BLI_array_randomize(void *data, unsigned int elem_size, unsigned int elem_num, unsigned int seed)
#define POINTER_FROM_INT(i)
#define POINTER_AS_INT(i)
#define STACK_CLEAR(stack)
#define STACK_PUSH(stack, val)
#define STACK_DECLARE(stack)
#define STACK_SIZE(stack)
#define STACK_INIT(stack, stack_num)
void DEG_id_tag_update(ID *id, unsigned int flags)
Object * DEG_get_evaluated_object(const Depsgraph *depsgraph, Object *object)
Object is a sort of wrapper for general info.
#define RV3D_CLIPPING_ENABLED(v3d, rv3d)
void DRW_select_buffer_context_create(Depsgraph *depsgraph, blender::Span< Base * > bases, short select_mode)
uint DRW_select_buffer_sample_point(Depsgraph *depsgraph, ARegion *region, View3D *v3d, const int center[2])
bool DRW_select_buffer_elem_get(uint sel_id, uint *r_elem, uint *r_base_index, char *r_elem_type)
uint DRW_select_buffer_find_nearest_to_point(Depsgraph *depsgraph, ARegion *region, View3D *v3d, const int center[2], uint id_min, uint id_max, uint *dist)
void EDBM_flag_disable_all(BMEditMesh *em, char hflag)
void ED_mesh_report_mirror_ex(wmOperator *op, int totmirr, int totfail, char selectmode)
void EDBM_update(Mesh *mesh, const EDBMUpdate_Params *params)
BMVert * EDBM_verts_mirror_get(BMEditMesh *em, BMVert *v)
void EDBM_select_more(BMEditMesh *em, bool use_face_step)
void EDBM_verts_mirror_cache_begin(BMEditMesh *em, int axis, bool use_self, bool use_select, bool respecthide, bool use_topology)
void EDBM_deselect_flush(BMEditMesh *em)
void EDBM_selectmode_flush(BMEditMesh *em)
void EDBM_selectmode_flush_ex(BMEditMesh *em, short selectmode)
void EDBM_verts_mirror_cache_end(BMEditMesh *em)
BMEdge * EDBM_verts_mirror_get_edge(BMEditMesh *em, BMEdge *e)
BMFace * EDBM_verts_mirror_get_face(BMEditMesh *em, BMFace *f)
void EDBM_flag_enable_all(BMEditMesh *em, char hflag)
void EDBM_select_less(BMEditMesh *em, bool use_face_step)
void EDBM_select_flush(BMEditMesh *em)
void EDBM_selectmode_to_scene(bContext *C)
bool ED_operator_editmesh_region_view3d(bContext *C)
bool ED_operator_editmesh(bContext *C)
bool ED_view3d_win_to_ray_clipped(Depsgraph *depsgraph, const ARegion *region, const View3D *v3d, const float mval[2], float r_ray_start[3], float r_ray_normal[3], bool do_clip_planes)
float ED_view3d_select_dist_px()
#define V3D_PROJ_TEST_CLIP_CONTENT_DEFAULT
void mesh_foreachScreenVert(const ViewContext *vc, void(*func)(void *user_data, BMVert *eve, const float screen_co[2], int index), void *user_data, eV3DProjTest clip_flag)
@ V3D_PROJ_TEST_CLIP_NEAR
eV3DProjStatus ED_view3d_project_float_object(const ARegion *region, const float co[3], float r_co[2], eV3DProjTest flag)
void ED_view3d_init_mats_rv3d(const Object *ob, RegionView3D *rv3d)
void mesh_foreachScreenEdge(const ViewContext *vc, void(*func)(void *user_data, BMEdge *eed, const float screen_co_a[2], const float screen_co_b[2], int index), void *user_data, eV3DProjTest clip_flag)
ViewContext ED_view3d_viewcontext_init(bContext *C, Depsgraph *depsgraph)
int ED_view3d_backbuf_sample_size_clamp(ARegion *region, float dist)
void view3d_operator_needs_opengl(const bContext *C)
void mesh_foreachScreenFace(const ViewContext *vc, void(*func)(void *user_data, BMFace *efa, const float screen_co[2], int index), void *user_data, eV3DProjTest clip_flag)
#define V3D_PROJ_TEST_CLIP_DEFAULT
#define XRAY_FLAG_ENABLED(v3d)
bool ED_view3d_clipping_test(const RegionView3D *rv3d, const float co[3], bool is_local)
void ED_view3d_viewcontext_init_object(ViewContext *vc, Object *obact)
static double angle(const Eigen::Vector3d &v1, const Eigen::Vector3d &v2)
Read Guarded memory(de)allocation.
#define BM_ELEM_CD_GET_BOOL(ele, offset)
#define BM_FACE_FIRST_LOOP(p)
#define BM_ELEM_CD_GET_VOID_P(ele, offset)
#define BM_elem_index_get(ele)
#define BM_elem_flag_disable(ele, hflag)
#define BM_elem_flag_set(ele, hflag, val)
#define BM_elem_index_set(ele, index)
#define BM_elem_flag_test(ele, hflag)
#define BM_elem_flag_enable(ele, hflag)
#define BM_ITER_ELEM(ele, iter, data, itype)
#define BM_ITER_MESH(ele, iter, bm, itype)
#define BM_ITER_MESH_INDEX(ele, iter, bm, itype, indexvar)
ATTR_WARN_UNUSED_RESULT BMesh * bm
BMVert * BM_mesh_active_vert_get(BMesh *bm)
void BM_face_select_set(BMesh *bm, BMFace *f, const bool select)
Select Face.
void BM_elem_select_set(BMesh *bm, BMElem *ele, const bool select)
BMFace * BM_mesh_active_face_get(BMesh *bm, const bool is_sloppy, const bool is_selected)
BMElem * BM_mesh_active_elem_get(BMesh *bm)
void BM_vert_select_set(BMesh *bm, BMVert *v, const bool select)
Select Vert.
void BM_edge_select_set(BMesh *bm, BMEdge *e, const bool select)
Select Edge.
void BM_mesh_deselect_flush(BMesh *bm)
void BM_mesh_elem_hflag_disable_all(BMesh *bm, const char htype, const char hflag, const bool respecthide)
void BM_mesh_active_face_set(BMesh *bm, BMFace *f)
#define BM_select_history_store(bm, ele)
#define BM_select_history_remove(bm, ele)
void BM_mesh_elem_toolflags_clear(BMesh *bm)
void BM_mesh_elem_toolflags_ensure(BMesh *bm)
BMVert * BM_vert_at_index_find_or_table(BMesh *bm, const int index)
void BM_mesh_elem_table_ensure(BMesh *bm, const char htype)
void BM_mesh_elem_index_ensure(BMesh *bm, const char htype)
BMEdge * BM_edge_at_index_find_or_table(BMesh *bm, const int index)
BMFace * BM_face_at_index_find_or_table(BMesh *bm, const int index)
BLI_INLINE BMFace * BM_face_at_index(BMesh *bm, const int index)
#define BMO_edge_flag_test(bm, e, oflag)
void BMO_pop(BMesh *bm)
BMESH OPSTACK POP.
#define BMO_edge_flag_set(bm, e, oflag, val)
void BMO_push(BMesh *bm, BMOperator *op)
BMESH OPSTACK PUSH.
#define BMO_elem_flag_enable(bm, ele, oflag)
void BM_face_calc_center_median_vcos(const BMesh *bm, const BMFace *f, float r_cent[3], const blender::Span< blender::float3 > vert_positions)
float BM_face_calc_area(const BMFace *f)
void BM_face_calc_center_median(const BMFace *f, float r_cent[3])
bool BM_edge_is_contiguous_loop_cd(const BMEdge *e, const int cd_loop_type, const int cd_loop_offset)
bool BM_edge_is_all_face_flag_test(const BMEdge *e, const char hflag, const bool respect_hide)
int BM_mesh_calc_face_groups(BMesh *bm, int *r_groups_array, int(**r_group_index)[2], BMLoopFilterFunc filter_fn, BMLoopPairFilterFunc filter_pair_fn, void *user_data, const char hflag_test, const char htype_step)
bool BM_face_is_any_edge_flag_test(const BMFace *f, const char hflag)
bool BM_face_is_any_vert_flag_test(const BMFace *f, const char hflag)
bool BM_edge_loop_pair(BMEdge *e, BMLoop **r_la, BMLoop **r_lb)
bool BM_vert_is_all_edge_flag_test(const BMVert *v, const char hflag, const bool respect_hide)
bool BM_vert_is_manifold(const BMVert *v)
int BM_edge_face_count(const BMEdge *e)
bool BM_edge_is_any_vert_flag_test(const BMEdge *e, const char hflag)
float BM_edge_calc_length(const BMEdge *e)
bool BM_vert_is_all_face_flag_test(const BMVert *v, const char hflag, const bool respect_hide)
bool BM_edge_is_any_face_flag_test(const BMEdge *e, const char hflag)
BLI_INLINE bool BM_edge_is_contiguous(const BMEdge *e) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL()
BLI_INLINE bool BM_edge_is_manifold(const BMEdge *e) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL()
BLI_INLINE bool BM_edge_is_boundary(const BMEdge *e) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL()
#define BM_edge_face_count_is_over(e, n)
BLI_INLINE bool BM_edge_is_wire(const BMEdge *e) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL()
ATTR_WARN_UNUSED_RESULT const BMLoop * l
ATTR_WARN_UNUSED_RESULT const BMVert const BMEdge * e
ATTR_WARN_UNUSED_RESULT const BMVert * v
int BM_mesh_region_match(BMesh *bm, BMFace **faces_region, uint faces_region_len, ListBase *r_face_regions)
void * BMW_begin(BMWalker *walker, void *start)
void BMW_init(BMWalker *walker, BMesh *bm, int type, short mask_vert, short mask_edge, short mask_face, BMWFlag flag, int layer)
Init Walker.
void BMW_end(BMWalker *walker)
End Walker.
void * BMW_step(BMWalker *walker)
Step Walker.
int BMW_current_depth(BMWalker *walker)
Walker Current Depth.
@ BMW_EDGELOOP_NONMANIFOLD
#define BMW_ITER(ele, walker, data)
static unsigned long seed
static AttributeOwner from_id(ID *id)
constexpr int64_t size() const
constexpr IndexRange index_range() const
constexpr bool is_empty() const
void append(const T &value)
local_group_size(16, 16) .push_constant(Type b
const Depsgraph * depsgraph
static int edbm_select_all_exec(bContext *C, wmOperator *op)
static void walker_select_count(BMEditMesh *em, int walkercode, void *start, int r_count_by_select[2])
BMVert * EDBM_vert_find_nearest_ex(ViewContext *vc, float *dist_px_manhattan_p, const bool use_select_bias, bool use_cycle, const Span< Base * > bases, uint *r_base_index)
void MESH_OT_select_less(wmOperatorType *ot)
bool EDBM_unified_findnearest_from_raycast(ViewContext *vc, const Span< Base * > bases, bool use_boundary_vertices, bool use_boundary_edges, int *r_base_index_vert, int *r_base_index_edge, int *r_base_index_face, BMVert **r_eve, BMEdge **r_eed, BMFace **r_efa)
static int edbm_select_random_exec(bContext *C, wmOperator *op)
static void findnearestface__doClosest(void *user_data, BMFace *efa, const float screen_co[2], int index)
static void walker_deselect_nth(BMEditMesh *em, const CheckerIntervalParams *op_params, BMHeader *h_act)
static void find_nearest_edge__doClosest(void *user_data, BMEdge *eed, const float screen_co_a[2], const float screen_co_b[2], int index)
static float bm_interior_face_group_calc_cost(ListBase *ls, const float *edge_lengths)
BMEdge * EDBM_edge_find_nearest(ViewContext *vc, float *dist_px_manhattan_p)
static int edbm_select_linked_flat_faces_exec(bContext *C, wmOperator *op)
BMVert * EDBM_vert_find_nearest(ViewContext *vc, float *dist_px_manhattan_p)
void MESH_OT_loop_to_region(wmOperatorType *ot)
void MESH_OT_select_mode(wmOperatorType *ot)
void EDBM_select_toggle_all(BMEditMesh *em)
static int edbm_select_linked_pick_invoke(bContext *C, wmOperator *op, const wmEvent *event)
static bool edbm_deselect_nth(BMEditMesh *em, const CheckerIntervalParams *op_params)
static void select_linked_delimit_end(BMEditMesh *em)
void MESH_OT_select_similar_region(wmOperatorType *ot)
static void find_nearest_face_center__doZBuf(void *user_data, BMFace *efa, const float screen_co[2], int)
#define FIND_NEAR_SELECT_BIAS
static int edbm_select_mode_exec(bContext *C, wmOperator *op)
static bool unified_findnearest(ViewContext *vc, const Span< Base * > bases, int *r_base_index, BMVert **r_eve, BMEdge **r_eed, BMFace **r_efa)
BMEdge * EDBM_edge_find_nearest_ex(ViewContext *vc, float *dist_px_manhattan_p, float *r_dist_center_px_manhattan, const bool use_select_bias, bool use_cycle, BMEdge **r_eed_zbuf, const Span< Base * > bases, uint *r_base_index)
static int edbm_select_linked_pick_exec(bContext *C, wmOperator *op)
BMFace * EDBM_face_find_nearest_ex(ViewContext *vc, float *dist_px_manhattan_p, float *r_dist_center, const bool use_zbuf_single_px, const bool use_select_bias, bool use_cycle, BMFace **r_efa_zbuf, const Span< Base * > bases, uint *r_base_index)
void MESH_OT_select_linked_pick(wmOperatorType *ot)
static int edbm_select_ungrouped_exec(bContext *C, wmOperator *op)
static bool edbm_select_by_attribute_poll(bContext *C)
static int edbm_select_more_exec(bContext *C, wmOperator *op)
static int loop_find_region(BMLoop *l, int flag, GSet *visit_face_set, BMFace ***region_out)
void EDBM_select_swap(BMEditMesh *em)
static int edbm_loop_to_region_exec(bContext *C, wmOperator *op)
static void mouse_mesh_loop_edge_ring(BMEditMesh *em, BMEdge *eed, bool select, bool select_clear)
static void mouse_mesh_loop_face(BMEditMesh *em, BMEdge *eed, bool select, bool select_clear)
BMFace * EDBM_face_find_nearest(ViewContext *vc, float *dist_px_manhattan_p)
void EDBM_selectmode_set(BMEditMesh *em)
static bool mouse_mesh_loop(bContext *C, const int mval[2], bool extend, bool deselect, bool toggle, bool ring)
static BMElem * edbm_select_id_bm_elem_get(const Span< Base * > bases, const uint sel_id, uint *r_base_index)
void MESH_OT_select_random(wmOperatorType *ot)
static int verg_radial(const void *va, const void *vb)
static void find_nearest_edge_center__doZBuf(void *user_data, BMEdge *eed, const float screen_co_a[2], const float screen_co_b[2], int)
static int loop_find_regions(BMEditMesh *em, const bool selbigger)
void EDBM_select_mirrored(BMEditMesh *em, const Mesh *mesh, const int axis, const bool extend, int *r_totmirr, int *r_totfail)
void MESH_OT_select_nth(wmOperatorType *ot)
static int edbm_select_mirror_exec(bContext *C, wmOperator *op)
static int edbm_select_loose_exec(bContext *C, wmOperator *op)
void MESH_OT_loop_multi_select(wmOperatorType *ot)
ViewContext em_setup_viewcontext(bContext *C)
static int edbm_select_loop_invoke(bContext *C, wmOperator *op, const wmEvent *event)
void EDBM_selectmode_convert(BMEditMesh *em, const short selectmode_old, const short selectmode_new)
static int edbm_select_by_attribute_exec(bContext *C, wmOperator *)
static bool bm_interior_loop_filter_fn(const BMLoop *l, void *)
static void select_linked_delimit_validate(BMesh *bm, int *delimit)
static int edbm_select_less_exec(bContext *C, wmOperator *op)
bool EDBM_selectmode_toggle_multi(bContext *C, const short selectmode_new, const int action, const bool use_extend, const bool use_expand)
static int edbm_select_face_by_sides_exec(bContext *C, wmOperator *op)
bool EDBM_unified_findnearest(ViewContext *vc, const Span< Base * > bases, int *r_base_index, BMVert **r_eve, BMEdge **r_eed, BMFace **r_efa)
static int edbm_select_axis_exec(bContext *C, wmOperator *op)
static bool edbm_selectmode_sync_multi_ex(Span< Object * > objects)
void MESH_OT_select_loose(wmOperatorType *ot)
static bool select_linked_delimit_test(BMEdge *e, int delimit, const DelimitData *delimit_data)
bool EDBM_deselect_by_material(BMEditMesh *em, const short index, const bool select)
void MESH_OT_select_by_attribute(wmOperatorType *ot)
static bool edbm_vert_or_edge_select_mode_poll(bContext *C)
void MESH_OT_edgering_select(wmOperatorType *ot)
static bool edbm_select_ungrouped_poll(bContext *C)
static void edbm_select_linked_pick_ex(BMEditMesh *em, BMElem *ele, bool sel, int delimit)
void MESH_OT_select_face_by_sides(wmOperatorType *ot)
void MESH_OT_select_axis(wmOperatorType *ot)
static void walker_select(BMEditMesh *em, int walkercode, void *start, const bool select)
void MESH_OT_select_mirror(wmOperatorType *ot)
static int edbm_region_to_loop_exec(bContext *C, wmOperator *)
static void deselect_nth_active(BMEditMesh *em, BMVert **r_eve, BMEdge **r_eed, BMFace **r_efa)
void MESH_OT_faces_select_linked_flat(wmOperatorType *ot)
void MESH_OT_edges_select_sharp(wmOperatorType *ot)
static void mouse_mesh_loop_edge(BMEditMesh *em, BMEdge *eed, bool select, bool select_clear, bool select_cycle)
static int select_linked_delimit_default_from_op(wmOperator *op, const int select_mode)
bool EDBM_selectmode_disable_multi_ex(Scene *scene, const Span< Base * > bases, const short selectmode_disable, const short selectmode_fallback)
static int edbm_loop_multiselect_exec(bContext *C, wmOperator *op)
bool EDBM_mesh_deselect_all_multi(bContext *C)
static int edbm_select_non_manifold_exec(bContext *C, wmOperator *op)
static int edbm_select_similar_region_exec(bContext *C, wmOperator *op)
static bool bm_edge_is_select_isolated(BMEdge *e)
void MESH_OT_select_interior_faces(wmOperatorType *ot)
bool EDBM_selectmode_disable_multi(bContext *C, const short selectmode_disable, const short selectmode_fallback)
void MESH_OT_select_linked(wmOperatorType *ot)
static void select_linked_delimit_begin(BMesh *bm, int delimit)
static int edbm_select_mode_invoke(bContext *C, wmOperator *op, const wmEvent *event)
static bool bm_interior_edge_is_manifold_except_face_index(BMEdge *e, int face_index, BMLoop *r_l_pair[2])
static int edbm_select_linked_exec(bContext *C, wmOperator *op)
bool EDBM_select_pick(bContext *C, const int mval[2], const SelectPick_Params *params)
static void findnearestvert__doClosest(void *user_data, BMVert *eve, const float screen_co[2], int index)
void MESH_OT_select_all(wmOperatorType *ot)
void MESH_OT_select_more(wmOperatorType *ot)
static int edbm_select_sharp_edges_exec(bContext *C, wmOperator *op)
#define FIND_NEAR_CYCLE_THRESHOLD_MIN
static std::string edbm_select_mode_get_description(bContext *, wmOperatorType *, PointerRNA *ptr)
bool EDBM_select_interior_faces(BMEditMesh *em)
void MESH_OT_region_to_loop(wmOperatorType *ot)
static void edbm_strip_selections(BMEditMesh *em)
void MESH_OT_loop_select(wmOperatorType *ot)
static int edbm_select_nth_exec(bContext *C, wmOperator *op)
bool EDBM_selectmode_set_multi(bContext *C, const short selectmode)
static int edbm_faces_select_interior_exec(bContext *C, wmOperator *)
void MESH_OT_select_ungrouped(wmOperatorType *ot)
static std::optional< BMIterType > domain_to_iter_type(const blender::bke::AttrDomain domain)
bool EDBM_selectmode_disable(Scene *scene, BMEditMesh *em, const short selectmode_disable, const short selectmode_fallback)
bool EDBM_mesh_deselect_all_multi_ex(const Span< Base * > bases)
void MESH_OT_select_non_manifold(wmOperatorType *ot)
BMElem * EDBM_elem_from_selectmode(BMEditMesh *em, BMVert *eve, BMEdge *eed, BMFace *efa)
BMElem * EDBM_elem_from_index_any_multi(const Scene *scene, ViewLayer *view_layer, uint object_index, uint elem_index, Object **r_obedit)
int EDBM_elem_to_index_any_multi(const Scene *scene, ViewLayer *view_layer, BMEditMesh *em, BMElem *ele, int *r_object_index)
draw_view in_light_buf[] float
draw_view push_constant(Type::INT, "radiance_src") .push_constant(Type capture_info_buf storage_buf(1, Qualifier::READ, "ObjectBounds", "bounds_buf[]") .push_constant(Type draw_view int
void *(* MEM_mallocN)(size_t len, const char *str)
void *(* MEM_malloc_arrayN)(size_t len, size_t size, const char *str)
void MEM_freeN(void *vmemh)
void *(* MEM_callocN)(size_t len, const char *str)
ccl_device_inline float4 select(const int4 mask, const float4 a, const float4 b)
void base_activate(bContext *C, Base *base)
PropertyRNA * RNA_struct_find_property(PointerRNA *ptr, const char *identifier)
void RNA_boolean_set(PointerRNA *ptr, const char *name, bool value)
bool RNA_property_is_set(PointerRNA *ptr, PropertyRNA *prop)
void RNA_int_set(PointerRNA *ptr, const char *name, int value)
void RNA_property_enum_set(PointerRNA *ptr, PropertyRNA *prop, int value)
int RNA_int_get(PointerRNA *ptr, const char *name)
float RNA_float_get(PointerRNA *ptr, const char *name)
int RNA_property_enum_get(PointerRNA *ptr, PropertyRNA *prop)
bool RNA_struct_property_is_set(PointerRNA *ptr, const char *identifier)
bool RNA_boolean_get(PointerRNA *ptr, const char *name)
int RNA_enum_get(PointerRNA *ptr, const char *name)
void RNA_def_property_float_default(PropertyRNA *prop, float value)
PropertyRNA * RNA_def_float_rotation(StructOrFunctionRNA *cont_, const char *identifier, const int len, const float *default_value, const float hardmin, const float hardmax, const char *ui_name, const char *ui_description, const float softmin, const float softmax)
PropertyRNA * RNA_def_float(StructOrFunctionRNA *cont_, const char *identifier, const float default_value, const float hardmin, const float hardmax, const char *ui_name, const char *ui_description, const float softmin, const float softmax)
PropertyRNA * RNA_def_enum(StructOrFunctionRNA *cont_, const char *identifier, const EnumPropertyItem *items, const int default_value, const char *ui_name, const char *ui_description)
PropertyRNA * RNA_def_enum_flag(StructOrFunctionRNA *cont_, const char *identifier, const EnumPropertyItem *items, const int default_value, const char *ui_name, const char *ui_description)
PropertyRNA * RNA_def_boolean(StructOrFunctionRNA *cont_, const char *identifier, const bool default_value, const char *ui_name, const char *ui_description)
void RNA_def_property_flag(PropertyRNA *prop, PropertyFlag flag)
PropertyRNA * RNA_def_int(StructOrFunctionRNA *cont_, const char *identifier, const int default_value, const int hardmin, const int hardmax, const char *ui_name, const char *ui_description, const int softmin, const int softmax)
const EnumPropertyItem rna_enum_mesh_delimit_mode_items[]
const EnumPropertyItem rna_enum_axis_flag_xyz_items[]
const EnumPropertyItem rna_enum_axis_xyz_items[]
const EnumPropertyItem rna_enum_mesh_select_mode_items[]
const EnumPropertyItem rna_enum_transform_orientation_items[]
struct BMEditSelection * next
struct BMLoop * radial_next
eCustomDataType cd_loop_type
float dist_center_px_manhattan
NearestEdgeUserData_Hit hit
NearestEdgeUserData_Hit hit_cycle
NearestFaceUserData_Hit hit
NearestFaceUserData_Hit hit_cycle
NearestVertUserData_Hit hit_cycle
NearestVertUserData_Hit hit
struct ToolSettings * toolsettings
bool(* poll)(bContext *C) ATTR_WARN_UNUSED_RESULT
std::string(* get_description)(bContext *C, wmOperatorType *ot, PointerRNA *ptr)
int(* invoke)(bContext *C, wmOperator *op, const wmEvent *event) ATTR_WARN_UNUSED_RESULT
int(* exec)(bContext *C, wmOperator *op) ATTR_WARN_UNUSED_RESULT
struct ReportList * reports
bool WM_cursor_test_motion_and_update(const int mval[2])
void WM_main_add_notifier(uint type, void *reference)
void WM_event_add_notifier(const bContext *C, uint type, void *reference)
void WM_operator_properties_checker_interval_from_op(wmOperator *op, CheckerIntervalParams *op_params)
int WM_operator_properties_select_random_seed_increment_get(wmOperator *op)
void WM_operator_properties_select_random(wmOperatorType *ot)
void WM_operator_properties_select_all(wmOperatorType *ot)
void WM_operator_properties_checker_interval(wmOperatorType *ot, bool nth_can_disable)
bool WM_operator_properties_checker_interval_test(const CheckerIntervalParams *op_params, int depth)