=bmesh= merge from trunk at r36529
[blender.git] / source / blender / editors / uvedit / uvedit_draw.c
1 /*
2  * $Id$
3  *
4  * ***** BEGIN GPL LICENSE BLOCK *****
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License
8  * as published by the Free Software Foundation; either version 2
9  * of the License, or (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software Foundation,
18  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19  *
20  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
21  * All rights reserved.
22  *
23  * Contributor(s): Blender Foundation, 2002-2009
24  *
25  * ***** END GPL LICENSE BLOCK *****
26  */
27
28 /** \file blender/editors/uvedit/uvedit_draw.c
29  *  \ingroup eduv
30  */
31
32
33 #include <float.h>
34 #include <math.h>
35 #include <stdlib.h>
36 #include <string.h>
37
38 #include "MEM_guardedalloc.h"
39
40 #include "DNA_mesh_types.h"
41 #include "DNA_meshdata_types.h"
42 #include "DNA_object_types.h"
43 #include "DNA_scene_types.h"
44 #include "DNA_screen_types.h"
45 #include "DNA_space_types.h"
46
47 #include "BLI_math.h"
48 #include "BLI_editVert.h"
49 #include "BLI_utildefines.h"
50
51 #include "BKE_DerivedMesh.h"
52 #include "BKE_mesh.h"
53 #include "BKE_tessmesh.h"
54
55 #include "BLI_array.h"
56
57 #include "BIF_gl.h"
58 #include "BIF_glutil.h"
59
60 #include "ED_util.h"
61 #include "ED_image.h"
62 #include "ED_mesh.h"
63 #include "ED_uvedit.h"
64
65 #include "UI_resources.h"
66
67 #include "uvedit_intern.h"
68
69 static void drawcursor_sima(SpaceImage *sima, ARegion *ar)
70 {
71         float zoomx, zoomy, w, h;
72         int width, height;
73
74         ED_space_image_size(sima, &width, &height);
75         ED_space_image_zoom(sima, ar, &zoomx, &zoomy);
76
77         w= zoomx*width/256.0f;
78         h= zoomy*height/256.0f;
79         
80         cpack(0xFFFFFF);
81         glTranslatef(sima->cursor[0], sima->cursor[1], 0.0);
82         fdrawline(-0.05f/w, 0, 0, 0.05f/h);
83         fdrawline(0, 0.05f/h, 0.05f/w, 0.0f);
84         fdrawline(0.05f/w, 0.0f, 0.0f, -0.05f/h);
85         fdrawline(0.0f, -0.05f/h, -0.05f/w, 0.0f);
86
87         setlinestyle(4);
88         cpack(0xFF);
89         fdrawline(-0.05f/w, 0.0f, 0.0f, 0.05f/h);
90         fdrawline(0.0f, 0.05f/h, 0.05f/w, 0.0f);
91         fdrawline(0.05f/w, 0.0f, 0.0f, -0.05f/h);
92         fdrawline(0.0f, -0.05f/h, -0.05f/w, 0.0f);
93
94
95         setlinestyle(0.0f);
96         cpack(0x0);
97         fdrawline(-0.020f/w, 0.0f, -0.1f/w, 0.0f);
98         fdrawline(0.1f/w, 0.0f, 0.020f/w, 0.0f);
99         fdrawline(0.0f, -0.020f/h, 0.0f, -0.1f/h);
100         fdrawline(0.0f, 0.1f/h, 0.0f, 0.020f/h);
101
102         setlinestyle(1);
103         cpack(0xFFFFFF);
104         fdrawline(-0.020f/w, 0.0f, -0.1f/w, 0.0f);
105         fdrawline(0.1f/w, 0.0f, 0.020f/w, 0.0f);
106         fdrawline(0.0f, -0.020f/h, 0.0f, -0.1f/h);
107         fdrawline(0.0f, 0.1f/h, 0.0f, 0.020f/h);
108
109         glTranslatef(-sima->cursor[0], -sima->cursor[1], 0.0);
110         setlinestyle(0);
111 }
112
113 static int draw_uvs_face_check(Scene *scene)
114 {
115         ToolSettings *ts= scene->toolsettings;
116
117         /* checks if we are selecting only faces */
118         if(ts->uv_flag & UV_SYNC_SELECTION) {
119                 if(ts->selectmode == SCE_SELECT_FACE)
120                         return 2;
121                 else if(ts->selectmode & SCE_SELECT_FACE)
122                         return 1;
123                 else
124                         return 0;
125         }
126         else
127                 return (ts->uv_selectmode == UV_SELECT_FACE);
128 }
129
130 static void draw_uvs_shadow(Object *obedit)
131 {
132         BMEditMesh *em;
133         BMFace *efa;
134         BMLoop *l;
135         BMIter iter, liter;
136         MLoopUV *luv;
137         
138         em= ((Mesh*)obedit->data)->edit_btmesh;
139
140         /* draws the grey mesh when painting */
141         glColor3ub(112, 112, 112);
142
143         BM_ITER(efa, &iter, em->bm, BM_FACES_OF_MESH, NULL) {
144                 glBegin(GL_LINE_LOOP);
145                 BM_ITER(l, &liter, em->bm, BM_LOOPS_OF_FACE, efa) {
146                         luv= CustomData_bmesh_get(&em->bm->ldata, l->head.data, CD_MLOOPUV);
147
148                         glVertex2fv(luv->uv);
149                 }
150                 glEnd();
151         }
152 }
153
154 static int draw_uvs_dm_shadow(DerivedMesh *dm)
155 {
156         /* draw shadow mesh - this is the mesh with the modifier applied */
157
158         if(dm && dm->drawUVEdges && CustomData_has_layer(&dm->loopData, CD_MLOOPUV)) {
159                 glColor3ub(112, 112, 112);
160                 dm->drawUVEdges(dm);
161                 return 1;
162         }
163
164         return 0;
165 }
166
167 static void draw_uvs_stretch(SpaceImage *sima, Scene *scene, BMEditMesh *em, MTexPoly *activetf)
168 {
169         BMFace *efa;
170         BMLoop *l;
171         BMIter iter, liter;
172         MTexPoly *tf;
173         MLoopUV *luv;
174         Image *ima= sima->image;
175         BLI_array_declare(tf_uv);
176         BLI_array_declare(tf_uvorig);
177         float aspx, aspy, col[4], (*tf_uv)[2] = NULL, (*tf_uvorig)[2] = NULL;
178         int i;
179
180         ED_space_image_uv_aspect(sima, &aspx, &aspy);
181         
182         switch(sima->dt_uvstretch) {
183                 case SI_UVDT_STRETCH_AREA:
184                 {
185                         float totarea=0.0f, totuvarea=0.0f, areadiff, uvarea, area;
186                         
187                         BM_ITER(efa, &iter, em->bm, BM_FACES_OF_MESH, NULL) {
188                                 tf= CustomData_bmesh_get(&em->bm->pdata, efa->head.data, CD_MTEXPOLY);
189                                 
190                                 BLI_array_empty(tf_uv);
191                                 BLI_array_empty(tf_uvorig);
192                                 
193                                 i = 0;
194                                 BM_ITER(l, &liter, em->bm, BM_LOOPS_OF_FACE, efa) {
195                                         luv= CustomData_bmesh_get(&em->bm->ldata, l->head.data, CD_MLOOPUV);
196                                         BLI_array_growone(tf_uv);
197                                         BLI_array_growone(tf_uvorig);
198
199                                         tf_uvorig[i][0] = luv->uv[0];
200                                         tf_uvorig[i][1] = luv->uv[1];
201
202                                         i++;
203                                 }
204
205                                 poly_copy_aspect(tf_uvorig, tf_uv, aspx, aspy, efa->len);
206
207                                 totarea += BM_face_area(efa);
208                                 //totuvarea += tf_area(tf, efa->v4!=0);
209                                 totuvarea += poly_uv_area(tf_uv, efa->len);
210                                 
211                                 if(uvedit_face_visible(scene, ima, efa, tf)) {
212                                         BMINDEX_SET(efa, 1);
213                                 }
214                                 else {
215                                         if(tf == activetf)
216                                                 activetf= NULL;
217                                         BMINDEX_SET(efa, 0);
218                                 }
219                         }
220                         
221                         if(totarea < FLT_EPSILON || totuvarea < FLT_EPSILON) {
222                                 col[0] = 1.0;
223                                 col[1] = col[2] = 0.0;
224                                 glColor3fv(col);
225                                 BM_ITER(efa, &iter, em->bm, BM_FACES_OF_MESH, NULL) {
226                                         if(BMINDEX_GET(efa)) {
227                                                 glBegin(GL_POLYGON);
228                                                 BM_ITER(l, &liter, em->bm, BM_LOOPS_OF_FACE, efa) {
229                                                         luv = CustomData_bmesh_get(&em->bm->ldata, l->head.data, CD_MLOOPUV);
230                                                         glVertex2fv(luv->uv);
231                                                 }
232                                                 glEnd();
233                                         }
234                                 }
235                         }
236                         else {
237                                 BM_ITER(efa, &iter, em->bm, BM_FACES_OF_MESH, NULL) {
238                                         if(BMINDEX_GET(efa)) {
239                                                 area = BM_face_area(efa) / totarea;
240
241                                                 BLI_array_empty(tf_uv);
242                                                 BLI_array_empty(tf_uvorig);
243
244                                                 i = 0;
245                                                 BM_ITER(l, &liter, em->bm, BM_LOOPS_OF_FACE, efa) {
246                                                         luv= CustomData_bmesh_get(&em->bm->ldata, l->head.data, CD_MLOOPUV);
247                                                         BLI_array_growone(tf_uv);
248                                                         BLI_array_growone(tf_uvorig);
249
250                                                         tf_uvorig[i][0] = luv->uv[0];
251                                                         tf_uvorig[i][1] = luv->uv[1];
252
253                                                         i++;
254                                                 }
255
256                                                 poly_copy_aspect(tf_uvorig, tf_uv, aspx, aspy, efa->len);
257
258                                                 //uvarea = tf_area(tf, efa->v4!=0) / totuvarea;
259                                                 uvarea = poly_uv_area(tf_uv, efa->len) / totuvarea;
260                                                 
261                                                 if(area < FLT_EPSILON || uvarea < FLT_EPSILON)
262                                                         areadiff = 1.0f;
263                                                 else if(area>uvarea)
264                                                         areadiff = 1.0f-(uvarea/area);
265                                                 else
266                                                         areadiff = 1.0f-(area/uvarea);
267                                                 
268                                                 weight_to_rgb(areadiff, col, col+1, col+2);
269                                                 glColor3fv(col);
270                                                 
271                                                 glBegin(GL_POLYGON);
272                                                 BM_ITER(l, &liter, em->bm, BM_LOOPS_OF_FACE, efa) {
273                                                         luv = CustomData_bmesh_get(&em->bm->ldata, l->head.data, CD_MLOOPUV);
274                                                         glVertex2fv(luv->uv);
275                                                 }
276                                                 glEnd();
277                                         }
278                                 }
279                         }
280                         break;
281                 }
282                 case SI_UVDT_STRETCH_ANGLE:
283                 {
284 #if 0 //BMESH_TODO
285                         float uvang1,uvang2,uvang3,uvang4;
286                         float ang1,ang2,ang3,ang4;
287                         float av1[3], av2[3], av3[3], av4[3]; /* use for 2d and 3d  angle vectors */
288                         float a;
289                         
290                         col[3] = 0.5; /* hard coded alpha, not that nice */
291                         
292                         glShadeModel(GL_SMOOTH);
293                         
294                         for(efa= em->faces.first; efa; efa= efa->next) {
295                                 tf= CustomData_em_get(&em->fdata, efa->head.data, CD_MTFACE);
296                                 
297                                 if(uvedit_face_visible(scene, ima, efa, tf)) {
298                                         efa->tmp.p = tf;
299                                         uv_copy_aspect(tf->uv, tf_uv, aspx, aspy);
300                                         if(efa->v4) {
301                                                 
302 #if 0                                           /* Simple but slow, better reuse normalized vectors */
303                                                 uvang1 = RAD2DEG(angle_v2v2v2(tf_uv[3], tf_uv[0], tf_uv[1]));
304                                                 ang1 = RAD2DEG(angle_v3v3v3(efa->v4->co, efa->v1->co, efa->v2->co));
305                                                 
306                                                 uvang2 = RAD2DEG(angle_v2v2v2(tf_uv[0], tf_uv[1], tf_uv[2]));
307                                                 ang2 = RAD2DEG(angle_v3v3v3(efa->v1->co, efa->v2->co, efa->v3->co));
308                                                 
309                                                 uvang3 = RAD2DEG(angle_v2v2v2(tf_uv[1], tf_uv[2], tf_uv[3]));
310                                                 ang3 = RAD2DEG(angle_v3v3v3(efa->v2->co, efa->v3->co, efa->v4->co));
311                                                 
312                                                 uvang4 = RAD2DEG(angle_v2v2v2(tf_uv[2], tf_uv[3], tf_uv[0]));
313                                                 ang4 = RAD2DEG(angle_v3v3v3(efa->v3->co, efa->v4->co, efa->v1->co));
314 #endif
315                                                 
316                                                 /* uv angles */
317                                                 VECSUB2D(av1, tf_uv[3], tf_uv[0]); normalize_v2(av1);
318                                                 VECSUB2D(av2, tf_uv[0], tf_uv[1]); normalize_v2(av2);
319                                                 VECSUB2D(av3, tf_uv[1], tf_uv[2]); normalize_v2(av3);
320                                                 VECSUB2D(av4, tf_uv[2], tf_uv[3]); normalize_v2(av4);
321                                                 
322                                                 /* This is the correct angle however we are only comparing angles
323                                                  * uvang1 = 90-((angle_normalized_v2v2(av1, av2) * 180.0/M_PI)-90);*/
324                                                 uvang1 = angle_normalized_v2v2(av1, av2);
325                                                 uvang2 = angle_normalized_v2v2(av2, av3);
326                                                 uvang3 = angle_normalized_v2v2(av3, av4);
327                                                 uvang4 = angle_normalized_v2v2(av4, av1);
328                                                 
329                                                 /* 3d angles */
330                                                 VECSUB(av1, efa->v4->co, efa->v1->co); normalize_v3(av1);
331                                                 VECSUB(av2, efa->v1->co, efa->v2->co); normalize_v3(av2);
332                                                 VECSUB(av3, efa->v2->co, efa->v3->co); normalize_v3(av3);
333                                                 VECSUB(av4, efa->v3->co, efa->v4->co); normalize_v3(av4);
334                                                 
335                                                 /* This is the correct angle however we are only comparing angles
336                                                  * ang1 = 90-((angle_normalized_v3v3(av1, av2) * 180.0/M_PI)-90);*/
337                                                 ang1 = angle_normalized_v3v3(av1, av2);
338                                                 ang2 = angle_normalized_v3v3(av2, av3);
339                                                 ang3 = angle_normalized_v3v3(av3, av4);
340                                                 ang4 = angle_normalized_v3v3(av4, av1);
341                                                 
342                                                 glBegin(GL_QUADS);
343                                                 
344                                                 /* This simple makes the angles display worse then they really are ;)
345                                                  * 1.0-powf((1.0-a), 2) */
346                                                 
347                                                 a = fabsf(uvang1-ang1)/(float)M_PI;
348                                                 weight_to_rgb(1.0f-powf((1.0f-a), 2.0f), col, col+1, col+2);
349                                                 glColor3fv(col);
350                                                 glVertex2fv(tf->uv[0]);
351                                                 a = fabsf(uvang2-ang2)/(float)M_PI;
352                                                 weight_to_rgb(1.0f-powf((1.0f-a), 2.0f), col, col+1, col+2);
353                                                 glColor3fv(col);
354                                                 glVertex2fv(tf->uv[1]);
355                                                 a = fabsf(uvang3-ang3)/(float)M_PI;
356                                                 weight_to_rgb(1.0f-powf((1.0f-a), 2.0f), col, col+1, col+2);
357                                                 glColor3fv(col);
358                                                 glVertex2fv(tf->uv[2]);
359                                                 a = fabsf(uvang4-ang4)/(float)M_PI;
360                                                 weight_to_rgb(1.0f-powf((1.0f-a), 2.0f), col, col+1, col+2);
361                                                 glColor3fv(col);
362                                                 glVertex2fv(tf->uv[3]);
363                                                 
364                                         }
365                                         else {
366 #if 0                                           /* Simple but slow, better reuse normalized vectors */
367                                                 uvang1 = RAD2DEG(angle_v2v2v2(tf_uv[2], tf_uv[0], tf_uv[1]));
368                                                 ang1 = RAD2DEG(angle_v3v3v3(efa->v3->co, efa->v1->co, efa->v2->co));
369                                                 
370                                                 uvang2 = RAD2DEG(angle_v2v2v2(tf_uv[0], tf_uv[1], tf_uv[2]));
371                                                 ang2 = RAD2DEG(angle_v3v3v3(efa->v1->co, efa->v2->co, efa->v3->co));
372                                                 
373                                                 uvang3 = M_PI-(uvang1+uvang2);
374                                                 ang3 = M_PI-(ang1+ang2);
375 #endif                                          
376                                                 
377                                                 /* uv angles */
378                                                 VECSUB2D(av1, tf_uv[2], tf_uv[0]); normalize_v2(av1);
379                                                 VECSUB2D(av2, tf_uv[0], tf_uv[1]); normalize_v2(av2);
380                                                 VECSUB2D(av3, tf_uv[1], tf_uv[2]); normalize_v2(av3);
381                                                 
382                                                 /* This is the correct angle however we are only comparing angles
383                                                  * uvang1 = 90-((angle_normalized_v2v2(av1, av2) * 180.0/M_PI)-90); */
384                                                 uvang1 = angle_normalized_v2v2(av1, av2);
385                                                 uvang2 = angle_normalized_v2v2(av2, av3);
386                                                 uvang3 = angle_normalized_v2v2(av3, av1);
387                                                 
388                                                 /* 3d angles */
389                                                 VECSUB(av1, efa->v3->co, efa->v1->co); normalize_v3(av1);
390                                                 VECSUB(av2, efa->v1->co, efa->v2->co); normalize_v3(av2);
391                                                 VECSUB(av3, efa->v2->co, efa->v3->co); normalize_v3(av3);
392                                                 /* This is the correct angle however we are only comparing angles
393                                                  * ang1 = 90-((angle_normalized_v3v3(av1, av2) * 180.0/M_PI)-90); */
394                                                 ang1 = angle_normalized_v3v3(av1, av2);
395                                                 ang2 = angle_normalized_v3v3(av2, av3);
396                                                 ang3 = angle_normalized_v3v3(av3, av1);
397                                                 
398                                                 /* This simple makes the angles display worse then they really are ;)
399                                                  * 1.0f-powf((1.0-a), 2) */
400                                                 
401                                                 glBegin(GL_TRIANGLES);
402                                                 a = fabsf(uvang1-ang1)/(float)M_PI;
403                                                 weight_to_rgb(1.0f-powf((1.0f-a), 2.0f), col, col+1, col+2);
404                                                 glColor3fv(col);
405                                                 glVertex2fv(tf->uv[0]);
406                                                 a = fabsf(uvang2-ang2)/(float)M_PI;
407                                                 weight_to_rgb(1.0f-powf((1.0f-a), 2.0f), col, col+1, col+2);
408                                                 glColor3fv(col);
409                                                 glVertex2fv(tf->uv[1]);
410                                                 a = fabsf(uvang3-ang3)/(float)M_PI;
411                                                 weight_to_rgb(1.0f-powf((1.0f-a), 2.0f), col, col+1, col+2);
412                                                 glColor3fv(col);
413                                                 glVertex2fv(tf->uv[2]);
414                                         }
415                                         glEnd();
416                                 }
417                                 else {
418                                         if(tf == activetf)
419                                                 activetf= NULL;
420                                         efa->tmp.p = NULL;
421                                 }
422                         }
423
424                         glShadeModel(GL_FLAT);
425                         break;
426
427 #endif
428                 }
429         }
430 }
431
432 static void draw_uvs_other(Scene *scene, Object *obedit, MTexPoly *activetf)
433 {
434         Base *base;
435         Image *curimage;
436
437         curimage= (activetf)? activetf->tpage: NULL;
438
439         glColor3ub(96, 96, 96);
440
441         for(base=scene->base.first; base; base=base->next) {
442                 Object *ob= base->object;
443
444                 if(!(base->flag & SELECT)) continue;
445                 if(!(base->lay & scene->lay)) continue;
446                 if(ob->restrictflag & OB_RESTRICT_VIEW) continue;
447
448                 if((ob->type==OB_MESH) && (ob!=obedit)) {
449                         Mesh *me= ob->data;
450
451                         if(me->mtface) {
452                                 MPoly *mface= me->mpoly;
453                                 MTexPoly *tface= me->mtpoly;
454                                 MLoopUV *mloopuv;
455                                 int a, b;
456
457                                 for(a=me->totpoly; a>0; a--, tface++, mface++) {
458                                         if(tface->tpage == curimage) {
459                                                 glBegin(GL_LINE_LOOP);
460
461                                                 mloopuv = me->mloopuv + mface->loopstart;
462                                                 for (b=0; b<mface->totloop; b++, mloopuv++) {
463                                                         glVertex2fv(mloopuv->uv);
464                                                 }
465                                                 glEnd();
466                                         }
467                                 }
468                         }
469                 }
470         }
471 }
472
473 /* draws uv's in the image space */
474 static void draw_uvs(SpaceImage *sima, Scene *scene, Object *obedit)
475 {
476         ToolSettings *ts;
477         Mesh *me= obedit->data;
478         BMEditMesh *em;
479         BMFace *efa, *efa_act, *activef;
480         BMLoop *l;
481         BMIter iter, liter;
482         MTexPoly *tf, *activetf = NULL;
483         MLoopUV *luv;
484         DerivedMesh *finaldm, *cagedm;
485         unsigned char col1[4], col2[4];
486         float pointsize;
487         int drawfaces, interpedges;
488         int i;
489         Image *ima= sima->image;
490
491         em= me->edit_btmesh;
492         activetf= EDBM_get_active_mtexpoly(em, &efa_act, 0); /* will be set to NULL if hidden */
493         activef = EDBM_get_actFace(em, 0);
494         ts= scene->toolsettings;
495
496         drawfaces= draw_uvs_face_check(scene);
497         if(ts->uv_flag & UV_SYNC_SELECTION)
498                 interpedges= (ts->selectmode & SCE_SELECT_VERTEX);
499         else
500                 interpedges= (ts->uv_selectmode == UV_SELECT_VERTEX);
501         
502         /* draw other uvs */
503         if(sima->flag & SI_DRAW_OTHER)
504                 draw_uvs_other(scene, obedit, activetf);
505
506         /* 1. draw shadow mesh */
507         
508         if(sima->flag & SI_DRAWSHADOW) {
509                 /* first try existing derivedmesh */
510                 if(!draw_uvs_dm_shadow(em->derivedFinal)) {
511                         /* create one if it does not exist */
512                         cagedm = editbmesh_get_derived_cage_and_final(scene, obedit, me->edit_btmesh, &finaldm, CD_MASK_BAREMESH|CD_MASK_MTFACE);
513
514                         /* when sync selection is enabled, all faces are drawn (except for hidden)
515                          * so if cage is the same as the final, theres no point in drawing this */
516                         if(!((ts->uv_flag & UV_SYNC_SELECTION) && (cagedm == finaldm)))
517                                 draw_uvs_dm_shadow(finaldm);
518                         
519                         /* release derivedmesh again */
520                         if(cagedm != finaldm) cagedm->release(cagedm);
521                         finaldm->release(finaldm);
522                 }
523         }
524         
525         /* 2. draw colored faces */
526         
527         if(sima->flag & SI_DRAW_STRETCH) {
528                 draw_uvs_stretch(sima, scene, em, activetf);
529         }
530         else if(me->drawflag & ME_DRAWFACES) {
531                 /* draw transparent faces */
532                 UI_GetThemeColor4ubv(TH_FACE, col1);
533                 UI_GetThemeColor4ubv(TH_FACE_SELECT, col2);
534                 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
535                 glEnable(GL_BLEND);
536                 
537                 BM_ITER(efa, &iter, em->bm, BM_FACES_OF_MESH, NULL) {
538                         tf= CustomData_bmesh_get(&em->bm->pdata, efa->head.data, CD_MTEXPOLY);
539                         
540                         if(uvedit_face_visible(scene, ima, efa, tf)) {
541                                 BMINDEX_SET(efa, 1);
542                                 if(tf==activetf) continue; /* important the temp boolean is set above */
543
544                                 if(uvedit_face_selected(scene, em, efa))
545                                         glColor4ubv((GLubyte *)col2);
546                                 else
547                                         glColor4ubv((GLubyte *)col1);
548                                 
549                                 glBegin(GL_POLYGON);
550                                 BM_ITER(l, &liter, em->bm, BM_LOOPS_OF_FACE, efa) {
551                                         luv = CustomData_bmesh_get(&em->bm->ldata, l->head.data, CD_MLOOPUV);
552                                         glVertex2fv(luv->uv);
553                                 }
554                                 glEnd();
555                         }
556                         else {
557                                 if(tf == activetf)
558                                         activetf= NULL;
559                                 BMINDEX_SET(efa, 0);
560                         }
561                 }
562                 glDisable(GL_BLEND);
563         }
564         else {
565                 /* would be nice to do this within a draw loop but most below are optional, so it would involve too many checks */
566                 
567                 BM_ITER(efa, &iter, em->bm, BM_FACES_OF_MESH, NULL) {
568                         tf= CustomData_bmesh_get(&em->bm->pdata, efa->head.data, CD_MTEXPOLY);
569
570                         if(uvedit_face_visible(scene, ima, efa, tf)) {          
571                                 BMINDEX_SET(efa, 1);
572                         }
573                         else {
574                                 if(tf == activetf)
575                                         activetf= NULL;
576                                 BMINDEX_SET(efa, 0);
577                         }
578                 }
579                 
580         }
581         
582         /* 3. draw active face stippled */
583
584         if(activef) {
585                 glEnable(GL_BLEND);
586                 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
587                 UI_ThemeColor4(TH_EDITMESH_ACTIVE);
588
589                 glEnable(GL_POLYGON_STIPPLE);
590                 glPolygonStipple(stipple_quarttone);
591
592                 glBegin(GL_POLYGON);
593                 BM_ITER(l, &liter, em->bm, BM_LOOPS_OF_FACE, activef) {
594                         luv = CustomData_bmesh_get(&em->bm->ldata, l->head.data, CD_MLOOPUV);
595                         glVertex2fv(luv->uv);
596                 }
597                 glEnd();
598
599                 glDisable(GL_POLYGON_STIPPLE);
600                 glDisable(GL_BLEND);
601         }
602         
603         /* 4. draw edges */
604
605         if(sima->flag & SI_SMOOTH_UV) {
606                 glEnable(GL_LINE_SMOOTH);
607                 glEnable(GL_BLEND);
608                 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
609         }
610         
611         switch(sima->dt_uv) {
612                 case SI_UVDT_DASH:
613                         BM_ITER(efa, &iter, em->bm, BM_FACES_OF_MESH, NULL) {
614                                 if (!BMINDEX_GET(efa))
615                                         continue;
616                                 tf = CustomData_bmesh_get(&em->bm->pdata, efa->head.data, CD_MTEXPOLY);
617
618                                 if(tf) {
619                                         cpack(0x111111);
620
621                                         glBegin(GL_LINE_LOOP);
622                                         BM_ITER(l, &liter, em->bm, BM_LOOPS_OF_FACE, efa) {
623                                                 luv = CustomData_bmesh_get(&em->bm->ldata, l->head.data, CD_MLOOPUV);
624                                                 glVertex2fv(luv->uv);
625                                         }
626                                         glEnd();
627
628                                         setlinestyle(2);
629                                         cpack(0x909090);
630
631                                         glBegin(GL_LINE_LOOP);
632                                         BM_ITER(l, &liter, em->bm, BM_LOOPS_OF_FACE, efa) {
633                                                 luv = CustomData_bmesh_get(&em->bm->ldata, l->head.data, CD_MLOOPUV);
634                                                 glVertex2fv(luv->uv);
635                                         }
636                                         glEnd();
637
638                                         /*glBegin(GL_LINE_STRIP);
639                                                 luv = CustomData_bmesh_get(&em->bm->ldata, efa->lbase->head.data, CD_MLOOPUV);
640                                                 glVertex2fv(luv->uv);
641                                                 luv = CustomData_bmesh_get(&em->bm->ldata, efa->lbase->next->head.data, CD_MLOOPUV);
642                                                 glVertex2fv(luv->uv);
643                                         glEnd();*/
644
645                                         setlinestyle(0);
646                                 }
647                         }
648                         break;
649                 case SI_UVDT_BLACK: /* black/white */
650                 case SI_UVDT_WHITE: 
651                         if(sima->dt_uv==SI_UVDT_WHITE) glColor3f(1.0f, 1.0f, 1.0f);
652                         else glColor3f(0.0f, 0.0f, 0.0f);
653
654                         BM_ITER(efa, &iter, em->bm, BM_FACES_OF_MESH, NULL) {
655                                 if (!BMINDEX_GET(efa))
656                                         continue;
657
658                                 glBegin(GL_LINE_LOOP);
659                                 BM_ITER(l, &liter, em->bm, BM_LOOPS_OF_FACE, efa) {
660                                         luv = CustomData_bmesh_get(&em->bm->ldata, l->head.data, CD_MLOOPUV);
661                                         glVertex2fv(luv->uv);
662                                 }
663                                 glEnd();
664                         }
665                         break;
666                 case SI_UVDT_OUTLINE:
667                         glLineWidth(3);
668                         cpack(0x0);
669                         
670                         BM_ITER(efa, &iter, em->bm, BM_FACES_OF_MESH, NULL) {
671                                 if (!BMINDEX_GET(efa))
672                                         continue;
673
674                                 glBegin(GL_LINE_LOOP);
675                                 BM_ITER(l, &liter, em->bm, BM_LOOPS_OF_FACE, efa) {
676                                         luv = CustomData_bmesh_get(&em->bm->ldata, l->head.data, CD_MLOOPUV);
677                                         glVertex2fv(luv->uv);
678                                 }
679                                 glEnd();
680                         }
681                         
682                         glLineWidth(1);
683                         col2[0] = col2[1] = col2[2] = 192; col2[3] = 255;
684                         glColor4ubv((unsigned char *)col2); 
685                         
686                         if(me->drawflag & ME_DRAWEDGES) {
687                                 int lastsel= 0, sel;
688                                 UI_GetThemeColor4ubv(TH_VERTEX_SELECT, col1);
689
690                                 if(interpedges) {
691                                         glShadeModel(GL_SMOOTH);
692
693                                         BM_ITER(efa, &iter, em->bm, BM_FACES_OF_MESH, NULL) {
694                                                 if (!BMINDEX_GET(efa))
695                                                         continue;
696
697                                                 glBegin(GL_LINE_LOOP);
698                                                 i = 0;
699                                                 BM_ITER(l, &liter, em->bm, BM_LOOPS_OF_FACE, efa) {
700                                                         sel = (uvedit_uv_selected(em, scene, l)? 1 : 0);
701                                                         if(sel != lastsel) { glColor4ubv(sel ? (GLubyte *)col1 : (GLubyte *)col2); lastsel = sel; }
702
703                                                         luv = CustomData_bmesh_get(&em->bm->ldata, l->head.data, CD_MLOOPUV);
704                                                         glVertex2fv(luv->uv);
705                                                         luv = CustomData_bmesh_get(&em->bm->ldata, l->next->head.data, CD_MLOOPUV);
706                                                         glVertex2fv(luv->uv);
707                                                         i += 1;
708                                                 }
709                                                 glEnd();
710                                         }
711
712                                         glShadeModel(GL_FLAT);
713                                 }
714                                 else {
715                                         BM_ITER(efa, &iter, em->bm, BM_FACES_OF_MESH, NULL) {
716                                                 if (!BMINDEX_GET(efa))
717                                                         continue;
718
719                                                 glBegin(GL_LINE_LOOP);
720                                                 i = 0;
721                                                 BM_ITER(l, &liter, em->bm, BM_LOOPS_OF_FACE, efa) {
722                                                         sel = (uvedit_edge_selected(em, scene, l)? 1 : 0);
723                                                         if(sel != lastsel) { glColor4ubv(sel ? (GLubyte *)col1 : (GLubyte *)col2); lastsel = sel; }
724
725                                                         luv = CustomData_bmesh_get(&em->bm->ldata, l->head.data, CD_MLOOPUV);
726                                                         glVertex2fv(luv->uv);
727                                                         luv = CustomData_bmesh_get(&em->bm->ldata, l->next->head.data, CD_MLOOPUV);
728                                                         glVertex2fv(luv->uv);
729                                                         i += 1;
730                                                 }
731                                                 glEnd();
732                                         }
733                                 }
734                         }
735                         else {
736                                 /* no nice edges */
737                                 BM_ITER(efa, &iter, em->bm, BM_FACES_OF_MESH, NULL) {
738                                         if (!BMINDEX_GET(efa))
739                                                 continue;
740                                 
741                                         glBegin(GL_LINE_LOOP);
742                                         BM_ITER(l, &liter, em->bm, BM_LOOPS_OF_FACE, efa) {
743                                                 luv = CustomData_bmesh_get(&em->bm->ldata, l->head.data, CD_MLOOPUV);
744                                                 glVertex2fv(luv->uv);
745                                         }
746                                         glEnd();
747                                 }
748                         }
749                         
750                         break;
751         }
752
753         if(sima->flag & SI_SMOOTH_UV) {
754                 glDisable(GL_LINE_SMOOTH);
755                 glDisable(GL_BLEND);
756         }
757
758         /* 5. draw face centers */
759
760         if(drawfaces) {
761                 float cent[2];
762                 
763                 pointsize = UI_GetThemeValuef(TH_FACEDOT_SIZE);
764                 glPointSize(pointsize); // TODO - drawobject.c changes this value after - Investigate!
765                 
766                 /* unselected faces */
767                 UI_ThemeColor(TH_WIRE);
768
769                 bglBegin(GL_POINTS);
770                 BM_ITER(efa, &iter, em->bm, BM_FACES_OF_MESH, NULL) {
771                         if (!BMINDEX_GET(efa))
772                                 continue;
773
774                         if(!uvedit_face_selected(scene, em, efa)) {
775                                 poly_uv_center(em, efa, cent);
776                                 bglVertex2fv(cent);
777                         }
778                 }
779                 bglEnd();
780
781                 /* selected faces */
782                 UI_ThemeColor(TH_FACE_DOT);
783
784                 bglBegin(GL_POINTS);
785                 BM_ITER(efa, &iter, em->bm, BM_FACES_OF_MESH, NULL) {
786                         if (!BMINDEX_GET(efa))
787                                 continue;
788
789                         if(uvedit_face_selected(scene, em, efa)) {
790                                 poly_uv_center(em, efa, cent);
791                                 bglVertex2fv(cent);
792                         }
793                 }
794                 bglEnd();
795         }
796
797         /* 6. draw uv vertices */
798         
799         if(drawfaces != 2) { /* 2 means Mesh Face Mode */
800                 /* unselected uvs */
801                 UI_ThemeColor(TH_VERTEX);
802                 pointsize = UI_GetThemeValuef(TH_VERTEX_SIZE);
803                 glPointSize(pointsize);
804         
805                 bglBegin(GL_POINTS);
806                 BM_ITER(efa, &iter, em->bm, BM_FACES_OF_MESH, NULL) {
807                         if (!BMINDEX_GET(efa))
808                                 continue;
809
810                         BM_ITER(l, &liter, em->bm, BM_LOOPS_OF_FACE, efa) {
811                                 luv = CustomData_bmesh_get(&em->bm->ldata, l->head.data, CD_MLOOPUV);
812                                 if(!uvedit_uv_selected(em, scene, l))
813                                         bglVertex2fv(luv->uv);
814                         }
815                 }
816                 bglEnd();
817         
818                 /* pinned uvs */
819                 /* give odd pointsizes odd pin pointsizes */
820                 glPointSize(pointsize*2 + (((int)pointsize % 2)? (-1): 0));
821                 cpack(0xFF);
822         
823                 bglBegin(GL_POINTS);
824                 BM_ITER(efa, &iter, em->bm, BM_FACES_OF_MESH, NULL) {
825                         if (!BMINDEX_GET(efa))
826                                 continue;
827
828                         BM_ITER(l, &liter, em->bm, BM_LOOPS_OF_FACE, efa) {
829                                 luv = CustomData_bmesh_get(&em->bm->ldata, l->head.data, CD_MLOOPUV);
830
831                                 if(luv->flag & MLOOPUV_PINNED)
832                                         bglVertex2fv(luv->uv);
833                         }
834                 }
835                 bglEnd();
836         
837                 /* selected uvs */
838                 UI_ThemeColor(TH_VERTEX_SELECT);
839                 glPointSize(pointsize);
840         
841                 bglBegin(GL_POINTS);
842                 BM_ITER(efa, &iter, em->bm, BM_FACES_OF_MESH, NULL) {
843                         if (!BMINDEX_GET(efa))
844                                 continue;
845
846                         BM_ITER(l, &liter, em->bm, BM_LOOPS_OF_FACE, efa) {
847                                 luv = CustomData_bmesh_get(&em->bm->ldata, l->head.data, CD_MLOOPUV);
848
849                                 if(uvedit_uv_selected(em, scene, l))
850                                         bglVertex2fv(luv->uv);
851                         }
852                 }
853                 bglEnd();       
854         }
855
856         glPointSize(1.0);
857 }
858
859 void draw_uvedit_main(SpaceImage *sima, ARegion *ar, Scene *scene, Object *obedit)
860 {
861         int show_uvedit, show_uvshadow;
862
863         show_uvedit= ED_space_image_show_uvedit(sima, obedit);
864         show_uvshadow= ED_space_image_show_uvshadow(sima, obedit);
865
866         if(show_uvedit || show_uvshadow) {
867                 if(show_uvshadow)
868                         draw_uvs_shadow(obedit);
869                 else
870                         draw_uvs(sima, scene, obedit);
871
872                 if(show_uvedit)
873                         drawcursor_sima(sima, ar);
874         }
875 }
876