~ubuntu-branches/ubuntu/gutsy/blender/gutsy-security

« back to all changes in this revision

Viewing changes to source/blender/src/editface.c

  • Committer: Bazaar Package Importer
  • Author(s): Lukas Fittl
  • Date: 2006-09-20 01:57:27 UTC
  • mfrom: (1.2.4 upstream)
  • Revision ID: james.westby@ubuntu.com-20060920015727-gmoqlxwstx9wwqs3
Tags: 2.42a-1ubuntu1
* Merge from Debian unstable (Closes: Malone #55903). Remaining changes:
  - debian/genpot: Add python scripts from Lee June <blender@eyou.com> to
    generate a reasonable PO template from the sources. Since gettext is used
    in a highly nonstandard way, xgettext does not work for this job.
  - debian/rules: Call the scripts, generate po/blender.pot, and clean it up
    in the clean target.
  - Add a proper header to the generated PO template.
* debian/control: Build depend on libavformat-dev >= 3:0.cvs20060823-3.1,
  otherwise this package will FTBFS

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/**
2
 
 * $Id: editface.c,v 1.50 2005/10/24 22:20:30 blendix Exp $
 
2
 * $Id: editface.c,v 1.63 2006/06/27 04:30:06 campbellbarton Exp $
3
3
 *
4
4
 * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
5
5
 *
34
34
#include <math.h>
35
35
#include <string.h>
36
36
 
37
 
#ifdef HAVE_CONFIG_H
38
 
#include <config.h>
39
 
#endif
40
 
 
41
37
#include "MEM_guardedalloc.h"
42
38
 
43
39
#include "BLI_blenlib.h"
44
40
#include "BLI_arithb.h"
 
41
#include "BLI_heap.h"
 
42
#include "BLI_edgehash.h"
45
43
 
46
44
#include "MTC_matrixops.h"
47
45
 
95
93
 
96
94
#include "BDR_unwrapper.h"
97
95
 
98
 
TFace *lasttface=NULL;
 
96
/* Pupmenu codes: */
 
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
 
110
#define UV_CYL_EX 32
 
111
#define UV_SPHERE_EX 34
 
112
 
 
113
/* Some macro tricks to make pupmenu construction look nicer :-)
 
114
   Sorry, just did it for fun. */
 
115
 
 
116
#define _STR(x) " " #x
 
117
#define STRING(x) _STR(x)
 
118
 
 
119
#define MENUSTRING(string, code) string " %x" STRING(code)
 
120
#define MENUTITLE(string) string " %t|" 
 
121
 
 
122
 
 
123
/* returns 0 if not found, otherwise 1 */
 
124
static int facesel_face_pick(Mesh *me, short *mval, unsigned int *index, short rect)
 
125
{
 
126
        if (!me->tface || me->totface==0)
 
127
                return 0;
 
128
 
 
129
        if (G.vd->flag & V3D_NEEDBACKBUFDRAW) {
 
130
                check_backbuf();
 
131
                persp(PERSP_VIEW);
 
132
        }
 
133
 
 
134
        if (rect) {
 
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 */
 
137
                short dist;
 
138
                *index = sample_backbuf_rect(mval, 3, 1, me->totface+1, &dist);
 
139
        }
 
140
        else
 
141
                /* sample only on the exact position */
 
142
                *index = sample_backbuf(mval[0], mval[1]);
 
143
 
 
144
        if ((*index)<=0 || (*index)>(unsigned int)me->totface)
 
145
                return 0;
 
146
 
 
147
        (*index)--;
 
148
        
 
149
        return 1;
 
150
}
 
151
 
 
152
/* returns 0 if not found, otherwise 1 */
 
153
static int facesel_edge_pick(Mesh *me, short *mval, unsigned int *index)
 
154
{
 
155
        short dist;
 
156
        unsigned int min = me->totface + 1;
 
157
        unsigned int max = me->totface + me->totedge + 1;
 
158
 
 
159
        if (me->totedge == 0)
 
160
                return 0;
 
161
 
 
162
        if (G.vd->flag & V3D_NEEDBACKBUFDRAW) {
 
163
                check_backbuf();
 
164
                persp(PERSP_VIEW);
 
165
        }
 
166
 
 
167
        *index = sample_backbuf_rect(mval, 50, min, max, &dist);
 
168
 
 
169
        if (*index == 0)
 
170
                return 0;
 
171
 
 
172
        (*index)--;
 
173
        
 
174
        return 1;
 
175
}
99
176
 
100
177
static void uv_calc_center_vector(float *result, Object *ob, Mesh *me)
101
178
{
269
346
        float dx, dy, rotatematrix[4][4], radius= 1.0, min[3], cent[3], max[3];
270
347
        float fac= 1.0, upangledeg= 0.0, sideangledeg= 90.0;
271
348
        int i, b, mi, a, n;
272
 
        /* settings from buttonswindow */
273
 
        extern float uv_calc_radius, uv_calc_cubesize;
274
 
        extern short uv_calc_mapdir, uv_calc_mapalign;
275
349
 
276
 
        if(uv_calc_mapdir==1)  {
 
350
        if(G.scene->toolsettings->uvcalc_mapdir==1)  {
277
351
                upangledeg= 90.0;
278
352
                sideangledeg= 0.0;
279
353
        }
280
354
        else {
281
355
                upangledeg= 0.0;
282
 
                if(uv_calc_mapalign==1) sideangledeg= 0.0;
 
356
                if(G.scene->toolsettings->uvcalc_mapalign==1) sideangledeg= 0.0;
283
357
                else sideangledeg= 90.0;
284
358
        }
285
359
 
370
444
        case B_UVAUTO_SPHERE:
371
445
                uv_calc_center_vector(cent, ob, me);
372
446
                        
373
 
                if(mapmode==B_UVAUTO_CYLINDER) radius = uv_calc_radius;
 
447
                if(mapmode==B_UVAUTO_CYLINDER) radius = G.scene->toolsettings->uvcalc_radius;
374
448
 
375
449
                /* be compatible to the "old" sphere/cylinder mode */
376
 
                if (uv_calc_mapdir== 2)
 
450
                if (G.scene->toolsettings->uvcalc_mapdir== 2)
377
451
                        Mat4One(rotatematrix);
378
452
                else 
379
453
                        uv_calc_map_matrix(rotatematrix,ob,upangledeg,sideangledeg,radius);
414
488
                short cox, coy;
415
489
                float *loc= ob->obmat[3];
416
490
                MVert *mv= me->mvert;
 
491
                float cubesize = G.scene->toolsettings->uvcalc_cubesize;
417
492
 
418
493
                tface= me->tface;
419
494
                mface= me->mface;
430
505
                                else if(no[1]>=no[0] && no[1]>=no[2]) coy= 2;
431
506
                                else { cox= 1; coy= 2; }
432
507
                                
433
 
                                tface->uv[0][0]= 0.5+0.5*uv_calc_cubesize*(loc[cox] + (mv+mface->v1)->co[cox]);
434
 
                                tface->uv[0][1]= 0.5+0.5*uv_calc_cubesize*(loc[coy] + (mv+mface->v1)->co[coy]);
 
508
                                tface->uv[0][0]= 0.5+0.5*cubesize*(loc[cox] + (mv+mface->v1)->co[cox]);
 
509
                                tface->uv[0][1]= 0.5+0.5*cubesize*(loc[coy] + (mv+mface->v1)->co[coy]);
435
510
                                dx = floor(tface->uv[0][0]);
436
511
                                dy = floor(tface->uv[0][1]);
437
512
                                tface->uv[0][0] -= dx;
438
513
                                tface->uv[0][1] -= dy;
439
 
                                tface->uv[1][0]= 0.5+0.5*uv_calc_cubesize*(loc[cox] + (mv+mface->v2)->co[cox]);
440
 
                                tface->uv[1][1]= 0.5+0.5*uv_calc_cubesize*(loc[coy] + (mv+mface->v2)->co[coy]);
 
514
                                tface->uv[1][0]= 0.5+0.5*cubesize*(loc[cox] + (mv+mface->v2)->co[cox]);
 
515
                                tface->uv[1][1]= 0.5+0.5*cubesize*(loc[coy] + (mv+mface->v2)->co[coy]);
441
516
                                tface->uv[1][0] -= dx;
442
517
                                tface->uv[1][1] -= dy;
443
 
                                tface->uv[2][0]= 0.5+0.5*uv_calc_cubesize*(loc[cox] + (mv+mface->v3)->co[cox]);
444
 
                                tface->uv[2][1]= 0.5+0.5*uv_calc_cubesize*(loc[coy] + (mv+mface->v3)->co[coy]);
 
518
                                tface->uv[2][0]= 0.5+0.5*cubesize*(loc[cox] + (mv+mface->v3)->co[cox]);
 
519
                                tface->uv[2][1]= 0.5+0.5*cubesize*(loc[coy] + (mv+mface->v3)->co[coy]);
445
520
                                tface->uv[2][0] -= dx;
446
521
                                tface->uv[2][1] -= dy;
447
522
                                if(mface->v4) {
448
 
                                        tface->uv[3][0]= 0.5+0.5*uv_calc_cubesize*(loc[cox] + (mv+mface->v4)->co[cox]);
449
 
                                        tface->uv[3][1]= 0.5+0.5*uv_calc_cubesize*(loc[coy] + (mv+mface->v4)->co[coy]);
 
523
                                        tface->uv[3][0]= 0.5+0.5*cubesize*(loc[cox] + (mv+mface->v4)->co[cox]);
 
524
                                        tface->uv[3][1]= 0.5+0.5*cubesize*(loc[coy] + (mv+mface->v4)->co[coy]);
450
525
                                        tface->uv[3][0] -= dx;
451
526
                                        tface->uv[3][1] -= dy;
452
527
                                }
493
568
        allqueue(REDRAWIMAGE, 0);
494
569
}
495
570
 
496
 
void set_lasttface()
 
571
TFace *get_active_tface()
497
572
{
498
573
        Mesh *me;
499
 
        TFace *tface;
 
574
        TFace *tf;
500
575
        int a;
501
576
        
502
 
        lasttface= 0;
503
 
        if(OBACT==NULL || OBACT->type!=OB_MESH) return;
 
577
        if(OBACT==NULL || OBACT->type!=OB_MESH)
 
578
                return NULL;
504
579
        
505
580
        me= get_mesh(OBACT);
506
 
        if(me==0 || me->tface==0) return;
507
 
        
508
 
        tface= me->tface;
509
 
        a= me->totface;
510
 
        while(a--) {
511
 
                if(tface->flag & TF_ACTIVE) {
512
 
                        lasttface= tface;
513
 
                        return;
514
 
                }
515
 
                tface++;
516
 
        }
517
 
 
518
 
        tface= me->tface;
519
 
        a= me->totface;
520
 
        while(a--) {
521
 
                if(tface->flag & TF_SELECT) {
522
 
                        lasttface= tface;
523
 
                        return;
524
 
                }
525
 
                tface++;
526
 
        }
527
 
 
528
 
        tface= me->tface;
529
 
        a= me->totface;
530
 
        while(a--) {
531
 
                if((tface->flag & TF_HIDE)==0) {
532
 
                        lasttface= tface;
533
 
                        return;
534
 
                }
535
 
                tface++;
536
 
        }
 
581
        if(me==0 || me->tface==0)
 
582
                return NULL;
 
583
        
 
584
        for(a=0, tf=me->tface; a < me->totface; a++, tf++)
 
585
                if(tf->flag & TF_ACTIVE)
 
586
                        return tf;
 
587
 
 
588
        for(a=0, tf=me->tface; a < me->totface; a++, tf++)
 
589
                if(tf->flag & TF_SELECT)
 
590
                        return tf;
 
591
 
 
592
        for(a=0, tf=me->tface; a < me->totface; a++, tf++)
 
593
                if((tf->flag & TF_HIDE)==0)
 
594
                        return tf;
 
595
        
 
596
        return NULL;
537
597
}
538
598
 
539
599
void default_uv(float uv[][2], float size)
666
726
                        error("The active object is not in this layer");
667
727
                        
668
728
                getmouseco_areawin(mval);
669
 
                if (!face_pick(me, mval[0], mval[1], &index)) return;
 
729
                if (!facesel_face_pick(me, mval, &index, 1)) return;
670
730
        }
671
731
 
672
732
        select_linked_tfaces_with_seams(mode, me, index);
916
976
        }
