2 * ***** BEGIN GPL LICENSE BLOCK *****
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License
6 * as published by the Free Software Foundation; either version 2
7 * of the License, or (at your option) any later version.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software Foundation,
16 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18 * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
19 * All rights reserved.
21 * Contributor(s): Blender Foundation, 2002-2009
23 * ***** END GPL LICENSE BLOCK *****
26 /** \file blender/editors/uvedit/uvedit_draw.c
36 #include "MEM_guardedalloc.h"
38 #include "DNA_mesh_types.h"
39 #include "DNA_meshdata_types.h"
40 #include "DNA_object_types.h"
41 #include "DNA_scene_types.h"
42 #include "DNA_screen_types.h"
43 #include "DNA_space_types.h"
46 #include "BLI_utildefines.h"
48 #include "BKE_DerivedMesh.h"
50 #include "BKE_tessmesh.h"
52 #include "BLI_array.h"
55 #include "BIF_glutil.h"
60 #include "ED_uvedit.h"
62 #include "UI_resources.h"
64 #include "uvedit_intern.h"
66 static void drawcursor_sima(SpaceImage *sima, ARegion *ar)
68 float zoomx, zoomy, w, h;
71 ED_space_image_size(sima, &width, &height);
72 ED_space_image_zoom(sima, ar, &zoomx, &zoomy);
74 w = zoomx * width / 256.0f;
75 h = zoomy * height / 256.0f;
78 glTranslatef(sima->cursor[0], sima->cursor[1], 0.0);
79 fdrawline(-0.05f / w, 0, 0, 0.05f / h);
80 fdrawline(0, 0.05f / h, 0.05f / w, 0.0f);
81 fdrawline(0.05f / w, 0.0f, 0.0f, -0.05f / h);
82 fdrawline(0.0f, -0.05f / h, -0.05f / w, 0.0f);
86 fdrawline(-0.05f / w, 0.0f, 0.0f, 0.05f / h);
87 fdrawline(0.0f, 0.05f / h, 0.05f / w, 0.0f);
88 fdrawline(0.05f / w, 0.0f, 0.0f, -0.05f / h);
89 fdrawline(0.0f, -0.05f / h, -0.05f / w, 0.0f);
94 fdrawline(-0.020f / w, 0.0f, -0.1f / w, 0.0f);
95 fdrawline(0.1f / w, 0.0f, 0.020f / w, 0.0f);
96 fdrawline(0.0f, -0.020f / h, 0.0f, -0.1f / h);
97 fdrawline(0.0f, 0.1f / h, 0.0f, 0.020f / h);
101 fdrawline(-0.020f / w, 0.0f, -0.1f / w, 0.0f);
102 fdrawline(0.1f / w, 0.0f, 0.020f / w, 0.0f);
103 fdrawline(0.0f, -0.020f / h, 0.0f, -0.1f / h);
104 fdrawline(0.0f, 0.1f / h, 0.0f, 0.020f / h);
106 glTranslatef(-sima->cursor[0], -sima->cursor[1], 0.0);
110 static int draw_uvs_face_check(Scene *scene)
112 ToolSettings *ts = scene->toolsettings;
114 /* checks if we are selecting only faces */
115 if (ts->uv_flag & UV_SYNC_SELECTION) {
116 if (ts->selectmode == SCE_SELECT_FACE)
118 else if (ts->selectmode & SCE_SELECT_FACE)
124 return (ts->uv_selectmode == UV_SELECT_FACE);
127 static void draw_uvs_shadow(Object *obedit)
129 BMEditMesh *em = BMEdit_FromObject(obedit);
136 /* draws the grey mesh when painting */
137 glColor3ub(112, 112, 112);
139 BM_ITER_MESH (efa, &iter, bm, BM_FACES_OF_MESH) {
140 glBegin(GL_LINE_LOOP);
141 BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
142 luv = CustomData_bmesh_get(&bm->ldata, l->head.data, CD_MLOOPUV);
144 glVertex2fv(luv->uv);
150 static int draw_uvs_dm_shadow(DerivedMesh *dm)
152 /* draw shadow mesh - this is the mesh with the modifier applied */
154 if (dm && dm->drawUVEdges && CustomData_has_layer(&dm->loopData, CD_MLOOPUV)) {
155 glColor3ub(112, 112, 112);
163 static void draw_uvs_stretch(SpaceImage *sima, Scene *scene, BMEditMesh *em, MTexPoly *activetf)
171 Image *ima = sima->image;
172 BLI_array_declare(tf_uv);
173 BLI_array_declare(tf_uvorig);
174 float aspx, aspy, col[4], (*tf_uv)[2] = NULL, (*tf_uvorig)[2] = NULL;
177 ED_space_image_uv_aspect(sima, &aspx, &aspy);
179 switch (sima->dt_uvstretch) {
180 case SI_UVDT_STRETCH_AREA:
182 float totarea = 0.0f, totuvarea = 0.0f, areadiff, uvarea, area;
184 BM_ITER_MESH (efa, &iter, bm, BM_FACES_OF_MESH) {
185 tf = CustomData_bmesh_get(&bm->pdata, efa->head.data, CD_MTEXPOLY);
187 BLI_array_empty(tf_uv);
188 BLI_array_empty(tf_uvorig);
189 BLI_array_growitems(tf_uv, efa->len);
190 BLI_array_growitems(tf_uvorig, efa->len);
193 BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
194 luv = CustomData_bmesh_get(&bm->ldata, l->head.data, CD_MLOOPUV);
196 copy_v2_v2(tf_uvorig[i], luv->uv);
201 poly_copy_aspect(tf_uvorig, tf_uv, aspx, aspy, efa->len);
203 totarea += BM_face_calc_area(efa);
204 //totuvarea += tf_area(tf, efa->v4!=0);
205 totuvarea += poly_uv_area(tf_uv, efa->len);
207 if (uvedit_face_visible(scene, ima, efa, tf)) {
208 BM_elem_flag_enable(efa, BM_ELEM_TAG);
213 BM_elem_flag_disable(efa, BM_ELEM_TAG);
217 if (totarea < FLT_EPSILON || totuvarea < FLT_EPSILON) {
219 col[1] = col[2] = 0.0;
221 BM_ITER_MESH (efa, &iter, bm, BM_FACES_OF_MESH) {
222 if (BM_elem_flag_test(efa, BM_ELEM_TAG)) {
224 BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
225 luv = CustomData_bmesh_get(&bm->ldata, l->head.data, CD_MLOOPUV);
226 glVertex2fv(luv->uv);
233 BM_ITER_MESH (efa, &iter, bm, BM_FACES_OF_MESH) {
234 if (BM_elem_flag_test(efa, BM_ELEM_TAG)) {
235 area = BM_face_calc_area(efa) / totarea;
237 BLI_array_empty(tf_uv);
238 BLI_array_empty(tf_uvorig);
239 BLI_array_growitems(tf_uv, efa->len);
240 BLI_array_growitems(tf_uvorig, efa->len);
243 BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
244 luv = CustomData_bmesh_get(&bm->ldata, l->head.data, CD_MLOOPUV);
246 copy_v2_v2(tf_uvorig[i], luv->uv);
251 poly_copy_aspect(tf_uvorig, tf_uv, aspx, aspy, efa->len);
253 //uvarea = tf_area(tf, efa->v4!=0) / totuvarea;
254 uvarea = poly_uv_area(tf_uv, efa->len) / totuvarea;
256 if (area < FLT_EPSILON || uvarea < FLT_EPSILON)
258 else if (area > uvarea)
259 areadiff = 1.0f - (uvarea / area);
261 areadiff = 1.0f - (area / uvarea);
263 weight_to_rgb(col, areadiff);
267 BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
268 luv = CustomData_bmesh_get(&bm->ldata, l->head.data, CD_MLOOPUV);
269 glVertex2fv(luv->uv);
277 case SI_UVDT_STRETCH_ANGLE:
281 float (*av)[3] = NULL; /* use for 2d and 3d angle vectors */
282 float (*auv)[2] = NULL;
285 BLI_array_declare(uvang);
286 BLI_array_declare(ang);
287 BLI_array_declare(av);
288 BLI_array_declare(auv);
290 col[3] = 0.5; /* hard coded alpha, not that nice */
292 glShadeModel(GL_SMOOTH);
294 BM_ITER_MESH (efa, &iter, bm, BM_FACES_OF_MESH) {
295 tf = CustomData_bmesh_get(&bm->pdata, efa->head.data, CD_MTEXPOLY);
297 if (uvedit_face_visible(scene, ima, efa, tf)) {
299 BM_elem_flag_enable(efa, BM_ELEM_TAG);
300 BLI_array_empty(tf_uv);
301 BLI_array_empty(tf_uvorig);
302 BLI_array_empty(uvang);
303 BLI_array_empty(ang);
305 BLI_array_empty(auv);
306 BLI_array_growitems(tf_uv, nverts);
307 BLI_array_growitems(tf_uvorig, nverts);
308 BLI_array_growitems(uvang, nverts);
309 BLI_array_growitems(ang, nverts);
310 BLI_array_growitems(av, nverts);
311 BLI_array_growitems(auv, nverts);
313 BM_ITER_ELEM_INDEX (l, &liter, efa, BM_LOOPS_OF_FACE, i) {
314 luv = CustomData_bmesh_get(&bm->ldata, l->head.data, CD_MLOOPUV);
315 copy_v2_v2(tf_uvorig[i], luv->uv);
318 poly_copy_aspect(tf_uvorig, tf_uv, aspx, aspy, nverts);
321 BM_ITER_ELEM_INDEX (l, &liter, efa, BM_LOOPS_OF_FACE, i) {
322 sub_v2_v2v2(auv[i], tf_uv[j], tf_uv[i]); normalize_v2(auv[i]);
323 sub_v3_v3v3(av[i], l->prev->v->co, l->v->co); normalize_v3(av[i]);
327 for (i = 0; i < nverts; i++) {
329 /* Simple but slow, better reuse normalized vectors
330 * (Not ported to bmesh, copied for reference) */
331 uvang1 = RAD2DEG(angle_v2v2v2(tf_uv[3], tf_uv[0], tf_uv[1]));
332 ang1 = RAD2DEG(angle_v3v3v3(efa->v4->co, efa->v1->co, efa->v2->co));
334 uvang[i] = angle_normalized_v2v2(auv[i], auv[(i + 1) % nverts]);
335 ang[i] = angle_normalized_v3v3(av[i], av[(i + 1) % nverts]);
339 BM_ITER_ELEM_INDEX (l, &liter, efa, BM_LOOPS_OF_FACE, i) {
340 luv = CustomData_bmesh_get(&bm->ldata, l->head.data, CD_MLOOPUV);
341 a = fabsf(uvang[i] - ang[i]) / (float)M_PI;
342 weight_to_rgb(col, 1.0f - powf((1.0f - a), 2.0f));
344 glVertex2fv(luv->uv);
351 BM_elem_flag_disable(efa, BM_ELEM_TAG);
355 glShadeModel(GL_FLAT);
357 BLI_array_free(uvang);
366 BLI_array_free(tf_uv);
367 BLI_array_free(tf_uvorig);
370 static void draw_uvs_other(Scene *scene, Object *obedit, Image *curimage)
374 glColor3ub(96, 96, 96);
376 for (base = scene->base.first; base; base = base->next) {
377 Object *ob = base->object;
379 if (!(base->flag & SELECT)) continue;
380 if (!(base->lay & scene->lay)) continue;
381 if (ob->restrictflag & OB_RESTRICT_VIEW) continue;
383 if ((ob->type == OB_MESH) && (ob != obedit)) {
387 MPoly *mpoly = me->mpoly;
388 MTexPoly *mtpoly = me->mtpoly;
392 for (a = me->totpoly; a > 0; a--, mtpoly++, mpoly++) {
393 if (mtpoly->tpage == curimage) {
394 glBegin(GL_LINE_LOOP);
396 mloopuv = me->mloopuv + mpoly->loopstart;
397 for (b = 0; b < mpoly->totloop; b++, mloopuv++) {
398 glVertex2fv(mloopuv->uv);
408 static void draw_uvs_texpaint(SpaceImage *sima, Scene *scene, Object *ob)
411 Image *curimage = ED_space_image(sima);
413 if (sima->flag & SI_DRAW_OTHER)
414 draw_uvs_other(scene, ob, curimage);
416 glColor3ub(112, 112, 112);
419 MPoly *mpoly = me->mpoly;
420 MTexPoly *tface = me->mtpoly;
424 for (a = me->totpoly; a > 0; a--, tface++, mpoly++) {
425 if (tface->tpage == curimage) {
426 glBegin(GL_LINE_LOOP);
428 mloopuv = me->mloopuv + mpoly->loopstart;
429 for (b = 0; b < mpoly->totloop; b++, mloopuv++) {
430 glVertex2fv(mloopuv->uv);
438 /* draws uv's in the image space */
439 static void draw_uvs(SpaceImage *sima, Scene *scene, Object *obedit)
442 Mesh *me = obedit->data;
443 BMEditMesh *em = me->edit_btmesh;
445 BMFace *efa, *efa_act, *activef;
448 MTexPoly *tf, *activetf = NULL;
450 DerivedMesh *finaldm, *cagedm;
451 unsigned char col1[4], col2[4];
453 int drawfaces, interpedges;
454 Image *ima = sima->image;
456 StitchPreviewer *stitch_preview = uv_get_stitch_previewer();
458 activetf = EDBM_mtexpoly_active_get(em, &efa_act, FALSE); /* will be set to NULL if hidden */
459 activef = BM_active_face_get(bm, FALSE);
460 ts = scene->toolsettings;
462 drawfaces = draw_uvs_face_check(scene);
463 if (ts->uv_flag & UV_SYNC_SELECTION)
464 interpedges = (ts->selectmode & SCE_SELECT_VERTEX);
466 interpedges = (ts->uv_selectmode == UV_SELECT_VERTEX);
469 if (sima->flag & SI_DRAW_OTHER) {
470 Image *curimage = (activetf) ? activetf->tpage : NULL;
472 draw_uvs_other(scene, obedit, curimage);
475 /* 1. draw shadow mesh */
477 if (sima->flag & SI_DRAWSHADOW) {
478 /* first try existing derivedmesh */
479 if (!draw_uvs_dm_shadow(em->derivedFinal)) {
480 /* create one if it does not exist */
481 cagedm = editbmesh_get_derived_cage_and_final(scene, obedit, me->edit_btmesh, &finaldm, CD_MASK_BAREMESH | CD_MASK_MTFACE);
483 /* when sync selection is enabled, all faces are drawn (except for hidden)
484 * so if cage is the same as the final, theres no point in drawing this */
485 if (!((ts->uv_flag & UV_SYNC_SELECTION) && (cagedm == finaldm)))
486 draw_uvs_dm_shadow(finaldm);
488 /* release derivedmesh again */
489 if (cagedm != finaldm) cagedm->release(cagedm);
490 finaldm->release(finaldm);
494 /* 2. draw colored faces */
496 if (sima->flag & SI_DRAW_STRETCH) {
497 draw_uvs_stretch(sima, scene, em, activetf);
499 else if (!(sima->flag & SI_NO_DRAWFACES)) {
500 /* draw transparent faces */
501 UI_GetThemeColor4ubv(TH_FACE, col1);
502 UI_GetThemeColor4ubv(TH_FACE_SELECT, col2);
503 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
506 BM_ITER_MESH (efa, &iter, bm, BM_FACES_OF_MESH) {
507 tf = CustomData_bmesh_get(&bm->pdata, efa->head.data, CD_MTEXPOLY);
509 if (uvedit_face_visible(scene, ima, efa, tf)) {
510 BM_elem_flag_enable(efa, BM_ELEM_TAG);
511 if (tf == activetf) continue; /* important the temp boolean is set above */
513 if (uvedit_face_selected(scene, em, efa))
514 glColor4ubv((GLubyte *)col2);
516 glColor4ubv((GLubyte *)col1);
519 BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
520 luv = CustomData_bmesh_get(&bm->ldata, l->head.data, CD_MLOOPUV);
521 glVertex2fv(luv->uv);
528 BM_elem_flag_disable(efa, BM_ELEM_TAG);
534 /* would be nice to do this within a draw loop but most below are optional, so it would involve too many checks */
536 BM_ITER_MESH (efa, &iter, bm, BM_FACES_OF_MESH) {
537 tf = CustomData_bmesh_get(&bm->pdata, efa->head.data, CD_MTEXPOLY);
539 if (uvedit_face_visible(scene, ima, efa, tf)) {
540 BM_elem_flag_enable(efa, BM_ELEM_TAG);
545 BM_elem_flag_disable(efa, BM_ELEM_TAG);
551 /* 3. draw active face stippled */
554 tf = CustomData_bmesh_get(&bm->pdata, activef->head.data, CD_MTEXPOLY);
555 if (uvedit_face_visible(scene, ima, activef, tf)) {
557 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
558 UI_ThemeColor4(TH_EDITMESH_ACTIVE);
560 glEnable(GL_POLYGON_STIPPLE);
561 glPolygonStipple(stipple_quarttone);
564 BM_ITER_ELEM (l, &liter, activef, BM_LOOPS_OF_FACE) {
565 luv = CustomData_bmesh_get(&bm->ldata, l->head.data, CD_MLOOPUV);
566 glVertex2fv(luv->uv);
570 glDisable(GL_POLYGON_STIPPLE);
577 if (sima->flag & SI_SMOOTH_UV) {
578 glEnable(GL_LINE_SMOOTH);
580 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
583 switch (sima->dt_uv) {
585 BM_ITER_MESH (efa, &iter, bm, BM_FACES_OF_MESH) {
586 if (!BM_elem_flag_test(efa, BM_ELEM_TAG))
588 tf = CustomData_bmesh_get(&bm->pdata, efa->head.data, CD_MTEXPOLY);
593 glBegin(GL_LINE_LOOP);
594 BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
595 luv = CustomData_bmesh_get(&bm->ldata, l->head.data, CD_MLOOPUV);
596 glVertex2fv(luv->uv);
603 glBegin(GL_LINE_LOOP);
604 BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
605 luv = CustomData_bmesh_get(&bm->ldata, l->head.data, CD_MLOOPUV);
606 glVertex2fv(luv->uv);
611 glBegin(GL_LINE_STRIP);
612 luv = CustomData_bmesh_get(&bm->ldata, efa->lbase->head.data, CD_MLOOPUV);
613 glVertex2fv(luv->uv);
614 luv = CustomData_bmesh_get(&bm->ldata, efa->lbase->next->head.data, CD_MLOOPUV);
615 glVertex2fv(luv->uv);
623 case SI_UVDT_BLACK: /* black/white */
625 if (sima->dt_uv == SI_UVDT_WHITE) glColor3f(1.0f, 1.0f, 1.0f);
626 else glColor3f(0.0f, 0.0f, 0.0f);
628 BM_ITER_MESH (efa, &iter, bm, BM_FACES_OF_MESH) {
629 if (!BM_elem_flag_test(efa, BM_ELEM_TAG))
632 glBegin(GL_LINE_LOOP);
633 BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
634 luv = CustomData_bmesh_get(&bm->ldata, l->head.data, CD_MLOOPUV);
635 glVertex2fv(luv->uv);
640 case SI_UVDT_OUTLINE:
644 BM_ITER_MESH (efa, &iter, bm, BM_FACES_OF_MESH) {
645 if (!BM_elem_flag_test(efa, BM_ELEM_TAG))
648 glBegin(GL_LINE_LOOP);
649 BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
650 luv = CustomData_bmesh_get(&bm->ldata, l->head.data, CD_MLOOPUV);
651 glVertex2fv(luv->uv);
657 col2[0] = col2[1] = col2[2] = 192; col2[3] = 255;
658 glColor4ubv((unsigned char *)col2);
660 if (me->drawflag & ME_DRAWEDGES) {
661 int sel, lastsel = -1;
662 UI_GetThemeColor4ubv(TH_VERTEX_SELECT, col1);
665 glShadeModel(GL_SMOOTH);
667 BM_ITER_MESH (efa, &iter, bm, BM_FACES_OF_MESH) {
668 if (!BM_elem_flag_test(efa, BM_ELEM_TAG))
671 glBegin(GL_LINE_LOOP);
672 BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
673 sel = (uvedit_uv_selected(em, scene, l) ? 1 : 0);
674 glColor4ubv(sel ? (GLubyte *)col1 : (GLubyte *)col2);
676 luv = CustomData_bmesh_get(&bm->ldata, l->head.data, CD_MLOOPUV);
677 glVertex2fv(luv->uv);
682 glShadeModel(GL_FLAT);
685 BM_ITER_MESH (efa, &iter, bm, BM_FACES_OF_MESH) {
686 if (!BM_elem_flag_test(efa, BM_ELEM_TAG))
690 BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
691 sel = (uvedit_edge_selected(em, scene, l) ? 1 : 0);
692 if (sel != lastsel) {
693 glColor4ubv(sel ? (GLubyte *)col1 : (GLubyte *)col2);
696 luv = CustomData_bmesh_get(&bm->ldata, l->head.data, CD_MLOOPUV);
697 glVertex2fv(luv->uv);
698 luv = CustomData_bmesh_get(&bm->ldata, l->next->head.data, CD_MLOOPUV);
699 glVertex2fv(luv->uv);
707 BM_ITER_MESH (efa, &iter, bm, BM_FACES_OF_MESH) {
708 if (!BM_elem_flag_test(efa, BM_ELEM_TAG))
711 glBegin(GL_LINE_LOOP);
712 BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
713 luv = CustomData_bmesh_get(&bm->ldata, l->head.data, CD_MLOOPUV);
714 glVertex2fv(luv->uv);
723 if (sima->flag & SI_SMOOTH_UV) {
724 glDisable(GL_LINE_SMOOTH);
728 /* 5. draw face centers */
733 pointsize = UI_GetThemeValuef(TH_FACEDOT_SIZE);
734 glPointSize(pointsize); // TODO - drawobject.c changes this value after - Investigate!
736 /* unselected faces */
737 UI_ThemeColor(TH_WIRE);
740 BM_ITER_MESH (efa, &iter, bm, BM_FACES_OF_MESH) {
741 if (!BM_elem_flag_test(efa, BM_ELEM_TAG))
744 if (!uvedit_face_selected(scene, em, efa)) {
745 poly_uv_center(em, efa, cent);
752 UI_ThemeColor(TH_FACE_DOT);
755 BM_ITER_MESH (efa, &iter, bm, BM_FACES_OF_MESH) {
756 if (!BM_elem_flag_test(efa, BM_ELEM_TAG))
759 if (uvedit_face_selected(scene, em, efa)) {
760 poly_uv_center(em, efa, cent);
767 /* 6. draw uv vertices */
769 if (drawfaces != 2) { /* 2 means Mesh Face Mode */
771 UI_ThemeColor(TH_VERTEX);
772 pointsize = UI_GetThemeValuef(TH_VERTEX_SIZE);
773 glPointSize(pointsize);
776 BM_ITER_MESH (efa, &iter, bm, BM_FACES_OF_MESH) {
777 if (!BM_elem_flag_test(efa, BM_ELEM_TAG))
780 BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
781 luv = CustomData_bmesh_get(&bm->ldata, l->head.data, CD_MLOOPUV);
782 if (!uvedit_uv_selected(em, scene, l))
783 bglVertex2fv(luv->uv);
789 /* give odd pointsizes odd pin pointsizes */
790 glPointSize(pointsize * 2 + (((int)pointsize % 2) ? (-1) : 0));
794 BM_ITER_MESH (efa, &iter, bm, BM_FACES_OF_MESH) {
795 if (!BM_elem_flag_test(efa, BM_ELEM_TAG))
798 BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
799 luv = CustomData_bmesh_get(&bm->ldata, l->head.data, CD_MLOOPUV);
801 if (luv->flag & MLOOPUV_PINNED)
802 bglVertex2fv(luv->uv);
808 UI_ThemeColor(TH_VERTEX_SELECT);
809 glPointSize(pointsize);
812 BM_ITER_MESH (efa, &iter, bm, BM_FACES_OF_MESH) {
813 if (!BM_elem_flag_test(efa, BM_ELEM_TAG))
816 BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
817 luv = CustomData_bmesh_get(&bm->ldata, l->head.data, CD_MLOOPUV);
819 if (uvedit_uv_selected(em, scene, l))
820 bglVertex2fv(luv->uv);
826 /* finally draw stitch preview */
827 if (stitch_preview) {
829 glPushClientAttrib(GL_CLIENT_VERTEX_ARRAY_BIT);
830 glEnableClientState(GL_VERTEX_ARRAY);
834 UI_ThemeColor4(TH_STITCH_PREVIEW_ACTIVE);
835 glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
836 glVertexPointer(2, GL_FLOAT, 0, stitch_preview->static_tris);
837 glDrawArrays(GL_TRIANGLES, 0, stitch_preview->num_static_tris * 3);
839 glVertexPointer(2, GL_FLOAT, 0, stitch_preview->preview_polys);
840 for (i = 0; i < stitch_preview->num_polys; i++) {
841 glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
842 UI_ThemeColor4(TH_STITCH_PREVIEW_FACE);
843 glDrawArrays(GL_POLYGON, index, stitch_preview->uvs_per_polygon[i]);
844 glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
845 UI_ThemeColor4(TH_STITCH_PREVIEW_EDGE);
846 glDrawArrays(GL_POLYGON, index, stitch_preview->uvs_per_polygon[i]);
848 index += stitch_preview->uvs_per_polygon[i];
850 glPolygonMode(GL_FRONT_AND_BACK, GL_POINT);
852 UI_ThemeColor4(TH_STITCH_PREVIEW_VERT);
853 glDrawArrays(GL_TRIANGLES, 0, stitch_preview->num_tris * 3);
857 /* draw vert preview */
858 glPointSize(pointsize * 2.0);
859 UI_ThemeColor4(TH_STITCH_PREVIEW_STITCHABLE);
860 glVertexPointer(2, GL_FLOAT, 0, stitch_preview->preview_stitchable);
861 glDrawArrays(GL_POINTS, 0, stitch_preview->num_stitchable);
863 UI_ThemeColor4(TH_STITCH_PREVIEW_UNSTITCHABLE);
864 glVertexPointer(2, GL_FLOAT, 0, stitch_preview->preview_unstitchable);
865 glDrawArrays(GL_POINTS, 0, stitch_preview->num_unstitchable);
868 glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
874 void draw_uvedit_main(SpaceImage *sima, ARegion *ar, Scene *scene, Object *obedit, Object *obact)
876 ToolSettings *toolsettings = scene->toolsettings;
877 int show_uvedit, show_uvshadow, show_texpaint_uvshadow;
879 show_texpaint_uvshadow = (obact && obact->type == OB_MESH && obact->mode == OB_MODE_TEXTURE_PAINT);
880 show_uvedit = ED_space_image_show_uvedit(sima, obedit);
881 show_uvshadow = ED_space_image_show_uvshadow(sima, obedit);
883 if (show_uvedit || show_uvshadow || show_texpaint_uvshadow) {
885 draw_uvs_shadow(obedit);
886 else if (show_uvedit)
887 draw_uvs(sima, scene, obedit);
889 draw_uvs_texpaint(sima, scene, obact);
891 if (show_uvedit && !(toolsettings->use_uv_sculpt))
892 drawcursor_sima(sima, ar);