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

« back to all changes in this revision

Viewing changes to source/blender/src/editmesh_mods.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:
40
40
#include <string.h>
41
41
#include <math.h>
42
42
 
43
 
#ifdef HAVE_CONFIG_H
44
 
#include <config.h>
45
 
#endif
46
 
 
47
43
#include "MEM_guardedalloc.h"
48
44
 
49
45
#include "MTC_matrixops.h"
92
88
#include "BSE_edit.h"
93
89
#include "BSE_view.h"
94
90
 
 
91
#include "IMB_imbuf_types.h"
95
92
#include "IMB_imbuf.h"
96
93
 
 
94
#include "RE_render_ext.h"  /* externtex */
 
95
 
97
96
#include "mydevice.h"
98
97
#include "blendef.h"
99
 
#include "render.h"  // externtex
100
98
 
101
99
#include "editmesh.h"
102
100
 
103
101
 
104
102
/* ****************************** MIRROR **************** */
105
103
 
106
 
static EditVert *get_x_mirror_vert(EditVert *eve)
107
 
{
108
 
        int index;
109
 
        
110
 
        index= mesh_get_x_mirror_vert(G.obedit, POINTER_TO_INT(eve));
111
 
        if(index != -1)
112
 
                return INT_TO_POINTER(index);
113
 
        return NULL;
114
 
}
115
 
 
116
104
void EM_select_mirrored(void)
117
105
{
118
106
        if(G.scene->selectmode & SCE_SELECT_VERTEX) {
121
109
                
122
110
                for(eve= em->verts.first; eve; eve= eve->next) {
123
111
                        if(eve->f & SELECT) {
124
 
                                v1= get_x_mirror_vert(eve);
 
112
                                v1= editmesh_get_x_mirror_vert(G.obedit, eve->co);
125
113
                                if(v1) {
126
114
                                        eve->f &= ~SELECT;
127
115
                                        v1->f |= SELECT;
133
121
 
134
122
/* ****************************** SELECTION ROUTINES **************** */
135
123
 
136
 
unsigned int em_solidoffs=0, em_wireoffs=0, em_vertoffs=0;      // set in drawobject.c ... for colorindices
137
 
 
138
 
static void check_backbuf(void)
139
 
{
140
 
        if(G.vd->flag & V3D_NEEDBACKBUFDRAW) {
141
 
                backdrawview3d(0);
142
 
        }
143
 
}
144
 
 
145
 
/* samples a single pixel (copied from vpaint) */
146
 
static unsigned int sample_backbuf(int x, int y)
147
 
{
148
 
        unsigned int col;
149
 
        
150
 
        if(x>=curarea->winx || y>=curarea->winy) return 0;
151
 
        x+= curarea->winrct.xmin;
152
 
        y+= curarea->winrct.ymin;
153
 
        
154
 
        check_backbuf(); // actually not needed for apple
155
 
 
156
 
#ifdef __APPLE__
157
 
        glReadBuffer(GL_AUX0);
158
 
#endif
159
 
        glReadPixels(x,  y, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE,  &col);
160
 
        glReadBuffer(GL_BACK);  
161
 
        
162
 
        if(G.order==B_ENDIAN) SWITCH_INT(col);
163
 
        
164
 
        return framebuffer_to_index(col);
165
 
}
166
 
 
167
 
/* reads full rect, converts indices */
168
 
static unsigned int *read_backbuf(short xmin, short ymin, short xmax, short ymax)
169
 
{
170
 
        unsigned int *dr, *buf;
171
 
        int a;
172
 
        short xminc, yminc, xmaxc, ymaxc;
173
 
        
174
 
        /* clip */
175
 
        if(xmin<0) xminc= 0; else xminc= xmin;
176
 
        if(xmax>=curarea->winx) xmaxc= curarea->winx-1; else xmaxc= xmax;
177
 
        if(xminc > xmaxc) return NULL;
178
 
 
179
 
        if(ymin<0) yminc= 0; else yminc= ymin;
180
 
        if(ymax>=curarea->winy) ymaxc= curarea->winy-1; else ymaxc= ymax;
181
 
        if(yminc > ymaxc) return NULL;
182
 
        
183
 
        buf= MEM_mallocN( (xmaxc-xminc+1)*(ymaxc-yminc+1)*sizeof(int), "sample rect");
184
 
 
185
 
        check_backbuf(); // actually not needed for apple
186
 
        
187
 
#ifdef __APPLE__
188
 
        glReadBuffer(GL_AUX0);
189
 
#endif
190
 
        glReadPixels(curarea->winrct.xmin+xminc, curarea->winrct.ymin+yminc, (xmaxc-xminc+1), (ymaxc-yminc+1), GL_RGBA, GL_UNSIGNED_BYTE, buf);
191
 
        glReadBuffer(GL_BACK);  
192
 
 
193
 
        if(G.order==B_ENDIAN) IMB_convert_rgba_to_abgr((xmaxc-xminc+1)*(ymaxc-yminc+1), buf);
194
 
 
195
 
        a= (xmaxc-xminc+1)*(ymaxc-yminc+1);
196
 
        dr= buf;
197
 
        while(a--) {
198
 
                if(*dr) *dr= framebuffer_to_index(*dr);
199
 
                dr++;
200
 
        }
201
 
        
202
 
        /* put clipped result back, if needed */
203
 
        if(xminc==xmin && xmaxc==xmax && yminc==ymin && ymaxc==ymax) return buf;
204
 
        else {
205
 
                unsigned int *buf1= MEM_callocN( (xmax-xmin+1)*(ymax-ymin+1)*sizeof(int), "sample rect2");
206
 
                unsigned int *rd;
207
 
                short xs, ys;
208
 
 
209
 
                rd= buf;
210
 
                dr= buf1;
211
 
                
212
 
                for(ys= ymin; ys<=ymax; ys++) {
213
 
                        for(xs= xmin; xs<=xmax; xs++, dr++) {
214
 
                                if( xs>=xminc && xs<=xmaxc && ys>=yminc && ys<=ymaxc) {
215
 
                                        *dr= *rd;
216
 
                                        rd++;
217
 
                                }
218
 
                        }
219
 
                }
220
 
                MEM_freeN(buf);
221
 
                return buf1;
222
 
        }
223
 
        
224
 
        return buf;
225
 
}
226
 
 
227
 
 
228
 
/* smart function to sample a rect spiralling outside, nice for backbuf selection */
229
 
static unsigned int sample_backbuf_rect(short mval[2], int size, unsigned int min, unsigned int max, short *dist)
230
 
{
231
 
        unsigned int *buf, *bufmin, *bufmax;
232
 
        int minx, miny;
233
 
        int a, b, rc, nr, amount, dirvec[4][2];
234
 
        short distance=0;
235
 
        unsigned int index = 0;
236
 
        
237
 
        amount= (size-1)/2;
238
 
 
239
 
        minx = mval[0]-(amount+1);
240
 
        miny = mval[1]-(amount+1);
241
 
        buf = read_backbuf(minx, miny, minx+size-1, miny+size-1);
242
 
        if (!buf)
243
 
                return 0;
244
 
 
245
 
        rc= 0;
246
 
        
247
 
        dirvec[0][0]= 1; dirvec[0][1]= 0;
248
 
        dirvec[1][0]= 0; dirvec[1][1]= -size;
249
 
        dirvec[2][0]= -1; dirvec[2][1]= 0;
250
 
        dirvec[3][0]= 0; dirvec[3][1]= size;
251
 
        
252
 
        bufmin= buf;
253
 
        bufmax= buf+ size*size;
254
 
        buf+= amount*size+ amount;
255
 
        
256
 
        for(nr=1; nr<=size; nr++) {
257
 
                
258
 
                for(a=0; a<2; a++) {
259
 
                        for(b=0; b<nr; b++, distance++) {
260
 
                                if (*buf && *buf>=min && *buf<max) {
261
 
                                        *dist= (short) sqrt( (float)distance ); // XXX, this distance is wrong - zr
262
 
                                        index = *buf - min+1; // messy yah, but indices start at 1
263
 
                                        goto exit;
264
 
                                }
265
 
                                
266
 
                                buf+= (dirvec[rc][0]+dirvec[rc][1]);
267
 
                                
268
 
                                if(buf<bufmin || buf>=bufmax) {
269
 
                                        goto exit;
270
 
                                }
271
 
                        }
272
 
                        rc++;
273
 
                        rc &= 3;
274
 
                }
275
 
        }
276
 
 
277
 
exit:
278
 
        MEM_freeN(bufmin);
279
 
        return index;
280
 
}
 
124
unsigned int em_solidoffs=0, em_wireoffs=0, em_vertoffs=0;      /* set in drawobject.c ... for colorindices */
281
125
 
282
126
/* facilities for border select and circle select */
283
127
static char *selbuf= NULL;
307
151
        filldisplist(&lb, &lb);
308
152
 
309
153
        /* do the draw */
310
 
        dl= lb.first;   // filldisplist adds in head of list
 
154
        dl= lb.first;   /* filldisplist adds in head of list */
311
155
        if(dl->type==DL_INDEX3) {
312
156
                int *index;
313
157
                
332
176
/* returns if all is OK */
333
177
int EM_init_backbuf_border(short xmin, short ymin, short xmax, short ymax)
334
178
{
335
 
        unsigned int *buf, *dr;
 
179
        struct ImBuf *buf;
 
180
        unsigned int *dr;
336
181
        int a;
337
182
        
338
183
        if(G.obedit==NULL || G.vd->drawtype<OB_SOLID || (G.vd->flag & V3D_ZBUF_SELECT)==0) return 0;
339
184
        if(em_vertoffs==0) return 0;
340
185
        
341
 
        dr= buf= read_backbuf(xmin, ymin, xmax, ymax);
 
186
        buf= read_backbuf(xmin, ymin, xmax, ymax);
342
187
        if(buf==NULL) return 0;
 
188
 
 
189
        dr = buf->rect;
343
190
        
344
191
        /* build selection lookup */
345
192
        selbuf= MEM_callocN(em_vertoffs+1, "selbuf");
350
197
                        selbuf[*dr]= 1;
351
198
                dr++;
352
199
        }
353
 
        MEM_freeN(buf);
 
200
        IMB_freeImBuf(buf);
354
201
        return 1;
355
202
}
356
203
 
376
223
*/
377
224
int EM_mask_init_backbuf_border(short mcords[][2], short tot, short xmin, short ymin, short xmax, short ymax)
378
225
{
379
 
        unsigned int *buf, *bufmask, *dr, *drm;
 
226
        unsigned int *dr, *drm;
 
227
        struct ImBuf *buf, *bufmask;
380
228
        int a;
381
229
        
382
230
        /* method in use for face selecting too */
388
236
 
389
237
        if(em_vertoffs==0) return 0;
390
238
        
391
 
        dr= buf= read_backbuf(xmin, ymin, xmax, ymax);
 
239
        buf= read_backbuf(xmin, ymin, xmax, ymax);
392
240
        if(buf==NULL) return 0;
393
241
 
 
242
        dr = buf->rect;
 
243
 
394
244
        /* draw the mask */
395
245
#ifdef __APPLE__
396
246
        glDrawBuffer(GL_AUX0);
403
253
        /* yah, opengl doesn't do concave... tsk! */
404
254
        draw_triangulated(mcords, tot); 
405
255
        
406
 
        glBegin(GL_LINE_LOOP);  // for zero sized masks, lines
 
256
        glBegin(GL_LINE_LOOP);  /* for zero sized masks, lines */
407
257
        for(a=0; a<tot; a++) glVertex2s(mcords[a][0], mcords[a][1]);
408
258
        glEnd();
409
259
        
410
260
        persp(PERSP_VIEW);
411
 
        glFinish();     // to be sure readpixels sees mask
 
261
        glFinish();     /* to be sure readpixels sees mask */
412
262
        
413
263
        glDrawBuffer(GL_BACK);
414
264
        
415
265
        /* grab mask */
416
 
        drm= bufmask= read_backbuf(xmin, ymin, xmax, ymax);
417
 
        if(bufmask==NULL) return 0; // only when mem alloc fails, go crash somewhere else!
 
266
        bufmask= read_backbuf(xmin, ymin, xmax, ymax);
 
267
        drm = bufmask->rect;
 
268
        if(bufmask==NULL) return 0; /* only when mem alloc fails, go crash somewhere else! */
418
269
        
419
270
        /* build selection lookup */
420
271
        selbuf= MEM_callocN(em_vertoffs+1, "selbuf");
424
275
                if(*dr>0 && *dr<=em_vertoffs && *drm==0) selbuf[*dr]= 1;
425
276
                dr++; drm++;
426
277
        }
427
 
        MEM_freeN(buf);
428
 
        MEM_freeN(bufmask);
 
278
        IMB_freeImBuf(buf);
 
279
        IMB_freeImBuf(bufmask);
429
280
        return 1;
430
281
        
431
282
}
433
284
/* circle shaped sample area */
434
285
int EM_init_backbuf_circle(short xs, short ys, short rads)
435
286
{
436
 
        unsigned int *buf, *dr;
 
287
        struct ImBuf *buf;
 
288
        unsigned int *dr;
437
289
        short xmin, ymin, xmax, ymax, xc, yc;
438
290
        int radsq;
439
291
        
447
299
        
448
300
        xmin= xs-rads; xmax= xs+rads;
449
301
        ymin= ys-rads; ymax= ys+rads;
450
 
        dr= buf= read_backbuf(xmin, ymin, xmax, ymax);
 
302
        buf= read_backbuf(xmin, ymin, xmax, ymax);
451
303
        if(buf==NULL) return 0;
 
304
 
 
305
        dr = buf->rect;
452
306
        
453
307
        /* build selection lookup */
454
308
        selbuf= MEM_callocN(em_vertoffs+1, "selbuf");
461
315
                }
462
316
        }
463
317
 
464
 
        MEM_freeN(buf);
 
318
        IMB_freeImBuf(buf);
465
319
        return 1;
466
320
        
467
321
}
468
322
 
469
323
static void findnearestvert__doClosest(void *userData, EditVert *eve, int x, int y, int index)
470
324
{
471
 
        struct { short mval[2], pass, select, dist; int lastIndex, closestIndex; EditVert *closest; } *data = userData;
 
325
        struct { short mval[2], pass, select; int dist, lastIndex, closestIndex; EditVert *closest; } *data = userData;
472
326
 
473
327
        if (data->pass==0) {
474
328
                if (index<=data->lastIndex)
479
333
        }
480
334
 
481
335
        if (data->dist>3) {
482
 
                short temp = abs(data->mval[0] - x) + abs(data->mval[1]- y);
 
336
                int temp = abs(data->mval[0] - x) + abs(data->mval[1]- y);
483
337
                if ((eve->f&1)==data->select) temp += 5;
484
338
 
485
339
                if (temp<data->dist) {
508
362
                }
509
363
        }
510
364
        else {
511
 
                struct { short mval[2], pass, select, dist; int lastIndex, closestIndex; EditVert *closest; } data;
 
365
                struct { short mval[2], pass, select; int dist, lastIndex, closestIndex; EditVert *closest; } data;
512
366
                static int lastSelectedIndex=0;
513
367
                static EditVert *lastSelected=NULL;
514
368
 
672
526
 
673
527
                        data.mval[0] = mval[0];
674
528
                        data.mval[1] = mval[1];
675
 
                        data.dist = 0x7FFF;             // largest short
 
529
                        data.dist = 0x7FFF;             /* largest short */
676
530
                        data.toFace = efa;
677
531
 
678
532
                        mesh_foreachScreenFace(findnearestface__getDistance, &data);
679
533
 
680
 
                        if(G.scene->selectmode == SCE_SELECT_FACE || data.dist<*dist) { // only faces, no dist check
 
534
                        if(G.scene->selectmode == SCE_SELECT_FACE || data.dist<*dist) { /* only faces, no dist check */
681
535
                                *dist= data.dist;
682
536
                                return efa;
683
537
                        }
875
729
        if(G.scene->selectmode & SCE_SELECT_FACE)
876
730
                *efa= findnearestface(&dist);
877
731
 
878
 
        dist-= 20;      // since edges select lines, we give dots advantage of 20 pix
 
732
        dist-= 20;      /* since edges select lines, we give dots advantage of 20 pix */
879
733
        if(G.scene->selectmode & SCE_SELECT_EDGE)
880
734
                *eed= findnearestedge(&dist);
881
735
 
890
744
        return (*eve || *eed || *efa);
891
745
}
892
746
 
 
747
/* this as a way to compare the ares, perim  of 2 faces thay will scale to different sizes */
 
748
#define SCALE_CMP(a,b) (fabs(a-b) <= thresh*a || (a>0 && fabs(b/a)<=thresh))
 
749
 
 
750
/* ****************  GROUP SELECTS ************** */
 
751
/* selects new faces/edges/verts based on the
 
752
 existing selection
 
753
 
 
754
FACES GROUP
 
755
 mode 1: same material
 
756
 mode 2: same image
 
757
 mode 3: same area
 
758
 mode 4: same perimeter
 
759
 mode 5: same normal
 
760
 mode 6: same co-planer
 
761
*/
 
762
int facegroup_select(short mode)
 
763
{
 
764
        EditMesh *em = G.editMesh;
 
765
        EditFace *efa, *base_efa=NULL;
 
766
        unsigned int selcount=0; /*count how many new faces we select*/
 
767
        
 
768
        /*deselcount, count how many deselected faces are left, so we can bail out early
 
769
        also means that if there are no deselected faces, we can avoid a lot of looping */
 
770
        unsigned int deselcount=0; 
 
771
        
 
772
        short ok=0;
 
773
        float thresh=G.scene->toolsettings->select_thresh;
 
774
        
 
775
        for(efa= em->faces.first; efa; efa= efa->next) {
 
776
                if (!efa->h) {
 
777
                        if (efa->f & SELECT) {
 
778
                                efa->f1=1;
 
779
                                ok=1;
 
780
                        } else {
 
781
                                efa->f1=0;
 
782
                                deselcount++; /* a deselected face we may select later */
 
783
                        }
 
784
                }
 
785
        }
 
786
        
 
787
        if (!ok || !deselcount) /* no data selected OR no more data to select */
 
788
                return 0;
 
789
        
 
790
        /*if mode is 3 then record face areas, 4 record perimeter */
 
791
        if (mode==3) {
 
792
                for(efa= em->faces.first; efa; efa= efa->next) {
 
793
                        efa->tmp.fp= EM_face_area(efa);
 
794
                }
 
795
        } else if (mode==4) {
 
796
                for(efa= em->faces.first; efa; efa= efa->next) {
 
797
                        efa->tmp.fp= EM_face_perimeter(efa);
 
798
                }
 
799
        }
 
800
        
 
801
        for(base_efa= em->faces.first; base_efa; base_efa= base_efa->next) {
 
802
                if (base_efa->f1) {
 
803
                        if (mode==1) { /* same material */
 
804
                                for(efa= em->faces.first; efa; efa= efa->next) {
 
805
                                        if (
 
806
                                                !(efa->f & SELECT) &&
 
807
                                                !efa->h &&
 
808
                                                base_efa->mat_nr == efa->mat_nr
 
809
                                        ) {
 
810
                                                EM_select_face(efa, 1);
 
811
                                                selcount++;
 
812
                                                deselcount--;
 
813
                                                if (!deselcount) /*have we selected all posible faces?, if so return*/
 
814
                                                        return selcount;
 
815
                                        }
 
816
                                }
 
817
                        } else if (mode==2) { /* same image */
 
818
                                for(efa= em->faces.first; efa; efa= efa->next) {
 
819
                                        if (!(efa->f & SELECT) && !efa->h && base_efa->tf.tpage == efa->tf.tpage) {
 
820
                                                EM_select_face(efa, 1);
 
821
                                                selcount++;
 
822
                                                deselcount--;
 
823
                                                if (!deselcount) /*have we selected all posible faces?, if so return*/
 
824
                                                        return selcount;
 
825
                                        }
 
826
                                }
 
827
                        } else if (mode==3 || mode==4) { /* same area OR same perimeter, both use the same temp var */
 
828
                                for(efa= em->faces.first; efa; efa= efa->next) {
 
829
                                        if (!(efa->f & SELECT) && !efa->h) {
 
830
                                                if (SCALE_CMP(base_efa->tmp.fp, efa->tmp.fp)) {
 
831
                                                
 
832
                                                        EM_select_face(efa, 1);
 
833
                                                        selcount++;
 
834
                                                        deselcount--;
 
835
                                                        if (!deselcount) /*have we selected all posible faces?, if so return*/
 
836
                                                                return selcount;
 
837
                                                }
 
838
                                        }
 
839
                                }
 
840
                        } else if (mode==5) { /* same normal */
 
841
                                float angle;
 
842
                                for(efa= em->faces.first; efa; efa= efa->next) {
 
843
                                        if (!(efa->f & SELECT) && !efa->h) {
 
844
                                                angle= VecAngle2(base_efa->n, efa->n);
 
845
                                                if (angle/180.0<=thresh) {
 
846
                                                        EM_select_face(efa, 1);
 
847
                                                        selcount++;
 
848
                                                        deselcount--;
 
849
                                                        if (!deselcount) /*have we selected all posible faces?, if so return*/
 
850
                                                                return selcount;
 
851
                                                }
 
852
                                        }
 
853
                                }
 
854
                        } else if (mode==6) { /* same planer */
 
855
                                float angle, base_dot, dot;
 
856
                                base_dot= Inpf(base_efa->cent, base_efa->n);
 
857
                                for(efa= em->faces.first; efa; efa= efa->next) {
 
858
                                        if (!(efa->f & SELECT) && !efa->h) {
 
859
                                                angle= VecAngle2(base_efa->n, efa->n);
 
860
                                                if (angle/180.0<=thresh) {
 
861
                                                        dot=Inpf(efa->cent, base_efa->n);
 
862
                                                        if (fabs(base_dot-dot) <= thresh) {
 
863
                                                                EM_select_face(efa, 1);
 
864
                                                                selcount++;
 
865
                                                                deselcount--;
 
866
                                                                if (!deselcount) /*have we selected all posible faces?, if so return*/
 
867
                                                                        return selcount;
 
868
                                                        }
 
869
                                                }
 
870
                                        }
 
871
                                }
 
872
                        }
 
873
                }
 
874
        } /* end base_efa loop */
 
875
        return selcount;
 
876
}
 
877
 
 
878
 
 
879
/*
 
880
EDGE GROUP
 
881
 mode 1: same length
 
882
 mode 2: same direction
 
883
 mode 3: same number of face users
 
884
 mode 4: similar face angles.
 
885
 mode 5: similar crease
 
886
*/
 
887
 
 
888
/* this function is only used by edgegroup_select's edge angle */
 
889
 
 
890
 
 
891
 
 
892
int edgegroup_select(short mode)
 
893
{
 
894
        EditMesh *em = G.editMesh;
 
895
        EditEdge *eed, *base_eed=NULL;
 
896
        unsigned int selcount=0; /* count how many new edges we select*/
 
897
        
 
898
        /*count how many visible selected edges there are,
 
899
        so we can return when there are none left */
 
900
        unsigned int deselcount=0;
 
901
        
 
902
        short ok=0;
 
903
        float thresh=G.scene->toolsettings->select_thresh;
 
904
        
 
905
        for(eed= em->edges.first; eed; eed= eed->next) {
 
906
                if (!eed->h) {
 
907
                        if (eed->f & SELECT) {
 
908
                                eed->f1=1;
 
909
                                ok=1;
 
910
                        } else {
 
911
                                eed->f1=0;
 
912
                                deselcount++;
 
913
                        }
 
914
                        /* set all eed->tmp.l to 0 we use it later.
 
915
                        for counting face users*/
 
916
                        eed->tmp.l=0;
 
917
                        eed->f2=0; /* only for mode 4, edge animations */
 
918
                }
 
919
        }
 
920
        
 
921
        if (!ok || !deselcount) /* no data selected OR no more data to select*/
 
922
                return 0;
 
923
        
 
924
        if (mode==1) { /*store length*/
 
925
                for(eed= em->edges.first; eed; eed= eed->next) {
 
926
                        eed->tmp.fp= VecLenf(eed->v1->co, eed->v2->co);
 
927
                }
 
928
        } else if (mode==3) { /*store face users*/
 
929
                EditFace *efa;
 
930
                /* cound how many faces each edge uses use tmp->l */
 
931
                for(efa= em->faces.first; efa; efa= efa->next) {
 
932
                        efa->e1->tmp.l++;
 
933
                        efa->e2->tmp.l++;
 
934
                        efa->e3->tmp.l++;
 
935
                        if (efa->e4) efa->e4->tmp.l++;
 
936
                }
 
937
        } else if (mode==4) { /*store edge angles */
 
938
                EditFace *efa;
 
939
                int j;
 
940
                /* cound how many faces each edge uses use tmp.l */
 
941
                for(efa= em->faces.first; efa; efa= efa->next) {
 
942
                        /* here we use the edges temp data to assign a face
 
943
                        if a face has alredy been assigned (eed->f2==1)
 
944
                        we calculate the angle between the current face and
 
945
                        the edges previously found face.
 
946
                        store the angle in eed->tmp.fp (loosing the face eed->tmp.f)
 
947
                        but tagging eed->f2==2, so we know not to look at it again.
 
948
                        This only works for edges that connect to 2 faces. but its good enough
 
949
                        */
 
950
                        
 
951
                        /* se we can loop through face edges*/
 
952
                        j=0;
 
953
                        eed= efa->e1;
 
954
                        while (j<4) {
 
955
                                if (j==1) eed= efa->e2;
 
956
                                else if (j==2) eed= efa->e3;
 
957
                                else if (j==3) {
 
958
                                        eed= efa->e4;
 
959
                                        if (!eed)
 
960
                                                break;
 
961
                                } /* done looping */
 
962
                                
 
963
                                if (eed->f2==2)
 
964
                                        break;
 
965
                                else if (eed->f2==0) /* first access, assign the face */
 
966
                                        eed->tmp.f= efa;
 
967
                                else if (eed->f2==1) /* second, we assign the angle*/
 
968
                                        eed->tmp.fp= VecAngle2(eed->tmp.f->n, efa->n)/180;
 
969
                                eed->f2++; /* f2==0 no face assigned. f2==1 one face found. f2==2 angle calculated.*/
 
970
                                j++;
 
971
                        }
 
972
                }
 
973
        }
 
974
        
 
975
        for(base_eed= em->edges.first; base_eed; base_eed= base_eed->next) {
 
976
                if (base_eed->f1) {
 
977
                        if (mode==1) { /* same length */
 
978
                                for(eed= em->edges.first; eed; eed= eed->next) {
 
979
                                        if (
 
980
                                                !(eed->f & SELECT) &&
 
981
                                                !eed->h &&
 
982
                                                (SCALE_CMP(base_eed->tmp.fp, eed->tmp.fp))
 
983
                                        ) {
 
984
                                                EM_select_edge(eed, 1);
 
985
                                                selcount++;
 
986
                                                deselcount--;
 
987
                                                if (!deselcount) /*have we selected all posible faces?, if so return*/
 
988
                                                        return selcount;
 
989
                                        }
 
990
                                }
 
991
                        } else if (mode==2) { /* same direction */
 
992
                                float base_dir[3], dir[3], angle;
 
993
                                VecSubf(base_dir, base_eed->v1->co, base_eed->v2->co);
 
994
                                for(eed= em->edges.first; eed; eed= eed->next) {
 
995
                                        if (!(eed->f & SELECT) && !eed->h) {
 
996
                                                VecSubf(dir, eed->v1->co, eed->v2->co);
 
997
                                                angle= VecAngle2(base_dir, dir);
 
998
                                                
 
999
                                                if (angle>90) /* use the smallest angle between the edges */
 
1000
                                                        angle= fabs(angle-180.0f);
 
1001
                                                
 
1002
                                                if (angle/90.0<=thresh) {
 
1003
                                                        EM_select_edge(eed, 1);
 
1004
                                                        selcount++;
 
1005
                                                        deselcount--;
 
1006
                                                        if (!deselcount) /*have we selected all posible faces?, if so return*/
 
1007
                                                                return selcount;
 
1008
                                                }
 
1009
                                        }
 
1010
                                }
 
1011
                        } else if (mode==3) { /* face users */                          
 
1012
                                for(eed= em->edges.first; eed; eed= eed->next) {
 
1013
                                        if (
 
1014
                                                !(eed->f & SELECT) &&
 
1015
                                                !eed->h &&
 
1016
                                                base_eed->tmp.l==eed->tmp.l
 
1017
                                        ) {
 
1018
                                                EM_select_edge(eed, 1);
 
1019
                                                selcount++;
 
1020
                                                deselcount--;
 
1021
                                                if (!deselcount) /*have we selected all posible faces?, if so return*/
 
1022
                                                        return selcount;
 
1023
                                        }
 
1024
                                }
 
1025
                        } else if (mode==4 && base_eed->f2==2) { /* edge angles, f2==2 means the edge has an angle. */                          
 
1026
                                for(eed= em->edges.first; eed; eed= eed->next) {
 
1027
                                        if (
 
1028
                                                !(eed->f & SELECT) &&
 
1029
                                                !eed->h &&
 
1030
                                                eed->f2==2 &&
 
1031
                                                (fabs(base_eed->tmp.fp-eed->tmp.fp)<=thresh)
 
1032
                                        ) {
 
1033
                                                EM_select_edge(eed, 1);
 
1034
                                                selcount++;
 
1035
                                                deselcount--;
 
1036
                                                if (!deselcount) /*have we selected all posible faces?, if so return*/
 
1037
                                                        return selcount;
 
1038
                                        }
 
1039
                                }
 
1040
                        } else if (mode==5) { /* edge crease */
 
1041
                                for(eed= em->edges.first; eed; eed= eed->next) {
 
1042
                                        if (
 
1043
                                                !(eed->f & SELECT) &&
 
1044
                                                !eed->h &&
 
1045
                                                (fabs(base_eed->crease-eed->crease) <= thresh)
 
1046
                                        ) {
 
1047
                                                EM_select_edge(eed, 1);
 
1048
                                                selcount++;
 
1049
                                                deselcount--;
 
1050
                                                if (!deselcount) /*have we selected all posible faces?, if so return*/
 
1051
                                                        return selcount;
 
1052
                                        }
 
1053
                                }
 
1054
                        }
 
1055
                }
 
1056
        } 
 
1057
        return selcount;
 
1058
}
 
1059
 
 
1060
 
 
1061
/*
 
1062
VERT GROUP
 
1063
 mode 1: same normal
 
1064
 mode 2: same number of face users
 
1065
 mode 3: same vertex groups
 
1066
*/
 
1067
int vertgroup_select(short mode)
 
1068
{
 
1069
        EditMesh *em = G.editMesh;
 
1070
        EditVert *eve, *base_eve=NULL;
 
1071
        
 
1072
        unsigned int selcount=0; /* count how many new edges we select*/
 
1073
        
 
1074
        /*count how many visible selected edges there are,
 
1075
        so we can return when there are none left */
 
1076
        unsigned int deselcount=0;
 
1077
        
 
1078
        short ok=0;
 
1079
        float thresh=G.scene->toolsettings->select_thresh;
 
1080
        
 
1081
        for(eve= em->verts.first; eve; eve= eve->next) {
 
1082
                if (!eve->h) {
 
1083
                        if (eve->f & SELECT) {
 
1084
                                eve->f1=1;
 
1085
                                ok=1;
 
1086
                        } else {
 
1087
                                eve->f1=0;
 
1088
                                deselcount++;
 
1089
                        }
 
1090
                        /* set all eve->tmp.l to 0 we use them later.*/
 
1091
                        eve->tmp.l=0;
 
1092
                }
 
1093
                
 
1094
        }
 
1095
        
 
1096
        if (!ok || !deselcount) /* no data selected OR no more data to select*/
 
1097
                return 0;
 
1098
        
 
1099
        
 
1100
        if (mode==2) { /* store face users */
 
1101
                EditFace *efa;
 
1102
                
 
1103
                /* count how many faces each edge uses use tmp->l */
 
1104
                for(efa= em->faces.first; efa; efa= efa->next) {
 
1105
                        efa->v1->tmp.l++;
 
1106
                        efa->v2->tmp.l++;
 
1107
                        efa->v3->tmp.l++;
 
1108
                        if (efa->v4) efa->v4->tmp.l++;
 
1109
                }
 
1110
        }
 
1111
        
 
1112
        
 
1113
        for(base_eve= em->verts.first; base_eve; base_eve= base_eve->next) {
 
1114
                if (base_eve->f1) {
 
1115
                                
 
1116
                        if (mode==1) { /* same normal */
 
1117
                                float angle;
 
1118
                                for(eve= em->verts.first; eve; eve= eve->next) {
 
1119
                                        if (!(eve->f & SELECT) && !eve->h) {
 
1120
                                                angle= VecAngle2(base_eve->no, eve->no);
 
1121
                                                if (angle/180.0<=thresh) {
 
1122
                                                        eve->f |= SELECT;
 
1123
                                                        selcount++;
 
1124
                                                        deselcount--;
 
1125
                                                        if (!deselcount) /*have we selected all posible faces?, if so return*/
 
1126
                                                                return selcount;
 
1127
                                                }
 
1128
                                        }
 
1129
                                }
 
1130
                        } else if (mode==2) { /* face users */
 
1131
                                for(eve= em->verts.first; eve; eve= eve->next) {
 
1132
                                        if (
 
1133
                                                !(eve->f & SELECT) &&
 
1134
                                                !eve->h &&
 
1135
                                                base_eve->tmp.l==eve->tmp.l
 
1136
                                        ) {
 
1137
                                                eve->f |= SELECT;
 
1138
                                                selcount++;
 
1139
                                                deselcount--;
 
1140
                                                if (!deselcount) /*have we selected all posible faces?, if so return*/
 
1141
                                                        return selcount;
 
1142
                                        }
 
1143
                                }
 
1144
                        } else if (mode==3 && base_eve->totweight != 0) { /* vertex groups */
 
1145
                                short i,j; /*weight index*/
 
1146
                                
 
1147
                                for(eve= em->verts.first; eve; eve= eve->next) {
 
1148
                                        if (
 
1149
                                                !(eve->f & SELECT) &&
 
1150
                                                !eve->h &&
 
1151
                                                eve->totweight
 
1152
                                        ) {
 
1153
                                                /* do the extra check for selection in the following if, so were not
 
1154
                                                checking verts that may be alredy selected */
 
1155
                                                for (i=0; base_eve->totweight >i && !(eve->f & SELECT); i++) { 
 
1156
                                                        for (j=0; eve->totweight >j; j++) {
 
1157
                                                                if (base_eve->dw[i].def_nr==eve->dw[j].def_nr) {
 
1158
                                                                        eve->f |= SELECT;
 
1159
                                                                        selcount++;
 
1160
                                                                        deselcount--;
 
1161
                                                                        if (!deselcount) /*have we selected all posible faces?, if so return*/
 
1162
                                                                                return selcount;
 
1163
                                                                        break;
 
1164
                                                                }
 
1165
                                                        }
 
1166
                                                }
 
1167
                                        }
 
1168
                                }
 
1169
                        }
 
1170
                }
 
1171
        } /* end basevert loop */
 
1172
        return selcount;
 
1173
}
 
1174
 
 
1175
/* EditMode menu triggered from space.c by pressing Shift+G
 
1176
handles face/edge vert context and
 
1177
facegroup_select/edgegroup_select/vertgroup_select do all the work
 
1178
*/
 
1179
void select_mesh_group_menu()
 
1180
{
 
1181
        short ret;
 
1182
        int selcount;
 
1183
        
 
1184
        if(G.scene->selectmode & SCE_SELECT_FACE) {
 
1185
                ret= pupmenu("Select Grouped Faces %t|Same Material %x1|Same Image %x2|Similar Area %x3|Similar Perimeter %x4|Similar Normal %x5|Similar Co-Planer %x6");
 
1186
                if (ret<1) return;
 
1187
                selcount= facegroup_select(ret);
 
1188
                
 
1189
                if (selcount) { /* update if data was selected */
 
1190
                        G.totfacesel+=selcount;
 
1191
                        allqueue(REDRAWVIEW3D, 0);
 
1192
                        BIF_undo_push("Select Grouped Faces");
 
1193
                }
 
1194
                
 
1195
        } else if(G.scene->selectmode & SCE_SELECT_EDGE) {
 
1196
                ret= pupmenu("Select Grouped Edges%t|Similar Length %x1|Similar Direction %x2|Same Face Users%x3|Similar Adjacent Face Angle%x4|Similar Crease%x5");
 
1197
                if (ret<1) return;
 
1198
                selcount= edgegroup_select(ret);
 
1199
                
 
1200
                if (selcount) { /* update if data was selected */
 
1201
                        /*EM_select_flush();*/ /* dont use because it can end up selecting more edges and is not usefull*/
 
1202
                        G.totedgesel+=selcount;
 
1203
                        allqueue(REDRAWVIEW3D, 0);
 
1204
                        BIF_undo_push("Select Grouped Edges");
 
1205
                }
 
1206
                
 
1207
        } else if(G.scene->selectmode & SCE_SELECT_VERTEX) {
 
1208
                ret= pupmenu("Select Grouped Verts%t|Similar Normal %x1|Same Face Users %x2|Shared Vertex Groups%x3");
 
1209
                if (ret<1) return;
 
1210
                selcount= vertgroup_select(ret);
 
1211
                
 
1212
                if (selcount) { /* update if data was selected */
 
1213
                        EM_select_flush(); /* so that selected verts, go onto select faces */
 
1214
                        G.totedgesel+=selcount;
 
1215
                        allqueue(REDRAWVIEW3D, 0);
 
1216
                        BIF_undo_push("Select Grouped Verts");
 
1217
                }
 
1218
        }
 
1219
        
 
1220
}
 
1221
 
 
1222
 
893
1223
/* ****************  LOOP SELECTS *************** */
894
1224
 
895
1225
/* selects quads in loop direction of indicated edge */
919
1249
                }
920
1250
        }
921
1251
        
922
 
        // tag startedge OK
 
1252
        /* tag startedge OK*/
923
1253
        startedge->f2= 1;
924
1254
        
925
1255
        while(looking) {
926
1256
                looking= 0;
927
1257
                
928
1258
                for(efa= em->faces.first; efa; efa= efa->next) {
929
 
                        if(efa->e4 && efa->f1==0) {     // not done quad
930
 
                                if(efa->e1->f1<=2 && efa->e2->f1<=2 && efa->e3->f1<=2 && efa->e4->f1<=2) { // valence ok
 
1259
                        if(efa->e4 && efa->f1==0) {     /* not done quad */
 
1260
                                if(efa->e1->f1<=2 && efa->e2->f1<=2 && efa->e3->f1<=2 && efa->e4->f1<=2) { /* valence ok */
931
1261
 
932
 
                                        // if edge tagged, select opposing edge and mark face ok
 
1262
                                        /* if edge tagged, select opposing edge and mark face ok */
933
1263
                                        if(efa->e1->f2) {
934
1264
                                                efa->e3->f2= 1;
935
1265
                                                efa->f1= 1;
972
1302
        
973
1303
        for(efa= em->faces.first; efa; efa= efa->next) {
974
1304
                if(efa->h==0) {
975
 
                        if(efa->e1==eed || efa->e2==eed || efa->e3==eed || efa->e4==eed) {      // edge is in face
976
 
                                if(efa->e1->f2 || efa->e2->f2 || efa->e3->f2 || (efa->e4 && efa->e4->f2)) {     // face is tagged
 
1305
                        if(efa->e1==eed || efa->e2==eed || efa->e3==eed || efa->e4==eed) {      /* edge is in face */
 
1306
                                if(efa->e1->f2 || efa->e2->f2 || efa->e3->f2 || (efa->e4 && efa->e4->f2)) {     /* face is tagged */
977
1307
                                        return 0;
978
1308
                                }
979
1309
                        }
1010
1340
        for(eed= em->edges.first; eed; eed= eed->next) {
1011
1341
                eed->f1= 0;
1012
1342
                eed->f2= 0;
1013
 
                if((eed->h & 1)==0) {   // fgon edges add to valence too
 
1343
                if((eed->h & 1)==0) {   /* fgon edges add to valence too */
1014
1344
                        eed->v1->f1++; eed->v2->f1++;
1015
1345
                }
1016
1346
        }
1036
1366
                
1037
1367
                /* find correct valence edges which are not tagged yet, but connect to tagged one */
1038
1368
                for(eed= em->edges.first; eed; eed= eed->next) {
1039
 
                        if(eed->h==0 && eed->f2==0) { // edge not hidden, not tagged
1040
 
                                if( (eed->v1->f1<5 && eed->v1->f2) || (eed->v2->f1<5 && eed->v2->f2)) { // valence of vertex OK, and is tagged
 
1369
                        if(eed->h==0 && eed->f2==0) { /* edge not hidden, not tagged */
 
1370
                                if( (eed->v1->f1<5 && eed->v1->f2) || (eed->v2->f1<5 && eed->v2->f2)) { /* valence of vertex OK, and is tagged */
1041
1371
                                        /* new edge is not allowed to be in face with tagged edge */
1042
1372
                                        if(edge_not_in_tagged_face(eed)) {
1043
 
                                                if(eed->f1==starteed->f1) {     // same amount of faces
 
1373
                                                if(eed->f1==starteed->f1) {     /* same amount of faces */
1044
1374
                                                        looking= 1;
1045
1375
                                                        eed->f2= 1;
1046
1376
                                                        if(eed->v2->f1<5) eed->v2->f2= 1;
1084
1414
                }
1085
1415
        }
1086
1416
        
1087
 
        // tag startedge OK
 
1417
        /* tag startedge OK */
1088
1418
        startedge->f2= 1;
1089
1419
        
1090
1420
        while(looking) {
1091
1421
                looking= 0;
1092
1422
                
1093
1423
                for(efa= em->faces.first; efa; efa= efa->next) {
1094
 
                        if(efa->e4 && efa->f1==0) {     // not done quad
1095
 
                                if(efa->e1->f1<=2 && efa->e2->f1<=2 && efa->e3->f1<=2 && efa->e4->f1<=2) { // valence ok
 
1424
                        if(efa->e4 && efa->f1==0 && !efa->h) {  /* not done quad */
 
1425
                                if(efa->e1->f1<=2 && efa->e2->f1<=2 && efa->e3->f1<=2 && efa->e4->f1<=2) { /* valence ok */
1096
1426
 
1097
 
                                        // if edge tagged, select opposing edge and mark face ok
 
1427
                                        /* if edge tagged, select opposing edge and mark face ok */
1098
1428
                                        if(efa->e1->f2) {
1099
1429
                                                efa->e3->f2= 1;
1100
1430
                                                efa->f1= 1;
1125
1455
                if(eed->f2) EM_select_edge(eed, select);
1126
1456
        }
1127
1457
}
 
1458
 
 
1459
void loop_multiselect(int looptype)
 
1460
{
 
1461
        EditEdge *eed;
 
1462
        EditEdge **edarray;
 
1463
        int edindex, edfirstcount;
 
1464
        
 
1465
        /*edarray = MEM_mallocN(sizeof(*edarray)*G.totedgesel,"edge array");*/
 
1466
        edarray = MEM_mallocN(sizeof(EditEdge*)*G.totedgesel,"edge array");
 
1467
        edindex = 0;
 
1468
        edfirstcount = G.totedgesel;
 
1469
        
 
1470
        for(eed=G.editMesh->edges.first; eed; eed=eed->next){
 
1471
                if(eed->f&SELECT){
 
1472
                        edarray[edindex] = eed;
 
1473
                        edindex += 1;
 
1474
                }
 
1475
        }
 
1476
        
 
1477
        if(looptype){
 
1478
                for(edindex = 0; edindex < edfirstcount; edindex +=1){
 
1479
                        eed = edarray[edindex];
 
1480
                        edgering_select(eed,SELECT);
 
1481
                }
 
1482
                countall();
 
1483
                EM_selectmode_flush();
 
1484
                BIF_undo_push("Edge Ring Multi-Select");
 
1485
        }
 
1486
        else{
 
1487
                for(edindex = 0; edindex < edfirstcount; edindex +=1){
 
1488
                        eed = edarray[edindex];
 
1489
                        edgeloop_select(eed,SELECT);
 
1490
                }
 
1491
                countall();
 
1492
                EM_selectmode_flush();
 
1493
                BIF_undo_push("Edge Loop Multi-Select");
 
1494
        }
 
1495
        MEM_freeN(edarray);
 
1496
        allqueue(REDRAWVIEW3D,0);
 
1497
}
 
1498
                
1128
1499
/* ***************** MAIN MOUSE SELECTION ************** */
1129
1500
 
1130
 
// just to have the functions nice together
 
1501
/* just to have the functions nice together */
1131
1502
static void mouse_mesh_loop(void)
1132
1503
{
1133
1504
        EditEdge *eed;
 
1505
        int select;
1134
1506
        short dist= 50;
1135
1507
        
1136
1508
        eed= findnearestedge(&dist);
1138
1510
                
1139
1511
                if((G.qual & LR_SHIFTKEY)==0) EM_clear_flag_all(SELECT);
1140
1512
                
1141
 
                if((eed->f & SELECT)==0) EM_select_edge(eed, 1);
1142
 
                else if(G.qual & LR_SHIFTKEY) EM_select_edge(eed, 0);
 
1513
                if((eed->f & SELECT)==0) select=1;
 
1514
                else if(G.qual & LR_SHIFTKEY) select=0;
1143
1515
 
1144
1516
                if(G.scene->selectmode & SCE_SELECT_FACE) {
1145
 
                        faceloop_select(eed, eed->f & SELECT);
 
1517
                        faceloop_select(eed, select);
1146
1518
                }
1147
1519
                else if(G.scene->selectmode & SCE_SELECT_EDGE) {
1148
1520
            if(G.qual == (LR_CTRLKEY | LR_ALTKEY) || G.qual == (LR_CTRLKEY | LR_ALTKEY |LR_SHIFTKEY))
1149
 
                        edgering_select(eed, eed->f & SELECT);
 
1521
                        edgering_select(eed, select);
1150
1522
            else if(G.qual & LR_ALTKEY)
1151
 
                        edgeloop_select(eed, eed->f & SELECT);
 
1523
                        edgeloop_select(eed, select);
1152
1524
                }
1153
1525
        else if(G.scene->selectmode & SCE_SELECT_VERTEX) {
1154
1526
            if(G.qual == (LR_CTRLKEY | LR_ALTKEY) || G.qual == (LR_CTRLKEY | LR_ALTKEY |LR_SHIFTKEY))
1155
 
                        edgering_select(eed, eed->f & SELECT);
 
1527
                        edgering_select(eed, select);
1156
1528
            else if(G.qual & LR_ALTKEY)
1157
 
                        edgeloop_select(eed, eed->f & SELECT);
 
1529
                        edgeloop_select(eed, select);
1158
1530
                }
1159
1531
 
1160
1532
                /* frontbuffer draw of last selected only */
1183
1555
                if(efa) {
1184
1556
                        
1185
1557
                        if( (efa->f & SELECT)==0 ) {
 
1558
                                EM_store_selection(efa, EDITFACE);
1186
1559
                                EM_select_face_fgon(efa, 1);
1187
1560
                        }
1188
1561
                        else if(G.qual & LR_SHIFTKEY) {
 
1562
                                EM_remove_selection(efa, EDITFACE);
1189
1563
                                EM_select_face_fgon(efa, 0);
1190
1564
                        }
1191
1565
                }
1192
1566
                else if(eed) {
1193
1567
                        if((eed->f & SELECT)==0) {
 
1568
                                EM_store_selection(eed, EDITEDGE);
1194
1569
                                EM_select_edge(eed, 1);
1195
1570
                        }
1196
1571
                        else if(G.qual & LR_SHIFTKEY) {
 
1572
                                EM_remove_selection(eed, EDITEDGE);
1197
1573
                                EM_select_edge(eed, 0);
1198
1574
                        }
1199
1575
                }
1200
1576
                else if(eve) {
1201
 
                        if((eve->f & SELECT)==0) eve->f |= SELECT;
1202
 
                        else if(G.qual & LR_SHIFTKEY) eve->f &= ~SELECT;
 
1577
                        if((eve->f & SELECT)==0) {
 
1578
                                eve->f |= SELECT;
 
1579
                                EM_store_selection(eve, EDITVERT);
 
1580
                        }
 
1581
                        else if(G.qual & LR_SHIFTKEY){ 
 
1582
                                EM_remove_selection(eve, EDITVERT);
 
1583
                                eve->f &= ~SELECT;
 
1584
                        }
1203
1585
                }
1204
1586
                
1205
1587
                /* frontbuffer draw of last selected only */
1433
1815
                        if(eve->f1==1) eve->h= 1;
1434
1816
                }
1435
1817
        }
1436
 
                
 
1818
        
 
1819
        G.totedgesel= G.totfacesel= G.totvertsel= 0;
1437
1820
        allqueue(REDRAWVIEW3D, 0);
1438
1821
        DAG_object_flush_update(G.scene, G.obedit, OB_RECALC_DATA);     
1439
1822
        BIF_undo_push("Hide");
1470
1853
                }
1471
1854
        }
1472
1855
 
1473
 
        EM_fgon_flags();        // redo flags and indices for fgons
 
1856
        EM_fgon_flags();        /* redo flags and indices for fgons */
1474
1857
        EM_selectmode_flush();
1475
1858
        countall();
1476
1859
 
1484
1867
        EditMesh *em = G.editMesh;
1485
1868
        EditFace *efa;
1486
1869
 
1487
 
        /* Selects isolated verts, and edges that do not have 2 neighboring
 
1870
        /* Selects trias/qiads or isolated verts, and edges that do not have 2 neighboring
1488
1871
         * faces
1489
1872
         */
1490
 
        
1491
 
        if(G.scene->selectmode!=SCE_SELECT_FACE) {
 
1873
 
 
1874
        /* for loose vertices/edges, we first select all, loop below will deselect */
 
1875
        if(numverts==5)
 
1876
                EM_set_flag_all(SELECT);
 
1877
        else if(G.scene->selectmode!=SCE_SELECT_FACE) {
1492
1878
                error("Only works in face selection mode");
1493
1879
                return;
1494
1880
        }
1495
 
 
1496
 
        efa= em->faces.first;
1497
 
        while(efa) {
 
1881
        
 
1882
        for(efa= em->faces.first; efa; efa= efa->next) {
1498
1883
                if (efa->e4) {
1499
1884
                        EM_select_face(efa, (numverts==4) );
1500
1885
                }
1501
 
                else if (efa->e3) {
 
1886
                else {
1502
1887
                        EM_select_face(efa, (numverts==3) );
1503
1888
                }
1504
 
                else 
1505
 
                        EM_select_face(efa, (numverts!=3) && (numverts!=4) );
1506
 
                efa= efa->next;
1507
1889
        }
1508
1890
 
1509
1891
        countall();
1517
1899
                BIF_undo_push("Select non-Triangles/Quads");
1518
1900
}
1519
1901
 
 
1902
void select_sharp_edges(void)
 
1903
{
 
1904
        /* Find edges that have exactly two neighboring faces,
 
1905
         * check the angle between those faces, and if angle is
 
1906
         * small enough, select the edge
 
1907
         */
 
1908
        EditMesh *em = G.editMesh;
 
1909
        EditEdge *eed;
 
1910
        EditFace *efa;
 
1911
        EditFace **efa1;
 
1912
        EditFace **efa2;
 
1913
        long edgecount = 0, i;
 
1914
        static short sharpness = 135;
 
1915
        float fsharpness;
 
1916
 
 
1917
        if(G.scene->selectmode==SCE_SELECT_FACE) {
 
1918
                error("Doesn't work in face selection mode");
 
1919
                return;
 
1920
        }
 
1921
 
 
1922
        if(button(&sharpness,0, 180,"Max Angle:")==0) return;
 
1923
        /* if faces are at angle 'sharpness', then the face normals
 
1924
         * are at angle 180.0 - 'sharpness' (convert to radians too)
 
1925
         */
 
1926
        fsharpness = ((180.0 - sharpness) * M_PI) / 180.0;
 
1927
 
 
1928
        i=0;
 
1929
        /* count edges, use tmp.l  */
 
1930
        eed= em->edges.first;
 
1931
        while(eed) {
 
1932
                edgecount++;
 
1933
                eed->tmp.l = i;
 
1934
                eed= eed->next;
 
1935
                ++i;
 
1936
        }
 
1937
 
 
1938
        /* for each edge, we want a pointer to two adjacent faces */
 
1939
        efa1 = MEM_callocN(edgecount*sizeof(EditFace *), 
 
1940
                                           "pairs of edit face pointers");
 
1941
        efa2 = MEM_callocN(edgecount*sizeof(EditFace *), 
 
1942
                                           "pairs of edit face pointers");
 
1943
 
 
1944
#define face_table_edge(eed) { \
 
1945
                i = eed->tmp.l; \
 
1946
                if (i != -1) { \
 
1947
                        if (efa1[i]) { \
 
1948
                                if (efa2[i]) { \
 
1949
                                        /* invalidate, edge has more than two neighbors */ \
 
1950
                                        eed->tmp.l = -1; \
 
1951
                                } \
 
1952
                                else { \
 
1953
                                        efa2[i] = efa; \
 
1954
                                } \
 
1955
                        } \
 
1956
                        else { \
 
1957
                                efa1[i] = efa; \
 
1958
                        } \
 
1959
                } \
 
1960
        }
 
1961
 
 
1962
        /* find the adjacent faces of each edge, we want only two */
 
1963
        efa= em->faces.first;
 
1964
        while(efa) {
 
1965
                face_table_edge(efa->e1);
 
1966
                face_table_edge(efa->e2);
 
1967
                face_table_edge(efa->e3);
 
1968
                if (efa->e4) {
 
1969
                        face_table_edge(efa->e4);
 
1970
                }
 
1971
                efa= efa->next;
 
1972
        }
 
1973
 
 
1974
#undef face_table_edge
 
1975
 
 
1976
        eed = em->edges.first;
 
1977
        while(eed) {
 
1978
                i = eed->tmp.l;
 
1979
                if (i != -1) { 
 
1980
                        /* edge has two or less neighboring faces */
 
1981
                        if ( (efa1[i]) && (efa2[i]) ) { 
 
1982
                                /* edge has exactly two neighboring faces, check angle */
 
1983
                                float angle;
 
1984
                                angle = saacos(efa1[i]->n[0]*efa2[i]->n[0] +
 
1985
                                                           efa1[i]->n[1]*efa2[i]->n[1] +
 
1986
                                                           efa1[i]->n[2]*efa2[i]->n[2]);
 
1987
                                if (fabs(angle) >= fsharpness)
 
1988
                                        EM_select_edge(eed, 1);
 
1989
                        }
 
1990
                }
 
1991
 
 
1992
                eed= eed->next;
 
1993
        }
 
1994
 
 
1995
        MEM_freeN(efa1);
 
1996
        MEM_freeN(efa2);
 
1997
 
 
1998
        countall();
 
1999
        addqueue(curarea->win,  REDRAW, 0);
 
2000
        BIF_undo_push("Select Sharp Edges");
 
2001
}
 
2002
 
 
2003
void select_linked_flat_faces(void)
 
2004
{
 
2005
        /* Find faces that are linked to selected faces that are 
 
2006
         * relatively flat (angle between faces is higher than
 
2007
         * specified angle)
 
2008
         */
 
2009
        EditMesh *em = G.editMesh;
 
2010
        EditEdge *eed;
 
2011
        EditFace *efa;
 
2012
        EditFace **efa1;
 
2013
        EditFace **efa2;
 
2014
        long edgecount = 0, i, faceselcount=0, faceselcountold=0;
 
2015
        static short sharpness = 135;
 
2016
        float fsharpness;
 
2017
 
 
2018
        if(G.scene->selectmode!=SCE_SELECT_FACE) {
 
2019
                error("Only works in face selection mode");
 
2020
                return;
 
2021
        }
 
2022
 
 
2023
        if(button(&sharpness,0, 180,"Min Angle:")==0) return;
 
2024
        /* if faces are at angle 'sharpness', then the face normals
 
2025
         * are at angle 180.0 - 'sharpness' (convert to radians too)
 
2026
         */
 
2027
        fsharpness = ((180.0 - sharpness) * M_PI) / 180.0;
 
2028
 
 
2029
        i=0;
 
2030
        /* count edges, use tmp.l */
 
2031
        eed= em->edges.first;
 
2032
        while(eed) {
 
2033
                edgecount++;
 
2034
                eed->tmp.l = i;
 
2035
                eed= eed->next;
 
2036
                ++i;
 
2037
        }
 
2038
 
 
2039
        /* for each edge, we want a pointer to two adjacent faces */
 
2040
        efa1 = MEM_callocN(edgecount*sizeof(EditFace *), 
 
2041
                                           "pairs of edit face pointers");
 
2042
        efa2 = MEM_callocN(edgecount*sizeof(EditFace *), 
 
2043
                                           "pairs of edit face pointers");
 
2044
 
 
2045
#define face_table_edge(eed) { \
 
2046
                i = eed->tmp.l; \
 
2047
                if (i != -1) { \
 
2048
                        if (efa1[i]) { \
 
2049
                                if (efa2[i]) { \
 
2050
                                        /* invalidate, edge has more than two neighbors */ \
 
2051
                                        eed->tmp.l = -1; \
 
2052
                                } \
 
2053
                                else { \
 
2054
                                        efa2[i] = efa; \
 
2055
                                } \
 
2056
                        } \
 
2057
                        else { \
 
2058
                                efa1[i] = efa; \
 
2059
                        } \
 
2060
                } \
 
2061
        }
 
2062
 
 
2063
        /* find the adjacent faces of each edge, we want only two */
 
2064
        efa= em->faces.first;
 
2065
        while(efa) {
 
2066
                face_table_edge(efa->e1);
 
2067
                face_table_edge(efa->e2);
 
2068
                face_table_edge(efa->e3);
 
2069
                if (efa->e4) {
 
2070
                        face_table_edge(efa->e4);
 
2071
                }
 
2072
 
 
2073
                /* while were at it, count the selected faces */
 
2074
                if (efa->f & SELECT) ++faceselcount;
 
2075
 
 
2076
                efa= efa->next;
 
2077
        }
 
2078
 
 
2079
#undef face_table_edge
 
2080
 
 
2081
        eed= em->edges.first;
 
2082
        while(eed) {
 
2083
                i = eed->tmp.l;
 
2084
                if (i != -1) { 
 
2085
                        /* edge has two or less neighboring faces */
 
2086
                        if ( (efa1[i]) && (efa2[i]) ) { 
 
2087
                                /* edge has exactly two neighboring faces, check angle */
 
2088
                                float angle;
 
2089
                                angle = saacos(efa1[i]->n[0]*efa2[i]->n[0] +
 
2090
                                                           efa1[i]->n[1]*efa2[i]->n[1] +
 
2091
                                                           efa1[i]->n[2]*efa2[i]->n[2]);
 
2092
                                /* invalidate: edge too sharp */
 
2093
                                if (fabs(angle) >= fsharpness)
 
2094
                                        eed->tmp.l = -1;
 
2095
                        }
 
2096
                        else {
 
2097
                                /* invalidate: less than two neighbors */
 
2098
                                eed->tmp.l = -1;
 
2099
                        }
 
2100
                }
 
2101
 
 
2102
                eed= eed->next;
 
2103
        }
 
2104
 
 
2105
#define select_flat_neighbor(eed) { \
 
2106
                                i = eed->tmp.l; \
 
2107
                                if (i!=-1) { \
 
2108
                                        if (! (efa1[i]->f & SELECT) ) { \
 
2109
                                                EM_select_face(efa1[i], 1); \
 
2110
                                                ++faceselcount; \
 
2111
                                        } \
 
2112
                                        if (! (efa2[i]->f & SELECT) ) { \
 
2113
                                                EM_select_face(efa2[i], 1); \
 
2114
                                                ++faceselcount; \
 
2115
                                        } \
 
2116
                                } \
 
2117
        }
 
2118
 
 
2119
        while (faceselcount != faceselcountold) {
 
2120
                faceselcountold = faceselcount;
 
2121
 
 
2122
                efa= em->faces.first;
 
2123
                while(efa) {
 
2124
                        if (efa->f & SELECT) {
 
2125
                                select_flat_neighbor(efa->e1);
 
2126
                                select_flat_neighbor(efa->e2);
 
2127
                                select_flat_neighbor(efa->e3);
 
2128
                                if (efa->e4) {
 
2129
                                        select_flat_neighbor(efa->e4);
 
2130
                                }
 
2131
                        }
 
2132
                        efa= efa->next;
 
2133
                }
 
2134
        }
 
2135
 
 
2136
#undef select_flat_neighbor
 
2137
 
 
2138
        MEM_freeN(efa1);
 
2139
        MEM_freeN(efa2);
 
2140
 
 
2141
        countall();
 
2142
        addqueue(curarea->win,  REDRAW, 0);
 
2143
        BIF_undo_push("Select Linked Flat Faces");
 
2144
}
 
2145
 
1520
2146
void select_non_manifold(void)
1521
2147
{
1522
2148
        EditMesh *em = G.editMesh;
1752
2378
        }
1753
2379
        
1754
2380
        countall();
 
2381
        BIF_undo_push("Select Less");
1755
2382
        allqueue(REDRAWVIEW3D, 0);
1756
2383
}
1757
2384
 
1762
2389
        EditVert *eve;
1763
2390
        EditEdge *eed;
1764
2391
        EditFace *efa;
1765
 
        short randfac = 50;
 
2392
        static short randfac = 50;
1766
2393
 
1767
2394
        if(G.obedit==NULL || (G.obedit->lay & G.vd->lay)==0) return;
1768
2395
 
1778
2405
                                        eve->f |= SELECT;
1779
2406
                        }
1780
2407
                }
 
2408
                EM_selectmode_flush();
 
2409
                countall();
 
2410
                BIF_undo_push("Select Random: Vertices");
1781
2411
        }
1782
2412
        else if(G.scene->selectmode & SCE_SELECT_EDGE) {
1783
2413
                for(eed= em->edges.first; eed; eed= eed->next) {
1786
2416
                                        EM_select_edge(eed, 1);
1787
2417
                        }
1788
2418
                }
 
2419
                EM_selectmode_flush();
 
2420
                countall();
 
2421
                BIF_undo_push("Select Random:Edges");
1789
2422
        }
1790
2423
        else {
1791
2424
                for(efa= em->faces.first; efa; efa= efa->next) {
1794
2427
                                        EM_select_face(efa, 1);
1795
2428
                        }
1796
2429
                }
 
2430
                
 
2431
                EM_selectmode_flush();
 
2432
                countall();
 
2433
                BIF_undo_push("Select Random:Faces");
1797
2434
        }
1798
 
        
1799
 
        EM_selectmode_flush();
1800
 
 
1801
 
        countall();
1802
2435
        allqueue(REDRAWVIEW3D, 0);
1803
2436
}
1804
2437
 
1839
2472
        else pupmenu_set_active(3);
1840
2473
        
1841
2474
        val= pupmenu("Select Mode%t|Vertices|Edges|Faces");
 
2475
        
 
2476
        
1842
2477
        if(val>0) {
1843
 
                if(val==1) G.scene->selectmode= SCE_SELECT_VERTEX;
1844
 
                else if(val==2) G.scene->selectmode= SCE_SELECT_EDGE;
1845
 
                else G.scene->selectmode= SCE_SELECT_FACE;
1846
 
        
1847
 
                EM_selectmode_set(); // when mode changes
 
2478
                if(val==1){ 
 
2479
                        G.scene->selectmode= SCE_SELECT_VERTEX;
 
2480
                        EM_selectmode_set();
 
2481
                        countall(); 
 
2482
                        BIF_undo_push("Selectmode Set: Vertex");
 
2483
                        }
 
2484
                else if(val==2){
 
2485
                        if((G.qual==LR_CTRLKEY)) EM_convertsel(G.scene->selectmode, SCE_SELECT_EDGE);
 
2486
                        G.scene->selectmode= SCE_SELECT_EDGE;
 
2487
                        EM_selectmode_set();
 
2488
                        countall();
 
2489
                        BIF_undo_push("Selectmode Set: Edge");
 
2490
                }
 
2491
                
 
2492
                else{
 
2493
                        if((G.qual==LR_CTRLKEY)) EM_convertsel(G.scene->selectmode, SCE_SELECT_FACE);
 
2494
                        G.scene->selectmode= SCE_SELECT_FACE;
 
2495
                        EM_selectmode_set();
 
2496
                        countall();
 
2497
                        BIF_undo_push("Selectmode Set: Vertex");
 
2498
                }
 
2499
                
1848
2500
                allqueue(REDRAWVIEW3D, 1);
1849
2501
        }
1850
2502
}
1891
2543
void Edge_Menu() {
1892
2544
        short ret;
1893
2545
 
1894
 
        ret= pupmenu("Edge Specials%t|Mark Seam %x1|Clear Seam %x2|Rotate Edge CW%x3|Rotate Edge CCW%x4|Loopcut%x6|Edge Slide%x5");
 
2546
        ret= pupmenu("Edge Specials%t|Mark Seam %x1|Clear Seam %x2|Rotate Edge CW%x3|Rotate Edge CCW%x4|Loopcut%x6|Edge Slide%x5|Edge Loop Select%x7|Edge Ring Select%x8|Loop to Region%x9|Region to Loop%x10");
1895
2547
 
1896
2548
        switch(ret)
1897
2549
        {
1915
2567
                CutEdgeloop(1);
1916
2568
                BIF_undo_push("Loopcut New");
1917
2569
                break;
 
2570
        case 7:
 
2571
                loop_multiselect(0);
 
2572
                break;
 
2573
        case 8:
 
2574
                loop_multiselect(1);
 
2575
                break;
 
2576
        case 9:
 
2577
                loop_to_region();
 
2578
                break;
 
2579
        case 10:
 
2580
                region_to_loop();
 
2581
                break;
1918
2582
        }
1919
2583
}
1920
2584
 
1947
2611
        
1948
2612
        eed= em->edges.first;
1949
2613
        while(eed) {
1950
 
                eed->f2= 0;             // edge direction
1951
 
                eed->f1= 0;             // counter
 
2614
                eed->f2= 0;             /* edge direction */
 
2615
                eed->f1= 0;             /* counter */
1952
2616
                eed= eed->next;
1953
2617
        }
1954
2618
 
2000
2664
                        }
2001
2665
                        efa= efa->next;
2002
2666
                }
 
2667
 
 
2668
                if (startvl==NULL)
 
2669
                        startvl= em->faces.first;
2003
2670
                
2004
2671
                /* set first face correct: calc normal */
2005
2672
                
2218
2885
{
2219
2886
        EditMesh *em = G.editMesh;
2220
2887
        int nselverts= EM_nvertices_selected();
2221
 
 
2222
 
        if (nselverts<3) {
2223
 
                if (nselverts==0) {
2224
 
                        error("No faces or vertices selected.");
2225
 
                } else {
2226
 
                        error("At least one face or three vertices must be selected.");
2227
 
                }
 
2888
        float norm[3]={0.0, 0.0, 0.0}; /* used for storing the mesh normal */
 
2889
        
 
2890
        if (nselverts==0) {
 
2891
                error("No faces or vertices selected.");
2228
2892
        } else if (EM_nfaces_selected()) {
2229
 
                float norm[3];
2230
2893
                EditFace *efa;
2231
 
 
2232
 
                norm[0]= norm[1]= norm[2]= 0.0;
2233
2894
                for (efa= em->faces.first; efa; efa= efa->next) {
2234
2895
                        if (faceselectedAND(efa, SELECT)) {
2235
2896
                                float fno[3];
2246
2907
 
2247
2908
                Mat4Mul3Vecfl(G.obedit->obmat, norm);
2248
2909
                view3d_align_axis_to_vector(v3d, axis, norm);
2249
 
        } else {
2250
 
                float cent[3], norm[3];
 
2910
        } else if (nselverts>2) {
 
2911
                float cent[3];
2251
2912
                EditVert *eve, *leve= NULL;
2252
2913
 
2253
 
                norm[0]= norm[1]= norm[2]= 0.0;
2254
2914
                editmesh_calc_selvert_center(cent);
2255
2915
                for (eve= em->verts.first; eve; eve= eve->next) {
2256
2916
                        if (eve->f & SELECT) {
2271
2931
 
2272
2932
                Mat4Mul3Vecfl(G.obedit->obmat, norm);
2273
2933
                view3d_align_axis_to_vector(v3d, axis, norm);
 
2934
        } else if (nselverts==2) { /* Align view to edge (or 2 verts) */ 
 
2935
                EditVert *eve, *leve= NULL;
 
2936
 
 
2937
                for (eve= em->verts.first; eve; eve= eve->next) {
 
2938
                        if (eve->f & SELECT) {
 
2939
                                if (leve) {
 
2940
                                        norm[0]= leve->co[0] - eve->co[0];
 
2941
                                        norm[1]= leve->co[1] - eve->co[1];
 
2942
                                        norm[2]= leve->co[2] - eve->co[2];
 
2943
                                        break; /* we know there are only 2 verts so no need to keep looking */
 
2944
                                }
 
2945
                                leve= eve;
 
2946
                        }
 
2947
                }
 
2948
                Mat4Mul3Vecfl(G.obedit->obmat, norm);
 
2949
                view3d_align_axis_to_vector(v3d, axis, norm);
 
2950
        } else if (nselverts==1) { /* Align view to vert normal */ 
 
2951
                EditVert *eve;
 
2952
 
 
2953
                for (eve= em->verts.first; eve; eve= eve->next) {
 
2954
                        if (eve->f & SELECT) {
 
2955
                                norm[0]= eve->no[0];
 
2956
                                norm[1]= eve->no[1];
 
2957
                                norm[2]= eve->no[2];
 
2958
                                break; /* we know this is the only selected vert, so no need to keep looking */
 
2959
                        }
 
2960
                }
 
2961
                Mat4Mul3Vecfl(G.obedit->obmat, norm);
 
2962
                view3d_align_axis_to_vector(v3d, axis, norm);
2274
2963
        }
2275
 
}
 
2964
2276
2965
 
2277
2966
/* **************** VERTEX DEFORMS *************** */
2278
2967
 
2300
2989
        eve= em->verts.first;
2301
2990
        while(eve) {
2302
2991
                if(eve->f & SELECT) {
2303
 
                        eve->vn= (EditVert *)adr;
 
2992
                        eve->tmp.fp = adr;
2304
2993
                        eve->f1= 0;
2305
2994
                        eve->f2= 0;
2306
2995
                        adr+= 3;
2348
3037
                        
2349
3038
                        if((eed->v1->f & SELECT) && eed->v1->f1<255) {
2350
3039
                                eed->v1->f1++;
2351
 
                                VecAddf((float *)eed->v1->vn, (float *)eed->v1->vn, fvec);
 
3040
                                VecAddf(eed->v1->tmp.fp, eed->v1->tmp.fp, fvec);
2352
3041
                        }
2353
3042
                        if((eed->v2->f & SELECT) && eed->v2->f1<255) {
2354
3043
                                eed->v2->f1++;
2355
 
                                VecAddf((float *)eed->v2->vn, (float *)eed->v2->vn, fvec);
 
3044
                                VecAddf(eed->v2->tmp.fp, eed->v2->tmp.fp, fvec);
2356
3045
                        }
2357
3046
                }
2358
3047
                eed= eed->next;
2362
3051
        while(eve) {
2363
3052
                if(eve->f & SELECT) {
2364
3053
                        if(eve->f1) {
2365
 
                                adr= (float *)eve->vn;
 
3054
                                adr = eve->tmp.fp;
2366
3055
                                fac= 0.5/(float)eve->f1;
2367
3056
                                
2368
3057
                                eve->co[0]= 0.5*eve->co[0]+fac*adr[0];
2382
3071
                                        }
2383
3072
                                }
2384
3073
                        }
2385
 
                        eve->vn= 0;
 
3074
                        eve->tmp.fp= 0;
2386
3075
                }
2387
3076
                eve= eve->next;
2388
3077
        }