rename api functions...
[blender.git] / source / blender / editors / uvedit / uvedit_smart_stitch.c
1 /*
2  * ***** BEGIN GPL LICENSE BLOCK *****
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License
6  * as published by the Free Software Foundation; either version 2
7  * of the License, or (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software Foundation,
16  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17  *
18  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
19  * All rights reserved.
20  *
21  * The Original Code is: all of this file.
22  *
23  * Contributor(s): Antony Riakiotakis.
24  *
25  * ***** END GPL LICENSE BLOCK *****
26  */
27
28 /** \file blender/editors/uvedit/uvedit_smart_stitch.c
29  *  \ingroup eduv
30  */
31
32
33 #include <stdlib.h>
34 #include <string.h>
35 #include <math.h>
36
37 #include "MEM_guardedalloc.h"
38
39 #include "DNA_object_types.h"
40 #include "DNA_mesh_types.h"
41 #include "DNA_meshdata_types.h"
42 #include "DNA_scene_types.h"
43
44 #include "BLI_ghash.h"
45 #include "BLI_math.h"
46 #include "BLI_math_vector.h"
47 #include "BLI_string.h"
48
49 #include "BIF_gl.h"
50
51 #include "BKE_context.h"
52 #include "BKE_customdata.h"
53 #include "BKE_depsgraph.h"
54 #include "BKE_mesh.h"
55 #include "BKE_tessmesh.h"
56
57 #include "ED_mesh.h"
58 #include "ED_uvedit.h"
59 #include "ED_screen.h"
60 #include "ED_space_api.h"
61
62 #include "RNA_access.h"
63 #include "RNA_define.h"
64
65 #include "WM_api.h"
66 #include "WM_types.h"
67
68 #include "UI_view2d.h"
69 #include "UI_resources.h"
70
71 #include "uvedit_intern.h"
72
73 /* ********************** smart stitch operator *********************** */
74
75 /* object that stores display data for previewing before accepting stitching */
76 typedef struct StitchPreviewer {
77         /* here we'll store the preview triangle indices of the mesh */
78         float *preview_polys;
79         /* uvs per polygon. */
80         unsigned int *uvs_per_polygon;
81         /*number of preview polygons */
82         unsigned int num_polys;
83         /* preview data. These will be either the previewed vertices or edges depending on stitch mode settings */
84         float *preview_stitchable;
85         float *preview_unstitchable;
86         /* here we'll store the number of elements to be drawn */
87         unsigned int num_stitchable;
88         unsigned int num_unstitchable;
89         unsigned int preview_uvs;
90         /* ...and here we'll store the triangles*/
91         float *static_tris;
92         unsigned int num_static_tris;
93 } StitchPreviewer;
94
95
96 struct IslandStitchData;
97
98 /* This is a straightforward implementation, count the uv's in the island that will move and take the mean displacement/rotation and apply it to all
99  * elements of the island except from the stitchable */
100 typedef struct IslandStitchData {
101         /* rotation can be used only for edges, for vertices there is no such notion */
102         float rotation;
103         float translation[2];
104         /* Used for rotation, the island will rotate around this point */
105         float medianPoint[2];
106         int numOfElements;
107         int num_rot_elements;
108         /* flag to remember if island has been added for preview */
109         char addedForPreview;
110         /* flag an island to be considered for determining static island */
111         char stitchableCandidate;
112         /* if edge rotation is used, flag so that vertex rotation is not used */
113         char use_edge_rotation;
114 } IslandStitchData;
115
116 /* just for averaging UVs */
117 typedef struct UVVertAverage {
118         float uv[2];
119         unsigned short count;
120 } UVVertAverage;
121
122 typedef struct UvEdge {
123         /* index to uv buffer */
124         unsigned int uv1;
125         unsigned int uv2;
126         /* general use flag (Used to check if edge is boundary here, and propagates to adjacency elements) */
127         char flag;
128         /* element that guarantees element->face has the face on element->tfindex and element->tfindex+1 is the second uv */
129         UvElement *element;
130 } UvEdge;
131
132
133 /* stitch state object */
134 typedef struct StitchState {
135         /* use limit flag */
136         char use_limit;
137         /* limit to operator, same as original operator */
138         float limit_dist;
139         /* snap uv islands together during stitching */
140         char snap_islands;
141         /* stich at midpoints or at islands */
142         char midpoints;
143         /* editmesh, cached for use in modal handler */
144         BMEditMesh *em;
145         /* clear seams of stitched edges after stitch */
146         char clear_seams;
147         /* element map for getting info about uv connectivity */
148         UvElementMap *element_map;
149         /* edge container */
150         UvEdge *uvedges;
151         /* container of first of a group of coincident uvs, these will be operated upon */
152         UvElement **uvs;
153         /* maps uvelements to their first coincident uv */
154         int *map;
155         /* 2D normals per uv to calculate rotation for snapping */
156         float *normals;
157         /* edge storage */
158         UvEdge *edges;
159
160         /* count of separate uvs and edges */
161         int total_boundary_edges;
162         int total_separate_uvs;
163         /* hold selection related information */
164         UvElement **selection_stack;
165         int selection_size;
166         /* island that stays in place */
167         int static_island;
168         /* store number of primitives per face so that we can allocate the active island buffer later */
169         unsigned int *tris_per_island;
170
171         void *draw_handle;
172 } StitchState;
173
174 typedef struct PreviewPosition {
175         int data_position;
176         int polycount_position;
177 } PreviewPosition;
178 /*
179  * defines for UvElement flags
180  */
181 #define STITCH_SELECTED 1
182 #define STITCH_STITCHABLE 2
183 #define STITCH_PROCESSED 4
184 #define STITCH_BOUNDARY 8
185 #define STITCH_STITCHABLE_CANDIDATE 16
186
187 #define STITCH_NO_PREVIEW -1
188
189 /* previewer stuff (see uvedit_intern.h for more info) */
190 static StitchPreviewer *_stitch_preview;
191
192 /* constructor */
193 static StitchPreviewer *stitch_preview_init(void)
194 {
195         _stitch_preview = MEM_mallocN(sizeof(StitchPreviewer), "stitch_previewer");
196         _stitch_preview->preview_polys = NULL;
197         _stitch_preview->preview_stitchable = NULL;
198         _stitch_preview->preview_unstitchable = NULL;
199         _stitch_preview->uvs_per_polygon = NULL;
200
201         _stitch_preview->preview_uvs = 0;
202         _stitch_preview->num_polys = 0;
203         _stitch_preview->num_stitchable = 0;
204         _stitch_preview->num_unstitchable = 0;
205
206         _stitch_preview->static_tris = NULL;
207
208         _stitch_preview->num_static_tris = 0;
209
210         return _stitch_preview;
211 }
212
213 /* destructor...yeah this should be C++ :) */
214 static void stitch_preview_delete(void)
215 {
216         if (_stitch_preview) {
217                 if (_stitch_preview->preview_polys) {
218                         MEM_freeN(_stitch_preview->preview_polys);
219                         _stitch_preview->preview_polys = NULL;
220                 }
221                 if (_stitch_preview->uvs_per_polygon) {
222                         MEM_freeN(_stitch_preview->uvs_per_polygon);
223                         _stitch_preview->uvs_per_polygon = NULL;
224                 }
225                 if (_stitch_preview->preview_stitchable) {
226                         MEM_freeN(_stitch_preview->preview_stitchable);
227                         _stitch_preview->preview_stitchable = NULL;
228                 }
229                 if (_stitch_preview->preview_unstitchable) {
230                         MEM_freeN(_stitch_preview->preview_unstitchable);
231                         _stitch_preview->preview_unstitchable = NULL;
232                 }
233                 if (_stitch_preview->static_tris) {
234                         MEM_freeN(_stitch_preview->static_tris);
235                         _stitch_preview->static_tris = NULL;
236                 }
237
238                 MEM_freeN(_stitch_preview);
239                 _stitch_preview = NULL;
240         }
241 }
242
243
244 /* "getter method" */
245 static StitchPreviewer *uv_get_stitch_previewer(void)
246 {
247         return _stitch_preview;
248 }
249
250 #define HEADER_LENGTH 256
251
252 /* This function updates the header of the UV editor when the stitch tool updates its settings */
253 static void stitch_update_header(StitchState *stitch_state, bContext *C)
254 {
255         static char str[] = "(S)nap %s, (M)idpoints %s, (L)imit %.2f (Alt Wheel adjust) %s, Switch (I)sland, shift select vertices";
256
257         char msg[HEADER_LENGTH];
258         ScrArea *sa = CTX_wm_area(C);
259
260         if (sa) {
261                 BLI_snprintf(msg, HEADER_LENGTH, str,
262                              stitch_state->snap_islands ? "On" : "Off",
263                              stitch_state->midpoints    ? "On" : "Off",
264                              stitch_state->limit_dist,
265                              stitch_state->use_limit    ? "On" : "Off");
266
267                 ED_area_headerprint(sa, msg);
268         }
269 }
270
271 static int getNumOfIslandUvs(UvElementMap *elementMap, int island)
272 {
273         if (island == elementMap->totalIslands - 1) {
274                 return elementMap->totalUVs - elementMap->islandIndices[island];
275         }
276         else {
277                 return elementMap->islandIndices[island + 1] - elementMap->islandIndices[island];
278         }
279 }
280
281 static void stitch_uv_rotate(float rotation, float medianPoint[2], float uv[2])
282 {
283         float uv_rotation_result[2];
284
285         uv[0] -= medianPoint[0];
286         uv[1] -= medianPoint[1];
287
288         uv_rotation_result[0] = cosf(rotation) * uv[0] - sinf(rotation) * uv[1];
289         uv_rotation_result[1] = sinf(rotation) * uv[0] + cosf(rotation) * uv[1];
290
291         uv[0] = uv_rotation_result[0] + medianPoint[0];
292         uv[1] = uv_rotation_result[1] + medianPoint[1];
293 }
294
295 static int stitch_check_uvs_stitchable(UvElement *element, UvElement *element_iter, StitchState *state)
296 {
297         float limit;
298         int do_limit;
299
300         if (element_iter == element) {
301                 return 0;
302         }
303
304         limit = state->limit_dist;
305         do_limit = state->use_limit;
306
307         if (do_limit) {
308                 MLoopUV *luv_orig, *luv_iter;
309                 BMLoop *l_orig, *l_iter;
310
311
312                 l_orig = element->l;
313                 luv_orig = CustomData_bmesh_get(&state->em->bm->ldata, l_orig->head.data, CD_MLOOPUV);
314                 l_iter = element_iter->l;
315                 luv_iter = CustomData_bmesh_get(&state->em->bm->ldata, l_iter->head.data, CD_MLOOPUV);
316
317                 if (fabsf(luv_orig->uv[0] - luv_iter->uv[0]) < limit &&
318                     fabsf(luv_orig->uv[1] - luv_iter->uv[1]) < limit)
319                 {
320                         return 1;
321                 }
322                 else {
323                         return 0;
324                 }
325         }
326         else {
327                 return 1;
328         }
329 }
330
331
332 static int stitch_check_uvs_state_stitchable(UvElement *element, UvElement *element_iter, StitchState *state)
333 {
334         if ((state->snap_islands && element->island == element_iter->island) ||
335             (!state->midpoints && element->island == element_iter->island))
336         {
337                 return 0;
338         }
339
340         return stitch_check_uvs_stitchable(element, element_iter, state);
341 }
342
343
344 /* calculate snapping for islands */
345 static void stitch_calculate_island_snapping(StitchState *state, PreviewPosition *preview_position, StitchPreviewer *preview, IslandStitchData *island_stitch_data, int final)
346 {
347         int i;
348         UvElement *element;
349
350         for (i = 0; i < state->element_map->totalIslands; i++) {
351                 if (island_stitch_data[i].addedForPreview) {
352                         int numOfIslandUVs = 0, j;
353
354                         /* check to avoid divide by 0 */
355                         if (island_stitch_data[i].num_rot_elements > 0) {
356                                 island_stitch_data[i].rotation /= island_stitch_data[i].num_rot_elements;
357                                 island_stitch_data[i].medianPoint[0] /= island_stitch_data[i].numOfElements;
358                                 island_stitch_data[i].medianPoint[1] /= island_stitch_data[i].numOfElements;
359                         }
360                         island_stitch_data[i].translation[0] /= island_stitch_data[i].numOfElements;
361                         island_stitch_data[i].translation[1] /= island_stitch_data[i].numOfElements;
362                         numOfIslandUVs = getNumOfIslandUvs(state->element_map, i);
363                         element = &state->element_map->buf[state->element_map->islandIndices[i]];
364                         for (j = 0; j < numOfIslandUVs; j++, element++) {
365                                 /* stitchable uvs have already been processed, don't process */
366                                 if (!(element->flag & STITCH_PROCESSED)) {
367                                         MLoopUV *luv;
368                                         BMLoop *l;
369
370                                         l = element->l;
371                                         luv = CustomData_bmesh_get(&state->em->bm->ldata, l->head.data, CD_MLOOPUV);
372
373                                         if (final) {
374
375                                                 stitch_uv_rotate(island_stitch_data[i].rotation, island_stitch_data[i].medianPoint, luv->uv);
376
377                                                 add_v2_v2(luv->uv, island_stitch_data[i].translation);
378                                         }
379
380                                         else {
381                                                 int face_preview_pos = preview_position[BM_elem_index_get(element->face)].data_position;
382
383                                                 stitch_uv_rotate(island_stitch_data[i].rotation, island_stitch_data[i].medianPoint,
384                                                                  preview->preview_polys + face_preview_pos + 2 * element->tfindex);
385
386                                                 add_v2_v2(preview->preview_polys + face_preview_pos + 2 * element->tfindex,
387                                                           island_stitch_data[i].translation);
388                                         }
389                                 }
390                                 /* cleanup */
391                                 element->flag &= STITCH_SELECTED;
392                         }
393                 }
394         }
395 }
396
397
398
399 static void stitch_island_calculate_edge_rotation(UvEdge *edge, StitchState *state, UVVertAverage *uv_average, unsigned int *uvfinal_map, IslandStitchData *island_stitch_data)
400 {
401         UvElement *element1, *element2;
402         float uv1[2], uv2[2];
403         float edgecos, edgesin;
404         int index1, index2;
405         float rotation;
406         MLoopUV *luv1, *luv2;
407         BMLoop *l1, *l2;
408
409         element1 = state->uvs[edge->uv1];
410         element2 = state->uvs[edge->uv2];
411
412         l1 = element1->l;
413         luv1 = CustomData_bmesh_get(&state->em->bm->ldata, l1->head.data, CD_MLOOPUV);
414         l2 = element2->l;
415         luv2 = CustomData_bmesh_get(&state->em->bm->ldata, l2->head.data, CD_MLOOPUV);
416
417         index1 = uvfinal_map[element1 - state->element_map->buf];
418         index2 = uvfinal_map[element2 - state->element_map->buf];
419
420         /* the idea here is to take the directions of the edges and find the rotation between final and initial
421          * direction. This, using inner and outer vector products, gives the angle. Directions are differences so... */
422         uv1[0] = luv2->uv[0] - luv1->uv[0];
423         uv1[1] = luv2->uv[1] - luv1->uv[1];
424
425         uv2[0] = uv_average[index2].uv[0] - uv_average[index1].uv[0];
426         uv2[1] = uv_average[index2].uv[1] - uv_average[index1].uv[1];
427
428         normalize_v2(uv1);
429         normalize_v2(uv2);
430
431         edgecos = uv1[0] * uv2[0] + uv1[1] * uv2[1];
432         edgesin = uv1[0] * uv2[1] - uv2[0] * uv1[1];
433
434         rotation = (edgesin > 0.0f) ?
435                     +acosf(max_ff(-1.0f, min_ff(1.0f, edgecos))) :
436                     -acosf(max_ff(-1.0f, min_ff(1.0f, edgecos)));
437
438         island_stitch_data[element1->island].num_rot_elements++;
439         island_stitch_data[element1->island].rotation += rotation;
440 }
441
442
443 static void stitch_island_calculate_vert_rotation(UvElement *element, StitchState *state, IslandStitchData *island_stitch_data)
444 {
445         float edgecos = 1.0f, edgesin = 0.0f;
446         int index;
447         UvElement *element_iter;
448         float rotation = 0;
449         BMLoop *l;
450
451         if (element->island == state->static_island && !state->midpoints)
452                 return;
453
454         l = element->l;
455
456         index = BM_elem_index_get(l->v);
457
458         element_iter = state->element_map->vert[index];
459
460         for (; element_iter; element_iter = element_iter->next) {
461                 if (element_iter->separate && stitch_check_uvs_state_stitchable(element, element_iter, state)) {
462                         int index_tmp1, index_tmp2;
463                         float normal[2];
464                         /* easily possible*/
465
466                         index_tmp1 = element_iter - state->element_map->buf;
467                         index_tmp1 = state->map[index_tmp1];
468                         index_tmp2 = element - state->element_map->buf;
469                         index_tmp2 = state->map[index_tmp2];
470
471                         negate_v2_v2(normal, state->normals + index_tmp2 * 2);
472                         edgecos = dot_v2v2(normal, state->normals + index_tmp1 * 2);
473                         edgesin = cross_v2v2(normal, state->normals + index_tmp1 * 2);
474                         rotation += (edgesin > 0.0f) ? acosf(edgecos) : -acosf(edgecos);
475                 }
476         }
477
478         if (state->midpoints)
479                 rotation /= 2.0f;
480         island_stitch_data[element->island].num_rot_elements++;
481         island_stitch_data[element->island].rotation += rotation;
482 }
483
484
485 static void stitch_state_delete(StitchState *stitch_state)
486 {
487         if (stitch_state) {
488                 if (stitch_state->element_map) {
489                         EDBM_uv_element_map_free(stitch_state->element_map);
490                 }
491                 if (stitch_state->uvs) {
492                         MEM_freeN(stitch_state->uvs);
493                 }
494                 if (stitch_state->selection_stack) {
495                         MEM_freeN(stitch_state->selection_stack);
496                 }
497                 if (stitch_state->tris_per_island) {
498                         MEM_freeN(stitch_state->tris_per_island);
499                 }
500                 if (stitch_state->map) {
501                         MEM_freeN(stitch_state->map);
502                 }
503                 if (stitch_state->normals) {
504                         MEM_freeN(stitch_state->normals);
505                 }
506                 if (stitch_state->edges) {
507                         MEM_freeN(stitch_state->edges);
508                 }
509                 MEM_freeN(stitch_state);
510         }
511 }
512
513
514
515 /* checks for remote uvs that may be stitched with a certain uv, flags them if stitchable. */
516 static void determine_uv_stitchability(UvElement *element, StitchState *state, IslandStitchData *island_stitch_data)
517 {
518         int vert_index;
519         UvElement *element_iter;
520         BMLoop *l;
521
522         l = element->l;
523
524         vert_index = BM_elem_index_get(l->v);
525         element_iter = state->element_map->vert[vert_index];
526
527         for (; element_iter; element_iter = element_iter->next) {
528                 if (element_iter->separate) {
529                         if (element_iter == element) {
530                                 continue;
531                         }
532                         if (stitch_check_uvs_stitchable(element, element_iter, state)) {
533                                 island_stitch_data[element_iter->island].stitchableCandidate = 1;
534                                 island_stitch_data[element->island].stitchableCandidate = 1;
535                                 element->flag |= STITCH_STITCHABLE_CANDIDATE;
536                         }
537                 }
538         }
539 }
540
541
542 /* set preview buffer position of UV face in editface->tmp.l */
543 static void stitch_set_face_preview_buffer_position(BMFace *efa, StitchPreviewer *preview, PreviewPosition *preview_position)
544 {
545         int index = BM_elem_index_get(efa);
546
547         if (preview_position[index].data_position == STITCH_NO_PREVIEW) {
548                 preview_position[index].data_position = preview->preview_uvs * 2;
549                 preview_position[index].polycount_position = preview->num_polys++;
550                 preview->preview_uvs += efa->len;
551         }
552 }
553
554
555 /* setup face preview for all coincident uvs and their faces */
556 static void stitch_setup_face_preview_for_uv_group(UvElement *element, StitchState *state, IslandStitchData *island_stitch_data,
557                                                    PreviewPosition *preview_position) {
558         StitchPreviewer *preview = uv_get_stitch_previewer();
559
560         /* static island does not change so returning immediately */
561         if (state->snap_islands && !state->midpoints && state->static_island == element->island)
562                 return;
563
564         if (state->snap_islands) {
565                 island_stitch_data[element->island].addedForPreview = 1;
566         }
567
568         do {
569                 stitch_set_face_preview_buffer_position(element->face, preview, preview_position);
570                 element = element->next;
571         } while (element && !element->separate);
572 }
573
574
575 /* checks if uvs are indeed stitchable and registers so that they can be shown in preview */
576 static void stitch_validate_stichability(UvElement *element, StitchState *state, IslandStitchData *island_stitch_data,
577                                          PreviewPosition *preview_position) {
578         UvElement *element_iter;
579         StitchPreviewer *preview;
580         int vert_index;
581         BMLoop *l;
582
583         l = element->l;
584
585         vert_index = BM_elem_index_get(l->v);
586
587         preview = uv_get_stitch_previewer();
588         element_iter = state->element_map->vert[vert_index];
589
590         for (; element_iter; element_iter = element_iter->next) {
591                 if (element_iter->separate) {
592                         if (element_iter == element)
593                                 continue;
594                         if (stitch_check_uvs_state_stitchable(element, element_iter, state)) {
595                                 if ((element_iter->island == state->static_island) || (element->island == state->static_island)) {
596                                         element->flag |= STITCH_STITCHABLE;
597                                         preview->num_stitchable++;
598                                         stitch_setup_face_preview_for_uv_group(element, state, island_stitch_data, preview_position);
599                                         return;
600                                 }
601                         }
602                 }
603         }
604
605         /* this can happen if the uvs to be stitched are not on a stitchable island */
606         if (!(element->flag & STITCH_STITCHABLE)) {
607                 preview->num_unstitchable++;
608         }
609 }
610
611 /* main processing function. It calculates preview and final positions. */
612 static int stitch_process_data(StitchState *state, Scene *scene, int final)
613 {
614         int i;
615         StitchPreviewer *preview;
616         IslandStitchData *island_stitch_data = NULL;
617         int previous_island = state->static_island;
618         BMFace *efa;
619         BMIter iter;
620         UVVertAverage *final_position;
621         char stitch_midpoints = state->midpoints;
622         /* used to map uv indices to uvaverage indices for selection */
623         unsigned int *uvfinal_map;
624         /* per face preview position in preview buffer */
625         PreviewPosition *preview_position;
626
627         /* cleanup previous preview */
628         stitch_preview_delete();
629         preview = stitch_preview_init();
630         if (preview == NULL)
631                 return 0;
632
633         preview_position = MEM_mallocN(state->em->bm->totface * sizeof(*preview_position), "stitch_face_preview_position");
634         /* each face holds its position in the preview buffer in tmp. -1 is uninitialized */
635         for (i = 0; i < state->em->bm->totface; i++) {
636                 preview_position[i].data_position = STITCH_NO_PREVIEW;
637         }
638
639         island_stitch_data = MEM_callocN(sizeof(*island_stitch_data) * state->element_map->totalIslands, "stitch_island_data");
640         if (!island_stitch_data) {
641                 return 0;
642         }
643
644         /* store indices to editVerts and Faces. May be unneeded but ensuring anyway */
645         BM_mesh_elem_index_ensure(state->em->bm, BM_VERT | BM_FACE);
646
647         /*****************************************
648          *  First determine stitchability of uvs *
649          *****************************************/
650
651         for (i = 0; i < state->selection_size; i++) {
652                 UvElement *element = state->selection_stack[i];
653                 determine_uv_stitchability(element, state, island_stitch_data);
654         }
655
656         /* set static island to one that is added for preview */
657         state->static_island %= state->element_map->totalIslands;
658         while (!(island_stitch_data[state->static_island].stitchableCandidate)) {
659                 state->static_island++;
660                 state->static_island %= state->element_map->totalIslands;
661                 /* this is entirely possible if for example limit stitching with no stitchable verts or no selection */
662                 if (state->static_island == previous_island)
663                         break;
664         }
665
666         for (i = 0; i < state->selection_size; i++) {
667                 UvElement *element = state->selection_stack[i];
668                 if (element->flag & STITCH_STITCHABLE_CANDIDATE) {
669                         element->flag &= ~STITCH_STITCHABLE_CANDIDATE;
670                         stitch_validate_stichability(element, state, island_stitch_data, preview_position);
671                 }
672                 else {
673                         /* add to preview for unstitchable */
674                         preview->num_unstitchable++;
675                 }
676         }
677
678         /*****************************************
679          *  Setup preview for stitchable islands *
680          *****************************************/
681         if (state->snap_islands) {
682                 for (i = 0; i < state->element_map->totalIslands; i++) {
683                         if (island_stitch_data[i].addedForPreview) {
684                                 int numOfIslandUVs = 0, j;
685                                 UvElement *element;
686                                 numOfIslandUVs = getNumOfIslandUvs(state->element_map, i);
687                                 element = &state->element_map->buf[state->element_map->islandIndices[i]];
688                                 for (j = 0; j < numOfIslandUVs; j++, element++) {
689                                         stitch_set_face_preview_buffer_position(element->face, preview, preview_position);
690                                 }
691                         }
692                 }
693         }
694
695         /*********************************************************************
696          * Setup the preview buffers and fill them with the appropriate data *
697          *********************************************************************/
698         if (!final) {
699                 BMIter liter;
700                 BMLoop *l;
701                 MLoopUV *luv;
702                 unsigned int buffer_index = 0;
703                 int stitchBufferIndex = 0, unstitchBufferIndex = 0;
704                 /* initialize the preview buffers */
705                 preview->preview_polys = (float *)MEM_mallocN(preview->preview_uvs * sizeof(float) * 2, "tri_uv_stitch_prev");
706                 preview->uvs_per_polygon = MEM_mallocN(preview->num_polys * sizeof(*preview->uvs_per_polygon), "tri_uv_stitch_prev");
707                 preview->preview_stitchable = (float *)MEM_mallocN(preview->num_stitchable * sizeof(float) * 2, "stitch_preview_stichable_data");
708                 preview->preview_unstitchable = (float *)MEM_mallocN(preview->num_unstitchable * sizeof(float) * 2, "stitch_preview_unstichable_data");
709
710                 preview->static_tris = (float *)MEM_mallocN(state->tris_per_island[state->static_island] * sizeof(float) * 6, "static_island_preview_tris");
711
712                 preview->num_static_tris = state->tris_per_island[state->static_island];
713                 /* will cause cancel and freeing of all data structures so OK */
714                 if (!preview->preview_polys || !preview->preview_stitchable || !preview->preview_unstitchable) {
715                         return 0;
716                 }
717
718                 /* copy data from MTFaces to the preview display buffers */
719                 BM_ITER_MESH (efa, &iter, state->em->bm, BM_FACES_OF_MESH) {
720                         /* just to test if face was added for processing. uvs of inselected vertices will return NULL */
721                         UvElement *element = ED_uv_element_get(state->element_map, efa, BM_FACE_FIRST_LOOP(efa));
722
723                         if (element) {
724                                 int numoftris = efa->len - 2;
725                                 int index = BM_elem_index_get(efa);
726                                 int face_preview_pos = preview_position[index].data_position;
727                                 if (face_preview_pos != STITCH_NO_PREVIEW) {
728                                         preview->uvs_per_polygon[preview_position[index].polycount_position] = efa->len;
729                                         BM_ITER_ELEM_INDEX (l, &liter, efa, BM_LOOPS_OF_FACE, i) {
730                                                 luv = CustomData_bmesh_get(&state->em->bm->ldata, l->head.data, CD_MLOOPUV);
731                                                 copy_v2_v2(preview->preview_polys + face_preview_pos + i * 2, luv->uv);
732                                         }
733                                 }
734
735                                 if (element->island == state->static_island) {
736                                         BMLoop *fl = BM_FACE_FIRST_LOOP(efa);
737                                         MLoopUV *fuv = CustomData_bmesh_get(&state->em->bm->ldata, fl->head.data, CD_MLOOPUV);
738
739                                         BM_ITER_ELEM_INDEX (l, &liter, efa, BM_LOOPS_OF_FACE, i) {
740                                                 if (i < numoftris) {
741                                                         /* using next since the first uv is already accounted for */
742                                                         BMLoop *lnext = l->next;
743                                                         MLoopUV *luvnext = CustomData_bmesh_get(&state->em->bm->ldata, lnext->next->head.data, CD_MLOOPUV);
744                                                         luv = CustomData_bmesh_get(&state->em->bm->ldata, lnext->head.data, CD_MLOOPUV);
745
746                                                         memcpy(preview->static_tris + buffer_index, fuv->uv, 2 * sizeof(float));
747                                                         memcpy(preview->static_tris + buffer_index + 2, luv->uv, 2 * sizeof(float));
748                                                         memcpy(preview->static_tris + buffer_index + 4, luvnext->uv, 2 * sizeof(float));
749                                                         buffer_index += 6;
750                                                 }
751                                                 else {
752                                                         break;
753                                                 }
754                                         }
755                                 }
756                         }
757                 }
758
759                 /* fill the appropriate preview buffers */
760                 for (i = 0; i < state->total_separate_uvs; i++) {
761                         UvElement *element = (UvElement *)state->uvs[i];
762                         if (element->flag & STITCH_STITCHABLE) {
763                                 l = element->l;
764                                 luv = CustomData_bmesh_get(&state->em->bm->ldata, l->head.data, CD_MLOOPUV);
765
766                                 copy_v2_v2(&preview->preview_stitchable[stitchBufferIndex * 2], luv->uv);
767
768                                 stitchBufferIndex++;
769                         }
770                         else if (element->flag & STITCH_SELECTED) {
771                                 l = element->l;
772                                 luv = CustomData_bmesh_get(&state->em->bm->ldata, l->head.data, CD_MLOOPUV);
773
774                                 copy_v2_v2(&preview->preview_unstitchable[unstitchBufferIndex * 2], luv->uv);
775                                 unstitchBufferIndex++;
776                         }
777                 }
778         }
779
780         /******************************************************
781          * Here we calculate the final coordinates of the uvs *
782          ******************************************************/
783
784         final_position = MEM_callocN(state->selection_size * sizeof(*final_position), "stitch_uv_average");
785         uvfinal_map = MEM_mallocN(state->element_map->totalUVs * sizeof(*uvfinal_map), "stitch_uv_final_map");
786
787         /* first pass, calculate final position for stitchable uvs of the static island */
788         for (i = 0; i < state->selection_size; i++) {
789                 UvElement *element = state->selection_stack[i];
790                 if (element->flag & STITCH_STITCHABLE) {
791                         BMLoop *l;
792                         MLoopUV *luv;
793                         UvElement *element_iter;
794
795                         l = element->l;
796                         luv = CustomData_bmesh_get(&state->em->bm->ldata, l->head.data, CD_MLOOPUV);
797
798
799                         uvfinal_map[element - state->element_map->buf] = i;
800
801                         copy_v2_v2(final_position[i].uv, luv->uv);
802                         final_position[i].count = 1;
803
804                         if (state->snap_islands && element->island == state->static_island && !stitch_midpoints)
805                                 continue;
806
807                         element_iter = state->element_map->vert[BM_elem_index_get(l->v)];
808
809                         for ( ; element_iter; element_iter = element_iter->next) {
810                                 if (element_iter->separate) {
811                                         if (stitch_check_uvs_state_stitchable(element, element_iter, state)) {
812                                                 l = element_iter->l;
813                                                 luv = CustomData_bmesh_get(&state->em->bm->ldata, l->head.data, CD_MLOOPUV);
814                                                 if (stitch_midpoints) {
815                                                         add_v2_v2(final_position[i].uv, luv->uv);
816                                                         final_position[i].count++;
817                                                 }
818                                                 else if (element_iter->island == state->static_island) {
819                                                         /* if multiple uvs on the static island exist,
820                                                          * last checked remains. to disambiguate we need to limit or use
821                                                          * edge stitch */
822                                                         copy_v2_v2(final_position[i].uv, luv->uv);
823                                                 }
824                                         }
825                                 }
826                         }
827                 }
828                 if (stitch_midpoints) {
829                         final_position[i].uv[0] /= final_position[i].count;
830                         final_position[i].uv[1] /= final_position[i].count;
831                 }
832         }
833
834         /* second pass, calculate island rotation and translation before modifying any uvs */
835         if (state->snap_islands) {
836                 for (i = 0; i < state->selection_size; i++) {
837                         UvElement *element = state->selection_stack[i];
838                         if (element->flag & STITCH_STITCHABLE) {
839                                 BMLoop *l;
840                                 MLoopUV *luv;
841
842                                 l = element->l;
843                                 luv = CustomData_bmesh_get(&state->em->bm->ldata, l->head.data, CD_MLOOPUV);
844
845                                 /* accumulate each islands' translation from stitchable elements. it is important to do here
846                                  * because in final pass MTFaces get modified and result is zero. */
847                                 island_stitch_data[element->island].translation[0] += final_position[i].uv[0] - luv->uv[0];
848                                 island_stitch_data[element->island].translation[1] += final_position[i].uv[1] - luv->uv[1];
849                                 island_stitch_data[element->island].medianPoint[0] += luv->uv[0];
850                                 island_stitch_data[element->island].medianPoint[1] += luv->uv[1];
851                                 island_stitch_data[element->island].numOfElements++;
852                         }
853                 }
854
855                 /* only calculate rotation when an edge has been fully selected */
856                 for (i = 0; i < state->total_boundary_edges; i++) {
857                         UvEdge *edge = state->edges + i;
858                         if ((state->uvs[edge->uv1]->flag & STITCH_STITCHABLE) && (state->uvs[edge->uv2]->flag & STITCH_STITCHABLE)) {
859                                 stitch_island_calculate_edge_rotation(edge, state, final_position, uvfinal_map, island_stitch_data);
860                                 island_stitch_data[state->uvs[edge->uv1]->island].use_edge_rotation = TRUE;
861                         }
862                 }
863
864                 /* clear seams of stitched edges */
865                 if (final && state->clear_seams) {
866                         for (i = 0; i < state->total_boundary_edges; i++) {
867                                 UvEdge *edge = state->edges + i;
868                                 if ((state->uvs[edge->uv1]->flag & STITCH_STITCHABLE) && (state->uvs[edge->uv2]->flag & STITCH_STITCHABLE))
869                                         BM_elem_flag_disable(edge->element->l->e, BM_ELEM_SEAM);
870                         }
871                 }
872
873                 for (i = 0; i < state->selection_size; i++) {
874                         UvElement *element = state->selection_stack[i];
875                         if (!island_stitch_data[element->island].use_edge_rotation) {
876                                 if (element->flag & STITCH_STITCHABLE) {
877                                         stitch_island_calculate_vert_rotation(element, state, island_stitch_data);
878                                 }
879                         }
880                 }
881
882         }
883
884         /* third pass, propagate changes to coincident uvs */
885         for (i = 0; i < state->selection_size; i++) {
886                 UvElement *element = state->selection_stack[i];
887                 if (element->flag & STITCH_STITCHABLE) {
888                         UvElement *element_iter = element;
889                         /* propagate to coincident uvs */
890                         do {
891                                 BMLoop *l;
892                                 MLoopUV *luv;
893
894                                 l = element_iter->l;
895                                 luv = CustomData_bmesh_get(&state->em->bm->ldata, l->head.data, CD_MLOOPUV);
896
897                                 element_iter->flag |= STITCH_PROCESSED;
898                                 /* either flush to preview or to the MTFace, if final */
899                                 if (final) {
900                                         copy_v2_v2(luv->uv, final_position[i].uv);
901
902                                         uvedit_uv_select_enable(state->em, scene, l, FALSE);
903                                 }
904                                 else {
905                                         int face_preview_pos = preview_position[BM_elem_index_get(element_iter->face)].data_position;
906                                         if (face_preview_pos != STITCH_NO_PREVIEW) {
907                                                 copy_v2_v2(preview->preview_polys + face_preview_pos + 2 * element_iter->tfindex,
908                                                            final_position[i].uv);
909                                         }
910                                 }
911
912                                 /* end of calculations, keep only the selection flag */
913                                 if ( (!state->snap_islands) || ((!stitch_midpoints) && (element_iter->island == state->static_island))) {
914                                         element_iter->flag &= STITCH_SELECTED;
915                                 }
916
917                                 element_iter = element_iter->next;
918                         } while (element_iter && !element_iter->separate);
919                 }
920         }
921
922         /* final pass, calculate Island translation/rotation if needed */
923         if (state->snap_islands) {
924                 stitch_calculate_island_snapping(state, preview_position, preview, island_stitch_data, final);
925         }
926
927         MEM_freeN(final_position);
928         MEM_freeN(uvfinal_map);
929         MEM_freeN(island_stitch_data);
930         MEM_freeN(preview_position);
931
932         return 1;
933 }
934
935 /* Stitch hash initialization functions */
936 static unsigned int uv_edge_hash(const void *key)
937 {
938         UvEdge *edge = (UvEdge *)key;
939         return
940             BLI_ghashutil_inthash(SET_INT_IN_POINTER(edge->uv2)) +
941             BLI_ghashutil_inthash(SET_INT_IN_POINTER(edge->uv1));
942 }
943
944 static int uv_edge_compare(const void *a, const void *b)
945 {
946         UvEdge *edge1 = (UvEdge *)a;
947         UvEdge *edge2 = (UvEdge *)b;
948
949         if ((edge1->uv1 == edge2->uv1) && (edge1->uv2 == edge2->uv2)) {
950                 return 0;
951         }
952         return 1;
953 }
954
955
956 /* Select all common uvs */
957 static void stitch_select_uv(UvElement *element, StitchState *state, int always_select)
958 {
959         BMLoop *l;
960         UvElement *element_iter;
961         UvElement **selection_stack = state->selection_stack;
962
963         l = element->l;
964
965         element_iter = state->element_map->vert[BM_elem_index_get(l->v)];
966         /* first deselect all common uvs */
967         for (; element_iter; element_iter = element_iter->next) {
968                 if (element_iter->separate) {
969                         /* only separators go to selection */
970                         if (element_iter->flag & STITCH_SELECTED) {
971                                 int i;
972                                 if (always_select)
973                                         continue;
974
975                                 element_iter->flag &= ~STITCH_SELECTED;
976                                 for (i = 0; i < state->selection_size; i++) {
977                                         if (selection_stack[i] == element_iter) {
978                                                 (state->selection_size)--;
979                                                 selection_stack[i] = selection_stack[state->selection_size];
980                                                 break;
981                                         }
982                                 }
983                         }
984                         else {
985                                 element_iter->flag |= STITCH_SELECTED;
986                                 selection_stack[state->selection_size++] = element_iter;
987                         }
988                 }
989         }
990 }
991
992 static void stitch_calculate_edge_normal(BMEditMesh *em, UvEdge *edge, float *normal)
993 {
994         BMLoop *l1 = edge->element->l;
995         BMLoop *l2 = l1->next;
996         MLoopUV *luv1, *luv2;
997         float tangent[2];
998
999         luv1 = CustomData_bmesh_get(&em->bm->ldata, l1->head.data, CD_MLOOPUV);
1000         luv2 = CustomData_bmesh_get(&em->bm->ldata, l2->head.data, CD_MLOOPUV);
1001
1002         sub_v2_v2v2(tangent, luv2->uv,  luv1->uv);
1003
1004         normal[0] = tangent[1];
1005         normal[1] = -tangent[0];
1006
1007         normalize_v2(normal);
1008 }
1009
1010 static void stitch_draw(const bContext *UNUSED(C), ARegion *UNUSED(ar), void *UNUSED(arg))
1011 {
1012         int i, index = 0;
1013         float pointsize = UI_GetThemeValuef(TH_VERTEX_SIZE);
1014         StitchPreviewer *stitch_preview = uv_get_stitch_previewer();
1015
1016         glPushClientAttrib(GL_CLIENT_VERTEX_ARRAY_BIT);
1017         glEnableClientState(GL_VERTEX_ARRAY);
1018
1019         glEnable(GL_BLEND);
1020
1021         UI_ThemeColor4(TH_STITCH_PREVIEW_ACTIVE);
1022         glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
1023         glVertexPointer(2, GL_FLOAT, 0, stitch_preview->static_tris);
1024         glDrawArrays(GL_TRIANGLES, 0, stitch_preview->num_static_tris * 3);
1025
1026         glVertexPointer(2, GL_FLOAT, 0, stitch_preview->preview_polys);
1027         for (i = 0; i < stitch_preview->num_polys; i++) {
1028                 glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
1029                 UI_ThemeColor4(TH_STITCH_PREVIEW_FACE);
1030                 glDrawArrays(GL_POLYGON, index, stitch_preview->uvs_per_polygon[i]);
1031                 glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
1032                 UI_ThemeColor4(TH_STITCH_PREVIEW_EDGE);
1033                 glDrawArrays(GL_POLYGON, index, stitch_preview->uvs_per_polygon[i]);
1034
1035                 index += stitch_preview->uvs_per_polygon[i];
1036         }
1037         glPolygonMode(GL_FRONT_AND_BACK, GL_POINT);
1038 #if 0
1039         UI_ThemeColor4(TH_STITCH_PREVIEW_VERT);
1040         glDrawArrays(GL_TRIANGLES, 0, stitch_preview->num_tris * 3);
1041 #endif
1042         glDisable(GL_BLEND);
1043
1044         /* draw vert preview */
1045         glPointSize(pointsize * 2.0f);
1046         UI_ThemeColor4(TH_STITCH_PREVIEW_STITCHABLE);
1047         glVertexPointer(2, GL_FLOAT, 0, stitch_preview->preview_stitchable);
1048         glDrawArrays(GL_POINTS, 0, stitch_preview->num_stitchable);
1049
1050         UI_ThemeColor4(TH_STITCH_PREVIEW_UNSTITCHABLE);
1051         glVertexPointer(2, GL_FLOAT, 0, stitch_preview->preview_unstitchable);
1052         glDrawArrays(GL_POINTS, 0, stitch_preview->num_unstitchable);
1053
1054         glPopClientAttrib();
1055         glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
1056
1057 }
1058
1059 static int stitch_init(bContext *C, wmOperator *op)
1060 {
1061         /* for fast edge lookup... */
1062         GHash *edgeHash;
1063         /* ...and actual edge storage */
1064         UvEdge *edges;
1065         int total_edges;
1066         /* maps uvelements to their first coincident uv */
1067         int *map;
1068         int counter = 0, i;
1069         BMFace *efa;
1070         BMLoop *l;
1071         BMIter iter, liter;
1072         BMEditMesh *em;
1073         GHashIterator *ghi;
1074         UvEdge *all_edges;
1075         StitchState *state = MEM_mallocN(sizeof(StitchState), "stitch state");
1076         Scene *scene = CTX_data_scene(C);
1077         ToolSettings *ts = scene->toolsettings;
1078
1079         Object *obedit = CTX_data_edit_object(C);
1080
1081         op->customdata = state;
1082
1083         if (!state)
1084                 return 0;
1085
1086         /* initialize state */
1087         state->use_limit = RNA_boolean_get(op->ptr, "use_limit");
1088         state->limit_dist = RNA_float_get(op->ptr, "limit");
1089         state->em = em = BMEdit_FromObject(obedit);
1090         state->snap_islands = RNA_boolean_get(op->ptr, "snap_islands");
1091         state->static_island = RNA_int_get(op->ptr, "static_island");
1092         state->midpoints = RNA_boolean_get(op->ptr, "midpoint_snap");
1093         state->clear_seams = RNA_boolean_get(op->ptr, "clear_seams");
1094         state->draw_handle = ED_region_draw_cb_activate(CTX_wm_region(C)->type, stitch_draw, NULL, REGION_DRAW_POST_VIEW);
1095         /* in uv synch selection, all uv's are visible */
1096         if (ts->uv_flag & UV_SYNC_SELECTION) {
1097                 state->element_map = EDBM_uv_element_map_create(state->em, 0, 1);
1098         }
1099         else {
1100                 state->element_map = EDBM_uv_element_map_create(state->em, 1, 1);
1101         }
1102         if (!state->element_map) {
1103                 stitch_state_delete(state);
1104                 return 0;
1105         }
1106
1107         /* Entirely possible if redoing last operator that static island is bigger than total number of islands.
1108          * This ensures we get no hang in the island checking code in stitch_process_data. */
1109         state->static_island %= state->element_map->totalIslands;
1110
1111         /* Count 'unique' uvs */
1112         for (i = 0; i < state->element_map->totalUVs; i++) {
1113                 if (state->element_map->buf[i].separate) {
1114                         counter++;
1115                 }
1116         }
1117
1118         /* Allocate the unique uv buffers */
1119         state->uvs = MEM_mallocN(sizeof(*state->uvs) * counter, "uv_stitch_unique_uvs");
1120         /* internal uvs need no normals but it is hard and slow to keep a map of
1121          * normals only for boundary uvs, so allocating for all uvs */
1122         state->normals = MEM_callocN(sizeof(*state->normals) * counter * 2, "uv_stitch_normals");
1123         state->total_separate_uvs = counter;
1124         /* we can at most have totalUVs edges or uvs selected. Actually they are less, considering we store only
1125          * unique uvs for processing but I am accounting for all bizarre cases, especially for edges, this way */
1126         state->selection_stack = MEM_mallocN(sizeof(*state->selection_stack) * counter, "uv_stitch_selection_stack");
1127         state->map = map = MEM_mallocN(sizeof(*map) * state->element_map->totalUVs, "uv_stitch_unique_map");
1128         /* Allocate the edge stack */
1129         edgeHash = BLI_ghash_new(uv_edge_hash, uv_edge_compare, "stitch_edge_hash");
1130         all_edges = MEM_mallocN(sizeof(*all_edges) * state->element_map->totalUVs, "stitch_all_edges");
1131
1132         if (!state->selection_stack || !state->uvs || !map || !edgeHash || !all_edges) {
1133                 stitch_state_delete(state);
1134                 return 0;
1135         }
1136
1137         /* So that we can use this as index for the UvElements */
1138         counter = -1;
1139         /* initialize the unique UVs and map */
1140         for (i = 0; i < em->bm->totvert; i++) {
1141                 UvElement *element = state->element_map->vert[i];
1142                 for (; element; element = element->next) {
1143                         if (element->separate) {
1144                                 counter++;
1145                                 state->uvs[counter] = element;
1146                         }
1147                         /* pointer arithmetic to the rescue, as always :)*/
1148                         map[element - state->element_map->buf] = counter;
1149                 }
1150         }
1151
1152         counter = 0;
1153         /* Now, on to generate our uv connectivity data */
1154         BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
1155                 if (!(ts->uv_flag & UV_SYNC_SELECTION) && ((BM_elem_flag_test(efa, BM_ELEM_HIDDEN)) || !BM_elem_flag_test(efa, BM_ELEM_SELECT)))
1156                         continue;
1157
1158                 BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
1159                         UvElement *element = ED_uv_element_get(state->element_map, efa, l);
1160                         int offset1, itmp1 = element - state->element_map->buf;
1161                         int offset2, itmp2 = ED_uv_element_get(state->element_map, efa, l->next) - state->element_map->buf;
1162
1163                         offset1 = map[itmp1];
1164                         offset2 = map[itmp2];
1165
1166                         all_edges[counter].flag = 0;
1167                         all_edges[counter].element = element;
1168                         /* using an order policy, sort uvs according to address space. This avoids
1169                          * Having two different UvEdges with the same uvs on different positions  */
1170                         if (offset1 < offset2) {
1171                                 all_edges[counter].uv1 = offset1;
1172                                 all_edges[counter].uv2 = offset2;
1173                         }
1174                         else {
1175                                 all_edges[counter].uv1 = offset2;
1176                                 all_edges[counter].uv2 = offset1;
1177                         }
1178
1179                         if (BLI_ghash_haskey(edgeHash, &all_edges[counter])) {
1180                                 char *flag = BLI_ghash_lookup(edgeHash, &all_edges[counter]);
1181                                 *flag = 0;
1182                         }
1183                         else {
1184                                 BLI_ghash_insert(edgeHash, &all_edges[counter], &(all_edges[counter].flag));
1185                                 all_edges[counter].flag = STITCH_BOUNDARY;
1186                         }
1187                         counter++;
1188                 }
1189         }
1190
1191
1192         ghi = BLI_ghashIterator_new(edgeHash);
1193         total_edges = 0;
1194         /* fill the edges with data */
1195         for (; !BLI_ghashIterator_isDone(ghi); BLI_ghashIterator_step(ghi)) {
1196                 UvEdge *edge = ((UvEdge *)BLI_ghashIterator_getKey(ghi));
1197                 if (edge->flag & STITCH_BOUNDARY) {
1198                         total_edges++;
1199                 }
1200         }
1201         state->edges = edges = MEM_mallocN(sizeof(*edges) * total_edges, "stitch_edges");
1202         if (!ghi || !edges) {
1203                 MEM_freeN(all_edges);
1204                 stitch_state_delete(state);
1205                 return 0;
1206         }
1207
1208         state->total_boundary_edges = total_edges;
1209
1210         /* fill the edges with data */
1211         for (i = 0, BLI_ghashIterator_init(ghi, edgeHash); !BLI_ghashIterator_isDone(ghi); BLI_ghashIterator_step(ghi)) {
1212                 UvEdge *edge = ((UvEdge *)BLI_ghashIterator_getKey(ghi));
1213                 if (edge->flag & STITCH_BOUNDARY) {
1214                         edges[i++] = *((UvEdge *)BLI_ghashIterator_getKey(ghi));
1215                 }
1216         }
1217
1218         /* cleanup temporary stuff */
1219         BLI_ghashIterator_free(ghi);
1220         MEM_freeN(all_edges);
1221
1222         /* refill hash with new pointers to cleanup duplicates */
1223         BLI_ghash_free(edgeHash, NULL, NULL);
1224
1225         /***** calculate 2D normals for boundary uvs *****/
1226
1227         /* we use boundary edges to calculate 2D normals.
1228          * to disambiguate the direction of the normal, we also need
1229          * a point "inside" the island, that can be provided by
1230          * the opposite uv for a quad, or the next uv for a triangle. */
1231
1232         for (i = 0; i < total_edges; i++) {
1233                 float normal[2];
1234                 stitch_calculate_edge_normal(em, edges + i, normal);
1235
1236                 add_v2_v2(state->normals + edges[i].uv1 * 2, normal);
1237                 add_v2_v2(state->normals + edges[i].uv2 * 2, normal);
1238
1239                 normalize_v2(state->normals + edges[i].uv1 * 2);
1240                 normalize_v2(state->normals + edges[i].uv2 * 2);
1241         }
1242
1243
1244         /***** fill selection stack *******/
1245
1246         state->selection_size = 0;
1247
1248         /* Load old selection if redoing operator with different settings */
1249         if (RNA_struct_property_is_set(op->ptr, "selection")) {
1250                 int faceIndex, elementIndex;
1251                 UvElement *element;
1252
1253                 EDBM_index_arrays_init(em, 0, 0, 1);
1254
1255                 RNA_BEGIN (op->ptr, itemptr, "selection")
1256                 {
1257                         faceIndex = RNA_int_get(&itemptr, "face_index");
1258                         elementIndex = RNA_int_get(&itemptr, "element_index");
1259                         efa = EDBM_face_at_index(em, faceIndex);
1260                         element = ED_uv_element_get(state->element_map, efa, BM_iter_at_index(NULL, BM_LOOPS_OF_FACE, efa, elementIndex));
1261                         stitch_select_uv(element, state, 1);
1262                 }
1263                 RNA_END;
1264
1265                 EDBM_index_arrays_free(em);
1266                 /* Clear the selection */
1267                 RNA_collection_clear(op->ptr, "selection");
1268
1269         }
1270         else {
1271                 BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
1272                         BM_ITER_ELEM_INDEX (l, &liter, efa, BM_LOOPS_OF_FACE, i) {
1273                                 if (uvedit_uv_select_test(em, scene, l)) {
1274                                         UvElement *element = ED_uv_element_get(state->element_map, efa, l);
1275                                         if (element) {
1276                                                 stitch_select_uv(element, state, 1);
1277                                         }
1278                                 }
1279                         }
1280                 }
1281         }
1282
1283         /***** initialize static island preview data *****/
1284
1285         state->tris_per_island = MEM_mallocN(sizeof(*state->tris_per_island) * state->element_map->totalIslands,
1286                                              "stitch island tris");
1287         for (i = 0; i < state->element_map->totalIslands; i++) {
1288                 state->tris_per_island[i] = 0;
1289         }
1290
1291         BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
1292                 UvElement *element = ED_uv_element_get(state->element_map, efa, BM_FACE_FIRST_LOOP(efa));
1293
1294                 if (element) {
1295                         state->tris_per_island[element->island] += (efa->len > 2) ? efa->len - 2 : 0;
1296                 }
1297         }
1298
1299         if (!stitch_process_data(state, scene, 0)) {
1300                 stitch_state_delete(state);
1301                 return 0;
1302         }
1303
1304         stitch_update_header(state, C);
1305         return 1;
1306 }
1307
1308 static int stitch_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
1309 {
1310         Object *obedit = CTX_data_edit_object(C);
1311         if (!stitch_init(C, op))
1312                 return OPERATOR_CANCELLED;
1313
1314         WM_event_add_modal_handler(C, op);
1315         WM_event_add_notifier(C, NC_GEOM | ND_DATA, obedit->data);
1316         return OPERATOR_RUNNING_MODAL;
1317 }
1318
1319 static void stitch_exit(bContext *C, wmOperator *op, int finished)
1320 {
1321         StitchState *stitch_state;
1322         Scene *scene;
1323         SpaceImage *sima;
1324         ScrArea *sa = CTX_wm_area(C);
1325         Object *obedit;
1326
1327         scene = CTX_data_scene(C);
1328         obedit = CTX_data_edit_object(C);
1329         sima = CTX_wm_space_image(C);
1330
1331         stitch_state = (StitchState *)op->customdata;
1332
1333         if (finished) {
1334                 int i;
1335
1336                 RNA_float_set(op->ptr, "limit", stitch_state->limit_dist);
1337                 RNA_boolean_set(op->ptr, "use_limit", stitch_state->use_limit);
1338                 RNA_boolean_set(op->ptr, "snap_islands", stitch_state->snap_islands);
1339                 RNA_int_set(op->ptr, "static_island", stitch_state->static_island);
1340                 RNA_boolean_set(op->ptr, "midpoint_snap", stitch_state->midpoints);
1341
1342                 /* Store selection for re-execution of stitch */
1343                 for (i = 0; i < stitch_state->selection_size; i++) {
1344                         PointerRNA itemptr;
1345                         UvElement *element = stitch_state->selection_stack[i];
1346
1347                         RNA_collection_add(op->ptr, "selection", &itemptr);
1348
1349                         RNA_int_set(&itemptr, "face_index", BM_elem_index_get(element->face));
1350
1351                         RNA_int_set(&itemptr, "element_index", element->tfindex);
1352                 }
1353
1354
1355                 uvedit_live_unwrap_update(sima, scene, obedit);
1356         }
1357
1358         if (sa)
1359                 ED_area_headerprint(sa, NULL);
1360
1361         ED_region_draw_cb_exit(CTX_wm_region(C)->type, stitch_state->draw_handle);
1362
1363         DAG_id_tag_update(obedit->data, 0);
1364         WM_event_add_notifier(C, NC_GEOM | ND_DATA, obedit->data);
1365
1366         stitch_state_delete(stitch_state);
1367         op->customdata = NULL;
1368
1369         stitch_preview_delete();
1370 }
1371
1372
1373 static int stitch_cancel(bContext *C, wmOperator *op)
1374 {
1375         stitch_exit(C, op, 0);
1376         return OPERATOR_CANCELLED;
1377 }
1378
1379
1380 static int stitch_exec(bContext *C, wmOperator *op)
1381 {
1382         Scene *scene = CTX_data_scene(C);
1383
1384         if (!stitch_init(C, op))
1385                 return OPERATOR_CANCELLED;
1386         if (stitch_process_data((StitchState *)op->customdata, scene, 1)) {
1387                 stitch_exit(C, op, 1);
1388                 return OPERATOR_FINISHED;
1389         }
1390         else {
1391                 return stitch_cancel(C, op);
1392         }
1393 }
1394
1395 static void stitch_select(bContext *C, Scene *scene, wmEvent *event, StitchState *stitch_state)
1396 {
1397         /* add uv under mouse to processed uv's */
1398         float co[2];
1399         NearestHit hit;
1400         ARegion *ar = CTX_wm_region(C);
1401         Image *ima = CTX_data_edit_image(C);
1402
1403         UI_view2d_region_to_view(&ar->v2d, event->mval[0], event->mval[1], &co[0], &co[1]);
1404         uv_find_nearest_vert(scene, ima, stitch_state->em, co, NULL, &hit);
1405
1406         if (hit.efa) {
1407                 /* Add vertex to selection, deselect all common uv's of vert other
1408                  * than selected and update the preview. This behavior was decided so that
1409                  * you can do stuff like deselect the opposite stitchable vertex and the initial still gets deselected */
1410
1411                 /* This works due to setting of tmp in find nearest uv vert */
1412                 UvElement *element = ED_uv_element_get(stitch_state->element_map, hit.efa, hit.l);
1413                 stitch_select_uv(element, stitch_state, 0);
1414
1415         }
1416 }
1417
1418 static int stitch_modal(bContext *C, wmOperator *op, wmEvent *event)
1419 {
1420         StitchState *stitch_state;
1421         Scene *scene = CTX_data_scene(C);
1422
1423         stitch_state = (StitchState *)op->customdata;
1424
1425         switch (event->type) {
1426                 case MIDDLEMOUSE:
1427                         return OPERATOR_PASS_THROUGH;
1428
1429                 /* Cancel */
1430                 case ESCKEY:
1431                         return stitch_cancel(C, op);
1432
1433
1434                 case LEFTMOUSE:
1435                         if (event->shift && (U.flag & USER_LMOUSESELECT)) {
1436                                 if (event->val == KM_RELEASE) {
1437                                         stitch_select(C, scene, event, stitch_state);
1438
1439                                         if (!stitch_process_data(stitch_state, scene, 0)) {
1440                                                 return stitch_cancel(C, op);
1441                                         }
1442                                 }
1443                                 break;
1444                         }
1445                 case PADENTER:
1446                 case RETKEY:
1447                         if (stitch_process_data(stitch_state, scene, 1)) {
1448                                 stitch_exit(C, op, 1);
1449                                 return OPERATOR_FINISHED;
1450                         }
1451                         else {
1452                                 return stitch_cancel(C, op);
1453                         }
1454
1455                 /* Increase limit */
1456                 case PADPLUSKEY:
1457                 case WHEELUPMOUSE:
1458                         if (event->alt) {
1459                                 stitch_state->limit_dist += 0.01f;
1460                                 if (!stitch_process_data(stitch_state, scene, 0)) {
1461                                         return stitch_cancel(C, op);
1462                                 }
1463                                 break;
1464                         }
1465                         else {
1466                                 return OPERATOR_PASS_THROUGH;
1467                         }
1468                 /* Decrease limit */
1469                 case PADMINUS:
1470                 case WHEELDOWNMOUSE:
1471                         if (event->alt) {
1472                                 stitch_state->limit_dist -= 0.01f;
1473                                 stitch_state->limit_dist = MAX2(0.01f, stitch_state->limit_dist);
1474                                 if (!stitch_process_data(stitch_state, scene, 0)) {
1475                                         return stitch_cancel(C, op);
1476                                 }
1477                                 break;
1478                         }
1479                         else {
1480                                 return OPERATOR_PASS_THROUGH;
1481                         }
1482
1483                 /* Use Limit (Default off)*/
1484                 case LKEY:
1485                         if (event->val == KM_PRESS) {
1486                                 stitch_state->use_limit = !stitch_state->use_limit;
1487                                 if (!stitch_process_data(stitch_state, scene, 0)) {
1488                                         return stitch_cancel(C, op);
1489                                 }
1490                                 break;
1491                         }
1492                         return OPERATOR_RUNNING_MODAL;
1493
1494                 case IKEY:
1495                         if (event->val == KM_PRESS) {
1496                                 stitch_state->static_island++;
1497                                 stitch_state->static_island %= stitch_state->element_map->totalIslands;
1498
1499                                 if (!stitch_process_data(stitch_state, scene, 0)) {
1500                                         return stitch_cancel(C, op);
1501                                 }
1502                                 break;
1503                         }
1504                         return OPERATOR_RUNNING_MODAL;
1505
1506                 case MKEY:
1507                         if (event->val == KM_PRESS) {
1508                                 stitch_state->midpoints = !stitch_state->midpoints;
1509                                 if (!stitch_process_data(stitch_state, scene, 0)) {
1510                                         return stitch_cancel(C, op);
1511                                 }
1512                         }
1513                         break;
1514
1515                 /* Select geometry*/
1516                 case RIGHTMOUSE:
1517                         if (!event->shift) {
1518                                 return stitch_cancel(C, op);
1519                         }
1520                         if (event->val == KM_RELEASE && !(U.flag & USER_LMOUSESELECT)) {
1521                                 stitch_select(C, scene, event, stitch_state);
1522
1523                                 if (!stitch_process_data(stitch_state, scene, 0)) {
1524                                         return stitch_cancel(C, op);
1525                                 }
1526                                 break;
1527                         }
1528                         return OPERATOR_RUNNING_MODAL;
1529
1530                 /* snap islands on/off */
1531                 case SKEY:
1532                         if (event->val == KM_PRESS) {
1533                                 stitch_state->snap_islands = !stitch_state->snap_islands;
1534                                 if (!stitch_process_data(stitch_state, scene, 0)) {
1535                                         return stitch_cancel(C, op);
1536                                 }
1537                                 break;
1538                         }
1539                         else {
1540                                 return OPERATOR_RUNNING_MODAL;
1541                         }
1542
1543                 default:
1544                         return OPERATOR_RUNNING_MODAL;
1545         }
1546
1547         /* if updated settings, renew feedback message */
1548         stitch_update_header(stitch_state, C);
1549         ED_region_tag_redraw(CTX_wm_region(C));
1550         return OPERATOR_RUNNING_MODAL;
1551 }
1552
1553 void UV_OT_stitch(wmOperatorType *ot)
1554 {
1555         PropertyRNA *prop;
1556
1557         /* identifiers */
1558         ot->name = "Stitch";
1559         ot->description = "Stitch selected UV vertices by proximity";
1560         ot->idname = "UV_OT_stitch";
1561         ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
1562         
1563         /* api callbacks */
1564         ot->invoke = stitch_invoke;
1565         ot->modal = stitch_modal;
1566         ot->exec = stitch_exec;
1567         ot->cancel = stitch_cancel;
1568         ot->poll = ED_operator_uvedit;
1569
1570         /* properties */
1571         RNA_def_boolean(ot->srna, "use_limit", 0, "Use Limit", "Stitch UVs within a specified limit distance");
1572         RNA_def_boolean(ot->srna, "snap_islands", 1, "Snap Islands",
1573                         "Snap islands together (on edge stitch mode, rotates the islands too)");
1574
1575         RNA_def_float(ot->srna, "limit", 0.01f, 0.0f, FLT_MAX, "Limit",
1576                       "Limit distance in normalized coordinates", 0.0, FLT_MAX);
1577         RNA_def_int(ot->srna, "static_island", 0, 0, INT_MAX, "Static Island",
1578                     "Island that stays in place when stitching islands", 0, INT_MAX);
1579         RNA_def_boolean(ot->srna, "midpoint_snap", 0, "Snap At Midpoint",
1580                         "UVs are stitched at midpoint instead of at static island");
1581         RNA_def_boolean(ot->srna, "clear_seams", 1, "Clear Seams",
1582                         "Clear seams of stitched edges");
1583         prop = RNA_def_collection_runtime(ot->srna, "selection", &RNA_SelectedUvElement, "Selection", "");
1584         /* Selection should not be editable or viewed in toolbar */
1585         RNA_def_property_flag(prop, PROP_HIDDEN);
1586 }