42 const bool flush_selection,
43 const bool flush_hidden)
47 const int *index_array =
nullptr;
51 if (mesh ==
nullptr) {
59 if (flush_selection) {
66 if (ob_eval ==
nullptr) {
77 if (me_orig !=
nullptr && mesh_eval !=
nullptr && me_orig->
faces_num == mesh->
faces_num) {
86 hide_poly_orig.finish();
88 if (flush_selection) {
95 select_poly_orig.finish();
107 const int orig_face_index = index_array[
i];
109 hide_poly_eval.span[
i] = hide_poly_orig[orig_face_index];
114 if (flush_selection) {
121 const int orig_face_index = index_array[
i];
123 select_poly_eval.span[
i] = select_poly_orig[orig_face_index];
126 select_poly_eval.
finish();
154 if (mesh ==
nullptr || mesh->
faces_num == 0) {
165 if (!hide_poly.
span[
i]) {
166 if (!select_poly.span[
i] == unselected) {
167 hide_poly.
span[
i] =
true;
171 if (hide_poly.
span[
i]) {
172 select_poly.span[
i] =
false;
177 select_poly.finish();
188 if (mesh ==
nullptr || mesh->
faces_num == 0) {
201 select_poly.span[
i] =
true;
207 attributes.
remove(
".hide_poly");
222 const bool skip_seams =
true)
226 const Span<int> corner_edges = mesh.corner_edges();
237 for (const int face_index : range) {
238 if (hide_poly[face_index]) {
241 const Span<int> face_edges = corner_edges.slice(faces[face_index]);
243 for (const int poly_loop_index : face_edges.index_range()) {
244 const int outer_edge = face_edges[poly_loop_index];
245 if (skip_seams && uv_seams[outer_edge]) {
249 for (const int inner_edge :
250 face_edges.slice(poly_loop_index, face_edges.size() - poly_loop_index))
252 if (outer_edge == inner_edge) {
255 if (skip_seams && uv_seams[inner_edge]) {
258 islands.join(inner_edge, outer_edge);
276 const Span<int> corner_edges = mesh.corner_edges();
285 for (
const int i : face_indices) {
286 for (
const int edge : corner_edges.
slice(
faces[
i])) {
287 if (uv_seams[edge]) {
290 const int root = islands.
find_root(edge);
291 selected_roots.add(root);
296 for (const int face_index : range) {
297 for (const int edge : corner_edges.slice(faces[face_index])) {
298 const int root = islands.find_root(edge);
299 if (selected_roots.contains(root)) {
300 select_poly.span[face_index] = select;
307 select_poly.finish();
314 if (mesh ==
nullptr || mesh->
faces_num == 0) {
331 select_poly.
span[index] =
true;
336 for (
const int i : select_poly.
span.index_range()) {
337 if (!select_poly.
span[
i]) {
352 const int current_edge_index)
354 const int index_in_poly = corner_edges.
slice(face).
first_index(current_edge_index);
356 if (index_in_poly >= 2) {
357 return corner_edges[face[index_in_poly - 2]];
360 return corner_edges[face[index_in_poly + 2]];
368 const int edge_start_index,
376 int current_face_index = face_start_index;
377 int current_edge_index = edge_start_index;
379 while (current_edge_index > 0) {
380 int next_face_index = -1;
382 for (
const int face_index : edge_to_face_map[current_edge_index]) {
383 if (face_index != current_face_index) {
384 next_face_index = face_index;
390 if (next_face_index == -1) {
395 if (
faces[next_face_index].
size() != 4) {
400 if (r_loop_faces.
contains(next_face_index)) {
405 if (hide_poly[next_face_index]) {
409 r_loop_faces.
add(next_face_index);
413 current_face_index = next_face_index;
436 if (closest_edge_index == -1) {
445 const Span<int> corner_edges = mesh->corner_edges();
451 faces, corner_edges, mesh->
edges_num, edge_to_face_offsets, edge_to_face_indices);
459 const Span<int> faces_to_closest_edge = edge_to_face_map[closest_edge_index];
462 if (faces_to_closest_edge.is_empty()) {
474 if (!traced_full_loop && faces_to_closest_edge.size() > 1) {
490 bool any_adjacent_poly_selected =
false;
491 for (
const int i : faces_to_closest_edge) {
492 any_adjacent_poly_selected |= select_poly.
span[
i];
494 const bool select_toggle =
select && !any_adjacent_poly_selected;
495 select_poly.
span.fill_indices(faces_to_select.
as_span(), select_toggle);
506 for (
const int edge_index : face_edges) {
511 if (select_vert[edge[0]] || select_vert[edge[1]]) {
516 if (select_vert[edge[0]] && select_vert[edge[1]]) {
537 const Span<int> corner_edges = mesh->corner_edges();
541 for (const int i : range) {
542 if (select_poly.span[i] || hide_poly[i]) {
545 const IndexRange face = faces[i];
546 if (poly_has_selected_neighbor(corner_edges.slice(face), edges, select_vert.span, face_step))
548 select_poly.span[i] = true;
553 select_poly.finish();
554 select_vert.finish();
562 for (
const int edge_index : face_edges) {
565 if (verts_of_unselected_faces[edge[0]] || verts_of_unselected_faces[edge[1]]) {
570 if (verts_of_unselected_faces[edge[0]] && verts_of_unselected_faces[edge[1]]) {
589 const Span<int> corner_verts = mesh->corner_verts();
590 const Span<int> corner_edges = mesh->corner_edges();
596 for (
const int i :
faces.index_range()) {
597 if (select_poly.
span[
i]) {
601 for (
const int vert : corner_verts.
slice(face)) {
602 verts_of_unselected_faces[vert].set(
true);
607 for (const int i : range) {
608 if (!select_poly.span[i] || hide_poly[i]) {
611 const IndexRange face = faces[i];
612 if (poly_has_unselected_neighbor(
613 corner_edges.slice(face), edges, verts_of_unselected_faces, face_step))
615 select_poly.span[i] = false;
620 select_poly.finish();
627 if (mesh ==
nullptr) {
641 if (!hide_poly[
i] && select_poly.span[
i]) {
648 bool changed =
false;
654 const bool old_selection = select_poly.span[
i];
657 select_poly.span[
i] =
true;
660 select_poly.span[
i] =
false;
663 select_poly.span[
i] = !select_poly.span[
i];
667 if (old_selection != select_poly.span[
i]) {
686 float vec[3], bmat[3][3];
693 copy_m3_m4(bmat, ob->object_to_world().ptr());
697 const Span<int> corner_verts = mesh->corner_verts();
705 if (hide_poly[
i] || !select_poly[
i]) {
709 for (
const int vert : corner_verts.
slice(
faces[
i])) {
711 add_v3_v3v3(vec, vec, ob->object_to_world().location());
728 bool changed =
false;
741 if (index < mesh->faces_num) {
742 if (!hide_poly[index]) {
749 if ((found &&
params.select_passthrough) && select_poly.varray[index]) {
752 else if (found ||
params.deselect_all) {
764 select_poly.varray.set(index,
true);
767 select_poly.varray.set(index,
false);
770 select_poly.varray.set(index, !select_poly.varray[index]);
784 return changed || found;
792 if (mesh ==
nullptr) {
800 if (mesh_eval ==
nullptr) {
815 for (
const int i : hide_vert_eval.span.index_range()) {
817 hide_vert_eval.span[
i] = hide_vert_orig[orig_indices[
i]];
832 for (
const int i : select_vert_eval.span.index_range()) {
834 select_vert_eval.span[
i] = select_vert_orig[orig_indices[
i]];
839 select_vert_orig.
materialize(select_vert_eval.span);
841 select_vert_eval.
finish();
854 if (mesh ==
nullptr || mesh->
faces_num == 0) {
865 for (const int2 &edge : edges.slice(range)) {
866 islands.join(edge[0], edge[1]);
876 for (
const int i : vertex_indices) {
877 const int root = islands.find_root(
i);
878 selected_roots.add(root);
882 for (const int i : range) {
883 const int root = islands.find_root(i);
884 if (selected_roots.contains(root)) {
885 select_vert.span[i] = select;
898 const int region_coordinates[2],
914 if (mesh ==
nullptr || mesh->
faces_num == 0) {
923 for (
const int i : select_vert.
span.index_range()) {
924 if (!select_vert.
span[
i]) {
946 const Span<int> corner_edges = mesh->corner_edges();
947 const Span<int> corner_verts = mesh->corner_verts();
955 faces, corner_edges, mesh->
edges_num, edge_to_face_offsets, edge_to_face_indices);
961 select_vert_original[
i].set(select_vert.
span[
i]);
967 const int2 &edge = edges[
i];
968 if ((!select_vert_original[edge[0]] && !select_vert_original[edge[1]]) || hide_edge[
i]) {
971 select_vert.
span[edge[0]] =
true;
972 select_vert.
span[edge[1]] =
true;
976 const Span<int> neighbor_polys = edge_to_face_map[
i];
977 for (
const int face_i : neighbor_polys) {
978 if (hide_poly[face_i]) {
982 for (
const int vert : corner_verts.
slice(face)) {
983 select_vert.
span[vert] =
true;
1004 const Span<int> corner_edges = mesh->corner_edges();
1005 const Span<int> corner_verts = mesh->corner_verts();
1013 faces, corner_edges, edges.
size(), edge_to_face_offsets, edge_to_face_indices);
1019 select_vert_original[
i].set(select_vert.
span[
i]);
1023 const int2 &edge = edges[
i];
1024 if ((select_vert_original[edge[0]] && select_vert_original[edge[1]]) && !hide_edge[
i]) {
1027 select_vert.
span[edge[0]] =
false;
1028 select_vert.
span[edge[1]] =
false;
1033 for (
const int face_i : edge_to_face_map[
i]) {
1034 if (hide_poly[face_i]) {
1038 for (
const int vert : corner_verts.
slice(face)) {
1039 select_vert.
span[vert] =
false;
1056 if (mesh ==
nullptr) {
1070 if (!hide_vert[
i] && select_vert.span[
i]) {
1077 bool changed =
false;
1082 const bool old_selection = select_vert.span[
i];
1085 select_vert.span[
i] =
true;
1088 select_vert.span[
i] =
false;
1091 select_vert.span[
i] = !select_vert.span[
i];
1094 if (old_selection != select_vert.span[
i]) {
1124 if (mesh ==
nullptr) {
1142 for (
const int i : select_vert.span.index_range()) {
1143 if (!hide_vert[
i]) {
1144 if (dverts[
i].dw ==
nullptr) {
1146 select_vert.span[
i] =
true;
1162 if (mesh ==
nullptr || mesh->
verts_num == 0) {
1172 for (
const int i : hide_vert.
span.index_range()) {
1173 if (!hide_vert.
span[
i]) {
1174 if (!select_vert.span[
i] == unselected) {
1175 hide_vert.
span[
i] =
true;
1179 if (hide_vert.
span[
i]) {
1180 select_vert.span[
i] =
false;
1184 select_vert.finish();
1196 if (mesh ==
nullptr || mesh->
verts_num == 0) {
1206 for (
const int i : select_vert.span.index_range()) {
1215 attributes.
remove(
".hide_vert");
Depsgraph * CTX_data_ensure_evaluated_depsgraph(const bContext *C)
ARegion * CTX_wm_region(const bContext *C)
CustomData interface, see also DNA_customdata_types.h.
const void * CustomData_get_layer(const CustomData *data, eCustomDataType type)
bool CustomData_has_layer(const CustomData *data, eCustomDataType type)
void BKE_mesh_batch_cache_dirty_tag(Mesh *mesh, eMeshBatchDirtyMode mode)
void BKE_mesh_mselect_clear(Mesh *mesh)
@ BKE_MESH_BATCH_DIRTY_SELECT_PAINT
@ BKE_MESH_BATCH_DIRTY_ALL
void BKE_mesh_mselect_validate(Mesh *mesh)
Mesh * BKE_mesh_from_object(Object *ob)
General operations, lookup, etc. for blender objects.
Mesh * BKE_object_get_evaluated_mesh(const Object *object_eval)
#define BLI_assert_unreachable()
void copy_m3_m4(float m1[3][3], const float m2[4][4])
void mul_v3_m3v3(float r[3], const float M[3][3], const float a[3])
void minmax_v3v3_v3(float min[3], float max[3], const float vec[3])
MINLINE void add_v3_v3v3(float r[3], const float a[3], const float b[3])
void DEG_id_tag_update(ID *id, unsigned int flags)
T * DEG_get_evaluated(const Depsgraph *depsgraph, T *id)
Object is a sort of wrapper for general info.
#define ED_MESH_PICK_DEFAULT_VERT_DIST
bool ED_mesh_pick_edge(bContext *C, Object *ob, const int mval[2], uint dist_px, uint *r_index)
bool ED_mesh_pick_face(bContext *C, Object *ob, const int mval[2], uint dist_px, uint *r_index)
#define ED_MESH_PICK_DEFAULT_FACE_DIST
bool ED_mesh_pick_vert(bContext *C, Object *ob, const int mval[2], uint dist_px, bool use_zbuf, uint *r_index)
void ED_region_tag_redraw(ARegion *region)
void ED_view3d_init_mats_rv3d(const Object *ob, RegionView3D *rv3d)
void ED_view3d_select_id_validate(const ViewContext *vc)
ViewContext ED_view3d_viewcontext_init(bContext *C, Depsgraph *depsgraph)
BPy_StructRNA * depsgraph
static DBVT_INLINE btScalar size(const btDbvtVolume &a)
constexpr Span slice(int64_t start, int64_t size) const
constexpr int64_t size() const
constexpr IndexRange index_range() const
constexpr bool is_empty() const
Span< Key > as_span() const
int find_root(int x) const
constexpr Span slice(int64_t start, int64_t size) const
constexpr int64_t first_index(const T &search_value) const
IndexRange index_range() const
void materialize(MutableSpan< T > r_span) const
bool contains(const Key &key) const
GAttributeReader lookup_or_default(StringRef attribute_id, AttrDomain domain, AttrType data_type, const void *default_value=nullptr) const
GSpanAttributeWriter lookup_or_add_for_write_span(StringRef attribute_id, AttrDomain domain, AttrType data_type, const AttributeInit &initializer=AttributeInitDefaultValue())
bool remove(const StringRef attribute_id)
GAttributeWriter lookup_or_add_for_write(StringRef attribute_id, AttrDomain domain, AttrType data_type, const AttributeInit &initializer=AttributeInitDefaultValue())
GSpanAttributeWriter lookup_or_add_for_write_only_span(StringRef attribute_id, AttrDomain domain, AttrType data_type)
static void build_poly_connections(blender::AtomicDisjointSet &islands, Mesh &mesh, const bool skip_seams=true)
static bool follow_face_loop(const int face_start_index, const int edge_start_index, const blender::OffsetIndices< int > faces, const blender::VArray< bool > &hide_poly, const blender::Span< int > corner_edges, const blender::GroupedSpan< int > edge_to_face_map, blender::VectorSet< int > &r_loop_faces)
static bool poly_has_unselected_neighbor(blender::Span< int > face_edges, blender::Span< blender::int2 > edges, blender::BitSpan verts_of_unselected_faces, const bool face_step)
bool paintface_minmax(Object *ob, float r_min[3], float r_max[3])
void paintvert_flush_flags(Object *ob)
void paintface_flush_flags(bContext *C, Object *ob, const bool flush_selection, const bool flush_hidden)
void paintface_reveal(bContext *C, Object *ob, const bool select)
void paintvert_tag_select_update(bContext *C, Object *ob)
void paintface_hide(bContext *C, Object *ob, const bool unselected)
void paintvert_select_ungrouped(Object *ob, bool extend, bool flush_flags)
static int get_opposing_edge_index(const blender::IndexRange face, const blender::Span< int > corner_edges, const int current_edge_index)
void paintface_select_less(Mesh *mesh, const bool face_step)
void paintface_select_more(Mesh *mesh, const bool face_step)
bool paintface_mouse_select(bContext *C, const int mval[2], const SelectPick_Params ¶ms, Object *ob)
bool paintvert_deselect_all_visible(Object *ob, int action, bool flush_flags)
void paintvert_select_linked(bContext *C, Object *ob)
void paintvert_select_linked_pick(bContext *C, Object *ob, const int region_coordinates[2], const bool select)
static void paintface_select_linked_faces(Mesh &mesh, const blender::Span< int > face_indices, const bool select)
static bool poly_has_selected_neighbor(blender::Span< int > face_edges, blender::Span< blender::int2 > edges, blender::Span< bool > select_vert, const bool face_step)
void paintvert_hide(bContext *C, Object *ob, const bool unselected)
void paintvert_reveal(bContext *C, Object *ob, const bool select)
void paintvert_select_less(Mesh *mesh, const bool face_step)
bool paintface_deselect_all_visible(bContext *C, Object *ob, int action, bool flush_flags)
void paintface_select_loop(bContext *C, Object *ob, const int mval[2], const bool select)
void paintvert_select_more(Mesh *mesh, const bool face_step)
void paintface_select_linked(bContext *C, Object *ob, const int mval[2], const bool select)
static void paintvert_select_linked_vertices(bContext *C, Object *ob, const blender::Span< int > vertex_indices, const bool select)
static BMFace * face_step(BMEdge *edge, BMFace *f)
GroupedSpan< int > build_edge_to_face_map(OffsetIndices< int > faces, Span< int > corner_edges, int edges_num, Array< int > &r_offsets, Array< int > &r_indices)
void mesh_select_vert_flush(Mesh &mesh)
void mesh_hide_vert_flush(Mesh &mesh)
void mesh_hide_face_flush(Mesh &mesh)
void mesh_select_face_flush(Mesh &mesh)
void parallel_for(const IndexRange range, const int64_t grain_size, const Function &function, const TaskSizeHints &size_hints=detail::TaskSizeHints_Static(1))
VecBase< int32_t, 2 > int2
ObjectRuntimeHandle * runtime
MutableVArraySpan< T > span
void WM_event_add_notifier(const bContext *C, uint type, void *reference)