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