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