Merge branch 'master' into blender2.8
[blender.git] / source / blender / editors / sculpt_paint / sculpt_uv.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) Blender Foundation, 2002-2009
19  * All rights reserved.
20  *
21  * Contributor(s): Antony Riakiotakis
22  *
23  * ***** END GPL LICENSE BLOCK *****
24  *
25  * UV Sculpt tools
26  *
27  */
28
29 /** \file blender/editors/sculpt_paint/sculpt_uv.c
30  *  \ingroup edsculpt
31  */
32
33
34 #include "MEM_guardedalloc.h"
35
36 #include "BLI_utildefines.h"
37 #include "BLI_math.h"
38 #include "BLI_ghash.h"
39
40 #include "DNA_object_types.h"
41 #include "DNA_scene_types.h"
42 #include "DNA_brush_types.h"
43 #include "DNA_meshdata_types.h"
44
45 #include "BKE_brush.h"
46 #include "BKE_colortools.h"
47 #include "BKE_context.h"
48 #include "BKE_customdata.h"
49 #include "BKE_editmesh.h"
50 #include "BKE_main.h"
51 #include "BKE_mesh_mapping.h"
52 #include "BKE_paint.h"
53
54 #include "DEG_depsgraph.h"
55
56 #include "ED_screen.h"
57 #include "ED_image.h"
58 #include "ED_mesh.h"
59
60 #include "GPU_immediate.h"
61 #include "GPU_immediate_util.h"
62
63 #include "WM_api.h"
64 #include "WM_types.h"
65
66 #include "RNA_access.h"
67 #include "RNA_define.h"
68
69 #include "paint_intern.h"
70 #include "uvedit_intern.h"
71
72 #include "UI_view2d.h"
73
74 #define MARK_BOUNDARY   1
75
76 typedef struct UvAdjacencyElement {
77         /* pointer to original uvelement */
78         UvElement *element;
79         /* uv pointer for convenience. Caution, this points to the original UVs! */
80         float *uv;
81         /* general use flag (Used to check if Element is boundary here) */
82         char flag;
83 } UvAdjacencyElement;
84
85 typedef struct UvEdge {
86         unsigned int uv1;
87         unsigned int uv2;
88         /* general use flag (Used to check if edge is boundary here, and propagates to adjacency elements) */
89         char flag;
90 } UvEdge;
91
92 typedef struct UVInitialStrokeElement {
93         /* index to unique uv */
94         int uv;
95
96         /* strength of brush on initial position */
97         float strength;
98
99         /* initial uv position */
100         float initial_uv[2];
101 } UVInitialStrokeElement;
102
103 typedef struct UVInitialStroke {
104         /* Initial Selection,for grab brushes for instance */
105         UVInitialStrokeElement *initialSelection;
106
107         /* total initially selected UVs*/
108         int totalInitialSelected;
109
110         /* initial mouse coordinates */
111         float init_coord[2];
112 } UVInitialStroke;
113
114
115 /* custom data for uv smoothing brush */
116 typedef struct UvSculptData {
117         /* Contains the first of each set of coincident uvs.
118          * These will be used to perform smoothing on and propagate the changes
119          * to their coincident uvs */
120         UvAdjacencyElement *uv;
121
122         /* ...Is what it says */
123         int totalUniqueUvs;
124
125         /* Edges used for adjacency info, used with laplacian smoothing */
126         UvEdge *uvedges;
127
128         /* need I say more? */
129         int totalUvEdges;
130
131         /* data for initial stroke, used by tools like grab */
132         UVInitialStroke *initial_stroke;
133
134         /* timer to be used for airbrush-type brush */
135         wmTimer *timer;
136
137         /* to determine quickly adjacent uvs */
138         UvElementMap *elementMap;
139
140         /* uvsmooth Paint for fast reference */
141         Paint *uvsculpt;
142
143         /* tool to use. duplicating here to change if modifier keys are pressed */
144         char tool;
145
146         /* store invert flag here */
147         char invert;
148 } UvSculptData;
149
150
151 static Brush *uv_sculpt_brush(bContext *C)
152 {
153         Scene *scene = CTX_data_scene(C);
154         ToolSettings *settings = scene->toolsettings;
155
156         if (!settings->uvsculpt)
157                 return NULL;
158         return BKE_paint_brush(&settings->uvsculpt->paint);
159 }
160
161
162 static int uv_sculpt_brush_poll_do(bContext *C, const bool check_region)
163 {
164         BMEditMesh *em;
165         int ret;
166         Object *obedit = CTX_data_edit_object(C);
167         SpaceImage *sima = CTX_wm_space_image(C);
168         Scene *scene = CTX_data_scene(C);
169         ToolSettings *toolsettings = scene->toolsettings;
170
171         if (!uv_sculpt_brush(C) || !obedit || obedit->type != OB_MESH ||
172             !sima || ED_space_image_show_render(sima) || (sima->mode == SI_MODE_PAINT))
173         {
174                 return 0;
175         }
176
177         em = BKE_editmesh_from_object(obedit);
178         ret = EDBM_uv_check(em);
179
180         if (ret) {
181                 ARegion *ar = CTX_wm_region(C);
182                 if ((!toolsettings->use_uv_sculpt) || (check_region && ar && (ar->regiontype != RGN_TYPE_WINDOW))) {
183                         ret = 0;
184                 }
185         }
186
187         return ret;
188 }
189
190 static int uv_sculpt_brush_poll(bContext *C)
191 {
192         return uv_sculpt_brush_poll_do(C, true);
193 }
194
195 static void brush_drawcursor_uvsculpt(bContext *C, int x, int y, void *UNUSED(customdata))
196 {
197 #define PX_SIZE_FADE_MAX 12.0f
198 #define PX_SIZE_FADE_MIN 4.0f
199
200         Scene *scene = CTX_data_scene(C);
201         //Brush *brush = image_paint_brush(C);
202         Paint *paint = BKE_paint_get_active_from_context(C);
203         Brush *brush = BKE_paint_brush(paint);
204
205         if (paint && brush && paint->flags & PAINT_SHOW_BRUSH) {
206                 const float size = (float)BKE_brush_size_get(scene, brush);
207                 float alpha = 0.5f;
208
209                 /* fade out the brush (cheap trick to work around brush interfering with sampling [#])*/
210                 if (size < PX_SIZE_FADE_MIN) {
211                         return;
212                 }
213                 else if (size < PX_SIZE_FADE_MAX) {
214                         alpha *= (size - PX_SIZE_FADE_MIN) / (PX_SIZE_FADE_MAX - PX_SIZE_FADE_MIN);
215                 }
216
217                 unsigned int pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
218                 immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
219                 immUniformColor3fvAlpha(brush->add_col, alpha);
220
221                 glEnable(GL_LINE_SMOOTH);
222                 glEnable(GL_BLEND);
223                 imm_draw_circle_wire_2d(pos, (float)x, (float)y, size, 40);
224                 glDisable(GL_BLEND);
225                 glDisable(GL_LINE_SMOOTH);
226
227                 immUnbindProgram();
228         }
229 #undef PX_SIZE_FADE_MAX
230 #undef PX_SIZE_FADE_MIN
231 }
232
233
234 void ED_space_image_uv_sculpt_update(Main *bmain, wmWindowManager *wm, Scene *scene)
235 {
236         ToolSettings *settings = scene->toolsettings;
237         if (settings->use_uv_sculpt) {
238                 if (!settings->uvsculpt) {
239                         settings->uvsculpt = MEM_callocN(sizeof(*settings->uvsculpt), "UV Smooth paint");
240                         settings->uv_sculpt_tool = UV_SCULPT_TOOL_GRAB;
241                         settings->uv_sculpt_settings = UV_SCULPT_LOCK_BORDERS | UV_SCULPT_ALL_ISLANDS;
242                         settings->uv_relax_method = UV_SCULPT_TOOL_RELAX_LAPLACIAN;
243                         /* Uv sculpting does not include explicit brush view control yet, always enable */
244                         settings->uvsculpt->paint.flags |= PAINT_SHOW_BRUSH;
245                 }
246
247                 BKE_paint_init(bmain, scene, ePaintSculptUV, PAINT_CURSOR_SCULPT);
248
249                 settings->uvsculpt->paint.paint_cursor = WM_paint_cursor_activate(wm, uv_sculpt_brush_poll,
250                                                                                   brush_drawcursor_uvsculpt, NULL);
251         }
252         else {
253                 if (settings->uvsculpt) {
254                         WM_paint_cursor_end(wm, settings->uvsculpt->paint.paint_cursor);
255                         settings->uvsculpt->paint.paint_cursor = NULL;
256                 }
257         }
258 }
259
260 int uv_sculpt_poll(bContext *C)
261 {
262         return uv_sculpt_brush_poll_do(C, true);
263 }
264
265 int uv_sculpt_keymap_poll(bContext *C)
266 {
267         return uv_sculpt_brush_poll_do(C, false);
268 }
269
270 /*********** Improved Laplacian Relaxation Operator ************************/
271 /* original code by Raul Fernandez Hernandez "farsthary"                   *
272  * adapted to uv smoothing by Antony Riakiatakis                           *
273  ***************************************************************************/
274
275 typedef struct Temp_UvData {
276         float sum_co[2], p[2], b[2], sum_b[2];
277         int ncounter;
278 } Temp_UVData;
279
280
281
282 static void HC_relaxation_iteration_uv(BMEditMesh *em, UvSculptData *sculptdata, float mouse_coord[2],
283                                        float alpha, float radius, float aspectRatio)
284 {
285         Temp_UVData *tmp_uvdata;
286         float diff[2];
287         int i;
288         float radius_root = sqrtf(radius);
289         Brush *brush = BKE_paint_brush(sculptdata->uvsculpt);
290
291         tmp_uvdata = (Temp_UVData *)MEM_callocN(sculptdata->totalUniqueUvs * sizeof(Temp_UVData), "Temporal data");
292
293         /* counting neighbors */
294         for (i = 0; i < sculptdata->totalUvEdges; i++) {
295                 UvEdge *tmpedge = sculptdata->uvedges + i;
296                 tmp_uvdata[tmpedge->uv1].ncounter++;
297                 tmp_uvdata[tmpedge->uv2].ncounter++;
298
299                 add_v2_v2(tmp_uvdata[tmpedge->uv2].sum_co, sculptdata->uv[tmpedge->uv1].uv);
300                 add_v2_v2(tmp_uvdata[tmpedge->uv1].sum_co, sculptdata->uv[tmpedge->uv2].uv);
301         }
302
303         for (i = 0; i < sculptdata->totalUniqueUvs; i++) {
304                 copy_v2_v2(diff, tmp_uvdata[i].sum_co);
305                 mul_v2_fl(diff, 1.f / tmp_uvdata[i].ncounter);
306                 copy_v2_v2(tmp_uvdata[i].p, diff);
307
308                 tmp_uvdata[i].b[0] = diff[0] - sculptdata->uv[i].uv[0];
309                 tmp_uvdata[i].b[1] = diff[1] - sculptdata->uv[i].uv[1];
310         }
311
312         for (i = 0; i < sculptdata->totalUvEdges; i++) {
313                 UvEdge *tmpedge = sculptdata->uvedges + i;
314                 add_v2_v2(tmp_uvdata[tmpedge->uv1].sum_b, tmp_uvdata[tmpedge->uv2].b);
315                 add_v2_v2(tmp_uvdata[tmpedge->uv2].sum_b, tmp_uvdata[tmpedge->uv1].b);
316         }
317
318         for (i = 0; i < sculptdata->totalUniqueUvs; i++) {
319                 float dist;
320                 /* This is supposed to happen only if "Pin Edges" is on, since we have initialization on stroke start
321                  * If ever uv brushes get their own mode we should check for toolsettings option too */
322                 if ((sculptdata->uv[i].flag & MARK_BOUNDARY)) {
323                         continue;
324                 }
325
326                 sub_v2_v2v2(diff, sculptdata->uv[i].uv, mouse_coord);
327                 diff[1] /= aspectRatio;
328                 if ((dist = dot_v2v2(diff, diff)) <= radius) {
329                         UvElement *element;
330                         float strength;
331                         strength = alpha * BKE_brush_curve_strength_clamped(brush, sqrtf(dist), radius_root);
332
333                         sculptdata->uv[i].uv[0] = (1.0f - strength) * sculptdata->uv[i].uv[0] + strength * (tmp_uvdata[i].p[0] - 0.5f * (tmp_uvdata[i].b[0] + tmp_uvdata[i].sum_b[0] / tmp_uvdata[i].ncounter));
334                         sculptdata->uv[i].uv[1] = (1.0f - strength) * sculptdata->uv[i].uv[1] + strength * (tmp_uvdata[i].p[1] - 0.5f * (tmp_uvdata[i].b[1] + tmp_uvdata[i].sum_b[1] / tmp_uvdata[i].ncounter));
335
336                         for (element = sculptdata->uv[i].element; element; element = element->next) {
337                                 MLoopUV *luv;
338                                 BMLoop *l;
339
340                                 if (element->separate && element != sculptdata->uv[i].element)
341                                         break;
342
343                                 l = element->l;
344                                 luv = CustomData_bmesh_get(&em->bm->ldata, l->head.data, CD_MLOOPUV);
345                                 copy_v2_v2(luv->uv, sculptdata->uv[i].uv);
346                         }
347                 }
348         }
349
350         MEM_freeN(tmp_uvdata);
351
352         return;
353 }
354
355 static void laplacian_relaxation_iteration_uv(BMEditMesh *em, UvSculptData *sculptdata, float mouse_coord[2], float alpha, float radius, float aspectRatio)
356 {
357         Temp_UVData *tmp_uvdata;
358         float diff[2];
359         int i;
360         float radius_root = sqrtf(radius);
361         Brush *brush = BKE_paint_brush(sculptdata->uvsculpt);
362
363         tmp_uvdata = (Temp_UVData *)MEM_callocN(sculptdata->totalUniqueUvs * sizeof(Temp_UVData), "Temporal data");
364
365         /* counting neighbors */
366         for (i = 0; i < sculptdata->totalUvEdges; i++) {
367                 UvEdge *tmpedge = sculptdata->uvedges + i;
368                 tmp_uvdata[tmpedge->uv1].ncounter++;
369                 tmp_uvdata[tmpedge->uv2].ncounter++;
370
371                 add_v2_v2(tmp_uvdata[tmpedge->uv2].sum_co, sculptdata->uv[tmpedge->uv1].uv);
372                 add_v2_v2(tmp_uvdata[tmpedge->uv1].sum_co, sculptdata->uv[tmpedge->uv2].uv);
373         }
374
375         /* Original Lacplacian algorithm included removal of normal component of translation. here it is not
376          * needed since we translate along the UV plane always.*/
377         for (i = 0; i < sculptdata->totalUniqueUvs; i++) {
378                 copy_v2_v2(tmp_uvdata[i].p, tmp_uvdata[i].sum_co);
379                 mul_v2_fl(tmp_uvdata[i].p, 1.f / tmp_uvdata[i].ncounter);
380         }
381
382         for (i = 0; i < sculptdata->totalUniqueUvs; i++) {
383                 float dist;
384                 /* This is supposed to happen only if "Pin Edges" is on, since we have initialization on stroke start
385                  * If ever uv brushes get their own mode we should check for toolsettings option too */
386                 if ((sculptdata->uv[i].flag & MARK_BOUNDARY)) {
387                         continue;
388                 }
389
390                 sub_v2_v2v2(diff, sculptdata->uv[i].uv, mouse_coord);
391                 diff[1] /= aspectRatio;
392                 if ((dist = dot_v2v2(diff, diff)) <= radius) {
393                         UvElement *element;
394                         float strength;
395                         strength = alpha * BKE_brush_curve_strength_clamped(brush, sqrtf(dist), radius_root);
396
397                         sculptdata->uv[i].uv[0] = (1.0f - strength) * sculptdata->uv[i].uv[0] + strength * tmp_uvdata[i].p[0];
398                         sculptdata->uv[i].uv[1] = (1.0f - strength) * sculptdata->uv[i].uv[1] + strength * tmp_uvdata[i].p[1];
399
400                         for (element = sculptdata->uv[i].element; element; element = element->next) {
401                                 MLoopUV *luv;
402                                 BMLoop *l;
403
404                                 if (element->separate && element != sculptdata->uv[i].element)
405                                         break;
406
407                                 l = element->l;
408                                 luv = CustomData_bmesh_get(&em->bm->ldata, l->head.data, CD_MLOOPUV);
409                                 copy_v2_v2(luv->uv, sculptdata->uv[i].uv);
410                         }
411                 }
412         }
413
414         MEM_freeN(tmp_uvdata);
415
416         return;
417 }
418
419
420 static void uv_sculpt_stroke_apply(bContext *C, wmOperator *op, const wmEvent *event, Object *obedit)
421 {
422         float co[2], radius, radius_root;
423         Scene *scene = CTX_data_scene(C);
424         ARegion *ar = CTX_wm_region(C);
425         BMEditMesh *em = BKE_editmesh_from_object(obedit);
426         unsigned int tool;
427         UvSculptData *sculptdata = (UvSculptData *)op->customdata;
428         SpaceImage *sima;
429         int invert;
430         int width, height;
431         float aspectRatio;
432         float alpha, zoomx, zoomy;
433         Brush *brush = BKE_paint_brush(sculptdata->uvsculpt);
434         ToolSettings *toolsettings = CTX_data_tool_settings(C);
435         tool = sculptdata->tool;
436         invert = sculptdata->invert ? -1 : 1;
437         alpha = BKE_brush_alpha_get(scene, brush);
438         UI_view2d_region_to_view(&ar->v2d, event->mval[0], event->mval[1], &co[0], &co[1]);
439
440         sima = CTX_wm_space_image(C);
441         ED_space_image_get_size(sima, &width, &height);
442         ED_space_image_get_zoom(sima, ar, &zoomx, &zoomy);
443
444         radius = BKE_brush_size_get(scene, brush) / (width * zoomx);
445         aspectRatio = width / (float)height;
446
447         /* We will compare squares to save some computation */
448         radius = radius * radius;
449         radius_root = sqrtf(radius);
450
451         /*
452          * Pinch Tool
453          */
454         if (tool == UV_SCULPT_TOOL_PINCH) {
455                 int i;
456                 alpha *= invert;
457                 for (i = 0; i < sculptdata->totalUniqueUvs; i++) {
458                         float dist, diff[2];
459                         /* This is supposed to happen only if "Lock Borders" is on, since we have initialization on stroke start
460                          * If ever uv brushes get their own mode we should check for toolsettings option too */
461                         if (sculptdata->uv[i].flag & MARK_BOUNDARY) {
462                                 continue;
463                         }
464
465                         sub_v2_v2v2(diff, sculptdata->uv[i].uv, co);
466                         diff[1] /= aspectRatio;
467                         if ((dist = dot_v2v2(diff, diff)) <= radius) {
468                                 UvElement *element;
469                                 float strength;
470                                 strength = alpha * BKE_brush_curve_strength_clamped(brush, sqrtf(dist), radius_root);
471                                 normalize_v2(diff);
472
473                                 sculptdata->uv[i].uv[0] -= strength * diff[0] * 0.001f;
474                                 sculptdata->uv[i].uv[1] -= strength * diff[1] * 0.001f;
475
476                                 for (element = sculptdata->uv[i].element; element; element = element->next) {
477                                         MLoopUV *luv;
478                                         BMLoop *l;
479
480                                         if (element->separate && element != sculptdata->uv[i].element)
481                                                 break;
482
483                                         l = element->l;
484                                         luv = CustomData_bmesh_get(&em->bm->ldata, l->head.data, CD_MLOOPUV);
485                                         copy_v2_v2(luv->uv, sculptdata->uv[i].uv);
486                                 }
487                         }
488                 }
489         }
490
491         /*
492          * Smooth Tool
493          */
494         else if (tool == UV_SCULPT_TOOL_RELAX) {
495                 unsigned int method = toolsettings->uv_relax_method;
496                 if (method == UV_SCULPT_TOOL_RELAX_HC) {
497                         HC_relaxation_iteration_uv(em, sculptdata, co, alpha, radius, aspectRatio);
498                 }
499                 else {
500                         laplacian_relaxation_iteration_uv(em, sculptdata, co, alpha, radius, aspectRatio);
501                 }
502         }
503
504         /*
505          * Grab Tool
506          */
507         else if (tool == UV_SCULPT_TOOL_GRAB) {
508                 int i;
509                 float diff[2];
510                 sub_v2_v2v2(diff, co, sculptdata->initial_stroke->init_coord);
511
512                 for (i = 0; i < sculptdata->initial_stroke->totalInitialSelected; i++) {
513                         UvElement *element;
514                         int uvindex = sculptdata->initial_stroke->initialSelection[i].uv;
515                         float strength = sculptdata->initial_stroke->initialSelection[i].strength;
516                         sculptdata->uv[uvindex].uv[0] = sculptdata->initial_stroke->initialSelection[i].initial_uv[0] + strength * diff[0];
517                         sculptdata->uv[uvindex].uv[1] = sculptdata->initial_stroke->initialSelection[i].initial_uv[1] + strength * diff[1];
518
519                         for (element = sculptdata->uv[uvindex].element; element; element = element->next) {
520                                 MLoopUV *luv;
521                                 BMLoop *l;
522
523                                 if (element->separate && element != sculptdata->uv[uvindex].element)
524                                         break;
525
526                                 l = element->l;
527                                 luv = CustomData_bmesh_get(&em->bm->ldata, l->head.data, CD_MLOOPUV);
528                                 copy_v2_v2(luv->uv, sculptdata->uv[uvindex].uv);
529                         }
530                 }
531         }
532 }
533
534
535 static void uv_sculpt_stroke_exit(bContext *C, wmOperator *op)
536 {
537         UvSculptData *data = op->customdata;
538         if (data->timer) {
539                 WM_event_remove_timer(CTX_wm_manager(C), CTX_wm_window(C), data->timer);
540         }
541         if (data->elementMap) {
542                 BM_uv_element_map_free(data->elementMap);
543         }
544         if (data->uv) {
545                 MEM_freeN(data->uv);
546         }
547         if (data->uvedges) {
548                 MEM_freeN(data->uvedges);
549         }
550         if (data->initial_stroke) {
551                 if (data->initial_stroke->initialSelection) {
552                         MEM_freeN(data->initial_stroke->initialSelection);
553                 }
554                 MEM_freeN(data->initial_stroke);
555         }
556
557         MEM_freeN(data);
558         op->customdata = NULL;
559 }
560
561 static int uv_element_offset_from_face_get(UvElementMap *map, BMFace *efa, BMLoop *l, int island_index, const bool doIslands)
562 {
563         UvElement *element = BM_uv_element_get(map, efa, l);
564         if (!element || (doIslands && element->island != island_index)) {
565                 return -1;
566         }
567         return element - map->buf;
568 }
569
570
571 static unsigned int uv_edge_hash(const void *key)
572 {
573         const UvEdge *edge = key;
574         return (BLI_ghashutil_uinthash(edge->uv2) +
575                 BLI_ghashutil_uinthash(edge->uv1));
576 }
577
578 static bool uv_edge_compare(const void *a, const void *b)
579 {
580         const UvEdge *edge1 = a;
581         const UvEdge *edge2 = b;
582
583         if ((edge1->uv1 == edge2->uv1) && (edge1->uv2 == edge2->uv2)) {
584                 return 0;
585         }
586         return 1;
587 }
588
589
590 static UvSculptData *uv_sculpt_stroke_init(bContext *C, wmOperator *op, const wmEvent *event)
591 {
592         Scene *scene = CTX_data_scene(C);
593         Object *obedit = CTX_data_edit_object(C);
594         ToolSettings *ts = scene->toolsettings;
595         UvSculptData *data = MEM_callocN(sizeof(*data), "UV Smooth Brush Data");
596         BMEditMesh *em = BKE_editmesh_from_object(obedit);
597         BMesh *bm = em->bm;
598
599         op->customdata = data;
600
601         curvemapping_initialize(ts->uvsculpt->paint.brush->curve);
602
603         if (data) {
604                 int counter = 0, i;
605                 ARegion *ar = CTX_wm_region(C);
606                 float co[2];
607                 BMFace *efa;
608                 MLoopUV *luv;
609                 BMLoop *l;
610                 BMIter iter, liter;
611
612                 UvEdge *edges;
613                 GHash *edgeHash;
614                 GHashIterator gh_iter;
615
616                 bool do_island_optimization = !(ts->uv_sculpt_settings & UV_SCULPT_ALL_ISLANDS);
617                 int island_index = 0;
618                 /* Holds, for each UvElement in elementMap, a pointer to its unique uv.*/
619                 int *uniqueUv;
620                 data->tool = (RNA_enum_get(op->ptr, "mode") == BRUSH_STROKE_SMOOTH) ? UV_SCULPT_TOOL_RELAX : ts->uv_sculpt_tool;
621                 data->invert = (RNA_enum_get(op->ptr, "mode") == BRUSH_STROKE_INVERT) ? 1 : 0;
622
623                 data->uvsculpt = &ts->uvsculpt->paint;
624
625                 if (do_island_optimization) {
626                         /* We will need island information */
627                         if (ts->uv_flag & UV_SYNC_SELECTION) {
628                                 data->elementMap = BM_uv_element_map_create(bm, false, true, true);
629                         }
630                         else {
631                                 data->elementMap = BM_uv_element_map_create(bm, true, true, true);
632                         }
633                 }
634                 else {
635                         if (ts->uv_flag & UV_SYNC_SELECTION) {
636                                 data->elementMap = BM_uv_element_map_create(bm, false, true, false);
637                         }
638                         else {
639                                 data->elementMap = BM_uv_element_map_create(bm, true, true, false);
640                         }
641                 }
642
643                 if (!data->elementMap) {
644                         uv_sculpt_stroke_exit(C, op);
645                         return NULL;
646                 }
647
648                 /* Mouse coordinates, useful for some functions like grab and sculpt all islands */
649                 UI_view2d_region_to_view(&ar->v2d, event->mval[0], event->mval[1], &co[0], &co[1]);
650
651                 /* we need to find the active island here */
652                 if (do_island_optimization) {
653                         UvElement *element;
654                         UvNearestHit hit = UV_NEAREST_HIT_INIT;
655                         Image *ima = CTX_data_edit_image(C);
656                         uv_find_nearest_vert(scene, ima, obedit, co, 0.0f, &hit);
657
658                         element = BM_uv_element_get(data->elementMap, hit.efa, hit.l);
659                         island_index = element->island;
660                 }
661
662
663                 /* Count 'unique' uvs */
664                 for (i = 0; i < data->elementMap->totalUVs; i++) {
665                         if (data->elementMap->buf[i].separate &&
666                             (!do_island_optimization || data->elementMap->buf[i].island == island_index))
667                         {
668                                 counter++;
669                         }
670                 }
671
672                 /* Allocate the unique uv buffers */
673                 data->uv = MEM_mallocN(sizeof(*data->uv) * counter, "uv_brush_unique_uvs");
674                 uniqueUv = MEM_mallocN(sizeof(*uniqueUv) * data->elementMap->totalUVs, "uv_brush_unique_uv_map");
675                 edgeHash = BLI_ghash_new(uv_edge_hash, uv_edge_compare, "uv_brush_edge_hash");
676                 /* we have at most totalUVs edges */
677                 edges = MEM_mallocN(sizeof(*edges) * data->elementMap->totalUVs, "uv_brush_all_edges");
678                 if (!data->uv || !uniqueUv || !edgeHash || !edges) {
679                         if (edges) {
680                                 MEM_freeN(edges);
681                         }
682                         if (uniqueUv) {
683                                 MEM_freeN(uniqueUv);
684                         }
685                         if (edgeHash) {
686                                 BLI_ghash_free(edgeHash, NULL, NULL);
687                         }
688                         uv_sculpt_stroke_exit(C, op);
689                         return NULL;
690                 }
691
692                 data->totalUniqueUvs = counter;
693                 /* So that we can use this as index for the UvElements */
694                 counter = -1;
695                 /* initialize the unique UVs */
696                 for (i = 0; i < bm->totvert; i++) {
697                         UvElement *element = data->elementMap->vert[i];
698                         for (; element; element = element->next) {
699                                 if (element->separate) {
700                                         if (do_island_optimization && (element->island != island_index)) {
701                                                 /* skip this uv if not on the active island */
702                                                 for (; element->next && !(element->next->separate); element = element->next)
703                                                         ;
704                                                 continue;
705                                         }
706
707                                         l = element->l;
708                                         luv = CustomData_bmesh_get(&em->bm->ldata, l->head.data, CD_MLOOPUV);
709
710                                         counter++;
711                                         data->uv[counter].element = element;
712                                         data->uv[counter].flag = 0;
713                                         data->uv[counter].uv = luv->uv;
714                                 }
715                                 /* pointer arithmetic to the rescue, as always :)*/
716                                 uniqueUv[element - data->elementMap->buf] = counter;
717                         }
718                 }
719
720
721                 /* Now, on to generate our uv connectivity data */
722                 counter = 0;
723                 BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
724                         BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
725                                 int offset1, itmp1 = uv_element_offset_from_face_get(data->elementMap, efa, l, island_index, do_island_optimization);
726                                 int offset2, itmp2 = uv_element_offset_from_face_get(data->elementMap, efa, l->next, island_index, do_island_optimization);
727                                 char *flag;
728
729                                 /* Skip edge if not found(unlikely) or not on valid island */
730                                 if (itmp1 == -1 || itmp2 == -1)
731                                         continue;
732
733                                 offset1 = uniqueUv[itmp1];
734                                 offset2 = uniqueUv[itmp2];
735
736                                 edges[counter].flag = 0;
737                                 /* using an order policy, sort uvs according to address space. This avoids
738                                  * Having two different UvEdges with the same uvs on different positions  */
739                                 if (offset1 < offset2) {
740                                         edges[counter].uv1 = offset1;
741                                         edges[counter].uv2 = offset2;
742                                 }
743                                 else {
744                                         edges[counter].uv1 = offset2;
745                                         edges[counter].uv2 = offset1;
746                                 }
747                                 /* Hack! Set the value of the key to its flag. Now we can set the flag when an edge exists twice :) */
748                                 flag = BLI_ghash_lookup(edgeHash, &edges[counter]);
749                                 if (flag) {
750                                         *flag = 1;
751                                 }
752                                 else {
753                                         /* Hack mentioned */
754                                         BLI_ghash_insert(edgeHash, &edges[counter], &edges[counter].flag);
755                                 }
756                                 counter++;
757                         }
758                 }
759
760                 MEM_freeN(uniqueUv);
761
762                 /* Allocate connectivity data, we allocate edges once */
763                 data->uvedges = MEM_mallocN(sizeof(*data->uvedges) * BLI_ghash_len(edgeHash), "uv_brush_edge_connectivity_data");
764                 if (!data->uvedges) {
765                         BLI_ghash_free(edgeHash, NULL, NULL);
766                         MEM_freeN(edges);
767                         uv_sculpt_stroke_exit(C, op);
768                         return NULL;
769                 }
770
771                 /* fill the edges with data */
772                 i = 0;
773                 GHASH_ITER (gh_iter, edgeHash) {
774                         data->uvedges[i++] = *((UvEdge *)BLI_ghashIterator_getKey(&gh_iter));
775                 }
776                 data->totalUvEdges = BLI_ghash_len(edgeHash);
777
778                 /* cleanup temporary stuff */
779                 BLI_ghash_free(edgeHash, NULL, NULL);
780                 MEM_freeN(edges);
781
782                 /* transfer boundary edge property to uvs */
783                 if (ts->uv_sculpt_settings & UV_SCULPT_LOCK_BORDERS) {
784                         for (i = 0; i < data->totalUvEdges; i++) {
785                                 if (!data->uvedges[i].flag) {
786                                         data->uv[data->uvedges[i].uv1].flag |= MARK_BOUNDARY;
787                                         data->uv[data->uvedges[i].uv2].flag |= MARK_BOUNDARY;
788                                 }
789                         }
790                 }
791
792                 /* Allocate initial selection for grab tool */
793                 if (data->tool == UV_SCULPT_TOOL_GRAB) {
794                         float radius, radius_root;
795                         UvSculptData *sculptdata = (UvSculptData *)op->customdata;
796                         SpaceImage *sima;
797                         int width, height;
798                         float aspectRatio;
799                         float alpha, zoomx, zoomy;
800                         Brush *brush = BKE_paint_brush(sculptdata->uvsculpt);
801
802                         alpha = BKE_brush_alpha_get(scene, brush);
803
804                         radius = BKE_brush_size_get(scene, brush);
805                         sima = CTX_wm_space_image(C);
806                         ED_space_image_get_size(sima, &width, &height);
807                         ED_space_image_get_zoom(sima, ar, &zoomx, &zoomy);
808
809                         aspectRatio = width / (float)height;
810                         radius /= (width * zoomx);
811                         radius = radius * radius;
812                         radius_root = sqrtf(radius);
813
814                         /* Allocate selection stack */
815                         data->initial_stroke = MEM_mallocN(sizeof(*data->initial_stroke), "uv_sculpt_initial_stroke");
816                         if (!data->initial_stroke) {
817                                 uv_sculpt_stroke_exit(C, op);
818                         }
819                         data->initial_stroke->initialSelection = MEM_mallocN(sizeof(*data->initial_stroke->initialSelection) * data->totalUniqueUvs, "uv_sculpt_initial_selection");
820                         if (!data->initial_stroke->initialSelection) {
821                                 uv_sculpt_stroke_exit(C, op);
822                         }
823
824                         copy_v2_v2(data->initial_stroke->init_coord, co);
825
826                         counter = 0;
827
828                         for (i = 0; i < data->totalUniqueUvs; i++) {
829                                 float dist, diff[2];
830                                 if (data->uv[i].flag & MARK_BOUNDARY) {
831                                         continue;
832                                 }
833
834                                 sub_v2_v2v2(diff, data->uv[i].uv, co);
835                                 diff[1] /= aspectRatio;
836                                 if ((dist = dot_v2v2(diff, diff)) <= radius) {
837                                         float strength;
838                                         strength = alpha * BKE_brush_curve_strength_clamped(brush, sqrtf(dist), radius_root);
839
840                                         data->initial_stroke->initialSelection[counter].uv = i;
841                                         data->initial_stroke->initialSelection[counter].strength = strength;
842                                         copy_v2_v2(data->initial_stroke->initialSelection[counter].initial_uv, data->uv[i].uv);
843                                         counter++;
844                                 }
845                         }
846
847                         data->initial_stroke->totalInitialSelected = counter;
848                 }
849         }
850
851         return op->customdata;
852 }
853
854 static int uv_sculpt_stroke_invoke(bContext *C, wmOperator *op, const wmEvent *event)
855 {
856         UvSculptData *data;
857         Object *obedit = CTX_data_edit_object(C);
858
859         if (!(data = uv_sculpt_stroke_init(C, op, event))) {
860                 return OPERATOR_CANCELLED;
861         }
862
863         uv_sculpt_stroke_apply(C, op, event, obedit);
864
865         data->timer = WM_event_add_timer(CTX_wm_manager(C), CTX_wm_window(C), TIMER, 0.001f);
866
867         if (!data->timer) {
868                 uv_sculpt_stroke_exit(C, op);
869                 return OPERATOR_CANCELLED;
870         }
871         WM_event_add_modal_handler(C, op);
872
873         return OPERATOR_RUNNING_MODAL;
874 }
875
876
877 static int uv_sculpt_stroke_modal(bContext *C, wmOperator *op, const wmEvent *event)
878 {
879         UvSculptData *data = (UvSculptData *)op->customdata;
880         Object *obedit = CTX_data_edit_object(C);
881
882         switch (event->type) {
883                 case LEFTMOUSE:
884                 case MIDDLEMOUSE:
885                 case RIGHTMOUSE:
886                         uv_sculpt_stroke_exit(C, op);
887                         return OPERATOR_FINISHED;
888
889                 case MOUSEMOVE:
890                 case INBETWEEN_MOUSEMOVE:
891                         uv_sculpt_stroke_apply(C, op, event, obedit);
892                         break;
893                 case TIMER:
894                         if (event->customdata == data->timer)
895                                 uv_sculpt_stroke_apply(C, op, event, obedit);
896                         break;
897                 default:
898                         return OPERATOR_RUNNING_MODAL;
899         }
900
901         ED_region_tag_redraw(CTX_wm_region(C));
902         WM_event_add_notifier(C, NC_GEOM | ND_DATA, obedit->data);
903         DEG_id_tag_update(obedit->data, 0);
904         return OPERATOR_RUNNING_MODAL;
905 }
906
907 void SCULPT_OT_uv_sculpt_stroke(wmOperatorType *ot)
908 {
909         static const EnumPropertyItem stroke_mode_items[] = {
910                 {BRUSH_STROKE_NORMAL, "NORMAL", 0, "Normal", "Apply brush normally"},
911                 {BRUSH_STROKE_INVERT, "INVERT", 0, "Invert", "Invert action of brush for duration of stroke"},
912                 {BRUSH_STROKE_SMOOTH, "RELAX", 0, "Relax", "Switch brush to relax mode for duration of stroke"},
913                 {0}
914         };
915
916         /* identifiers */
917         ot->name = "Sculpt UVs";
918         ot->description = "Sculpt UVs using a brush";
919         ot->idname = "SCULPT_OT_uv_sculpt_stroke";
920
921         /* api callbacks */
922         ot->invoke = uv_sculpt_stroke_invoke;
923         ot->modal = uv_sculpt_stroke_modal;
924         ot->poll = uv_sculpt_poll;
925
926         /* flags */
927         ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
928
929         /* props */
930         RNA_def_enum(ot->srna, "mode", stroke_mode_items, BRUSH_STROKE_NORMAL, "Mode", "Stroke Mode");
931 }