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