Blender V4.3
uvedit_islands.cc
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2023 Blender Authors
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
16#include "BLI_listbase.h"
17#include "BLI_math_vector.h"
18
19#include "BKE_editmesh.hh"
20
21#include "DNA_image_types.h"
22
23#include "ED_uvedit.hh" /* Own include. */
24
25/* -------------------------------------------------------------------- */
29bool uv_coords_isect_udim(const Image *image, const int udim_grid[2], const float coords[2])
30{
31 const float coords_floor[2] = {floorf(coords[0]), floorf(coords[1])};
32 const bool is_tiled_image = image && (image->source == IMA_SRC_TILED);
33
34 if (coords[0] < udim_grid[0] && coords[0] > 0 && coords[1] < udim_grid[1] && coords[1] > 0) {
35 return true;
36 }
37 /* Check if selection lies on a valid UDIM image tile. */
38 if (is_tiled_image) {
39 LISTBASE_FOREACH (const ImageTile *, tile, &image->tiles) {
40 const int tile_index = tile->tile_number - 1001;
41 const int target_x = (tile_index % 10);
42 const int target_y = (tile_index / 10);
43 if (coords_floor[0] == target_x && coords_floor[1] == target_y) {
44 return true;
45 }
46 }
47 }
48 /* Probably not required since UDIM grid checks for 1001. */
49 else if (image && !is_tiled_image) {
50 if (is_zero_v2(coords_floor)) {
51 return true;
52 }
53 }
54
55 return false;
56}
57
60/* -------------------------------------------------------------------- */
68
69static bool bm_loop_uv_shared_edge_check(const BMLoop *l_a, const BMLoop *l_b, void *user_data)
70{
71 const SharedUVLoopData *data = static_cast<const SharedUVLoopData *>(user_data);
72
73 if (data->use_seams) {
74 if (BM_elem_flag_test(l_a->e, BM_ELEM_SEAM)) {
75 return false;
76 }
77 }
78
79 return BM_loop_uv_share_edge_check((BMLoop *)l_a, (BMLoop *)l_b, data->offsets.uv);
80}
81
92 BMFace *efa,
93 const bool only_selected_faces,
94 const bool only_selected_uvs,
95 const BMUVOffsets &uv_offsets)
96{
98 return false;
99 }
100 if (only_selected_faces) {
101 if (only_selected_uvs) {
102 return BM_elem_flag_test(efa, BM_ELEM_SELECT) &&
103 uvedit_face_select_test(scene, efa, uv_offsets);
104 }
106 }
107 return true;
108}
109
111 BMesh *bm,
112 ListBase *island_list,
113 const bool only_selected_faces,
114 const bool only_selected_uvs,
115 const bool use_seams,
116 const float aspect_y,
117 const BMUVOffsets uv_offsets)
118{
119 BLI_assert(uv_offsets.uv >= 0);
120 int island_added = 0;
122
123 int *groups_array = static_cast<int *>(
124 MEM_mallocN(sizeof(*groups_array) * size_t(bm->totface), __func__));
125
126 int(*group_index)[2];
127
128 /* Set the tag for `BM_mesh_calc_face_groups`. */
129 BMFace *f;
130 BMIter iter;
131 BM_ITER_MESH (f, &iter, bm, BM_FACES_OF_MESH) {
132 const bool face_affected = uvedit_is_face_affected_for_calc_uv_islands(
133 scene, f, only_selected_faces, only_selected_uvs, uv_offsets);
134 BM_elem_flag_set(f, BM_ELEM_TAG, face_affected);
135 }
136
137 SharedUVLoopData user_data = {{0}};
138 user_data.offsets = uv_offsets;
139 user_data.use_seams = use_seams;
140
141 const int group_len = BM_mesh_calc_face_groups(bm,
142 groups_array,
143 &group_index,
144 nullptr,
146 &user_data,
148 BM_EDGE);
149
150 for (int i = 0; i < group_len; i++) {
151 const int faces_start = group_index[i][0];
152 const int faces_len = group_index[i][1];
153 BMFace **faces = static_cast<BMFace **>(MEM_mallocN(sizeof(*faces) * faces_len, __func__));
154
155 for (int j = 0; j < faces_len; j++) {
156 faces[j] = BM_face_at_index(bm, groups_array[faces_start + j]);
157 }
158
159 FaceIsland *island = static_cast<FaceIsland *>(MEM_callocN(sizeof(*island), __func__));
160 island->faces = faces;
161 island->faces_len = faces_len;
162 island->offsets = uv_offsets;
163 island->aspect_y = aspect_y;
164 BLI_addtail(island_list, island);
165 island_added += 1;
166 }
167
168 MEM_freeN(groups_array);
169 MEM_freeN(group_index);
170 return island_added;
171}
172
#define BLI_assert(a)
Definition BLI_assert.h:50
#define LISTBASE_FOREACH(type, var, list)
void BLI_addtail(struct ListBase *listbase, void *vlink) ATTR_NONNULL(1)
Definition listbase.cc:110
MINLINE bool is_zero_v2(const float v[2]) ATTR_WARN_UNUSED_RESULT
@ IMA_SRC_TILED
bool uvedit_face_select_test(const Scene *scene, BMFace *efa, BMUVOffsets offsets)
@ BM_ELEM_HIDDEN
@ BM_ELEM_SEAM
@ BM_ELEM_SELECT
@ BM_ELEM_TAG
#define BM_elem_flag_set(ele, hflag, val)
#define BM_elem_flag_test(ele, hflag)
#define BM_ITER_MESH(ele, iter, bm, itype)
@ BM_FACES_OF_MESH
ATTR_WARN_UNUSED_RESULT BMesh * bm
void BM_mesh_elem_table_ensure(BMesh *bm, const char htype)
BLI_INLINE BMFace * BM_face_at_index(BMesh *bm, const int index)
#define BM_FACE
#define BM_EDGE
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)
ATTR_WARN_UNUSED_RESULT const BMLoop * l_b
bool BM_loop_uv_share_edge_check(BMLoop *l_a, BMLoop *l_b, const int cd_loop_uv_offset)
#define floorf(x)
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
const int tile_index
ccl_global const KernelWorkTile * tile
void *(* MEM_mallocN)(size_t len, const char *str)
Definition mallocn.cc:44
void MEM_freeN(void *vmemh)
Definition mallocn.cc:105
void *(* MEM_callocN)(size_t len, const char *str)
Definition mallocn.cc:42
static char faces[256]
struct BMEdge * e
int totface
float aspect_y
Definition ED_uvedit.hh:297
BMFace ** faces
Definition ED_uvedit.hh:290
BMUVOffsets offsets
Definition ED_uvedit.hh:296
BMUVOffsets offsets
static bool uvedit_is_face_affected_for_calc_uv_islands(const Scene *scene, BMFace *efa, const bool only_selected_faces, const bool only_selected_uvs, const BMUVOffsets &uv_offsets)
int bm_mesh_calc_uv_islands(const Scene *scene, BMesh *bm, ListBase *island_list, const bool only_selected_faces, const bool only_selected_uvs, const bool use_seams, const float aspect_y, const BMUVOffsets uv_offsets)
bool uv_coords_isect_udim(const Image *image, const int udim_grid[2], const float coords[2])
static bool bm_loop_uv_shared_edge_check(const BMLoop *l_a, const BMLoop *l_b, void *user_data)