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