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