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