Merge branch 'master' into blender2.8
[blender.git] / source / blender / editors / uvedit / uvedit_draw.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  * Contributor(s): Blender Foundation, 2002-2009
22  *
23  * ***** END GPL LICENSE BLOCK *****
24  */
25
26 /** \file blender/editors/uvedit/uvedit_draw.c
27  *  \ingroup eduv
28  */
29
30
31 #include <float.h>
32 #include <math.h>
33 #include <stdlib.h>
34 #include <string.h>
35
36 #include "MEM_guardedalloc.h"
37
38 #include "DNA_material_types.h"
39 #include "DNA_mesh_types.h"
40 #include "DNA_meshdata_types.h"
41 #include "DNA_object_types.h"
42 #include "DNA_scene_types.h"
43 #include "DNA_screen_types.h"
44 #include "DNA_space_types.h"
45
46 #include "BLI_math.h"
47 #include "BLI_utildefines.h"
48 #include "BLI_buffer.h"
49 #include "BLI_bitmap.h"
50
51 #include "BKE_DerivedMesh.h"
52 #include "BKE_editmesh.h"
53 #include "BKE_material.h"
54 #include "BKE_layer.h"
55
56 #include "BKE_scene.h"
57
58 #include "BIF_glutil.h"
59
60 #include "DEG_depsgraph.h"
61 #include "DEG_depsgraph_query.h"
62
63 #include "GPU_batch.h"
64 #include "GPU_immediate.h"
65 #include "GPU_immediate_util.h"
66 #include "GPU_matrix.h"
67
68 #include "ED_image.h"
69 #include "ED_mesh.h"
70 #include "ED_uvedit.h"
71
72 #include "UI_resources.h"
73 #include "UI_interface.h"
74 #include "UI_view2d.h"
75
76 #include "uvedit_intern.h"
77
78 static void draw_uvs_lineloop_bmfaces(BMesh *bm, const int cd_loop_uv_offset, const uint shdr_pos);
79
80 void ED_image_draw_cursor(ARegion *ar, const float cursor[2])
81 {
82         float zoom[2], x_fac, y_fac;
83
84         UI_view2d_scale_get_inverse(&ar->v2d, &zoom[0], &zoom[1]);
85
86         mul_v2_fl(zoom, 256.0f * UI_DPI_FAC);
87         x_fac = zoom[0];
88         y_fac = zoom[1];
89
90         gpuTranslate2fv(cursor);
91
92         const uint shdr_pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
93
94         immBindBuiltinProgram(GPU_SHADER_2D_LINE_DASHED_UNIFORM_COLOR);
95
96         float viewport_size[4];
97         glGetFloatv(GL_VIEWPORT, viewport_size);
98         immUniform2f("viewport_size", viewport_size[2] / UI_DPI_FAC, viewport_size[3] / UI_DPI_FAC);
99
100         immUniform1i("num_colors", 2);  /* "advanced" mode */
101         immUniformArray4fv("colors", (float *)(float[][4]){{1.0f, 0.0f, 0.0f, 1.0f}, {1.0f, 1.0f, 1.0f, 1.0f}}, 2);
102         immUniform1f("dash_width", 8.0f);
103
104         immBegin(GWN_PRIM_LINES, 8);
105
106         immVertex2f(shdr_pos, -0.05f * x_fac, 0.0f);
107         immVertex2f(shdr_pos, 0.0f, 0.05f * y_fac);
108
109         immVertex2f(shdr_pos, 0.0f, 0.05f * y_fac);
110         immVertex2f(shdr_pos, 0.05f * x_fac, 0.0f);
111
112         immVertex2f(shdr_pos, 0.05f * x_fac, 0.0f);
113         immVertex2f(shdr_pos, 0.0f, -0.05f * y_fac);
114
115         immVertex2f(shdr_pos, 0.0f, -0.05f * y_fac);
116         immVertex2f(shdr_pos, -0.05f * x_fac, 0.0f);
117
118         immEnd();
119
120         immUniformArray4fv("colors", (float *)(float[][4]){{1.0f, 1.0f, 1.0f, 1.0f}, {0.0f, 0.0f, 0.0f, 1.0f}}, 2);
121         immUniform1f("dash_width", 2.0f);
122
123         immBegin(GWN_PRIM_LINES, 8);
124
125         immVertex2f(shdr_pos, -0.020f * x_fac, 0.0f);
126         immVertex2f(shdr_pos, -0.1f * x_fac, 0.0f);
127
128         immVertex2f(shdr_pos, 0.1f * x_fac, 0.0f);
129         immVertex2f(shdr_pos, 0.020f * x_fac, 0.0f);
130
131         immVertex2f(shdr_pos, 0.0f, -0.020f * y_fac);
132         immVertex2f(shdr_pos, 0.0f, -0.1f * y_fac);
133
134         immVertex2f(shdr_pos, 0.0f, 0.1f * y_fac);
135         immVertex2f(shdr_pos, 0.0f, 0.020f * y_fac);
136
137         immEnd();
138
139         immUnbindProgram();
140
141         gpuTranslate2f(-cursor[0], -cursor[1]);
142 }
143
144 static int draw_uvs_face_check(Scene *scene)
145 {
146         ToolSettings *ts = scene->toolsettings;
147
148         /* checks if we are selecting only faces */
149         if (ts->uv_flag & UV_SYNC_SELECTION) {
150                 if (ts->selectmode == SCE_SELECT_FACE)
151                         return 2;
152                 else if (ts->selectmode & SCE_SELECT_FACE)
153                         return 1;
154                 else
155                         return 0;
156         }
157         else
158                 return (ts->uv_selectmode == UV_SELECT_FACE);
159 }
160
161 static void draw_uvs_shadow(Object *obedit)
162 {
163         BMEditMesh *em = BKE_editmesh_from_object(obedit);
164         BMesh *bm = em->bm;
165
166         const int cd_loop_uv_offset = CustomData_get_offset(&bm->ldata, CD_MLOOPUV);
167
168         unsigned int pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
169
170         immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
171
172         /* draws the mesh when painting */
173         immUniformThemeColor(TH_UV_SHADOW);
174
175         draw_uvs_lineloop_bmfaces(bm, cd_loop_uv_offset, pos);
176
177         immUnbindProgram();
178 }
179
180 static void draw_uvs_stretch(SpaceImage *sima, Scene *scene, Object *obedit, BMEditMesh *em, const BMFace *efa_act)
181 {
182         BMesh *bm = em->bm;
183         BMFace *efa;
184         BMLoop *l;
185         BMIter iter, liter;
186         MLoopUV *luv;
187         Image *ima = sima->image;
188         float aspx, aspy, col[4];
189         int i;
190
191         const int cd_loop_uv_offset  = CustomData_get_offset(&bm->ldata, CD_MLOOPUV);
192
193         BLI_buffer_declare_static(vec2f, tf_uv_buf, BLI_BUFFER_NOP, BM_DEFAULT_NGON_STACK_SIZE);
194         BLI_buffer_declare_static(vec2f, tf_uvorig_buf, BLI_BUFFER_NOP, BM_DEFAULT_NGON_STACK_SIZE);
195
196         ED_space_image_get_uv_aspect(sima, &aspx, &aspy);
197
198         switch (sima->dt_uvstretch) {
199                 case SI_UVDT_STRETCH_AREA:
200                 {
201                         float totarea = 0.0f, totuvarea = 0.0f, areadiff, uvarea, area;
202
203                         BM_ITER_MESH (efa, &iter, bm, BM_FACES_OF_MESH) {
204                                 const int efa_len = efa->len;
205                                 float (*tf_uv)[2]     = (float (*)[2])BLI_buffer_reinit_data(&tf_uv_buf,     vec2f, efa_len);
206                                 float (*tf_uvorig)[2] = (float (*)[2])BLI_buffer_reinit_data(&tf_uvorig_buf, vec2f, efa_len);
207
208                                 BM_ITER_ELEM_INDEX (l, &liter, efa, BM_LOOPS_OF_FACE, i) {
209                                         luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
210                                         copy_v2_v2(tf_uvorig[i], luv->uv);
211                                 }
212
213                                 uv_poly_copy_aspect(tf_uvorig, tf_uv, aspx, aspy, efa->len);
214
215                                 totarea += BM_face_calc_area(efa);
216                                 totuvarea += area_poly_v2(tf_uv, efa->len);
217
218                                 if (uvedit_face_visible_test(scene, obedit, ima, efa)) {
219                                         BM_elem_flag_enable(efa, BM_ELEM_TAG);
220                                 }
221                                 else {
222                                         if (efa == efa_act) {
223                                                 efa_act = NULL;
224                                         }
225                                         BM_elem_flag_disable(efa, BM_ELEM_TAG);
226                                 }
227                         }
228
229                         unsigned int pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
230
231                         immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
232
233                         if (totarea < FLT_EPSILON || totuvarea < FLT_EPSILON) {
234                                 col[0] = 1.0;
235                                 col[1] = col[2] = 0.0;
236
237                                 immUniformColor3fv(col);
238
239                                 BM_ITER_MESH (efa, &iter, bm, BM_FACES_OF_MESH) {
240                                         if (BM_elem_flag_test(efa, BM_ELEM_TAG)) {
241                                                 immBegin(GWN_PRIM_TRI_FAN, efa->len);
242
243                                                 BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
244                                                         luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
245                                                         immVertex2fv(pos, luv->uv);
246                                                 }
247
248                                                 immEnd();
249                                         }
250                                 }
251                         }
252                         else {
253                                 BM_ITER_MESH (efa, &iter, bm, BM_FACES_OF_MESH) {
254                                         if (BM_elem_flag_test(efa, BM_ELEM_TAG)) {
255                                                 const int efa_len = efa->len;
256                                                 float (*tf_uv)[2]     = (float (*)[2])BLI_buffer_reinit_data(&tf_uv_buf,     vec2f, efa_len);
257                                                 float (*tf_uvorig)[2] = (float (*)[2])BLI_buffer_reinit_data(&tf_uvorig_buf, vec2f, efa_len);
258
259                                                 area = BM_face_calc_area(efa) / totarea;
260
261                                                 BM_ITER_ELEM_INDEX (l, &liter, efa, BM_LOOPS_OF_FACE, i) {
262                                                         luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
263                                                         copy_v2_v2(tf_uvorig[i], luv->uv);
264                                                 }
265
266                                                 uv_poly_copy_aspect(tf_uvorig, tf_uv, aspx, aspy, efa->len);
267
268                                                 uvarea = area_poly_v2(tf_uv, efa->len) / totuvarea;
269
270                                                 if (area < FLT_EPSILON || uvarea < FLT_EPSILON)
271                                                         areadiff = 1.0f;
272                                                 else if (area > uvarea)
273                                                         areadiff = 1.0f - (uvarea / area);
274                                                 else
275                                                         areadiff = 1.0f - (area / uvarea);
276
277                                                 weight_to_rgb(col, areadiff);
278                                                 immUniformColor3fv(col);
279
280                                                 /* TODO: use editmesh tessface */
281                                                 immBegin(GWN_PRIM_TRI_FAN, efa->len);
282
283                                                 BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
284                                                         luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
285                                                         immVertex2fv(pos, luv->uv);
286                                                 }
287
288                                                 immEnd();
289                                         }
290                                 }
291                         }
292
293                         immUnbindProgram();
294
295                         break;
296                 }
297                 case SI_UVDT_STRETCH_ANGLE:
298                 {
299                         float a;
300
301                         BLI_buffer_declare_static(float, uvang_buf, BLI_BUFFER_NOP, BM_DEFAULT_NGON_STACK_SIZE);
302                         BLI_buffer_declare_static(float, ang_buf,   BLI_BUFFER_NOP, BM_DEFAULT_NGON_STACK_SIZE);
303                         BLI_buffer_declare_static(vec3f, av_buf,  BLI_BUFFER_NOP, BM_DEFAULT_NGON_STACK_SIZE);
304                         BLI_buffer_declare_static(vec2f, auv_buf, BLI_BUFFER_NOP, BM_DEFAULT_NGON_STACK_SIZE);
305
306                         col[3] = 0.5f; /* hard coded alpha, not that nice */
307
308                         Gwn_VertFormat *format = immVertexFormat();
309                         unsigned int pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
310                         unsigned int color = GWN_vertformat_attr_add(format, "color", GWN_COMP_F32, 3, GWN_FETCH_FLOAT);
311
312                         immBindBuiltinProgram(GPU_SHADER_2D_SMOOTH_COLOR);
313
314                         BM_ITER_MESH (efa, &iter, bm, BM_FACES_OF_MESH) {
315                                 if (uvedit_face_visible_test(scene, obedit, ima, efa)) {
316                                         const int efa_len = efa->len;
317                                         float (*tf_uv)[2]     = (float (*)[2])BLI_buffer_reinit_data(&tf_uv_buf,     vec2f, efa_len);
318                                         float (*tf_uvorig)[2] = (float (*)[2])BLI_buffer_reinit_data(&tf_uvorig_buf, vec2f, efa_len);
319                                         float *uvang = BLI_buffer_reinit_data(&uvang_buf, float, efa_len);
320                                         float *ang   = BLI_buffer_reinit_data(&ang_buf,   float, efa_len);
321                                         float (*av)[3]  = (float (*)[3])BLI_buffer_reinit_data(&av_buf, vec3f, efa_len);
322                                         float (*auv)[2] = (float (*)[2])BLI_buffer_reinit_data(&auv_buf, vec2f, efa_len);
323                                         int j;
324
325                                         BM_elem_flag_enable(efa, BM_ELEM_TAG);
326
327                                         BM_ITER_ELEM_INDEX (l, &liter, efa, BM_LOOPS_OF_FACE, i) {
328                                                 luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
329                                                 copy_v2_v2(tf_uvorig[i], luv->uv);
330                                         }
331
332                                         uv_poly_copy_aspect(tf_uvorig, tf_uv, aspx, aspy, efa_len);
333
334                                         j = efa_len - 1;
335                                         BM_ITER_ELEM_INDEX (l, &liter, efa, BM_LOOPS_OF_FACE, i) {
336                                                 sub_v2_v2v2(auv[i], tf_uv[j], tf_uv[i]); normalize_v2(auv[i]);
337                                                 sub_v3_v3v3(av[i], l->prev->v->co, l->v->co); normalize_v3(av[i]);
338                                                 j = i;
339                                         }
340
341                                         for (i = 0; i < efa_len; i++) {
342 #if 0
343                                                 /* Simple but slow, better reuse normalized vectors
344                                                  * (Not ported to bmesh, copied for reference) */
345                                                 uvang1 = RAD2DEG(angle_v2v2v2(tf_uv[3], tf_uv[0], tf_uv[1]));
346                                                 ang1 = RAD2DEG(angle_v3v3v3(efa->v4->co, efa->v1->co, efa->v2->co));
347 #endif
348                                                 uvang[i] = angle_normalized_v2v2(auv[i], auv[(i + 1) % efa_len]);
349                                                 ang[i] = angle_normalized_v3v3(av[i], av[(i + 1) % efa_len]);
350                                         }
351
352                                         /* TODO: use editmesh tessface */
353                                         immBegin(GWN_PRIM_TRI_FAN, efa->len);
354                                         BM_ITER_ELEM_INDEX (l, &liter, efa, BM_LOOPS_OF_FACE, i) {
355                                                 luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
356                                                 a = fabsf(uvang[i] - ang[i]) / (float)M_PI;
357                                                 weight_to_rgb(col, 1.0f - pow2f(1.0f - a));
358                                                 immAttrib3fv(color, col);
359                                                 immVertex2fv(pos, luv->uv);
360                                         }
361                                         immEnd();
362                                 }
363                                 else {
364                                         if (efa == efa_act)
365                                                 efa_act = NULL;
366                                         BM_elem_flag_disable(efa, BM_ELEM_TAG);
367                                 }
368                         }
369
370                         immUnbindProgram();
371
372                         BLI_buffer_free(&uvang_buf);
373                         BLI_buffer_free(&ang_buf);
374                         BLI_buffer_free(&av_buf);
375                         BLI_buffer_free(&auv_buf);
376
377                         break;
378                 }
379         }
380
381         BLI_buffer_free(&tf_uv_buf);
382         BLI_buffer_free(&tf_uvorig_buf);
383 }
384
385 static void draw_uvs_lineloop_bmfaces(BMesh *bm, const int cd_loop_uv_offset, const uint shdr_pos)
386 {
387         BMIter iter, liter;
388         BMFace *efa;
389         BMLoop *l;
390         MLoopUV *luv;
391
392         /* For more efficiency first transfer the entire buffer to vram. */
393         Gwn_Batch *loop_batch = immBeginBatchAtMost(GWN_PRIM_LINE_LOOP, bm->totloop);
394
395         BM_ITER_MESH(efa, &iter, bm, BM_FACES_OF_MESH) {
396                 if (!BM_elem_flag_test(efa, BM_ELEM_TAG))
397                         continue;
398
399                 BM_ITER_ELEM(l, &liter, efa, BM_LOOPS_OF_FACE) {
400                         luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
401                         immVertex2fv(shdr_pos, luv->uv);
402                 }
403         }
404         immEnd();
405
406         /* Then draw each face contour separately. */
407         GWN_batch_program_use_begin(loop_batch);
408         unsigned int index = 0;
409         BM_ITER_MESH(efa, &iter, bm, BM_FACES_OF_MESH) {
410                 if (!BM_elem_flag_test(efa, BM_ELEM_TAG))
411                         continue;
412
413                 GWN_batch_draw_range_ex(loop_batch, index, efa->len, false);
414                 index += efa->len;
415         }
416         GWN_batch_program_use_end(loop_batch);
417         GWN_batch_discard(loop_batch);
418 }
419
420 static void draw_uvs_lineloop_mpoly(Mesh *me, MPoly *mpoly, unsigned int pos)
421 {
422         MLoopUV *mloopuv;
423         int i;
424
425         immBegin(GWN_PRIM_LINE_LOOP, mpoly->totloop);
426
427         mloopuv = &me->mloopuv[mpoly->loopstart];
428         for (i = mpoly->totloop; i != 0; i--, mloopuv++) {
429                 immVertex2fv(pos, mloopuv->uv);
430         }
431
432         immEnd();
433 }
434
435 static void draw_uvs_other_mesh(Object *ob, const Image *curimage,
436                                 const int other_uv_filter, unsigned int pos)
437 {
438         Mesh *me = ob->data;
439         MPoly *mpoly = me->mpoly;
440         int a;
441         BLI_bitmap *mat_test_array;
442         bool ok = false;
443         int totcol = 0;
444
445         if (me->mloopuv == NULL) {
446                 return;
447         }
448
449         if (curimage && ob->totcol == 0) {
450                 return;
451         }
452
453         totcol = max_ii(ob->totcol, 1);
454         mat_test_array = BLI_BITMAP_NEW_ALLOCA(totcol);
455
456         for (a = 0; a < totcol; a++) {
457                 Image *image;
458
459                 /* if no materials, assume a default material with no image */
460                 if (ob->totcol)
461                         ED_object_get_active_image(ob, a + 1, &image, NULL, NULL, NULL);
462                 else
463                         image = NULL;
464
465                 if (image == curimage) {
466                         BLI_BITMAP_ENABLE(mat_test_array, a);
467                         ok = true;
468                 }
469         }
470
471         if (ok == false) {
472                 return;
473         }
474
475         for (a = me->totpoly; a != 0; a--, mpoly++) {
476                 if (other_uv_filter == SI_FILTER_ALL) {
477                         /* Nothing to compare, all UV faces are visible. */
478                 }
479                 else if (other_uv_filter == SI_FILTER_SAME_IMAGE) {
480                         const int mat_nr = mpoly->mat_nr;
481                         if ((mat_nr >= totcol) ||
482                             (BLI_BITMAP_TEST(mat_test_array, mat_nr)) == 0)
483                         {
484                                 continue;
485                         }
486                 }
487
488                 draw_uvs_lineloop_mpoly(me, mpoly, pos);
489         }
490 }
491
492 static void draw_uvs_other(ViewLayer *view_layer, Object *obedit, const Image *curimage,
493                            const int other_uv_filter)
494 {
495         unsigned int pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
496
497         immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
498
499         immUniformThemeColor(TH_UV_OTHERS);
500
501         for (Base *base = view_layer->object_bases.first; base; base = base->next) {
502                 if (((base->flag & BASE_SELECTED) != 0) &&
503                     ((base->flag & BASE_VISIBLED) != 0))
504                 {
505                         Object *ob = base->object;
506                         if ((ob->type == OB_MESH) && (ob != obedit) && ((Mesh *)ob->data)->mloopuv) {
507                                 draw_uvs_other_mesh(ob, curimage, other_uv_filter, pos);
508                         }
509                 }
510         }
511         immUnbindProgram();
512 }
513
514 static void draw_uvs_texpaint(SpaceImage *sima, Scene *scene, ViewLayer *view_layer, Object *ob)
515 {
516         Image *curimage = ED_space_image(sima);
517         Mesh *me = ob->data;
518         Material *ma;
519
520         if (sima->flag & SI_DRAW_OTHER) {
521                 draw_uvs_other(view_layer, ob, curimage, sima->other_uv_filter);
522         }
523
524         ma = give_current_material(ob, ob->actcol);
525
526         if (me->mloopuv) {
527                 MPoly *mpoly = me->mpoly;
528                 MLoopUV *mloopuv, *mloopuv_base;
529                 int a, b;
530                 if (!(ma && ma->texpaintslot && ma->texpaintslot[ma->paint_active_slot].uvname &&
531                       (mloopuv = CustomData_get_layer_named(&me->ldata, CD_MLOOPUV, ma->texpaintslot[ma->paint_active_slot].uvname))))
532                 {
533                         mloopuv = me->mloopuv;
534                 }
535
536                 unsigned int pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
537
538                 immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
539
540                 immUniformThemeColor(TH_UV_SHADOW);
541
542                 mloopuv_base = mloopuv;
543
544                 for (a = me->totpoly; a > 0; a--, mpoly++) {
545                         if ((scene->toolsettings->uv_flag & UV_SHOW_SAME_IMAGE) && mpoly->mat_nr != ob->actcol - 1)
546                                 continue;
547
548                         immBegin(GWN_PRIM_LINE_LOOP, mpoly->totloop);
549
550                         mloopuv = mloopuv_base + mpoly->loopstart;
551                         for (b = 0; b < mpoly->totloop; b++, mloopuv++) {
552                                 immVertex2fv(pos, mloopuv->uv);
553                         }
554
555                         immEnd();
556                 }
557
558                 immUnbindProgram();
559         }
560 }
561
562 static void draw_uvs_looptri(BMEditMesh *em, unsigned int *r_loop_index, const int cd_loop_uv_offset, unsigned int pos)
563 {
564         unsigned int i = *r_loop_index;
565         BMFace *f = em->looptris[i][0]->f;
566         do {
567                 unsigned int j;
568                 for (j = 0; j < 3; j++) {
569                         MLoopUV *luv = BM_ELEM_CD_GET_VOID_P(em->looptris[i][j], cd_loop_uv_offset);
570                         immVertex2fv(pos, luv->uv);
571                 }
572                 i++;
573         } while (i != em->tottri && (f == em->looptris[i][0]->f));
574         *r_loop_index = i - 1;
575 }
576
577 /* draws uv's in the image space */
578 static void draw_uvs(SpaceImage *sima, Scene *scene, ViewLayer *view_layer, Object *obedit, Depsgraph *depsgraph)
579 {
580         ToolSettings *ts;
581         Mesh *me = obedit->data;
582         BMEditMesh *em = me->edit_btmesh;
583         BMesh *bm = em->bm;
584         BMFace *efa, *efa_act;
585         BMLoop *l;
586         BMIter iter, liter;
587         MLoopUV *luv;
588         float col1[4], col2[4];
589         float pointsize;
590         int drawfaces, interpedges;
591         Image *ima = sima->image;
592
593         const int cd_loop_uv_offset  = CustomData_get_offset(&bm->ldata, CD_MLOOPUV);
594
595         unsigned int pos, color;
596
597         efa_act = EDBM_uv_active_face_get(em, false, false); /* will be set to NULL if hidden */
598         ts = scene->toolsettings;
599
600         drawfaces = draw_uvs_face_check(scene);
601         if (ts->uv_flag & UV_SYNC_SELECTION)
602                 interpedges = (ts->selectmode & SCE_SELECT_VERTEX);
603         else
604                 interpedges = (ts->uv_selectmode == UV_SELECT_VERTEX);
605
606         /* draw other uvs */
607         if (sima->flag & SI_DRAW_OTHER) {
608                 Image *curimage;
609
610                 if (efa_act) {
611                         ED_object_get_active_image(obedit, efa_act->mat_nr + 1, &curimage, NULL, NULL, NULL);
612                 }
613                 else {
614                         curimage = ima;
615                 }
616
617                 draw_uvs_other(view_layer, obedit, curimage, sima->other_uv_filter);
618         }
619
620         /* 1. draw shadow mesh */
621
622         if (sima->flag & SI_DRAWSHADOW) {
623                 Object *ob_cage_eval = DEG_get_evaluated_object(depsgraph, obedit);
624                 /* XXX TODO: Need to check if shadow mesh is different than original mesh. */
625                 bool is_cage_like_final_meshes = (ob_cage_eval == obedit);
626
627                 /* When sync selection is enabled, all faces are drawn (except for hidden)
628                  * so if cage is the same as the final, there is no point in drawing this. */
629                 if (((ts->uv_flag & UV_SYNC_SELECTION) == 0) || is_cage_like_final_meshes) {
630                         draw_uvs_shadow(ob_cage_eval);
631                 }
632         }
633
634         /* 2. draw colored faces */
635
636         if (sima->flag & SI_DRAW_STRETCH) {
637                 draw_uvs_stretch(sima, scene, obedit, em, efa_act);
638         }
639         else {
640                 unsigned int tri_count = 0;
641                 BM_ITER_MESH(efa, &iter, bm, BM_FACES_OF_MESH) {
642                         if (uvedit_face_visible_test(scene, obedit, ima, efa)) {
643                                 BM_elem_flag_enable(efa, BM_ELEM_TAG);
644                                 tri_count += efa->len - 2;
645                         }
646                         else {
647                                 BM_elem_flag_disable(efa, BM_ELEM_TAG);
648                         }
649                 }
650
651                 if (tri_count && !(sima->flag & SI_NO_DRAWFACES)) {
652                         /* draw transparent faces */
653                         UI_GetThemeColor4fv(TH_FACE, col1);
654                         UI_GetThemeColor4fv(TH_FACE_SELECT, col2);
655                         glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
656                         glEnable(GL_BLEND);
657
658                         Gwn_VertFormat *format = immVertexFormat();
659                         pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
660                         color = GWN_vertformat_attr_add(format, "color", GWN_COMP_F32, 4, GWN_FETCH_FLOAT);
661
662                         immBindBuiltinProgram(GPU_SHADER_2D_FLAT_COLOR);
663
664                         Gwn_Batch *face_batch = immBeginBatch(GWN_PRIM_TRIS, tri_count * 3);
665                         for (unsigned int i = 0; i < em->tottri; i++) {
666                                 efa = em->looptris[i][0]->f;
667                                 if (BM_elem_flag_test(efa, BM_ELEM_TAG)) {
668                                         const bool is_select = uvedit_face_select_test(scene, efa, cd_loop_uv_offset);
669
670                                         if (efa == efa_act) {
671                                                 /* only once */
672                                                 float tmp_col[4];
673                                                 UI_GetThemeColor4fv(TH_EDITMESH_ACTIVE, tmp_col);
674                                                 immAttrib4fv(color, tmp_col);
675                                         }
676                                         else {
677                                                 immAttrib4fv(color, is_select ? col2 : col1);
678                                         }
679
680                                         draw_uvs_looptri(em, &i, cd_loop_uv_offset, pos);
681                                 }
682                         }
683                         immEnd();
684
685                         /* XXX performance: we should not create and throw away result. */
686                         GWN_batch_draw(face_batch);
687                         GWN_batch_program_use_end(face_batch);
688                         GWN_batch_discard(face_batch);
689
690                         immUnbindProgram();
691
692                         glDisable(GL_BLEND);
693                 }
694                 else {
695                         if (efa_act && !uvedit_face_visible_test(scene, obedit, ima, efa_act)) {
696                                 efa_act = NULL;
697                         }
698                 }
699         }
700
701         /* 3. draw active face stippled */
702         /* (removed during OpenGL upgrade, reimplement if needed) */
703
704         /* 4. draw edges */
705
706         if (sima->flag & SI_SMOOTH_UV) {
707                 glEnable(GL_LINE_SMOOTH);
708                 glEnable(GL_BLEND);
709                 glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
710         }
711
712         pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
713
714         switch (sima->dt_uv) {
715                 case SI_UVDT_DASH:
716                 {
717                         immBindBuiltinProgram(GPU_SHADER_2D_LINE_DASHED_UNIFORM_COLOR);
718
719                         float viewport_size[4];
720                         glGetFloatv(GL_VIEWPORT, viewport_size);
721                         immUniform2f("viewport_size", viewport_size[2] / UI_DPI_FAC, viewport_size[3] / UI_DPI_FAC);
722
723                         immUniform1i("num_colors", 2);  /* "advanced" mode */
724                         immUniformArray4fv("colors", (float *)(float[][4]){{0.56f, 0.56f, 0.56f, 1.0f}, {0.07f, 0.07f, 0.07f, 1.0f}}, 2);
725                         immUniform1f("dash_width", 4.0f);
726                         glLineWidth(1.0f);
727
728                         break;
729                 }
730                 case SI_UVDT_BLACK: /* black/white */
731                 case SI_UVDT_WHITE:
732                         immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
733                         if (sima->dt_uv == SI_UVDT_WHITE) {
734                                 immUniformColor3f(1.0f, 1.0f, 1.0f);
735                         }
736                         else {
737                                 immUniformColor3f(0.0f, 0.0f, 0.0f);
738                         }
739                         glLineWidth(1.0f);
740
741                         break;
742                 case SI_UVDT_OUTLINE:
743                         immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
744                         imm_cpack(0x0);
745                         glLineWidth(3.0f);
746
747                         break;
748         }
749
750         /* For more efficiency first transfer the entire buffer to vram. */
751         Gwn_Batch *loop_batch = immBeginBatchAtMost(GWN_PRIM_LINE_LOOP, bm->totloop);
752         Gwn_VertBuf *loop_vbo = loop_batch->verts[0];
753         BM_ITER_MESH(efa, &iter, bm, BM_FACES_OF_MESH) {
754                 if (!BM_elem_flag_test(efa, BM_ELEM_TAG))
755                         continue;
756
757                 BM_ITER_ELEM(l, &liter, efa, BM_LOOPS_OF_FACE) {
758                         luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
759                         immVertex2fv(pos, luv->uv);
760                 }
761         }
762         immEnd();
763
764         /* Then draw each face contour separately. */
765         if (loop_vbo->vertex_ct != 0) {
766                 GWN_batch_program_use_begin(loop_batch);
767                 unsigned int index = 0, loop_vbo_count;
768                 BM_ITER_MESH(efa, &iter, bm, BM_FACES_OF_MESH) {
769                         if (!BM_elem_flag_test(efa, BM_ELEM_TAG))
770                                 continue;
771
772                         GWN_batch_draw_range_ex(loop_batch, index, efa->len, false);
773                         index += efa->len;
774                 }
775                 loop_vbo_count = index;
776                 GWN_batch_program_use_end(loop_batch);
777                 immUnbindProgram();
778
779
780                 if (sima->dt_uv == SI_UVDT_OUTLINE) {
781                         glLineWidth(1.0f);
782                         UI_GetThemeColor4fv(TH_WIRE_EDIT, col2);
783
784                         if (me->drawflag & ME_DRAWEDGES) {
785                                 int sel;
786                                 UI_GetThemeColor4fv(TH_EDGE_SELECT, col1);
787
788                                 if (interpedges) {
789                                         /* Create a color buffer. */
790                                         static Gwn_VertFormat format = { 0 };
791                                         static uint shdr_col;
792                                         if (format.attrib_ct == 0) {
793                                                 shdr_col = GWN_vertformat_attr_add(&format, "color", GWN_COMP_F32, 4, GWN_FETCH_FLOAT);
794                                         }
795
796                                         Gwn_VertBuf *vbo_col = GWN_vertbuf_create_with_format(&format);
797                                         GWN_vertbuf_data_alloc(vbo_col, loop_vbo_count);
798
799                                         index = 0;
800                                         BM_ITER_MESH(efa, &iter, bm, BM_FACES_OF_MESH) {
801                                                 if (!BM_elem_flag_test(efa, BM_ELEM_TAG))
802                                                         continue;
803
804                                                 BM_ITER_ELEM(l, &liter, efa, BM_LOOPS_OF_FACE) {
805                                                         sel = uvedit_uv_select_test(scene, l, cd_loop_uv_offset);
806                                                         GWN_vertbuf_attr_set(vbo_col, shdr_col, index++, sel ? col1 : col2);
807                                                 }
808                                         }
809                                         /* Reuse the UV buffer and add the color buffer. */
810                                         GWN_batch_vertbuf_add_ex(loop_batch, vbo_col, true);
811
812                                         /* Now draw each face contour separately with another builtin program. */
813                                         GWN_batch_program_set_builtin(loop_batch, GPU_SHADER_2D_SMOOTH_COLOR);
814                                         gpuBindMatrices(loop_batch->interface);
815
816                                         GWN_batch_program_use_begin(loop_batch);
817                                         index = 0;
818                                         BM_ITER_MESH(efa, &iter, bm, BM_FACES_OF_MESH) {
819                                                 if (!BM_elem_flag_test(efa, BM_ELEM_TAG))
820                                                         continue;
821
822                                                 GWN_batch_draw_range_ex(loop_batch, index, efa->len, false);
823                                                 index += efa->len;
824                                         }
825                                         GWN_batch_program_use_end(loop_batch);
826                                 }
827                                 else {
828                                         Gwn_VertFormat *format = immVertexFormat();
829                                         pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
830                                         color = GWN_vertformat_attr_add(format, "color", GWN_COMP_F32, 4, GWN_FETCH_FLOAT);
831
832                                         immBindBuiltinProgram(GPU_SHADER_2D_FLAT_COLOR);
833
834                                         /* Use batch here to avoid problems with `IMM_BUFFER_SIZE`. */
835                                         Gwn_Batch *flat_edges_batch = immBeginBatchAtMost(GWN_PRIM_LINES, loop_vbo_count * 2);
836                                         BM_ITER_MESH(efa, &iter, bm, BM_FACES_OF_MESH) {
837                                                 if (!BM_elem_flag_test(efa, BM_ELEM_TAG))
838                                                         continue;
839
840                                                 BM_ITER_ELEM(l, &liter, efa, BM_LOOPS_OF_FACE) {
841                                                         sel = uvedit_edge_select_test(scene, l, cd_loop_uv_offset);
842                                                         immAttrib4fv(color, sel ? col1 : col2);
843
844                                                         luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
845                                                         immVertex2fv(pos, luv->uv);
846                                                         luv = BM_ELEM_CD_GET_VOID_P(l->next, cd_loop_uv_offset);
847                                                         immVertex2fv(pos, luv->uv);
848                                                 }
849                                         }
850                                         immEnd();
851
852                                         GWN_batch_draw(flat_edges_batch);
853                                         GWN_batch_discard(flat_edges_batch);
854
855                                         immUnbindProgram();
856                                 }
857                         }
858                         else {
859                                 GWN_batch_uniform_4fv(loop_batch, "color", col2);
860                                 immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
861
862                                 /* no nice edges */
863                                 GWN_batch_program_use_begin(loop_batch);
864                                 index = 0;
865                                 BM_ITER_MESH(efa, &iter, bm, BM_FACES_OF_MESH) {
866                                         if (!BM_elem_flag_test(efa, BM_ELEM_TAG))
867                                                 continue;
868
869                                         GWN_batch_draw_range_ex(loop_batch, index, efa->len, false);
870                                         index += efa->len;
871                                 }
872                                 GWN_batch_program_use_end(loop_batch);
873                                 immUnbindProgram();
874                         }
875                 }
876         }
877         else {
878                 immUnbindProgram();
879         }
880
881         GWN_batch_discard(loop_batch);
882
883         if (sima->flag & SI_SMOOTH_UV) {
884                 glDisable(GL_LINE_SMOOTH);
885                 glDisable(GL_BLEND);
886         }
887
888         /* 5. draw face centers */
889
890         if (drawfaces) {
891                 float cent[2];
892                 bool col_set = false;
893
894                 Gwn_VertFormat *format = immVertexFormat();
895                 pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
896                 color = GWN_vertformat_attr_add(format, "color", GWN_COMP_F32, 3, GWN_FETCH_FLOAT);
897
898                 immBindBuiltinProgram(GPU_SHADER_2D_FLAT_COLOR);
899
900                 pointsize = UI_GetThemeValuef(TH_FACEDOT_SIZE);
901                 glPointSize(pointsize);
902
903                 immBeginAtMost(GWN_PRIM_POINTS, bm->totface);
904
905                 /* unselected faces */
906
907                 BM_ITER_MESH (efa, &iter, bm, BM_FACES_OF_MESH) {
908                         if (!BM_elem_flag_test(efa, BM_ELEM_TAG))
909                                 continue;
910
911                         if (!uvedit_face_select_test(scene, efa, cd_loop_uv_offset)) {
912                                 /* Only set color for the first face */
913                                 if (!col_set) {
914                                         UI_GetThemeColor3fv(TH_WIRE, col1);
915                                         immAttrib3fv(color, col1);
916
917                                         col_set = true;
918                                 }
919
920                                 uv_poly_center(efa, cent, cd_loop_uv_offset);
921                                 immVertex2fv(pos, cent);
922                         }
923                 }
924
925                 col_set = false;
926
927                 /* selected faces */
928
929                 BM_ITER_MESH (efa, &iter, bm, BM_FACES_OF_MESH) {
930                         if (!BM_elem_flag_test(efa, BM_ELEM_TAG))
931                                 continue;
932
933                         if (uvedit_face_select_test(scene, efa, cd_loop_uv_offset)) {
934                                 /* Only set color for the first face */
935                                 if (!col_set) {
936                                         UI_GetThemeColor3fv(TH_FACE_DOT, col1);
937                                         immAttrib3fv(color, col1);
938
939                                         col_set = true;
940                                 }
941
942                                 uv_poly_center(efa, cent, cd_loop_uv_offset);
943                                 immVertex2fv(pos, cent);
944                         }
945                 }
946
947                 immEnd();
948
949                 immUnbindProgram();
950         }
951
952         /* 6. draw uv vertices */
953
954         if (drawfaces != 2) { /* 2 means Mesh Face Mode */
955                 pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
956
957                 immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
958
959                 /* unselected uvs */
960                 immUniformThemeColor(TH_VERTEX);
961                 pointsize = UI_GetThemeValuef(TH_VERTEX_SIZE);
962                 glPointSize(pointsize);
963
964                 immBeginAtMost(GWN_PRIM_POINTS, bm->totloop);
965
966                 BM_ITER_MESH (efa, &iter, bm, BM_FACES_OF_MESH) {
967                         if (!BM_elem_flag_test(efa, BM_ELEM_TAG))
968                                 continue;
969
970                         BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
971                                 luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
972                                 if (!uvedit_uv_select_test(scene, l, cd_loop_uv_offset))
973                                         immVertex2fv(pos, luv->uv);
974                         }
975                 }
976
977                 immEnd();
978
979                 /* pinned uvs */
980                 /* give odd pointsizes odd pin pointsizes */
981                 glPointSize(pointsize * 2 + (((int)pointsize % 2) ? (-1) : 0));
982                 imm_cpack(0xFF);
983
984                 immBeginAtMost(GWN_PRIM_POINTS, bm->totloop);
985
986                 BM_ITER_MESH (efa, &iter, bm, BM_FACES_OF_MESH) {
987                         if (!BM_elem_flag_test(efa, BM_ELEM_TAG))
988                                 continue;
989
990                         BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
991                                 luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
992
993                                 if (luv->flag & MLOOPUV_PINNED)
994                                         immVertex2fv(pos, luv->uv);
995                         }
996                 }
997
998                 immEnd();
999
1000                 /* selected uvs */
1001                 immUniformThemeColor(TH_VERTEX_SELECT);
1002                 glPointSize(pointsize);
1003
1004                 immBeginAtMost(GWN_PRIM_POINTS, bm->totloop);
1005
1006                 BM_ITER_MESH (efa, &iter, bm, BM_FACES_OF_MESH) {
1007                         if (!BM_elem_flag_test(efa, BM_ELEM_TAG))
1008                                 continue;
1009
1010                         BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
1011                                 luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
1012
1013                                 if (uvedit_uv_select_test(scene, l, cd_loop_uv_offset))
1014                                         immVertex2fv(pos, luv->uv);
1015                         }
1016                 }
1017
1018                 immEnd();
1019
1020                 immUnbindProgram();
1021         }
1022 }
1023
1024
1025 static void draw_uv_shadows_get(
1026         SpaceImage *sima, Object *ob, Object *obedit,
1027         bool *show_shadow, bool *show_texpaint)
1028 {
1029         *show_shadow = *show_texpaint = false;
1030
1031         if (ED_space_image_show_render(sima) || (sima->flag & SI_NO_DRAW_TEXPAINT))
1032                 return;
1033
1034         if ((sima->mode == SI_MODE_PAINT) && obedit && obedit->type == OB_MESH) {
1035                 struct BMEditMesh *em = BKE_editmesh_from_object(obedit);
1036
1037                 *show_shadow = EDBM_uv_check(em);
1038         }
1039
1040         *show_texpaint = (ob && ob->type == OB_MESH && ob->mode == OB_MODE_TEXTURE_PAINT);
1041 }
1042
1043 void ED_uvedit_draw_main(
1044         SpaceImage *sima,
1045         ARegion *ar, Scene *scene, ViewLayer *view_layer, Object *obedit, Object *obact, Depsgraph *depsgraph)
1046 {
1047         ToolSettings *toolsettings = scene->toolsettings;
1048         bool show_uvedit, show_uvshadow, show_texpaint_uvshadow;
1049
1050         show_uvedit = ED_space_image_show_uvedit(sima, obedit);
1051         draw_uv_shadows_get(sima, obact, obedit, &show_uvshadow, &show_texpaint_uvshadow);
1052
1053         if (show_uvedit || show_uvshadow || show_texpaint_uvshadow) {
1054                 if (show_uvshadow) {
1055                         draw_uvs_shadow(obedit);
1056                 }
1057                 else if (show_uvedit) {
1058                         uint objects_len = 0;
1059                         Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data_with_uvs(view_layer, &objects_len);
1060                         for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
1061                                 Object *ob_iter = objects[ob_index];
1062                                 draw_uvs(sima, scene, view_layer, ob_iter, depsgraph);
1063                         }
1064                         MEM_freeN(objects);
1065                 }
1066                 else {
1067                         draw_uvs_texpaint(sima, scene, view_layer, obact);
1068                 }
1069
1070                 if (show_uvedit && !(toolsettings->use_uv_sculpt))
1071                         ED_image_draw_cursor(ar, sima->cursor);
1072         }
1073 }
1074