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