917
977
}
918
978
 
919
 
/**
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
930
 
 */
931
 
int face_pick(Mesh *me, short x, short y, unsigned int *index)
932
 
{
933
 
        unsigned int col;
934
 
 
935
 
        if (me==0 || me->tface==0)
936
 
                return 0;
937
 
 
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;
941
 
        }
942
 
        if (G.vd->flag & V3D_NEEDBACKBUFDRAW) {
943
 
                backdrawview3d(0);
944
 
                persp(PERSP_VIEW);
945
 
        }
946
 
        /* Read the pixel under the cursor */
947
 
#ifdef __APPLE__
948
 
        glReadBuffer(GL_AUX0);
949
 
#endif
950
 
        glReadPixels(x+curarea->winrct.xmin, y+curarea->winrct.ymin, 1, 1,
951
 
                GL_RGBA, GL_UNSIGNED_BYTE, &col);
952
 
        glReadBuffer(GL_BACK);
953
 
 
954
 
        /* Unbelievable! */
955
 
        if (G.order==B_ENDIAN) {
956
 
                SWITCH_INT(col);
957
 
        }
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)
961
 
                return 0;
962
 
 
963
 
        (*index)--;
 
979
#define ME_SEAM_DONE ME_SEAM_LAST               /* reuse this flag */
 
