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