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