980
 
 
981
static float seam_cut_cost(Mesh *me, int e1, int e2, int vert)
 
982
{
 
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];
 
988
 
 
989
        cost = VecLenf(v1->co, v->co);
 
990
        cost += VecLenf(v->co, v2->co);
 
991
 
 
992
        VecSubf(d1, v->co, v1->co);
 
993
        VecSubf(d2, v2->co, v->co);
 
994
 
 
995
        cost = cost + 0.5f*cost*(2.0f - fabs(d1[0]*d2[0] + d1[1]*d2[1] + d1[2]*d2[2]));
 
996
 
 
997
        return cost;
 
998
}
 
999
 
 
1000
static void seam_add_adjacent(Mesh *me, Heap *heap, int mednum, int vertnum, int *nedges, int *edges, int *prevedge, float *cost)
 
1001
{
 
1002
        int startadj, endadj = nedges[vertnum+1];
 
1003
 
 
1004
        for (startadj = nedges[vertnum]; startadj < endadj; startadj++) {
 
1005
                int adjnum = edges[startadj];
 
1006
                MEdge *medadj = me->medge + adjnum;
 
1007
                float newcost;
 
1008
 
 
1009
                if (medadj->flag & ME_SEAM_DONE)
 
1010
                        continue;
 
1011
 
 
1012
                newcost = cost[mednum] + seam_cut_cost(me, mednum, adjnum, vertnum);
 
1013
 
 
1014
                if (cost[adjnum] > newcost) {
 
1015
                        cost[adjnum] = newcost;
 
1016
                        prevedge[adjnum] = mednum;
 
1017
                        BLI_heap_insert(heap, newcost, (void*)adjnum);
 
1018
                }
 
1019
        }
 
1020
}
 
