23 vertex->
uv_edges.append_non_duplicates(&uv_edge);
51 BLI_assert(
ELEM(v1, corner_verts[tri[0]], corner_verts[tri[1]], corner_verts[tri[2]]));
52 BLI_assert(
ELEM(
v2, corner_verts[tri[0]], corner_verts[tri[1]], corner_verts[tri[2]]));
53 for (
const int loop : {tri[0], tri[1], tri[2]}) {
54 const int vert = corner_verts[loop];
64 const int3 &tri_other)
66 int shared_uv_verts = 0;
67 for (
const int loop : {tri[0], tri[1], tri[2]}) {
68 for (
const int other_loop : {tri_other[0], tri_other[1], tri_other[2]}) {
69 if (uv_map[loop] == uv_map[other_loop]) {
74 return shared_uv_verts >= 2;
79 for (
const int loop : {tri[0], tri[1], tri[2]}) {
92 for (
const int loop : {tri[0], tri[1], tri[2]}) {
112 for (
int j = 0; j < 3; j++) {
120 edge_index = mesh_data.
edges.size();
121 *value = edge_index + 1;
122 mesh_data.
edges.append({v1,
v2});
126 edge_index = *value - 1;
136 for (
const int prim_i : mesh_data.
corner_tris.index_range()) {
149 const int primitive_i,
154 if (primitive_i == other_primitive_i) {
165 prims_to_add.
append(other_primitive_i);
176 int uv_island_id = 0;
178 for (
const int primitive_i : mesh_data.
corner_tris.index_range()) {
184 prims_to_add.
append(primitive_i);
186 const int other_primitive_i = prims_to_add.
pop_last();
237 :
vertex(mesh_data.corner_verts[loop]),
uv(mesh_data.uv_map[loop])
254 return primitives_around_uv_vertex;
265 return (
vertices[0]->uv == uv_map[loop_1] &&
vertices[1]->uv == uv_map[loop_2]) ||
286bool UVEdge::has_same_uv_vertices(
const UVEdge &other)
const
304 if (
vertices[0]->vertex == vertex) {
317 const int vert_index = vertex.
vertex;
320 if (
v->uv == vertex.
uv) {
330 if (found_vertex !=
nullptr) {
345 if (found_vertex ==
nullptr) {
362 if (found_edge !=
nullptr) {
368 result->uv_primitive_indices.clear();
376 for (
int i = 0;
i < 3;
i++) {
390 if (prim.has_shared_edge(primitive)) {
400 if (prim.has_shared_edge(mesh_data, primitive_i)) {
410 if (prim.has_shared_edge(primitive)) {
411 this->append(primitive);
418 const int primitive_i)
425 const int2 &edge = mesh_data.
edges[edge_i];
426 const int loop_1 =
get_uv_loop(mesh_data, tri, edge[0]);
427 const int loop_2 =
get_uv_loop(mesh_data, tri, edge[1]);
432 uv_primitive_ptr->
edges.append(uv_edge);
436 return uv_primitive_ptr;
444 for (
UVEdge *edge : prim.edges) {
453 if (!border.has_value()) {
456 if (!border->is_ccw()) {
457 border->flip_order();
465 *r_angle = std::numeric_limits<float>::max();
466 std::optional<UVBorderCorner>
result;
475 if (new_angle < *r_angle) {
476 *r_angle = new_angle;
485 std::optional<UVBorderCorner>
result;
486 float sharpest_angle = std::numeric_limits<float>::max();
490 if (new_angle < sharpest_angle) {
491 sharpest_angle = new_angle;
527 BLI_assert(mesh_data.corner_verts[tri[0]] == vertex);
536 std::stringstream ss;
540 ss <<
" uv1:" <<
uvs[0];
541 ss <<
" uv2:" <<
uvs[1];
542 ss <<
" uv3:" <<
uvs[2];
547 std::cout << ss.str();
566 flags.is_manifold =
true;
569 int previous_primitive = stop_primitive;
576 if (other_primitive_i == previous_primitive) {
583 const int2 &edge = mesh_data.
edges[edge_i];
584 if (edge_i == current_edge || (edge[0] != vertex && edge[1] != vertex)) {
588 current_edge = edge_i;
589 previous_primitive = other_primitive_i;
595 flags.is_manifold =
false;
598 if (stop_primitive == previous_primitive) {
608 if (!fan_edge.flags.found) {
621 fan_edge.flags.found = mesh_primitive_indices.
contains(fan_edge.primitive_index);
628 int other_v = mesh_data.
corner_verts[fan_edge.tri[fan_edge.vert_order[0]]];
629 if (other_v == uv_vertex.
vertex) {
630 other_v = mesh_data.
corner_verts[fan_edge.tri[fan_edge.vert_order[1]]];
636 if (other_v == other_edge_v) {
637 fan_edge.uvs[0] = uv_vertex.
uv;
638 fan_edge.uvs[1] = other_uv_vertex->
uv;
658 int v2 = mesh_data.
corner_verts[segment.tri[segment.vert_order[1]]];
659 if (vertex_index ==
v2) {
670 const int from_vertex,
673 int current_vert = from_vertex;
675 int v1 = mesh_data.
corner_verts[segment->tri[segment->vert_order[1]]];
676 int v2 = mesh_data.
corner_verts[segment->tri[segment->vert_order[2]]];
677 if (!
ELEM(current_vert, v1,
v2)) {
680 current_vert = v1 == current_vert ?
v2 : v1;
682 return current_vert == to_vertex;
693 const int from_vertex,
697 const int from_vert_order = 1;
698 const int to_vert_order = 2;
699 const int index_increment = reversed ? -1 : 1;
706 int v2 = mesh_data.
corner_verts[segment->tri[segment->vert_order[from_vert_order]]];
707 if (
v2 == from_vertex) {
710 index = (index + index_increment + edge_order.
size()) % edge_order.
size();
717 int v3 = mesh_data.
corner_verts[segment->tri[segment->vert_order[to_vert_order]]];
718 if (v3 == to_vertex) {
722 index = (index + index_increment + edge_order.
size()) % edge_order.
size();
738 if (!segment->flags.found) {
742 return solution.
size() - not_visited_steps;
746 const int from_vertex,
750 "Inconsistency detected, `from_vertex` isn't part of the outside of the fan.");
752 "Inconsistency detected, `to_vertex` isn't part of the outside of the fan.");
753 if (to_vertex == from_vertex) {
765 bool winding_1_valid =
is_path_valid(winding_1, mesh_data, from_vertex, to_vertex);
766 bool winding_2_valid =
is_path_valid(winding_2, mesh_data, from_vertex, to_vertex);
768 if (winding_1_valid && !winding_2_valid) {
771 if (!winding_1_valid && winding_2_valid) {
774 if (!winding_1_valid && !winding_2_valid) {
787 segment.print_debug(mesh_data);
798 const int mesh_primitive_i)
804 mesh_data, tri, connected_vert_1->
vertex, connected_vert_2->
vertex);
806 vert_template.
uv = uv_unconnected;
807 vert_template.
vertex = other_vert_i;
811 vert_template.
uv = connected_vert_1->
uv;
816 vert_template.
uv = connected_vert_2->
uv;
821 edge_template.
vertices[0] = vert_1_ptr;
822 edge_template.
vertices[1] = vert_2_ptr;
824 edge_template.
vertices[0] = vert_2_ptr;
825 edge_template.
vertices[1] = vert_ptr;
827 edge_template.
vertices[0] = vert_ptr;
828 edge_template.
vertices[1] = vert_1_ptr;
848 const int2 &edge = mesh_data.
edges[edge_i];
866 const int fill_primitive_i)
870 edge_template.
vertices[0] = &uv_vertex1;
871 edge_template.
vertices[1] = &uv_vertex2;
873 edge_template.
vertices[0] = &uv_vertex2;
874 edge_template.
vertices[1] = &uv_vertex3;
876 edge_template.
vertices[0] = &uv_vertex3;
877 edge_template.
vertices[1] = &uv_vertex1;
887 float min_uv_distance)
919 if (winding_solution.
size() < 2 && (num_to_add == 0 || corner.
angle > 2.0f)) {
923 const int fill_primitive_i = winding_solution.
size() == 1 ?
924 winding_solution[0]->primitive_index :
927 if (fill_primitive_i != -1) {
928 fill_primitive_1_i = fill_primitive_i;
929 fill_primitive_2_i = fill_primitive_i;
932 float2 center_uv = corner.
uv(0.5f, min_uv_distance);
968 num_to_add = winding_solution.
size();
974 float factor = (segment_index + 1.0f) / num_to_add;
975 float2 new_uv = corner.
uv(factor, min_uv_distance);
977 FanSegment &segment = *winding_solution[segment_index];
979 const int fill_primitive_i = segment.primitive_index;
982 mesh_data, tri_fill, uv_vertex->
vertex, shared_edge_vertex);
986 uv_vertex_template.
uv = uv_vertex->
uv;
988 uv_vertex_template.
vertex = shared_edge_vertex;
989 uv_vertex_template.
uv = old_uv;
991 uv_vertex_template.
vertex = other_prim_vertex;
992 uv_vertex_template.
uv = new_uv;
1001 new_border_edges.
append(new_border);
1005 border.
remove(border_insert);
1008 if (border_next < border_insert) {
1014 border.
remove(border_next);
1015 border.
edges.insert(border_insert, new_border_edges);
1038 const short island_index)
1044 border.update_indexes(border_index++);
1048 if (!extension_corner.has_value()) {
1052 UVVertex *uv_vertex = extension_corner->second->get_uv_vertex(0);
1056 if (
tile &&
tile->is_masked(island_index, uv_vertex->
uv)) {
1058 mesh_data, *
this, *extension_corner,
tile->get_pixel_size_in_uv_space() * 2.0f);
1067 std::stringstream ss;
1068 ss <<
"#### Start UVIsland ####\n";
1069 ss <<
"import bpy\n";
1070 ss <<
"import bpy_extras.object_utils\n";
1071 ss <<
"import mathutils\n";
1073 ss <<
"uvisland_vertices = [\n";
1075 ss <<
" mathutils.Vector((" << vertex_position.x <<
", " << vertex_position.y <<
", "
1076 << vertex_position.z <<
")),\n";
1080 ss <<
"uvisland_edges = []\n";
1082 ss <<
"uvisland_faces = [\n";
1084 ss <<
" [" << uvprimitive.edges[0]->vertices[0]->vertex <<
", "
1085 << uvprimitive.edges[0]->vertices[1]->vertex <<
", "
1087 .get_other_uv_vertex(uvprimitive.edges[0]->vertices[0],
1088 uvprimitive.edges[0]->vertices[1])
1094 ss <<
"uvisland_uvs = [\n";
1096 float2 uv = uvprimitive.edges[0]->vertices[0]->uv;
1097 ss <<
" " << uv.x <<
", " << uv.y <<
",\n";
1098 uv = uvprimitive.edges[0]->vertices[1]->uv;
1099 ss <<
" " << uv.x <<
", " << uv.y <<
",\n";
1101 .get_other_uv_vertex(uvprimitive.edges[0]->vertices[0],
1102 uvprimitive.edges[0]->vertices[1])
1104 ss <<
" " << uv.x <<
", " << uv.y <<
",\n";
1108 ss <<
"uvisland_mesh = bpy.data.meshes.new(name='UVIsland')\n";
1109 ss <<
"uvisland_mesh.from_pydata(uvisland_vertices, uvisland_edges, uvisland_faces)\n";
1110 ss <<
"uv_map = uvisland_mesh.attributes.new('UVMap', 'FLOAT2', 'CORNER')\n";
1111 ss <<
"uv_map.data.foreach_set('vector', uvisland_uvs)\n";
1112 ss <<
"bpy_extras.object_utils.object_data_add(bpy.context, uvisland_mesh)\n";
1113 ss <<
"#### End UVIsland ####\n\n\n";
1115 std::cout << ss.str();
1129 if (edge.tag ==
false) {
1130 starting_border_edge = &edge;
1134 if (starting_border_edge ==
nullptr) {
1135 return std::nullopt;
1138 border.
edges.append(*starting_border_edge);
1139 starting_border_edge->
tag =
true;
1143 while (current_uv != first_uv) {
1145 if (border_edge.tag ==
true) {
1149 for (
i = 0;
i < 2;
i++) {
1150 if (border_edge.edge->vertices[
i]->uv == current_uv) {
1151 border_edge.reverse_order =
i == 1;
1152 border_edge.tag =
true;
1153 current_uv = border_edge.get_uv_vertex(1)->uv;
1154 border.
edges.append(border_edge);
1184 edge.reverse_order = !edge.reverse_order;
1202 edges[
i].prev_index = prev;
1205 edges[
i].border_index = border_index;
1213 edges.remove(index);
1233 float desired_len =
max_ff(
second->length() * factor +
first->length() * (1.0 - factor),
1245 return first->get_uv_vertex(1) ==
second->get_uv_vertex(0);
1250 std::stringstream ss;
1253 ss <<
first->get_uv_vertex(0)->vertex <<
"-";
1254 ss <<
first->get_uv_vertex(1)->vertex <<
"-";
1255 ss <<
second->get_uv_vertex(1)->vertex <<
"\n";
1258 ss <<
first->get_uv_vertex(0)->vertex <<
"-";
1259 ss <<
first->get_uv_vertex(1)->vertex <<
", ";
1260 ss <<
second->get_uv_vertex(0)->vertex <<
"-";
1261 ss <<
second->get_uv_vertex(1)->vertex <<
"\n";
1263 std::cout << ss.str();
1277 for (
int i = 0;
i < 3;
i++) {
1278 for (
int j = 0; j < 3; j++) {
1289 for (
int i = 0;
i < 3;
i++) {
1290 for (
int j = 0; j < 3; j++) {
1303 int loop_1 = tri[2];
1304 for (
int i = 0;
i < 3;
i++) {
1305 int loop_2 = tri[
i];
1306 if (uv_edge->has_shared_edge(mesh_data.
uv_map, loop_1, loop_2)) {
1316 const uint8_t mesh_vert_index)
const
1319 const int mesh_vertex = mesh_data.
corner_verts[tri[mesh_vert_index]];
1321 for (
const UVVertex *uv_vert : uv_edge->vertices) {
1322 if (uv_vert->
vertex == mesh_vertex) {
1334 const float2 &e1 = uv_edge->vertices[0]->uv;
1335 const float2 &e2 = uv_edge->vertices[1]->uv;
1336 if ((e1 == uv1 && e2 == uv2) || (e1 == uv2 && e2 == uv1)) {
1347 const int e1 = uv_edge->vertices[0]->vertex;
1348 const int e2 = uv_edge->vertices[1]->vertex;
1349 if ((e1 == v1 && e2 ==
v2) || (e1 ==
v2 && e2 == v1)) {
1360 if (std::find(edge->vertices.begin(), edge->vertices.end(), uv_vertex) != edge->vertices.end())
1374 for (
const UVVertex *uv_vertex : edge->vertices) {
1375 if (!
ELEM(uv_vertex, v1,
v2)) {
1390 border_edges.
append(border_edge);
1408 return edge->vertices[actual_index];
1414 return edge->vertices[actual_index];
1440 uv_island->
id = uv_island_id;
1441 for (
const int primitive_i : mesh_data.
corner_tris.index_range()) {
1452 island.extract_borders();
1460 island.extend_border(mesh_data, islands_mask, index++);
1467 island.print_debug(mesh_data);
1505 int16_t island_index)
1516 tile.mask_resolution.x - 1);
1521 tile.mask_resolution.y - 1);
1523 for (
int y = buffer_bounds.
ymin;
y < buffer_bounds.
ymax + 1;
y++) {
1524 for (
int x = buffer_bounds.
xmin;
x < buffer_bounds.
xmax + 1;
x++) {
1525 float2 uv(
float(
x) /
tile.mask_resolution.x,
float(
y) /
tile.mask_resolution.y);
1528 mesh_data.
uv_map[tri[1]],
1529 mesh_data.
uv_map[tri[2]],
1530 uv +
tile.udim_offset,
1537 tile.mask[offset] = island_index;
1546 for (
const int i :
uv_islands.islands.index_range()) {
1554 tiles.append_as(
Tile(udim_offset, resolution));
1559 bool changed =
false;
1564 if (prev_mask[offset] != 0xffff) {
1567 if (
x != 0 && prev_mask[offset - 1] != 0xffff) {
1568 islands_mask.
mask[offset] = prev_mask[offset - 1];
1571 else if (
x < islands_mask.
mask_resolution.x - 1 && prev_mask[offset + 1] != 0xffff) {
1572 islands_mask.
mask[offset] = prev_mask[offset + 1];
1582 bool changed =
false;
1587 if (prev_mask[offset] != 0xffff) {
1590 if (
y != 0 && prev_mask[offset - islands_mask.
mask_resolution.x] != 0xffff) {
1608 while (index < max_iterations) {
1628 if (local_uv.x < 0.0f || local_uv.y < 0.0f || local_uv.x >= 1.0f || local_uv.y >= 1.0f) {
1634 return mask[offset] == island_index;
1640 if (
tile.contains(uv)) {
1650 if (
tile ==
nullptr) {
1653 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
unsigned long long int uint64_t
static DBVT_INLINE btScalar size(const btDbvtVolume &a)
void fill(const T &value) const
void reinitialize(const int64_t new_size)
void append(const T &value)
void append_non_duplicates(const T &value)
auto add_or_modify(const Key &key, const CreateValueF &create_value, const ModifyValueF &modify_value) -> decltype(create_value(nullptr))
constexpr int64_t size() const
bool contains(const T &value) const
void append(const T &value)
IndexRange index_range() const
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)
VecBase< float, D > normalize(VecOp< float, D >) RET
const ccl_global KernelWorkTile * tile
ccl_device_inline float2 mask(const MaskType mask, const float2 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)
AngleRadianBase< float > AngleRadian
AngleRadianBase< T > angle_between(const QuaternionBase< T > &a, const QuaternionBase< T > &b)
MatT from_rotation(const RotationT &rotation)
MatBase< float, 2, 2 > float2x2
VecBase< int32_t, 2 > int2
VecBase< float, 2 > float2
VecBase< int32_t, 3 > int3
VecBase< uint16_t, 2 > ushort2
VecBase< float, 3 > float3
FanSegment(const MeshData &mesh_data, const int primitive_index, const int3 tri, int vertex)
struct blender::bke::pbvh::uv_islands::FanSegment::@356056377220164103252025316204071224237371166074 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
void mark_already_added_segments(const UVVertex &uv_vertex)
struct blender::bke::pbvh::uv_islands::Fan::@053100026027005360023052335102030132303115051347 flags
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
OffsetIndices< int > faces
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
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)
Vector< int, 2 > uv_primitive_indices
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
struct blender::bke::pbvh::uv_islands::UVVertex::@146070211233272321030042025306175335142241112375 flags
Vector< UVEdge * > uv_edges