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