51 const bool flush_selection,
52 const bool flush_hidden)
56 const int *index_array =
nullptr;
60 if (mesh ==
nullptr) {
68 if (flush_selection) {
75 if (ob_eval ==
nullptr) {
86 if (me_orig !=
nullptr && mesh_eval !=
nullptr && me_orig->
faces_num == mesh->
faces_num) {
95 hide_poly_orig.finish();
97 if (flush_selection) {
104 select_poly_orig.finish();
116 const int orig_face_index = index_array[i];
118 hide_poly_eval.span[i] = hide_poly_orig[orig_face_index];
123 if (flush_selection) {
130 const int orig_face_index = index_array[i];
132 select_poly_eval.span[i] = select_poly_orig[orig_face_index];
135 select_poly_eval.
finish();
163 if (mesh ==
nullptr || mesh->
faces_num == 0) {
173 for (
int i = 0; i < mesh->
faces_num; i++) {
174 if (!hide_poly.
span[i]) {
175 if (!select_poly.span[i] == unselected) {
176 hide_poly.
span[i] =
true;
180 if (hide_poly.
span[i]) {
181 select_poly.span[i] =
false;
186 select_poly.finish();
197 if (mesh ==
nullptr || mesh->
faces_num == 0) {
210 select_poly.span[i] =
true;
216 attributes.
remove(
".hide_poly");
231 const bool skip_seams =
true)
235 const Span<int> corner_edges = mesh.corner_edges();
246 for (const int face_index : range) {
247 if (hide_poly[face_index]) {
250 const Span<int> face_edges = corner_edges.slice(faces[face_index]);
252 for (const int poly_loop_index : face_edges.index_range()) {
253 const int outer_edge = face_edges[poly_loop_index];
254 if (skip_seams && uv_seams[outer_edge]) {
258 for (const int inner_edge :
259 face_edges.slice(poly_loop_index, face_edges.size() - poly_loop_index))
261 if (outer_edge == inner_edge) {
264 if (skip_seams && uv_seams[inner_edge]) {
267 islands.join(inner_edge, outer_edge);
285 const Span<int> corner_edges = mesh.corner_edges();
294 for (
const int i : face_indices) {
295 for (
const int edge : corner_edges.
slice(
faces[i])) {
296 if (uv_seams[edge]) {
299 const int root = islands.
find_root(edge);
300 selected_roots.add(root);
305 for (const int face_index : range) {
306 for (const int edge : corner_edges.slice(faces[face_index])) {
307 const int root = islands.find_root(edge);
308 if (selected_roots.contains(root)) {
309 select_poly.span[face_index] = select;
316 select_poly.finish();
323 if (mesh ==
nullptr || mesh->
faces_num == 0) {
340 select_poly.
span[index] =
true;
345 for (
const int i : select_poly.
span.index_range()) {
346 if (!select_poly.
span[i]) {
366 int closest_edge_index;
370 for (
const int i : face_edges) {
372 const int2 edge = edges[i];
374 vert_positions[edge[1]]);
383 closest_edge_index = i;
386 return closest_edge_index;
391 const int current_edge_index)
393 const int index_in_poly = corner_edges.
slice(face).
first_index(current_edge_index);
395 if (index_in_poly >= 2) {
396 return corner_edges[face[index_in_poly - 2]];
399 return corner_edges[face[index_in_poly + 2]];
407 const int edge_start_index,
415 int current_face_index = face_start_index;
416 int current_edge_index = edge_start_index;
418 while (current_edge_index > 0) {
419 int next_face_index = -1;
421 for (
const int face_index : edge_to_face_map[current_edge_index]) {
422 if (face_index != current_face_index) {
423 next_face_index = face_index;
429 if (next_face_index == -1) {
434 if (
faces[next_face_index].
size() != 4) {
439 if (r_loop_faces.
contains(next_face_index)) {
444 if (hide_poly[next_face_index]) {
448 r_loop_faces.
add(next_face_index);
452 current_face_index = next_face_index;
480 const Span<int> corner_edges = mesh->corner_edges();
487 region, edges, corner_edges.
slice(face),
verts, mval);
492 faces, corner_edges, mesh->
edges_num, edge_to_face_offsets, edge_to_face_indices);
500 const Span<int> faces_to_closest_edge = edge_to_face_map[closest_edge_index];
509 if (!traced_full_loop && faces_to_closest_edge.size() > 1) {
525 bool any_adjacent_poly_selected =
false;
526 for (
const int i : faces_to_closest_edge) {
527 any_adjacent_poly_selected |= select_poly.
span[i];
529 const bool select_toggle =
select && !any_adjacent_poly_selected;
530 select_poly.
span.fill_indices(faces_to_select.
as_span(), select_toggle);
541 for (
const int edge_index : face_edges) {
546 if (select_vert[edge[0]] || select_vert[edge[1]]) {
551 if (select_vert[edge[0]] && select_vert[edge[1]]) {
572 const Span<int> corner_edges = mesh->corner_edges();
576 for (const int i : range) {
577 if (select_poly.span[i] || hide_poly[i]) {
580 const IndexRange face = faces[i];
581 if (poly_has_selected_neighbor(corner_edges.slice(face), edges, select_vert.span, face_step))
583 select_poly.span[i] = true;
588 select_poly.finish();
589 select_vert.finish();
597 for (
const int edge_index : face_edges) {
600 if (verts_of_unselected_faces[edge[0]] || verts_of_unselected_faces[edge[1]]) {
605 if (verts_of_unselected_faces[edge[0]] && verts_of_unselected_faces[edge[1]]) {
624 const Span<int> corner_verts = mesh->corner_verts();
625 const Span<int> corner_edges = mesh->corner_edges();
631 for (
const int i :
faces.index_range()) {
632 if (select_poly.
span[i]) {
636 for (
const int vert : corner_verts.
slice(face)) {
637 verts_of_unselected_faces[vert].set(
true);
642 for (const int i : range) {
643 if (!select_poly.span[i] || hide_poly[i]) {
646 const IndexRange face = faces[i];
647 if (poly_has_unselected_neighbor(
648 corner_edges.slice(face), edges, verts_of_unselected_faces, face_step))
650 select_poly.span[i] = false;
655 select_poly.finish();
662 if (mesh ==
nullptr) {
675 for (
int i = 0; i < mesh->
faces_num; i++) {
676 if (!hide_poly[i] && select_poly.span[i]) {
683 bool changed =
false;
685 for (
int i = 0; i < mesh->
faces_num; i++) {
689 const bool old_selection = select_poly.span[i];
692 select_poly.span[i] =
true;
695 select_poly.span[i] =
false;
698 select_poly.span[i] = !select_poly.span[i];
702 if (old_selection != select_poly.span[i]) {
721 float vec[3], bmat[3][3];
728 copy_m3_m4(bmat, ob->object_to_world().ptr());
732 const Span<int> corner_verts = mesh->corner_verts();
739 for (
int i = 0; i < mesh->
faces_num; i++) {
740 if (hide_poly[i] || !select_poly[i]) {
744 for (
const int vert : corner_verts.
slice(
faces[i])) {
746 add_v3_v3v3(vec, vec, ob->object_to_world().location());
763 bool changed =
false;
776 if (index < mesh->faces_num) {
777 if (!hide_poly[index]) {
784 if ((found &&
params->select_passthrough) && select_poly.varray[index]) {
787 else if (found ||
params->deselect_all) {
799 select_poly.varray.set(index,
true);
802 select_poly.varray.set(index,
false);
805 select_poly.varray.set(index, !select_poly.varray[index]);
819 return changed || found;
827 if (mesh ==
nullptr) {
835 if (mesh_eval ==
nullptr) {
850 for (
const int i : hide_vert_eval.span.index_range()) {
852 hide_vert_eval.span[i] = hide_vert_orig[orig_indices[i]];
867 for (
const int i : select_vert_eval.span.index_range()) {
869 select_vert_eval.span[i] = select_vert_orig[orig_indices[i]];
874 select_vert_orig.
materialize(select_vert_eval.span);
876 select_vert_eval.
finish();
889 if (mesh ==
nullptr || mesh->
faces_num == 0) {
900 for (const int2 &edge : edges.slice(range)) {
901 islands.join(edge[0], edge[1]);
911 for (
const int i : vertex_indices) {
912 const int root = islands.find_root(i);
913 selected_roots.add(root);
917 for (const int i : range) {
918 const int root = islands.find_root(i);
919 if (selected_roots.contains(root)) {
920 select_vert.span[i] = select;
933 const int region_coordinates[2],
949 if (mesh ==
nullptr || mesh->
faces_num == 0) {
958 for (
const int i : select_vert.
span.index_range()) {
959 if (!select_vert.
span[i]) {
981 const Span<int> corner_edges = mesh->corner_edges();
982 const Span<int> corner_verts = mesh->corner_verts();
990 faces, corner_edges, mesh->
edges_num, edge_to_face_offsets, edge_to_face_indices);
995 for (
int i = 0; i < mesh->
verts_num; i++) {
996 select_vert_original[i].set(select_vert.
span[i]);
1002 const int2 &edge = edges[i];
1003 if ((!select_vert_original[edge[0]] && !select_vert_original[edge[1]]) || hide_edge[i]) {
1006 select_vert.
span[edge[0]] =
true;
1007 select_vert.
span[edge[1]] =
true;
1011 const Span<int> neighbor_polys = edge_to_face_map[i];
1012 for (
const int face_i : neighbor_polys) {
1013 if (hide_poly[face_i]) {
1017 for (
const int vert : corner_verts.
slice(face)) {
1018 select_vert.
span[vert] =
true;
1039 const Span<int> corner_edges = mesh->corner_edges();
1040 const Span<int> corner_verts = mesh->corner_verts();
1048 faces, corner_edges, edges.
size(), edge_to_face_offsets, edge_to_face_indices);
1053 for (
int i = 0; i < mesh->
verts_num; i++) {
1054 select_vert_original[i].set(select_vert.
span[i]);
1058 const int2 &edge = edges[i];
1059 if ((select_vert_original[edge[0]] && select_vert_original[edge[1]]) && !hide_edge[i]) {
1062 select_vert.
span[edge[0]] =
false;
1063 select_vert.
span[edge[1]] =
false;
1068 for (
const int face_i : edge_to_face_map[i]) {
1069 if (hide_poly[face_i]) {
1073 for (
const int vert : corner_verts.
slice(face)) {
1074 select_vert.
span[vert] =
false;
1091 if (mesh ==
nullptr) {
1104 for (
int i = 0; i < mesh->
verts_num; i++) {
1105 if (!hide_vert[i] && select_vert.span[i]) {
1112 bool changed =
false;
1113 for (
int i = 0; i < mesh->
verts_num; i++) {
1117 const bool old_selection = select_vert.span[i];
1120 select_vert.span[i] =
true;
1123 select_vert.span[i] =
false;
1126 select_vert.span[i] = !select_vert.span[i];
1129 if (old_selection != select_vert.span[i]) {
1159 if (mesh ==
nullptr) {
1177 for (
const int i : select_vert.span.index_range()) {
1178 if (!hide_vert[i]) {
1179 if (dverts[i].dw ==
nullptr) {
1181 select_vert.span[i] =
true;
1197 if (mesh ==
nullptr || mesh->
verts_num == 0) {
1207 for (
const int i : hide_vert.
span.index_range()) {
1208 if (!hide_vert.
span[i]) {
1209 if (!select_vert.span[i] == unselected) {
1210 hide_vert.
span[i] =
true;
1214 if (hide_vert.
span[i]) {
1215 select_vert.span[i] =
false;
1219 select_vert.finish();
1231 if (mesh ==
nullptr || mesh->
verts_num == 0) {
1241 for (
const int i : select_vert.span.index_range()) {
1243 select_vert.span[i] =
select;
1250 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)
void BKE_mesh_mselect_validate(Mesh *mesh)
Mesh * BKE_mesh_from_object(Object *ob)
@ BKE_MESH_BATCH_DIRTY_SELECT_PAINT
@ BKE_MESH_BATCH_DIRTY_ALL
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)
Object * DEG_get_evaluated_object(const Depsgraph *depsgraph, Object *object)
Object is a sort of wrapper for general info.
#define ED_MESH_PICK_DEFAULT_VERT_DIST
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)
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 ED_view3d_select_id_validate(const ViewContext *vc)
ViewContext ED_view3d_viewcontext_init(bContext *C, Depsgraph *depsgraph)
#define V3D_PROJ_TEST_CLIP_DEFAULT
Contains defines and structs used throughout the imbuf module.
Read Guarded memory(de)allocation.
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, eCustomDataType data_type, const void *default_value=nullptr) const
GSpanAttributeWriter lookup_or_add_for_write_span(StringRef attribute_id, AttrDomain domain, eCustomDataType data_type, const AttributeInit &initializer=AttributeInitDefaultValue())
GAttributeWriter lookup_or_add_for_write(StringRef attribute_id, AttrDomain domain, eCustomDataType data_type, const AttributeInit &initializer=AttributeInitDefaultValue())
bool remove(const StringRef attribute_id)
GSpanAttributeWriter lookup_or_add_for_write_only_span(StringRef attribute_id, AttrDomain domain, eCustomDataType 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 *params, 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 int find_closest_edge_in_poly(ARegion *region, blender::Span< blender::int2 > edges, blender::Span< int > face_edges, blender::Span< blender::float3 > vert_positions, const int mval[2])
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)
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
ccl_device_inline float4 select(const int4 mask, const float4 a, const float4 b)
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)
T midpoint(const T &a, const T &b)
T distance_squared(const VecBase< T, Size > &a, const VecBase< T, Size > &b)
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
float distance(float a, float b)
ObjectRuntimeHandle * runtime
MutableVArraySpan< T > span
void WM_event_add_notifier(const bContext *C, uint type, void *reference)