Fix UV edit smart stitch not redoing correctly.
[blender.git] / source / blender / editors / uvedit / uvedit_smart_stitch.c
1 /*
2  * ***** BEGIN GPL LICENSE BLOCK *****
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License
6  * as published by the Free Software Foundation; either version 2
7  * of the License, or (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software Foundation,
16  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17  *
18  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
19  * All rights reserved.
20  *
21  * The Original Code is: all of this file.
22  *
23  * Contributor(s): Antony Riakiotakis.
24  *
25  * ***** END GPL LICENSE BLOCK *****
26  */
27
28 /** \file blender/editors/uvedit/uvedit_smart_stitch.c
29  *  \ingroup eduv
30  */
31
32
33 #include <stdlib.h>
34 #include <string.h>
35 #include <math.h>
36
37 #include "MEM_guardedalloc.h"
38
39 #include "DNA_object_types.h"
40 #include "DNA_meshdata_types.h"
41 #include "DNA_scene_types.h"
42
43 #include "BLI_utildefines.h"
44 #include "BLI_ghash.h"
45 #include "BLI_math.h"
46 #include "BLI_math_vector.h"
47 #include "BLI_string.h"
48
49 #include "BLT_translation.h"
50
51 #include "BIF_gl.h"
52
53 #include "BKE_context.h"
54 #include "BKE_customdata.h"
55 #include "BKE_depsgraph.h"
56 #include "BKE_mesh_mapping.h"
57 #include "BKE_editmesh.h"
58
59 #include "UI_interface.h"
60
61 #include "ED_mesh.h"
62 #include "ED_uvedit.h"
63 #include "ED_screen.h"
64 #include "ED_space_api.h"
65
66 #include "RNA_access.h"
67 #include "RNA_define.h"
68
69 #include "WM_api.h"
70 #include "WM_types.h"
71
72 #include "UI_view2d.h"
73 #include "UI_resources.h"
74
75 #include "uvedit_intern.h"
76
77 /* ********************** smart stitch operator *********************** */
78
79 /* object that stores display data for previewing before confirming stitching */
80 typedef struct StitchPreviewer {
81         /* here we'll store the preview triangle indices of the mesh */
82         float *preview_polys;
83         /* uvs per polygon. */
84         unsigned int *uvs_per_polygon;
85         /*number of preview polygons */
86         unsigned int num_polys;
87         /* preview data. These will be either the previewed vertices or edges depending on stitch mode settings */
88         float *preview_stitchable;
89         float *preview_unstitchable;
90         /* here we'll store the number of elements to be drawn */
91         unsigned int num_stitchable;
92         unsigned int num_unstitchable;
93         unsigned int preview_uvs;
94         /* ...and here we'll store the static island triangles */
95         float *static_tris;
96         unsigned int num_static_tris;
97 } StitchPreviewer;
98
99
100 struct IslandStitchData;
101
102 /**
103  * This is a straightforward implementation, count the UVs in the island
104  * that will move and take the mean displacement/rotation and apply it to all
105  * elements of the island except from the stitchable.
106  */
107 typedef struct IslandStitchData {
108         /* rotation can be used only for edges, for vertices there is no such notion */
109         float rotation;
110         float rotation_neg;
111         float translation[2];
112         /* Used for rotation, the island will rotate around this point */
113         float medianPoint[2];
114         int numOfElements;
115         int num_rot_elements;
116         int num_rot_elements_neg;
117         /* flag to remember if island has been added for preview */
118         char addedForPreview;
119         /* flag an island to be considered for determining static island */
120         char stitchableCandidate;
121         /* if edge rotation is used, flag so that vertex rotation is not used */
122         bool use_edge_rotation;
123 } IslandStitchData;
124
125 /* just for averaging UVs */
126 typedef struct UVVertAverage {
127         float uv[2];
128         unsigned short count;
129 } UVVertAverage;
130
131 typedef struct UvEdge {
132         /* index to uv buffer */
133         unsigned int uv1;
134         unsigned int uv2;
135         /* general use flag (Used to check if edge is boundary here, and propagates to adjacency elements) */
136         unsigned char flag;
137         /* element that guarantees element->face has the edge on element->tfindex and element->tfindex+1 is the second uv */
138         UvElement *element;
139         /* next uv edge with the same exact vertices as this one.. Calculated at startup to save time */
140         struct UvEdge *next;
141         /* point to first of common edges. Needed for iteration */
142         struct UvEdge *first;
143 } UvEdge;
144
145
146 /* stitch state object */
147 typedef struct StitchState {
148         float aspect;
149         /* use limit flag */
150         bool use_limit;
151         /* limit to operator, same as original operator */
152         float limit_dist;
153         /* snap uv islands together during stitching */
154         bool snap_islands;
155         /* stitch at midpoints or at islands */
156         bool midpoints;
157         /* editmesh, cached for use in modal handler */
158         BMEditMesh *em;
159         /* clear seams of stitched edges after stitch */
160         bool clear_seams;
161         /* element map for getting info about uv connectivity */
162         UvElementMap *element_map;
163         /* edge container */
164         UvEdge *uvedges;
165         /* container of first of a group of coincident uvs, these will be operated upon */
166         UvElement **uvs;
167         /* maps uvelements to their first coincident uv */
168         int *map;
169         /* 2D normals per uv to calculate rotation for snapping */
170         float *normals;
171         /* edge storage */
172         UvEdge *edges;
173         /* hash for quick lookup of edges */
174         GHash *edge_hash;
175
176         /* count of separate uvs and edges */
177         int total_separate_edges;
178         int total_separate_uvs;
179         /* hold selection related information */
180         void **selection_stack;
181         int selection_size;
182         /* island that stays in place */
183         int static_island;
184         /* store number of primitives per face so that we can allocate the active island buffer later */
185         unsigned int *tris_per_island;
186
187         /* vert or edge mode used for stitching */
188         char mode;
189         /* handle for drawing */
190         void *draw_handle;
191         /* preview data */
192         StitchPreviewer *stitch_preview;
193 } StitchState;
194
195 typedef struct PreviewPosition {
196         int data_position;
197         int polycount_position;
198 } PreviewPosition;
199 /*
200  * defines for UvElement/UcEdge flags
201  */
202 #define STITCH_SELECTED 1
203 #define STITCH_STITCHABLE 2
204 #define STITCH_PROCESSED 4
205 #define STITCH_BOUNDARY 8
206 #define STITCH_STITCHABLE_CANDIDATE 16
207
208 #define STITCH_NO_PREVIEW -1
209
210 enum StitchModes {
211         STITCH_VERT,
212         STITCH_EDGE
213 };
214
215 /* constructor */
216 static StitchPreviewer *stitch_preview_init(void)
217 {
218         StitchPreviewer *stitch_preview;
219
220         stitch_preview = MEM_mallocN(sizeof(StitchPreviewer), "stitch_previewer");
221         stitch_preview->preview_polys = NULL;
222         stitch_preview->preview_stitchable = NULL;
223         stitch_preview->preview_unstitchable = NULL;
224         stitch_preview->uvs_per_polygon = NULL;
225
226         stitch_preview->preview_uvs = 0;
227         stitch_preview->num_polys = 0;
228         stitch_preview->num_stitchable = 0;
229         stitch_preview->num_unstitchable = 0;
230
231         stitch_preview->static_tris = NULL;
232
233         stitch_preview->num_static_tris = 0;
234
235         return stitch_preview;
236 }
237
238 /* destructor...yeah this should be C++ :) */
239 static void stitch_preview_delete(StitchPreviewer *stitch_preview)
240 {
241         if (stitch_preview) {
242                 if (stitch_preview->preview_polys) {
243                         MEM_freeN(stitch_preview->preview_polys);
244                         stitch_preview->preview_polys = NULL;
245                 }
246                 if (stitch_preview->uvs_per_polygon) {
247                         MEM_freeN(stitch_preview->uvs_per_polygon);
248                         stitch_preview->uvs_per_polygon = NULL;
249                 }
250                 if (stitch_preview->preview_stitchable) {
251                         MEM_freeN(stitch_preview->preview_stitchable);
252                         stitch_preview->preview_stitchable = NULL;
253                 }
254                 if (stitch_preview->preview_unstitchable) {
255                         MEM_freeN(stitch_preview->preview_unstitchable);
256                         stitch_preview->preview_unstitchable = NULL;
257                 }
258                 if (stitch_preview->static_tris) {
259                         MEM_freeN(stitch_preview->static_tris);
260                         stitch_preview->static_tris = NULL;
261                 }
262                 MEM_freeN(stitch_preview);
263         }
264 }
265
266 /* This function updates the header of the UV editor when the stitch tool updates its settings */
267 static void stitch_update_header(StitchState *state, bContext *C)
268 {
269         const char *str = IFACE_(
270             "Mode(TAB) %s, "
271             "(S)nap %s, "
272             "(M)idpoints %s, "
273             "(L)imit %.2f (Alt Wheel adjust) %s, "
274             "Switch (I)sland, "
275             "shift select vertices"
276         );
277
278         char msg[UI_MAX_DRAW_STR];
279         ScrArea *sa = CTX_wm_area(C);
280
281         if (sa) {
282                 BLI_snprintf(msg, sizeof(msg), str,
283                              state->mode == STITCH_VERT ? IFACE_("Vertex") : IFACE_("Edge"),
284                              WM_bool_as_string(state->snap_islands),
285                              WM_bool_as_string(state->midpoints),
286                              state->limit_dist,
287                              WM_bool_as_string(state->use_limit));
288
289                 ED_area_headerprint(sa, msg);
290         }
291 }
292
293 static int getNumOfIslandUvs(UvElementMap *elementMap, int island)
294 {
295         if (island == elementMap->totalIslands - 1) {
296                 return elementMap->totalUVs - elementMap->islandIndices[island];
297         }
298         else {
299                 return elementMap->islandIndices[island + 1] - elementMap->islandIndices[island];
300         }
301 }
302
303 static void stitch_uv_rotate(float mat[2][2], float medianPoint[2], float uv[2], float aspect)
304 {
305         float uv_rotation_result[2];
306
307         uv[1] /= aspect;
308
309         sub_v2_v2(uv, medianPoint);
310         mul_v2_m2v2(uv_rotation_result, mat, uv);
311         add_v2_v2v2(uv, uv_rotation_result, medianPoint);
312
313         uv[1] *= aspect;
314 }
315
316 /* check if two uvelements are stitchable. This should only operate on -different- separate UvElements */
317 static bool stitch_check_uvs_stitchable(UvElement *element, UvElement *element_iter, StitchState *state)
318 {
319         BMesh *bm = state->em->bm;
320         float limit;
321
322         if (element_iter == element) {
323                 return 0;
324         }
325
326         limit = state->limit_dist;
327
328         if (state->use_limit) {
329                 MLoopUV *luv, *luv_iter;
330                 BMLoop *l;
331
332
333                 l = element->l;
334                 luv = CustomData_bmesh_get(&bm->ldata, l->head.data, CD_MLOOPUV);
335                 l = element_iter->l;
336                 luv_iter = CustomData_bmesh_get(&bm->ldata, l->head.data, CD_MLOOPUV);
337
338                 if (fabsf(luv->uv[0] - luv_iter->uv[0]) < limit &&
339                     fabsf(luv->uv[1] - luv_iter->uv[1]) < limit)
340                 {
341                         return 1;
342                 }
343                 else {
344                         return 0;
345                 }
346         }
347         else {
348                 return 1;
349         }
350 }
351
352 static bool stitch_check_edges_stitchable(UvEdge *edge, UvEdge *edge_iter, StitchState *state)
353 {
354         BMesh *bm = state->em->bm;
355         float limit;
356
357         if (edge_iter == edge) {
358                 return 0;
359         }
360
361         limit = state->limit_dist;
362
363         if (state->use_limit) {
364                 BMLoop *l;
365                 MLoopUV *luv_orig1, *luv_iter1;
366                 MLoopUV *luv_orig2, *luv_iter2;
367
368                 l = state->uvs[edge->uv1]->l;
369                 luv_orig1 = CustomData_bmesh_get(&bm->ldata, l->head.data, CD_MLOOPUV);
370                 l = state->uvs[edge_iter->uv1]->l;
371                 luv_iter1 = CustomData_bmesh_get(&bm->ldata, l->head.data, CD_MLOOPUV);
372
373                 l = state->uvs[edge->uv2]->l;
374                 luv_orig2 = CustomData_bmesh_get(&bm->ldata, l->head.data, CD_MLOOPUV);
375                 l = state->uvs[edge_iter->uv2]->l;
376                 luv_iter2 = CustomData_bmesh_get(&bm->ldata, l->head.data, CD_MLOOPUV);
377
378                 if (fabsf(luv_orig1->uv[0] - luv_iter1->uv[0]) < limit &&
379                     fabsf(luv_orig1->uv[1] - luv_iter1->uv[1]) < limit &&
380                     fabsf(luv_orig2->uv[0] - luv_iter2->uv[0]) < limit &&
381                     fabsf(luv_orig2->uv[1] - luv_iter2->uv[1]) < limit)
382                 {
383                         return 1;
384                 }
385                 else {
386                         return 0;
387                 }
388         }
389         else {
390                 return 1;
391         }
392 }
393
394 static bool stitch_check_uvs_state_stitchable(UvElement *element, UvElement *element_iter, StitchState *state)
395 {
396         if ((state->snap_islands && element->island == element_iter->island) ||
397             (!state->midpoints && element->island == element_iter->island))
398         {
399                 return 0;
400         }
401
402         return stitch_check_uvs_stitchable(element, element_iter, state);
403 }
404
405
406 static bool stitch_check_edges_state_stitchable(UvEdge *edge, UvEdge *edge_iter, StitchState *state)
407 {
408         if ((state->snap_islands && edge->element->island == edge_iter->element->island) ||
409             (!state->midpoints && edge->element->island == edge_iter->element->island))
410         {
411                 return 0;
412         }
413
414         return stitch_check_edges_stitchable(edge, edge_iter, state);
415 }
416
417 /* calculate snapping for islands */
418 static void stitch_calculate_island_snapping(
419         StitchState *state, PreviewPosition *preview_position, StitchPreviewer *preview,
420         IslandStitchData *island_stitch_data, int final)
421 {
422         BMesh *bm = state->em->bm;
423         int i;
424         UvElement *element;
425
426         for (i = 0; i < state->element_map->totalIslands; i++) {
427                 if (island_stitch_data[i].addedForPreview) {
428                         int numOfIslandUVs = 0, j;
429                         int totelem = island_stitch_data[i].num_rot_elements_neg + island_stitch_data[i].num_rot_elements;
430                         float rotation;
431                         float rotation_mat[2][2];
432
433                         /* check to avoid divide by 0 */
434                         if (island_stitch_data[i].num_rot_elements > 1)
435                                 island_stitch_data[i].rotation /= island_stitch_data[i].num_rot_elements;
436
437                         if (island_stitch_data[i].num_rot_elements_neg > 1)
438                                 island_stitch_data[i].rotation_neg /= island_stitch_data[i].num_rot_elements_neg;
439
440                         if (island_stitch_data[i].numOfElements > 1) {
441                                 island_stitch_data[i].medianPoint[0] /= island_stitch_data[i].numOfElements;
442                                 island_stitch_data[i].medianPoint[1] /= island_stitch_data[i].numOfElements;
443
444                                 island_stitch_data[i].translation[0] /= island_stitch_data[i].numOfElements;
445                                 island_stitch_data[i].translation[1] /= island_stitch_data[i].numOfElements;
446                         }
447
448                         island_stitch_data[i].medianPoint[1] /= state->aspect;
449                         if ((island_stitch_data[i].rotation + island_stitch_data[i].rotation_neg < (float)M_PI_2) ||
450                             island_stitch_data[i].num_rot_elements == 0 || island_stitch_data[i].num_rot_elements_neg == 0)
451                         {
452                                 rotation = (island_stitch_data[i].rotation * island_stitch_data[i].num_rot_elements -
453                                             island_stitch_data[i].rotation_neg *
454                                             island_stitch_data[i].num_rot_elements_neg) / totelem;
455                         }
456                         else {
457                                 rotation = (island_stitch_data[i].rotation * island_stitch_data[i].num_rot_elements +
458                                             (2.0f * (float)M_PI - island_stitch_data[i].rotation_neg) *
459                                             island_stitch_data[i].num_rot_elements_neg) / totelem;
460                         }
461
462                         angle_to_mat2(rotation_mat, rotation);
463                         numOfIslandUVs = getNumOfIslandUvs(state->element_map, i);
464                         element = &state->element_map->buf[state->element_map->islandIndices[i]];
465                         for (j = 0; j < numOfIslandUVs; j++, element++) {
466                                 /* stitchable uvs have already been processed, don't process */
467                                 if (!(element->flag & STITCH_PROCESSED)) {
468                                         MLoopUV *luv;
469                                         BMLoop *l;
470
471                                         l = element->l;
472                                         luv = CustomData_bmesh_get(&bm->ldata, l->head.data, CD_MLOOPUV);
473
474                                         if (final) {
475
476                                                 stitch_uv_rotate(rotation_mat, island_stitch_data[i].medianPoint, luv->uv, state->aspect);
477
478                                                 add_v2_v2(luv->uv, island_stitch_data[i].translation);
479                                         }
480
481                                         else {
482
483                                                 int face_preview_pos = preview_position[BM_elem_index_get(element->l->f)].data_position;
484
485                                                 stitch_uv_rotate(rotation_mat, island_stitch_data[i].medianPoint,
486                                                                  preview->preview_polys + face_preview_pos + 2 * element->loop_of_poly_index,
487                                                                  state->aspect);
488
489                                                 add_v2_v2(preview->preview_polys + face_preview_pos + 2 * element->loop_of_poly_index,
490                                                           island_stitch_data[i].translation);
491                                         }
492                                 }
493                                 /* cleanup */
494                                 element->flag &= STITCH_SELECTED;
495                         }
496                 }
497         }
498 }
499
500
501
502 static void stitch_island_calculate_edge_rotation(
503         UvEdge *edge, StitchState *state, UVVertAverage *uv_average, unsigned int *uvfinal_map,
504         IslandStitchData *island_stitch_data)
505 {
506         BMesh *bm = state->em->bm;
507         UvElement *element1, *element2;
508         float uv1[2], uv2[2];
509         float edgecos, edgesin;
510         int index1, index2;
511         float rotation;
512         MLoopUV *luv1, *luv2;
513
514         element1 = state->uvs[edge->uv1];
515         element2 = state->uvs[edge->uv2];
516
517         luv1 = CustomData_bmesh_get(&bm->ldata, element1->l->head.data, CD_MLOOPUV);
518         luv2 = CustomData_bmesh_get(&bm->ldata, element2->l->head.data, CD_MLOOPUV);
519
520         if (state->mode == STITCH_VERT) {
521                 index1 = uvfinal_map[element1 - state->element_map->buf];
522                 index2 = uvfinal_map[element2 - state->element_map->buf];
523         }
524         else {
525                 index1 = edge->uv1;
526                 index2 = edge->uv2;
527         }
528         /* the idea here is to take the directions of the edges and find the rotation between final and initial
529          * direction. This, using inner and outer vector products, gives the angle. Directions are differences so... */
530         uv1[0] = luv2->uv[0] - luv1->uv[0];
531         uv1[1] = luv2->uv[1] - luv1->uv[1];
532
533         uv1[1] /= state->aspect;
534
535         uv2[0] = uv_average[index2].uv[0] - uv_average[index1].uv[0];
536         uv2[1] = uv_average[index2].uv[1] - uv_average[index1].uv[1];
537
538         uv2[1] /= state->aspect;
539
540         normalize_v2(uv1);
541         normalize_v2(uv2);
542
543         edgecos = dot_v2v2(uv1, uv2);
544         edgesin = cross_v2v2(uv1, uv2);
545         rotation = acosf(max_ff(-1.0f, min_ff(1.0f, edgecos)));
546
547         if (edgesin > 0.0f) {
548                 island_stitch_data[element1->island].num_rot_elements++;
549                 island_stitch_data[element1->island].rotation += rotation;
550         }
551         else {
552                 island_stitch_data[element1->island].num_rot_elements_neg++;
553                 island_stitch_data[element1->island].rotation_neg += rotation;
554         }
555 }
556
557
558 static void stitch_island_calculate_vert_rotation(
559         UvElement *element, StitchState *state,
560         IslandStitchData *island_stitch_data)
561 {
562         float edgecos = 1.0f, edgesin = 0.0f;
563         int index;
564         UvElement *element_iter;
565         float rotation = 0, rotation_neg = 0;
566         int rot_elem = 0, rot_elem_neg = 0;
567         BMLoop *l;
568
569         if (element->island == state->static_island && !state->midpoints)
570                 return;
571
572         l = element->l;
573
574         index = BM_elem_index_get(l->v);
575
576         element_iter = state->element_map->vert[index];
577
578         for (; element_iter; element_iter = element_iter->next) {
579                 if (element_iter->separate && stitch_check_uvs_state_stitchable(element, element_iter, state)) {
580                         int index_tmp1, index_tmp2;
581                         float normal[2];
582
583                         /* only calculate rotation against static island uv verts */
584                         if (!state->midpoints && element_iter->island != state->static_island)
585                                 continue;
586
587                         index_tmp1 = element_iter - state->element_map->buf;
588                         index_tmp1 = state->map[index_tmp1];
589                         index_tmp2 = element - state->element_map->buf;
590                         index_tmp2 = state->map[index_tmp2];
591
592                         negate_v2_v2(normal, state->normals + index_tmp2 * 2);
593                         edgecos = dot_v2v2(normal, state->normals + index_tmp1 * 2);
594                         edgesin = cross_v2v2(normal, state->normals + index_tmp1 * 2);
595                         if (edgesin > 0.0f) {
596                                 rotation += acosf(max_ff(-1.0f, min_ff(1.0f, edgecos)));
597                                 rot_elem++;
598                         }
599                         else {
600                                 rotation_neg += acosf(max_ff(-1.0f, min_ff(1.0f, edgecos)));
601                                 rot_elem_neg++;
602                         }
603                 }
604         }
605
606         if (state->midpoints) {
607                 rotation /= 2.0f;
608                 rotation_neg /= 2.0f;
609         }
610         island_stitch_data[element->island].num_rot_elements += rot_elem;
611         island_stitch_data[element->island].rotation += rotation;
612         island_stitch_data[element->island].num_rot_elements_neg += rot_elem_neg;
613         island_stitch_data[element->island].rotation_neg += rotation_neg;
614 }
615
616
617 static void state_delete(StitchState *state)
618 {
619         if (state) {
620                 if (state->element_map) {
621                         BM_uv_element_map_free(state->element_map);
622                 }
623                 if (state->uvs) {
624                         MEM_freeN(state->uvs);
625                 }
626                 if (state->selection_stack) {
627                         MEM_freeN(state->selection_stack);
628                 }
629                 if (state->tris_per_island) {
630                         MEM_freeN(state->tris_per_island);
631                 }
632                 if (state->map) {
633                         MEM_freeN(state->map);
634                 }
635                 if (state->normals) {
636                         MEM_freeN(state->normals);
637                 }
638                 if (state->edges) {
639                         MEM_freeN(state->edges);
640                 }
641                 if (state->stitch_preview) {
642                         stitch_preview_delete(state->stitch_preview);
643                 }
644                 if (state->edge_hash) {
645                         BLI_ghash_free(state->edge_hash, NULL, NULL);
646                 }
647                 MEM_freeN(state);
648         }
649 }
650
651 static void stitch_uv_edge_generate_linked_edges(GHash *edge_hash, StitchState *state)
652 {
653         UvEdge *edges = state->edges;
654         const int *map = state->map;
655         UvElementMap *element_map = state->element_map;
656         UvElement *first_element = element_map->buf;
657         int i;
658
659         for (i = 0; i < state->total_separate_edges; i++) {
660                 UvEdge *edge = edges + i;
661
662                 if (edge->first)
663                         continue;
664
665                 /* only boundary edges can be stitched. Yes. Sorry about that :p */
666                 if (edge->flag & STITCH_BOUNDARY) {
667                         UvElement *element1 = state->uvs[edge->uv1];
668                         UvElement *element2 = state->uvs[edge->uv2];
669
670                         /* Now iterate through all faces and try to find edges sharing the same vertices */
671                         UvElement *iter1 = element_map->vert[BM_elem_index_get(element1->l->v)];
672                         UvEdge *last_set = edge;
673                         int elemindex2 = BM_elem_index_get(element2->l->v);
674
675                         edge->first = edge;
676
677                         for (; iter1; iter1 = iter1->next) {
678                                 UvElement *iter2 = NULL;
679
680                                 /* check to see if other vertex of edge belongs to same vertex as */
681                                 if (BM_elem_index_get(iter1->l->next->v) == elemindex2)
682                                         iter2 = BM_uv_element_get(element_map, iter1->l->f, iter1->l->next);
683                                 else if (BM_elem_index_get(iter1->l->prev->v) == elemindex2)
684                                         iter2 = BM_uv_element_get(element_map, iter1->l->f, iter1->l->prev);
685
686                                 if (iter2) {
687                                         int index1 = map[iter1 - first_element];
688                                         int index2 = map[iter2 - first_element];
689                                         UvEdge edgetmp;
690                                         UvEdge *edge2, *eiter;
691                                         bool valid = true;
692
693                                         /* make sure the indices are well behaved */
694                                         if (index1 > index2) {
695                                                 SWAP(int, index1, index2);
696                                         }
697
698                                         edgetmp.uv1 = index1;
699                                         edgetmp.uv2 = index2;
700
701                                         /* get the edge from the hash */
702                                         edge2 = BLI_ghash_lookup(edge_hash, &edgetmp);
703
704                                         /* more iteration to make sure non-manifold case is handled nicely */
705                                         for (eiter = edge; eiter; eiter = eiter->next) {
706                                                 if (edge2 == eiter) {
707                                                         valid = false;
708                                                         break;
709                                                 }
710                                         }
711
712                                         if (valid) {
713                                                 /* here I am taking care of non manifold case, assuming more than two matching edges.
714                                                  * I am not too sure we want this though */
715                                                 last_set->next = edge2;
716                                                 last_set = edge2;
717                                                 /* set first, similarly to uv elements. Now we can iterate among common edges easily */
718                                                 edge2->first = edge;
719                                         }
720                                 }
721                         }
722                 }
723                 else {
724                         /* so stitchability code works */
725                         edge->first = edge;
726                 }
727         }
728 }
729
730
731 /* checks for remote uvs that may be stitched with a certain uv, flags them if stitchable. */
732 static void determine_uv_stitchability(
733         UvElement *element, StitchState *state,
734         IslandStitchData *island_stitch_data)
735 {
736         int vert_index;
737         UvElement *element_iter;
738         BMLoop *l;
739
740         l = element->l;
741
742         vert_index = BM_elem_index_get(l->v);
743         element_iter = state->element_map->vert[vert_index];
744
745         for (; element_iter; element_iter = element_iter->next) {
746                 if (element_iter->separate) {
747                         if (stitch_check_uvs_stitchable(element, element_iter, state)) {
748                                 island_stitch_data[element_iter->island].stitchableCandidate = 1;
749                                 island_stitch_data[element->island].stitchableCandidate = 1;
750                                 element->flag |= STITCH_STITCHABLE_CANDIDATE;
751                         }
752                 }
753         }
754 }
755
756 static void determine_uv_edge_stitchability(
757         UvEdge *edge, StitchState *state,
758         IslandStitchData *island_stitch_data)
759 {
760         UvEdge *edge_iter = edge->first;
761
762         for (; edge_iter; edge_iter = edge_iter->next) {
763                 if (stitch_check_edges_stitchable(edge, edge_iter, state)) {
764                         island_stitch_data[edge_iter->element->island].stitchableCandidate = 1;
765                         island_stitch_data[edge->element->island].stitchableCandidate = 1;
766                         edge->flag |= STITCH_STITCHABLE_CANDIDATE;
767                 }
768         }
769 }
770
771
772 /* set preview buffer position of UV face in editface->tmp.l */
773 static void stitch_set_face_preview_buffer_position(
774         BMFace *efa, StitchPreviewer *preview, PreviewPosition *preview_position)
775 {
776         int index = BM_elem_index_get(efa);
777
778         if (preview_position[index].data_position == STITCH_NO_PREVIEW) {
779                 preview_position[index].data_position = preview->preview_uvs * 2;
780                 preview_position[index].polycount_position = preview->num_polys++;
781                 preview->preview_uvs += efa->len;
782         }
783 }
784
785
786 /* setup face preview for all coincident uvs and their faces */
787 static void stitch_setup_face_preview_for_uv_group(
788         UvElement *element, StitchState *state, IslandStitchData *island_stitch_data,
789         PreviewPosition *preview_position)
790 {
791         StitchPreviewer *preview = state->stitch_preview;
792
793         /* static island does not change so returning immediately */
794         if (state->snap_islands && !state->midpoints && state->static_island == element->island)
795                 return;
796
797         if (state->snap_islands) {
798                 island_stitch_data[element->island].addedForPreview = 1;
799         }
800
801         do {
802                 stitch_set_face_preview_buffer_position(element->l->f, preview, preview_position);
803                 element = element->next;
804         } while (element && !element->separate);
805 }
806
807
808 /* checks if uvs are indeed stitchable and registers so that they can be shown in preview */
809 static void stitch_validate_uv_stitchability(
810         UvElement *element, StitchState *state, IslandStitchData *island_stitch_data,
811         PreviewPosition *preview_position)
812 {
813         UvElement *element_iter;
814         StitchPreviewer *preview = state->stitch_preview;
815         int vert_index;
816         BMLoop *l;
817
818         l = element->l;
819
820         vert_index = BM_elem_index_get(l->v);
821
822         element_iter = state->element_map->vert[vert_index];
823
824         for (; element_iter; element_iter = element_iter->next) {
825                 if (element_iter->separate) {
826                         if (element_iter == element)
827                                 continue;
828                         if (stitch_check_uvs_state_stitchable(element, element_iter, state)) {
829                                 if ((element_iter->island == state->static_island) || (element->island == state->static_island)) {
830                                         element->flag |= STITCH_STITCHABLE;
831                                         preview->num_stitchable++;
832                                         stitch_setup_face_preview_for_uv_group(element, state, island_stitch_data, preview_position);
833                                         return;
834                                 }
835                         }
836                 }
837         }
838
839         /* this can happen if the uvs to be stitched are not on a stitchable island */
840         if (!(element->flag & STITCH_STITCHABLE)) {
841                 preview->num_unstitchable++;
842         }
843 }
844
845
846 static void stitch_validate_edge_stitchability(
847         UvEdge *edge, StitchState *state, IslandStitchData *island_stitch_data,
848         PreviewPosition *preview_position)
849 {
850         UvEdge *edge_iter = edge->first;
851         StitchPreviewer *preview = state->stitch_preview;
852
853         for (; edge_iter; edge_iter = edge_iter->next) {
854                 if (edge_iter == edge)
855                         continue;
856                 if (stitch_check_edges_state_stitchable(edge, edge_iter, state)) {
857                         if ((edge_iter->element->island == state->static_island) || (edge->element->island == state->static_island)) {
858                                 edge->flag |= STITCH_STITCHABLE;
859                                 preview->num_stitchable++;
860                                 stitch_setup_face_preview_for_uv_group(state->uvs[edge->uv1], state, island_stitch_data, preview_position);
861                                 stitch_setup_face_preview_for_uv_group(state->uvs[edge->uv2], state, island_stitch_data, preview_position);
862                                 return;
863                         }
864                 }
865         }
866
867         /* this can happen if the uvs to be stitched are not on a stitchable island */
868         if (!(edge->flag & STITCH_STITCHABLE)) {
869                 preview->num_unstitchable++;
870         }
871 }
872
873
874 static void stitch_propagate_uv_final_position(
875         Scene *scene,
876         UvElement *element, int index, PreviewPosition *preview_position,
877         UVVertAverage *final_position, StitchState *state,
878         const bool final)
879 {
880         BMesh *bm = state->em->bm;
881         StitchPreviewer *preview = state->stitch_preview;
882
883         const int cd_loop_uv_offset = CustomData_get_offset(&bm->ldata, CD_MLOOPUV);
884
885         if (element->flag & STITCH_STITCHABLE) {
886                 UvElement *element_iter = element;
887                 /* propagate to coincident uvs */
888                 do {
889                         BMLoop *l;
890                         MLoopUV *luv;
891
892                         l = element_iter->l;
893                         luv = CustomData_bmesh_get(&bm->ldata, l->head.data, CD_MLOOPUV);
894
895                         element_iter->flag |= STITCH_PROCESSED;
896                         /* either flush to preview or to the MTFace, if final */
897                         if (final) {
898                                 copy_v2_v2(luv->uv, final_position[index].uv);
899
900                                 uvedit_uv_select_enable(state->em, scene, l, false, cd_loop_uv_offset);
901                         }
902                         else {
903                                 int face_preview_pos = preview_position[BM_elem_index_get(element_iter->l->f)].data_position;
904                                 if (face_preview_pos != STITCH_NO_PREVIEW) {
905                                         copy_v2_v2(preview->preview_polys + face_preview_pos + 2 * element_iter->loop_of_poly_index,
906                                                    final_position[index].uv);
907                                 }
908                         }
909
910                         /* end of calculations, keep only the selection flag */
911                         if ((!state->snap_islands) || ((!state->midpoints) && (element_iter->island == state->static_island))) {
912                                 element_iter->flag &= STITCH_SELECTED;
913                         }
914
915                         element_iter = element_iter->next;
916                 } while (element_iter && !element_iter->separate);
917         }
918 }
919
920 /* main processing function. It calculates preview and final positions. */
921 static int stitch_process_data(StitchState *state, Scene *scene, int final)
922 {
923         int i;
924         StitchPreviewer *preview;
925         IslandStitchData *island_stitch_data = NULL;
926         int previous_island = state->static_island;
927         BMesh *bm = state->em->bm;
928         BMFace *efa;
929         BMIter iter;
930         UVVertAverage *final_position = NULL;
931
932         char stitch_midpoints = state->midpoints;
933         /* used to map uv indices to uvaverage indices for selection */
934         unsigned int *uvfinal_map = NULL;
935         /* per face preview position in preview buffer */
936         PreviewPosition *preview_position = NULL;
937
938         /* cleanup previous preview */
939         stitch_preview_delete(state->stitch_preview);
940         preview = state->stitch_preview = stitch_preview_init();
941         if (preview == NULL)
942                 return 0;
943
944         preview_position = MEM_mallocN(bm->totface * sizeof(*preview_position), "stitch_face_preview_position");
945         /* each face holds its position in the preview buffer in tmp. -1 is uninitialized */
946         for (i = 0; i < bm->totface; i++) {
947                 preview_position[i].data_position = STITCH_NO_PREVIEW;
948         }
949
950         island_stitch_data = MEM_callocN(sizeof(*island_stitch_data) * state->element_map->totalIslands, "stitch_island_data");
951         if (!island_stitch_data) {
952                 return 0;
953         }
954
955         /* store indices to editVerts and Faces. May be unneeded but ensuring anyway */
956         BM_mesh_elem_index_ensure(bm, BM_VERT | BM_FACE);
957
958         /****************************************
959          * First determine stitchability of uvs *
960          ****************************************/
961
962         for (i = 0; i < state->selection_size; i++) {
963                 if (state->mode == STITCH_VERT) {
964                         UvElement *element = (UvElement *)state->selection_stack[i];
965                         determine_uv_stitchability(element, state, island_stitch_data);
966                 }
967                 else {
968                         UvEdge *edge = (UvEdge *)state->selection_stack[i];
969                         determine_uv_edge_stitchability(edge, state, island_stitch_data);
970                 }
971         }
972
973         /* set static island to one that is added for preview */
974         state->static_island %= state->element_map->totalIslands;
975         while (!(island_stitch_data[state->static_island].stitchableCandidate)) {
976                 state->static_island++;
977                 state->static_island %= state->element_map->totalIslands;
978                 /* this is entirely possible if for example limit stitching with no stitchable verts or no selection */
979                 if (state->static_island == previous_island)
980                         break;
981         }
982
983         for (i = 0; i < state->selection_size; i++) {
984                 if (state->mode == STITCH_VERT) {
985                         UvElement *element = (UvElement *)state->selection_stack[i];
986                         if (element->flag & STITCH_STITCHABLE_CANDIDATE) {
987                                 element->flag &= ~STITCH_STITCHABLE_CANDIDATE;
988                                 stitch_validate_uv_stitchability(element, state, island_stitch_data, preview_position);
989                         }
990                         else {
991                                 /* add to preview for unstitchable */
992                                 preview->num_unstitchable++;
993                         }
994                 }
995                 else {
996                         UvEdge *edge = (UvEdge *)state->selection_stack[i];
997                         if (edge->flag & STITCH_STITCHABLE_CANDIDATE) {
998                                 edge->flag &= ~STITCH_STITCHABLE_CANDIDATE;
999                                 stitch_validate_edge_stitchability(edge, state, island_stitch_data, preview_position);
1000                         }
1001                         else {
1002                                 preview->num_unstitchable++;
1003                         }
1004                 }
1005         }
1006
1007         /*****************************************
1008          *  Setup preview for stitchable islands *
1009          *****************************************/
1010         if (state->snap_islands) {
1011                 for (i = 0; i < state->element_map->totalIslands; i++) {
1012                         if (island_stitch_data[i].addedForPreview) {
1013                                 int numOfIslandUVs = 0, j;
1014                                 UvElement *element;
1015                                 numOfIslandUVs = getNumOfIslandUvs(state->element_map, i);
1016                                 element = &state->element_map->buf[state->element_map->islandIndices[i]];
1017                                 for (j = 0; j < numOfIslandUVs; j++, element++) {
1018                                         stitch_set_face_preview_buffer_position(element->l->f, preview, preview_position);
1019                                 }
1020                         }
1021                 }
1022         }
1023
1024         /*********************************************************************
1025          * Setup the preview buffers and fill them with the appropriate data *
1026          *********************************************************************/
1027         if (!final) {
1028                 BMIter liter;
1029                 BMLoop *l;
1030                 MLoopUV *luv;
1031                 unsigned int buffer_index = 0;
1032                 int stitchBufferIndex = 0, unstitchBufferIndex = 0;
1033                 int preview_size = (state->mode == STITCH_VERT) ? 2 : 4;
1034                 /* initialize the preview buffers */
1035                 preview->preview_polys = (float *)MEM_mallocN(preview->preview_uvs * sizeof(float) * 2, "tri_uv_stitch_prev");
1036                 preview->uvs_per_polygon = MEM_mallocN(preview->num_polys * sizeof(*preview->uvs_per_polygon), "tri_uv_stitch_prev");
1037                 preview->preview_stitchable = (float *)MEM_mallocN(preview->num_stitchable * sizeof(float) * preview_size, "stitch_preview_stitchable_data");
1038                 preview->preview_unstitchable = (float *)MEM_mallocN(preview->num_unstitchable * sizeof(float) * preview_size, "stitch_preview_unstitchable_data");
1039
1040                 preview->static_tris = (float *)MEM_mallocN(state->tris_per_island[state->static_island] * sizeof(float) * 6, "static_island_preview_tris");
1041
1042                 preview->num_static_tris = state->tris_per_island[state->static_island];
1043                 /* will cause cancel and freeing of all data structures so OK */
1044                 if (!preview->preview_polys || !preview->preview_stitchable || !preview->preview_unstitchable) {
1045                         return 0;
1046                 }
1047
1048                 /* copy data from MLoopUVs to the preview display buffers */
1049                 BM_ITER_MESH (efa, &iter, bm, BM_FACES_OF_MESH) {
1050                         /* just to test if face was added for processing. uvs of unselected vertices will return NULL */
1051                         UvElement *element = BM_uv_element_get(state->element_map, efa, BM_FACE_FIRST_LOOP(efa));
1052
1053                         if (element) {
1054                                 int numoftris = efa->len - 2;
1055                                 int index = BM_elem_index_get(efa);
1056                                 int face_preview_pos = preview_position[index].data_position;
1057                                 if (face_preview_pos != STITCH_NO_PREVIEW) {
1058                                         preview->uvs_per_polygon[preview_position[index].polycount_position] = efa->len;
1059                                         BM_ITER_ELEM_INDEX (l, &liter, efa, BM_LOOPS_OF_FACE, i) {
1060                                                 luv = CustomData_bmesh_get(&bm->ldata, l->head.data, CD_MLOOPUV);
1061                                                 copy_v2_v2(preview->preview_polys + face_preview_pos + i * 2, luv->uv);
1062                                         }
1063                                 }
1064
1065                                 if (element->island == state->static_island) {
1066                                         BMLoop *fl = BM_FACE_FIRST_LOOP(efa);
1067                                         MLoopUV *fuv = CustomData_bmesh_get(&bm->ldata, fl->head.data, CD_MLOOPUV);
1068
1069                                         BM_ITER_ELEM_INDEX (l, &liter, efa, BM_LOOPS_OF_FACE, i) {
1070                                                 if (i < numoftris) {
1071                                                         /* using next since the first uv is already accounted for */
1072                                                         BMLoop *lnext = l->next;
1073                                                         MLoopUV *luvnext = CustomData_bmesh_get(&bm->ldata, lnext->next->head.data, CD_MLOOPUV);
1074                                                         luv = CustomData_bmesh_get(&bm->ldata, lnext->head.data, CD_MLOOPUV);
1075
1076                                                         memcpy(preview->static_tris + buffer_index, fuv->uv, 2 * sizeof(float));
1077                                                         memcpy(preview->static_tris + buffer_index + 2, luv->uv, 2 * sizeof(float));
1078                                                         memcpy(preview->static_tris + buffer_index + 4, luvnext->uv, 2 * sizeof(float));
1079                                                         buffer_index += 6;
1080                                                 }
1081                                                 else {
1082                                                         break;
1083                                                 }
1084                                         }
1085                                 }
1086                         }
1087                 }
1088
1089                 /* fill the appropriate preview buffers */
1090                 if (state->mode == STITCH_VERT) {
1091                         for (i = 0; i < state->total_separate_uvs; i++) {
1092                                 UvElement *element = (UvElement *)state->uvs[i];
1093                                 if (element->flag & STITCH_STITCHABLE) {
1094                                         l = element->l;
1095                                         luv = CustomData_bmesh_get(&bm->ldata, l->head.data, CD_MLOOPUV);
1096
1097                                         copy_v2_v2(&preview->preview_stitchable[stitchBufferIndex * 2], luv->uv);
1098
1099                                         stitchBufferIndex++;
1100                                 }
1101                                 else if (element->flag & STITCH_SELECTED) {
1102                                         l = element->l;
1103                                         luv = CustomData_bmesh_get(&bm->ldata, l->head.data, CD_MLOOPUV);
1104
1105                                         copy_v2_v2(&preview->preview_unstitchable[unstitchBufferIndex * 2], luv->uv);
1106                                         unstitchBufferIndex++;
1107                                 }
1108                         }
1109                 }
1110                 else {
1111                         for (i = 0; i < state->total_separate_edges; i++) {
1112                                 UvEdge *edge = state->edges + i;
1113                                 UvElement *element1 = state->uvs[edge->uv1];
1114                                 UvElement *element2 = state->uvs[edge->uv2];
1115
1116                                 if (edge->flag & STITCH_STITCHABLE) {
1117                                         l = element1->l;
1118                                         luv = CustomData_bmesh_get(&bm->ldata, l->head.data, CD_MLOOPUV);
1119                                         copy_v2_v2(&preview->preview_stitchable[stitchBufferIndex * 4], luv->uv);
1120
1121                                         l = element2->l;
1122                                         luv = CustomData_bmesh_get(&bm->ldata, l->head.data, CD_MLOOPUV);
1123                                         copy_v2_v2(&preview->preview_stitchable[stitchBufferIndex * 4 + 2], luv->uv);
1124
1125                                         stitchBufferIndex++;
1126                                         BLI_assert(stitchBufferIndex <= preview->num_stitchable);
1127                                 }
1128                                 else if (edge->flag & STITCH_SELECTED) {
1129                                         l = element1->l;
1130                                         luv = CustomData_bmesh_get(&bm->ldata, l->head.data, CD_MLOOPUV);
1131                                         copy_v2_v2(&preview->preview_unstitchable[unstitchBufferIndex * 4], luv->uv);
1132
1133                                         l = element2->l;
1134                                         luv = CustomData_bmesh_get(&bm->ldata, l->head.data, CD_MLOOPUV);
1135                                         copy_v2_v2(&preview->preview_unstitchable[unstitchBufferIndex * 4 + 2], luv->uv);
1136
1137                                         unstitchBufferIndex++;
1138                                         BLI_assert(unstitchBufferIndex <= preview->num_unstitchable);
1139                                 }
1140                         }
1141                 }
1142         }
1143
1144         /******************************************************
1145          * Here we calculate the final coordinates of the uvs *
1146          ******************************************************/
1147
1148         if (state->mode == STITCH_VERT) {
1149                 final_position = MEM_callocN(state->selection_size * sizeof(*final_position), "stitch_uv_average");
1150                 uvfinal_map = MEM_mallocN(state->element_map->totalUVs * sizeof(*uvfinal_map), "stitch_uv_final_map");
1151         }
1152         else {
1153                 final_position = MEM_callocN(state->total_separate_uvs * sizeof(*final_position), "stitch_uv_average");
1154         }
1155
1156         /* first pass, calculate final position for stitchable uvs of the static island */
1157         for (i = 0; i < state->selection_size; i++) {
1158                 if (state->mode == STITCH_VERT) {
1159                         UvElement *element = state->selection_stack[i];
1160
1161                         if (element->flag & STITCH_STITCHABLE) {
1162                                 BMLoop *l;
1163                                 MLoopUV *luv;
1164                                 UvElement *element_iter;
1165
1166                                 l = element->l;
1167                                 luv = CustomData_bmesh_get(&bm->ldata, l->head.data, CD_MLOOPUV);
1168
1169                                 uvfinal_map[element - state->element_map->buf] = i;
1170
1171                                 copy_v2_v2(final_position[i].uv, luv->uv);
1172                                 final_position[i].count = 1;
1173
1174                                 if (state->snap_islands && element->island == state->static_island && !stitch_midpoints)
1175                                         continue;
1176
1177                                 element_iter = state->element_map->vert[BM_elem_index_get(l->v)];
1178
1179                                 for ( ; element_iter; element_iter = element_iter->next) {
1180                                         if (element_iter->separate) {
1181                                                 if (stitch_check_uvs_state_stitchable(element, element_iter, state)) {
1182                                                         l = element_iter->l;
1183                                                         luv = CustomData_bmesh_get(&bm->ldata, l->head.data, CD_MLOOPUV);
1184                                                         if (stitch_midpoints) {
1185                                                                 add_v2_v2(final_position[i].uv, luv->uv);
1186                                                                 final_position[i].count++;
1187                                                         }
1188                                                         else if (element_iter->island == state->static_island) {
1189                                                                 /* if multiple uvs on the static island exist,
1190                                                                  * last checked remains. to disambiguate we need to limit or use
1191                                                                  * edge stitch */
1192                                                                 copy_v2_v2(final_position[i].uv, luv->uv);
1193                                                         }
1194                                                 }
1195                                         }
1196                                 }
1197                         }
1198                         if (stitch_midpoints) {
1199                                 final_position[i].uv[0] /= final_position[i].count;
1200                                 final_position[i].uv[1] /= final_position[i].count;
1201                         }
1202                 }
1203                 else {
1204                         UvEdge *edge = state->selection_stack[i];
1205
1206                         if (edge->flag & STITCH_STITCHABLE) {
1207                                 MLoopUV *luv2, *luv1;
1208                                 BMLoop *l;
1209                                 UvEdge *edge_iter;
1210
1211                                 l = state->uvs[edge->uv1]->l;
1212                                 luv1 = CustomData_bmesh_get(&bm->ldata, l->head.data, CD_MLOOPUV);
1213                                 l = state->uvs[edge->uv2]->l;
1214                                 luv2 = CustomData_bmesh_get(&bm->ldata, l->head.data, CD_MLOOPUV);
1215
1216                                 copy_v2_v2(final_position[edge->uv1].uv, luv1->uv);
1217                                 copy_v2_v2(final_position[edge->uv2].uv, luv2->uv);
1218                                 final_position[edge->uv1].count = 1;
1219                                 final_position[edge->uv2].count = 1;
1220
1221                                 state->uvs[edge->uv1]->flag |= STITCH_STITCHABLE;
1222                                 state->uvs[edge->uv2]->flag |= STITCH_STITCHABLE;
1223
1224                                 if (state->snap_islands && edge->element->island == state->static_island && !stitch_midpoints)
1225                                         continue;
1226
1227                                 for (edge_iter = edge->first; edge_iter; edge_iter = edge_iter->next) {
1228                                         if (stitch_check_edges_state_stitchable (edge, edge_iter, state)) {
1229                                                 l = state->uvs[edge_iter->uv1]->l;
1230                                                 luv1 = CustomData_bmesh_get(&bm->ldata, l->head.data, CD_MLOOPUV);
1231                                                 l = state->uvs[edge_iter->uv2]->l;
1232                                                 luv2 = CustomData_bmesh_get(&bm->ldata, l->head.data, CD_MLOOPUV);
1233
1234                                                 if (stitch_midpoints) {
1235                                                         add_v2_v2(final_position[edge->uv1].uv, luv1->uv);
1236                                                         final_position[edge->uv1].count++;
1237                                                         add_v2_v2(final_position[edge->uv2].uv, luv2->uv);
1238                                                         final_position[edge->uv2].count++;
1239                                                 }
1240                                                 else if (edge_iter->element->island == state->static_island) {
1241                                                         copy_v2_v2(final_position[edge->uv1].uv, luv1->uv);
1242                                                         copy_v2_v2(final_position[edge->uv2].uv, luv2->uv);
1243                                                 }
1244                                         }
1245                                 }
1246                         }
1247                 }
1248         }
1249
1250         /* take mean position here. For edge case, this can't be done inside the loop for shared uvverts */
1251         if (state->mode == STITCH_EDGE && stitch_midpoints) {
1252                 for (i = 0; i < state->total_separate_uvs; i++) {
1253                         final_position[i].uv[0] /= final_position[i].count;
1254                         final_position[i].uv[1] /= final_position[i].count;
1255                 }
1256         }
1257
1258         /* second pass, calculate island rotation and translation before modifying any uvs */
1259         if (state->snap_islands) {
1260                 if (state->mode == STITCH_VERT) {
1261                         for (i = 0; i < state->selection_size; i++) {
1262                                 UvElement *element = state->selection_stack[i];
1263
1264                                 if (element->flag & STITCH_STITCHABLE) {
1265                                         BMLoop *l;
1266                                         MLoopUV *luv;
1267
1268                                         l = element->l;
1269                                         luv = CustomData_bmesh_get(&bm->ldata, l->head.data, CD_MLOOPUV);
1270
1271                                         /* accumulate each islands' translation from stitchable elements. it is important to do here
1272                                          * because in final pass MTFaces get modified and result is zero. */
1273                                         island_stitch_data[element->island].translation[0] += final_position[i].uv[0] - luv->uv[0];
1274                                         island_stitch_data[element->island].translation[1] += final_position[i].uv[1] - luv->uv[1];
1275                                         island_stitch_data[element->island].medianPoint[0] += luv->uv[0];
1276                                         island_stitch_data[element->island].medianPoint[1] += luv->uv[1];
1277                                         island_stitch_data[element->island].numOfElements++;
1278                                 }
1279                         }
1280
1281                         /* only calculate rotation when an edge has been fully selected */
1282                         for (i = 0; i < state->total_separate_edges; i++) {
1283                                 UvEdge *edge = state->edges + i;
1284                                 if ((edge->flag & STITCH_BOUNDARY) &&
1285                                     (state->uvs[edge->uv1]->flag & STITCH_STITCHABLE) &&
1286                                     (state->uvs[edge->uv2]->flag & STITCH_STITCHABLE))
1287                                 {
1288                                         stitch_island_calculate_edge_rotation(edge, state, final_position, uvfinal_map, island_stitch_data);
1289                                         island_stitch_data[state->uvs[edge->uv1]->island].use_edge_rotation = true;
1290                                 }
1291                         }
1292
1293                         /* clear seams of stitched edges */
1294                         if (final && state->clear_seams) {
1295                                 for (i = 0; i < state->total_separate_edges; i++) {
1296                                         UvEdge *edge = state->edges + i;
1297                                         if ((state->uvs[edge->uv1]->flag & STITCH_STITCHABLE) &&
1298                                             (state->uvs[edge->uv2]->flag & STITCH_STITCHABLE))
1299                                         {
1300                                                 BM_elem_flag_disable(edge->element->l->e, BM_ELEM_SEAM);
1301                                         }
1302                                 }
1303                         }
1304
1305                         for (i = 0; i < state->selection_size; i++) {
1306                                 UvElement *element = state->selection_stack[i];
1307                                 if (!island_stitch_data[element->island].use_edge_rotation) {
1308                                         if (element->flag & STITCH_STITCHABLE) {
1309                                                 stitch_island_calculate_vert_rotation(element, state, island_stitch_data);
1310                                         }
1311                                 }
1312                         }
1313                 }
1314                 else {
1315                         for (i = 0; i < state->total_separate_uvs; i++) {
1316                                 UvElement *element = state->uvs[i];
1317
1318                                 if (element->flag & STITCH_STITCHABLE) {
1319                                         BMLoop *l;
1320                                         MLoopUV *luv;
1321
1322                                         l = element->l;
1323                                         luv = CustomData_bmesh_get(&bm->ldata, l->head.data, CD_MLOOPUV);
1324
1325                                         /* accumulate each islands' translation from stitchable elements. it is important to do here
1326                                          * because in final pass MTFaces get modified and result is zero. */
1327                                         island_stitch_data[element->island].translation[0] += final_position[i].uv[0] - luv->uv[0];
1328                                         island_stitch_data[element->island].translation[1] += final_position[i].uv[1] - luv->uv[1];
1329                                         island_stitch_data[element->island].medianPoint[0] += luv->uv[0];
1330                                         island_stitch_data[element->island].medianPoint[1] += luv->uv[1];
1331                                         island_stitch_data[element->island].numOfElements++;
1332                                 }
1333                         }
1334
1335                         for (i = 0; i < state->selection_size; i++) {
1336                                 UvEdge *edge = state->selection_stack[i];
1337
1338                                 if (edge->flag & STITCH_STITCHABLE) {
1339                                         stitch_island_calculate_edge_rotation(edge, state, final_position, NULL, island_stitch_data);
1340                                         island_stitch_data[state->uvs[edge->uv1]->island].use_edge_rotation = true;
1341                                 }
1342                         }
1343
1344                         /* clear seams of stitched edges */
1345                         if (final && state->clear_seams) {
1346                                 for (i = 0; i < state->selection_size; i++) {
1347                                         UvEdge *edge = state->selection_stack[i];
1348                                         if (edge->flag & STITCH_STITCHABLE) {
1349                                                 BM_elem_flag_disable(edge->element->l->e, BM_ELEM_SEAM);
1350                                         }
1351                                 }
1352                         }
1353                 }
1354         }
1355
1356         /* third pass, propagate changes to coincident uvs */
1357         for (i = 0; i < state->selection_size; i++) {
1358                 if (state->mode == STITCH_VERT) {
1359                         UvElement *element = state->selection_stack[i];
1360
1361                         stitch_propagate_uv_final_position(scene, element, i, preview_position, final_position, state, final);
1362                 }
1363                 else {
1364                         UvEdge *edge = state->selection_stack[i];
1365
1366                         stitch_propagate_uv_final_position(
1367                                 scene, state->uvs[edge->uv1], edge->uv1, preview_position, final_position, state, final);
1368                         stitch_propagate_uv_final_position(
1369                                 scene, state->uvs[edge->uv2], edge->uv2, preview_position, final_position, state, final);
1370
1371                         edge->flag &= (STITCH_SELECTED | STITCH_BOUNDARY);
1372                 }
1373         }
1374
1375         /* final pass, calculate Island translation/rotation if needed */
1376         if (state->snap_islands) {
1377                 stitch_calculate_island_snapping(state, preview_position, preview, island_stitch_data, final);
1378         }
1379
1380         MEM_freeN(final_position);
1381         if (state->mode == STITCH_VERT) {
1382                 MEM_freeN(uvfinal_map);
1383         }
1384         MEM_freeN(island_stitch_data);
1385         MEM_freeN(preview_position);
1386
1387         return 1;
1388 }
1389
1390 /* Stitch hash initialization functions */
1391 static unsigned int uv_edge_hash(const void *key)
1392 {
1393         const UvEdge *edge = key;
1394         return (BLI_ghashutil_uinthash(edge->uv2) +
1395                 BLI_ghashutil_uinthash(edge->uv1));
1396 }
1397
1398 static bool uv_edge_compare(const void *a, const void *b)
1399 {
1400         const UvEdge *edge1 = a;
1401         const UvEdge *edge2 = b;
1402
1403         if ((edge1->uv1 == edge2->uv1) && (edge1->uv2 == edge2->uv2)) {
1404                 return 0;
1405         }
1406         return 1;
1407 }
1408
1409 /* select all common edges */
1410 static void stitch_select_edge(UvEdge *edge, StitchState *state, int always_select)
1411 {
1412         UvEdge *eiter;
1413         UvEdge **selection_stack = (UvEdge **)state->selection_stack;
1414
1415         for (eiter = edge->first; eiter; eiter = eiter->next) {
1416                 if (eiter->flag & STITCH_SELECTED) {
1417                         int i;
1418                         if (always_select)
1419                                 continue;
1420
1421                         eiter->flag &= ~STITCH_SELECTED;
1422                         for (i = 0; i < state->selection_size; i++) {
1423                                 if (selection_stack[i] == eiter) {
1424                                         (state->selection_size)--;
1425                                         selection_stack[i] = selection_stack[state->selection_size];
1426                                         break;
1427                                 }
1428                         }
1429                 }
1430                 else {
1431                         eiter->flag |= STITCH_SELECTED;
1432                         selection_stack[state->selection_size++] = eiter;
1433                 }
1434         }
1435 }
1436
1437
1438 /* Select all common uvs */
1439 static void stitch_select_uv(UvElement *element, StitchState *state, int always_select)
1440 {
1441         BMLoop *l;
1442         UvElement *element_iter;
1443         UvElement **selection_stack = (UvElement **)state->selection_stack;
1444
1445         l = element->l;
1446
1447         element_iter = state->element_map->vert[BM_elem_index_get(l->v)];
1448         /* first deselect all common uvs */
1449         for (; element_iter; element_iter = element_iter->next) {
1450                 if (element_iter->separate) {
1451                         /* only separators go to selection */
1452                         if (element_iter->flag & STITCH_SELECTED) {
1453                                 int i;
1454                                 if (always_select)
1455                                         continue;
1456
1457                                 element_iter->flag &= ~STITCH_SELECTED;
1458                                 for (i = 0; i < state->selection_size; i++) {
1459                                         if (selection_stack[i] == element_iter) {
1460                                                 (state->selection_size)--;
1461                                                 selection_stack[i] = selection_stack[state->selection_size];
1462                                                 break;
1463                                         }
1464                                 }
1465                         }
1466                         else {
1467                                 element_iter->flag |= STITCH_SELECTED;
1468                                 selection_stack[state->selection_size++] = element_iter;
1469                         }
1470                 }
1471         }
1472 }
1473
1474 static void stitch_switch_selection_mode(StitchState *state)
1475 {
1476         void **old_selection_stack = state->selection_stack;
1477         int old_selection_size = state->selection_size;
1478         state->selection_size = 0;
1479
1480         if (state->mode == STITCH_VERT) {
1481                 int i;
1482                 state->selection_stack = MEM_mallocN(state->total_separate_edges * sizeof(*state->selection_stack),
1483                                                      "stitch_new_edge_selection_stack");
1484
1485                 /* check if both elements of an edge are selected */
1486                 for (i = 0; i < state->total_separate_edges; i++) {
1487                         UvEdge *edge = state->edges + i;
1488                         UvElement *element1 = state->uvs[edge->uv1];
1489                         UvElement *element2 = state->uvs[edge->uv2];
1490
1491                         if ((element1->flag & STITCH_SELECTED) && (element2->flag & STITCH_SELECTED))
1492                                 stitch_select_edge(edge, state, true);
1493                 }
1494
1495                 /* unselect selected uvelements */
1496                 for (i = 0; i < old_selection_size; i++) {
1497                         UvElement *element = old_selection_stack[i];
1498
1499                         element->flag &= ~STITCH_SELECTED;
1500                 }
1501                 state->mode = STITCH_EDGE;
1502         }
1503         else {
1504                 int i;
1505                 state->selection_stack = MEM_mallocN(state->total_separate_uvs * sizeof(*state->selection_stack),
1506                                                      "stitch_new_vert_selection_stack");
1507
1508                 for (i = 0; i < old_selection_size; i++) {
1509                         UvEdge *edge = old_selection_stack[i];
1510                         UvElement *element1 = state->uvs[edge->uv1];
1511                         UvElement *element2 = state->uvs[edge->uv2];
1512
1513                         stitch_select_uv(element1, state, true);
1514                         stitch_select_uv(element2, state, true);
1515
1516                         edge->flag &= ~STITCH_SELECTED;
1517                 }
1518                 state->mode = STITCH_VERT;
1519         }
1520         MEM_freeN(old_selection_stack);
1521 }
1522
1523 static void stitch_calculate_edge_normal(BMEditMesh *em, UvEdge *edge, float *normal, float aspect)
1524 {
1525         BMLoop *l1 = edge->element->l;
1526         MLoopUV *luv1, *luv2;
1527         float tangent[2];
1528
1529         luv1 = CustomData_bmesh_get(&em->bm->ldata, l1->head.data, CD_MLOOPUV);
1530         luv2 = CustomData_bmesh_get(&em->bm->ldata, l1->next->head.data, CD_MLOOPUV);
1531
1532         sub_v2_v2v2(tangent, luv2->uv,  luv1->uv);
1533
1534         tangent[1] /= aspect;
1535
1536         normal[0] = tangent[1];
1537         normal[1] = -tangent[0];
1538
1539         normalize_v2(normal);
1540 }
1541
1542 static void stitch_draw(const bContext *UNUSED(C), ARegion *UNUSED(ar), void *arg)
1543 {
1544         int i, index = 0;
1545         StitchState *state = (StitchState *)arg;
1546         StitchPreviewer *stitch_preview = state->stitch_preview;
1547
1548         glPushClientAttrib(GL_CLIENT_VERTEX_ARRAY_BIT);
1549         glEnableClientState(GL_VERTEX_ARRAY);
1550
1551         glEnable(GL_BLEND);
1552
1553         UI_ThemeColor4(TH_STITCH_PREVIEW_ACTIVE);
1554         glVertexPointer(2, GL_FLOAT, 0, stitch_preview->static_tris);
1555         glDrawArrays(GL_TRIANGLES, 0, stitch_preview->num_static_tris * 3);
1556
1557         glVertexPointer(2, GL_FLOAT, 0, stitch_preview->preview_polys);
1558         for (i = 0; i < stitch_preview->num_polys; i++) {
1559                 glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
1560                 UI_ThemeColor4(TH_STITCH_PREVIEW_FACE);
1561                 glDrawArrays(GL_POLYGON, index, stitch_preview->uvs_per_polygon[i]);
1562                 glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
1563                 UI_ThemeColor4(TH_STITCH_PREVIEW_EDGE);
1564                 glDrawArrays(GL_POLYGON, index, stitch_preview->uvs_per_polygon[i]);
1565 #if 0
1566                 glPolygonMode(GL_FRONT_AND_BACK, GL_POINT);
1567                 UI_ThemeColor4(TH_STITCH_PREVIEW_VERT);
1568                 glDrawArrays(GL_POLYGON, index, stitch_preview->uvs_per_polygon[i]);
1569 #endif
1570
1571                 index += stitch_preview->uvs_per_polygon[i];
1572         }
1573         glDisable(GL_BLEND);
1574
1575         /* draw vert preview */
1576         if (state->mode == STITCH_VERT) {
1577                 glPointSize(UI_GetThemeValuef(TH_VERTEX_SIZE) * 2.0f);
1578
1579                 UI_ThemeColor4(TH_STITCH_PREVIEW_STITCHABLE);
1580                 glVertexPointer(2, GL_FLOAT, 0, stitch_preview->preview_stitchable);
1581                 glDrawArrays(GL_POINTS, 0, stitch_preview->num_stitchable);
1582
1583                 UI_ThemeColor4(TH_STITCH_PREVIEW_UNSTITCHABLE);
1584                 glVertexPointer(2, GL_FLOAT, 0, stitch_preview->preview_unstitchable);
1585                 glDrawArrays(GL_POINTS, 0, stitch_preview->num_unstitchable);
1586         }
1587         else {
1588                 UI_ThemeColor4(TH_STITCH_PREVIEW_STITCHABLE);
1589                 glVertexPointer(2, GL_FLOAT, 0, stitch_preview->preview_stitchable);
1590                 glDrawArrays(GL_LINES, 0, 2 * stitch_preview->num_stitchable);
1591
1592                 UI_ThemeColor4(TH_STITCH_PREVIEW_UNSTITCHABLE);
1593                 glVertexPointer(2, GL_FLOAT, 0, stitch_preview->preview_unstitchable);
1594                 glDrawArrays(GL_LINES, 0, 2 * stitch_preview->num_unstitchable);
1595         }
1596
1597         glPopClientAttrib();
1598         glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
1599 }
1600
1601 static UvEdge *uv_edge_get(BMLoop *l, StitchState *state)
1602 {
1603         UvEdge tmp_edge;
1604
1605         UvElement *element1 = BM_uv_element_get(state->element_map, l->f, l);
1606         UvElement *element2 = BM_uv_element_get(state->element_map, l->f, l->next);
1607
1608         int uv1 = state->map[element1 - state->element_map->buf];
1609         int uv2 = state->map[element2 - state->element_map->buf];
1610
1611         if (uv1 < uv2) {
1612                 tmp_edge.uv1 = uv1;
1613                 tmp_edge.uv2 = uv2;
1614         }
1615         else {
1616                 tmp_edge.uv1 = uv2;
1617                 tmp_edge.uv2 = uv1;
1618         }
1619
1620         return BLI_ghash_lookup(state->edge_hash, &tmp_edge);
1621 }
1622
1623 static int stitch_init(bContext *C, wmOperator *op)
1624 {
1625         /* for fast edge lookup... */
1626         GHash *edge_hash;
1627         /* ...and actual edge storage */
1628         UvEdge *edges;
1629         int total_edges;
1630         /* maps uvelements to their first coincident uv */
1631         int *map;
1632         int counter = 0, i;
1633         BMFace *efa;
1634         BMLoop *l;
1635         BMIter iter, liter;
1636         GHashIterator gh_iter;
1637         UvEdge *all_edges;
1638         StitchState *state;
1639         Scene *scene = CTX_data_scene(C);
1640         ToolSettings *ts = scene->toolsettings;
1641         ARegion *ar = CTX_wm_region(C);
1642         float aspx, aspy;
1643         Object *obedit = CTX_data_edit_object(C);
1644         BMEditMesh *em = BKE_editmesh_from_object(obedit);
1645         const int cd_loop_uv_offset = CustomData_get_offset(&em->bm->ldata, CD_MLOOPUV);
1646
1647         if (!ar)
1648                 return 0;
1649
1650         state = MEM_callocN(sizeof(StitchState), "stitch state");
1651
1652         op->customdata = state;
1653
1654         /* initialize state */
1655         state->use_limit = RNA_boolean_get(op->ptr, "use_limit");
1656         state->limit_dist = RNA_float_get(op->ptr, "limit");
1657         state->em = em;
1658         state->snap_islands = RNA_boolean_get(op->ptr, "snap_islands");
1659         state->static_island = RNA_int_get(op->ptr, "static_island");
1660         state->midpoints = RNA_boolean_get(op->ptr, "midpoint_snap");
1661         state->clear_seams = RNA_boolean_get(op->ptr, "clear_seams");
1662         if (RNA_struct_property_is_set(op->ptr, "mode")) {
1663                 state->mode = RNA_enum_get(op->ptr, "mode");
1664         }
1665         else {
1666                 if (ts->uv_flag & UV_SYNC_SELECTION) {
1667                         if (ts->selectmode & SCE_SELECT_VERTEX)
1668                                 state->mode = STITCH_VERT;
1669                         else
1670                                 state->mode = STITCH_EDGE;
1671                 }
1672                 else {
1673                         if (ts->uv_selectmode & UV_SELECT_VERTEX) {
1674                                 state->mode = STITCH_VERT;
1675                         }
1676                         else {
1677                                 state->mode = STITCH_EDGE;
1678                         }
1679                 }
1680         }
1681
1682         /* in uv synch selection, all uv's are visible */
1683         if (ts->uv_flag & UV_SYNC_SELECTION) {
1684                 state->element_map = BM_uv_element_map_create(state->em->bm, false, true, true);
1685         }
1686         else {
1687                 state->element_map = BM_uv_element_map_create(state->em->bm, true, true, true);
1688         }
1689         if (!state->element_map) {
1690                 state_delete(state);
1691                 return 0;
1692         }
1693
1694         ED_uvedit_get_aspect(scene, obedit, em->bm, &aspx, &aspy);
1695         state->aspect = aspx / aspy;
1696
1697         /* Entirely possible if redoing last operator that static island is bigger than total number of islands.
1698          * This ensures we get no hang in the island checking code in stitch_stitch_process_data. */
1699         state->static_island %= state->element_map->totalIslands;
1700
1701         /* Count 'unique' uvs */
1702         for (i = 0; i < state->element_map->totalUVs; i++) {
1703                 if (state->element_map->buf[i].separate) {
1704                         counter++;
1705                 }
1706         }
1707
1708         /* explicitly set preview to NULL, to avoid deleting an invalid pointer on stitch_process_data */
1709         state->stitch_preview = NULL;
1710         /* Allocate the unique uv buffers */
1711         state->uvs = MEM_mallocN(sizeof(*state->uvs) * counter, "uv_stitch_unique_uvs");
1712         /* internal uvs need no normals but it is hard and slow to keep a map of
1713          * normals only for boundary uvs, so allocating for all uvs */
1714         state->normals = MEM_callocN(sizeof(*state->normals) * counter * 2, "uv_stitch_normals");
1715         state->total_separate_uvs = counter;
1716         state->map = map = MEM_mallocN(sizeof(*map) * state->element_map->totalUVs, "uv_stitch_unique_map");
1717         /* Allocate the edge stack */
1718         edge_hash = BLI_ghash_new(uv_edge_hash, uv_edge_compare, "stitch_edge_hash");
1719         all_edges = MEM_mallocN(sizeof(*all_edges) * state->element_map->totalUVs, "stitch_all_edges");
1720
1721         if (!state->uvs || !map || !edge_hash || !all_edges) {
1722                 state_delete(state);
1723                 return 0;
1724         }
1725
1726         /* So that we can use this as index for the UvElements */
1727         counter = -1;
1728         /* initialize the unique UVs and map */
1729         for (i = 0; i < em->bm->totvert; i++) {
1730                 UvElement *element = state->element_map->vert[i];
1731                 for (; element; element = element->next) {
1732                         if (element->separate) {
1733                                 counter++;
1734                                 state->uvs[counter] = element;
1735                         }
1736                         /* pointer arithmetic to the rescue, as always :)*/
1737                         map[element - state->element_map->buf] = counter;
1738                 }
1739         }
1740
1741         counter = 0;
1742         /* Now, on to generate our uv connectivity data */
1743         BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
1744                 if (!(ts->uv_flag & UV_SYNC_SELECTION) &&
1745                     ((BM_elem_flag_test(efa, BM_ELEM_HIDDEN)) || !BM_elem_flag_test(efa, BM_ELEM_SELECT)))
1746                 {
1747                         continue;
1748                 }
1749
1750                 BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
1751                         UvElement *element = BM_uv_element_get(state->element_map, efa, l);
1752                         int offset1, itmp1 = element - state->element_map->buf;
1753                         int offset2, itmp2 = BM_uv_element_get(state->element_map, efa, l->next) - state->element_map->buf;
1754                         UvEdge *edge;
1755
1756                         offset1 = map[itmp1];
1757                         offset2 = map[itmp2];
1758
1759                         all_edges[counter].next = NULL;
1760                         all_edges[counter].first = NULL;
1761                         all_edges[counter].flag = 0;
1762                         all_edges[counter].element = element;
1763                         /* using an order policy, sort uvs according to address space. This avoids
1764                          * Having two different UvEdges with the same uvs on different positions  */
1765                         if (offset1 < offset2) {
1766                                 all_edges[counter].uv1 = offset1;
1767                                 all_edges[counter].uv2 = offset2;
1768                         }
1769                         else {
1770                                 all_edges[counter].uv1 = offset2;
1771                                 all_edges[counter].uv2 = offset1;
1772                         }
1773
1774                         edge = BLI_ghash_lookup(edge_hash, &all_edges[counter]);
1775                         if (edge) {
1776                                 edge->flag = 0;
1777                         }
1778                         else {
1779                                 BLI_ghash_insert(edge_hash, &all_edges[counter], &all_edges[counter]);
1780                                 all_edges[counter].flag = STITCH_BOUNDARY;
1781                         }
1782                         counter++;
1783                 }
1784         }
1785
1786         total_edges = BLI_ghash_len(edge_hash);
1787         state->edges = edges = MEM_mallocN(sizeof(*edges) * total_edges, "stitch_edges");
1788
1789         /* I assume any system will be able to at least allocate an iterator :p */
1790         if (!edges) {
1791                 state_delete(state);
1792                 return 0;
1793         }
1794
1795         state->total_separate_edges = total_edges;
1796
1797         /* fill the edges with data */
1798         i = 0;
1799         GHASH_ITER (gh_iter, edge_hash) {
1800                 edges[i++] = *((UvEdge *)BLI_ghashIterator_getKey(&gh_iter));
1801         }
1802
1803         /* cleanup temporary stuff */
1804         MEM_freeN(all_edges);
1805
1806         BLI_ghash_free(edge_hash, NULL, NULL);
1807
1808         /* refill an edge hash to create edge connnectivity data */
1809         state->edge_hash = edge_hash = BLI_ghash_new(uv_edge_hash, uv_edge_compare, "stitch_edge_hash");
1810         for (i = 0; i < total_edges; i++) {
1811                 BLI_ghash_insert(edge_hash, edges + i, edges + i);
1812         }
1813         stitch_uv_edge_generate_linked_edges(edge_hash, state);
1814
1815         /***** calculate 2D normals for boundary uvs *****/
1816
1817         /* we use boundary edges to calculate 2D normals.
1818          * to disambiguate the direction of the normal, we also need
1819          * a point "inside" the island, that can be provided by
1820          * the winding of the polygon (assuming counter-clockwise flow). */
1821
1822         for (i = 0; i < total_edges; i++) {
1823                 UvEdge *edge = edges + i;
1824                 float normal[2];
1825                 if (edge->flag & STITCH_BOUNDARY) {
1826                         stitch_calculate_edge_normal(em, edge, normal, state->aspect);
1827
1828                         add_v2_v2(state->normals + edge->uv1 * 2, normal);
1829                         add_v2_v2(state->normals + edge->uv2 * 2, normal);
1830
1831                         normalize_v2(state->normals + edge->uv1 * 2);
1832                         normalize_v2(state->normals + edge->uv2 * 2);
1833                 }
1834         }
1835
1836
1837         /***** fill selection stack *******/
1838
1839         state->selection_size = 0;
1840
1841         /* Load old selection if redoing operator with different settings */
1842         if (RNA_struct_property_is_set(op->ptr, "selection")) {
1843                 int faceIndex, elementIndex;
1844                 UvElement *element;
1845                 enum StitchModes stored_mode = RNA_enum_get(op->ptr, "stored_mode");
1846
1847                 BM_mesh_elem_table_ensure(em->bm, BM_FACE);
1848
1849                 if (stored_mode == STITCH_VERT) {
1850                         state->selection_stack = MEM_mallocN(sizeof(*state->selection_stack) * state->total_separate_uvs, "uv_stitch_selection_stack");
1851
1852                         RNA_BEGIN (op->ptr, itemptr, "selection")
1853                         {
1854                                 faceIndex = RNA_int_get(&itemptr, "face_index");
1855                                 elementIndex = RNA_int_get(&itemptr, "element_index");
1856                                 efa = BM_face_at_index(em->bm, faceIndex);
1857                                 element = BM_uv_element_get(state->element_map, efa, BM_iter_at_index(NULL, BM_LOOPS_OF_FACE, efa, elementIndex));
1858                                 stitch_select_uv(element, state, 1);
1859                         }
1860                         RNA_END;
1861                 }
1862                 else {
1863                         state->selection_stack = MEM_mallocN(sizeof(*state->selection_stack) * state->total_separate_edges, "uv_stitch_selection_stack");
1864
1865                         RNA_BEGIN (op->ptr, itemptr, "selection")
1866                         {
1867                                 UvEdge tmp_edge, *edge;
1868                                 int uv1, uv2;
1869                                 faceIndex = RNA_int_get(&itemptr, "face_index");
1870                                 elementIndex = RNA_int_get(&itemptr, "element_index");
1871                                 efa = BM_face_at_index(em->bm, faceIndex);
1872                                 element = BM_uv_element_get(state->element_map, efa, BM_iter_at_index(NULL, BM_LOOPS_OF_FACE, efa, elementIndex));
1873                                 uv1 = map[element - state->element_map->buf];
1874
1875                                 element = BM_uv_element_get(state->element_map, efa, BM_iter_at_index(NULL, BM_LOOPS_OF_FACE, efa, (elementIndex + 1) % efa->len));
1876                                 uv2 = map[element - state->element_map->buf];
1877
1878                                 if (uv1 < uv2) {
1879                                         tmp_edge.uv1 = uv1;
1880                                         tmp_edge.uv2 = uv2;
1881                                 }
1882                                 else {
1883                                         tmp_edge.uv1 = uv2;
1884                                         tmp_edge.uv2 = uv1;
1885                                 }
1886
1887                                 edge = BLI_ghash_lookup(edge_hash, &tmp_edge);
1888
1889                                 stitch_select_edge(edge, state, true);
1890                         }
1891                         RNA_END;
1892                 }
1893                 /* if user has switched the operator mode after operation, we need to convert
1894                  * the stored format */
1895                 if (state->mode != stored_mode) {
1896                         state->mode = stored_mode;
1897                         stitch_switch_selection_mode(state);
1898                 }
1899                 /* Clear the selection */
1900                 RNA_collection_clear(op->ptr, "selection");
1901
1902         }
1903         else {
1904                 if (state->mode == STITCH_VERT) {
1905                         state->selection_stack = MEM_mallocN(sizeof(*state->selection_stack) * state->total_separate_uvs, "uv_stitch_selection_stack");
1906
1907                         BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
1908                                 BM_ITER_ELEM_INDEX (l, &liter, efa, BM_LOOPS_OF_FACE, i) {
1909                                         if (uvedit_uv_select_test(scene, l, cd_loop_uv_offset)) {
1910                                                 UvElement *element = BM_uv_element_get(state->element_map, efa, l);
1911                                                 if (element) {
1912                                                         stitch_select_uv(element, state, 1);
1913                                                 }
1914                                         }
1915                                 }
1916                         }
1917                 }
1918                 else {
1919                         state->selection_stack = MEM_mallocN(sizeof(*state->selection_stack) * state->total_separate_edges, "uv_stitch_selection_stack");
1920
1921                         BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
1922                                 if (!(ts->uv_flag & UV_SYNC_SELECTION) &&
1923                                     ((BM_elem_flag_test(efa, BM_ELEM_HIDDEN)) || !BM_elem_flag_test(efa, BM_ELEM_SELECT)))
1924                                 {
1925                                         continue;
1926                                 }
1927
1928                                 BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
1929                                         if (uvedit_edge_select_test(scene, l, cd_loop_uv_offset)) {
1930                                                 UvEdge *edge = uv_edge_get(l, state);
1931                                                 if (edge) {
1932                                                         stitch_select_edge(edge, state, true);
1933                                                 }
1934                                         }
1935                                 }
1936                         }
1937                 }
1938         }
1939
1940         /***** initialize static island preview data *****/
1941
1942         state->tris_per_island = MEM_mallocN(sizeof(*state->tris_per_island) * state->element_map->totalIslands,
1943                                              "stitch island tris");
1944         for (i = 0; i < state->element_map->totalIslands; i++) {
1945                 state->tris_per_island[i] = 0;
1946         }
1947
1948         BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
1949                 UvElement *element = BM_uv_element_get(state->element_map, efa, BM_FACE_FIRST_LOOP(efa));
1950
1951                 if (element) {
1952                         state->tris_per_island[element->island] += (efa->len > 2) ? efa->len - 2 : 0;
1953                 }
1954         }
1955
1956         if (!stitch_process_data(state, scene, false)) {
1957
1958                 state_delete(state);
1959                 return 0;
1960         }
1961
1962         state->draw_handle = ED_region_draw_cb_activate(ar->type, stitch_draw, state, REGION_DRAW_POST_VIEW);
1963
1964         stitch_update_header(state, C);
1965         return 1;
1966 }
1967
1968 static int stitch_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
1969 {
1970         Object *obedit = CTX_data_edit_object(C);
1971         if (!stitch_init(C, op))
1972                 return OPERATOR_CANCELLED;
1973
1974         WM_event_add_modal_handler(C, op);
1975         WM_event_add_notifier(C, NC_GEOM | ND_DATA, obedit->data);
1976         return OPERATOR_RUNNING_MODAL;
1977 }
1978
1979 static void stitch_exit(bContext *C, wmOperator *op, int finished)
1980 {
1981         StitchState *state;
1982         Scene *scene;
1983         SpaceImage *sima;
1984         ScrArea *sa = CTX_wm_area(C);
1985         Object *obedit;
1986
1987         scene = CTX_data_scene(C);
1988         obedit = CTX_data_edit_object(C);
1989         sima = CTX_wm_space_image(C);
1990
1991         state = (StitchState *)op->customdata;
1992
1993         if (finished) {
1994                 int i;
1995
1996                 RNA_float_set(op->ptr, "limit", state->limit_dist);
1997                 RNA_boolean_set(op->ptr, "use_limit", state->use_limit);
1998                 RNA_boolean_set(op->ptr, "snap_islands", state->snap_islands);
1999                 RNA_int_set(op->ptr, "static_island", state->static_island);
2000                 RNA_boolean_set(op->ptr, "midpoint_snap", state->midpoints);
2001                 RNA_enum_set(op->ptr, "mode", state->mode);
2002                 RNA_enum_set(op->ptr, "stored_mode", state->mode);
2003
2004                 /* Store selection for re-execution of stitch */
2005                 RNA_collection_clear(op->ptr, "selection");
2006                 for (i = 0; i < state->selection_size; i++) {
2007                         UvElement *element;
2008                         PointerRNA itemptr;
2009                         if (state->mode == STITCH_VERT) {
2010                                 element = state->selection_stack[i];
2011                         }
2012                         else {
2013                                 element = ((UvEdge *)state->selection_stack[i])->element;
2014                         }
2015                         RNA_collection_add(op->ptr, "selection", &itemptr);
2016
2017                         RNA_int_set(&itemptr, "face_index", BM_elem_index_get(element->l->f));
2018                         RNA_int_set(&itemptr, "element_index", element->loop_of_poly_index);
2019                 }
2020
2021                 uvedit_live_unwrap_update(sima, scene, obedit);
2022         }
2023
2024         if (sa)
2025                 ED_area_headerprint(sa, NULL);
2026
2027         ED_region_draw_cb_exit(CTX_wm_region(C)->type, state->draw_handle);
2028
2029         DAG_id_tag_update(obedit->data, 0);
2030         WM_event_add_notifier(C, NC_GEOM | ND_DATA, obedit->data);
2031
2032         state_delete(state);
2033         op->customdata = NULL;
2034 }
2035
2036
2037 static void stitch_cancel(bContext *C, wmOperator *op)
2038 {
2039         stitch_exit(C, op, 0);
2040 }
2041
2042
2043 static int stitch_exec(bContext *C, wmOperator *op)
2044 {
2045         Scene *scene = CTX_data_scene(C);
2046
2047         if (!stitch_init(C, op))
2048                 return OPERATOR_CANCELLED;
2049         if (stitch_process_data((StitchState *)op->customdata, scene, 1)) {
2050                 stitch_exit(C, op, 1);
2051                 return OPERATOR_FINISHED;
2052         }
2053         else {
2054                 stitch_cancel(C, op);
2055                 return OPERATOR_CANCELLED;
2056         }
2057 }
2058
2059 static void stitch_select(bContext *C, Scene *scene, const wmEvent *event, StitchState *state)
2060 {
2061         /* add uv under mouse to processed uv's */
2062         float co[2];
2063         UvNearestHit hit = UV_NEAREST_HIT_INIT;
2064         ARegion *ar = CTX_wm_region(C);
2065         Image *ima = CTX_data_edit_image(C);
2066
2067         UI_view2d_region_to_view(&ar->v2d, event->mval[0], event->mval[1], &co[0], &co[1]);
2068
2069         if (state->mode == STITCH_VERT) {
2070                 if (uv_find_nearest_vert(
2071                             scene, ima, state->em, co, 0.0f, &hit))
2072                 {
2073                         /* Add vertex to selection, deselect all common uv's of vert other
2074                          * than selected and update the preview. This behavior was decided so that
2075                          * you can do stuff like deselect the opposite stitchable vertex and the initial still gets deselected */
2076
2077                         /* This works due to setting of tmp in find nearest uv vert */
2078                         UvElement *element = BM_uv_element_get(state->element_map, hit.efa, hit.l);
2079                         stitch_select_uv(element, state, false);
2080
2081                 }
2082         }
2083         else {
2084                 if (uv_find_nearest_edge(
2085                             scene, ima, state->em, co, &hit))
2086                 {
2087                         UvEdge *edge = uv_edge_get(hit.l, state);
2088                         stitch_select_edge(edge, state, false);
2089                 }
2090         }
2091 }
2092
2093 static int stitch_modal(bContext *C, wmOperator *op, const wmEvent *event)
2094 {
2095         StitchState *state;
2096         Scene *scene = CTX_data_scene(C);
2097
2098         state = (StitchState *)op->customdata;
2099
2100         switch (event->type) {
2101                 case MIDDLEMOUSE:
2102                         return OPERATOR_PASS_THROUGH;
2103
2104                         /* Cancel */
2105                 case ESCKEY:
2106                         stitch_cancel(C, op);
2107                         return OPERATOR_CANCELLED;
2108
2109                 case LEFTMOUSE:
2110                         if (event->shift && (U.flag & USER_LMOUSESELECT)) {
2111                                 if (event->val == KM_PRESS) {
2112                                         stitch_select(C, scene, event, state);
2113
2114                                         if (!stitch_process_data(state, scene, false)) {
2115                                                 stitch_cancel(C, op);
2116                                                 return OPERATOR_CANCELLED;
2117                                         }
2118                                 }
2119                                 break;
2120                         }
2121                         ATTR_FALLTHROUGH;
2122                 case PADENTER:
2123                 case RETKEY:
2124                         if (event->val == KM_PRESS) {
2125                                 if (stitch_process_data(state, scene, true)) {
2126                                         stitch_exit(C, op, 1);
2127                                         return OPERATOR_FINISHED;
2128                                 }
2129                                 else {
2130                                         stitch_cancel(C, op);
2131                                         return OPERATOR_CANCELLED;
2132                                 }
2133                         }
2134                         else {
2135                                 return OPERATOR_PASS_THROUGH;
2136                         }
2137                         /* Increase limit */
2138                 case PADPLUSKEY:
2139                 case WHEELUPMOUSE:
2140                         if (event->val == KM_PRESS && event->alt) {
2141                                 state->limit_dist += 0.01f;
2142                                 if (!stitch_process_data(state, scene, false)) {
2143                                         stitch_cancel(C, op);
2144                                         return OPERATOR_CANCELLED;
2145                                 }
2146                                 break;
2147                         }
2148                         else {
2149                                 return OPERATOR_PASS_THROUGH;
2150                         }
2151                         /* Decrease limit */
2152                 case PADMINUS:
2153                 case WHEELDOWNMOUSE:
2154                         if (event->val == KM_PRESS && event->alt) {
2155                                 state->limit_dist -= 0.01f;
2156                                 state->limit_dist = MAX2(0.01f, state->limit_dist);
2157                                 if (!stitch_process_data(state, scene, false)) {
2158                                         stitch_cancel(C, op);
2159                                         return OPERATOR_CANCELLED;
2160                                 }
2161                                 break;
2162                         }
2163                         else {
2164                                 return OPERATOR_PASS_THROUGH;
2165                         }
2166
2167                         /* Use Limit (Default off) */
2168                 case LKEY:
2169                         if (event->val == KM_PRESS) {
2170                                 state->use_limit = !state->use_limit;
2171                                 if (!stitch_process_data(state, scene, false)) {
2172                                         stitch_cancel(C, op);
2173                                         return OPERATOR_CANCELLED;
2174                                 }
2175                                 break;
2176                         }
2177                         return OPERATOR_RUNNING_MODAL;
2178
2179                 case IKEY:
2180                         if (event->val == KM_PRESS) {
2181                                 state->static_island++;
2182                                 state->static_island %= state->element_map->totalIslands;
2183
2184                                 if (!stitch_process_data(state, scene, false)) {
2185                                         stitch_cancel(C, op);
2186                                         return OPERATOR_CANCELLED;
2187                                 }
2188                                 break;
2189                         }
2190                         return OPERATOR_RUNNING_MODAL;
2191
2192                 case MKEY:
2193                         if (event->val == KM_PRESS) {
2194                                 state->midpoints = !state->midpoints;
2195                                 if (!stitch_process_data(state, scene, false)) {
2196                                         stitch_cancel(C, op);
2197                                         return OPERATOR_CANCELLED;
2198                                 }
2199                         }
2200                         break;
2201
2202                         /* Select geometry */
2203                 case RIGHTMOUSE:
2204                         if (!event->shift) {
2205                                 stitch_cancel(C, op);
2206                                 return OPERATOR_CANCELLED;
2207                         }
2208                         if (event->val == KM_PRESS && !(U.flag & USER_LMOUSESELECT)) {
2209                                 stitch_select(C, scene, event, state);
2210
2211                                 if (!stitch_process_data(state, scene, false)) {
2212                                         stitch_cancel(C, op);
2213                                         return OPERATOR_CANCELLED;
2214                                 }
2215                                 break;
2216                         }
2217                         return OPERATOR_RUNNING_MODAL;
2218
2219                         /* snap islands on/off */
2220                 case SKEY:
2221                         if (event->val == KM_PRESS) {
2222                                 state->snap_islands = !state->snap_islands;
2223                                 if (!stitch_process_data(state, scene, false)) {
2224                                         stitch_cancel(C, op);
2225                                         return OPERATOR_CANCELLED;
2226                                 }
2227                                 break;
2228                         }
2229                         else {
2230                                 return OPERATOR_RUNNING_MODAL;
2231                         }
2232
2233                         /* switch between edge/vertex mode */
2234                 case TABKEY:
2235                         if (event->val == KM_PRESS) {
2236                                 stitch_switch_selection_mode(state);
2237
2238                                 if (!stitch_process_data(state, scene, false)) {
2239                                         stitch_cancel(C, op);
2240                                         return OPERATOR_CANCELLED;
2241                                 }
2242                         }
2243                         break;
2244
2245                 default:
2246                         return OPERATOR_RUNNING_MODAL;
2247         }
2248
2249         /* if updated settings, renew feedback message */
2250         stitch_update_header(state, C);
2251         ED_region_tag_redraw(CTX_wm_region(C));
2252         return OPERATOR_RUNNING_MODAL;
2253 }
2254
2255 void UV_OT_stitch(wmOperatorType *ot)
2256 {
2257         PropertyRNA *prop;
2258
2259         static const EnumPropertyItem stitch_modes[] = {
2260             {STITCH_VERT, "VERTEX", 0, "Vertex", ""},
2261             {STITCH_EDGE, "EDGE", 0, "Edge", ""},
2262             {0, NULL, 0, NULL, NULL}
2263         };
2264
2265         /* identifiers */
2266         ot->name = "Stitch";
2267         ot->description = "Stitch selected UV vertices by proximity";
2268         ot->idname = "UV_OT_stitch";
2269         ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
2270
2271         /* api callbacks */
2272         ot->invoke = stitch_invoke;
2273         ot->modal = stitch_modal;
2274         ot->exec = stitch_exec;
2275         ot->cancel = stitch_cancel;
2276         ot->poll = ED_operator_uvedit;
2277
2278         /* properties */
2279         RNA_def_boolean(ot->srna, "use_limit", 0, "Use Limit", "Stitch UVs within a specified limit distance");
2280         RNA_def_boolean(ot->srna, "snap_islands", 1, "Snap Islands",
2281                         "Snap islands together (on edge stitch mode, rotates the islands too)");
2282
2283         RNA_def_float(ot->srna, "limit", 0.01f, 0.0f, FLT_MAX, "Limit",
2284                       "Limit distance in normalized coordinates", 0.0, FLT_MAX);
2285         RNA_def_int(ot->srna, "static_island", 0, 0, INT_MAX, "Static Island",
2286                     "Island that stays in place when stitching islands", 0, INT_MAX);
2287         RNA_def_boolean(ot->srna, "midpoint_snap", 0, "Snap At Midpoint",
2288                         "UVs are stitched at midpoint instead of at static island");
2289         RNA_def_boolean(ot->srna, "clear_seams", 1, "Clear Seams",
2290                         "Clear seams of stitched edges");
2291         RNA_def_enum(ot->srna, "mode", stitch_modes, STITCH_VERT, "Operation Mode",
2292                      "Use vertex or edge stitching");
2293         prop =  RNA_def_enum(ot->srna, "stored_mode", stitch_modes, STITCH_VERT, "Stored Operation Mode",
2294                              "Use vertex or edge stitching");
2295         RNA_def_property_flag(prop, PROP_HIDDEN);
2296         prop = RNA_def_collection_runtime(ot->srna, "selection", &RNA_SelectedUvElement, "Selection", "");
2297         /* Selection should not be editable or viewed in toolbar */
2298         RNA_def_property_flag(prop, PROP_HIDDEN);
2299 }