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