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