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