quiet some warnings & (possible/unlikely error)
[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_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                         (!state->midpoints && element->island == element_iter->island))
295                 return 0;
296
297         return stitch_check_uvs_stitchable(element, element_iter, state);
298 }
299
300
301 /* calculate snapping for islands */
302 static void stitch_calculate_island_snapping(StitchState *state, StitchPreviewer *preview, IslandStitchData *island_stitch_data, int final){
303         int i;
304         EditFace *efa;
305         MTFace *mt;
306         UvElement *element;
307
308         for(i = 0; i <  state->element_map->totalIslands; i++){
309                 if(island_stitch_data[i].addedForPreview){
310                         int numOfIslandUVs = 0, j;
311
312                         /* check to avoid divide by 0 */
313                         if(island_stitch_data[i].num_rot_elements>0){
314                                 island_stitch_data[i].rotation /= island_stitch_data[i].num_rot_elements;
315                                 island_stitch_data[i].medianPoint[0] /= island_stitch_data[i].numOfElements;
316                                 island_stitch_data[i].medianPoint[1] /= island_stitch_data[i].numOfElements;
317                         }
318                         island_stitch_data[i].translation[0] /= island_stitch_data[i].numOfElements;
319                         island_stitch_data[i].translation[1] /= island_stitch_data[i].numOfElements;
320                         numOfIslandUVs = getNumOfIslandUvs(state->element_map, i);
321                         element = &state->element_map->buf[state->element_map->islandIndices[i]];
322                         for(j = 0; j < numOfIslandUVs; j++, element++){
323                                 /* stitchable uvs have already been processed, don't process */
324                                 if(!(element->flag & STITCH_PROCESSED)){
325                                         efa = element->face;
326                                         mt = CustomData_em_get(&state->em->fdata, efa->data, CD_MTFACE);
327                                         if(final){
328
329                                                 stitch_uv_rotate(island_stitch_data[i].rotation, island_stitch_data[i].medianPoint, mt->uv[element->tfindex]);
330
331                                                 mt->uv[element->tfindex][0] += island_stitch_data[i].translation[0];
332                                                 mt->uv[element->tfindex][1] += island_stitch_data[i].translation[1];
333                                         }
334                                         else if(efa->tmp.l != STITCH_NO_PREVIEW){
335                                                 if(efa->v4){
336
337                                                         stitch_uv_rotate(island_stitch_data[i].rotation, island_stitch_data[i].medianPoint, &preview->preview_quads[efa->tmp.l + 2*element->tfindex]);
338
339                                                         preview->preview_quads[efa->tmp.l + 2*element->tfindex] += island_stitch_data[i].translation[0];
340                                                         preview->preview_quads[efa->tmp.l + 2*element->tfindex + 1] += island_stitch_data[i].translation[1];
341                                                 }
342                                                 else {
343
344                                                         stitch_uv_rotate(island_stitch_data[i].rotation, island_stitch_data[i].medianPoint, &preview->preview_tris[efa->tmp.l + 2*element->tfindex]);
345
346                                                         preview->preview_tris[efa->tmp.l + 2*element->tfindex]  += island_stitch_data[i].translation[0];
347                                                         preview->preview_tris[efa->tmp.l + 2*element->tfindex + 1] += island_stitch_data[i].translation[1];
348                                                 }
349                                         }
350                                 }
351                                 /* cleanup */
352                                 element->flag &= STITCH_SELECTED;
353                         }
354                 }
355         }
356 }
357
358
359
360 static void stitch_island_calculate_edge_rotation(UvEdge *edge, StitchState *state, UVVertAverage *uv_average, unsigned int *uvfinal_map, IslandStitchData *island_stitch_data)
361 {
362         UvElement *element1, *element2;
363         EditFace *efa1;
364         EditFace *efa2;
365         MTFace *mt1;
366         MTFace *mt2;
367         float uv1[2], uv2[2];
368         float edgecos, edgesin;
369         int index1, index2;
370         float rotation;
371
372         element1 = state->uvs[edge->uv1];
373         element2 = state->uvs[edge->uv2];
374
375         efa1 = element1->face;
376         mt1 = CustomData_em_get(&state->em->fdata, efa1->data, CD_MTFACE);
377         efa2 = element2->face;
378         mt2 = CustomData_em_get(&state->em->fdata, efa2->data, CD_MTFACE);
379
380         index1 = uvfinal_map[element1 - state->element_map->buf];
381         index2 = uvfinal_map[element2 - state->element_map->buf];
382
383         /* the idea here is to take the directions of the edges and find the rotation between final and initial
384         * direction. This, using inner and outer vector products, gives the angle. Directions are differences so... */
385         uv1[0] = mt2->uv[element2->tfindex][0] - mt1->uv[element1->tfindex][0];
386         uv1[1] = mt2->uv[element2->tfindex][1] - mt1->uv[element1->tfindex][1];
387
388         uv2[0] = uv_average[index2].uv[0] - uv_average[index1].uv[0];
389         uv2[1] = uv_average[index2].uv[1] - uv_average[index1].uv[1];
390
391         normalize_v2(uv1);
392         normalize_v2(uv2);
393
394         edgecos = uv1[0]*uv2[0] + uv1[1]*uv2[1];
395         edgesin = uv1[0]*uv2[1] - uv2[0]*uv1[1];
396
397         rotation = (edgesin > 0)? acos(MAX2(-1.0, MIN2(1.0, edgecos))): -acos(MAX2(-1.0, MIN2(1.0, edgecos)));
398
399         island_stitch_data[element1->island].num_rot_elements++;
400         island_stitch_data[element1->island].rotation += rotation;
401 }
402
403
404 static void stitch_island_calculate_vert_rotation(UvElement *element, StitchState *state, IslandStitchData *island_stitch_data)
405 {
406         float edgecos = 1, edgesin = 0;
407         int index;
408         UvElement *element_iter;
409         float rotation = 0;
410
411         if(element->island == state->static_island && !state->midpoints)
412                 return;
413
414         index = (*(&element->face->v1 + element->tfindex))->tmp.l;
415
416         element_iter = state->element_map->vert[index];
417
418         for(; element_iter; element_iter = element_iter->next){
419                 if(element_iter->separate && stitch_check_uvs_state_stitchable(element, element_iter, state)){
420                         int index_tmp1, index_tmp2;
421                         float normal[2];
422                         /* easily possible*/
423
424                         index_tmp1 = element_iter - state->element_map->buf;
425                         index_tmp1 = state->map[index_tmp1];
426                         index_tmp2 = element - state->element_map->buf;
427                         index_tmp2 = state->map[index_tmp2];
428
429                         negate_v2_v2(normal, state->normals + index_tmp2*2);
430                         edgecos = dot_v2v2(normal, state->normals + index_tmp1*2);
431                         edgesin = cross_v2v2(normal, state->normals + index_tmp1*2);
432                         rotation += (edgesin > 0)? acos(edgecos): -acos(edgecos);
433                 }
434         }
435
436         if(state->midpoints)
437                 rotation /= 2.0;
438         island_stitch_data[element->island].num_rot_elements++;
439         island_stitch_data[element->island].rotation += rotation;
440 }
441
442
443 static void stitch_state_delete(StitchState *stitch_state)
444 {
445         if(stitch_state){
446                 if(stitch_state->element_map){
447                         EM_free_uv_element_map(stitch_state->element_map);
448                 }
449                 if(stitch_state->uvs){
450                         MEM_freeN(stitch_state->uvs);
451                 }
452                 if(stitch_state->selection_stack){
453                         MEM_freeN(stitch_state->selection_stack);
454                 }
455                 if(stitch_state->quads_per_island){
456                         MEM_freeN(stitch_state->quads_per_island);
457                 }
458                 if(stitch_state->tris_per_island){
459                         MEM_freeN(stitch_state->tris_per_island);
460                 }
461                 if(stitch_state->map){
462                         MEM_freeN(stitch_state->map);
463                 }
464                 if(stitch_state->normals){
465                         MEM_freeN(stitch_state->normals);
466                 }
467                 if(stitch_state->edges){
468                         MEM_freeN(stitch_state->edges);
469                 }
470                 MEM_freeN(stitch_state);
471         }
472 }
473
474
475
476 /* checks for remote uvs that may be stitched with a certain uv, flags them if stitchable. */
477 static void determine_uv_stitchability(UvElement *element, StitchState *state, IslandStitchData *island_stitch_data){
478         int vert_index;
479         UvElement *element_iter;
480
481         vert_index = (*(&element->face->v1 + element->tfindex))->tmp.l;
482         element_iter = state->element_map->vert[vert_index];
483
484         for(; element_iter; element_iter = element_iter->next){
485                 if(element_iter->separate){
486                         if(element_iter == element){
487                                 continue;
488                         }
489                         if(stitch_check_uvs_stitchable(element, element_iter, state)){
490                                 island_stitch_data[element_iter->island].stitchableCandidate = 1;
491                                 island_stitch_data[element->island].stitchableCandidate = 1;
492                                 element->flag |= STITCH_STITCHABLE_CANDIDATE;
493                         }
494                 }
495         }
496 }
497
498
499 /* set preview buffer position of UV face in editface->tmp.l */
500 static void stitch_set_face_preview_buffer_position(EditFace *efa, StitchPreviewer *preview)
501 {
502         if(efa->tmp.l == STITCH_NO_PREVIEW)
503         {
504                 if(efa->v4)
505                 {
506                         efa->tmp.l = preview->num_quads*8;
507                         preview->num_quads++;
508                 } else {
509                         efa->tmp.l = preview->num_tris*6;
510                         preview->num_tris++;
511                 }
512         }
513 }
514
515
516 /* setup face preview for all coincident uvs and their faces */
517 static void stitch_setup_face_preview_for_uv_group(UvElement *element, StitchState *state, IslandStitchData *island_stitch_data){
518         StitchPreviewer *preview = uv_get_stitch_previewer();
519
520         /* static island does not change so returning immediately */
521         if(state->snap_islands && !state->midpoints && state->static_island == element->island)
522                 return;
523
524         if(state->snap_islands){
525                 island_stitch_data[element->island].addedForPreview = 1;
526         }
527
528         do{
529                 stitch_set_face_preview_buffer_position(element->face, preview);
530                 element = element->next;
531         }while(element && !element->separate);
532 }
533
534
535 /* checks if uvs are indeed stitchable and registers so that they can be shown in preview */
536 static void stitch_validate_stichability(UvElement *element, StitchState *state, IslandStitchData *island_stitch_data){
537         UvElement *element_iter;
538         StitchPreviewer *preview;
539
540         preview = uv_get_stitch_previewer();
541         element_iter = state->element_map->vert[(*(&element->face->v1 + element->tfindex))->tmp.l];
542
543         for(; element_iter; element_iter = element_iter->next){
544                 if(element_iter->separate){
545                         if(element_iter == element)
546                                 continue;
547                         if(stitch_check_uvs_state_stitchable(element, element_iter, state)){
548                                 if((element_iter->island == state->static_island) || (element->island == state->static_island)){
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;
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 {
917         UvElement *element = edge->element;
918         EditFace *efa = element->face;
919         MTFace *mt = CustomData_em_get(&em->fdata, efa->data, CD_MTFACE);
920         int nverts = efa->v4?4 : 3;
921         int index = (element->tfindex + 2)%nverts;
922         float tangent[2], internal[2];
923
924         sub_v2_v2v2(tangent, mt->uv[(element->tfindex + 1)%nverts],  mt->uv[element->tfindex]);
925         sub_v2_v2v2(internal, mt->uv[index],  mt->uv[element->tfindex]);
926
927         /* choose one of the normals */
928         normal[0] = tangent[1];
929         normal[1] = -tangent[0];
930
931         /* if normal points inside the face, invert */
932         if(dot_v2v2(normal, internal) > 0){
933                 normal[0] = -tangent[1];
934                 normal[1] = tangent[0];
935         }
936
937         normalize_v2(normal);
938 }
939
940 static int stitch_init(bContext *C, wmOperator *op)
941 {
942         /* for fast edge lookup... */
943         GHash *edgeHash;
944         /* ...and actual edge storage */
945         UvEdge *edges;
946         int total_edges;
947         /* maps uvelements to their first coincident uv */
948         int *map;
949         int counter = 0, i;
950         EditFace *efa;
951         EditMesh *em;
952         GHashIterator* ghi;
953         UvEdge *all_edges;
954         StitchState *state = MEM_mallocN(sizeof(StitchState), "stitch state");
955         Scene *scene = CTX_data_scene(C);
956         ToolSettings *ts = scene->toolsettings;
957
958         Object *obedit = CTX_data_edit_object(C);
959
960         op->customdata = state;
961
962         if(!state)
963                 return 0;
964
965         /* initialize state */
966         state->use_limit = RNA_boolean_get(op->ptr, "use_limit");
967         state->limit_dist = RNA_float_get(op->ptr, "limit");
968         state->em = em = BKE_mesh_get_editmesh((Mesh*)obedit->data);
969         state->snap_islands = RNA_boolean_get(op->ptr, "snap_islands");
970         state->static_island = RNA_int_get(op->ptr, "static_island");
971         state->midpoints = RNA_boolean_get(op->ptr, "midpoint_snap");
972         /* in uv synch selection, all uv's are visible */
973         if(ts->uv_flag & UV_SYNC_SELECTION){
974                 state->element_map = EM_make_uv_element_map(state->em, 0, 1);
975         }else{
976                 state->element_map = EM_make_uv_element_map(state->em, 1, 1);
977         }
978         if(!state->element_map){
979                 stitch_state_delete(state);
980                 return 0;
981         }
982
983         /* Entirely possible if redoing last operator that static island is bigger than total number of islands.
984          * This ensures we get no hang in the island checking code in stitch_process_data. */
985         state->static_island %= state->element_map->totalIslands;
986
987         /* Count 'unique' uvs */
988         for(i = 0; i < state->element_map->totalUVs; i++){
989                 if(state->element_map->buf[i].separate){
990                         counter++;
991                 }
992         }
993
994         /* Allocate the unique uv buffers */
995         state->uvs = MEM_mallocN(sizeof(*state->uvs)*counter, "uv_stitch_unique_uvs");
996         /* internal uvs need no normals but it is hard and slow to keep a map of
997          * normals only for boundary uvs, so allocating for all uvs */
998         state->normals = MEM_callocN(sizeof(*state->normals)*counter*2, "uv_stitch_normals");
999         state->total_separate_uvs = counter;
1000         /* we can at most have totalUVs edges or uvs selected. Actually they are less, considering we store only
1001          * unique uvs for processing but I am accounting for all bizarre cases, especially for edges, this way */
1002         state->selection_stack = MEM_mallocN(sizeof(*state->selection_stack)*counter, "uv_stitch_selection_stack");
1003         state->map = map = MEM_mallocN(sizeof(*map)*state->element_map->totalUVs, "uv_stitch_unique_map");
1004         /* Allocate the edge stack */
1005         edgeHash = BLI_ghash_new(uv_edge_hash, uv_edge_compare, "stitch_edge_hash");
1006         all_edges = MEM_mallocN(sizeof(*all_edges)*state->element_map->totalUVs, "stitch_all_edges");
1007
1008         if(!state->selection_stack || !state->uvs || !map || !edgeHash || !all_edges){
1009                 stitch_state_delete(state);
1010                 return 0;
1011         }
1012
1013         /* So that we can use this as index for the UvElements */
1014         counter = -1;
1015         /* initialize the unique UVs and map */
1016         for(i = 0; i < state->em->totvert; i++){
1017                 UvElement *element = state->element_map->vert[i];
1018                 for(; element; element = element->next){
1019                         if(element->separate){
1020                                 counter++;
1021                                 state->uvs[counter] = element;
1022                         }
1023                         /* pointer arithmetic to the rescue, as always :)*/
1024                         map[element - state->element_map->buf] = counter;
1025                 }
1026         }
1027
1028         /* Now, on to generate our uv connectivity data */
1029         for(efa = state->em->faces.first, counter = 0; efa; efa = efa->next){
1030                 if((ts->uv_flag & UV_SYNC_SELECTION) || (!efa->h && efa->f & SELECT)){
1031                         int nverts = efa->v4 ? 4 : 3;
1032
1033                         for(i = 0; i < nverts; i++){
1034                                 UvElement *element = ED_get_uv_element(state->element_map, efa, i);
1035                                 int offset1, itmp1 = element - state->element_map->buf;
1036                                 int offset2, itmp2 = ED_get_uv_element(state->element_map, efa, (i+1)%nverts) - state->element_map->buf;
1037
1038                                 offset1 = map[itmp1];
1039                                 offset2 = map[itmp2];
1040
1041                                 all_edges[counter].flag = 0;
1042                                 all_edges[counter].element = element;
1043                                 /* using an order policy, sort uvs according to address space. This avoids
1044                                  * Having two different UvEdges with the same uvs on different positions  */
1045                                 if(offset1 < offset2){
1046                                         all_edges[counter].uv1 = offset1;
1047                                         all_edges[counter].uv2 = offset2;
1048                                 }
1049                                 else{
1050                                         all_edges[counter].uv1 = offset2;
1051                                         all_edges[counter].uv2 = offset1;
1052                                 }
1053
1054                                 if(BLI_ghash_haskey(edgeHash, &all_edges[counter])){
1055                                         char *flag = BLI_ghash_lookup(edgeHash, &all_edges[counter]);
1056                                         *flag = 0;
1057                                 }
1058                                 else{
1059                                         BLI_ghash_insert(edgeHash, &all_edges[counter], &(all_edges[counter].flag));
1060                                         all_edges[counter].flag = STITCH_BOUNDARY;
1061                                 }
1062                                 counter++;
1063                         }
1064                 }
1065         }
1066
1067
1068         ghi = BLI_ghashIterator_new(edgeHash);
1069         total_edges = 0;
1070         /* fill the edges with data */
1071         for(; !BLI_ghashIterator_isDone(ghi); BLI_ghashIterator_step(ghi)){
1072                 UvEdge *edge = ((UvEdge *)BLI_ghashIterator_getKey(ghi));
1073                 if(edge->flag & STITCH_BOUNDARY){
1074                         total_edges++;
1075                 }
1076         }
1077         state->edges = edges = MEM_mallocN(sizeof(*edges)*total_edges, "stitch_edges");
1078         if(!ghi || !edges){
1079                 MEM_freeN(all_edges);
1080                 stitch_state_delete(state);
1081                 return 0;
1082         }
1083
1084         state->total_boundary_edges = total_edges;
1085
1086         /* fill the edges with data */
1087         for(i = 0, BLI_ghashIterator_init(ghi, edgeHash); !BLI_ghashIterator_isDone(ghi); BLI_ghashIterator_step(ghi)){
1088                 UvEdge *edge = ((UvEdge *)BLI_ghashIterator_getKey(ghi));
1089                 if(edge->flag & STITCH_BOUNDARY){
1090                         edges[i++] = *((UvEdge *)BLI_ghashIterator_getKey(ghi));
1091                 }
1092         }
1093
1094         /* cleanup temporary stuff */
1095         BLI_ghashIterator_free(ghi);
1096         MEM_freeN(all_edges);
1097
1098         /* refill hash with new pointers to cleanup duplicates */
1099         BLI_ghash_free(edgeHash, NULL, NULL);
1100
1101         /***** calculate 2D normals for boundary uvs *****/
1102
1103         /* we use boundary edges to calculate 2D normals.
1104          * to disambiguate the direction of the normal, we also need
1105          * a point "inside" the island, that can be provided by
1106          * the opposite uv for a quad, or the next uv for a triangle. */
1107
1108         for(i = 0; i < total_edges; i++){
1109                 float normal[2];
1110                 stitch_calculate_edge_normal(em, edges + i, normal);
1111
1112                 add_v2_v2(state->normals + edges[i].uv1*2, normal);
1113                 add_v2_v2(state->normals + edges[i].uv2*2, normal);
1114
1115                 normalize_v2(state->normals + edges[i].uv1*2);
1116                 normalize_v2(state->normals + edges[i].uv2*2);
1117         }
1118
1119
1120         /***** fill selection stack *******/
1121
1122         state->selection_size = 0;
1123
1124         /* Load old selection if redoing operator with different settings */
1125         if(RNA_struct_property_is_set(op->ptr, "selection")){
1126                 int faceIndex, elementIndex;
1127                 UvElement *element;
1128
1129                 EM_init_index_arrays(em, 0, 0, 1);
1130
1131
1132                         RNA_BEGIN(op->ptr, itemptr, "selection") {
1133                                 faceIndex = RNA_int_get(&itemptr, "face_index");
1134                                 elementIndex = RNA_int_get(&itemptr, "element_index");
1135                                 efa = EM_get_face_for_index(faceIndex);
1136                                 element = ED_get_uv_element(state->element_map, efa, elementIndex);
1137                                 stitch_select_uv(element, state, 1);
1138                         }
1139                         RNA_END;
1140
1141                 EM_free_index_arrays();
1142                 /* Clear the selection */
1143                 RNA_collection_clear(op->ptr, "selection");
1144
1145         } else {
1146                 for(efa = state->em->faces.first ; efa; efa = efa->next){
1147                         int numOfVerts;
1148                         MTFace *mt;
1149                         mt = CustomData_em_get(&state->em->fdata, efa->data, CD_MTFACE);
1150                         numOfVerts = efa->v4 ? 4 : 3;
1151
1152                         for(i = 0; i < numOfVerts; i++){
1153                                 if(uvedit_uv_selected(scene, efa, mt, i)){
1154                                         UvElement *element = ED_get_uv_element(state->element_map, efa, i);
1155                                         stitch_select_uv(element, state, 1);
1156                                 }
1157                         }
1158                 }
1159         }
1160
1161         /***** initialise static island preview data *****/
1162
1163         state->quads_per_island = MEM_mallocN(sizeof(*state->quads_per_island)*state->element_map->totalIslands,
1164                         "stitch island quads");
1165         state->tris_per_island = MEM_mallocN(sizeof(*state->tris_per_island)*state->element_map->totalIslands,
1166                         "stitch island tris");
1167         for(i = 0; i < state->element_map->totalIslands; i++){
1168                 state->quads_per_island[i] = 0;
1169                 state->tris_per_island[i] = 0;
1170         }
1171
1172         for(efa = state->em->faces.first; efa; efa = efa->next){
1173                 UvElement *element = ED_get_uv_element(state->element_map, efa, 0);
1174
1175                 if(element){
1176                         if(efa->v4){
1177                                 state->quads_per_island[element->island]++;
1178                         }
1179                         else {
1180                                 state->tris_per_island[element->island]++;
1181                         }
1182                 }
1183         }
1184
1185         if(!stitch_process_data(state, scene, 0)){
1186                 stitch_state_delete(state);
1187                 return 0;
1188         }
1189
1190         stitch_update_header(state, C);
1191         return 1;
1192 }
1193
1194 static int stitch_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
1195 {
1196         Object *obedit = CTX_data_edit_object(C);
1197         if(!stitch_init(C, op))
1198                 return OPERATOR_CANCELLED;
1199
1200         WM_event_add_modal_handler(C, op);
1201         WM_event_add_notifier(C, NC_GEOM|ND_DATA, obedit->data);
1202         return OPERATOR_RUNNING_MODAL;
1203 }
1204
1205 static void stitch_exit(bContext *C, wmOperator *op, int finished)
1206 {
1207         StitchState *stitch_state;
1208         Scene *scene;
1209         SpaceImage *sima;
1210         ScrArea *sa= CTX_wm_area(C);
1211         Object *obedit;
1212
1213         scene= CTX_data_scene(C);
1214         obedit= CTX_data_edit_object(C);
1215         sima= CTX_wm_space_image(C);
1216
1217         stitch_state = (StitchState *)op->customdata;
1218
1219         if(finished){
1220                 EditFace *efa;
1221                 int i;
1222
1223                 RNA_float_set(op->ptr, "limit", stitch_state->limit_dist);
1224                 RNA_boolean_set(op->ptr, "use_limit", stitch_state->use_limit);
1225                 RNA_boolean_set(op->ptr, "snap_islands", stitch_state->snap_islands);
1226                 RNA_int_set(op->ptr, "static_island", stitch_state->static_island);
1227                 RNA_boolean_set(op->ptr, "midpoint_snap", stitch_state->midpoints);
1228
1229                 for(i = 0, efa = stitch_state->em->faces.first; efa; efa = efa->next, i++){
1230                         efa->tmp.l = i;
1231                 }
1232
1233                 /* Store selection for re-execution of stitch */
1234                 for(i = 0; i < stitch_state->selection_size; i++){
1235                         PointerRNA itemptr;
1236                         UvElement *element = stitch_state->selection_stack[i];
1237
1238                         RNA_collection_add(op->ptr, "selection", &itemptr);
1239
1240                         RNA_int_set(&itemptr, "face_index", element->face->tmp.l);
1241                         RNA_int_set(&itemptr, "element_index", element->tfindex);
1242                 }
1243
1244
1245                 uvedit_live_unwrap_update(sima, scene, obedit);
1246         }
1247
1248         if(sa)
1249                 ED_area_headerprint(sa, NULL);
1250
1251         DAG_id_tag_update(obedit->data, 0);
1252         WM_event_add_notifier(C, NC_GEOM|ND_DATA, obedit->data);
1253         BKE_mesh_end_editmesh(obedit->data, stitch_state->em);
1254
1255         stitch_state_delete(stitch_state);
1256         op->customdata = NULL;
1257
1258         stitch_preview_delete();
1259 }
1260
1261
1262 static int stitch_cancel(bContext *C, wmOperator *op)
1263 {
1264         stitch_exit(C, op, 0);
1265         return OPERATOR_CANCELLED;
1266 }
1267
1268
1269 static int stitch_exec(bContext *C, wmOperator *op)
1270 {
1271         Scene *scene = CTX_data_scene(C);
1272
1273         if(!stitch_init(C, op))
1274                 return OPERATOR_CANCELLED;
1275         if(stitch_process_data((StitchState *)op->customdata, scene, 1)){
1276                 stitch_exit(C, op, 1);
1277                 return OPERATOR_FINISHED;
1278         }else {
1279                 return stitch_cancel(C, op);
1280         }
1281 }
1282
1283 static void stitch_select(bContext *C, Scene *scene, wmEvent *event, StitchState *stitch_state){
1284         /* add uv under mouse to processed uv's */
1285         float co[2];
1286         NearestHit hit;
1287         ARegion *ar= CTX_wm_region(C);
1288         Image *ima= CTX_data_edit_image(C);
1289
1290         UI_view2d_region_to_view(&ar->v2d, event->mval[0], event->mval[1], &co[0], &co[1]);
1291         uv_find_nearest_vert(scene, ima, stitch_state->em, co, NULL, &hit);
1292
1293         if(hit.efa)
1294         {
1295                 /* Add vertex to selection, deselect all common uv's of vert other
1296                  * than selected and update the preview. This behavior was decided so that
1297                  * you can do stuff like deselect the opposite stitchable vertex and the initial still gets deselected */
1298
1299                 /* This works due to setting of tmp in find nearest uv vert */
1300                 UvElement *element = ED_get_uv_element(stitch_state->element_map, hit.efa, hit.uv);
1301                 stitch_select_uv(element, stitch_state, 0);
1302
1303         }
1304 }
1305
1306 static int stitch_modal(bContext *C, wmOperator *op, wmEvent *event)
1307 {
1308         StitchState *stitch_state;
1309         Scene *scene = CTX_data_scene(C);
1310
1311         stitch_state = (StitchState *)op->customdata;
1312
1313         switch(event->type){
1314                 case MIDDLEMOUSE:
1315                         return OPERATOR_PASS_THROUGH;
1316
1317                 /* Cancel */
1318                 case ESCKEY:
1319                         return stitch_cancel(C, op);
1320
1321
1322                 case LEFTMOUSE:
1323                         if(event->shift && (U.flag & USER_LMOUSESELECT)){
1324                                 if(event->val == KM_RELEASE){
1325                                         stitch_select(C, scene, event, stitch_state);
1326
1327                                         if(!stitch_process_data(stitch_state, scene, 0)){
1328                                                 return stitch_cancel(C, op);
1329                                         }
1330                                 }
1331                                 break;
1332                         }
1333                 case PADENTER:
1334                 case RETKEY:
1335                         if(stitch_process_data(stitch_state, scene, 1)){
1336                                 stitch_exit(C, op, 1);
1337                                 return OPERATOR_FINISHED;
1338                         }
1339                         else {
1340                                 return stitch_cancel(C, op);
1341                         }
1342
1343                 /* Increase limit */
1344                 case PADPLUSKEY:
1345                 case WHEELUPMOUSE:
1346                         if(event->alt){
1347                                 stitch_state->limit_dist += 0.01;
1348                                 if(!stitch_process_data(stitch_state, scene, 0)){
1349                                         return stitch_cancel(C, op);
1350                                 }
1351                                 break;
1352                         }
1353                         else{
1354                                 return OPERATOR_PASS_THROUGH;
1355                         }
1356                 /* Decrease limit */
1357                 case PADMINUS:
1358                 case WHEELDOWNMOUSE:
1359                         if(event->alt){
1360                                 stitch_state->limit_dist -= 0.01;
1361                                 stitch_state->limit_dist = MAX2(0.01, stitch_state->limit_dist);
1362                                 if(!stitch_process_data(stitch_state, scene, 0)){
1363                                         return stitch_cancel(C, op);
1364                                 }
1365                                 break;
1366                         }else{
1367                                 return OPERATOR_PASS_THROUGH;
1368                         }
1369
1370                 /* Use Limit (Default off)*/
1371                 case LKEY:
1372                         if(event->val == KM_PRESS){
1373                                 stitch_state->use_limit = !stitch_state->use_limit;
1374                                 if(!stitch_process_data(stitch_state, scene, 0)){
1375                                         return stitch_cancel(C, op);
1376                                 }
1377                                 break;
1378                         }
1379                         return OPERATOR_RUNNING_MODAL;
1380
1381                 case IKEY:
1382                         if(event->val == KM_PRESS){
1383                                 stitch_state->static_island++;
1384                                 stitch_state->static_island %= stitch_state->element_map->totalIslands;
1385
1386                                 if(!stitch_process_data(stitch_state, scene, 0)){
1387                                         return stitch_cancel(C, op);
1388                                 }
1389                                 break;
1390                         }
1391                         return OPERATOR_RUNNING_MODAL;
1392
1393                 case MKEY:
1394                         if(event->val == KM_PRESS){
1395                                 stitch_state->midpoints = !stitch_state->midpoints;
1396                                 if(!stitch_process_data(stitch_state, scene, 0)){
1397                                         return stitch_cancel(C, op);
1398                                 }
1399                         }
1400                         break;
1401
1402                 /* Select geometry*/
1403                 case RIGHTMOUSE:
1404                         if(!event->shift){
1405                                         return stitch_cancel(C, op);
1406                         }
1407                         if(event->val == KM_RELEASE && !(U.flag & USER_LMOUSESELECT)){
1408                                 stitch_select(C, scene, event, stitch_state);
1409
1410                                 if(!stitch_process_data(stitch_state, scene, 0)){
1411                                         return stitch_cancel(C, op);
1412                                 }
1413                                 break;
1414                         }
1415                         return OPERATOR_RUNNING_MODAL;
1416
1417                 /* snap islands on/off */
1418                 case SKEY:
1419                         if(event->val == KM_PRESS){
1420                                 stitch_state->snap_islands = !stitch_state->snap_islands;
1421                                 if(!stitch_process_data(stitch_state, scene, 0)){
1422                                         return stitch_cancel(C, op);
1423                                 }
1424                                 break;
1425                         } else
1426                         return OPERATOR_RUNNING_MODAL;
1427
1428                 default:
1429                         return OPERATOR_RUNNING_MODAL;
1430         }
1431
1432         /* if updated settings, renew feedback message */
1433         stitch_update_header(stitch_state, C);
1434         ED_region_tag_redraw(CTX_wm_region(C));
1435         return OPERATOR_RUNNING_MODAL;
1436 }
1437
1438 void UV_OT_stitch(wmOperatorType *ot)
1439 {
1440         PropertyRNA *prop;
1441
1442         /* identifiers */
1443         ot->name = "Stitch";
1444         ot->description = "Stitch selected UV vertices by proximity";
1445         ot->idname = "UV_OT_stitch";
1446         ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO;
1447         
1448         /* api callbacks */
1449         ot->invoke = stitch_invoke;
1450         ot->modal = stitch_modal;
1451         ot->exec = stitch_exec;
1452         ot->cancel = stitch_cancel;
1453         ot->poll= ED_operator_uvedit;
1454
1455         /* properties */
1456         RNA_def_boolean(ot->srna, "use_limit", 0, "Use Limit", "Stitch UVs within a specified limit distance");
1457         RNA_def_boolean(ot->srna, "snap_islands", 1, "Snap Islands",
1458                                   "Snap islands together (on edge stitch mode, rotates the islands too)");
1459
1460         RNA_def_float(ot->srna, "limit", 0.01f, 0.0f, FLT_MAX, "Limit",
1461                                 "Limit distance in normalized coordinates", 0.0, FLT_MAX);
1462         RNA_def_int(ot->srna, "static_island", 0, 0, INT_MAX, "Static Island",
1463                               "Island that stays in place when stitching islands", 0, INT_MAX);
1464         RNA_def_boolean(ot->srna, "midpoint_snap", 0, "Snap At Midpoint",
1465                                   "UVs are stitched at midpoint instead of at static island");
1466         prop = RNA_def_collection_runtime(ot->srna, "selection", &RNA_SelectedUvElement, "Selection", "");
1467         /* Selection should not be editable or viewed in toolbar */
1468         RNA_def_property_flag(prop, PROP_HIDDEN);
1469 }
1470
1471