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