1021
 
 
1022
static int seam_shortest_path(Mesh *me, int source, int target)
 
1023
{
 
1024
        Heap *heap;
 
1025
        EdgeHash *ehash;
 
1026
        float *cost;
 
1027
        MEdge *med;
 
1028
        int a, *nedges, *edges, *prevedge, mednum = -1, nedgeswap = 0;
 
1029
        TFace *tf;
 
1030
        MFace *mf;
 
1031
 
 
1032
        /* mark hidden edges as done, so we don't use them */
 
1033
        ehash = BLI_edgehash_new();
 
1034
 
 
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);
 
1039
                        if (mf->v4) {
 
1040
                                BLI_edgehash_insert(ehash, mf->v3, mf->v4, NULL);
 
1041
                                BLI_edgehash_insert(ehash, mf->v4, mf->v1, NULL);
 
1042
                        }
 
1043
                        else
 
1044
                                BLI_edgehash_insert(ehash, mf->v3, mf->v1, NULL);
 
1045
                }
 
1046
        }
 
1047
 
 
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;
 
1051
 
 
1052
        BLI_edgehash_free(ehash, NULL);
 
1053
 
 
1054
        /* alloc */
 
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");
 
1059
 
 
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]++;
 
1064
        }
 
1065
 
 
1066
        for (a=1; a<me->totvert; a++) {
 
1067
                int newswap = nedges[a+1];
 
1068
                nedges[a+1] = nedgeswap + nedges[a];
 
1069
                nedgeswap = newswap;
 
1070
        }
 
