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