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