1071
        nedges[0] = nedges[1] = 0;
 
1072
 
 
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;
 
1076
 
 
1077
                cost[a] = 1e20f;
 
1078
                prevedge[a] = -1;
 
1079
        }
 
1080
 
 
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;
 
1085
 
 
1086
        while (!BLI_heap_empty(heap)) {
 
1087
                mednum = (int)BLI_heap_popmin(heap);
 
1088
                med = me->medge + mednum;
 
1089
 
 
1090
                if (mednum == target)
 
1091
                        break;
 
1092
 
 
1093
                if (med->flag & ME_SEAM_DONE)
 
1094
                        continue;
 
1095
 
 
1096
                med->flag |= ME_SEAM_DONE;
 
1097
 
 
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);
 
1100
        }
964
1101
        
 
1102
        MEM_freeN(nedges);
 
1103
        MEM_freeN(edges);
 
1104
        MEM_freeN(cost);
 
1105
        BLI_heap_free(heap, NULL);
 
1106
 
 
1107
        for (a=0, med=me->medge; a<me->totedge; a++, med++)
 
1108
                med->flag &= ~ME_SEAM_DONE;
 
1109
 
 
1110
        if (mednum != target) {
 
1111
                MEM_freeN(prevedge);
 
1112
                return 0;
 
1113
        }
 
1114
 
 
1115
        /* follow path back to source and mark as seam */
 
1116
        if (mednum == target) {
 
1117
                short allseams = 1;
 
1118
 
 
1119
                mednum = target;
 
1120
                do {
 
1121
                        med = me->medge + mednum;
 
1122
                        if (!(med->flag & ME_SEAM)) {
 
1123
                                allseams = 0;
 
1124
                                break;
 
1125
                        }
 
1126
                        mednum = prevedge[mednum];
 
1127
                } while (mednum != source);
 
1128
 
 
1129
                mednum = target;
 
1130
                do {
 
1131
                        med = me->medge + mednum;
 
1132
                        if (allseams)
 
1133
                                med->flag &= ~ME_SEAM;
 
1134
                        else
 
1135
                                med->flag |= ME_SEAM;
 
1136
                        mednum = prevedge[mednum];
 
1137
                } while (mednum != -1);
 
1138
        }
 
1139
 
 
1140
        MEM_freeN(prevedge);
965
1141
        return 1;
966
1142
}
967
1143
 
 
1144
static void seam_select(Mesh *me, short *mval, short path)
 
1145
{
 
1146
        unsigned int index = 0;
 
1147
        MEdge *medge, *med;
 
1148
        int a, lastindex = -1;
 
1149
 
 
1150
        if (!facesel_edge_pick(me, mval, &index))
 
1151
                return;
 
1152
 
 
1153
        for (a=0, med=me->medge; a<me->totedge; a++, med++) {
 
1154
                if (med->flag & ME_SEAM_LAST) {
 
1155
                        lastindex = a;
 
1156
                        med->flag &= ~ME_SEAM_LAST;
 
1157
                        break;
 
1158
                }
 
1159
        }
 
1160
 
 
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;
 
1166
 
 
1167
        G.f |= G_DRAWSEAMS;
 
1168
 
 
1169
        if (G.rt == 8)
 
1170
                unwrap_lscm(1);
 
1171
 
 
1172
        BIF_undo_push("Mark Seam");
 
1173
 
 
1174
        object_tface_flags_changed(OBACT, 1);
 
1175
}
 
