39 const bool *hide_poly,
40 const bool *select_poly,
41 const int *corner_verts,
42 const float (*mloopuv)[2],
46 const bool use_winding)
60 if (!selected || (!(hide_poly && hide_poly[a]) && (select_poly && select_poly[a]))) {
73 if (!vmap->
vert || !vmap->
buf) {
78 bool *winding =
nullptr;
85 if (!selected || (!(hide_poly && hide_poly[a]) && (select_poly && select_poly[a]))) {
86 float(*tf_uv)[2] =
nullptr;
93 nverts = int(face.
size());
95 for (
i = 0;
i < nverts;
i++) {
99 buf->
next = vmap->
vert[corner_verts[face[
i]]];
100 vmap->
vert[corner_verts[face[
i]]] = buf;
116 for (
uint a = 0; a < totvert; a++) {
119 const float *uv, *uv2;
128 uv = mloopuv[
faces[
v->face_index].start() +
v->loop_of_face_index];
138 if (
fabsf(uv[0] - uv2[0]) < limit[0] &&
fabsf(uv[1] - uv2[1]) < limit[1] &&
139 (!use_winding || winding[iterv->
face_index] == winding[
v->face_index]))
147 iterv->
next = newvlist;
160 vmap->
vert[a] = newvlist;
174 return vmap->
vert[
v];
195 const int *corner_verts,
204 for (
i = 0;
i < tris_num;
i++) {
205 for (
int j = 3; j--;) {
206 map[corner_verts[corner_tris[
i][j]]].
count++;
212 for (
i = 0;
i < totvert;
i++) {
214 index_step += map[
i].
count;
221 for (
i = 0;
i < tris_num;
i++) {
222 for (
int j = 3; j--;) {
223 MeshElemMap *map_ele = &map[corner_verts[corner_tris[
i][j]]];
235 const int *final_origindex,
244 for (
i = 0;
i < totfinal;
i++) {
247 map[final_origindex[
i]].
count++;
253 for (
i = 0;
i < totsource;
i++) {
255 index_step += map[
i].
count;
262 for (
i = 0;
i < totfinal;
i++) {
276 const int *corner_tri_faces,
277 const int corner_tris_num)
291 for (
int i = 0;
i < corner_tris_num;
i++) {
310 const int grain_size,
314 for (const int64_t index : range) {
315 MutableSpan<int> group = indices.slice(groups[index]);
316 std::sort(group.begin(), group.end());
338 for (const int64_t i : range) {
339 const int group_index = group_indices[i];
340 const int index_in_group = atomic_fetch_and_add_int32(&counts[group_index], 1);
341 results[offsets[group_index][index_in_group]] = int(i);
344 sort_small_groups(offsets, 1024, results);
357 for (const int64_t face : range) {
358 for (const int elem : group_to_elem.slice(groups[face])) {
359 const int index_in_group = atomic_fetch_and_add_int32(&counts[elem], 1);
360 results[offsets[elem][index_in_group]] = int(face);
364 sort_small_groups(offsets, 1024, results);
368 const int groups_num,
397 for (const int64_t edge : range) {
398 for (const int vert : {edges[edge][0], edges[edge][1]}) {
399 const int index_in_group = atomic_fetch_and_add_int32(&counts[vert], 1);
400 r_indices[offsets[vert][index_in_group]] = int(edge);
404 sort_small_groups(offsets, 1024, r_indices);
405 return {offsets, r_indices};
439 return gather_groups(corner_verts, verts_num, r_offsets, r_indices);
447 return gather_groups(corner_edges, edges_num, r_offsets, r_indices);
482 const int *face_groups,
484 const int face_group_id,
485 const int face_group_id_overflowed,
486 int &r_bit_face_group_mask)
491 for (
const int face_idx : faces_from_item) {
492 int bit = face_groups[face_idx];
493 if (!
ELEM(bit, 0, face_group_id, face_group_id_overflowed) && !(r_bit_face_group_mask & bit)) {
494 r_bit_face_group_mask |= bit;
522 const bool use_bitflags,
523 const bool use_boundary_vertices_for_bitflags,
528 int *r_totedgeboundaries)
534 int num_edgeboundaries = 0;
537 constexpr int temp_face_group_id = 3;
541 constexpr int face_group_id_overflowed = 5;
544 bool group_id_overflow =
false;
546 if (
faces.is_empty()) {
548 *r_face_groups =
nullptr;
549 if (r_edge_boundaries) {
550 *r_edge_boundaries =
nullptr;
551 *r_totedgeboundaries = 0;
556 if (r_edge_boundaries) {
558 *r_totedgeboundaries = 0;
565 faces, corner_edges, totedge, edge_to_face_src_offsets, edge_to_face_src_indices);
569 if (use_bitflags && vert_face_map.
is_empty()) {
571 faces, corner_verts, totvert, vert_to_face_src_offsets, vert_to_face_src_indices);
579 int bit_face_group_mask = 0;
581 int ps_curr_idx = 0, ps_end_idx = 0;
583 for (face = face_prev; face < int(
faces.size()); face++) {
584 if (face_groups[face] == 0) {
589 if (face ==
int(
faces.size())) {
594 face_group_id = use_bitflags ? temp_face_group_id : ++tot_group;
597 face_prev = face + 1;
599 face_groups[face] = face_group_id;
600 face_stack[ps_end_idx++] = face;
602 while (ps_curr_idx != ps_end_idx) {
603 face = face_stack[ps_curr_idx++];
604 BLI_assert(face_groups[face] == face_group_id);
607 const int edge = corner_edges[loop];
610 const int *p = map_ele.
data();
611 int i = int(map_ele.
size());
612 if (!edge_boundary_check(face,
int(loop), edge,
i, map_ele)) {
617 if (face_groups[*p] == 0) {
618 face_groups[*p] = face_group_id;
619 face_stack[ps_end_idx++] = *p;
626 num_edgeboundaries++;
633 face_group_id_overflowed,
634 bit_face_group_mask);
635 if (use_boundary_vertices_for_bitflags) {
649 const int vert = corner_verts[loop];
653 face_group_id_overflowed,
654 bit_face_group_mask);
665 int i, *p, gid_bit = 0;
669 for (; (face_group_id & bit_face_group_mask) && (gid_bit < 32); gid_bit++) {
684 "Warning, could not find an available id for current smooth group, faces will me "
686 "as out of any smooth group...\n");
689 face_group_id = face_group_id_overflowed;
691 group_id_overflow =
true;
693 tot_group = std::max(gid_bit, tot_group);
695 for (
i = ps_end_idx, p = face_stack;
i--; p++) {
696 face_groups[*p] = face_group_id;
707 int i = int(
faces.size()), *gid = face_groups;
709 if (*gid == face_group_id_overflowed) {
719 *r_totgroup = tot_group;
720 *r_face_groups = face_groups;
721 if (r_edge_boundaries) {
722 *r_edge_boundaries = edge_boundaries;
723 *r_totedgeboundaries = num_edgeboundaries;
735 const bool use_bitflags,
736 const bool use_boundary_vertices_for_bitflags)
738 int *face_groups =
nullptr;
740 auto face_is_smooth = [&](
const int i) {
return sharp_faces.
is_empty() || !sharp_faces[
i]; };
742 auto face_is_island_boundary_smooth = [&](
const int face_index,
744 const int edge_index,
745 const int edge_user_count,
749 if (face_is_smooth(face_index) && !(!sharp_edges.
is_empty() && sharp_edges[edge_index]) &&
750 (edge_user_count == 2))
753 const int other_face_index = (face_index == edge_face_map_elem[0]) ? edge_face_map_elem[1] :
754 edge_face_map_elem[0];
755 return !face_is_smooth(other_face_index);
768 use_boundary_vertices_for_bitflags,
769 face_is_island_boundary_smooth,
786 edges_num, 0,
faces, corner_edges, {}, sharp_edges, sharp_faces, r_totgroup,
false,
false);
796 const bool use_boundary_vertices_for_bitflags,
808 use_boundary_vertices_for_bitflags);
811#define MISLAND_DEFAULT_BUFSIZE 64
814 const short item_type,
816 const short island_type,
817 const short innercut_type)
821 if (mem ==
nullptr) {
823 island_store->
mem = mem;
855 island_store->
islands =
nullptr;
860 if (island_store->
mem) {
869 if (island_store->
mem) {
871 island_store->
mem =
nullptr;
877 const int *items_indices,
878 const int num_island_items,
879 int *island_item_indices,
880 const int num_innercut_items,
881 int *innercut_item_indices)
886 const int curr_island_idx = island_store->
islands_num++;
887 const size_t curr_num_islands = size_t(island_store->
islands_num);
900 memcpy(islds, island_store->
islands,
sizeof(*islds) * (curr_num_islands - 1));
905 memcpy(innrcuts, island_store->
innercuts,
sizeof(*innrcuts) * (curr_num_islands - 1));
911 isld->
count = num_island_items;
912 isld->
indices =
static_cast<int *
>(
914 memcpy(isld->
indices, island_item_indices,
sizeof(*isld->
indices) *
size_t(num_island_items));
918 innrcut->
count = num_innercut_items;
919 innrcut->
indices =
static_cast<int *
>(
922 innercut_item_indices,
923 sizeof(*innrcut->
indices) *
size_t(num_innercut_items));
927 const bool *uv_seams,
929 const int *corner_verts,
930 const int *corner_edges,
931 const int corners_num,
932 const float (*luvs)[2],
936 int *face_groups =
nullptr;
941 int num_pidx, num_lidx;
947 int num_edge_boundaries = 0;
948 char *edge_boundary_count =
nullptr;
949 int *edge_innercut_indices =
nullptr;
950 int num_einnercuts = 0;
961 faces, {corner_edges, corners_num}, totedge, edge_to_face_offsets, edge_to_face_indices);
968 {corner_edges, corners_num}, totedge, edge_to_corner_offsets, edge_to_corner_indices);
977 auto mesh_check_island_boundary_uv = [&](
const int ,
979 const int edge_index,
983 const Span<int> edge_to_corners = edge_to_corner_map[corner_edges[corner]];
987 const int v1 = corner_verts[edge_to_corners[0]];
988 const int v2 = corner_verts[edge_to_corners[1]];
989 const float *uvco_v1 = luvs[edge_to_corners[0]];
990 const float *uvco_v2 = luvs[edge_to_corners[1]];
991 for (
int i = 2;
i < edge_to_corners.
size();
i += 2) {
992 if (corner_verts[edge_to_corners[
i]] == v1) {
1013 return uv_seams && uv_seams[edge_index];
1019 {corner_edges, corners_num},
1025 mesh_check_island_boundary_uv,
1029 &num_edge_boundaries);
1031 if (!num_face_groups) {
1032 if (num_edge_boundaries) {
1038 if (num_edge_boundaries) {
1047 for (grp_idx = 1; grp_idx <= num_face_groups; grp_idx++) {
1048 num_pidx = num_lidx = 0;
1049 if (num_edge_boundaries) {
1051 memset(edge_boundary_count, 0,
sizeof(*edge_boundary_count) *
size_t(totedge));
1055 if (face_groups[p_idx] != grp_idx) {
1058 face_indices[num_pidx++] = int(p_idx);
1060 const int edge_i = corner_edges[corner];
1061 loop_indices[num_lidx++] = int(corner);
1062 if (num_edge_boundaries &&
BLI_BITMAP_TEST(edge_boundaries, edge_i) &&
1063 (edge_boundary_count[edge_i] < 2))
1065 edge_boundary_count[edge_i]++;
1066 if (edge_boundary_count[edge_i] == 2) {
1067 edge_innercut_indices[num_einnercuts++] = edge_i;
1079 edge_innercut_indices);
1086 if (num_edge_boundaries) {
1090 if (num_edge_boundaries) {
1101 const bool *uv_seams,
1103 const int *corner_verts,
1104 const int *corner_edges,
1105 const int corners_num,
1110 totedge, uv_seams,
faces, corner_verts, corner_edges, corners_num,
nullptr, r_island_store);
1117 const bool *uv_seams,
1119 const int *corner_verts,
1120 const int *corner_edges,
1121 const int corners_num,
1122 const float (*luvs)[2],
1128 totedge, uv_seams,
faces, corner_verts, corner_edges, corners_num, luvs, r_island_store);
CustomData interface, see also DNA_customdata_types.h.
#define BLI_BITMAP_NEW(_num, _alloc_string)
#define BLI_BITMAP_TEST(_bitmap, _index)
#define BLI_BITMAP_ENABLE(_bitmap, _index)
#define BLI_buffer_reinit_data(buffer_, type_, new_count_)
#define BLI_buffer_declare_static(type_, name_, flag_, static_count_)
#define BLI_buffer_free(name_)
float cross_poly_v2(const float verts[][2], unsigned int nr)
MINLINE void copy_v2_v2(float r[2], const float a[2])
MINLINE bool equals_v2v2(const float v1[2], const float v2[2]) ATTR_WARN_UNUSED_RESULT
MINLINE void sub_v2_v2v2(float r[2], const float a[2], const float b[2])
#define BLI_MEMARENA_STD_BUFSIZE
MemArena * BLI_memarena_new(size_t bufsize, const char *name) ATTR_WARN_UNUSED_RESULT ATTR_RETURNS_NONNULL ATTR_NONNULL(2) ATTR_MALLOC
void BLI_memarena_free(MemArena *ma) ATTR_NONNULL(1)
void * BLI_memarena_alloc(MemArena *ma, size_t size) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1) ATTR_MALLOC ATTR_ALLOC_SIZE(2)
void BLI_memarena_clear(MemArena *ma) ATTR_NONNULL(1)
#define BLI_SCOPED_DEFER(function_to_defer)
#define UNUSED_VARS_NDEBUG(...)
Read Guarded memory(de)allocation.
Provides wrapper around system-specific atomic primitives, and some extensions (faked-atomic operatio...
ATTR_WARN_UNUSED_RESULT const BMVert * v2
ATTR_WARN_UNUSED_RESULT const BMVert * v
static DBVT_INLINE btScalar size(const btDbvtVolume &a)
constexpr int64_t size() const
Span< T > as_span() const
const T & last(const int64_t n=0) const
void reinitialize(const int64_t new_size)
constexpr int64_t size() const
Span< NewT > constexpr cast() const
constexpr const T * data() const
constexpr int64_t size() const
constexpr const T * end() const
constexpr IndexRange index_range() const
constexpr const T * begin() const
constexpr bool is_empty() const
IndexRange index_range() const
void * MEM_calloc_arrayN(size_t len, size_t size, const char *str)
void * MEM_callocN(size_t len, const char *str)
void * MEM_malloc_arrayN(size_t len, size_t size, const char *str)
void MEM_freeN(void *vmemh)
UvMapVert * BKE_mesh_uv_vert_map_get_vert(UvVertMap *vmap, uint v)
int * BKE_mesh_calc_smoothgroups_bitflags(int edges_num, int verts_num, const blender::OffsetIndices< int > faces, const blender::Span< int > corner_edges, const blender::Span< int > corner_verts, const blender::Span< bool > sharp_edges, const blender::Span< bool > sharp_faces, const bool use_boundary_vertices_for_bitflags, int *r_totgroup)
void BKE_mesh_origindex_map_create_corner_tri(MeshElemMap **r_map, int **r_mem, const blender::OffsetIndices< int > faces, const int *corner_tri_faces, const int corner_tris_num)
bool BKE_mesh_calc_islands_loop_face_edgeseam(const float(*vert_positions)[3], const int totvert, const blender::int2 *edges, const int totedge, const bool *uv_seams, const blender::OffsetIndices< int > faces, const int *corner_verts, const int *corner_edges, const int corners_num, MeshIslandStore *r_island_store)
void BKE_mesh_origindex_map_create(MeshElemMap **r_map, int **r_mem, const int totsource, const int *final_origindex, const int totfinal)
void BKE_mesh_loop_islands_add(MeshIslandStore *island_store, const int item_num, const int *items_indices, const int num_island_items, int *island_item_indices, const int num_innercut_items, int *innercut_item_indices)
int * BKE_mesh_calc_smoothgroups(int edges_num, const blender::OffsetIndices< int > faces, const blender::Span< int > corner_edges, const blender::Span< bool > sharp_edges, const blender::Span< bool > sharp_faces, int *r_totgroup)
static void face_edge_loop_islands_calc(const int totedge, const int totvert, const blender::OffsetIndices< int > faces, const blender::Span< int > corner_edges, const blender::Span< int > corner_verts, blender::GroupedSpan< int > edge_face_map, blender::GroupedSpan< int > vert_face_map, const bool use_bitflags, const bool use_boundary_vertices_for_bitflags, MeshRemap_CheckIslandBoundary edge_boundary_check, int **r_face_groups, int *r_totgroup, BLI_bitmap **r_edge_boundaries, int *r_totedgeboundaries)
void BKE_mesh_loop_islands_init(MeshIslandStore *island_store, const short item_type, const int items_num, const short island_type, const short innercut_type)
#define MISLAND_DEFAULT_BUFSIZE
void BKE_mesh_loop_islands_clear(MeshIslandStore *island_store)
blender::FunctionRef< bool(int face_index, int corner, int edge_index, int edge_user_count, const blender::Span< int > edge_face_map_elem)> MeshRemap_CheckIslandBoundary
bool BKE_mesh_calc_islands_loop_face_uvmap(float(*vert_positions)[3], const int totvert, blender::int2 *edges, const int totedge, const bool *uv_seams, const blender::OffsetIndices< int > faces, const int *corner_verts, const int *corner_edges, const int corners_num, const float(*luvs)[2], MeshIslandStore *r_island_store)
void BKE_mesh_uv_vert_map_free(UvVertMap *vmap)
void BKE_mesh_vert_corner_tri_map_create(MeshElemMap **r_map, int **r_mem, const int totvert, const blender::int3 *corner_tris, const int tris_num, const int *corner_verts, const int)
UvVertMap * BKE_mesh_uv_vert_map_create(const blender::OffsetIndices< int > faces, const bool *hide_poly, const bool *select_poly, const int *corner_verts, const float(*mloopuv)[2], uint totvert, const float limit[2], const bool selected, const bool use_winding)
static int * mesh_calc_smoothgroups(const int edges_num, const int verts_num, const blender::OffsetIndices< int > faces, const blender::Span< int > corner_edges, const blender::Span< int > corner_verts, const blender::Span< bool > sharp_edges, const blender::Span< bool > sharp_faces, int *r_totgroup, const bool use_bitflags, const bool use_boundary_vertices_for_bitflags)
void BKE_mesh_loop_islands_free(MeshIslandStore *island_store)
static void face_edge_loop_islands_calc_bitflags_exclude_at_boundary(const int *face_groups, const blender::Span< int > faces_from_item, const int face_group_id, const int face_group_id_overflowed, int &r_bit_face_group_mask)
static bool mesh_calc_islands_loop_face_uv(const int totedge, const bool *uv_seams, const blender::OffsetIndices< int > faces, const int *corner_verts, const int *corner_edges, const int corners_num, const float(*luvs)[2], MeshIslandStore *r_island_store)
void build_vert_to_face_indices(OffsetIndices< int > faces, Span< int > corner_verts, OffsetIndices< int > offsets, MutableSpan< int > face_indices)
GroupedSpan< int > build_vert_to_corner_map(Span< int > corner_verts, int verts_num, Array< int > &r_offsets, Array< int > &r_indices)
static Array< int > reverse_indices_in_groups(const Span< int > group_indices, const OffsetIndices< int > offsets)
GroupedSpan< int > build_edge_to_corner_map(Span< int > corner_edges, int edges_num, Array< int > &r_offsets, Array< int > &r_indices)
static Array< int > create_reverse_offsets(const Span< int > indices, const int items_num)
static GroupedSpan< int > gather_groups(const Span< int > group_indices, const int groups_num, Array< int > &r_offsets, Array< int > &r_indices)
static void sort_small_groups(const OffsetIndices< int > groups, const int grain_size, MutableSpan< int > indices)
int face_triangles_num(const int face_size)
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)
Array< int > build_corner_to_face_map(OffsetIndices< int > faces)
Array< int > build_vert_to_corner_indices(Span< int > corner_verts, OffsetIndices< int > offsets)
GroupedSpan< int > build_vert_to_face_map(OffsetIndices< int > faces, Span< int > corner_verts, int verts_num, Array< int > &r_offsets, Array< int > &r_indices)
static void reverse_group_indices_in_groups(const OffsetIndices< int > groups, const Span< int > group_to_elem, const OffsetIndices< int > offsets, MutableSpan< int > results)
GroupedSpan< int > build_vert_to_edge_map(Span< int2 > edges, int verts_num, Array< int > &r_offsets, Array< int > &r_indices)
void build_reverse_map(OffsetIndices< int > offsets, MutableSpan< int > r_map)
void build_reverse_offsets(Span< int > indices, MutableSpan< int > offsets)
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
VecBase< float, 2 > float2
VecBase< int32_t, 3 > int3
unsigned short loop_of_face_index