Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'source/blender/editors/uvedit')
-rw-r--r--source/blender/editors/uvedit/uvedit_draw.c130
-rw-r--r--source/blender/editors/uvedit/uvedit_ops.c41
-rw-r--r--source/blender/editors/uvedit/uvedit_smart_stitch.c1010
3 files changed, 728 insertions, 453 deletions
diff --git a/source/blender/editors/uvedit/uvedit_draw.c b/source/blender/editors/uvedit/uvedit_draw.c
index f0d6b5c2a71..616f4eac2ad 100644
--- a/source/blender/editors/uvedit/uvedit_draw.c
+++ b/source/blender/editors/uvedit/uvedit_draw.c
@@ -90,9 +90,9 @@ void ED_image_draw_cursor(ARegion *ar, const float cursor[2])
GPU_line_width(1.0f);
- gpuTranslate2fv(cursor);
+ GPU_matrix_translate_2fv(cursor);
- const uint shdr_pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
+ const uint shdr_pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
immBindBuiltinProgram(GPU_SHADER_2D_LINE_DASHED_UNIFORM_COLOR);
@@ -104,7 +104,7 @@ void ED_image_draw_cursor(ARegion *ar, const float cursor[2])
immUniformArray4fv("colors", (float *)(float[][4]){{1.0f, 0.0f, 0.0f, 1.0f}, {1.0f, 1.0f, 1.0f, 1.0f}}, 2);
immUniform1f("dash_width", 8.0f);
- immBegin(GWN_PRIM_LINES, 8);
+ immBegin(GPU_PRIM_LINES, 8);
immVertex2f(shdr_pos, -0.05f * x_fac, 0.0f);
immVertex2f(shdr_pos, 0.0f, 0.05f * y_fac);
@@ -123,7 +123,7 @@ void ED_image_draw_cursor(ARegion *ar, const float cursor[2])
immUniformArray4fv("colors", (float *)(float[][4]){{1.0f, 1.0f, 1.0f, 1.0f}, {0.0f, 0.0f, 0.0f, 1.0f}}, 2);
immUniform1f("dash_width", 2.0f);
- immBegin(GWN_PRIM_LINES, 8);
+ immBegin(GPU_PRIM_LINES, 8);
immVertex2f(shdr_pos, -0.020f * x_fac, 0.0f);
immVertex2f(shdr_pos, -0.1f * x_fac, 0.0f);
@@ -141,7 +141,7 @@ void ED_image_draw_cursor(ARegion *ar, const float cursor[2])
immUnbindProgram();
- gpuTranslate2f(-cursor[0], -cursor[1]);
+ GPU_matrix_translate_2f(-cursor[0], -cursor[1]);
}
static int draw_uvs_face_check(Scene *scene)
@@ -168,7 +168,7 @@ static void draw_uvs_shadow(Object *obedit)
const int cd_loop_uv_offset = CustomData_get_offset(&bm->ldata, CD_MLOOPUV);
- uint pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
+ uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
@@ -229,7 +229,7 @@ static void draw_uvs_stretch(SpaceImage *sima, Scene *scene, Object *obedit, BME
}
}
- uint pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
+ uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
@@ -241,7 +241,7 @@ static void draw_uvs_stretch(SpaceImage *sima, Scene *scene, Object *obedit, BME
BM_ITER_MESH (efa, &iter, bm, BM_FACES_OF_MESH) {
if (BM_elem_flag_test(efa, BM_ELEM_TAG)) {
- immBegin(GWN_PRIM_TRI_FAN, efa->len);
+ immBegin(GPU_PRIM_TRI_FAN, efa->len);
BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
@@ -281,7 +281,7 @@ static void draw_uvs_stretch(SpaceImage *sima, Scene *scene, Object *obedit, BME
immUniformColor3fv(col);
/* TODO: use editmesh tessface */
- immBegin(GWN_PRIM_TRI_FAN, efa->len);
+ immBegin(GPU_PRIM_TRI_FAN, efa->len);
BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
@@ -308,9 +308,9 @@ static void draw_uvs_stretch(SpaceImage *sima, Scene *scene, Object *obedit, BME
col[3] = 0.5f; /* hard coded alpha, not that nice */
- Gwn_VertFormat *format = immVertexFormat();
- uint pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
- uint color = GWN_vertformat_attr_add(format, "color", GWN_COMP_F32, 3, GWN_FETCH_FLOAT);
+ GPUVertFormat *format = immVertexFormat();
+ uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
+ uint color = GPU_vertformat_attr_add(format, "color", GPU_COMP_F32, 3, GPU_FETCH_FLOAT);
immBindBuiltinProgram(GPU_SHADER_2D_SMOOTH_COLOR);
@@ -353,7 +353,7 @@ static void draw_uvs_stretch(SpaceImage *sima, Scene *scene, Object *obedit, BME
}
/* TODO: use editmesh tessface */
- immBegin(GWN_PRIM_TRI_FAN, efa->len);
+ immBegin(GPU_PRIM_TRI_FAN, efa->len);
BM_ITER_ELEM_INDEX (l, &liter, efa, BM_LOOPS_OF_FACE, i) {
luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
a = fabsf(uvang[i] - ang[i]) / (float)M_PI;
@@ -393,7 +393,7 @@ static void draw_uvs_lineloop_bmfaces(BMesh *bm, const int cd_loop_uv_offset, co
MLoopUV *luv;
/* For more efficiency first transfer the entire buffer to vram. */
- Gwn_Batch *loop_batch = immBeginBatchAtMost(GWN_PRIM_LINE_LOOP, bm->totloop);
+ GPUBatch *loop_batch = immBeginBatchAtMost(GPU_PRIM_LINE_LOOP, bm->totloop);
BM_ITER_MESH(efa, &iter, bm, BM_FACES_OF_MESH) {
if (!BM_elem_flag_test(efa, BM_ELEM_TAG))
@@ -407,17 +407,17 @@ static void draw_uvs_lineloop_bmfaces(BMesh *bm, const int cd_loop_uv_offset, co
immEnd();
/* Then draw each face contour separately. */
- GWN_batch_program_use_begin(loop_batch);
+ GPU_batch_program_use_begin(loop_batch);
unsigned int index = 0;
BM_ITER_MESH(efa, &iter, bm, BM_FACES_OF_MESH) {
if (!BM_elem_flag_test(efa, BM_ELEM_TAG))
continue;
- GWN_batch_draw_range_ex(loop_batch, index, efa->len, false);
+ GPU_batch_draw_range_ex(loop_batch, index, efa->len, false);
index += efa->len;
}
- GWN_batch_program_use_end(loop_batch);
- GWN_batch_discard(loop_batch);
+ GPU_batch_program_use_end(loop_batch);
+ GPU_batch_discard(loop_batch);
}
static void draw_uvs_lineloop_mpoly(Mesh *me, MPoly *mpoly, unsigned int pos)
@@ -425,7 +425,7 @@ static void draw_uvs_lineloop_mpoly(Mesh *me, MPoly *mpoly, unsigned int pos)
MLoopUV *mloopuv;
int i;
- immBegin(GWN_PRIM_LINE_LOOP, mpoly->totloop);
+ immBegin(GPU_PRIM_LINE_LOOP, mpoly->totloop);
mloopuv = &me->mloopuv[mpoly->loopstart];
for (i = mpoly->totloop; i != 0; i--, mloopuv++) {
@@ -495,7 +495,7 @@ static void draw_uvs_other_mesh(Object *ob, const Image *curimage,
static void draw_uvs_other(ViewLayer *view_layer, Object *obedit, const Image *curimage,
const int other_uv_filter)
{
- uint pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
+ uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
@@ -536,7 +536,7 @@ static void draw_uvs_texpaint(SpaceImage *sima, Scene *scene, ViewLayer *view_la
mloopuv = me->mloopuv;
}
- uint pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
+ uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
@@ -548,7 +548,7 @@ static void draw_uvs_texpaint(SpaceImage *sima, Scene *scene, ViewLayer *view_la
if ((scene->toolsettings->uv_flag & UV_SHOW_SAME_IMAGE) && mpoly->mat_nr != ob->actcol - 1)
continue;
- immBegin(GWN_PRIM_LINE_LOOP, mpoly->totloop);
+ immBegin(GPU_PRIM_LINE_LOOP, mpoly->totloop);
mloopuv = mloopuv_base + mpoly->loopstart;
for (b = 0; b < mpoly->totloop; b++, mloopuv++) {
@@ -658,13 +658,13 @@ static void draw_uvs(SpaceImage *sima, Scene *scene, ViewLayer *view_layer, Obje
GPU_blend_set_func_separate(GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA);
GPU_blend(true);
- Gwn_VertFormat *format = immVertexFormat();
- pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
- color = GWN_vertformat_attr_add(format, "color", GWN_COMP_F32, 4, GWN_FETCH_FLOAT);
+ GPUVertFormat *format = immVertexFormat();
+ pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
+ color = GPU_vertformat_attr_add(format, "color", GPU_COMP_F32, 4, GPU_FETCH_FLOAT);
immBindBuiltinProgram(GPU_SHADER_2D_FLAT_COLOR);
- Gwn_Batch *face_batch = immBeginBatch(GWN_PRIM_TRIS, tri_count * 3);
+ GPUBatch *face_batch = immBeginBatch(GPU_PRIM_TRIS, tri_count * 3);
for (unsigned int i = 0; i < em->tottri; i++) {
efa = em->looptris[i][0]->f;
if (BM_elem_flag_test(efa, BM_ELEM_TAG)) {
@@ -686,9 +686,9 @@ static void draw_uvs(SpaceImage *sima, Scene *scene, ViewLayer *view_layer, Obje
immEnd();
/* XXX performance: we should not create and throw away result. */
- GWN_batch_draw(face_batch);
- GWN_batch_program_use_end(face_batch);
- GWN_batch_discard(face_batch);
+ GPU_batch_draw(face_batch);
+ GPU_batch_program_use_end(face_batch);
+ GPU_batch_discard(face_batch);
immUnbindProgram();
@@ -712,7 +712,7 @@ static void draw_uvs(SpaceImage *sima, Scene *scene, ViewLayer *view_layer, Obje
GPU_blend_set_func_separate(GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA);
}
- pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
+ pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
switch (sima->dt_uv) {
case SI_UVDT_DASH:
@@ -751,8 +751,8 @@ static void draw_uvs(SpaceImage *sima, Scene *scene, ViewLayer *view_layer, Obje
}
/* For more efficiency first transfer the entire buffer to vram. */
- Gwn_Batch *loop_batch = immBeginBatchAtMost(GWN_PRIM_LINE_LOOP, bm->totloop);
- Gwn_VertBuf *loop_vbo = loop_batch->verts[0];
+ GPUBatch *loop_batch = immBeginBatchAtMost(GPU_PRIM_LINE_LOOP, bm->totloop);
+ GPUVertBuf *loop_vbo = loop_batch->verts[0];
BM_ITER_MESH(efa, &iter, bm, BM_FACES_OF_MESH) {
if (!BM_elem_flag_test(efa, BM_ELEM_TAG))
continue;
@@ -766,17 +766,17 @@ static void draw_uvs(SpaceImage *sima, Scene *scene, ViewLayer *view_layer, Obje
/* Then draw each face contour separately. */
if (loop_vbo->vertex_len != 0) {
- GWN_batch_program_use_begin(loop_batch);
+ GPU_batch_program_use_begin(loop_batch);
unsigned int index = 0, loop_vbo_count;
BM_ITER_MESH(efa, &iter, bm, BM_FACES_OF_MESH) {
if (!BM_elem_flag_test(efa, BM_ELEM_TAG))
continue;
- GWN_batch_draw_range_ex(loop_batch, index, efa->len, false);
+ GPU_batch_draw_range_ex(loop_batch, index, efa->len, false);
index += efa->len;
}
loop_vbo_count = index;
- GWN_batch_program_use_end(loop_batch);
+ GPU_batch_program_use_end(loop_batch);
immUnbindProgram();
@@ -790,14 +790,14 @@ static void draw_uvs(SpaceImage *sima, Scene *scene, ViewLayer *view_layer, Obje
if (interpedges) {
/* Create a color buffer. */
- static Gwn_VertFormat format = { 0 };
+ static GPUVertFormat format = { 0 };
static uint shdr_col;
if (format.attr_len == 0) {
- shdr_col = GWN_vertformat_attr_add(&format, "color", GWN_COMP_F32, 4, GWN_FETCH_FLOAT);
+ shdr_col = GPU_vertformat_attr_add(&format, "color", GPU_COMP_F32, 4, GPU_FETCH_FLOAT);
}
- Gwn_VertBuf *vbo_col = GWN_vertbuf_create_with_format(&format);
- GWN_vertbuf_data_alloc(vbo_col, loop_vbo_count);
+ GPUVertBuf *vbo_col = GPU_vertbuf_create_with_format(&format);
+ GPU_vertbuf_data_alloc(vbo_col, loop_vbo_count);
index = 0;
BM_ITER_MESH(efa, &iter, bm, BM_FACES_OF_MESH) {
@@ -806,36 +806,36 @@ static void draw_uvs(SpaceImage *sima, Scene *scene, ViewLayer *view_layer, Obje
BM_ITER_ELEM(l, &liter, efa, BM_LOOPS_OF_FACE) {
sel = uvedit_uv_select_test(scene, l, cd_loop_uv_offset);
- GWN_vertbuf_attr_set(vbo_col, shdr_col, index++, sel ? col1 : col2);
+ GPU_vertbuf_attr_set(vbo_col, shdr_col, index++, sel ? col1 : col2);
}
}
/* Reuse the UV buffer and add the color buffer. */
- GWN_batch_vertbuf_add_ex(loop_batch, vbo_col, true);
+ GPU_batch_vertbuf_add_ex(loop_batch, vbo_col, true);
/* Now draw each face contour separately with another builtin program. */
- GWN_batch_program_set_builtin(loop_batch, GPU_SHADER_2D_SMOOTH_COLOR);
- gpuBindMatrices(loop_batch->interface);
+ GPU_batch_program_set_builtin(loop_batch, GPU_SHADER_2D_SMOOTH_COLOR);
+ GPU_matrix_bind(loop_batch->interface);
- GWN_batch_program_use_begin(loop_batch);
+ GPU_batch_program_use_begin(loop_batch);
index = 0;
BM_ITER_MESH(efa, &iter, bm, BM_FACES_OF_MESH) {
if (!BM_elem_flag_test(efa, BM_ELEM_TAG))
continue;
- GWN_batch_draw_range_ex(loop_batch, index, efa->len, false);
+ GPU_batch_draw_range_ex(loop_batch, index, efa->len, false);
index += efa->len;
}
- GWN_batch_program_use_end(loop_batch);
+ GPU_batch_program_use_end(loop_batch);
}
else {
- Gwn_VertFormat *format = immVertexFormat();
- pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
- color = GWN_vertformat_attr_add(format, "color", GWN_COMP_F32, 4, GWN_FETCH_FLOAT);
+ GPUVertFormat *format = immVertexFormat();
+ pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
+ color = GPU_vertformat_attr_add(format, "color", GPU_COMP_F32, 4, GPU_FETCH_FLOAT);
immBindBuiltinProgram(GPU_SHADER_2D_FLAT_COLOR);
/* Use batch here to avoid problems with `IMM_BUFFER_SIZE`. */
- Gwn_Batch *flat_edges_batch = immBeginBatchAtMost(GWN_PRIM_LINES, loop_vbo_count * 2);
+ GPUBatch *flat_edges_batch = immBeginBatchAtMost(GPU_PRIM_LINES, loop_vbo_count * 2);
BM_ITER_MESH(efa, &iter, bm, BM_FACES_OF_MESH) {
if (!BM_elem_flag_test(efa, BM_ELEM_TAG))
continue;
@@ -852,27 +852,27 @@ static void draw_uvs(SpaceImage *sima, Scene *scene, ViewLayer *view_layer, Obje
}
immEnd();
- GWN_batch_draw(flat_edges_batch);
- GWN_batch_discard(flat_edges_batch);
+ GPU_batch_draw(flat_edges_batch);
+ GPU_batch_discard(flat_edges_batch);
immUnbindProgram();
}
}
else {
- GWN_batch_uniform_4fv(loop_batch, "color", col2);
+ GPU_batch_uniform_4fv(loop_batch, "color", col2);
immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
/* no nice edges */
- GWN_batch_program_use_begin(loop_batch);
+ GPU_batch_program_use_begin(loop_batch);
index = 0;
BM_ITER_MESH(efa, &iter, bm, BM_FACES_OF_MESH) {
if (!BM_elem_flag_test(efa, BM_ELEM_TAG))
continue;
- GWN_batch_draw_range_ex(loop_batch, index, efa->len, false);
+ GPU_batch_draw_range_ex(loop_batch, index, efa->len, false);
index += efa->len;
}
- GWN_batch_program_use_end(loop_batch);
+ GPU_batch_program_use_end(loop_batch);
immUnbindProgram();
}
}
@@ -881,7 +881,7 @@ static void draw_uvs(SpaceImage *sima, Scene *scene, ViewLayer *view_layer, Obje
immUnbindProgram();
}
- GWN_batch_discard(loop_batch);
+ GPU_batch_discard(loop_batch);
if (sima->flag & SI_SMOOTH_UV) {
GPU_line_smooth(false);
@@ -894,16 +894,16 @@ static void draw_uvs(SpaceImage *sima, Scene *scene, ViewLayer *view_layer, Obje
float cent[2];
bool col_set = false;
- Gwn_VertFormat *format = immVertexFormat();
- pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
- color = GWN_vertformat_attr_add(format, "color", GWN_COMP_F32, 3, GWN_FETCH_FLOAT);
+ GPUVertFormat *format = immVertexFormat();
+ pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
+ color = GPU_vertformat_attr_add(format, "color", GPU_COMP_F32, 3, GPU_FETCH_FLOAT);
immBindBuiltinProgram(GPU_SHADER_2D_FLAT_COLOR);
pointsize = UI_GetThemeValuef(TH_FACEDOT_SIZE);
GPU_point_size(pointsize);
- immBeginAtMost(GWN_PRIM_POINTS, bm->totface);
+ immBeginAtMost(GPU_PRIM_POINTS, bm->totface);
/* unselected faces */
@@ -955,7 +955,7 @@ static void draw_uvs(SpaceImage *sima, Scene *scene, ViewLayer *view_layer, Obje
/* 6. draw uv vertices */
if (drawfaces != 2) { /* 2 means Mesh Face Mode */
- pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
+ pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
@@ -964,7 +964,7 @@ static void draw_uvs(SpaceImage *sima, Scene *scene, ViewLayer *view_layer, Obje
pointsize = UI_GetThemeValuef(TH_VERTEX_SIZE);
GPU_point_size(pointsize);
- immBeginAtMost(GWN_PRIM_POINTS, bm->totloop);
+ immBeginAtMost(GPU_PRIM_POINTS, bm->totloop);
BM_ITER_MESH (efa, &iter, bm, BM_FACES_OF_MESH) {
if (!BM_elem_flag_test(efa, BM_ELEM_TAG))
@@ -984,7 +984,7 @@ static void draw_uvs(SpaceImage *sima, Scene *scene, ViewLayer *view_layer, Obje
GPU_point_size(pointsize * 2 + (((int)pointsize % 2) ? (-1) : 0));
imm_cpack(0xFF);
- immBeginAtMost(GWN_PRIM_POINTS, bm->totloop);
+ immBeginAtMost(GPU_PRIM_POINTS, bm->totloop);
BM_ITER_MESH (efa, &iter, bm, BM_FACES_OF_MESH) {
if (!BM_elem_flag_test(efa, BM_ELEM_TAG))
@@ -1004,7 +1004,7 @@ static void draw_uvs(SpaceImage *sima, Scene *scene, ViewLayer *view_layer, Obje
immUniformThemeColor(TH_VERTEX_SELECT);
GPU_point_size(pointsize);
- immBeginAtMost(GWN_PRIM_POINTS, bm->totloop);
+ immBeginAtMost(GPU_PRIM_POINTS, bm->totloop);
BM_ITER_MESH (efa, &iter, bm, BM_FACES_OF_MESH) {
if (!BM_elem_flag_test(efa, BM_ELEM_TAG))
diff --git a/source/blender/editors/uvedit/uvedit_ops.c b/source/blender/editors/uvedit/uvedit_ops.c
index faccb44767f..32bf32b03ab 100644
--- a/source/blender/editors/uvedit/uvedit_ops.c
+++ b/source/blender/editors/uvedit/uvedit_ops.c
@@ -80,6 +80,7 @@
#include "RNA_access.h"
#include "RNA_define.h"
+#include "RNA_enum_types.h"
#include "WM_api.h"
#include "WM_types.h"
@@ -971,7 +972,7 @@ static UvMapVert *uv_select_edgeloop_vertex_map_get(UvVertMap *vmap, BMFace *efa
for (iterv = first; iterv; iterv = iterv->next) {
if (iterv->separate)
first = iterv;
- if (iterv->f == BM_elem_index_get(efa))
+ if (iterv->poly_index == BM_elem_index_get(efa))
return first;
}
@@ -993,9 +994,9 @@ static bool uv_select_edgeloop_edge_tag_faces(BMEditMesh *em, UvMapVert *first1,
if (iterv2->separate && iterv2 != first2)
break;
- if (iterv1->f == iterv2->f) {
+ if (iterv1->poly_index == iterv2->poly_index) {
/* if face already tagged, don't do this edge */
- efa = BM_face_at_index(em->bm, iterv1->f);
+ efa = BM_face_at_index(em->bm, iterv1->poly_index);
if (BM_elem_flag_test(efa, BM_ELEM_TAG))
return false;
@@ -1019,8 +1020,8 @@ static bool uv_select_edgeloop_edge_tag_faces(BMEditMesh *em, UvMapVert *first1,
if (iterv2->separate && iterv2 != first2)
break;
- if (iterv1->f == iterv2->f) {
- efa = BM_face_at_index(em->bm, iterv1->f);
+ if (iterv1->poly_index == iterv2->poly_index) {
+ efa = BM_face_at_index(em->bm, iterv1->poly_index);
BM_elem_flag_enable(efa, BM_ELEM_TAG);
break;
}
@@ -1231,18 +1232,19 @@ static void uv_select_linked_multi(
for (iterv = vlist; iterv; iterv = iterv->next) {
if (iterv->separate)
startv = iterv;
- if (iterv->f == a)
+ if (iterv->poly_index == a)
break;
}
for (iterv = startv; iterv; iterv = iterv->next) {
if ((startv != iterv) && (iterv->separate))
break;
- else if (!flag[iterv->f]) {
- flag[iterv->f] = 1;
- stack[stacksize] = iterv->f;
+ else if (!flag[iterv->poly_index]) {
+ flag[iterv->poly_index] = 1;
+ stack[stacksize] = iterv->poly_index;
stacksize++;
}
+
}
}
}
@@ -2742,7 +2744,7 @@ static void uv_select_flush_from_tag_sticky_loc_internal(
if (vlist_iter->separate)
start_vlist = vlist_iter;
- if (efa_index == vlist_iter->f)
+ if (efa_index == vlist_iter->poly_index)
break;
vlist_iter = vlist_iter->next;
@@ -2754,12 +2756,12 @@ static void uv_select_flush_from_tag_sticky_loc_internal(
if (vlist_iter != start_vlist && vlist_iter->separate)
break;
- if (efa_index != vlist_iter->f) {
+ if (efa_index != vlist_iter->poly_index) {
BMLoop *l_other;
- efa_vlist = BM_face_at_index(em->bm, vlist_iter->f);
+ efa_vlist = BM_face_at_index(em->bm, vlist_iter->poly_index);
/* tf_vlist = BM_ELEM_CD_GET_VOID_P(efa_vlist, cd_poly_tex_offset); */ /* UNUSED */
- l_other = BM_iter_at_index(em->bm, BM_LOOPS_OF_FACE, efa_vlist, vlist_iter->tfindex);
+ l_other = BM_iter_at_index(em->bm, BM_LOOPS_OF_FACE, efa_vlist, vlist_iter->loop_of_poly_index);
uvedit_uv_select_set(em, scene, l_other, select, false, cd_loop_uv_offset);
}
@@ -4178,14 +4180,14 @@ static int uv_seams_from_islands_exec(bContext *C, wmOperator *op)
v1coincident = 0;
separated2 = 0;
- efa1 = BM_face_at_index(bm, mv1->f);
+ efa1 = BM_face_at_index(bm, mv1->poly_index);
mvinit2 = vmap->vert[BM_elem_index_get(editedge->v2)];
for (mv2 = mvinit2; mv2; mv2 = mv2->next) {
if (mv2->separate)
mv2sep = mv2;
- efa2 = BM_face_at_index(bm, mv2->f);
+ efa2 = BM_face_at_index(bm, mv2->poly_index);
if (efa1 == efa2) {
/* if v1 is not coincident no point in comparing */
if (v1coincident) {
@@ -4403,6 +4405,15 @@ void ED_keymap_uvedit(wmKeyConfig *keyconf)
RNA_string_set(kmi->ptr, "data_path", "tool_settings.use_uv_sculpt");
#endif
+ /* Select Element (Sync Select: on) */
+ ED_keymap_editmesh_elem_mode(keyconf, keymap);
+ /* Hack to prevent fall-through, when the button isn't visible. */
+ WM_keymap_add_item(keymap, "MESH_OT_select_mode", FOURKEY, KM_PRESS, 0, 0);
+ /* Select Element (Sync Select: off) */
+ WM_keymap_add_context_enum_set_items(
+ keymap, rna_enum_mesh_select_mode_uv_items, "tool_settings.uv_select_mode",
+ ONEKEY, KM_PRESS, 0, 0);
+
/* Mark edge seam */
WM_keymap_add_item(keymap, "UV_OT_mark_seam", EKEY, KM_PRESS, KM_CTRL, 0);
diff --git a/source/blender/editors/uvedit/uvedit_smart_stitch.c b/source/blender/editors/uvedit/uvedit_smart_stitch.c
index c3737787933..422c3489e01 100644
--- a/source/blender/editors/uvedit/uvedit_smart_stitch.c
+++ b/source/blender/editors/uvedit/uvedit_smart_stitch.c
@@ -54,6 +54,7 @@
#include "BKE_customdata.h"
#include "BKE_mesh_mapping.h"
#include "BKE_editmesh.h"
+#include "BKE_layer.h"
#include "DEG_depsgraph.h"
@@ -150,20 +151,11 @@ typedef struct UvEdge {
/* stitch state object */
typedef struct StitchState {
float aspect;
- /* use limit flag */
- bool use_limit;
- /* limit to operator, same as original operator */
- float limit_dist;
- /* snap uv islands together during stitching */
- bool snap_islands;
- /* stitch at midpoints or at islands */
- bool midpoints;
/* object for editmesh */
Object *obedit;
/* editmesh, cached for use in modal handler */
BMEditMesh *em;
- /* clear seams of stitched edges after stitch */
- bool clear_seams;
+
/* element map for getting info about uv connectivity */
UvElementMap *element_map;
/* edge container */
@@ -178,6 +170,8 @@ typedef struct StitchState {
UvEdge *edges;
/* hash for quick lookup of edges */
GHash *edge_hash;
+ /* which islands to stop at (to make active) when pressing 'I' */
+ bool *island_is_stitchable;
/* count of separate uvs and edges */
int total_separate_edges;
@@ -185,18 +179,39 @@ typedef struct StitchState {
/* hold selection related information */
void **selection_stack;
int selection_size;
- /* island that stays in place */
- int static_island;
+
/* store number of primitives per face so that we can allocate the active island buffer later */
unsigned int *tris_per_island;
+ /* preview data */
+ StitchPreviewer *stitch_preview;
+} StitchState;
+/* Stitch state container. */
+typedef struct StitchStateContainer {
+ /* clear seams of stitched edges after stitch */
+ bool clear_seams;
+ /* use limit flag */
+ bool use_limit;
+ /* limit to operator, same as original operator */
+ float limit_dist;
+ /* snap uv islands together during stitching */
+ bool snap_islands;
+ /* stitch at midpoints or at islands */
+ bool midpoints;
/* vert or edge mode used for stitching */
char mode;
/* handle for drawing */
void *draw_handle;
- /* preview data */
- StitchPreviewer *stitch_preview;
-} StitchState;
+ /* island that stays in place */
+ int static_island;
+
+ /* Objects and states are aligned. */
+ int objects_len;
+ Object **objects;
+ StitchState **states;
+
+ int active_object_index;
+} StitchStateContainer;
typedef struct PreviewPosition {
int data_position;
@@ -270,7 +285,7 @@ static void stitch_preview_delete(StitchPreviewer *stitch_preview)
}
/* This function updates the header of the UV editor when the stitch tool updates its settings */
-static void stitch_update_header(StitchState *state, bContext *C)
+static void stitch_update_header(StitchStateContainer *ssc, bContext *C)
{
const char *str = IFACE_(
"Mode(TAB) %s, "
@@ -285,12 +300,13 @@ static void stitch_update_header(StitchState *state, bContext *C)
ScrArea *sa = CTX_wm_area(C);
if (sa) {
- BLI_snprintf(msg, sizeof(msg), str,
- state->mode == STITCH_VERT ? IFACE_("Vertex") : IFACE_("Edge"),
- WM_bool_as_string(state->snap_islands),
- WM_bool_as_string(state->midpoints),
- state->limit_dist,
- WM_bool_as_string(state->use_limit));
+ BLI_snprintf(
+ msg, sizeof(msg), str,
+ ssc->mode == STITCH_VERT ? IFACE_("Vertex") : IFACE_("Edge"),
+ WM_bool_as_string(ssc->snap_islands),
+ WM_bool_as_string(ssc->midpoints),
+ ssc->limit_dist,
+ WM_bool_as_string(ssc->use_limit));
ED_workspace_status_text(C, msg);
}
@@ -320,7 +336,9 @@ static void stitch_uv_rotate(float mat[2][2], float medianPoint[2], float uv[2],
}
/* check if two uvelements are stitchable. This should only operate on -different- separate UvElements */
-static bool stitch_check_uvs_stitchable(UvElement *element, UvElement *element_iter, StitchState *state)
+static bool stitch_check_uvs_stitchable(
+ UvElement *element, UvElement *element_iter,
+ StitchStateContainer *ssc, StitchState *state)
{
BMesh *bm = state->em->bm;
float limit;
@@ -329,9 +347,9 @@ static bool stitch_check_uvs_stitchable(UvElement *element, UvElement *element_i
return 0;
}
- limit = state->limit_dist;
+ limit = ssc->limit_dist;
- if (state->use_limit) {
+ if (ssc->use_limit) {
MLoopUV *luv, *luv_iter;
BMLoop *l;
@@ -355,7 +373,9 @@ static bool stitch_check_uvs_stitchable(UvElement *element, UvElement *element_i
}
}
-static bool stitch_check_edges_stitchable(UvEdge *edge, UvEdge *edge_iter, StitchState *state)
+static bool stitch_check_edges_stitchable(
+ UvEdge *edge, UvEdge *edge_iter,
+ StitchStateContainer *ssc, StitchState *state)
{
BMesh *bm = state->em->bm;
float limit;
@@ -364,9 +384,9 @@ static bool stitch_check_edges_stitchable(UvEdge *edge, UvEdge *edge_iter, Stitc
return 0;
}
- limit = state->limit_dist;
+ limit = ssc->limit_dist;
- if (state->use_limit) {
+ if (ssc->use_limit) {
BMLoop *l;
MLoopUV *luv_orig1, *luv_iter1;
MLoopUV *luv_orig2, *luv_iter2;
@@ -397,27 +417,30 @@ static bool stitch_check_edges_stitchable(UvEdge *edge, UvEdge *edge_iter, Stitc
}
}
-static bool stitch_check_uvs_state_stitchable(UvElement *element, UvElement *element_iter, StitchState *state)
+static bool stitch_check_uvs_state_stitchable(
+ UvElement *element, UvElement *element_iter,
+ StitchStateContainer *ssc, StitchState *state)
{
- if ((state->snap_islands && element->island == element_iter->island) ||
- (!state->midpoints && element->island == element_iter->island))
+ if ((ssc->snap_islands && element->island == element_iter->island) ||
+ (!ssc->midpoints && element->island == element_iter->island))
{
return 0;
}
- return stitch_check_uvs_stitchable(element, element_iter, state);
+ return stitch_check_uvs_stitchable(element, element_iter, ssc, state);
}
-
-static bool stitch_check_edges_state_stitchable(UvEdge *edge, UvEdge *edge_iter, StitchState *state)
+static bool stitch_check_edges_state_stitchable(
+ UvEdge *edge, UvEdge *edge_iter,
+ StitchStateContainer *ssc, StitchState *state)
{
- if ((state->snap_islands && edge->element->island == edge_iter->element->island) ||
- (!state->midpoints && edge->element->island == edge_iter->element->island))
+ if ((ssc->snap_islands && edge->element->island == edge_iter->element->island) ||
+ (!ssc->midpoints && edge->element->island == edge_iter->element->island))
{
return 0;
}
- return stitch_check_edges_stitchable(edge, edge_iter, state);
+ return stitch_check_edges_stitchable(edge, edge_iter, ssc, state);
}
/* calculate snapping for islands */
@@ -489,9 +512,10 @@ static void stitch_calculate_island_snapping(
int face_preview_pos = preview_position[BM_elem_index_get(element->l->f)].data_position;
stitch_uv_rotate(rotation_mat, island_stitch_data[i].medianPoint,
- preview->preview_polys + face_preview_pos + 2 * element->tfindex, state->aspect);
+ preview->preview_polys + face_preview_pos + 2 * element->loop_of_poly_index,
+ state->aspect);
- add_v2_v2(preview->preview_polys + face_preview_pos + 2 * element->tfindex,
+ add_v2_v2(preview->preview_polys + face_preview_pos + 2 * element->loop_of_poly_index,
island_stitch_data[i].translation);
}
}
@@ -505,8 +529,8 @@ static void stitch_calculate_island_snapping(
static void stitch_island_calculate_edge_rotation(
- UvEdge *edge, StitchState *state, UVVertAverage *uv_average, unsigned int *uvfinal_map,
- IslandStitchData *island_stitch_data)
+ UvEdge *edge, StitchStateContainer *ssc, StitchState *state, UVVertAverage *uv_average,
+ unsigned int *uvfinal_map, IslandStitchData *island_stitch_data)
{
BMesh *bm = state->em->bm;
UvElement *element1, *element2;
@@ -522,7 +546,7 @@ static void stitch_island_calculate_edge_rotation(
luv1 = CustomData_bmesh_get(&bm->ldata, element1->l->head.data, CD_MLOOPUV);
luv2 = CustomData_bmesh_get(&bm->ldata, element2->l->head.data, CD_MLOOPUV);
- if (state->mode == STITCH_VERT) {
+ if (ssc->mode == STITCH_VERT) {
index1 = uvfinal_map[element1 - state->element_map->buf];
index2 = uvfinal_map[element2 - state->element_map->buf];
}
@@ -561,7 +585,7 @@ static void stitch_island_calculate_edge_rotation(
static void stitch_island_calculate_vert_rotation(
- UvElement *element, StitchState *state,
+ UvElement *element, StitchStateContainer *ssc, StitchState *state,
IslandStitchData *island_stitch_data)
{
float edgecos = 1.0f, edgesin = 0.0f;
@@ -571,7 +595,7 @@ static void stitch_island_calculate_vert_rotation(
int rot_elem = 0, rot_elem_neg = 0;
BMLoop *l;
- if (element->island == state->static_island && !state->midpoints)
+ if (element->island == ssc->static_island && !ssc->midpoints)
return;
l = element->l;
@@ -581,12 +605,12 @@ static void stitch_island_calculate_vert_rotation(
element_iter = state->element_map->vert[index];
for (; element_iter; element_iter = element_iter->next) {
- if (element_iter->separate && stitch_check_uvs_state_stitchable(element, element_iter, state)) {
+ if (element_iter->separate && stitch_check_uvs_state_stitchable(element, element_iter, ssc, state)) {
int index_tmp1, index_tmp2;
float normal[2];
/* only calculate rotation against static island uv verts */
- if (!state->midpoints && element_iter->island != state->static_island)
+ if (!ssc->midpoints && element_iter->island != ssc->static_island)
continue;
index_tmp1 = element_iter - state->element_map->buf;
@@ -608,7 +632,7 @@ static void stitch_island_calculate_vert_rotation(
}
}
- if (state->midpoints) {
+ if (ssc->midpoints) {
rotation /= 2.0f;
rotation_neg /= 2.0f;
}
@@ -622,6 +646,9 @@ static void stitch_island_calculate_vert_rotation(
static void state_delete(StitchState *state)
{
if (state) {
+ if (state->island_is_stitchable) {
+ MEM_freeN(state->island_is_stitchable);
+ }
if (state->element_map) {
BM_uv_element_map_free(state->element_map);
}
@@ -653,6 +680,18 @@ static void state_delete(StitchState *state)
}
}
+static void state_delete_all(StitchStateContainer *ssc)
+{
+ if (ssc) {
+ for (uint ob_index = 0; ob_index < ssc->objects_len; ob_index++) {
+ state_delete(ssc->states[ob_index]);
+ }
+ MEM_freeN(ssc->states);
+ MEM_freeN(ssc->objects);
+ MEM_freeN(ssc);
+ }
+}
+
static void stitch_uv_edge_generate_linked_edges(GHash *edge_hash, StitchState *state)
{
UvEdge *edges = state->edges;
@@ -735,7 +774,7 @@ static void stitch_uv_edge_generate_linked_edges(GHash *edge_hash, StitchState *
/* checks for remote uvs that may be stitched with a certain uv, flags them if stitchable. */
static void determine_uv_stitchability(
- UvElement *element, StitchState *state,
+ UvElement *element, StitchStateContainer *ssc, StitchState *state,
IslandStitchData *island_stitch_data)
{
int vert_index;
@@ -749,7 +788,7 @@ static void determine_uv_stitchability(
for (; element_iter; element_iter = element_iter->next) {
if (element_iter->separate) {
- if (stitch_check_uvs_stitchable(element, element_iter, state)) {
+ if (stitch_check_uvs_stitchable(element, element_iter, ssc, state)) {
island_stitch_data[element_iter->island].stitchableCandidate = 1;
island_stitch_data[element->island].stitchableCandidate = 1;
element->flag |= STITCH_STITCHABLE_CANDIDATE;
@@ -759,13 +798,13 @@ static void determine_uv_stitchability(
}
static void determine_uv_edge_stitchability(
- UvEdge *edge, StitchState *state,
+ UvEdge *edge, StitchStateContainer *ssc, StitchState *state,
IslandStitchData *island_stitch_data)
{
UvEdge *edge_iter = edge->first;
for (; edge_iter; edge_iter = edge_iter->next) {
- if (stitch_check_edges_stitchable(edge, edge_iter, state)) {
+ if (stitch_check_edges_stitchable(edge, edge_iter, ssc, state)) {
island_stitch_data[edge_iter->element->island].stitchableCandidate = 1;
island_stitch_data[edge->element->island].stitchableCandidate = 1;
edge->flag |= STITCH_STITCHABLE_CANDIDATE;
@@ -790,16 +829,16 @@ static void stitch_set_face_preview_buffer_position(
/* setup face preview for all coincident uvs and their faces */
static void stitch_setup_face_preview_for_uv_group(
- UvElement *element, StitchState *state, IslandStitchData *island_stitch_data,
- PreviewPosition *preview_position)
+ UvElement *element, StitchStateContainer *ssc, StitchState *state,
+ IslandStitchData *island_stitch_data, PreviewPosition *preview_position)
{
StitchPreviewer *preview = state->stitch_preview;
/* static island does not change so returning immediately */
- if (state->snap_islands && !state->midpoints && state->static_island == element->island)
+ if (ssc->snap_islands && !ssc->midpoints && ssc->static_island == element->island)
return;
- if (state->snap_islands) {
+ if (ssc->snap_islands) {
island_stitch_data[element->island].addedForPreview = 1;
}
@@ -812,11 +851,18 @@ static void stitch_setup_face_preview_for_uv_group(
/* checks if uvs are indeed stitchable and registers so that they can be shown in preview */
static void stitch_validate_uv_stitchability(
- UvElement *element, StitchState *state, IslandStitchData *island_stitch_data,
- PreviewPosition *preview_position)
+ UvElement *element, StitchStateContainer *ssc, StitchState *state,
+ IslandStitchData *island_stitch_data, PreviewPosition *preview_position)
{
- UvElement *element_iter;
StitchPreviewer *preview = state->stitch_preview;
+
+ /* If not the active object, then it's unstitchable */
+ if (ssc->states[ssc->active_object_index] != state) {
+ preview->num_unstitchable++;
+ return;
+ }
+
+ UvElement *element_iter;
int vert_index;
BMLoop *l;
@@ -830,11 +876,11 @@ static void stitch_validate_uv_stitchability(
if (element_iter->separate) {
if (element_iter == element)
continue;
- if (stitch_check_uvs_state_stitchable(element, element_iter, state)) {
- if ((element_iter->island == state->static_island) || (element->island == state->static_island)) {
+ if (stitch_check_uvs_state_stitchable(element, element_iter, ssc, state)) {
+ if ((element_iter->island == ssc->static_island) || (element->island == ssc->static_island)) {
element->flag |= STITCH_STITCHABLE;
preview->num_stitchable++;
- stitch_setup_face_preview_for_uv_group(element, state, island_stitch_data, preview_position);
+ stitch_setup_face_preview_for_uv_group(element, ssc, state, island_stitch_data, preview_position);
return;
}
}
@@ -849,21 +895,28 @@ static void stitch_validate_uv_stitchability(
static void stitch_validate_edge_stitchability(
- UvEdge *edge, StitchState *state, IslandStitchData *island_stitch_data,
- PreviewPosition *preview_position)
+ UvEdge *edge, StitchStateContainer *ssc, StitchState *state,
+ IslandStitchData *island_stitch_data, PreviewPosition *preview_position)
{
- UvEdge *edge_iter = edge->first;
StitchPreviewer *preview = state->stitch_preview;
+ /* If not the active object, then it's unstitchable */
+ if (ssc->states[ssc->active_object_index] != state) {
+ preview->num_unstitchable++;
+ return;
+ }
+
+ UvEdge *edge_iter = edge->first;
+
for (; edge_iter; edge_iter = edge_iter->next) {
if (edge_iter == edge)
continue;
- if (stitch_check_edges_state_stitchable(edge, edge_iter, state)) {
- if ((edge_iter->element->island == state->static_island) || (edge->element->island == state->static_island)) {
+ if (stitch_check_edges_state_stitchable(edge, edge_iter, ssc, state)) {
+ if ((edge_iter->element->island == ssc->static_island) || (edge->element->island == ssc->static_island)) {
edge->flag |= STITCH_STITCHABLE;
preview->num_stitchable++;
- stitch_setup_face_preview_for_uv_group(state->uvs[edge->uv1], state, island_stitch_data, preview_position);
- stitch_setup_face_preview_for_uv_group(state->uvs[edge->uv2], state, island_stitch_data, preview_position);
+ stitch_setup_face_preview_for_uv_group(state->uvs[edge->uv1], ssc, state, island_stitch_data, preview_position);
+ stitch_setup_face_preview_for_uv_group(state->uvs[edge->uv2], ssc, state, island_stitch_data, preview_position);
return;
}
}
@@ -879,7 +932,7 @@ static void stitch_validate_edge_stitchability(
static void stitch_propagate_uv_final_position(
Scene *scene,
UvElement *element, int index, PreviewPosition *preview_position,
- UVVertAverage *final_position, StitchState *state,
+ UVVertAverage *final_position, StitchStateContainer *ssc, StitchState *state,
const bool final)
{
BMesh *bm = state->em->bm;
@@ -907,13 +960,13 @@ static void stitch_propagate_uv_final_position(
else {
int face_preview_pos = preview_position[BM_elem_index_get(element_iter->l->f)].data_position;
if (face_preview_pos != STITCH_NO_PREVIEW) {
- copy_v2_v2(preview->preview_polys + face_preview_pos + 2 * element_iter->tfindex,
- final_position[index].uv);
+ copy_v2_v2(preview->preview_polys + face_preview_pos + 2 * element_iter->loop_of_poly_index,
+ final_position[index].uv);
}
}
/* end of calculations, keep only the selection flag */
- if ((!state->snap_islands) || ((!state->midpoints) && (element_iter->island == state->static_island))) {
+ if ((!ssc->snap_islands) || ((!ssc->midpoints) && (element_iter->island == ssc->static_island))) {
element_iter->flag &= STITCH_SELECTED;
}
@@ -923,18 +976,20 @@ static void stitch_propagate_uv_final_position(
}
/* main processing function. It calculates preview and final positions. */
-static int stitch_process_data(StitchState *state, Scene *scene, int final)
+static int stitch_process_data(
+ StitchStateContainer *ssc, StitchState *state, Scene *scene, int final)
{
int i;
StitchPreviewer *preview;
IslandStitchData *island_stitch_data = NULL;
- int previous_island = state->static_island;
+ int previous_island = ssc->static_island;
BMesh *bm = state->em->bm;
BMFace *efa;
BMIter iter;
UVVertAverage *final_position = NULL;
+ bool is_active_state = (state == ssc->states[ssc->active_object_index]);
- char stitch_midpoints = state->midpoints;
+ char stitch_midpoints = ssc->midpoints;
/* used to map uv indices to uvaverage indices for selection */
unsigned int *uvfinal_map = NULL;
/* per face preview position in preview buffer */
@@ -965,32 +1020,41 @@ static int stitch_process_data(StitchState *state, Scene *scene, int final)
*****************************************/
for (i = 0; i < state->selection_size; i++) {
- if (state->mode == STITCH_VERT) {
+ if (ssc->mode == STITCH_VERT) {
UvElement *element = (UvElement *)state->selection_stack[i];
- determine_uv_stitchability(element, state, island_stitch_data);
+ determine_uv_stitchability(element, ssc, state, island_stitch_data);
}
else {
UvEdge *edge = (UvEdge *)state->selection_stack[i];
- determine_uv_edge_stitchability(edge, state, island_stitch_data);
+ determine_uv_edge_stitchability(edge, ssc, state, island_stitch_data);
}
}
- /* set static island to one that is added for preview */
- state->static_island %= state->element_map->totalIslands;
- while (!(island_stitch_data[state->static_island].stitchableCandidate)) {
- state->static_island++;
- state->static_island %= state->element_map->totalIslands;
- /* this is entirely possible if for example limit stitching with no stitchable verts or no selection */
- if (state->static_island == previous_island)
- break;
+ /* remember stitchable candidates as places the 'I' button */
+ /* will stop at. */
+ for (int island_idx = 0; island_idx < state->element_map->totalIslands; island_idx++) {
+ state->island_is_stitchable[island_idx] = island_stitch_data[island_idx].stitchableCandidate ? true : false;
+ }
+
+ if (is_active_state) {
+ /* set static island to one that is added for preview */
+ ssc->static_island %= state->element_map->totalIslands;
+ while (!(island_stitch_data[ssc->static_island].stitchableCandidate)) {
+ ssc->static_island++;
+ ssc->static_island %= state->element_map->totalIslands;
+ /* this is entirely possible if for example limit stitching with no stitchable verts or no selection */
+ if (ssc->static_island == previous_island) {
+ break;
+ }
+ }
}
for (i = 0; i < state->selection_size; i++) {
- if (state->mode == STITCH_VERT) {
+ if (ssc->mode == STITCH_VERT) {
UvElement *element = (UvElement *)state->selection_stack[i];
if (element->flag & STITCH_STITCHABLE_CANDIDATE) {
element->flag &= ~STITCH_STITCHABLE_CANDIDATE;
- stitch_validate_uv_stitchability(element, state, island_stitch_data, preview_position);
+ stitch_validate_uv_stitchability(element, ssc, state, island_stitch_data, preview_position);
}
else {
/* add to preview for unstitchable */
@@ -1001,7 +1065,7 @@ static int stitch_process_data(StitchState *state, Scene *scene, int final)
UvEdge *edge = (UvEdge *)state->selection_stack[i];
if (edge->flag & STITCH_STITCHABLE_CANDIDATE) {
edge->flag &= ~STITCH_STITCHABLE_CANDIDATE;
- stitch_validate_edge_stitchability(edge, state, island_stitch_data, preview_position);
+ stitch_validate_edge_stitchability(edge, ssc, state, island_stitch_data, preview_position);
}
else {
preview->num_unstitchable++;
@@ -1009,10 +1073,90 @@ static int stitch_process_data(StitchState *state, Scene *scene, int final)
}
}
+ /*********************************************************************
+ * Setup the stitchable & unstitchable preview buffers and fill *
+ * them with the appropriate data *
+ *********************************************************************/
+ if (!final) {
+ BMLoop *l;
+ MLoopUV *luv;
+ int stitchBufferIndex = 0, unstitchBufferIndex = 0;
+ int preview_size = (ssc->mode == STITCH_VERT) ? 2 : 4;
+ /* initialize the preview buffers */
+ preview->preview_stitchable = (float *)MEM_mallocN(preview->num_stitchable * sizeof(float) * preview_size, "stitch_preview_stitchable_data");
+ preview->preview_unstitchable = (float *)MEM_mallocN(preview->num_unstitchable * sizeof(float) * preview_size, "stitch_preview_unstitchable_data");
+
+ /* will cause cancel and freeing of all data structures so OK */
+ if (!preview->preview_stitchable || !preview->preview_unstitchable) {
+ return 0;
+ }
+
+ /* fill the appropriate preview buffers */
+ if (ssc->mode == STITCH_VERT) {
+ for (i = 0; i < state->total_separate_uvs; i++) {
+ UvElement *element = (UvElement *)state->uvs[i];
+ if (element->flag & STITCH_STITCHABLE) {
+ l = element->l;
+ luv = CustomData_bmesh_get(&bm->ldata, l->head.data, CD_MLOOPUV);
+
+ copy_v2_v2(&preview->preview_stitchable[stitchBufferIndex * 2], luv->uv);
+
+ stitchBufferIndex++;
+ }
+ else if (element->flag & STITCH_SELECTED) {
+ l = element->l;
+ luv = CustomData_bmesh_get(&bm->ldata, l->head.data, CD_MLOOPUV);
+
+ copy_v2_v2(&preview->preview_unstitchable[unstitchBufferIndex * 2], luv->uv);
+ unstitchBufferIndex++;
+ }
+ }
+ }
+ else {
+ for (i = 0; i < state->total_separate_edges; i++) {
+ UvEdge *edge = state->edges + i;
+ UvElement *element1 = state->uvs[edge->uv1];
+ UvElement *element2 = state->uvs[edge->uv2];
+
+ if (edge->flag & STITCH_STITCHABLE) {
+ l = element1->l;
+ luv = CustomData_bmesh_get(&bm->ldata, l->head.data, CD_MLOOPUV);
+ copy_v2_v2(&preview->preview_stitchable[stitchBufferIndex * 4], luv->uv);
+
+ l = element2->l;
+ luv = CustomData_bmesh_get(&bm->ldata, l->head.data, CD_MLOOPUV);
+ copy_v2_v2(&preview->preview_stitchable[stitchBufferIndex * 4 + 2], luv->uv);
+
+ stitchBufferIndex++;
+ BLI_assert(stitchBufferIndex <= preview->num_stitchable);
+ }
+ else if (edge->flag & STITCH_SELECTED) {
+ l = element1->l;
+ luv = CustomData_bmesh_get(&bm->ldata, l->head.data, CD_MLOOPUV);
+ copy_v2_v2(&preview->preview_unstitchable[unstitchBufferIndex * 4], luv->uv);
+
+ l = element2->l;
+ luv = CustomData_bmesh_get(&bm->ldata, l->head.data, CD_MLOOPUV);
+ copy_v2_v2(&preview->preview_unstitchable[unstitchBufferIndex * 4 + 2], luv->uv);
+
+ unstitchBufferIndex++;
+ BLI_assert(unstitchBufferIndex <= preview->num_unstitchable);
+ }
+ }
+ }
+ }
+
+ if (ssc->states[ssc->active_object_index] != state) {
+ /* This is not the active object/state, exit here */
+ MEM_freeN(island_stitch_data);
+ MEM_freeN(preview_position);
+ return 1;
+ }
+
/*****************************************
* Setup preview for stitchable islands *
*****************************************/
- if (state->snap_islands) {
+ if (ssc->snap_islands) {
for (i = 0; i < state->element_map->totalIslands; i++) {
if (island_stitch_data[i].addedForPreview) {
int numOfIslandUVs = 0, j;
@@ -1027,26 +1171,24 @@ static int stitch_process_data(StitchState *state, Scene *scene, int final)
}
/*********************************************************************
- * Setup the preview buffers and fill them with the appropriate data *
+ * Setup the remaining preview buffers and fill them with the *
+ * appropriate data *
*********************************************************************/
if (!final) {
BMIter liter;
BMLoop *l;
MLoopUV *luv;
unsigned int buffer_index = 0;
- int stitchBufferIndex = 0, unstitchBufferIndex = 0;
- int preview_size = (state->mode == STITCH_VERT) ? 2 : 4;
+
/* initialize the preview buffers */
preview->preview_polys = (float *)MEM_mallocN(preview->preview_uvs * sizeof(float) * 2, "tri_uv_stitch_prev");
preview->uvs_per_polygon = MEM_mallocN(preview->num_polys * sizeof(*preview->uvs_per_polygon), "tri_uv_stitch_prev");
- preview->preview_stitchable = (float *)MEM_mallocN(preview->num_stitchable * sizeof(float) * preview_size, "stitch_preview_stitchable_data");
- preview->preview_unstitchable = (float *)MEM_mallocN(preview->num_unstitchable * sizeof(float) * preview_size, "stitch_preview_unstitchable_data");
- preview->static_tris = (float *)MEM_mallocN(state->tris_per_island[state->static_island] * sizeof(float) * 6, "static_island_preview_tris");
+ preview->static_tris = (float *)MEM_mallocN(state->tris_per_island[ssc->static_island] * sizeof(float) * 6, "static_island_preview_tris");
- preview->num_static_tris = state->tris_per_island[state->static_island];
+ preview->num_static_tris = state->tris_per_island[ssc->static_island];
/* will cause cancel and freeing of all data structures so OK */
- if (!preview->preview_polys || !preview->preview_stitchable || !preview->preview_unstitchable) {
+ if (!preview->preview_polys) {
return 0;
}
@@ -1067,7 +1209,8 @@ static int stitch_process_data(StitchState *state, Scene *scene, int final)
}
}
- if (element->island == state->static_island) {
+ /* if this is the static_island on the active object */
+ if (element->island == ssc->static_island) {
BMLoop *fl = BM_FACE_FIRST_LOOP(efa);
MLoopUV *fuv = CustomData_bmesh_get(&bm->ldata, fl->head.data, CD_MLOOPUV);
@@ -1090,67 +1233,13 @@ static int stitch_process_data(StitchState *state, Scene *scene, int final)
}
}
}
-
- /* fill the appropriate preview buffers */
- if (state->mode == STITCH_VERT) {
- for (i = 0; i < state->total_separate_uvs; i++) {
- UvElement *element = (UvElement *)state->uvs[i];
- if (element->flag & STITCH_STITCHABLE) {
- l = element->l;
- luv = CustomData_bmesh_get(&bm->ldata, l->head.data, CD_MLOOPUV);
-
- copy_v2_v2(&preview->preview_stitchable[stitchBufferIndex * 2], luv->uv);
-
- stitchBufferIndex++;
- }
- else if (element->flag & STITCH_SELECTED) {
- l = element->l;
- luv = CustomData_bmesh_get(&bm->ldata, l->head.data, CD_MLOOPUV);
-
- copy_v2_v2(&preview->preview_unstitchable[unstitchBufferIndex * 2], luv->uv);
- unstitchBufferIndex++;
- }
- }
- }
- else {
- for (i = 0; i < state->total_separate_edges; i++) {
- UvEdge *edge = state->edges + i;
- UvElement *element1 = state->uvs[edge->uv1];
- UvElement *element2 = state->uvs[edge->uv2];
-
- if (edge->flag & STITCH_STITCHABLE) {
- l = element1->l;
- luv = CustomData_bmesh_get(&bm->ldata, l->head.data, CD_MLOOPUV);
- copy_v2_v2(&preview->preview_stitchable[stitchBufferIndex * 4], luv->uv);
-
- l = element2->l;
- luv = CustomData_bmesh_get(&bm->ldata, l->head.data, CD_MLOOPUV);
- copy_v2_v2(&preview->preview_stitchable[stitchBufferIndex * 4 + 2], luv->uv);
-
- stitchBufferIndex++;
- BLI_assert(stitchBufferIndex <= preview->num_stitchable);
- }
- else if (edge->flag & STITCH_SELECTED) {
- l = element1->l;
- luv = CustomData_bmesh_get(&bm->ldata, l->head.data, CD_MLOOPUV);
- copy_v2_v2(&preview->preview_unstitchable[unstitchBufferIndex * 4], luv->uv);
-
- l = element2->l;
- luv = CustomData_bmesh_get(&bm->ldata, l->head.data, CD_MLOOPUV);
- copy_v2_v2(&preview->preview_unstitchable[unstitchBufferIndex * 4 + 2], luv->uv);
-
- unstitchBufferIndex++;
- BLI_assert(unstitchBufferIndex <= preview->num_unstitchable);
- }
- }
- }
}
/******************************************************
* Here we calculate the final coordinates of the uvs *
******************************************************/
- if (state->mode == STITCH_VERT) {
+ if (ssc->mode == STITCH_VERT) {
final_position = MEM_callocN(state->selection_size * sizeof(*final_position), "stitch_uv_average");
uvfinal_map = MEM_mallocN(state->element_map->totalUVs * sizeof(*uvfinal_map), "stitch_uv_final_map");
}
@@ -1160,7 +1249,7 @@ static int stitch_process_data(StitchState *state, Scene *scene, int final)
/* first pass, calculate final position for stitchable uvs of the static island */
for (i = 0; i < state->selection_size; i++) {
- if (state->mode == STITCH_VERT) {
+ if (ssc->mode == STITCH_VERT) {
UvElement *element = state->selection_stack[i];
if (element->flag & STITCH_STITCHABLE) {
@@ -1176,21 +1265,21 @@ static int stitch_process_data(StitchState *state, Scene *scene, int final)
copy_v2_v2(final_position[i].uv, luv->uv);
final_position[i].count = 1;
- if (state->snap_islands && element->island == state->static_island && !stitch_midpoints)
+ if (ssc->snap_islands && element->island == ssc->static_island && !stitch_midpoints)
continue;
element_iter = state->element_map->vert[BM_elem_index_get(l->v)];
for ( ; element_iter; element_iter = element_iter->next) {
if (element_iter->separate) {
- if (stitch_check_uvs_state_stitchable(element, element_iter, state)) {
+ if (stitch_check_uvs_state_stitchable(element, element_iter, ssc, state)) {
l = element_iter->l;
luv = CustomData_bmesh_get(&bm->ldata, l->head.data, CD_MLOOPUV);
if (stitch_midpoints) {
add_v2_v2(final_position[i].uv, luv->uv);
final_position[i].count++;
}
- else if (element_iter->island == state->static_island) {
+ else if (element_iter->island == ssc->static_island) {
/* if multiple uvs on the static island exist,
* last checked remains. to disambiguate we need to limit or use
* edge stitch */
@@ -1226,11 +1315,11 @@ static int stitch_process_data(StitchState *state, Scene *scene, int final)
state->uvs[edge->uv1]->flag |= STITCH_STITCHABLE;
state->uvs[edge->uv2]->flag |= STITCH_STITCHABLE;
- if (state->snap_islands && edge->element->island == state->static_island && !stitch_midpoints)
+ if (ssc->snap_islands && edge->element->island == ssc->static_island && !stitch_midpoints)
continue;
for (edge_iter = edge->first; edge_iter; edge_iter = edge_iter->next) {
- if (stitch_check_edges_state_stitchable (edge, edge_iter, state)) {
+ if (stitch_check_edges_state_stitchable(edge, edge_iter, ssc, state)) {
l = state->uvs[edge_iter->uv1]->l;
luv1 = CustomData_bmesh_get(&bm->ldata, l->head.data, CD_MLOOPUV);
l = state->uvs[edge_iter->uv2]->l;
@@ -1242,7 +1331,7 @@ static int stitch_process_data(StitchState *state, Scene *scene, int final)
add_v2_v2(final_position[edge->uv2].uv, luv2->uv);
final_position[edge->uv2].count++;
}
- else if (edge_iter->element->island == state->static_island) {
+ else if (edge_iter->element->island == ssc->static_island) {
copy_v2_v2(final_position[edge->uv1].uv, luv1->uv);
copy_v2_v2(final_position[edge->uv2].uv, luv2->uv);
}
@@ -1253,7 +1342,7 @@ static int stitch_process_data(StitchState *state, Scene *scene, int final)
}
/* take mean position here. For edge case, this can't be done inside the loop for shared uvverts */
- if (state->mode == STITCH_EDGE && stitch_midpoints) {
+ if (ssc->mode == STITCH_EDGE && stitch_midpoints) {
for (i = 0; i < state->total_separate_uvs; i++) {
final_position[i].uv[0] /= final_position[i].count;
final_position[i].uv[1] /= final_position[i].count;
@@ -1261,8 +1350,8 @@ static int stitch_process_data(StitchState *state, Scene *scene, int final)
}
/* second pass, calculate island rotation and translation before modifying any uvs */
- if (state->snap_islands) {
- if (state->mode == STITCH_VERT) {
+ if (ssc->snap_islands) {
+ if (ssc->mode == STITCH_VERT) {
for (i = 0; i < state->selection_size; i++) {
UvElement *element = state->selection_stack[i];
@@ -1290,13 +1379,13 @@ static int stitch_process_data(StitchState *state, Scene *scene, int final)
(state->uvs[edge->uv1]->flag & STITCH_STITCHABLE) &&
(state->uvs[edge->uv2]->flag & STITCH_STITCHABLE))
{
- stitch_island_calculate_edge_rotation(edge, state, final_position, uvfinal_map, island_stitch_data);
+ stitch_island_calculate_edge_rotation(edge, ssc, state, final_position, uvfinal_map, island_stitch_data);
island_stitch_data[state->uvs[edge->uv1]->island].use_edge_rotation = true;
}
}
/* clear seams of stitched edges */
- if (final && state->clear_seams) {
+ if (final && ssc->clear_seams) {
for (i = 0; i < state->total_separate_edges; i++) {
UvEdge *edge = state->edges + i;
if ((state->uvs[edge->uv1]->flag & STITCH_STITCHABLE) &&
@@ -1311,7 +1400,7 @@ static int stitch_process_data(StitchState *state, Scene *scene, int final)
UvElement *element = state->selection_stack[i];
if (!island_stitch_data[element->island].use_edge_rotation) {
if (element->flag & STITCH_STITCHABLE) {
- stitch_island_calculate_vert_rotation(element, state, island_stitch_data);
+ stitch_island_calculate_vert_rotation(element, ssc, state, island_stitch_data);
}
}
}
@@ -1328,7 +1417,7 @@ static int stitch_process_data(StitchState *state, Scene *scene, int final)
luv = CustomData_bmesh_get(&bm->ldata, l->head.data, CD_MLOOPUV);
/* accumulate each islands' translation from stitchable elements. it is important to do here
- * because in final pass MTFaces get modified and result is zero. */
+ * because in final pass MTFaces get modified and result is zero. */
island_stitch_data[element->island].translation[0] += final_position[i].uv[0] - luv->uv[0];
island_stitch_data[element->island].translation[1] += final_position[i].uv[1] - luv->uv[1];
island_stitch_data[element->island].medianPoint[0] += luv->uv[0];
@@ -1341,13 +1430,13 @@ static int stitch_process_data(StitchState *state, Scene *scene, int final)
UvEdge *edge = state->selection_stack[i];
if (edge->flag & STITCH_STITCHABLE) {
- stitch_island_calculate_edge_rotation(edge, state, final_position, NULL, island_stitch_data);
+ stitch_island_calculate_edge_rotation(edge, ssc, state, final_position, NULL, island_stitch_data);
island_stitch_data[state->uvs[edge->uv1]->island].use_edge_rotation = true;
}
}
/* clear seams of stitched edges */
- if (final && state->clear_seams) {
+ if (final && ssc->clear_seams) {
for (i = 0; i < state->selection_size; i++) {
UvEdge *edge = state->selection_stack[i];
if (edge->flag & STITCH_STITCHABLE) {
@@ -1360,30 +1449,30 @@ static int stitch_process_data(StitchState *state, Scene *scene, int final)
/* third pass, propagate changes to coincident uvs */
for (i = 0; i < state->selection_size; i++) {
- if (state->mode == STITCH_VERT) {
+ if (ssc->mode == STITCH_VERT) {
UvElement *element = state->selection_stack[i];
- stitch_propagate_uv_final_position(scene, element, i, preview_position, final_position, state, final);
+ stitch_propagate_uv_final_position(scene, element, i, preview_position, final_position, ssc, state, final);
}
else {
UvEdge *edge = state->selection_stack[i];
stitch_propagate_uv_final_position(
- scene, state->uvs[edge->uv1], edge->uv1, preview_position, final_position, state, final);
+ scene, state->uvs[edge->uv1], edge->uv1, preview_position, final_position, ssc, state, final);
stitch_propagate_uv_final_position(
- scene, state->uvs[edge->uv2], edge->uv2, preview_position, final_position, state, final);
+ scene, state->uvs[edge->uv2], edge->uv2, preview_position, final_position, ssc, state, final);
edge->flag &= (STITCH_SELECTED | STITCH_BOUNDARY);
}
}
/* final pass, calculate Island translation/rotation if needed */
- if (state->snap_islands) {
+ if (ssc->snap_islands) {
stitch_calculate_island_snapping(state, preview_position, preview, island_stitch_data, final);
}
MEM_freeN(final_position);
- if (state->mode == STITCH_VERT) {
+ if (ssc->mode == STITCH_VERT) {
MEM_freeN(uvfinal_map);
}
MEM_freeN(island_stitch_data);
@@ -1392,6 +1481,17 @@ static int stitch_process_data(StitchState *state, Scene *scene, int final)
return 1;
}
+static int stitch_process_data_all(StitchStateContainer *ssc, Scene *scene, int final)
+{
+ for (uint ob_index = 0; ob_index < ssc->objects_len; ob_index++) {
+ if (!stitch_process_data(ssc, ssc->states[ob_index], scene, final)) {
+ return 0;
+ }
+ }
+
+ return 1;
+}
+
/* Stitch hash initialization functions */
static unsigned int uv_edge_hash(const void *key)
{
@@ -1476,13 +1576,13 @@ static void stitch_select_uv(UvElement *element, StitchState *state, int always_
}
}
-static void stitch_switch_selection_mode(StitchState *state)
+static void stitch_set_selection_mode(StitchState *state, const char from_stitch_mode)
{
void **old_selection_stack = state->selection_stack;
int old_selection_size = state->selection_size;
state->selection_size = 0;
- if (state->mode == STITCH_VERT) {
+ if (from_stitch_mode == STITCH_VERT) {
int i;
state->selection_stack = MEM_mallocN(state->total_separate_edges * sizeof(*state->selection_stack),
"stitch_new_edge_selection_stack");
@@ -1503,7 +1603,6 @@ static void stitch_switch_selection_mode(StitchState *state)
element->flag &= ~STITCH_SELECTED;
}
- state->mode = STITCH_EDGE;
}
else {
int i;
@@ -1520,12 +1619,26 @@ static void stitch_switch_selection_mode(StitchState *state)
edge->flag &= ~STITCH_SELECTED;
}
- state->mode = STITCH_VERT;
}
MEM_freeN(old_selection_stack);
}
-static void stitch_calculate_edge_normal(BMEditMesh *em, UvEdge *edge, float *normal, float aspect)
+static void stitch_switch_selection_mode_all(StitchStateContainer *ssc)
+{
+ for (uint ob_index = 0; ob_index < ssc->objects_len; ob_index++) {
+ stitch_set_selection_mode(ssc->states[ob_index], ssc->mode);
+ }
+
+ if (ssc->mode == STITCH_VERT) {
+ ssc->mode = STITCH_EDGE;
+ }
+ else {
+ ssc->mode = STITCH_VERT;
+ }
+}
+
+static void stitch_calculate_edge_normal(
+ BMEditMesh *em, UvEdge *edge, float *normal, float aspect)
{
BMLoop *l1 = edge->element->l;
MLoopUV *luv1, *luv2;
@@ -1534,7 +1647,7 @@ static void stitch_calculate_edge_normal(BMEditMesh *em, UvEdge *edge, float *no
luv1 = CustomData_bmesh_get(&em->bm->ldata, l1->head.data, CD_MLOOPUV);
luv2 = CustomData_bmesh_get(&em->bm->ldata, l1->next->head.data, CD_MLOOPUV);
- sub_v2_v2v2(tangent, luv2->uv, luv1->uv);
+ sub_v2_v2v2(tangent, luv2->uv, luv1->uv);
tangent[1] /= aspect;
@@ -1546,123 +1659,132 @@ static void stitch_calculate_edge_normal(BMEditMesh *em, UvEdge *edge, float *no
/**
*/
-static void stitch_draw_vbo(Gwn_VertBuf *vbo, Gwn_PrimType prim_type, const float col[4])
+static void stitch_draw_vbo(GPUVertBuf *vbo, GPUPrimType prim_type, const float col[4])
{
- Gwn_Batch *batch = GWN_batch_create_ex(prim_type, vbo, NULL, GWN_BATCH_OWNS_VBO);
- GWN_batch_program_set_builtin(batch, GPU_SHADER_2D_UNIFORM_COLOR);
- GWN_batch_uniform_4fv(batch, "color", col);
- GWN_batch_draw(batch);
- GWN_batch_discard(batch);
+ GPUBatch *batch = GPU_batch_create_ex(prim_type, vbo, NULL, GPU_BATCH_OWNS_VBO);
+ GPU_batch_program_set_builtin(batch, GPU_SHADER_2D_UNIFORM_COLOR);
+ GPU_batch_uniform_4fv(batch, "color", col);
+ GPU_batch_draw(batch);
+ GPU_batch_discard(batch);
}
/* TODO make things pretier : store batches inside StitchPreviewer instead of the bare verts pos */
static void stitch_draw(const bContext *UNUSED(C), ARegion *UNUSED(ar), void *arg)
{
- int j, index = 0;
- unsigned int num_line = 0, num_tri, tri_idx = 0, line_idx = 0;
- StitchState *state = (StitchState *)arg;
- StitchPreviewer *stitch_preview = state->stitch_preview;
- Gwn_VertBuf *vbo, *vbo_line;
- float col[4];
-
- static Gwn_VertFormat format = { 0 };
- static unsigned int pos_id;
- if (format.attr_len == 0) {
- pos_id = GWN_vertformat_attr_add(&format, "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
- }
- GPU_blend(true);
+ StitchStateContainer *ssc = (StitchStateContainer *)arg;
- /* Static Tris */
- UI_GetThemeColor4fv(TH_STITCH_PREVIEW_ACTIVE, col);
- vbo = GWN_vertbuf_create_with_format(&format);
- GWN_vertbuf_data_alloc(vbo, stitch_preview->num_static_tris * 3);
- for (int i = 0; i < stitch_preview->num_static_tris * 3; i++) {
- GWN_vertbuf_attr_set(vbo, pos_id, i, &stitch_preview->static_tris[i * 2]);
- }
- stitch_draw_vbo(vbo, GWN_PRIM_TRIS, col);
+ for (uint ob_index = 0; ob_index < ssc->objects_len; ob_index++) {
+ int j, index = 0;
+ unsigned int num_line = 0, num_tri, tri_idx = 0, line_idx = 0;
+ StitchState *state = ssc->states[ob_index];
+ StitchPreviewer *stitch_preview = state->stitch_preview;
+ GPUVertBuf *vbo, *vbo_line;
+ float col[4];
+ static GPUVertFormat format = { 0 };
+ static unsigned int pos_id;
+ if (format.attr_len == 0) {
+ pos_id = GPU_vertformat_attr_add(&format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
+ }
- /* Preview Polys */
- for (int i = 0; i < stitch_preview->num_polys; i++)
- num_line += stitch_preview->uvs_per_polygon[i];
+ GPU_blend(true);
- num_tri = num_line - 2 * stitch_preview->num_polys;
+ /* Static Tris */
+ if (stitch_preview->static_tris) {
+ UI_GetThemeColor4fv(TH_STITCH_PREVIEW_ACTIVE, col);
+ vbo = GPU_vertbuf_create_with_format(&format);
+ GPU_vertbuf_data_alloc(vbo, stitch_preview->num_static_tris * 3);
+ for (int i = 0; i < stitch_preview->num_static_tris * 3; i++) {
+ GPU_vertbuf_attr_set(vbo, pos_id, i, &stitch_preview->static_tris[i * 2]);
+ }
+ stitch_draw_vbo(vbo, GPU_PRIM_TRIS, col);
+ }
- /* we need to convert the polys into triangles / lines */
- vbo = GWN_vertbuf_create_with_format(&format);
- vbo_line = GWN_vertbuf_create_with_format(&format);
+ /* Preview Polys */
+ if (stitch_preview->preview_polys) {
+ for (int i = 0; i < stitch_preview->num_polys; i++)
+ num_line += stitch_preview->uvs_per_polygon[i];
- GWN_vertbuf_data_alloc(vbo, num_tri * 3);
- GWN_vertbuf_data_alloc(vbo_line, num_line * 2);
+ num_tri = num_line - 2 * stitch_preview->num_polys;
- for (int i = 0; i < stitch_preview->num_polys; i++) {
- BLI_assert(stitch_preview->uvs_per_polygon[i] >= 3);
+ /* we need to convert the polys into triangles / lines */
+ vbo = GPU_vertbuf_create_with_format(&format);
+ vbo_line = GPU_vertbuf_create_with_format(&format);
- /* Start line */
- GWN_vertbuf_attr_set(vbo_line, pos_id, line_idx++, &stitch_preview->preview_polys[index]);
- GWN_vertbuf_attr_set(vbo_line, pos_id, line_idx++, &stitch_preview->preview_polys[index + 2]);
+ GPU_vertbuf_data_alloc(vbo, num_tri * 3);
+ GPU_vertbuf_data_alloc(vbo_line, num_line * 2);
- for (j = 1; j < stitch_preview->uvs_per_polygon[i] - 1; ++j) {
- GWN_vertbuf_attr_set(vbo, pos_id, tri_idx++, &stitch_preview->preview_polys[index]);
- GWN_vertbuf_attr_set(vbo, pos_id, tri_idx++, &stitch_preview->preview_polys[index + (j + 0) * 2]);
- GWN_vertbuf_attr_set(vbo, pos_id, tri_idx++, &stitch_preview->preview_polys[index + (j + 1) * 2]);
- GWN_vertbuf_attr_set(vbo_line, pos_id, line_idx++, &stitch_preview->preview_polys[index + (j + 0) * 2]);
- GWN_vertbuf_attr_set(vbo_line, pos_id, line_idx++, &stitch_preview->preview_polys[index + (j + 1) * 2]);
- }
+ for (int i = 0; i < stitch_preview->num_polys; i++) {
+ BLI_assert(stitch_preview->uvs_per_polygon[i] >= 3);
- /* Closing line */
- GWN_vertbuf_attr_set(vbo_line, pos_id, line_idx++, &stitch_preview->preview_polys[index]);
- /* j = uvs_per_polygon[i] - 1*/
- GWN_vertbuf_attr_set(vbo_line, pos_id, line_idx++, &stitch_preview->preview_polys[index + j * 2]);
+ /* Start line */
+ GPU_vertbuf_attr_set(vbo_line, pos_id, line_idx++, &stitch_preview->preview_polys[index]);
+ GPU_vertbuf_attr_set(vbo_line, pos_id, line_idx++, &stitch_preview->preview_polys[index + 2]);
- index += stitch_preview->uvs_per_polygon[i] * 2;
- }
- UI_GetThemeColor4fv(TH_STITCH_PREVIEW_FACE, col);
- stitch_draw_vbo(vbo, GWN_PRIM_TRIS, col);
- UI_GetThemeColor4fv(TH_STITCH_PREVIEW_EDGE, col);
- stitch_draw_vbo(vbo_line, GWN_PRIM_LINES, col);
+ for (j = 1; j < stitch_preview->uvs_per_polygon[i] - 1; ++j) {
+ GPU_vertbuf_attr_set(vbo, pos_id, tri_idx++, &stitch_preview->preview_polys[index]);
+ GPU_vertbuf_attr_set(vbo, pos_id, tri_idx++, &stitch_preview->preview_polys[index + (j + 0) * 2]);
+ GPU_vertbuf_attr_set(vbo, pos_id, tri_idx++, &stitch_preview->preview_polys[index + (j + 1) * 2]);
- GPU_blend(false);
+ GPU_vertbuf_attr_set(vbo_line, pos_id, line_idx++, &stitch_preview->preview_polys[index + (j + 0) * 2]);
+ GPU_vertbuf_attr_set(vbo_line, pos_id, line_idx++, &stitch_preview->preview_polys[index + (j + 1) * 2]);
+ }
+ /* Closing line */
+ GPU_vertbuf_attr_set(vbo_line, pos_id, line_idx++, &stitch_preview->preview_polys[index]);
+ /* j = uvs_per_polygon[i] - 1*/
+ GPU_vertbuf_attr_set(vbo_line, pos_id, line_idx++, &stitch_preview->preview_polys[index + j * 2]);
- /* draw stitch vert/lines preview */
- if (state->mode == STITCH_VERT) {
- GPU_point_size(UI_GetThemeValuef(TH_VERTEX_SIZE) * 2.0f);
+ index += stitch_preview->uvs_per_polygon[i] * 2;
+ }
- UI_GetThemeColor4fv(TH_STITCH_PREVIEW_STITCHABLE, col);
- vbo = GWN_vertbuf_create_with_format(&format);
- GWN_vertbuf_data_alloc(vbo, stitch_preview->num_stitchable);
- for (int i = 0; i < stitch_preview->num_stitchable; i++) {
- GWN_vertbuf_attr_set(vbo, pos_id, i, &stitch_preview->preview_stitchable[i * 2]);
+ UI_GetThemeColor4fv(TH_STITCH_PREVIEW_FACE, col);
+ stitch_draw_vbo(vbo, GPU_PRIM_TRIS, col);
+ UI_GetThemeColor4fv(TH_STITCH_PREVIEW_EDGE, col);
+ stitch_draw_vbo(vbo_line, GPU_PRIM_LINES, col);
}
- stitch_draw_vbo(vbo, GWN_PRIM_POINTS, col);
- UI_GetThemeColor4fv(TH_STITCH_PREVIEW_UNSTITCHABLE, col);
- vbo = GWN_vertbuf_create_with_format(&format);
- GWN_vertbuf_data_alloc(vbo, stitch_preview->num_unstitchable);
- for (int i = 0; i < stitch_preview->num_unstitchable; i++) {
- GWN_vertbuf_attr_set(vbo, pos_id, i, &stitch_preview->preview_unstitchable[i * 2]);
- }
- stitch_draw_vbo(vbo, GWN_PRIM_POINTS, col);
- }
- else {
- UI_GetThemeColor4fv(TH_STITCH_PREVIEW_STITCHABLE, col);
- vbo = GWN_vertbuf_create_with_format(&format);
- GWN_vertbuf_data_alloc(vbo, stitch_preview->num_stitchable * 2);
- for (int i = 0; i < stitch_preview->num_stitchable * 2; i++) {
- GWN_vertbuf_attr_set(vbo, pos_id, i, &stitch_preview->preview_stitchable[i * 2]);
+ GPU_blend(false);
+
+ /* draw stitch vert/lines preview */
+ if (ssc->mode == STITCH_VERT) {
+ GPU_point_size(UI_GetThemeValuef(TH_VERTEX_SIZE) * 2.0f);
+
+ UI_GetThemeColor4fv(TH_STITCH_PREVIEW_STITCHABLE, col);
+ vbo = GPU_vertbuf_create_with_format(&format);
+ GPU_vertbuf_data_alloc(vbo, stitch_preview->num_stitchable);
+ for (int i = 0; i < stitch_preview->num_stitchable; i++) {
+ GPU_vertbuf_attr_set(vbo, pos_id, i, &stitch_preview->preview_stitchable[i * 2]);
+ }
+ stitch_draw_vbo(vbo, GPU_PRIM_POINTS, col);
+
+ UI_GetThemeColor4fv(TH_STITCH_PREVIEW_UNSTITCHABLE, col);
+ vbo = GPU_vertbuf_create_with_format(&format);
+ GPU_vertbuf_data_alloc(vbo, stitch_preview->num_unstitchable);
+ for (int i = 0; i < stitch_preview->num_unstitchable; i++) {
+ GPU_vertbuf_attr_set(vbo, pos_id, i, &stitch_preview->preview_unstitchable[i * 2]);
+ }
+ stitch_draw_vbo(vbo, GPU_PRIM_POINTS, col);
}
- stitch_draw_vbo(vbo, GWN_PRIM_LINES, col);
+ else {
+ UI_GetThemeColor4fv(TH_STITCH_PREVIEW_STITCHABLE, col);
+ vbo = GPU_vertbuf_create_with_format(&format);
+ GPU_vertbuf_data_alloc(vbo, stitch_preview->num_stitchable * 2);
+ for (int i = 0; i < stitch_preview->num_stitchable * 2; i++) {
+ GPU_vertbuf_attr_set(vbo, pos_id, i, &stitch_preview->preview_stitchable[i * 2]);
+ }
+ stitch_draw_vbo(vbo, GPU_PRIM_LINES, col);
- UI_GetThemeColor4fv(TH_STITCH_PREVIEW_UNSTITCHABLE, col);
- vbo = GWN_vertbuf_create_with_format(&format);
- GWN_vertbuf_data_alloc(vbo, stitch_preview->num_unstitchable * 2);
- for (int i = 0; i < stitch_preview->num_unstitchable * 2; i++) {
- GWN_vertbuf_attr_set(vbo, pos_id, i, &stitch_preview->preview_unstitchable[i * 2]);
+ UI_GetThemeColor4fv(TH_STITCH_PREVIEW_UNSTITCHABLE, col);
+ vbo = GPU_vertbuf_create_with_format(&format);
+ GPU_vertbuf_data_alloc(vbo, stitch_preview->num_unstitchable * 2);
+ for (int i = 0; i < stitch_preview->num_unstitchable * 2; i++) {
+ GPU_vertbuf_attr_set(vbo, pos_id, i, &stitch_preview->preview_unstitchable[i * 2]);
+ }
+ stitch_draw_vbo(vbo, GPU_PRIM_LINES, col);
}
- stitch_draw_vbo(vbo, GWN_PRIM_LINES, col);
}
}
@@ -1688,7 +1810,9 @@ static UvEdge *uv_edge_get(BMLoop *l, StitchState *state)
return BLI_ghash_lookup(state->edge_hash, &tmp_edge);
}
-static int stitch_init(bContext *C, wmOperator *op)
+static StitchState *stitch_init(
+ bContext *C, wmOperator *op,
+ StitchStateContainer *ssc, Object *obedit)
{
/* for fast edge lookup... */
GHash *edge_hash;
@@ -1706,47 +1830,16 @@ static int stitch_init(bContext *C, wmOperator *op)
StitchState *state;
Scene *scene = CTX_data_scene(C);
ToolSettings *ts = scene->toolsettings;
- ARegion *ar = CTX_wm_region(C);
float aspx, aspy;
- Object *obedit = CTX_data_edit_object(C);
+
BMEditMesh *em = BKE_editmesh_from_object(obedit);
const int cd_loop_uv_offset = CustomData_get_offset(&em->bm->ldata, CD_MLOOPUV);
- if (!ar)
- return 0;
-
- state = MEM_callocN(sizeof(StitchState), "stitch state");
-
- op->customdata = state;
+ state = MEM_callocN(sizeof(StitchState), "stitch state obj");
/* initialize state */
- state->use_limit = RNA_boolean_get(op->ptr, "use_limit");
- state->limit_dist = RNA_float_get(op->ptr, "limit");
state->obedit = obedit;
state->em = em;
- state->snap_islands = RNA_boolean_get(op->ptr, "snap_islands");
- state->static_island = RNA_int_get(op->ptr, "static_island");
- state->midpoints = RNA_boolean_get(op->ptr, "midpoint_snap");
- state->clear_seams = RNA_boolean_get(op->ptr, "clear_seams");
- if (RNA_struct_property_is_set(op->ptr, "mode")) {
- state->mode = RNA_enum_get(op->ptr, "mode");
- }
- else {
- if (ts->uv_flag & UV_SYNC_SELECTION) {
- if (ts->selectmode & SCE_SELECT_VERTEX)
- state->mode = STITCH_VERT;
- else
- state->mode = STITCH_EDGE;
- }
- else {
- if (ts->uv_selectmode & UV_SELECT_VERTEX) {
- state->mode = STITCH_VERT;
- }
- else {
- state->mode = STITCH_EDGE;
- }
- }
- }
/* in uv synch selection, all uv's are visible */
if (ts->uv_flag & UV_SYNC_SELECTION) {
@@ -1757,16 +1850,12 @@ static int stitch_init(bContext *C, wmOperator *op)
}
if (!state->element_map) {
state_delete(state);
- return 0;
+ return NULL;
}
ED_uvedit_get_aspect(scene, obedit, em->bm, &aspx, &aspy);
state->aspect = aspx / aspy;
- /* Entirely possible if redoing last operator that static island is bigger than total number of islands.
- * This ensures we get no hang in the island checking code in stitch_stitch_process_data. */
- state->static_island %= state->element_map->totalIslands;
-
/* Count 'unique' uvs */
for (i = 0; i < state->element_map->totalUVs; i++) {
if (state->element_map->buf[i].separate) {
@@ -1785,11 +1874,11 @@ static int stitch_init(bContext *C, wmOperator *op)
state->map = map = MEM_mallocN(sizeof(*map) * state->element_map->totalUVs, "uv_stitch_unique_map");
/* Allocate the edge stack */
edge_hash = BLI_ghash_new(uv_edge_hash, uv_edge_compare, "stitch_edge_hash");
- all_edges = MEM_mallocN(sizeof(*all_edges) * state->element_map->totalUVs, "stitch_all_edges");
+ all_edges = MEM_mallocN(sizeof(*all_edges) * state->element_map->totalUVs, "ssc_edges");
if (!state->uvs || !map || !edge_hash || !all_edges) {
state_delete(state);
- return 0;
+ return NULL;
}
/* So that we can use this as index for the UvElements */
@@ -1858,7 +1947,7 @@ static int stitch_init(bContext *C, wmOperator *op)
/* I assume any system will be able to at least allocate an iterator :p */
if (!edges) {
state_delete(state);
- return 0;
+ return NULL;
}
state->total_separate_edges = total_edges;
@@ -1908,7 +1997,8 @@ static int stitch_init(bContext *C, wmOperator *op)
state->selection_size = 0;
/* Load old selection if redoing operator with different settings */
- if (RNA_struct_property_is_set(op->ptr, "selection")) {
+ /* WIP */
+ if (false && RNA_struct_property_is_set(op->ptr, "selection")) {
int faceIndex, elementIndex;
UvElement *element;
enum StitchModes stored_mode = RNA_enum_get(op->ptr, "stored_mode");
@@ -1961,16 +2051,15 @@ static int stitch_init(bContext *C, wmOperator *op)
}
/* if user has switched the operator mode after operation, we need to convert
* the stored format */
- if (state->mode != stored_mode) {
- state->mode = stored_mode;
- stitch_switch_selection_mode(state);
+ if (ssc->mode != stored_mode) {
+ stitch_set_selection_mode(state, stored_mode);
}
/* Clear the selection */
RNA_collection_clear(op->ptr, "selection");
}
else {
- if (state->mode == STITCH_VERT) {
+ if (ssc->mode == STITCH_VERT) {
state->selection_stack = MEM_mallocN(sizeof(*state->selection_stack) * state->total_separate_uvs, "uv_stitch_selection_stack");
BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
@@ -2022,22 +2111,154 @@ static int stitch_init(bContext *C, wmOperator *op)
}
}
- if (!stitch_process_data(state, scene, false)) {
+ state->island_is_stitchable = MEM_callocN(sizeof(bool) * state->element_map->totalIslands, "stitch I stops");
+ if (!state->island_is_stitchable) {
+ state_delete(state);
+ return NULL;
+ }
+ if (!stitch_process_data(ssc, state, scene, false)) {
state_delete(state);
+ return NULL;
+ }
+
+ return state;
+}
+
+static bool goto_next_island(StitchStateContainer *ssc)
+{
+ StitchState *active_state = ssc->states[ssc->active_object_index];
+ StitchState *original_active_state = active_state;
+
+ int original_island = ssc->static_island;
+
+ do {
+ ssc->static_island++;
+ if (ssc->static_island >= active_state->element_map->totalIslands) {
+ /* go to next object */
+ ssc->active_object_index++;
+ ssc->active_object_index %= ssc->objects_len;
+
+ active_state = ssc->states[ssc->active_object_index];
+ ssc->static_island = 0;
+ }
+
+ if (active_state->island_is_stitchable[ssc->static_island]) {
+ /* We're at an island to make active */
+ return true;
+ }
+ } while (!(active_state == original_active_state &&
+ ssc->static_island == original_island));
+
+ return false;
+}
+
+static int stitch_init_all(bContext *C, wmOperator *op)
+{
+ ARegion *ar = CTX_wm_region(C);
+ if (!ar)
+ return 0;
+
+ Scene *scene = CTX_data_scene(C);
+ ToolSettings *ts = scene->toolsettings;
+
+ StitchStateContainer *ssc = MEM_callocN(sizeof(StitchStateContainer), "stitch collection");
+
+ op->customdata = ssc;
+
+ ssc->use_limit = RNA_boolean_get(op->ptr, "use_limit");
+ ssc->limit_dist = RNA_float_get(op->ptr, "limit");
+ ssc->snap_islands = RNA_boolean_get(op->ptr, "snap_islands");
+ ssc->midpoints = RNA_boolean_get(op->ptr, "midpoint_snap");
+ ssc->clear_seams = RNA_boolean_get(op->ptr, "clear_seams");
+ ssc->active_object_index = RNA_int_get(op->ptr, "active_object_index");
+ ssc->static_island = 0;
+
+ if (RNA_struct_property_is_set(op->ptr, "mode")) {
+ ssc->mode = RNA_enum_get(op->ptr, "mode");
+ }
+ else {
+ if (ts->uv_flag & UV_SYNC_SELECTION) {
+ if (ts->selectmode & SCE_SELECT_VERTEX)
+ ssc->mode = STITCH_VERT;
+ else
+ ssc->mode = STITCH_EDGE;
+ }
+ else {
+ if (ts->uv_selectmode & UV_SELECT_VERTEX) {
+ ssc->mode = STITCH_VERT;
+ }
+ else {
+ ssc->mode = STITCH_EDGE;
+ }
+ }
+ }
+
+ ssc->objects_len = 0;
+ ssc->states = NULL;
+
+ ViewLayer *view_layer = CTX_data_view_layer(C);
+ uint objects_len = 0;
+ Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data_with_uvs(view_layer, &objects_len);
+
+ if (objects_len == 0) {
+ MEM_freeN(objects);
+ state_delete_all(ssc);
return 0;
}
- state->draw_handle = ED_region_draw_cb_activate(ar->type, stitch_draw, state, REGION_DRAW_POST_VIEW);
+ ssc->objects = MEM_callocN(sizeof(Object *) * objects_len, "Object *ssc->objects");
+ ssc->states = MEM_callocN(sizeof(StitchState *) * objects_len, "StitchState");
+ ssc->objects_len = 0;
+
+ for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
+ Object *obedit = objects[ob_index];
+
+ StitchState *stitch_state_ob = stitch_init(C, op, ssc, obedit);
+
+ if (stitch_state_ob) {
+ ssc->objects[ssc->objects_len] = obedit;
+ ssc->states[ssc->objects_len] = stitch_state_ob;
+ ssc->objects_len++;
+ }
+ }
+
+ MEM_freeN(objects);
+
+ if (ssc->objects_len == 0) {
+ state_delete_all(ssc);
+ return 0;
+ }
+
+ ssc->active_object_index %= ssc->objects_len;
+
+ ssc->static_island = RNA_int_get(op->ptr, "static_island");
+
+ StitchState *state = ssc->states[ssc->active_object_index];
+ ssc->static_island %= state->element_map->totalIslands;
+
+ /* If the initial active object doesn't have any stitchable islands */
+ /* then no active island will be seen in the UI. Make sure we're on */
+ /* a stitchable object and island. */
+ if (!state->island_is_stitchable[ssc->static_island]) {
+ goto_next_island(ssc);
+ state = ssc->states[ssc->active_object_index];
+ }
+
+ /* process active stitchobj again now that it can detect it's the active stitchobj */
+ stitch_process_data(ssc, state, scene, false);
+
+ stitch_update_header(ssc, C);
+
+ ssc->draw_handle = ED_region_draw_cb_activate(ar->type, stitch_draw, ssc, REGION_DRAW_POST_VIEW);
- stitch_update_header(state, C);
return 1;
}
static int stitch_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
{
Object *obedit = CTX_data_edit_object(C);
- if (!stitch_init(C, op))
+ if (!stitch_init_all(C, op))
return OPERATOR_CANCELLED;
WM_event_add_modal_handler(C, op);
@@ -2047,34 +2268,37 @@ static int stitch_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(even
static void stitch_exit(bContext *C, wmOperator *op, int finished)
{
- StitchState *state;
Scene *scene;
SpaceImage *sima;
ScrArea *sa = CTX_wm_area(C);
- Object *obedit;
scene = CTX_data_scene(C);
- obedit = CTX_data_edit_object(C);
sima = CTX_wm_space_image(C);
- state = (StitchState *)op->customdata;
+ StitchStateContainer *ssc = (StitchStateContainer *)op->customdata;
+ StitchState *state = ssc->states[ssc->active_object_index];
+ Object *obedit = state->obedit;
if (finished) {
int i;
- RNA_float_set(op->ptr, "limit", state->limit_dist);
- RNA_boolean_set(op->ptr, "use_limit", state->use_limit);
- RNA_boolean_set(op->ptr, "snap_islands", state->snap_islands);
- RNA_int_set(op->ptr, "static_island", state->static_island);
- RNA_boolean_set(op->ptr, "midpoint_snap", state->midpoints);
- RNA_enum_set(op->ptr, "mode", state->mode);
- RNA_enum_set(op->ptr, "stored_mode", state->mode);
+ RNA_float_set(op->ptr, "limit", ssc->limit_dist);
+ RNA_boolean_set(op->ptr, "use_limit", ssc->use_limit);
+ RNA_boolean_set(op->ptr, "snap_islands", ssc->snap_islands);
+ RNA_boolean_set(op->ptr, "midpoint_snap", ssc->midpoints);
+ RNA_boolean_set(op->ptr, "clear_seams", ssc->clear_seams);
+ RNA_enum_set(op->ptr, "mode", ssc->mode);
+ RNA_enum_set(op->ptr, "stored_mode", ssc->mode);
+ RNA_int_set(op->ptr, "active_object_index", ssc->active_object_index);
+
+ RNA_int_set(op->ptr, "static_island", ssc->static_island);
/* Store selection for re-execution of stitch */
+ /* WIP */
for (i = 0; i < state->selection_size; i++) {
UvElement *element;
PointerRNA itemptr;
- if (state->mode == STITCH_VERT) {
+ if (ssc->mode == STITCH_VERT) {
element = state->selection_stack[i];
}
else {
@@ -2083,7 +2307,7 @@ static void stitch_exit(bContext *C, wmOperator *op, int finished)
RNA_collection_add(op->ptr, "selection", &itemptr);
RNA_int_set(&itemptr, "face_index", BM_elem_index_get(element->l->f));
- RNA_int_set(&itemptr, "element_index", element->tfindex);
+ RNA_int_set(&itemptr, "element_index", element->loop_of_poly_index);
}
uvedit_live_unwrap_update(sima, scene, obedit);
@@ -2092,12 +2316,13 @@ static void stitch_exit(bContext *C, wmOperator *op, int finished)
if (sa)
ED_workspace_status_text(C, NULL);
- ED_region_draw_cb_exit(CTX_wm_region(C)->type, state->draw_handle);
+ ED_region_draw_cb_exit(CTX_wm_region(C)->type, ssc->draw_handle);
DEG_id_tag_update(obedit->data, 0);
WM_event_add_notifier(C, NC_GEOM | ND_DATA, obedit->data);
- state_delete(state);
+ state_delete_all(ssc);
+
op->customdata = NULL;
}
@@ -2112,9 +2337,9 @@ static int stitch_exec(bContext *C, wmOperator *op)
{
Scene *scene = CTX_data_scene(C);
- if (!stitch_init(C, op))
+ if (!stitch_init_all(C, op))
return OPERATOR_CANCELLED;
- if (stitch_process_data((StitchState *)op->customdata, scene, 1)) {
+ if (stitch_process_data_all((StitchStateContainer *)op->customdata, scene, 1)) {
stitch_exit(C, op, 1);
return OPERATOR_FINISHED;
}
@@ -2124,7 +2349,8 @@ static int stitch_exec(bContext *C, wmOperator *op)
}
}
-static void stitch_select(bContext *C, Scene *scene, const wmEvent *event, StitchState *state)
+static StitchState *stitch_select(
+ bContext *C, Scene *scene, const wmEvent *event, StitchStateContainer *ssc)
{
/* add uv under mouse to processed uv's */
float co[2];
@@ -2134,36 +2360,60 @@ static void stitch_select(bContext *C, Scene *scene, const wmEvent *event, Stitc
UI_view2d_region_to_view(&ar->v2d, event->mval[0], event->mval[1], &co[0], &co[1]);
- if (state->mode == STITCH_VERT) {
- if (uv_find_nearest_vert(
- scene, ima, state->obedit, co, 0.0f, &hit))
+ if (ssc->mode == STITCH_VERT) {
+ if (uv_find_nearest_vert_multi(
+ scene, ima, ssc->objects, ssc->objects_len, co, 0.0f, &hit))
{
/* Add vertex to selection, deselect all common uv's of vert other
* than selected and update the preview. This behavior was decided so that
* you can do stuff like deselect the opposite stitchable vertex and the initial still gets deselected */
+ /* find StitchState from hit->ob */
+ StitchState *state = NULL;
+ for (uint ob_index = 0; ob_index < ssc->objects_len; ob_index++) {
+ if (hit.ob == ssc->objects[ob_index]) {
+ state = ssc->states[ob_index];
+ break;
+ }
+ }
+
/* This works due to setting of tmp in find nearest uv vert */
UvElement *element = BM_uv_element_get(state->element_map, hit.efa, hit.l);
stitch_select_uv(element, state, false);
+ return state;
}
}
else {
- if (uv_find_nearest_edge(
- scene, ima, state->obedit, co, &hit))
+ if (uv_find_nearest_edge_multi(
+ scene, ima, ssc->objects, ssc->objects_len, co, &hit))
{
+ /* find StitchState from hit->ob */
+ StitchState *state = NULL;
+ for (uint ob_index = 0; ob_index < ssc->objects_len; ob_index++) {
+ if (hit.ob == ssc->objects[ob_index]) {
+ state = ssc->states[ob_index];
+ break;
+ }
+ }
+
UvEdge *edge = uv_edge_get(hit.l, state);
stitch_select_edge(edge, state, false);
+
+ return state;
}
}
+
+ return NULL;
}
static int stitch_modal(bContext *C, wmOperator *op, const wmEvent *event)
{
- StitchState *state;
+ StitchStateContainer *ssc;
Scene *scene = CTX_data_scene(C);
- state = (StitchState *)op->customdata;
+ ssc = op->customdata;
+ StitchState *active_state = ssc->states[ssc->active_object_index];
switch (event->type) {
case MIDDLEMOUSE:
@@ -2177,9 +2427,9 @@ static int stitch_modal(bContext *C, wmOperator *op, const wmEvent *event)
case LEFTMOUSE:
if (event->shift && (U.flag & USER_LMOUSESELECT)) {
if (event->val == KM_PRESS) {
- stitch_select(C, scene, event, state);
+ StitchState *selected_state = stitch_select(C, scene, event, ssc);
- if (!stitch_process_data(state, scene, false)) {
+ if (selected_state && !stitch_process_data(ssc, selected_state, scene, false)) {
stitch_cancel(C, op);
return OPERATOR_CANCELLED;
}
@@ -2190,7 +2440,7 @@ static int stitch_modal(bContext *C, wmOperator *op, const wmEvent *event)
case PADENTER:
case RETKEY:
if (event->val == KM_PRESS) {
- if (stitch_process_data(state, scene, true)) {
+ if (stitch_process_data(ssc, active_state, scene, true)) {
stitch_exit(C, op, 1);
return OPERATOR_FINISHED;
}
@@ -2206,8 +2456,8 @@ static int stitch_modal(bContext *C, wmOperator *op, const wmEvent *event)
case PADPLUSKEY:
case WHEELUPMOUSE:
if (event->val == KM_PRESS && event->alt) {
- state->limit_dist += 0.01f;
- if (!stitch_process_data(state, scene, false)) {
+ ssc->limit_dist += 0.01f;
+ if (!stitch_process_data(ssc, active_state, scene, false)) {
stitch_cancel(C, op);
return OPERATOR_CANCELLED;
}
@@ -2220,9 +2470,9 @@ static int stitch_modal(bContext *C, wmOperator *op, const wmEvent *event)
case PADMINUS:
case WHEELDOWNMOUSE:
if (event->val == KM_PRESS && event->alt) {
- state->limit_dist -= 0.01f;
- state->limit_dist = MAX2(0.01f, state->limit_dist);
- if (!stitch_process_data(state, scene, false)) {
+ ssc->limit_dist -= 0.01f;
+ ssc->limit_dist = MAX2(0.01f, ssc->limit_dist);
+ if (!stitch_process_data(ssc, active_state, scene, false)) {
stitch_cancel(C, op);
return OPERATOR_CANCELLED;
}
@@ -2235,8 +2485,8 @@ static int stitch_modal(bContext *C, wmOperator *op, const wmEvent *event)
/* Use Limit (Default off) */
case LKEY:
if (event->val == KM_PRESS) {
- state->use_limit = !state->use_limit;
- if (!stitch_process_data(state, scene, false)) {
+ ssc->use_limit = !ssc->use_limit;
+ if (!stitch_process_data(ssc, active_state, scene, false)) {
stitch_cancel(C, op);
return OPERATOR_CANCELLED;
}
@@ -2246,12 +2496,23 @@ static int stitch_modal(bContext *C, wmOperator *op, const wmEvent *event)
case IKEY:
if (event->val == KM_PRESS) {
- state->static_island++;
- state->static_island %= state->element_map->totalIslands;
+ /* Move to next island and maybe next object */
- if (!stitch_process_data(state, scene, false)) {
- stitch_cancel(C, op);
- return OPERATOR_CANCELLED;
+ if (goto_next_island(ssc)) {
+ StitchState *new_active_state = ssc->states[ssc->active_object_index];
+
+ /* active_state is the origional active state */
+ if (active_state != new_active_state) {
+ if (!stitch_process_data(ssc, active_state, scene, false)) {
+ stitch_cancel(C, op);
+ return OPERATOR_CANCELLED;
+ }
+ }
+
+ if (!stitch_process_data(ssc, new_active_state, scene, false)) {
+ stitch_cancel(C, op);
+ return OPERATOR_CANCELLED;
+ }
}
break;
}
@@ -2259,8 +2520,8 @@ static int stitch_modal(bContext *C, wmOperator *op, const wmEvent *event)
case MKEY:
if (event->val == KM_PRESS) {
- state->midpoints = !state->midpoints;
- if (!stitch_process_data(state, scene, false)) {
+ ssc->midpoints = !ssc->midpoints;
+ if (!stitch_process_data(ssc, active_state, scene, false)) {
stitch_cancel(C, op);
return OPERATOR_CANCELLED;
}
@@ -2274,9 +2535,9 @@ static int stitch_modal(bContext *C, wmOperator *op, const wmEvent *event)
return OPERATOR_CANCELLED;
}
if (event->val == KM_PRESS && !(U.flag & USER_LMOUSESELECT)) {
- stitch_select(C, scene, event, state);
+ StitchState *selected_state = stitch_select(C, scene, event, ssc);
- if (!stitch_process_data(state, scene, false)) {
+ if (selected_state && !stitch_process_data(ssc, selected_state, scene, false)) {
stitch_cancel(C, op);
return OPERATOR_CANCELLED;
}
@@ -2287,8 +2548,8 @@ static int stitch_modal(bContext *C, wmOperator *op, const wmEvent *event)
/* snap islands on/off */
case SKEY:
if (event->val == KM_PRESS) {
- state->snap_islands = !state->snap_islands;
- if (!stitch_process_data(state, scene, false)) {
+ ssc->snap_islands = !ssc->snap_islands;
+ if (!stitch_process_data(ssc, active_state, scene, false)) {
stitch_cancel(C, op);
return OPERATOR_CANCELLED;
}
@@ -2301,9 +2562,9 @@ static int stitch_modal(bContext *C, wmOperator *op, const wmEvent *event)
/* switch between edge/vertex mode */
case TABKEY:
if (event->val == KM_PRESS) {
- stitch_switch_selection_mode(state);
+ stitch_switch_selection_mode_all(ssc);
- if (!stitch_process_data(state, scene, false)) {
+ if (!stitch_process_data_all(ssc, scene, false)) {
stitch_cancel(C, op);
return OPERATOR_CANCELLED;
}
@@ -2315,8 +2576,9 @@ static int stitch_modal(bContext *C, wmOperator *op, const wmEvent *event)
}
/* if updated settings, renew feedback message */
- stitch_update_header(state, C);
+ stitch_update_header(ssc, C);
ED_region_tag_redraw(CTX_wm_region(C));
+
return OPERATOR_RUNNING_MODAL;
}
@@ -2352,14 +2614,16 @@ void UV_OT_stitch(wmOperatorType *ot)
"Limit distance in normalized coordinates", 0.0, FLT_MAX);
RNA_def_int(ot->srna, "static_island", 0, 0, INT_MAX, "Static Island",
"Island that stays in place when stitching islands", 0, INT_MAX);
+ RNA_def_int(ot->srna, "active_object_index", 0, 0, INT_MAX, "Active Object",
+ "Index of the active object", 0, INT_MAX);
RNA_def_boolean(ot->srna, "midpoint_snap", 0, "Snap At Midpoint",
"UVs are stitched at midpoint instead of at static island");
RNA_def_boolean(ot->srna, "clear_seams", 1, "Clear Seams",
"Clear seams of stitched edges");
RNA_def_enum(ot->srna, "mode", stitch_modes, STITCH_VERT, "Operation Mode",
"Use vertex or edge stitching");
- prop = RNA_def_enum(ot->srna, "stored_mode", stitch_modes, STITCH_VERT, "Stored Operation Mode",
- "Use vertex or edge stitching");
+ prop = RNA_def_enum(ot->srna, "stored_mode", stitch_modes, STITCH_VERT, "Stored Operation Mode",
+ "Use vertex or edge stitching");
RNA_def_property_flag(prop, PROP_HIDDEN);
prop = RNA_def_collection_runtime(ot->srna, "selection", &RNA_SelectedUvElement, "Selection", "");
/* Selection should not be editable or viewed in toolbar */