1176
 
 
1177
void seam_edgehash_insert_face(EdgeHash *ehash, MFace *mf)
 
1178
{
 
1179
        BLI_edgehash_insert(ehash, mf->v1, mf->v2, NULL);
 
1180
        BLI_edgehash_insert(ehash, mf->v2, mf->v3, NULL);
 
1181
        if (mf->v4) {
 
1182
                BLI_edgehash_insert(ehash, mf->v3, mf->v4, NULL);
 
1183
                BLI_edgehash_insert(ehash, mf->v4, mf->v1, NULL);
 
1184
        }
 
1185
        else
 
1186
                BLI_edgehash_insert(ehash, mf->v3, mf->v1, NULL);
 
1187
}
 
1188
 
 
1189
void seam_mark_clear_tface(short mode)
 
1190
{
 
1191
        Mesh *me;
 
1192
        TFace *tf;
 
1193
        MFace *mf;
 
1194
        MEdge *med;
 
1195
        int a;
 
1196
        
 
1197
        me= get_mesh(OBACT);
 
1198
        if(me==0 || me->tface==0 || me->totface==0) return;
 
1199
 
 
1200
        if (mode == 0)
 
1201
                mode = pupmenu("Seams%t|Mark Border Seam %x1|Clear Seam %x2");
 
1202
 
 
1203
        if (mode != 1 && mode != 2)
 
1204
                return;
 
1205
 
 
1206
        if (mode == 2) {
 
1207
                EdgeHash *ehash = BLI_edgehash_new();
 
1208
 
 
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);
 
1212
 
 
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;
 
1216
 
 
1217
                BLI_edgehash_free(ehash, NULL);
 
1218
        }
 
1219
        else {
 
1220
                /* mark edges that are on both selected and deselected faces */
 
1221
                EdgeHash *ehash1 = BLI_edgehash_new();
 
1222
                EdgeHash *ehash2 = BLI_edgehash_new();
 
1223
 
 
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);
 
1227
                        else
 
1228
                                seam_edgehash_insert_face(ehash2, mf);
 
1229
                }
 
1230
 
 
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;
 
1235
 
 
1236
                BLI_edgehash_free(ehash1, NULL);
 
1237
                BLI_edgehash_free(ehash2, NULL);
 
1238
        }
 
1239
 
 
1240
        if (G.rt == 8)
 
1241
                unwrap_lscm(1);
 
1242
 
 
1243
        G.f |= G_DRAWSEAMS;
 
1244
        BIF_undo_push("Mark Seam");
 
1245
 
 
1246
        object_tface_flags_changed(OBACT, 1);
 
1247
}
 
1248
 
968
1249
void face_select()
969
1250
{
970
1251
        Object *ob;
981
1262
        }
982
1263
        me = get_mesh(ob);
983
1264
        getmouseco_areawin(mval);
984
 
        if (!face_pick(me, mval[0], mval[1], &index)) return;
 
1265
 
 
1266
        if (G.qual & LR_ALTKEY) {
 
1267
                seam_select(me, mval, (G.qual & LR_SHIFTKEY) != 0);
 
1268
                return;
 
1269
        }
 
1270
 
 
1271
        if (!facesel_face_pick(me, mval, &index, 1)) return;
985
1272
        
986
1273
        tsel= (((TFace*)me->tface)+index);
987
1274
        msel= (((MFace*)me->mface)+index);
1009
1296
        }
1010
1297
        else tsel->flag |= TF_SELECT;
1011
1298
        
1012
 
        lasttface = tsel;
1013
 
        
1014
1299
        /* image window redraw */
1015
1300
        
