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