22 vertex->uv_edges.append_non_duplicates(&uv_edge);
29 uv_edge->uv_primitives.append_non_duplicates(&uv_primitive);
50 BLI_assert(
ELEM(v1, corner_verts[tri[0]], corner_verts[tri[1]], corner_verts[tri[2]]));
51 BLI_assert(
ELEM(
v2, corner_verts[tri[0]], corner_verts[tri[1]], corner_verts[tri[2]]));
52 for (
const int loop : {tri[0], tri[1], tri[2]}) {
53 const int vert = corner_verts[loop];
63 const int3 &tri_other)
65 int shared_uv_verts = 0;
66 for (
const int loop : {tri[0], tri[1], tri[2]}) {
67 for (
const int other_loop : {tri_other[0], tri_other[1], tri_other[2]}) {
68 if (uv_map[loop] == uv_map[other_loop]) {
73 return shared_uv_verts >= 2;
78 for (
const int loop : {tri[0], tri[1], tri[2]}) {
91 for (
const int loop : {tri[0], tri[1], tri[2]}) {
111 for (
int j = 0; j < 3; j++) {
119 edge_index = mesh_data.
edges.size();
120 *value = edge_index + 1;
121 mesh_data.
edges.append({v1,
v2});
125 edge_index = *value - 1;
129 edges.append(edge_index);
148 const int primitive_i,
153 if (primitive_i == other_primitive_i) {
164 prims_to_add.
append(other_primitive_i);
175 int uv_island_id = 0;
183 prims_to_add.
append(primitive_i);
185 const int other_primitive_i = prims_to_add.
pop_last();
207 corner_tris(corner_tris),
208 corner_verts(corner_verts),
210 vert_positions(vert_positions),
211 vert_to_edge_map(vert_positions.size()),
212 edge_to_primitive_map(0),
213 primitive_to_edge_map(corner_tris.size())
236 : vertex(mesh_data.corner_verts[loop]), uv(mesh_data.uv_map[loop])
249 for (
const UVPrimitive *uv_primitive : uv_edge->uv_primitives) {
253 return primitives_around_uv_vertex;
264 return (vertices[0]->uv == uv_map[loop_1] && vertices[1]->uv == uv_map[loop_2]) ||
265 (vertices[0]->uv == uv_map[loop_2] && vertices[1]->uv == uv_map[loop_1]);
270 return (vertices[0]->uv == v1.
uv && vertices[1]->uv ==
v2.uv) ||
271 (vertices[0]->uv ==
v2.uv && vertices[1]->uv == v1.
uv);
281 return (vertices[0]->vertex == vert1 && vertices[1]->vertex == vert2) ||
282 (vertices[0]->vertex == vert2 && vertices[1]->vertex == vert1);
285bool UVEdge::has_same_uv_vertices(
const UVEdge &other)
const
303 if (vertices[0]->vertex == vertex) {
316 const int vert_index = vertex.
vertex;
319 if (
v->uv == vertex.uv) {
329 if (found_vertex !=
nullptr) {
344 if (found_vertex ==
nullptr) {
349 if (other_vertex->
vertex == edge.vertices[1]->vertex &&
350 other_vertex->
uv == edge.vertices[1]->uv)
361 if (found_edge !=
nullptr) {
375 for (
int i = 0; i < 3; i++) {
382 new_prim_ptr->
edges[i]->uv_primitives.append(new_prim_ptr);
390 if (prim.has_shared_edge(primitive)) {
402 if (prim.has_shared_edge(mesh_data, primitive_i)) {
414 if (prim.has_shared_edge(primitive)) {
423 const int primitive_i)
430 const int2 &edge = mesh_data.
edges[edge_i];
431 const int loop_1 =
get_uv_loop(mesh_data, tri, edge[0]);
432 const int loop_2 =
get_uv_loop(mesh_data, tri, edge[1]);
437 uv_primitive_ptr->
edges.append(uv_edge);
441 return uv_primitive_ptr;
450 for (
UVEdge *edge : prim.edges) {
451 if (edge->is_border_edge()) {
460 if (!border.has_value()) {
463 if (!border->is_ccw()) {
464 border->flip_order();
466 borders.append(*border);
472 *r_angle = std::numeric_limits<float>::max();
473 std::optional<UVBorderCorner>
result;
475 const UVVertex *uv_vertex = edge.get_uv_vertex(0);
482 if (new_angle < *r_angle) {
483 *r_angle = new_angle;
492 std::optional<UVBorderCorner>
result;
493 float sharpest_angle = std::numeric_limits<float>::max();
497 if (new_angle < sharpest_angle) {
498 sharpest_angle = new_angle;
543 std::stringstream ss;
547 ss <<
" uv1:" <<
uvs[0];
548 ss <<
" uv2:" <<
uvs[1];
549 ss <<
" uv3:" <<
uvs[2];
554 std::cout << ss.str();
573 flags.is_manifold =
true;
576 int previous_primitive = stop_primitive;
583 if (other_primitive_i == previous_primitive) {
590 const int2 &edge = mesh_data.
edges[edge_i];
591 if (edge_i == current_edge || (edge[0] != vertex && edge[1] != vertex)) {
595 current_edge = edge_i;
596 previous_primitive = other_primitive_i;
602 flags.is_manifold =
false;
605 if (stop_primitive == previous_primitive) {
615 if (!fan_edge.flags.found) {
628 fan_edge.flags.found = mesh_primitive_indices.
contains(fan_edge.primitive_index);
635 int other_v = mesh_data.
corner_verts[fan_edge.tri[fan_edge.vert_order[0]]];
636 if (other_v == uv_vertex.
vertex) {
637 other_v = mesh_data.
corner_verts[fan_edge.tri[fan_edge.vert_order[1]]];
641 const UVVertex *other_uv_vertex = edge->get_other_uv_vertex(uv_vertex.
vertex);
643 if (other_v == other_edge_v) {
644 fan_edge.uvs[0] = uv_vertex.
uv;
645 fan_edge.uvs[1] = other_uv_vertex->
uv;
652 for (
int i = 0; i <
segments.size() - 1; i++) {
665 int v2 = mesh_data.
corner_verts[segment.tri[segment.vert_order[1]]];
666 if (vertex_index ==
v2) {
677 const int from_vertex,
680 int current_vert = from_vertex;
682 int v1 = mesh_data.
corner_verts[segment->tri[segment->vert_order[1]]];
683 int v2 = mesh_data.
corner_verts[segment->tri[segment->vert_order[2]]];
684 if (!
ELEM(current_vert, v1,
v2)) {
687 current_vert = v1 == current_vert ?
v2 : v1;
689 return current_vert == to_vertex;
700 const int from_vertex,
704 const int from_vert_order = 1;
705 const int to_vert_order = 2;
706 const int index_increment = reversed ? -1 : 1;
713 int v2 = mesh_data.
corner_verts[segment->tri[segment->vert_order[from_vert_order]]];
714 if (
v2 == from_vertex) {
717 index = (index + index_increment + edge_order.
size()) % edge_order.
size();
722 result.append(segment);
724 int v3 = mesh_data.
corner_verts[segment->tri[segment->vert_order[to_vert_order]]];
725 if (v3 == to_vertex) {
729 index = (index + index_increment + edge_order.
size()) % edge_order.
size();
745 if (!segment->flags.found) {
749 return solution.
size() - not_visited_steps;
753 const int from_vertex,
757 "Inconsistency detected, `from_vertex` isn't part of the outside of the fan.");
759 "Inconsistency detected, `to_vertex` isn't part of the outside of the fan.");
760 if (to_vertex == from_vertex) {
772 bool winding_1_valid =
is_path_valid(winding_1, mesh_data, from_vertex, to_vertex);
773 bool winding_2_valid =
is_path_valid(winding_2, mesh_data, from_vertex, to_vertex);
775 if (winding_1_valid && !winding_2_valid) {
778 if (!winding_1_valid && winding_2_valid) {
781 if (!winding_1_valid && !winding_2_valid) {
794 segment.print_debug(mesh_data);
805 const int mesh_primitive_i)
811 mesh_data, tri, connected_vert_1->
vertex, connected_vert_2->
vertex);
813 vert_template.
uv = uv_unconnected;
814 vert_template.
vertex = other_vert_i;
818 vert_template.
uv = connected_vert_1->
uv;
823 vert_template.
uv = connected_vert_2->
uv;
828 edge_template.
vertices[0] = vert_1_ptr;
829 edge_template.
vertices[1] = vert_2_ptr;
831 edge_template.
vertices[0] = vert_2_ptr;
832 edge_template.
vertices[1] = vert_ptr;
834 edge_template.
vertices[0] = vert_ptr;
835 edge_template.
vertices[1] = vert_1_ptr;
847 if (corner.first->get_uv_vertex(1) != corner.second->get_uv_vertex(0)) {
850 if (corner.first->get_uv_vertex(0) == corner.second->get_uv_vertex(1)) {
853 const UVVertex *shared_vert = corner.second->get_uv_vertex(0);
855 const int2 &edge = mesh_data.
edges[edge_i];
856 if (corner.first->edge->has_same_vertices(edge)) {
860 if (other_vert == corner.second->get_uv_vertex(1)->vertex) {
873 const int fill_primitive_i)
877 edge_template.
vertices[0] = &uv_vertex1;
878 edge_template.
vertices[1] = &uv_vertex2;
880 edge_template.
vertices[0] = &uv_vertex2;
881 edge_template.
vertices[1] = &uv_vertex3;
883 edge_template.
vertices[0] = &uv_vertex3;
884 edge_template.
vertices[1] = &uv_vertex1;
894 float min_uv_distance)
897 int border_index = corner.first->border_index;
899 if (!corner.connected_in_mesh()) {
903 UVVertex *uv_vertex = corner.second->get_uv_vertex(0);
916 mesh_data, corner.first->get_uv_vertex(0)->vertex, corner.second->get_uv_vertex(1)->vertex);
926 if (winding_solution.
size() < 2 && (num_to_add == 0 || corner.angle > 2.0f)) {
927 int fill_primitive_1_i = corner.second->uv_primitive->primitive_i;
928 int fill_primitive_2_i = corner.first->uv_primitive->primitive_i;
930 const int fill_primitive_i = winding_solution.
size() == 1 ?
931 winding_solution[0]->primitive_index :
934 if (fill_primitive_i != -1) {
935 fill_primitive_1_i = fill_primitive_i;
936 fill_primitive_2_i = fill_primitive_i;
939 float2 center_uv = corner.uv(0.5f, min_uv_distance);
942 corner.first->get_uv_vertex(1),
943 corner.first->get_uv_vertex(0),
949 corner.second->get_uv_vertex(0),
950 corner.second->get_uv_vertex(1),
960 corner.first->get_uv_vertex(0)->uv, center_uv);
967 corner.second->get_uv_vertex(1)->uv, center_uv);
972 UVEdge *current_edge = corner.first->edge;
975 num_to_add = winding_solution.
size();
981 float factor = (segment_index + 1.0f) / num_to_add;
982 float2 new_uv = corner.uv(factor, min_uv_distance);
984 FanSegment &segment = *winding_solution[segment_index];
986 const int fill_primitive_i = segment.primitive_index;
989 mesh_data, tri_fill, uv_vertex->
vertex, shared_edge_vertex);
993 uv_vertex_template.
uv = uv_vertex->
uv;
995 uv_vertex_template.
vertex = shared_edge_vertex;
996 uv_vertex_template.
uv = old_uv;
998 uv_vertex_template.
vertex = other_prim_vertex;
999 uv_vertex_template.
uv = new_uv;
1008 new_border_edges.
append(new_border);
1011 int border_insert = corner.first->index;
1012 border.
remove(border_insert);
1014 int border_next = corner.second->index;
1015 if (border_next < border_insert) {
1021 border.
remove(border_next);
1022 border.
edges.insert(border_insert, new_border_edges);
1032 for (
UVVertex &uv_vertex : uv_vertices) {
1033 uv_vertex.flags.is_border =
false;
1034 uv_vertex.flags.is_extended =
false;
1039 border_edge.edge->vertices[0]->flags.is_border =
true;
1040 border_edge.edge->vertices[1]->flags.is_border =
true;
1047 const short island_index)
1053 border.update_indexes(border_index++);
1057 if (!extension_corner.has_value()) {
1061 UVVertex *uv_vertex = extension_corner->second->get_uv_vertex(0);
1065 if (
tile &&
tile->is_masked(island_index, uv_vertex->
uv)) {
1067 mesh_data, *
this, *extension_corner,
tile->get_pixel_size_in_uv_space() * 2.0f);
1076 std::stringstream ss;
1077 ss <<
"#### Start UVIsland ####\n";
1078 ss <<
"import bpy\n";
1079 ss <<
"import bpy_extras.object_utils\n";
1080 ss <<
"import mathutils\n";
1082 ss <<
"uvisland_vertices = [\n";
1084 ss <<
" mathutils.Vector((" << vertex_position.x <<
", " << vertex_position.y <<
", "
1085 << vertex_position.z <<
")),\n";
1089 ss <<
"uvisland_edges = []\n";
1091 ss <<
"uvisland_faces = [\n";
1093 for (
const UVPrimitive &uvprimitive : uvprimitives) {
1094 ss <<
" [" << uvprimitive.edges[0]->vertices[0]->vertex <<
", "
1095 << uvprimitive.edges[0]->vertices[1]->vertex <<
", "
1097 .get_other_uv_vertex(uvprimitive.edges[0]->vertices[0],
1098 uvprimitive.edges[0]->vertices[1])
1105 ss <<
"uvisland_uvs = [\n";
1107 for (
const UVPrimitive &uvprimitive : uvprimitives) {
1108 float2 uv = uvprimitive.edges[0]->vertices[0]->uv;
1109 ss <<
" " << uv.x <<
", " << uv.y <<
",\n";
1110 uv = uvprimitive.edges[0]->vertices[1]->uv;
1111 ss <<
" " << uv.x <<
", " << uv.y <<
",\n";
1113 .get_other_uv_vertex(uvprimitive.edges[0]->vertices[0],
1114 uvprimitive.edges[0]->vertices[1])
1116 ss <<
" " << uv.x <<
", " << uv.y <<
",\n";
1121 ss <<
"uvisland_mesh = bpy.data.meshes.new(name='UVIsland')\n";
1122 ss <<
"uvisland_mesh.from_pydata(uvisland_vertices, uvisland_edges, uvisland_faces)\n";
1123 ss <<
"uv_map = uvisland_mesh.attributes.new('UVMap', 'FLOAT2', 'CORNER')\n";
1124 ss <<
"uv_map.data.foreach_set('vector', uvisland_uvs)\n";
1125 ss <<
"bpy_extras.object_utils.object_data_add(bpy.context, uvisland_mesh)\n";
1126 ss <<
"#### End UVIsland ####\n\n\n";
1128 std::cout << ss.str();
1142 if (edge.tag ==
false) {
1143 starting_border_edge = &edge;
1147 if (starting_border_edge ==
nullptr) {
1148 return std::nullopt;
1151 border.
edges.append(*starting_border_edge);
1152 starting_border_edge->
tag =
true;
1156 while (current_uv != first_uv) {
1158 if (border_edge.tag ==
true) {
1162 for (i = 0; i < 2; i++) {
1163 if (border_edge.edge->vertices[i]->uv == current_uv) {
1164 border_edge.reverse_order = i == 1;
1165 border_edge.tag =
true;
1166 current_uv = border_edge.get_uv_vertex(1)->uv;
1167 border.
edges.append(border_edge);
1182 const UVVertex *uv_vertex1 = edge.get_uv_vertex(0);
1183 const UVVertex *uv_vertex2 = edge.get_uv_vertex(1);
1184 const UVVertex *uv_vertex3 = edge.get_other_uv_vertex();
1195 uint64_t border_index = edges.first().border_index;
1197 edge.reverse_order = !edge.reverse_order;
1199 std::reverse(edges.begin(), edges.end());
1207 edge.get_uv_vertex(1)->uv - edge.get_uv_vertex(0)->uv);
1212 for (
int64_t i = 0; i < edges.size(); i++) {
1213 int64_t prev = (i - 1 + edges.size()) % edges.size();
1215 edges[i].prev_index = prev;
1217 edges[i].next_index =
next;
1218 edges[i].border_index = border_index;
1225 uint64_t border_index = edges[0].border_index;
1226 edges.remove(index);
1237 : first(first), second(second), angle(angle)
1245 float angle_between = angle * factor;
1263 std::stringstream ss;
1276 std::cout << ss.str();
1290 for (
int i = 0; i < 3; i++) {
1291 for (
int j = 0; j < 3; j++) {
1293 result.
append(std::pair<UVEdge *, UVEdge *>(edges[i], other.edges[j]));
1302 for (
int i = 0; i < 3; i++) {
1303 for (
int j = 0; j < 3; j++) {
1316 int loop_1 = tri[2];
1317 for (
int i = 0; i < 3; i++) {
1318 int loop_2 = tri[i];
1319 if (uv_edge->has_shared_edge(mesh_data.
uv_map, loop_1, loop_2)) {
1329 const uint8_t mesh_vert_index)
const
1332 const int mesh_vertex = mesh_data.
corner_verts[tri[mesh_vert_index]];
1334 for (
const UVVertex *uv_vert : uv_edge->vertices) {
1335 if (uv_vert->vertex == mesh_vertex) {
1347 const float2 &e1 = uv_edge->vertices[0]->uv;
1348 const float2 &e2 = uv_edge->vertices[1]->uv;
1349 if ((e1 == uv1 && e2 == uv2) || (e1 == uv2 && e2 == uv1)) {
1360 const int e1 = uv_edge->
vertices[0]->vertex;
1361 const int e2 = uv_edge->vertices[1]->vertex;
1362 if ((e1 == v1 && e2 ==
v2) || (e1 ==
v2 && e2 == v1)) {
1373 if (std::find(edge->vertices.begin(), edge->vertices.end(), uv_vertex) != edge->vertices.end())
1387 for (
const UVVertex *uv_vertex : edge->vertices) {
1388 if (!
ELEM(uv_vertex, v1,
v2)) {
1403 border_edges.
append(border_edge);
1414 : edge(edge), uv_primitive(uv_primitive)
1421 return edge->vertices[actual_index];
1427 return edge->vertices[actual_index];
1437 return len_v2v2(edge->vertices[0]->uv, edge->vertices[1]->uv);
1452 UVIsland *uv_island = &islands.last();
1453 uv_island->
id = uv_island_id;
1465 island.extract_borders();
1473 island.extend_border(mesh_data, islands_mask, index++);
1480 island.print_debug(mesh_data);
1496 : udim_offset(udim_offset),
1497 tile_resolution(tile_resolution),
1499 mask(mask_resolution.x * mask_resolution.y)
1506 const float2 tile_uv = uv - udim_offset;
1512 return min_ff(1.0f / tile_resolution.x, 1.0f / tile_resolution.y);
1521 for (
const UVPrimitive &uv_primitive : uv_primitives) {
1530 tile.mask_resolution.
x - 1);
1535 tile.mask_resolution.
y - 1);
1537 for (
int y = buffer_bounds.
ymin; y < buffer_bounds.
ymax + 1; y++) {
1538 for (
int x = buffer_bounds.
xmin; x < buffer_bounds.
xmax + 1; x++) {
1539 float2 uv(
float(x) /
tile.mask_resolution.
x,
float(y) /
tile.mask_resolution.
y);
1542 mesh_data.
uv_map[tri[1]],
1543 mesh_data.
uv_map[tri[2]],
1544 uv +
tile.udim_offset,
1551 tile.mask[offset] = island_index;
1561 for (
const int i : uv_islands.
islands.index_range()) {
1569 tiles.append_as(
Tile(udim_offset, resolution));
1574 bool changed =
false;
1579 if (prev_mask[offset] != 0xffff) {
1582 if (x != 0 && prev_mask[offset - 1] != 0xffff) {
1583 islands_mask.
mask[offset] = prev_mask[offset - 1];
1586 else if (x < islands_mask.
mask_resolution.x - 1 && prev_mask[offset + 1] != 0xffff) {
1587 islands_mask.
mask[offset] = prev_mask[offset + 1];
1597 bool changed =
false;
1602 if (prev_mask[offset] != 0xffff) {
1605 if (y != 0 && prev_mask[offset - islands_mask.
mask_resolution.x] != 0xffff) {
1623 while (index < max_iterations) {
1642 float2 local_uv = uv - udim_offset;
1643 if (local_uv.x < 0.0f || local_uv.y < 0.0f || local_uv.x >= 1.0f || local_uv.y >= 1.0f) {
1646 float2 pixel_pos_f = local_uv *
float2(mask_resolution.x, mask_resolution.y);
1648 uint64_t offset = pixel_pos.y * mask_resolution.x + pixel_pos.x;
1649 return mask[offset] == island_index;
1655 if (
tile.contains(uv)) {
1665 if (
tile ==
nullptr) {
1668 return tile->is_masked(island_index, uv);
#define BLI_assert_unreachable()
#define BLI_assert_msg(a, msg)
MINLINE float max_ff(float a, float b)
MINLINE int min_ii(int a, int b)
MINLINE float min_ff(float a, float b)
MINLINE int max_ii(int a, int b)
int barycentric_inside_triangle_v2(const float w[3])
void barycentric_weights_v2(const float v1[2], const float v2[2], const float v3[2], const float co[2], float w[3])
float cross_poly_v2(const float verts[][2], unsigned int nr)
MINLINE float len_v2v2(const float v1[2], const float v2[2]) ATTR_WARN_UNUSED_RESULT
MINLINE void copy_v2_v2(float r[2], const float a[2])
float angle_signed_v2v2(const float v1[2], const float v2[2]) ATTR_WARN_UNUSED_RESULT
void BLI_rctf_do_minmax_v(struct rctf *rect, const float xy[2])
void BLI_rctf_init_minmax(struct rctf *rect)
#define IN_RANGE(a, b, c)
ATTR_WARN_UNUSED_RESULT const BMVert * v2
ATTR_WARN_UNUSED_RESULT const BMVert const BMEdge * e
ATTR_WARN_UNUSED_RESULT const BMVert * v
SIMD_FORCE_INLINE btVector3 & normalize()
Normalize this vector x^2 + y^2 + z^2 = 1.
void fill(const T &value) const
void reinitialize(const int64_t new_size)
auto add_or_modify(const Key &key, const CreateValueF &create_value, const ModifyValueF &modify_value) -> decltype(create_value(nullptr))
constexpr int64_t size() const
constexpr IndexRange index_range() const
bool contains(const T &value) const
void append(const T &value)
IndexRange index_range() const
void reserve(const int64_t min_capacity)
void append_non_duplicates(const T &value)
void add(const int primitive_i, const int edge_i)
void add(const Span< int > edges, const int tri_i)
void add(const int edge_i, const int v1, const int v2)
ccl_global const KernelWorkTile * tile
ccl_device_inline float2 floor(const float2 a)
ccl_device_inline float3 ceil(const float3 a)
static Vector< int > connecting_mesh_primitive_indices(const UVVertex &uv_vertex)
static int get_uv_loop(const MeshData &mesh_data, const int3 &tri, const int vert)
static void uv_primitive_append_to_uv_edges(UVPrimitive &uv_primitive)
static void dilate_tile(UVIslandsMask::Tile &tile, int max_iterations)
static void add_uv_island(const MeshData &mesh_data, UVIslandsMask::Tile &tile, const UVIsland &uv_island, int16_t island_index)
static bool dilate_x(UVIslandsMask::Tile &islands_mask)
static void uv_vertex_init_flags(UVVertex &uv_vertex)
static rctf primitive_uv_bounds(const int3 &tri, const Span< float2 > uv_map)
static void reset_extendability_flags(UVIsland &island)
static int find_fill_primitive(const MeshData &mesh_data, UVBorderCorner &corner)
static void uv_edge_append_to_uv_vertices(UVEdge &uv_edge)
static bool dilate_y(UVIslandsMask::Tile &islands_mask)
static std::optional< UVBorderCorner > sharpest_border_corner(UVBorder &border, float *r_angle)
static ushort2 mask_resolution_from_tile_resolution(ushort2 tile_resolution)
static void add_uv_primitive_fill(UVIsland &island, UVVertex &uv_vertex1, UVVertex &uv_vertex2, UVVertex &uv_vertex3, const int fill_primitive_i)
static void uv_primitive_append_to_uv_vertices(UVPrimitive &uv_primitive)
static int mesh_data_init_primitive_uv_island_ids(MeshData &mesh_data)
static constexpr int INVALID_UV_ISLAND_ID
static void add_uv_primitive_shared_uv_edge(const MeshData &mesh_data, UVIsland &island, UVVertex *connected_vert_1, UVVertex *connected_vert_2, float2 uv_unconnected, const int mesh_primitive_i)
static void extract_uv_neighbors(const MeshData &mesh_data, const Span< int > uv_island_ids, const int primitive_i, Vector< int > &prims_to_add)
static void extend_at_vert(const MeshData &mesh_data, UVIsland &island, UVBorderCorner &corner, float min_uv_distance)
static void mesh_data_init(MeshData &mesh_data)
static UVPrimitive * add_primitive(const MeshData &mesh_data, UVIsland &uv_island, const int primitive_i)
static int primitive_get_other_uv_vertex(const MeshData &mesh_data, const int3 &tri, const int v1, const int v2)
static bool primitive_has_shared_uv_edge(const Span< float2 > uv_map, const int3 &tri, const int3 &tri_other)
static void mesh_data_init_edges(MeshData &mesh_data)
VecBase< float, 2 > float2
VecBase< uint16_t, 2 > ushort2
unsigned __int64 uint64_t
FanSegment(const MeshData &mesh_data, const int primitive_index, const int3 tri, int vertex)
struct blender::bke::pbvh::uv_islands::FanSegment::@94 flags
void print_debug(const MeshData &mesh_data) const
Vector< FanSegment * > best_path_between(const MeshData &mesh_data, const int from_vertex, const int to_vertex)
void print_debug(const MeshData &mesh_data) const
struct blender::bke::pbvh::uv_islands::Fan::@95 flags
void mark_already_added_segments(const UVVertex &uv_vertex)
Vector< FanSegment > segments
void init_uv_coordinates(const MeshData &mesh_data, UVVertex &uv_vertex)
bool contains_vertex_on_outside(const MeshData &mesh_data, const int vertex_index) const
int count_edges_not_added() const
static int64_t score(const Span< FanSegment * > solution)
static Vector< FanSegment * > path_between(const Span< FanSegment * > edge_order, const MeshData &mesh_data, const int from_vertex, const int to_vertex, const bool reversed)
static bool is_path_valid(const Span< FanSegment * > path, const MeshData &mesh_data, const int from_vertex, const int to_vertex)
Fan(const MeshData &mesh_data, const int vertex)
VertToEdgeMap vert_to_edge_map
TriangleToEdgeMap primitive_to_edge_map
Span< float3 > vert_positions
EdgeToPrimitiveMap edge_to_primitive_map
Array< int > uv_island_ids
MeshData(OffsetIndices< int > faces, Span< int3 > corner_tris, Span< int > corner_verts, Span< float2 > uv_map, Span< float3 > vert_positions)
bool connected_in_mesh() const
float2 uv(float factor, float min_uv_distance)
UVBorderCorner(UVBorderEdge *first, UVBorderEdge *second, float angle)
UVBorderEdge(UVEdge *edge, UVPrimitive *uv_primitive)
UVPrimitive * uv_primitive
UVVertex * get_uv_vertex(int index)
const UVVertex * get_other_uv_vertex() const
float outside_angle(const UVBorderEdge &edge) const
static std::optional< UVBorder > extract_from_edges(Vector< UVBorderEdge > &edges)
void update_indexes(uint64_t border_index)
void remove(int64_t index)
Vector< UVBorderEdge > edges
bool is_border_edge() const
Vector< UVPrimitive *, 2 > uv_primitives
bool has_same_vertices(const int2 &edge) const
bool has_shared_edge(Span< float2 > uv_map, const int loop_1, const int loop_2) const
std::array< UVVertex *, 2 > vertices
UVVertex * get_other_uv_vertex(const int vertex_index)
VectorList< UVPrimitive > uv_primitives
Vector< UVBorder > borders
VectorList< UVVertex > uv_vertices
Map< int64_t, Vector< UVVertex * > > uv_vertex_lookup
void print_debug(const MeshData &mesh_data) const
bool has_shared_edge(const UVPrimitive &primitive) const
void extend_border(const MeshData &mesh_data, const UVIslandsMask &mask, const short island_index)
VectorList< UVEdge > uv_edges
UVVertex * lookup_or_create(const UVVertex &vertex)
UVVertex * lookup(const UVVertex &vertex)
Tile(float2 udim_offset, ushort2 tile_resolution)
bool is_masked(const uint16_t island_index, const float2 uv) const
bool contains(const float2 uv) const
float get_pixel_size_in_uv_space() const
void dilate(int max_iterations)
void add(const MeshData &mesh_data, const UVIslands &islands)
const Tile * find_tile(const float2 uv) const
bool is_masked(const uint16_t island_index, const float2 uv) const
void add_tile(float2 udim_offset, ushort2 resolution)
UVIslands(const MeshData &mesh_data)
void extend_borders(const MeshData &mesh_data, const UVIslandsMask &islands_mask)
Vector< UVIsland > islands
void print_debug(const MeshData &mesh_data) const
Vector< std::pair< UVEdge *, UVEdge * > > shared_edges(UVPrimitive &other)
UVPrimitive(const int primitive_i)
UVEdge * get_uv_edge(const float2 uv1, const float2 uv2) const
bool has_shared_edge(const UVPrimitive &other) const
Vector< UVEdge *, 3 > edges
UVBorder extract_border() const
const UVVertex * get_other_uv_vertex(const UVVertex *v1, const UVVertex *v2) const
bool contains_uv_vertex(const UVVertex *uv_vertex) const
const UVVertex * get_uv_vertex(const MeshData &mesh_data, const uint8_t mesh_vert_index) const
Vector< UVEdge * > uv_edges
struct blender::bke::pbvh::uv_islands::UVVertex::@96 flags