1016
1301
        BIF_undo_push("Select UV face");
1023
1308
        Mesh *me;
1024
1309
        TFace *tface;
1025
1310
        rcti rect;
1026
 
        unsigned int *rectm, *rt;
 
1311
        struct ImBuf *ibuf;
 
1312
        unsigned int *rt;
1027
1313
        int a, sx, sy, index, val;
1028
1314
        char *selar;
1029
1315
        
1046
1332
                sy= (rect.ymax-rect.ymin+1);
1047
1333
                if(sx*sy<=0) return;
1048
1334
 
1049
 
                rt=rectm= MEM_mallocN(sizeof(int)*sx*sy, "selrect");
1050
 
                glReadPixels(rect.xmin+curarea->winrct.xmin,  rect.ymin+curarea->winrct.ymin, sx, sy, GL_RGBA, GL_UNSIGNED_BYTE,  rectm);
1051
 
                if(G.order==B_ENDIAN) IMB_convert_rgba_to_abgr(sx*sy, rectm);
 
1335
                ibuf = IMB_allocImBuf(sx,sy,32,IB_rect,0);
 
1336
                rt = ibuf->rect;
 
1337
                glReadPixels(rect.xmin+curarea->winrct.xmin,  rect.ymin+curarea->winrct.ymin, sx, sy, GL_RGBA, GL_UNSIGNED_BYTE,  ibuf->rect);
 
1338
                if(G.order==B_ENDIAN) IMB_convert_rgba_to_abgr(ibuf);
1052
1339
 
1053
1340
                a= sx*sy;
1054
1341
                while(a--) {
1070
1357
                        }
1071
1358
                }
1072
1359
                
1073
 
                MEM_freeN(rectm);
 
1360
                IMB_freeImBuf(ibuf);
1074
1361
                MEM_freeN(selar);
1075
1362
 
1076
1363
                BIF_undo_push("Border Select UV face");
1082
1369
#endif
1083
1370
}
1084
1371
 
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
1101
 
 
1102
 
/* Some macro tricks to make pupmenu construction look nicer :-)
1103
 
   Sorry, just did it for fun. */
1104
 
 
1105
 
#define _STR(x) " " #x
1106
 
#define STRING(x) _STR(x)
1107
 
 
1108
 
#define MENUSTRING(string, code) string " %x" STRING(code)
1109
 
#define MENUTITLE(string) string " %t|" 
1110
 
 
1111
1372
void uv_autocalc_tface()
1112
1373
{
1113
1374
        short mode;
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) );
 
1389
                      
1128
1390
        
1129
1391
        
1130
1392
        switch(mode) {
1152
1414
                calculate_uv_map(B_UVAUTO_STD1); break;
1153
1415
        case UV_WINDOW_MAPPING:
1154
1416
                calculate_uv_map(B_UVAUTO_WINDOW); break;
1155
 
        case UV_LSCM_MAPPING:
1156
 
                unwrap_lscm(); break;
 
1417
        case UV_UNWRAP_MAPPING:
 
1418
                unwrap_lscm(0); break;
1157
1419
        }
1158
1420
}
1159
1421
 
1162
1424
        Object *ob = OBACT;
1163
1425
        Mesh *me = 0;
1164
1426
        
 
1427
        if(ob==NULL) return;
 
1428
        if(ob->id.lib) {
 
1429
                error("Can't edit library data");
 
1430
                return;
 
1431
        }
 
1432
        
 
1433
        me= get_mesh(ob);
 
1434
        if(me && me->id.lib) {
 
1435
                error("Can't edit library data");
 
1436
                return;
 
1437
        }
 
1438
        
1165
1439
        scrarea_queue_headredraw(curarea);
1166
 
        if(ob==NULL || ob->id.lib) return;
1167
 
        
1168
 
        if(G.f & G_FACESELECT) G.f &= ~G_FACESELECT;
1169
 
        else {
1170
 
                if (ob && ob->type == OB_MESH) G.f |= G_FACESELECT;
1171
 
        }
