49#include "RNA_prototypes.hh"
215#define STITCH_NO_PREVIEW -1
255 return stitch_preview;
261 if (stitch_preview) {
278 "(L)imit %.2f (Alt Wheel adjust) %s, "
280 "shift select vertices");
299 const float medianPoint[2],
303 float uv_rotation_result[2];
323 if (element_iter == element) {
337 if (
fabsf(luv[0] - luv_iter[0]) < limit &&
fabsf(luv[1] - luv_iter[1]) < limit) {
353 if (edge_iter == edge) {
366 if (
fabsf(luv_orig1[0] - luv_iter1[0]) < limit &&
fabsf(luv_orig1[1] - luv_iter1[1]) < limit &&
367 fabsf(luv_orig2[0] - luv_iter2[0]) < limit &&
fabsf(luv_orig2[1] - luv_iter2[1]) < limit)
415 for (
int i = 0; i <
state->element_map->total_islands; i++) {
416 if (island_stitch_data[i].addedForPreview) {
417 int numOfIslandUVs = 0, j;
421 float rotation_mat[2][2];
424 if (island_stitch_data[i].num_rot_elements > 1) {
428 if (island_stitch_data[i].num_rot_elements_neg > 1) {
432 if (island_stitch_data[i].numOfElements > 1) {
441 if ((island_stitch_data[i].rotation + island_stitch_data[i].rotation_neg <
float(
M_PI_2)) ||
442 island_stitch_data[i].num_rot_elements == 0 ||
443 island_stitch_data[i].num_rot_elements_neg == 0)
453 island_stitch_data[i].num_rot_elements_neg) /
458 numOfIslandUVs =
state->element_map->island_total_uvs[i];
459 element = &
state->element_map->storage[
state->element_map->island_indices[i]];
460 for (j = 0; j < numOfIslandUVs; j++, element++) {
472 add_v2_v2(luv, island_stitch_data[i].translation);
477 int face_preview_pos =
481 island_stitch_data[i].medianPoint,
483 2 * element->loop_of_face_index,
502 const uint *uvfinal_map,
506 float uv1[2], uv2[2];
507 float edgecos, edgesin;
511 element1 =
state->uvs[edge->uv1];
512 element2 =
state->uvs[edge->uv2];
518 index1 = uvfinal_map[element1 -
state->element_map->storage];
519 index2 = uvfinal_map[element2 -
state->element_map->storage];
528 uv1[0] = luv2[0] - luv1[0];
529 uv1[1] = luv2[1] - luv1[1];
531 uv1[1] /=
state->aspect;
533 uv2[0] = uv_average[index2].
uv[0] - uv_average[index1].
uv[0];
534 uv2[1] = uv_average[index2].
uv[1] - uv_average[index1].
uv[1];
536 uv2[1] /=
state->aspect;
545 if (edgesin > 0.0f) {
561 float rotation = 0, rotation_neg = 0;
562 int rot_elem = 0, rot_elem_neg = 0;
569 for (; element_iter; element_iter = element_iter->
next) {
580 int index_tmp1 = element_iter -
state->element_map->storage;
581 index_tmp1 =
state->map[index_tmp1];
582 int index_tmp2 = element -
state->element_map->storage;
583 index_tmp2 =
state->map[index_tmp2];
586 float edgecos =
dot_v2v2(normal,
state->normals + index_tmp1 * 2);
588 if (edgesin > 0.0f) {
601 rotation_neg /= 2.0f;
604 island_stitch_data[element->island].
rotation += rotation;
606 island_stitch_data[element->island].
rotation_neg += rotation_neg;
612 if (
state->island_is_stitchable) {
615 if (
state->element_map) {
621 if (
state->selection_stack) {
624 if (
state->tris_per_island) {
630 if (
state->normals) {
637 state->stitch_preview =
nullptr;
638 if (
state->edge_hash) {
660 const int *map =
state->map;
662 for (
int i = 0; i <
state->total_separate_edges; i++) {
681 for (; iter1; iter1 = iter1->
next) {
693 int index1 = map[iter1 - element_map->
storage];
694 int index2 = map[iter2 - element_map->
storage];
700 if (index1 > index2) {
701 std::swap(index1, index2);
704 edgetmp.
uv1 = index1;
705 edgetmp.
uv2 = index2;
711 for (eiter = edge; eiter; eiter = eiter->
next) {
712 if (edge2 == eiter) {
721 last_set->
next = edge2;
745 for (; element_iter; element_iter = element_iter->
next) {
764 for (; edge_iter; edge_iter = edge_iter->
next) {
807 element = element->next;
808 }
while (element && !element->separate);
828 for (; element_iter; element_iter = element_iter->
next) {
830 if (element_iter == element) {
840 element, ssc,
state, island_stitch_data, preview_position);
870 for (; edge_iter; edge_iter = edge_iter->
next) {
871 if (edge_iter == edge) {
881 state->uvs[edge->uv1], ssc,
state, island_stitch_data, preview_position);
883 state->uvs[edge->uv2], ssc,
state, island_stitch_data, preview_position);
926 int face_preview_pos =
931 final_position[index].
uv);
942 element_iter = element_iter->
next;
943 }
while (element_iter && !element_iter->
separate);
967 uint *uvfinal_map =
nullptr;
974 if (preview ==
nullptr) {
986 sizeof(*island_stitch_data) *
state->element_map->total_islands,
"stitch_island_data"));
987 if (!island_stitch_data) {
998 for (i = 0; i <
state->selection_size; i++) {
1010 for (
int island_idx = 0; island_idx <
state->element_map->total_islands; island_idx++) {
1016 if (is_active_state) {
1030 for (i = 0; i <
state->selection_size; i++) {
1034 element->flag &= ~STITCH_STITCHABLE_CANDIDATE;
1036 cd_loop_uv_offset, element, ssc,
state, island_stitch_data, preview_position);
1046 edge->flag &= ~STITCH_STITCHABLE_CANDIDATE;
1048 cd_loop_uv_offset, edge, ssc,
state, island_stitch_data, preview_position);
1062 int stitchBufferIndex = 0, unstitchBufferIndex = 0;
1066 preview->
num_stitchable *
sizeof(
float) * preview_size,
"stitch_preview_stitchable_data");
1068 sizeof(
float) * preview_size,
1069 "stitch_preview_unstitchable_data");
1078 for (i = 0; i <
state->total_separate_uvs; i++) {
1083 stitchBufferIndex++;
1088 unstitchBufferIndex++;
1093 for (i = 0; i <
state->total_separate_edges; i++) {
1105 stitchBufferIndex++;
1106 BLI_assert(stitchBufferIndex <= preview->num_stitchable);
1115 unstitchBufferIndex++;
1116 BLI_assert(unstitchBufferIndex <= preview->num_unstitchable);
1133 for (i = 0; i <
state->element_map->total_islands; i++) {
1134 if (island_stitch_data[i].addedForPreview) {
1135 int numOfIslandUVs =
state->element_map->island_total_uvs[i];
1137 for (
int j = 0; j < numOfIslandUVs; j++, element++) {
1152 uint buffer_index = 0;
1162 "static_island_preview_tris"));
1177 int numoftris = efa->
len - 2;
1179 int face_preview_pos = preview_position[index].
data_position;
1194 if (i < numoftris) {
1200 memcpy(preview->
static_tris + buffer_index, fuv,
sizeof(
float[2]));
1201 memcpy(preview->
static_tris + buffer_index + 2, luv,
sizeof(
float[2]));
1202 memcpy(preview->
static_tris + buffer_index + 4, luvnext,
sizeof(
float[2]));
1220 MEM_callocN(
state->selection_size *
sizeof(*final_position),
"stitch_uv_average"));
1221 uvfinal_map =
static_cast<uint *
>(
1222 MEM_mallocN(
state->element_map->total_uvs *
sizeof(*uvfinal_map),
"stitch_uv_final_map"));
1226 MEM_callocN(
state->total_separate_uvs *
sizeof(*final_position),
"stitch_uv_average"));
1230 for (i = 0; i <
state->selection_size; i++) {
1238 uvfinal_map[element -
state->element_map->storage] = i;
1241 final_position[i].
count = 1;
1248 for (; element_iter; element_iter = element_iter->
next) {
1251 l = element_iter->
l;
1253 if (stitch_midpoints) {
1255 final_position[i].
count++;
1267 if (stitch_midpoints) {
1268 final_position[i].
uv[0] /= final_position[i].
count;
1269 final_position[i].
uv[1] /= final_position[i].
count;
1280 l =
state->uvs[edge->uv1]->l;
1282 l =
state->uvs[edge->uv2]->l;
1287 final_position[edge->uv1].
count = 1;
1288 final_position[edge->uv2].
count = 1;
1298 for (edge_iter = edge->
first; edge_iter; edge_iter = edge_iter->
next) {
1306 if (stitch_midpoints) {
1308 final_position[edge->uv1].
count++;
1310 final_position[edge->uv2].
count++;
1325 for (i = 0; i <
state->total_separate_uvs; i++) {
1326 final_position[i].
uv[0] /= final_position[i].
count;
1327 final_position[i].
uv[1] /= final_position[i].
count;
1334 for (i = 0; i <
state->selection_size; i++) {
1347 island_stitch_data[element->island].
translation[0] += final_position[i].
uv[0] - luv[0];
1348 island_stitch_data[element->island].
translation[1] += final_position[i].
uv[1] - luv[1];
1349 island_stitch_data[element->island].
medianPoint[0] += luv[0];
1350 island_stitch_data[element->island].
medianPoint[1] += luv[1];
1356 for (i = 0; i <
state->total_separate_edges; i++) {
1367 island_stitch_data);
1374 for (i = 0; i <
state->total_separate_edges; i++) {
1384 for (i = 0; i <
state->selection_size; i++) {
1389 cd_loop_uv_offset, element, ssc,
state, island_stitch_data);
1395 for (i = 0; i <
state->total_separate_uvs; i++) {
1408 island_stitch_data[element->island].
translation[0] += final_position[i].
uv[0] - luv[0];
1409 island_stitch_data[element->island].
translation[1] += final_position[i].
uv[1] - luv[1];
1410 island_stitch_data[element->island].
medianPoint[0] += luv[0];
1411 island_stitch_data[element->island].
medianPoint[1] += luv[1];
1416 for (i = 0; i <
state->selection_size; i++) {
1421 cd_loop_uv_offset, edge, ssc,
state, final_position,
nullptr, island_stitch_data);
1428 for (i = 0; i <
state->selection_size; i++) {
1439 for (i = 0; i <
state->selection_size; i++) {
1444 scene, element, i, preview_position, final_position, ssc,
state,
final);
1450 state->uvs[edge->uv1],
1458 state->uvs[edge->uv2],
1473 cd_loop_uv_offset,
state, preview_position, preview, island_stitch_data,
final);
1512 if ((edge1->
uv1 == edge2->
uv1) && (edge1->
uv2 == edge2->
uv2)) {
1524 for (eiter = edge->
first; eiter; eiter = eiter->
next) {
1527 if (always_select) {
1531 eiter->
flag &= ~STITCH_SELECTED;
1532 for (i = 0; i <
state->selection_size; i++) {
1533 if (selection_stack[i] == eiter) {
1534 (
state->selection_size)--;
1535 selection_stack[i] = selection_stack[
state->selection_size];
1542 selection_stack[
state->selection_size++] = eiter;
1553 for (; element_iter; element_iter = element_iter->
next) {
1558 if (always_select) {
1562 element_iter->
flag &= ~STITCH_SELECTED;
1563 for (i = 0; i <
state->selection_size; i++) {
1564 if (selection_stack[i] == element_iter) {
1565 (
state->selection_size)--;
1566 selection_stack[i] = selection_stack[
state->selection_size];
1573 selection_stack[
state->selection_size++] = element_iter;
1581 void **old_selection_stack =
state->selection_stack;
1582 int old_selection_size =
state->selection_size;
1583 state->selection_size = 0;
1587 state->selection_stack =
static_cast<void **
>(
1589 "stitch_new_edge_selection_stack"));
1592 for (i = 0; i <
state->total_separate_edges; i++) {
1603 for (i = 0; i < old_selection_size; i++) {
1606 element->
flag &= ~STITCH_SELECTED;
1611 state->selection_stack =
static_cast<void **
>(
1613 "stitch_new_vert_selection_stack"));
1615 for (i = 0; i < old_selection_size; i++) {
1616 UvEdge *edge =
static_cast<UvEdge *
>(old_selection_stack[i]);
1623 edge->flag &= ~STITCH_SELECTED;
1648 BMLoop *l1 = edge->element->l;
1656 tangent[1] /= aspect;
1658 normal[0] = tangent[1];
1659 normal[1] = -tangent[0];
1684 uint num_line = 0, num_tri, tri_idx = 0, line_idx = 0;
1692 if (
format.attr_len == 0) {
1711 for (
int i = 0; i < stitch_preview->
num_polys; i++) {
1715 num_tri = num_line - 2 * stitch_preview->
num_polys;
1724 for (
int i = 0; i < stitch_preview->
num_polys; i++) {
1730 vbo_line, pos_id, line_idx++, &stitch_preview->
preview_polys[index + 2]);
1735 vbo, pos_id, tri_idx++, &stitch_preview->
preview_polys[index + (j + 0) * 2]);
1737 vbo, pos_id, tri_idx++, &stitch_preview->
preview_polys[index + (j + 1) * 2]);
1740 vbo_line, pos_id, line_idx++, &stitch_preview->
preview_polys[index + (j + 0) * 2]);
1742 vbo_line, pos_id, line_idx++, &stitch_preview->
preview_polys[index + (j + 1) * 2]);
1749 vbo_line, pos_id, line_idx++, &stitch_preview->
preview_polys[index + j * 2]);
1809 if (!element1 || !element2) {
1813 int uv1 =
state->map[element1 -
state->element_map->storage];
1814 int uv2 =
state->map[element2 -
state->element_map->storage];
1853 state = MEM_cnew<StitchState>(
"stitch state obj");
1856 state->obedit = obedit;
1861 const int selectmode_orig = scene->toolsettings->
selectmode;
1864 scene->toolsettings->selectmode = selectmode_orig;
1866 if (!
state->element_map) {
1873 int unique_uvs =
state->element_map->total_unique_uvs;
1874 state->total_separate_uvs = unique_uvs;
1882 state->normals =
static_cast<float *
>(
1883 MEM_callocN(
sizeof(*
state->normals) * 2 * unique_uvs,
"uv_stitch_normals"));
1884 state->map = map =
static_cast<int *
>(
1885 MEM_mallocN(
sizeof(*map) *
state->element_map->total_uvs,
"uv_stitch_unique_map"));
1888 all_edges =
static_cast<UvEdge *
>(
1889 MEM_mallocN(
sizeof(*all_edges) *
state->element_map->total_uvs,
"ssc_edges"));
1892 if (!
state->uvs || !map || !edge_hash || !all_edges) {
1900 for (
int i = 0; i < em->
bm->
totvert; i++) {
1902 for (;
element; element = element->next) {
1903 if (element->separate) {
1908 map[element -
state->element_map->storage] = counter;
1925 int itmp1 = element -
state->element_map->storage;
1929 int offset1 = map[itmp1];
1930 int offset2 = map[itmp2];
1932 all_edges[counter].
next =
nullptr;
1933 all_edges[counter].
first =
nullptr;
1934 all_edges[counter].
flag = 0;
1938 if (offset1 < offset2) {
1939 all_edges[counter].
uv1 = offset1;
1940 all_edges[counter].
uv2 = offset2;
1943 all_edges[counter].
uv1 = offset2;
1944 all_edges[counter].
uv2 = offset1;
1961 MEM_mallocN(
sizeof(*edges) * total_edges,
"stitch_edges"));
1969 state->total_separate_edges = total_edges;
1984 for (i = 0; i < total_edges; i++) {
1996 for (i = 0; i < total_edges; i++) {
1997 UvEdge *edge = edges + i;
2012 state->selection_size = 0;
2015 if (state_init !=
nullptr) {
2016 int faceIndex, elementIndex;
2025 state->selection_stack =
static_cast<void **
>(
2027 "uv_stitch_selection_stack"));
2029 while (selected_count--) {
2040 state->selection_stack =
static_cast<void **
>(
2042 "uv_stitch_selection_stack"));
2044 while (selected_count--) {
2053 uv1 = map[element -
state->element_map->storage];
2059 uv2 = map[element -
state->element_map->storage];
2077 if (ssc->
mode != stored_mode) {
2083 state->selection_stack =
static_cast<void **
>(
2085 "uv_stitch_selection_stack"));
2099 state->selection_stack =
static_cast<void **
>(
2101 "uv_stitch_selection_stack"));
2125 sizeof(*
state->tris_per_island) *
state->element_map->total_islands,
"stitch island tris"));
2126 for (i = 0; i <
state->element_map->total_islands; i++) {
2127 state->tris_per_island[i] = 0;
2134 state->tris_per_island[element->island] += (efa->
len > 2) ? efa->
len - 2 : 0;
2138 state->island_is_stitchable =
static_cast<bool *
>(
2139 MEM_callocN(
sizeof(
bool) *
state->element_map->total_islands,
"stitch I stops"));
2140 if (!
state->island_is_stitchable) {
2156 StitchState *original_active_state = active_state;
2175 }
while (!(active_state == original_active_state && ssc->
static_island == original_island));
2193 scene, view_layer, v3d);
2195 if (objects.is_empty()) {
2203 "Stitching only works with less than %i objects selected (%i selected)",
2205 int(objects.size()));
2249 int *objs_selection_count =
nullptr;
2259 objs_selection_count =
static_cast<int *
>(
2260 MEM_mallocN(
sizeof(
int *) * objects.size(),
"objects_selection_count"));
2263 int total_selected = 0;
2264 for (
uint ob_index = 0; ob_index < objects.size(); ob_index++) {
2265 total_selected += objs_selection_count[ob_index];
2283 state_init->
to_select = selected_uvs_arr;
2286 for (
uint ob_index = 0; ob_index < objects.size(); ob_index++) {
2287 Object *obedit = objects[ob_index];
2289 if (state_init !=
nullptr) {
2295 if (state_init !=
nullptr) {
2300 if (stitch_state_ob) {
2392 int *objs_selection_count =
nullptr;
2393 objs_selection_count =
static_cast<int *
>(
2405 for (
int i = 0; i <
state->selection_size; i++) {
2412 element = ((
UvEdge *)
state->selection_stack[i])->element;
2417 RNA_int_set(&itemptr,
"element_index", element->loop_of_face_index);
2421 objs_selection_count[ob_index] =
state->selection_size;
2498 if (hit.ob == ssc->
objects[ob_index]) {
2517 if (hit.ob == ssc->
objects[ob_index]) {
2540 switch (event->
type) {
2613 if (active_state != new_active_state) {
2700 {0,
nullptr, 0,
nullptr,
nullptr},
2705 ot->
description =
"Stitch selected UV vertices by proximity";
2718 ot->
srna,
"use_limit",
false,
"Use Limit",
"Stitch UVs within a specified limit distance");
2723 "Snap islands together (on edge stitch mode, rotates the islands too)");
2731 "Limit distance in normalized coordinates",
2740 "Island that stays in place when stitching islands",
2744 "active_object_index",
2749 "Index of the active object",
2756 "UVs are stitched at midpoint instead of at static island");
2763 "Use vertex or edge stitching");
2768 "Stored Operation Mode",
2769 "Use vertex or edge stitching");
2772 ot->
srna,
"selection", &RNA_SelectedUvElement,
"Selection",
"");
2778 "objects_selection_count",
2783 "Objects Selection Count",
SpaceImage * CTX_wm_space_image(const bContext *C)
ScrArea * CTX_wm_area(const bContext *C)
Scene * CTX_data_scene(const bContext *C)
ARegion * CTX_wm_region(const bContext *C)
View3D * CTX_wm_view3d(const bContext *C)
ViewLayer * CTX_data_view_layer(const bContext *C)
CustomData interface, see also DNA_customdata_types.h.
int CustomData_get_offset(const CustomData *data, eCustomDataType type)
BMEditMesh * BKE_editmesh_from_object(Object *ob)
Return the BMEditMesh for a given object.
blender::Vector< Object * > BKE_view_layer_array_from_objects_in_edit_mode_unique_data_with_uvs(const Scene *scene, ViewLayer *view_layer, const View3D *v3d)
void BKE_reportf(ReportList *reports, eReportType type, const char *format,...) ATTR_PRINTF_FORMAT(3
void BKE_report(ReportList *reports, eReportType type, const char *message)
BLI_INLINE void * BLI_ghashIterator_getKey(GHashIterator *ghi) ATTR_WARN_UNUSED_RESULT
unsigned int BLI_ghashutil_uinthash(unsigned int key)
#define GHASH_ITER(gh_iter_, ghash_)
GHash * BLI_ghash_new(GHashHashFP hashfp, GHashCmpFP cmpfp, const char *info) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT
unsigned int BLI_ghash_len(const GHash *gh) ATTR_WARN_UNUSED_RESULT
void * BLI_ghash_lookup(const GHash *gh, const void *key) ATTR_WARN_UNUSED_RESULT
void BLI_ghash_insert(GHash *gh, void *key, void *val)
void BLI_ghash_free(GHash *gh, GHashKeyFreeFP keyfreefp, GHashValFreeFP valfreefp)
MINLINE float max_ff(float a, float b)
MINLINE float min_ff(float a, float b)
void mul_v2_m2v2(float r[2], const float mat[2][2], const float vec[2])
void angle_to_mat2(float R[2][2], float angle)
MINLINE void sub_v2_v2(float r[2], const float a[2])
MINLINE void copy_v2_v2(float r[2], const float a[2])
MINLINE void add_v2_v2(float r[2], const float a[2])
MINLINE void negate_v2_v2(float r[2], const float a[2])
MINLINE float cross_v2v2(const float a[2], const float b[2]) ATTR_WARN_UNUSED_RESULT
MINLINE void add_v2_v2v2(float r[2], const float a[2], const float b[2])
MINLINE void sub_v2_v2v2(float r[2], const float a[2], const float b[2])
MINLINE float dot_v2v2(const float a[2], const float b[2]) ATTR_WARN_UNUSED_RESULT
MINLINE float normalize_v2(float n[2])
#define SNPRINTF(dst, format,...)
void DEG_id_tag_update(ID *id, unsigned int flags)
Object is a sort of wrapper for general info.
UvElement * BM_uv_element_get(const UvElementMap *element_map, const BMLoop *l)
void BM_uv_element_map_free(UvElementMap *element_map)
UvElementMap * BM_uv_element_map_create(BMesh *bm, const Scene *scene, bool uv_selected, bool use_winding, bool use_seams, bool do_islands)
UvElement * BM_uv_element_get_head(UvElementMap *element_map, UvElement *child)
void ED_workspace_status_text(bContext *C, const char *str)
void ED_region_tag_redraw(ARegion *region)
bool ED_operator_uvedit(bContext *C)
void * ED_region_draw_cb_activate(ARegionType *art, void(*draw)(const bContext *, ARegion *, void *), void *customdata, int type)
#define REGION_DRAW_POST_VIEW
bool ED_region_draw_cb_exit(ARegionType *art, void *handle)
float ED_uvedit_get_aspect_y(Object *obedit)
bool uvedit_edge_select_test(const Scene *scene, BMLoop *l, BMUVOffsets offsets)
void uvedit_uv_select_enable(const Scene *scene, BMesh *bm, BMLoop *l, bool do_history, BMUVOffsets offsets)
bool uvedit_uv_select_test(const Scene *scene, BMLoop *l, BMUVOffsets offsets)
blender::gpu::Batch * GPU_batch_create_ex(GPUPrimType primitive_type, blender::gpu::VertBuf *vertex_buf, blender::gpu::IndexBuf *index_buf, eGPUBatchFlag owns_flag)
void GPU_batch_discard(blender::gpu::Batch *batch)
void GPU_batch_program_set_builtin(blender::gpu::Batch *batch, eGPUBuiltinShader shader_id)
void GPU_batch_draw(blender::gpu::Batch *batch)
#define GPU_batch_uniform_4fv(batch, name, val)
@ GPU_SHADER_3D_UNIFORM_COLOR
void GPU_blend(eGPUBlend blend)
void GPU_point_size(float size)
#define GPU_vertbuf_create_with_format(format)
void GPU_vertbuf_attr_set(blender::gpu::VertBuf *, uint a_idx, uint v_idx, const void *data)
void GPU_vertbuf_data_alloc(blender::gpu::VertBuf &verts, uint v_len)
Read Guarded memory(de)allocation.
#define RNA_BEGIN(sptr, itemptr, propname)
#define RNA_MAX_ARRAY_LENGTH
@ TH_STITCH_PREVIEW_UNSTITCHABLE
@ TH_STITCH_PREVIEW_ACTIVE
@ TH_STITCH_PREVIEW_STITCHABLE
void UI_GetThemeColor4fv(int colorid, float col[4])
float UI_GetThemeValuef(int colorid)
void UI_view2d_region_to_view(const View2D *v2d, float x, float y, float *r_view_x, float *r_view_y) ATTR_NONNULL()
#define BM_FACE_FIRST_LOOP(p)
#define BM_ELEM_CD_GET_FLOAT_P(ele, offset)
#define BM_elem_index_get(ele)
#define BM_elem_flag_disable(ele, hflag)
#define BM_elem_flag_test(ele, hflag)
void * BM_iter_at_index(BMesh *bm, const char itype, void *data, int index)
#define BM_ITER_ELEM(ele, iter, data, itype)
#define BM_ITER_MESH(ele, iter, bm, itype)
#define BM_ITER_ELEM_INDEX(ele, iter, data, itype, indexvar)
ATTR_WARN_UNUSED_RESULT BMesh * bm
void BM_mesh_elem_table_ensure(BMesh *bm, const char htype)
void BM_mesh_elem_index_ensure(BMesh *bm, const char htype)
BLI_INLINE BMFace * BM_face_at_index(BMesh *bm, const int index)
ATTR_WARN_UNUSED_RESULT const void * element
ATTR_WARN_UNUSED_RESULT const BMLoop * l
BMUVOffsets BM_uv_map_get_offsets(const BMesh *bm)
local_group_size(16, 16) .push_constant(Type b
draw_view in_light_buf[] float
void *(* MEM_mallocN)(size_t len, const char *str)
void MEM_freeN(void *vmemh)
void *(* MEM_callocN)(size_t len, const char *str)
void RNA_int_set_array(PointerRNA *ptr, const char *name, const int *values)
void RNA_int_get_array(PointerRNA *ptr, const char *name, int *values)
void RNA_collection_clear(PointerRNA *ptr, const char *name)
PropertyRNA * RNA_struct_find_property(PointerRNA *ptr, const char *identifier)
void RNA_boolean_set(PointerRNA *ptr, const char *name, bool value)
void RNA_int_set(PointerRNA *ptr, const char *name, int value)
void RNA_collection_add(PointerRNA *ptr, const char *name, PointerRNA *r_value)
int RNA_int_get(PointerRNA *ptr, const char *name)
float RNA_float_get(PointerRNA *ptr, const char *name)
void RNA_float_set(PointerRNA *ptr, const char *name, float value)
bool RNA_struct_property_is_set(PointerRNA *ptr, const char *identifier)
bool RNA_boolean_get(PointerRNA *ptr, const char *name)
void RNA_enum_set(PointerRNA *ptr, const char *name, int value)
int RNA_enum_get(PointerRNA *ptr, const char *name)
PropertyRNA * RNA_def_int_array(StructOrFunctionRNA *cont_, const char *identifier, const int len, const int *default_value, const int hardmin, const int hardmax, const char *ui_name, const char *ui_description, const int softmin, const int softmax)
PropertyRNA * RNA_def_float(StructOrFunctionRNA *cont_, const char *identifier, const float default_value, const float hardmin, const float hardmax, const char *ui_name, const char *ui_description, const float softmin, const float softmax)
PropertyRNA * RNA_def_enum(StructOrFunctionRNA *cont_, const char *identifier, const EnumPropertyItem *items, const int default_value, const char *ui_name, const char *ui_description)
void RNA_def_property_array(PropertyRNA *prop, int length)
PropertyRNA * RNA_def_collection_runtime(StructOrFunctionRNA *cont_, const char *identifier, StructRNA *type, const char *ui_name, const char *ui_description)
PropertyRNA * RNA_def_boolean(StructOrFunctionRNA *cont_, const char *identifier, const bool default_value, const char *ui_name, const char *ui_description)
void RNA_def_property_flag(PropertyRNA *prop, PropertyFlag flag)
PropertyRNA * RNA_def_int(StructOrFunctionRNA *cont_, const char *identifier, const int default_value, const int hardmin, const int hardmax, const char *ui_name, const char *ui_description, const int softmin, const int softmax)
float * preview_unstitchable
float * preview_stitchable
bool * island_is_stitchable
UvElementMap * element_map
StitchPreviewer * stitch_preview
unsigned short loop_of_face_index
bool(* poll)(bContext *C) ATTR_WARN_UNUSED_RESULT
int(* modal)(bContext *C, wmOperator *op, const wmEvent *event) ATTR_WARN_UNUSED_RESULT
int(* invoke)(bContext *C, wmOperator *op, const wmEvent *event) ATTR_WARN_UNUSED_RESULT
int(* exec)(bContext *C, wmOperator *op) ATTR_WARN_UNUSED_RESULT
void(* cancel)(bContext *C, wmOperator *op)
struct ReportList * reports
bool uv_find_nearest_vert_multi(Scene *scene, blender::Span< Object * > objects, const float co[2], float penalty_dist, UvNearestHit *hit)
UvNearestHit uv_nearest_hit_init_max(const View2D *v2d)
void uvedit_live_unwrap_update(SpaceImage *sima, Scene *scene, Object *obedit)
bool uv_find_nearest_edge_multi(Scene *scene, blender::Span< Object * > objects, const float co[2], float penalty, UvNearestHit *hit)
static int stitch_init_all(bContext *C, wmOperator *op)
static StitchState * stitch_init(bContext *C, wmOperator *op, StitchStateContainer *ssc, Object *obedit, StitchStateInit *state_init)
static void stitch_propagate_uv_final_position(Scene *scene, UvElement *element, int index, PreviewPosition *preview_position, UVVertAverage *final_position, StitchStateContainer *ssc, StitchState *state, const bool final)
static void stitch_switch_selection_mode_all(StitchStateContainer *ssc)
static void stitch_select_edge(UvEdge *edge, StitchState *state, int always_select)
static bool stitch_check_uvs_state_stitchable(const int cd_loop_uv_offset, UvElement *element, UvElement *element_iter, StitchStateContainer *ssc)
static void stitch_exit(bContext *C, wmOperator *op, int finished)
static void stitch_draw_vbo(blender::gpu::VertBuf *vbo, GPUPrimType prim_type, const float col[4])
void UV_OT_stitch(wmOperatorType *ot)
static void stitch_island_calculate_vert_rotation(const int cd_loop_uv_offset, UvElement *element, StitchStateContainer *ssc, StitchState *state, IslandStitchData *island_stitch_data)
static void determine_uv_stitchability(const int cd_loop_uv_offset, UvElement *element, StitchStateContainer *ssc, StitchState *state, IslandStitchData *island_stitch_data)
static void stitch_draw(const bContext *, ARegion *, void *arg)
static void stitch_update_header(StitchStateContainer *ssc, bContext *C)
static int stitch_process_data_all(StitchStateContainer *ssc, Scene *scene, int final)
static void stitch_validate_edge_stitchability(const int cd_loop_uv_offset, UvEdge *edge, StitchStateContainer *ssc, StitchState *state, IslandStitchData *island_stitch_data, PreviewPosition *preview_position)
static bool stitch_check_edges_state_stitchable(const int cd_loop_uv_offset, UvEdge *edge, UvEdge *edge_iter, StitchStateContainer *ssc, StitchState *state)
static void stitch_uv_edge_generate_linked_edges(GHash *edge_hash, StitchState *state)
static bool uv_edge_compare(const void *a, const void *b)
static void state_delete_all(StitchStateContainer *ssc)
static void stitch_island_calculate_edge_rotation(const int cd_loop_uv_offset, UvEdge *edge, StitchStateContainer *ssc, StitchState *state, UVVertAverage *uv_average, const uint *uvfinal_map, IslandStitchData *island_stitch_data)
static void stitch_validate_uv_stitchability(const int cd_loop_uv_offset, UvElement *element, StitchStateContainer *ssc, StitchState *state, IslandStitchData *island_stitch_data, PreviewPosition *preview_position)
static void stitch_set_face_preview_buffer_position(BMFace *efa, StitchPreviewer *preview, PreviewPosition *preview_position)
static void stitch_uv_rotate(const float mat[2][2], const float medianPoint[2], float uv[2], float aspect)
static void stitch_calculate_edge_normal(const int cd_loop_uv_offset, UvEdge *edge, float *normal, float aspect)
static StitchState * stitch_select(bContext *C, Scene *scene, const wmEvent *event, StitchStateContainer *ssc)
static void stitch_cancel(bContext *C, wmOperator *op)
static bool goto_next_island(StitchStateContainer *ssc)
static int stitch_invoke(bContext *C, wmOperator *op, const wmEvent *)
static UvEdge * uv_edge_get(BMLoop *l, StitchState *state)
static bool stitch_check_uvs_stitchable(const int cd_loop_uv_offset, UvElement *element, UvElement *element_iter, StitchStateContainer *ssc)
static uint uv_edge_hash(const void *key)
#define STITCH_NO_PREVIEW
static void stitch_preview_delete(StitchPreviewer *stitch_preview)
static bool stitch_check_edges_stitchable(const int cd_loop_uv_offset, UvEdge *edge, UvEdge *edge_iter, StitchStateContainer *ssc, StitchState *state)
static void stitch_setup_face_preview_for_uv_group(UvElement *element, StitchStateContainer *ssc, StitchState *state, IslandStitchData *island_stitch_data, PreviewPosition *preview_position)
static void determine_uv_edge_stitchability(const int cd_loop_uv_offset, UvEdge *edge, StitchStateContainer *ssc, StitchState *state, IslandStitchData *island_stitch_data)
static void stitch_set_selection_mode(StitchState *state, const char from_stitch_mode)
@ STITCH_STITCHABLE_CANDIDATE
static int stitch_exec(bContext *C, wmOperator *op)
static void state_delete(StitchState *state)
static void stitch_select_uv(UvElement *element, StitchState *state, int always_select)
static int stitch_process_data(StitchStateContainer *ssc, StitchState *state, Scene *scene, int final)
static void stitch_calculate_island_snapping(const int cd_loop_uv_offset, StitchState *state, PreviewPosition *preview_position, StitchPreviewer *preview, IslandStitchData *island_stitch_data, int final)
static int stitch_modal(bContext *C, wmOperator *op, const wmEvent *event)
static StitchPreviewer * stitch_preview_init()
wmEventHandler_Op * WM_event_add_modal_handler(bContext *C, wmOperator *op)
void WM_event_add_notifier(const bContext *C, uint type, void *reference)
const char * WM_bool_as_string(bool test)