96
94
#include "BDR_unwrapper.h"
98
TFace *lasttface=NULL;
97
#define UV_CUBE_MAPPING 2
98
#define UV_CYL_MAPPING 3
99
#define UV_SPHERE_MAPPING 4
100
#define UV_BOUNDS8_MAPPING 68
101
#define UV_BOUNDS4_MAPPING 65
102
#define UV_BOUNDS2_MAPPING 66
103
#define UV_BOUNDS1_MAPPING 67
104
#define UV_STD8_MAPPING 131
105
#define UV_STD4_MAPPING 130
106
#define UV_STD2_MAPPING 129
107
#define UV_STD1_MAPPING 128
108
#define UV_WINDOW_MAPPING 5
109
#define UV_UNWRAP_MAPPING 6
111
#define UV_SPHERE_EX 34
113
/* Some macro tricks to make pupmenu construction look nicer :-)
114
Sorry, just did it for fun. */
116
#define _STR(x) " " #x
117
#define STRING(x) _STR(x)
119
#define MENUSTRING(string, code) string " %x" STRING(code)
120
#define MENUTITLE(string) string " %t|"
123
/* returns 0 if not found, otherwise 1 */
124
static int facesel_face_pick(Mesh *me, short *mval, unsigned int *index, short rect)
126
if (!me->tface || me->totface==0)
129
if (G.vd->flag & V3D_NEEDBACKBUFDRAW) {
135
/* sample rect to increase changes of selecting, so that when clicking
136
on an edge in the backbuf, we can still select a face */
138
*index = sample_backbuf_rect(mval, 3, 1, me->totface+1, &dist);
141
/* sample only on the exact position */
142
*index = sample_backbuf(mval[0], mval[1]);
144
if ((*index)<=0 || (*index)>(unsigned int)me->totface)
152
/* returns 0 if not found, otherwise 1 */
153
static int facesel_edge_pick(Mesh *me, short *mval, unsigned int *index)
156
unsigned int min = me->totface + 1;
157
unsigned int max = me->totface + me->totedge + 1;
159
if (me->totedge == 0)
162
if (G.vd->flag & V3D_NEEDBACKBUFDRAW) {
167
*index = sample_backbuf_rect(mval, 50, min, max, &dist);
100
177
static void uv_calc_center_vector(float *result, Object *ob, Mesh *me)
920
* Returns the face under the give position in screen coordinates.
921
* Code extracted from face_select routine.
922
* Question: why is all of the backbuffer drawn?
923
* We're only interested in one pixel!
924
* @author Maarten Gribnau
925
* @param me the mesh with the faces to be picked
926
* @param x the x-coordinate to pick at
927
* @param y the y-coordinate to pick at
928
* @param index the index of the face
929
* @return 1 if found, 0 if none found
931
int face_pick(Mesh *me, short x, short y, unsigned int *index)
935
if (me==0 || me->tface==0)
938
/* Have OpenGL draw in the back buffer with color coded face indices */
939
if (curarea->win_swap==WIN_EQUAL) {
940
G.vd->flag |= V3D_NEEDBACKBUFDRAW;
942
if (G.vd->flag & V3D_NEEDBACKBUFDRAW) {
946
/* Read the pixel under the cursor */
948
glReadBuffer(GL_AUX0);
950
glReadPixels(x+curarea->winrct.xmin, y+curarea->winrct.ymin, 1, 1,
951
GL_RGBA, GL_UNSIGNED_BYTE, &col);
952
glReadBuffer(GL_BACK);
955
if (G.order==B_ENDIAN) {
958
/* Convert the color back to a face index */
959
*index = framebuffer_to_index(col);
960
if (col==0 || (*index)<=0 || (*index)>(unsigned) me->totface)
979
#define ME_SEAM_DONE ME_SEAM_LAST /* reuse this flag */
981
static float seam_cut_cost(Mesh *me, int e1, int e2, int vert)
983
MVert *v = me->mvert + vert;
984
MEdge *med1 = me->medge + e1, *med2 = me->medge + e2;
985
MVert *v1 = me->mvert + ((med1->v1 == vert)? med1->v2: med1->v1);
986
MVert *v2 = me->mvert + ((med2->v1 == vert)? med2->v2: med2->v1);
987
float cost, d1[3], d2[3];
989
cost = VecLenf(v1->co, v->co);
990
cost += VecLenf(v->co, v2->co);
992
VecSubf(d1, v->co, v1->co);
993
VecSubf(d2, v2->co, v->co);
995
cost = cost + 0.5f*cost*(2.0f - fabs(d1[0]*d2[0] + d1[1]*d2[1] + d1[2]*d2[2]));
1000
static void seam_add_adjacent(Mesh *me, Heap *heap, int mednum, int vertnum, int *nedges, int *edges, int *prevedge, float *cost)
1002
int startadj, endadj = nedges[vertnum+1];
1004
for (startadj = nedges[vertnum]; startadj < endadj; startadj++) {
1005
int adjnum = edges[startadj];
1006
MEdge *medadj = me->medge + adjnum;
1009
if (medadj->flag & ME_SEAM_DONE)
1012
newcost = cost[mednum] + seam_cut_cost(me, mednum, adjnum, vertnum);
1014
if (cost[adjnum] > newcost) {
1015
cost[adjnum] = newcost;
1016
prevedge[adjnum] = mednum;
1017
BLI_heap_insert(heap, newcost, (void*)adjnum);
1022
static int seam_shortest_path(Mesh *me, int source, int target)
1028
int a, *nedges, *edges, *prevedge, mednum = -1, nedgeswap = 0;
1032
/* mark hidden edges as done, so we don't use them */
1033
ehash = BLI_edgehash_new();
1035
for (a=0, mf=me->mface, tf=me->tface; a<me->totface; a++, tf++, mf++) {
1036
if (!(tf->flag & TF_HIDE)) {
1037
BLI_edgehash_insert(ehash, mf->v1, mf->v2, NULL);
1038
BLI_edgehash_insert(ehash, mf->v2, mf->v3, NULL);
1040
BLI_edgehash_insert(ehash, mf->v3, mf->v4, NULL);
1041
BLI_edgehash_insert(ehash, mf->v4, mf->v1, NULL);
1044
BLI_edgehash_insert(ehash, mf->v3, mf->v1, NULL);
1048
for (a=0, med=me->medge; a<me->totedge; a++, med++)
1049
if (!BLI_edgehash_haskey(ehash, med->v1, med->v2))
1050
med->flag |= ME_SEAM_DONE;
1052
BLI_edgehash_free(ehash, NULL);
1055
nedges = MEM_callocN(sizeof(*nedges)*me->totvert+1, "SeamPathNEdges");
1056
edges = MEM_mallocN(sizeof(*edges)*me->totedge*2, "SeamPathEdges");
1057
prevedge = MEM_mallocN(sizeof(*prevedge)*me->totedge, "SeamPathPrevious");
1058
cost = MEM_mallocN(sizeof(*cost)*me->totedge, "SeamPathCost");
1060
/* count edges, compute adjacent edges offsets and fill adjacent edges */
1061
for (a=0, med=me->medge; a<me->totedge; a++, med++) {
1062
nedges[med->v1+1]++;
1063
nedges[med->v2+1]++;
1066
for (a=1; a<me->totvert; a++) {
1067
int newswap = nedges[a+1];
1068
nedges[a+1] = nedgeswap + nedges[a];
1069
nedgeswap = newswap;
1071
nedges[0] = nedges[1] = 0;
1073
for (a=0, med=me->medge; a<me->totedge; a++, med++) {
1074
edges[nedges[med->v1+1]++] = a;
1075
edges[nedges[med->v2+1]++] = a;
1081
/* regular dijkstra shortest path, but over edges instead of vertices */
1082
heap = BLI_heap_new();
1083
BLI_heap_insert(heap, 0.0f, (void*)source);
1084
cost[source] = 0.0f;
1086
while (!BLI_heap_empty(heap)) {
1087
mednum = (int)BLI_heap_popmin(heap);
1088
med = me->medge + mednum;
1090
if (mednum == target)
1093
if (med->flag & ME_SEAM_DONE)
1096
med->flag |= ME_SEAM_DONE;
1098
seam_add_adjacent(me, heap, mednum, med->v1, nedges, edges, prevedge, cost);
1099
seam_add_adjacent(me, heap, mednum, med->v2, nedges, edges, prevedge, cost);
1105
BLI_heap_free(heap, NULL);
1107
for (a=0, med=me->medge; a<me->totedge; a++, med++)
1108
med->flag &= ~ME_SEAM_DONE;
1110
if (mednum != target) {
1111
MEM_freeN(prevedge);
1115
/* follow path back to source and mark as seam */
1116
if (mednum == target) {
1121
med = me->medge + mednum;
1122
if (!(med->flag & ME_SEAM)) {
1126
mednum = prevedge[mednum];
1127
} while (mednum != source);
1131
med = me->medge + mednum;
1133
med->flag &= ~ME_SEAM;
1135
med->flag |= ME_SEAM;
1136
mednum = prevedge[mednum];
1137
} while (mednum != -1);
1140
MEM_freeN(prevedge);
1144
static void seam_select(Mesh *me, short *mval, short path)
1146
unsigned int index = 0;
1148
int a, lastindex = -1;
1150
if (!facesel_edge_pick(me, mval, &index))
1153
for (a=0, med=me->medge; a<me->totedge; a++, med++) {
1154
if (med->flag & ME_SEAM_LAST) {
1156
med->flag &= ~ME_SEAM_LAST;
1161
medge = me->medge + index;
1162
if (!path || (lastindex == -1) || (index == lastindex) ||
1163
!seam_shortest_path(me, lastindex, index))
1164
medge->flag ^= ME_SEAM;
1165
medge->flag |= ME_SEAM_LAST;
1172
BIF_undo_push("Mark Seam");
1174
object_tface_flags_changed(OBACT, 1);
1177
void seam_edgehash_insert_face(EdgeHash *ehash, MFace *mf)
1179
BLI_edgehash_insert(ehash, mf->v1, mf->v2, NULL);
1180
BLI_edgehash_insert(ehash, mf->v2, mf->v3, NULL);
1182
BLI_edgehash_insert(ehash, mf->v3, mf->v4, NULL);
1183
BLI_edgehash_insert(ehash, mf->v4, mf->v1, NULL);
1186
BLI_edgehash_insert(ehash, mf->v3, mf->v1, NULL);
1189
void seam_mark_clear_tface(short mode)
1197
me= get_mesh(OBACT);
1198
if(me==0 || me->tface==0 || me->totface==0) return;
1201
mode = pupmenu("Seams%t|Mark Border Seam %x1|Clear Seam %x2");
1203
if (mode != 1 && mode != 2)
1207
EdgeHash *ehash = BLI_edgehash_new();
1209
for (a=0, mf=me->mface, tf=me->tface; a<me->totface; a++, tf++, mf++)
1210
if (!(tf->flag & TF_HIDE) && (tf->flag & TF_SELECT))
1211
seam_edgehash_insert_face(ehash, mf);
1213
for (a=0, med=me->medge; a<me->totedge; a++, med++)
1214
if (BLI_edgehash_haskey(ehash, med->v1, med->v2))
1215
med->flag &= ~ME_SEAM;
1217
BLI_edgehash_free(ehash, NULL);
1220
/* mark edges that are on both selected and deselected faces */
1221
EdgeHash *ehash1 = BLI_edgehash_new();
1222
EdgeHash *ehash2 = BLI_edgehash_new();
1224
for (a=0, mf=me->mface, tf=me->tface; a<me->totface; a++, tf++, mf++) {
1225
if ((tf->flag & TF_HIDE) || !(tf->flag & TF_SELECT))
1226
seam_edgehash_insert_face(ehash1, mf);
1228
seam_edgehash_insert_face(ehash2, mf);
1231
for (a=0, med=me->medge; a<me->totedge; a++, med++)
1232
if (BLI_edgehash_haskey(ehash1, med->v1, med->v2) &&
1233
BLI_edgehash_haskey(ehash2, med->v1, med->v2))
1234
med->flag |= ME_SEAM;
1236
BLI_edgehash_free(ehash1, NULL);
1237
BLI_edgehash_free(ehash2, NULL);
1244
BIF_undo_push("Mark Seam");
1246
object_tface_flags_changed(OBACT, 1);
968
1249
void face_select()
1085
/* Pupmenu codes: */
1086
#define UV_CUBE_MAPPING 2
1087
#define UV_CYL_MAPPING 3
1088
#define UV_SPHERE_MAPPING 4
1089
#define UV_BOUNDS8_MAPPING 68
1090
#define UV_BOUNDS4_MAPPING 65
1091
#define UV_BOUNDS2_MAPPING 66
1092
#define UV_BOUNDS1_MAPPING 67
1093
#define UV_STD8_MAPPING 131
1094
#define UV_STD4_MAPPING 130
1095
#define UV_STD2_MAPPING 129
1096
#define UV_STD1_MAPPING 128
1097
#define UV_WINDOW_MAPPING 5
1098
#define UV_LSCM_MAPPING 6
1099
#define UV_CYL_EX 32
1100
#define UV_SPHERE_EX 34
1102
/* Some macro tricks to make pupmenu construction look nicer :-)
1103
Sorry, just did it for fun. */
1105
#define _STR(x) " " #x
1106
#define STRING(x) _STR(x)
1108
#define MENUSTRING(string, code) string " %x" STRING(code)
1109
#define MENUTITLE(string) string " %t|"
1111
1372
void uv_autocalc_tface()
1114
1375
mode= pupmenu(MENUTITLE("UV Calculation")
1115
MENUSTRING("Cube", UV_CUBE_MAPPING) "|"
1116
MENUSTRING("Cylinder", UV_CYL_MAPPING) "|"
1117
MENUSTRING("Sphere", UV_SPHERE_MAPPING) "|"
1118
MENUSTRING("LSCM", UV_LSCM_MAPPING) "|"
1119
MENUSTRING("Bounds to 1/8", UV_BOUNDS8_MAPPING) "|"
1120
MENUSTRING("Bounds to 1/4", UV_BOUNDS4_MAPPING) "|"
1121
MENUSTRING("Bounds to 1/2", UV_BOUNDS2_MAPPING) "|"
1122
MENUSTRING("Bounds to 1/1", UV_BOUNDS1_MAPPING) "|"
1123
MENUSTRING("Standard 1/8", UV_STD8_MAPPING) "|"
1124
MENUSTRING("Standard 1/4", UV_STD4_MAPPING) "|"
1125
MENUSTRING("Standard 1/2", UV_STD2_MAPPING) "|"
1126
MENUSTRING("Standard 1/1", UV_STD1_MAPPING) "|"
1127
MENUSTRING("From Window", UV_WINDOW_MAPPING) );
1376
MENUSTRING("Cube Projection", UV_CUBE_MAPPING) "|"
1377
MENUSTRING("Cylinder from View", UV_CYL_MAPPING) "|"
1378
MENUSTRING("Sphere from View", UV_SPHERE_MAPPING) "|"
1379
MENUSTRING("Unwrap", UV_UNWRAP_MAPPING) "|"
1380
MENUSTRING("Project From View", UV_WINDOW_MAPPING) "|"
1381
MENUSTRING("Project from View 1/1", UV_BOUNDS1_MAPPING) "|"
1382
MENUSTRING("Project from View 1/2", UV_BOUNDS2_MAPPING) "|"
1383
MENUSTRING("Project from View 1/4", UV_BOUNDS4_MAPPING) "|"
1384
MENUSTRING("Project from View 1/8", UV_BOUNDS8_MAPPING) "|"
1385
MENUSTRING("Reset 1/1", UV_STD1_MAPPING) "|"
1386
MENUSTRING("Reset 1/2", UV_STD2_MAPPING) "|"
1387
MENUSTRING("Reset 1/4", UV_STD4_MAPPING) "|"
1388
MENUSTRING("Reset 1/8", UV_STD8_MAPPING) );
1162
1424
Object *ob = OBACT;
1427
if(ob==NULL) return;
1429
error("Can't edit library data");
1434
if(me && me->id.lib) {
1435
error("Can't edit library data");
1165
1439
scrarea_queue_headredraw(curarea);
1166
if(ob==NULL || ob->id.lib) return;
1168
if(G.f & G_FACESELECT) G.f &= ~G_FACESELECT;
1170
if (ob && ob->type == OB_MESH) G.f |= G_FACESELECT;
1173
allqueue(REDRAWVIEW3D, 0);
1174
allqueue(REDRAWBUTSEDIT, 0);
1175
allqueue(REDRAWIMAGE, 0);
1179
if(me && me->tface==NULL) make_tfaces(me);
1441
if(me) /* make sure modifiers are updated for mapping requirements */
1442
DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA);
1181
1444
if(G.f & G_FACESELECT) {
1445
G.f &= ~G_FACESELECT;
1447
if((G.f & (G_WEIGHTPAINT|G_VERTEXPAINT|G_TEXTUREPAINT))==0) {
1450
setcursor_space(SPACE_VIEW3D, CURSOR_STD);
1451
BIF_undo_push("End UV Faceselect");
1454
else if (me && (ob->lay & G.vd->lay)) {
1455
G.f |= G_FACESELECT;
1182
1459
setcursor_space(SPACE_VIEW3D, CURSOR_FACESEL);
1185
set_seamtface(); /* set TF_SEAM flags in tface */
1187
1460
BIF_undo_push("Set UV Faceselect");
1189
else if((G.f & (G_WEIGHTPAINT|G_VERTEXPAINT|G_TEXTUREPAINT))==0) {
1192
DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA);
1194
setcursor_space(SPACE_VIEW3D, CURSOR_STD);
1195
BIF_undo_push("End UV Faceselect");
1465
allqueue(REDRAWVIEW3D, 0);
1466
allqueue(REDRAWBUTSEDIT, 0);
1467
allqueue(REDRAWIMAGE, 0);
1470
void set_texturepaint() /* toggle */
1475
scrarea_queue_headredraw(curarea);
1476
if(ob==NULL) return;
1478
error("Can't edit library data");
1483
if(me && me->id.lib) {
1484
error("Can't edit library data");
1489
DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA);
1491
if(G.f & G_TEXTUREPAINT)
1492
G.f &= ~G_TEXTUREPAINT;
1494
G.f |= G_TEXTUREPAINT;
1496
allqueue(REDRAWVIEW3D, 0);
1202
1500
* Get the view ray through the screen point.