1172
 
 
1173
 
        allqueue(REDRAWVIEW3D, 0);
1174
 
        allqueue(REDRAWBUTSEDIT, 0);
1175
 
        allqueue(REDRAWIMAGE, 0);
1176
 
        
1177
 
        ob= OBACT;
1178
 
        me= get_mesh(ob);
1179
 
        if(me && me->tface==NULL) make_tfaces(me);
 
1440
        
 
1441
        if(me) /* make sure modifiers are updated for mapping requirements */
 
1442
                DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA);
1180
1443
 
1181
1444
        if(G.f & G_FACESELECT) {
 
1445
                G.f &= ~G_FACESELECT;
 
1446
 
 
1447
                if((G.f & (G_WEIGHTPAINT|G_VERTEXPAINT|G_TEXTUREPAINT))==0) {
 
1448
                        if(me)
 
1449
                                reveal_tface();
 
1450
                        setcursor_space(SPACE_VIEW3D, CURSOR_STD);
 
1451
                        BIF_undo_push("End UV Faceselect");
 
1452
                }
 
1453
        }
 
1454
        else if (me && (ob->lay & G.vd->lay)) {
 
1455
                G.f |= G_FACESELECT;
 
1456
                if(me->tface==NULL)
 
1457
                        make_tfaces(me);
 
1458
 
1182
1459
                setcursor_space(SPACE_VIEW3D, CURSOR_FACESEL);
1183
 
                if(me) {
1184
 
                        set_lasttface();
1185
 
                        set_seamtface(); /* set TF_SEAM flags in tface */
1186
 
                }
1187
1460
                BIF_undo_push("Set UV Faceselect");
1188
1461
        }
1189
 
        else if((G.f & (G_WEIGHTPAINT|G_VERTEXPAINT|G_TEXTUREPAINT))==0) {
1190
 
                if(me) {
1191
 
                        reveal_tface();
1192
 
                        DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA);
1193
 
                }
1194
 
                setcursor_space(SPACE_VIEW3D, CURSOR_STD);
1195
 
                BIF_undo_push("End UV Faceselect");
1196
 
        }
 
1462
 
1197
1463
        countall();
1198
 
}
1199
 
 
 
1464
 
 
1465
        allqueue(REDRAWVIEW3D, 0);
 
1466
        allqueue(REDRAWBUTSEDIT, 0);
 
1467
        allqueue(REDRAWIMAGE, 0);
 
1468
}
 
1469
 
 
1470
void set_texturepaint() /* toggle */
 
1471
{
 
1472
        Object *ob = OBACT;
 
1473
        Mesh *me = 0;
 
1474
        
 
1475
        scrarea_queue_headredraw(curarea);
 
1476
        if(ob==NULL) return;
 
1477
        if(ob->id.lib) {
 
1478
                error("Can't edit library data");
 
1479
                return;
 
1480
        }
 
1481
 
 
1482
        me= get_mesh(ob);
 
1483
        if(me && me->id.lib) {
 
1484
                error("Can't edit library data");
 
1485
                return;
 
1486
        }
 
1487
        
 
1488
        if(me)
 
1489
                DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA);
 
1490
 
 
1491
        if(G.f & G_TEXTUREPAINT)
 
1492
                G.f &= ~G_TEXTUREPAINT;
 
1493
        else if (me)
 
1494
                G.f |= G_TEXTUREPAINT;
 
1495
 
 
1496
        allqueue(REDRAWVIEW3D, 0);
 
1497
}
1200
1498
 
1201
1499
/**
1202
1500
 * Get the view ray through the screen point.
1501
1799
                if ((xy[0] != xy_old[0]) || (xy[1] != xy_old[1])) {
1502
1800
 
1503
1801
                        /* Get face to draw on */
1504
 
                        if (!face_pick(me, xy[0], xy[1], &face_index)) face = NULL;
 
1802
                        if (!facesel_face_pick(me, xy, &face_index, 0)) face = NULL;
1505
1803
                        else face = (((TFace*)me->tface)+face_index);
1506
1804
 
1507
1805
                        /* Check if this is another face. */