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

« back to all changes in this revision

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

  • Committer: Bazaar Package Importer
  • Author(s): Florian Ernst
  • Date: 2005-11-06 12:40:03 UTC
  • mfrom: (1.1.2 upstream)
  • Revision ID: james.westby@ubuntu.com-20051106124003-3pgs7tcg5rox96xg
Tags: 2.37a-1.1
* Non-maintainer upload.
* Split out parts of 01_SConstruct_debian.dpatch again: root_build_dir
  really needs to get adjusted before the clean target runs - closes: #333958,
  see #288882 for reference

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/**
2
 
 * $Id: editview.c,v 1.22 2004/03/28 08:46:35 zuster Exp $
 
2
 * $Id: editview.c,v 1.62 2005/05/10 04:21:11 theeth Exp $
3
3
 *
4
4
 * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
5
5
 *
40
40
#include <config.h>
41
41
#endif
42
42
 
43
 
#ifdef WIN32
44
 
#include "BLI_winstuff.h"
45
 
#endif
46
 
 
47
43
#include "IMB_imbuf.h"
48
44
#include "PIL_time.h"
49
45
 
62
58
#include "BLI_arithb.h"
63
59
#include "BLI_editVert.h"
64
60
 
65
 
#include "BKE_utildefines.h"
 
61
#include "BKE_armature.h"
66
62
#include "BKE_global.h"
67
 
#include "BKE_armature.h"
68
63
#include "BKE_lattice.h"
 
64
#include "BKE_mesh.h"
 
65
#include "BKE_utildefines.h"
69
66
 
70
 
#include "BIF_gl.h"
71
 
#include "BIF_mywindow.h"
72
 
#include "BIF_space.h"
73
 
#include "BIF_screen.h"
74
67
#include "BIF_butspace.h"
 
68
#include "BIF_editarmature.h"
75
69
#include "BIF_editgroup.h"
76
70
#include "BIF_editmesh.h"
77
71
#include "BIF_editoops.h"
78
72
#include "BIF_editsima.h"
79
73
#include "BIF_editview.h"
 
74
#include "BIF_gl.h"
80
75
#include "BIF_glutil.h"
81
 
#include "BIF_editarmature.h"
 
76
#include "BIF_interface.h"
 
77
#include "BIF_mywindow.h"
 
78
#include "BIF_space.h"
 
79
#include "BIF_screen.h"
82
80
#include "BIF_toolbox.h"
83
81
 
84
82
#include "BDR_editobject.h"     /* For headerprint */
93
91
#include "BSE_drawview.h"
94
92
#include "BSE_editaction.h"
95
93
 
 
94
#include "editmesh.h"   // borderselect uses it...
96
95
#include "blendef.h"
97
96
#include "mydevice.h"
98
97
 
 
98
#include "BIF_transform.h"
 
99
 
99
100
extern ListBase editNurb; /* originally from exports.h, memory from editcurve.c*/
100
101
/* editmball.c */
101
102
extern ListBase editelems;
102
103
 
103
 
 
 
104
/* local prototypes */
 
105
void obedit_selectionCB(short , Object *, short *, float ); /* called in edit.c */ 
104
106
 
105
107
void arrows_move_cursor(unsigned short event)
106
108
{
119
121
        }
120
122
}
121
123
 
122
 
#define MOVES 50
 
124
/* *********************** GESTURE AND LASSO ******************* */
 
125
 
 
126
/* helper also for borderselect */
 
127
static int edge_fully_inside_rect(rcti rect, short x1, short y1, short x2, short y2)
 
128
{
 
129
        
 
130
        // check points in rect
 
131
        if(rect.xmin<x1 && rect.xmax>x1 && rect.ymin<y1 && rect.ymax>y1) 
 
132
                if(rect.xmin<x2 && rect.xmax>x2 && rect.ymin<y2 && rect.ymax>y2) return 1;
 
133
        
 
134
        return 0;
 
135
        
 
136
}
 
137
 
 
138
static int edge_inside_rect(rcti rect, short x1, short y1, short x2, short y2)
 
139
{
 
140
        int d1, d2, d3, d4;
 
141
        
 
142
        // check points in rect
 
143
        if(rect.xmin<x1 && rect.xmax>x1 && rect.ymin<y1 && rect.ymax>y1) return 1;
 
144
        if(rect.xmin<x2 && rect.xmax>x2 && rect.ymin<y2 && rect.ymax>y2) return 1;
 
145
        
 
146
        /* check points completely out rect */
 
147
        if(x1<rect.xmin && x2<rect.xmin) return 0;
 
148
        if(x1>rect.xmax && x2>rect.xmax) return 0;
 
149
        if(y1<rect.ymin && y2<rect.ymin) return 0;
 
150
        if(y1>rect.ymax && y2>rect.ymax) return 0;
 
151
        
 
152
        // simple check lines intersecting. 
 
153
        d1= (y1-y2)*(x1- rect.xmin ) + (x2-x1)*(y1- rect.ymin );
 
154
        d2= (y1-y2)*(x1- rect.xmin ) + (x2-x1)*(y1- rect.ymax );
 
155
        d3= (y1-y2)*(x1- rect.xmax ) + (x2-x1)*(y1- rect.ymax );
 
156
        d4= (y1-y2)*(x1- rect.xmax ) + (x2-x1)*(y1- rect.ymin );
 
157
        
 
158
        if(d1<0 && d2<0 && d3<0 && d4<0) return 0;
 
159
        if(d1>0 && d2>0 && d3>0 && d4>0) return 0;
 
160
        
 
161
        return 1;
 
162
}
 
163
 
 
164
 
 
165
#define MOVES_GESTURE 50
 
166
#define MOVES_LASSO 500
 
167
 
 
168
static int lasso_inside(short mcords[][2], short moves, short sx, short sy)
 
169
{
 
170
        /* we do the angle rule, define that all added angles should be about zero or 2*PI */
 
171
        float angletot=0.0, len, dot, ang, cross, fp1[2], fp2[2];
 
172
        int a;
 
173
        short *p1, *p2;
 
174
        
 
175
        p1= mcords[moves-1];
 
176
        p2= mcords[0];
 
177
        
 
178
        /* first vector */
 
179
        fp1[0]= (float)(p1[0]-sx);
 
180
        fp1[1]= (float)(p1[1]-sy);
 
181
        len= sqrt(fp1[0]*fp1[0] + fp1[1]*fp1[1]);
 
182
        fp1[0]/= len;
 
183
        fp1[1]/= len;
 
184
        
 
185
        for(a=0; a<moves; a++) {
 
186
                /* second vector */
 
187
                fp2[0]= (float)(p2[0]-sx);
 
188
                fp2[1]= (float)(p2[1]-sy);
 
189
                len= sqrt(fp2[0]*fp2[0] + fp2[1]*fp2[1]);
 
190
                fp2[0]/= len;
 
191
                fp2[1]/= len;
 
192
                
 
193
                /* dot and angle and cross */
 
194
                dot= fp1[0]*fp2[0] + fp1[1]*fp2[1];
 
195
                ang= fabs(saacos(dot));
 
196
 
 
197
                cross= (float)((p1[1]-p2[1])*(p1[0]-sx) + (p2[0]-p1[0])*(p1[1]-sy));
 
198
                
 
199
                if(cross<0.0) angletot-= ang;
 
200
                else angletot+= ang;
 
201
                
 
202
                /* circulate */
 
203
                fp1[0]= fp2[0]; fp1[1]= fp2[1];
 
204
                p1= p2;
 
205
                p2= mcords[a+1];
 
206
        }
 
207
        
 
208
        if( fabs(angletot) > 4.0 ) return 1;
 
209
        return 0;
 
210
}
 
211
 
 
212
/* edge version for lasso select. we assume boundbox check was done */
 
213
static int lasso_inside_edge(short mcords[][2], short moves, short *v1, short *v2)
 
214
{
 
215
        int a;
 
216
 
 
217
        // check points in lasso
 
218
        if(lasso_inside(mcords, moves, v1[0], v1[1])) return 1;
 
219
        if(lasso_inside(mcords, moves, v2[0], v2[1])) return 1;
 
220
        
 
221
        /* no points in lasso, so we have to intersect with lasso edge */
 
222
        
 
223
        if( IsectLL2Ds(mcords[0], mcords[moves-1], v1, v2) > 0) return 1;
 
224
        for(a=0; a<moves-1; a++) {
 
225
                if( IsectLL2Ds(mcords[a], mcords[a+1], v1, v2) > 0) return 1;
 
226
        }
 
227
        
 
228
        return 0;
 
229
}
 
230
 
 
231
 
 
232
/* warning; lasso select with backbuffer-check draws in backbuf with persp(PERSP_WIN) 
 
233
   and returns with persp(PERSP_VIEW). After lasso select backbuf is not OK
 
234
*/
 
235
static void do_lasso_select_objects(short mcords[][2], short moves, short select)
 
236
{
 
237
        Base *base;
 
238
        
 
239
        for(base= G.scene->base.first; base; base= base->next) {
 
240
                if(base->lay & G.vd->lay) {
 
241
                        project_short(base->object->obmat[3], &base->sx);
 
242
                        if(lasso_inside(mcords, moves, base->sx, base->sy)) {
 
243
                                
 
244
                                if(select) base->flag |= SELECT;
 
245
                                else base->flag &= ~SELECT;
 
246
                                base->object->flag= base->flag;
 
247
                        }
 
248
                }
 
249
        }
 
250
}
 
251
 
 
252
static void lasso_select_boundbox(rcti *rect, short mcords[][2], short moves)
 
253
{
 
254
        short a;
 
255
        
 
256
        rect->xmin= rect->xmax= mcords[0][0];
 
257
        rect->ymin= rect->ymax= mcords[0][1];
 
258
        
 
259
        for(a=1; a<moves; a++) {
 
260
                if(mcords[a][0]<rect->xmin) rect->xmin= mcords[a][0];
 
261
                else if(mcords[a][0]>rect->xmax) rect->xmax= mcords[a][0];
 
262
                if(mcords[a][1]<rect->ymin) rect->ymin= mcords[a][1];
 
263
                else if(mcords[a][1]>rect->ymax) rect->ymax= mcords[a][1];
 
264
        }
 
265
}
 
266
 
 
267
static void do_lasso_select_mesh(short mcords[][2], short moves, short select)
 
268
{
 
269
        extern int em_solidoffs, em_wireoffs;   // let linker solve it... from editmesh_mods.c 
 
270
        EditMesh *em = G.editMesh;
 
271
        EditVert *eve;
 
272
        EditEdge *eed;
 
273
        EditFace *efa;
 
274
        rcti rect;
 
275
        int index, bbsel=0; // bbsel: no clip needed with screencoords
 
276
        
 
277
        lasso_select_boundbox(&rect, mcords, moves);
 
278
        
 
279
        bbsel= EM_mask_init_backbuf_border(mcords, moves, rect.xmin, rect.ymin, rect.xmax, rect.ymax);
 
280
        
 
281
        if(G.scene->selectmode & SCE_SELECT_VERTEX) {
 
282
                if(bbsel==0) calc_meshverts_ext();      /* clips, drawobject.c */
 
283
                index= em_wireoffs;
 
284
                for(eve= em->verts.first; eve; eve= eve->next, index++) {
 
285
                        if(eve->h==0) {
 
286
                                if(bbsel) {
 
287
                                        if(EM_check_backbuf_border(index)) {
 
288
                                                if(select) eve->f|= 1;
 
289
                                                else eve->f&= 254;
 
290
                                        }
 
291
                                }
 
292
                                else if(eve->xs>rect.xmin && eve->xs<rect.xmax && eve->ys>rect.ymin && eve->ys<rect.ymax) {
 
293
                                        if(lasso_inside(mcords, moves, eve->xs, eve->ys)) {
 
294
                                                if(select) eve->f|= 1;
 
295
                                                else eve->f&= 254;
 
296
                                        }
 
297
                                }
 
298
                        }
 
299
                }
 
300
        }
 
301
        if(G.scene->selectmode & SCE_SELECT_EDGE) {
 
302
                short done= 0;
 
303
                
 
304
                calc_meshverts_ext_f2();        /* doesnt clip, drawobject.c */
 
305
                index= em_solidoffs;
 
306
                
 
307
                /* two stages, for nice edge select first do 'both points in rect' 
 
308
                        also when bbsel is true */
 
309
                for(eed= em->edges.first; eed; eed= eed->next, index++) {
 
310
                        if(eed->h==0) {
 
311
                                if(edge_fully_inside_rect(rect, eed->v1->xs, eed->v1->ys,  eed->v2->xs, eed->v2->ys)) {
 
312
                                        if(lasso_inside(mcords, moves, eed->v1->xs, eed->v1->ys)) {
 
313
                                                if(lasso_inside(mcords, moves, eed->v2->xs, eed->v2->ys)) {
 
314
                                                        if(EM_check_backbuf_border(index)) {
 
315
                                                                EM_select_edge(eed, select);
 
316
                                                                done = 1;
 
317
                                                        }
 
318
                                                }
 
319
                                        }
 
320
                                }
 
321
                        }
 
322
                }
 
323
                
 
324
                if(done==0) {
 
325
                        index= em_solidoffs;
 
326
                        for(eed= em->edges.first; eed; eed= eed->next, index++) {
 
327
                                if(eed->h==0) {
 
328
                                        if(bbsel) {
 
329
                                                if(EM_check_backbuf_border(index))
 
330
                                                        EM_select_edge(eed, select);
 
331
                                        }
 
332
                                        else if(lasso_inside_edge(mcords, moves, &eed->v1->xs, &eed->v2->xs)) {
 
333
                                                EM_select_edge(eed, select);
 
334
                                        }
 
335
                                }
 
336
                        }
 
337
                }
 
338
        }
 
339
        
 
340
        if(G.scene->selectmode & SCE_SELECT_FACE) {
 
341
                if(bbsel==0) calc_mesh_facedots_ext();
 
342
                index= 1;
 
343
                for(efa= em->faces.first; efa; efa= efa->next, index++) {
 
344
                        if(efa->h==0) {
 
345
                                if(bbsel) {
 
346
                                        if(EM_check_backbuf_border(index)) {
 
347
                                                EM_select_face_fgon(efa, select);
 
348
                                        }
 
349
                                }
 
350
                                else if(efa->xs>rect.xmin && efa->xs<rect.xmax && efa->ys>rect.ymin && efa->ys<rect.ymax) {
 
351
                                        if(lasso_inside(mcords, moves, efa->xs, efa->ys)) {
 
352
                                                EM_select_face_fgon(efa, select);
 
353
                                        }
 
354
                                }
 
355
                        }
 
356
                }
 
357
        }
 
358
        
 
359
        EM_free_backbuf_border();
 
360
        EM_selectmode_flush();
 
361
        
 
362
}
 
363
 
 
364
static void do_lasso_select_curve(short mcords[][2], short moves, short select)
 
365
{
 
366
        Nurb *nu;
 
367
        BPoint *bp;
 
368
        BezTriple *bezt;
 
369
        int a;
 
370
        
 
371
        calc_nurbverts_ext();   /* drawobject.c */
 
372
        nu= editNurb.first;
 
373
        while(nu) {
 
374
                if((nu->type & 7)==CU_BEZIER) {
 
375
                        bezt= nu->bezt;
 
376
                        a= nu->pntsu;
 
377
                        while(a--) {
 
378
                                if(bezt->hide==0) {
 
379
                                        if(lasso_inside(mcords, moves, bezt->s[0][0], bezt->s[0][1])) {
 
380
                                                if(select) bezt->f1|= 1;
 
381
                                                else bezt->f1 &= ~1;
 
382
                                        }
 
383
                                        if(lasso_inside(mcords, moves, bezt->s[1][0], bezt->s[1][1])) {
 
384
                                                if(select) bezt->f2|= 1;
 
385
                                                else bezt->f2 &= ~1;
 
386
                                        }
 
387
                                        if(lasso_inside(mcords, moves, bezt->s[2][0], bezt->s[2][1])) {
 
388
                                                if(select) bezt->f3|= 1;
 
389
                                                else bezt->f3 &= ~1;
 
390
                                        }
 
391
                                }
 
392
                                bezt++;
 
393
                        }
 
394
                }
 
395
                else {
 
396
                        bp= nu->bp;
 
397
                        a= nu->pntsu*nu->pntsv;
 
398
                        while(a--) {
 
399
                                if(bp->hide==0) {
 
400
                                        if(lasso_inside(mcords, moves, bp->s[0], bp->s[1])) {
 
401
                                                if(select) bp->f1|= 1;
 
402
                                                else bp->f1 &= ~1;
 
403
                                        }
 
404
                                }
 
405
                                bp++;
 
406
                        }
 
407
                }
 
408
                nu= nu->next;
 
409
        }
 
410
}
 
411
 
 
412
static void do_lasso_select_lattice(short mcords[][2], short moves, short select)
 
413
{
 
414
        BPoint *bp;
 
415
        int a;
 
416
        
 
417
        calc_lattverts_ext();
 
418
        
 
419
        bp= editLatt->def;
 
420
        
 
421
        a= editLatt->pntsu*editLatt->pntsv*editLatt->pntsw;
 
422
        while(a--) {
 
423
                if(bp->hide==0) {
 
424
                        if(lasso_inside(mcords, moves, bp->s[0], bp->s[1])) {
 
425
                                if(select) bp->f1|= 1;
 
426
                                else bp->f1 &= ~1;
 
427
                        }
 
428
                }
 
429
                bp++;
 
430
        }
 
431
}
 
432
 
 
433
 
 
434
static void do_lasso_select_facemode(short mcords[][2], short moves, short select)
 
435
{
 
436
        extern int em_vertoffs;         // still bad code, let linker solve for now
 
437
        Mesh *me;
 
438
        TFace *tface;
 
439
        rcti rect;
 
440
        int a;
 
441
        
 
442
        me= get_mesh(OBACT);
 
443
        if(me==NULL || me->tface==NULL) return;
 
444
        if(me->totface==0) return;
 
445
        tface= me->tface;
 
446
        
 
447
        em_vertoffs= me->totface+1;     // max index array
 
448
        
 
449
        lasso_select_boundbox(&rect, mcords, moves);
 
450
        EM_mask_init_backbuf_border(mcords, moves, rect.xmin, rect.ymin, rect.xmax, rect.ymax);
 
451
        
 
452
        for(a=1; a<=me->totface; a++, tface++) {
 
453
                if(EM_check_backbuf_border(a)) {
 
454
                        if(select) tface->flag |= TF_SELECT;
 
455
                        else tface->flag &= ~TF_SELECT;
 
456
                }
 
457
        }
 
458
        
 
459
        EM_free_backbuf_border();
 
460
        
 
461
        allqueue(REDRAWVIEW3D, 0);
 
462
        allqueue(REDRAWIMAGE, 0);
 
463
}
 
464
 
 
465
static void do_lasso_select(short mcords[][2], short moves, short select)
 
466
{
 
467
        if(G.obedit==NULL) {
 
468
                if(G.f & G_FACESELECT)
 
469
                        do_lasso_select_facemode(mcords, moves, select);
 
470
                else if(G.f & (G_VERTEXPAINT|G_TEXTUREPAINT|G_WEIGHTPAINT))
 
471
                        ;
 
472
                else  
 
473
                        do_lasso_select_objects(mcords, moves, select);
 
474
        }
 
475
        else if(G.obedit->type==OB_MESH) 
 
476
                do_lasso_select_mesh(mcords, moves, select);
 
477
        else if(G.obedit->type==OB_CURVE || G.obedit->type==OB_SURF) 
 
478
                do_lasso_select_curve(mcords, moves, select);
 
479
        else if(G.obedit->type==OB_LATTICE) 
 
480
                do_lasso_select_lattice(mcords, moves, select);
 
481
        
 
482
        BIF_undo_push("Lasso select");
 
483
 
 
484
        allqueue(REDRAWVIEW3D, 0);
 
485
        countall();
 
486
}
 
487
 
 
488
/* un-draws and draws again */
 
489
static void draw_lasso_select(short mcords[][2], short moves, short end)
 
490
{
 
491
        int a;
 
492
        
 
493
        setlinestyle(2);
 
494
        /* clear draw */
 
495
        if(moves>1) {
 
496
                for(a=1; a<=moves-1; a++) {
 
497
                        sdrawXORline(mcords[a-1][0], mcords[a-1][1], mcords[a][0], mcords[a][1]);
 
498
                }
 
499
                sdrawXORline(mcords[moves-1][0], mcords[moves-1][1], mcords[0][0], mcords[0][1]);
 
500
        }
 
501
        if(!end) {
 
502
                /* new draw */
 
503
                for(a=1; a<=moves; a++) {
 
504
                        sdrawXORline(mcords[a-1][0], mcords[a-1][1], mcords[a][0], mcords[a][1]);
 
505
                }
 
506
                sdrawXORline(mcords[moves][0], mcords[moves][1], mcords[0][0], mcords[0][1]);
 
507
        }
 
508
        setlinestyle(0);
 
509
}
123
510
 
124
511
 
125
512
static char interpret_move(short mcord[][2], int count)
126
513
{
127
 
        float x1, x2, y1, y2, d1, d2, inp, sq, mouse[MOVES][2];
 
514
        float x1, x2, y1, y2, d1, d2, inp, sq, mouse[MOVES_GESTURE][2];
128
515
        int i, j, dir = 0;
129
516
        
130
517
        if (count <= 10) return ('g');
231
618
        return (0);
232
619
}
233
620
 
 
621
 
 
622
/* return 1 to denote gesture did something, also does lasso */
234
623
int gesture(void)
235
624
{
236
 
        short mcords[MOVES][2];
 
625
        short mcords[MOVES_LASSO][2]; // the larger size
237
626
        int i= 1, end= 0, a;
238
627
        unsigned short event=0;
239
 
        short mval[2], val, timer=0;
 
628
        short mval[2], val, timer=0, mousebut, lasso=0, maxmoves;
 
629
        
 
630
        if (U.flag & USER_LMOUSESELECT) mousebut = R_MOUSE;
 
631
        else mousebut = L_MOUSE;
 
632
        
 
633
        if(G.qual & LR_CTRLKEY) {
 
634
                if(curarea->spacetype==SPACE_VIEW3D) {
 
635
                        if(G.obedit==NULL) {
 
636
                                if(G.f & (G_VERTEXPAINT|G_TEXTUREPAINT|G_WEIGHTPAINT)) return 0;
 
637
                                if(G.obpose) return 0;
 
638
                        }
 
639
                        lasso= 1;
 
640
                }
 
641
        }
240
642
        
241
643
        glDrawBuffer(GL_FRONT);
242
 
        persp(0);       /*  ortho at pixel level */
 
644
        persp(PERSP_WIN);       /*  ortho at pixel level */
243
645
        
244
646
        getmouseco_areawin(mval);
245
647
        
246
648
        mcords[0][0] = mval[0];
247
649
        mcords[0][1] = mval[1];
248
650
        
249
 
        while(get_mbut()&L_MOUSE) {
 
651
        if(lasso) maxmoves= MOVES_LASSO;
 
652
        else maxmoves= MOVES_GESTURE;
 
653
        
 
654
        while(get_mbut() & mousebut) {
250
655
                
251
656
                if(qtest()) event= extern_qread(&val);
252
657
                else if(i==1) {
254
659
                        PIL_sleep_ms(10);
255
660
                        timer++;
256
661
                        if(timer>=10*U.tb_leftmouse) {
 
662
                                glDrawBuffer(GL_BACK); /* !! */
257
663
                                toolbox_n();
258
664
                                return 1;
259
665
                        }
265
671
                        if( abs(mval[0]-mcords[i-1][0])>3 || abs(mval[1]-mcords[i-1][1])>3 ) {
266
672
                                mcords[i][0] = mval[0];
267
673
                                mcords[i][1] = mval[1];
 
674
                                
268
675
                                if(i) {
269
 
                                        sdrawXORline(mcords[i-1][0], mcords[i-1][1], mcords[i][0], mcords[i][1]);
 
676
                                        if(lasso) draw_lasso_select(mcords, i, 0);
 
677
                                        else sdrawXORline(mcords[i-1][0], mcords[i-1][1], mcords[i][0], mcords[i][1]);
270
678
                                        glFlush();
271
679
                                }
272
680
                                i++;
280
688
                        if(event) end= 1;       /* blender returns 0 */
281
689
                        break;
282
690
                }
283
 
                if (i == MOVES || end == 1) break;
 
691
                if (i == maxmoves || end == 1) break;
284
692
        }
285
 
 
286
 
        for(a=1; a<i; a++) {
 
693
        
 
694
        /* clear */
 
695
        if(lasso) draw_lasso_select(mcords, i, 1);
 
696
        else for(a=1; a<i; a++) {
287
697
                sdrawXORline(mcords[a-1][0], mcords[a-1][1], mcords[a][0], mcords[a][1]);
288
698
        }
289
699
        
290
 
        persp(1);
 
700
        persp(PERSP_VIEW);
291
701
        glDrawBuffer(GL_BACK);
292
702
        
293
703
        if (i > 2) {
294
 
                i = interpret_move(mcords, i);
295
 
                
296
 
                if(i) {
297
 
                        if(curarea->spacetype==SPACE_IPO) transform_ipo(i);
298
 
                        else if(curarea->spacetype==SPACE_IMAGE) transform_tface_uv(i);
299
 
                        else if(curarea->spacetype==SPACE_OOPS) transform_oops('g');
300
 
                        else transform(i);
 
704
                if(lasso) do_lasso_select(mcords, i, (G.qual & LR_SHIFTKEY)==0);
 
705
                else {
 
706
                        i = interpret_move(mcords, i);
 
707
                        
 
708
                        if(i) {
 
709
                                if(curarea->spacetype==SPACE_IPO) transform_ipo(i);
 
710
                                else if(curarea->spacetype==SPACE_IMAGE) transform_tface_uv(i, 0);
 
711
                                else if(curarea->spacetype==SPACE_OOPS) transform_oops('g', 0);
 
712
                                else {
 
713
                                        if(i=='g') {
 
714
                                                initTransform(TFM_TRANSLATION, CTX_NONE);
 
715
                                                Transform();
 
716
                                        }
 
717
                                        else if(i=='r') {
 
718
                                                initTransform(TFM_ROTATION, CTX_NONE);
 
719
                                                Transform();
 
720
                                        }
 
721
                                        else {
 
722
                                                initTransform(TFM_RESIZE, CTX_NONE);
 
723
                                                Transform();
 
724
                                        }
 
725
                                }
 
726
                        }
301
727
                }
302
 
                
303
728
                return 1;
304
729
        }
305
 
        else return 0;
 
730
        return 0;
306
731
}
307
732
 
308
733
void mouse_cursor(void)
389
814
        allqueue(REDRAWNLA, 0);
390
815
        
391
816
        countall();
392
 
 
 
817
        BIF_undo_push("(De)select all");
393
818
}
394
819
 
395
820
/* selects all objects of a particular type, on currently visible layers */
411
836
        allqueue(REDRAWNLA, 0);
412
837
        
413
838
        countall();
414
 
 
 
839
        BIF_undo_push("Select all per type");
415
840
}
416
841
/* selects all objects on a particular layer */
417
 
void selectall_layer(int layernum) 
 
842
void selectall_layer(unsigned int layernum) 
418
843
{
419
844
        Base *base;
420
845
        
432
857
        allqueue(REDRAWNLA, 0);
433
858
        
434
859
        countall();
435
 
 
 
860
        BIF_undo_push("Select all per layer");
436
861
}
 
862
 
437
863
static void deselectall_except(Base *b)   /* deselect all except b */
438
864
{
439
865
        Base *base;
506
932
        
507
933
        BASACT= base;
508
934
        
509
 
        /* signals to buttons */
510
 
        redraw_test_buttons(base);
511
 
 
512
 
        set_active_group();
513
 
        
514
 
        /* signal to ipo */
515
 
 
516
 
        if (base) {
517
 
                allqueue(REDRAWIPO, base->object->ipowin);
518
 
                allqueue(REDRAWACTION, 0);
519
 
                allqueue(REDRAWNLA, 0);
 
935
        if(base) {
 
936
                /* signals to buttons */
 
937
                redraw_test_buttons(base->object);
 
938
 
 
939
                set_active_group();
 
940
                
 
941
                /* signal to ipo */
 
942
 
 
943
                if (base) {
 
944
                        allqueue(REDRAWIPO, base->object->ipowin);
 
945
                        allqueue(REDRAWACTION, 0);
 
946
                        allqueue(REDRAWNLA, 0);
 
947
                }
520
948
        }
521
 
 
522
 
 
523
949
}
524
950
 
525
951
void set_active_object(Object *ob)
536
962
        }
537
963
}
538
964
 
 
965
/* The max number of menu items in an object select menu */
 
966
#define SEL_MENU_SIZE 22
 
967
 
 
968
static Base *mouse_select_menu(unsigned int *buffer, int hits, short *mval)
 
969
{
 
970
        Base *baseList[SEL_MENU_SIZE]={NULL}; /*baseList is used to store all possible bases to bring up a menu */
 
971
        Base *base;
 
972
        short baseCount = 0;
 
973
        char menuText[20 + SEL_MENU_SIZE*32] = "Select Object%t";       // max ob name = 22
 
974
        char str[32];
 
975
        
 
976
        for(base=FIRSTBASE; base; base= base->next) {
 
977
                if(base->lay & G.vd->lay) {
 
978
                        baseList[baseCount] = NULL;
 
979
                        
 
980
                        /* two selection methods, the CTRL select uses max dist of 15 */
 
981
                        if(buffer) {
 
982
                                int a;
 
983
                                for(a=0; a<hits; a++) {
 
984
                                        /* index was converted */
 
985
                                        if(base->selcol==buffer[ (4 * a) + 3 ]) baseList[baseCount] = base;
 
986
                                }
 
987
                        }
 
988
                        else {
 
989
                                int temp, dist=15;
 
990
                                
 
991
                                project_short(base->object->obmat[3], &base->sx);
 
992
                                
 
993
                                temp= abs(base->sx -mval[0]) + abs(base->sy -mval[1]);
 
994
                                if(temp<dist ) baseList[baseCount] = base;
 
995
                        }
 
996
                        
 
997
                        if(baseList[baseCount]) {
 
998
                                if (baseCount < SEL_MENU_SIZE) {
 
999
                                        baseList[baseCount] = base;
 
1000
                                        sprintf(str, "|%s %%x%d", base->object->id.name+2, baseCount+1);        // max ob name == 22
 
1001
                                        strcat(menuText, str);
 
1002
                                        baseCount++;
 
1003
                                }
 
1004
                        }
 
1005
                }
 
1006
        }
 
1007
        
 
1008
        if(baseCount<=1) return baseList[0];
 
1009
        else {
 
1010
                baseCount = pupmenu(menuText);
 
1011
                
 
1012
                if (baseCount != -1) { /* If nothing is selected then dont do anything */
 
1013
                        return baseList[baseCount-1];
 
1014
                }
 
1015
                else return NULL;
 
1016
        }
 
1017
}
 
1018
 
539
1019
void mouse_select(void)
540
1020
{
541
1021
        Base *base, *startbase=NULL, *basact=NULL, *oldbasact=NULL;
543
1023
        int temp, a, dist=100;
544
1024
        short hits, mval[2];
545
1025
 
546
 
        /* always start list from basact */
 
1026
        /* always start list from basact in wire mode */
547
1027
        startbase=  FIRSTBASE;
548
1028
        if(BASACT && BASACT->next) startbase= BASACT->next;
549
1029
 
550
1030
        getmouseco_areawin(mval);
551
 
 
 
1031
        
 
1032
        /* This block uses the control key to make the object selected by its centre point rather then its contents */
552
1033
        if(G.obedit==0 && (G.qual & LR_CTRLKEY)) {
553
 
 
554
 
                base= startbase;
555
 
                while(base) {
556
 
                        
557
 
                        if(base->lay & G.vd->lay) {
558
 
                                
559
 
                                project_short(base->object->obmat[3], &base->sx);
560
 
                                
561
 
                                temp= abs(base->sx -mval[0]) + abs(base->sy -mval[1]);
562
 
                                if(base==BASACT) temp+=10;
563
 
                                if(temp<dist ) {
564
 
                                        basact= base;
565
 
                                        dist= temp;
 
1034
                
 
1035
                if(G.qual & LR_ALTKEY) basact= mouse_select_menu(NULL, 0, mval);
 
1036
                else {
 
1037
                        base= startbase;
 
1038
                        while(base) {
 
1039
                                
 
1040
                                if(base->lay & G.vd->lay) {
 
1041
                                        
 
1042
                                        project_short(base->object->obmat[3], &base->sx);
 
1043
                                        
 
1044
                                        temp= abs(base->sx -mval[0]) + abs(base->sy -mval[1]);
 
1045
                                        if(base==BASACT) temp+=10;
 
1046
                                        if(temp<dist ) {
 
1047
                                                
 
1048
                                                dist= temp;
 
1049
                                                basact= base;
 
1050
                                        }
566
1051
                                }
 
1052
                                base= base->next;
 
1053
                                
 
1054
                                if(base==0) base= FIRSTBASE;
 
1055
                                if(base==startbase) break;
567
1056
                        }
568
 
                        base= base->next;
569
 
                        
570
 
                        if(base==0) base= FIRSTBASE;
571
 
                        if(base==startbase) break;
572
1057
                }
573
 
 
574
 
                /* complete redraw when: */
575
 
                if(G.f & (G_VERTEXPAINT+G_FACESELECT+G_TEXTUREPAINT+G_WEIGHTPAINT)) allqueue(REDRAWVIEW3D, 0);
576
 
                
577
1058
        }
578
1059
        else {
579
1060
                hits= selectprojektie(buffer, mval[0]-7, mval[1]-7, mval[0]+7, mval[1]+7);
580
1061
                if(hits==0) hits= selectprojektie(buffer, mval[0]-21, mval[1]-21, mval[0]+21, mval[1]+21);
581
1062
 
582
1063
                if(hits>0) {
583
 
 
584
 
                        base= startbase;
585
 
                        while(base) {
586
 
                                if(base->lay & G.vd->lay) {
 
1064
                        
 
1065
                        if(G.qual & LR_ALTKEY) basact= mouse_select_menu(buffer, hits, mval);
 
1066
                        else {
 
1067
                                static short lastmval[2]={-100, -100};
 
1068
                                int donearest= 0;
 
1069
                                
 
1070
                                /* define if we use solid nearest select or not */
 
1071
                                if(G.vd->drawtype>OB_WIRE) {
 
1072
                                        donearest= 1;
 
1073
                                        if( ABS(mval[0]-lastmval[0])<3 && ABS(mval[1]-lastmval[1])<3) {
 
1074
                                                donearest= 0;
 
1075
                                        }
 
1076
                                }
 
1077
                                lastmval[0]= mval[0]; lastmval[1]= mval[1];
 
1078
                                
 
1079
                                if(donearest) {
 
1080
                                        unsigned int min= 0xFFFFFFFF;
 
1081
                                        int selcol= 0, notcol=0;
 
1082
                                        
 
1083
                                        /* prevent not being able to select active object... */
 
1084
                                        if(BASACT && (BASACT->flag & SELECT) && hits>1) notcol= BASACT->selcol;
 
1085
                                        
587
1086
                                        for(a=0; a<hits; a++) {
588
1087
                                                /* index was converted */
589
 
                                                if(base->selcol==buffer[ (4 * a) + 3 ]) basact= base;
590
 
                                        }
591
 
                                }
592
 
                                if(basact) break;
593
 
                                
594
 
                                base= base->next;
595
 
                                if(base==0) base= FIRSTBASE;
596
 
                                if(base==startbase) break;
 
1088
                                                if( min > buffer[4*a+1] && notcol!=buffer[4*a+3]) {
 
1089
                                                        min= buffer[4*a+1];
 
1090
                                                        selcol= buffer[4*a+3];
 
1091
                                                }
 
1092
                                        }
 
1093
                                        base= FIRSTBASE;
 
1094
                                        while(base) {
 
1095
                                                if(base->lay & G.vd->lay) {
 
1096
                                                        if(base->selcol==selcol) break;
 
1097
                                                }
 
1098
                                                base= base->next;
 
1099
                                        }
 
1100
                                        if(base) basact= base;
 
1101
                                }
 
1102
                                else {
 
1103
                                        
 
1104
                                        base= startbase;
 
1105
                                        while(base) {
 
1106
                                                if(base->lay & G.vd->lay) {
 
1107
                                                        for(a=0; a<hits; a++) {
 
1108
                                                                /* index was converted */
 
1109
                                                                if(base->selcol==buffer[(4*a)+3]) {
 
1110
                                                                        basact= base;
 
1111
                                                                }
 
1112
                                                        }
 
1113
                                                }
 
1114
                                                
 
1115
                                                if(basact) break;
 
1116
                                                
 
1117
                                                base= base->next;
 
1118
                                                if(base==0) base= FIRSTBASE;
 
1119
                                                if(base==startbase) break;
 
1120
                                        }
 
1121
                                }
597
1122
                        }
598
1123
                }
599
1124
        }
628
1153
                                set_active_base(basact);
629
1154
                        }
630
1155
 
631
 
                        // for visual speed
632
 
                        if(oldbasact && oldbasact != basact && (oldbasact->lay & G.vd->lay)) 
633
 
                                draw_object_ext(oldbasact);
634
 
                        draw_object_ext(basact);
635
 
 
 
1156
                        // for visual speed, only in wire mode
 
1157
                        if(G.vd->drawtype==OB_WIRE) {
 
1158
                                if(oldbasact && oldbasact != basact && (oldbasact->lay & G.vd->lay)) 
 
1159
                                        draw_object_ext(oldbasact);
 
1160
                                draw_object_ext(basact);
 
1161
                        }
 
1162
                        
636
1163
                        if(basact->object->type!=OB_MESH) {
637
1164
                                if(G.f & G_WEIGHTPAINT) {
638
1165
                                        set_wpaint();   /* toggle */
652
1179
                        allqueue(REDRAWBUTSOBJECT, 0);
653
1180
                        allqueue(REDRAWACTION, 0);
654
1181
                        allqueue(REDRAWNLA, 0);
 
1182
                        allqueue(REDRAWTIME, 0);
655
1183
                        allqueue(REDRAWHEADERS, 0);     /* To force display update for the posebutton */
 
1184
                        
656
1185
                }
657
1186
                
658
1187
        }
659
1188
 
660
1189
        countall();
661
1190
 
662
 
        rightmouse_transform();
 
1191
        rightmouse_transform(); // does undo push!
663
1192
}
664
1193
 
665
1194
/* ------------------------------------------------------------------------- */
 
1195
 
 
1196
static int edge_inside_circle(short centx, short centy, short rad, short x1, short y1, short x2, short y2)
 
1197
{
 
1198
        int radsq= rad*rad;
 
1199
        float v1[2], v2[2], v3[2];
 
1200
        
 
1201
        // check points in circle itself
 
1202
        if( (x1-centx)*(x1-centx) + (y1-centy)*(y1-centy) <= radsq ) return 1;
 
1203
        if( (x2-centx)*(x2-centx) + (y2-centy)*(y2-centy) <= radsq ) return 1;
 
1204
        
 
1205
        // pointdistline
 
1206
        v3[0]= centx;
 
1207
        v3[1]= centy;
 
1208
        v1[0]= x1;
 
1209
        v1[1]= y1;
 
1210
        v2[0]= x2;
 
1211
        v2[1]= y2;
 
1212
        
 
1213
        if( PdistVL2Dfl(v3, v1, v2) < (float)rad ) return 1;
 
1214
        
 
1215
        return 0;
 
1216
}
 
1217
 
 
1218
 
666
1219
/**
667
1220
 * Does the 'borderselect' command. (Select verts based on selecting with a 
668
1221
 * border: key 'b'). All selecting seems to be done in the get_border part.
669
1222
 */
670
1223
void borderselect(void)
671
1224
{
672
 
        EditMesh *em = G.editMesh;
673
1225
        rcti rect;
674
1226
        Base *base;
675
1227
        Nurb *nu;
676
1228
        BezTriple *bezt;
677
1229
        BPoint *bp;
678
1230
        MetaElem *ml;
679
 
        struct EditVert *eve;
680
1231
        unsigned int buffer[MAXPICKBUF];
681
1232
        int a, index;
682
1233
        short hits, val, tel;
685
1236
                face_borderselect();
686
1237
                return;
687
1238
        }
688
 
 
 
1239
        setlinestyle(2);
689
1240
        val= get_border(&rect, 3);
 
1241
        setlinestyle(0);
690
1242
        if(val) {
691
1243
                if (G.obpose){
692
1244
                        if(G.obpose->type==OB_ARMATURE) {
718
1270
                                allqueue(REDRAWVIEW3D, 0);
719
1271
                        }
720
1272
                }
721
 
                else
722
 
                if(G.obedit) {
 
1273
                else if(G.obedit) {
723
1274
                        /* used to be a bigger test, also included sector and life */
724
1275
                        if(G.obedit->type==OB_MESH) {
725
 
                                
726
 
                                calc_meshverts_ext();   /* drawobject.c */
727
 
                                eve= em->verts.first;
728
 
                                while(eve) {            
729
 
                                        if(eve->h==0 && eve->xs>rect.xmin && eve->xs<rect.xmax) {
730
 
                                                if(eve->ys>rect.ymin && eve->ys<rect.ymax) {
731
 
                                                        if(val==LEFTMOUSE) eve->f|= 1;
732
 
                                                        else eve->f&= 254;
733
 
                                                }
734
 
                                        }
735
 
                                        eve= eve->next;
736
 
                                }
 
1276
                                extern int em_solidoffs, em_wireoffs;   // let linker solve it... from editmesh_mods.c 
 
1277
                                EditMesh *em = G.editMesh;
 
1278
                                EditVert *eve;
 
1279
                                EditEdge *eed;
 
1280
                                EditFace *efa;
 
1281
                                int index, bbsel=0; // bbsel: no clip needed with screencoords
 
1282
                                
 
1283
                                bbsel= EM_init_backbuf_border(rect.xmin, rect.ymin, rect.xmax, rect.ymax);
 
1284
 
 
1285
                                if(G.scene->selectmode & SCE_SELECT_VERTEX) {
 
1286
                                        if(bbsel==0) calc_meshverts_ext();      /* clips, drawobject.c */
 
1287
                                        index= em_wireoffs;
 
1288
                                        for(eve= em->verts.first; eve; eve= eve->next, index++) {
 
1289
                                                if(eve->h==0) {
 
1290
                                                        if(bbsel || (eve->xs>rect.xmin && eve->xs<rect.xmax && eve->ys>rect.ymin && eve->ys<rect.ymax)) {
 
1291
                                                                if(EM_check_backbuf_border(index)) {
 
1292
                                                                        if(val==LEFTMOUSE) eve->f|= 1;
 
1293
                                                                        else eve->f&= 254;
 
1294
                                                                }
 
1295
                                                        }
 
1296
                                                }
 
1297
                                        }
 
1298
                                }
 
1299
                                if(G.scene->selectmode & SCE_SELECT_EDGE) {
 
1300
                                        short done= 0;
 
1301
                                        
 
1302
                                        calc_meshverts_ext_f2();        /* doesnt clip, drawobject.c */
 
1303
                                        index= em_solidoffs;
 
1304
                                        /* two stages, for nice edge select first do 'both points in rect'
 
1305
                                           also when bbsel is true */
 
1306
                                        for(eed= em->edges.first; eed; eed= eed->next, index++) {
 
1307
                                                if(eed->h==0) {
 
1308
                                                        if(edge_fully_inside_rect(rect, eed->v1->xs, eed->v1->ys, eed->v2->xs, eed->v2->ys)) {
 
1309
                                                                if(EM_check_backbuf_border(index)) {
 
1310
                                                                        EM_select_edge(eed, val==LEFTMOUSE);
 
1311
                                                                        done = 1;
 
1312
                                                                }
 
1313
                                                        }
 
1314
                                                }
 
1315
                                        }
 
1316
 
 
1317
                                        if(done==0) {
 
1318
                                                index= em_solidoffs;
 
1319
                                                for(eed= em->edges.first; eed; eed= eed->next, index++) {
 
1320
                                                        if(eed->h==0) {
 
1321
                                                                if(bbsel) {
 
1322
                                                                        if(EM_check_backbuf_border(index))
 
1323
                                                                                EM_select_edge(eed, val==LEFTMOUSE);
 
1324
                                                                }
 
1325
                                                                else if(edge_inside_rect(rect, eed->v1->xs, eed->v1->ys, eed->v2->xs, eed->v2->ys)) {
 
1326
                                                                        EM_select_edge(eed, val==LEFTMOUSE);
 
1327
                                                                }
 
1328
                                                        }
 
1329
                                                }
 
1330
                                        }
 
1331
                                }
 
1332
                                
 
1333
                                if(G.scene->selectmode & SCE_SELECT_FACE) {
 
1334
                                        if(bbsel==0) calc_mesh_facedots_ext();
 
1335
                                        index= 1;
 
1336
                                        for(efa= em->faces.first; efa; efa= efa->next, index++) {
 
1337
                                                if(efa->h==0) {
 
1338
                                                        if(bbsel || (efa->xs>rect.xmin && efa->xs<rect.xmax && efa->ys>rect.ymin && efa->ys<rect.ymax)) {
 
1339
                                                                if(EM_check_backbuf_border(index)) {
 
1340
                                                                        EM_select_face_fgon(efa, val==LEFTMOUSE);
 
1341
                                                                }
 
1342
                                                        }
 
1343
                                                }
 
1344
                                        }
 
1345
                                }
 
1346
                                
 
1347
                                EM_free_backbuf_border();
 
1348
                                        
 
1349
                                EM_selectmode_flush();
737
1350
                                allqueue(REDRAWVIEW3D, 0);
738
1351
                                
739
1352
                        }
799
1412
                                
800
1413
                                while(ml) {
801
1414
                                        for(a=0; a<hits; a++) {
802
 
                                                if(ml->selcol==buffer[ (4 * a) + 3 ]) {
 
1415
                                                if(ml->selcol1==buffer[ (4 * a) + 3 ]) {
 
1416
                                                        ml->flag |= MB_SCALE_RAD;
 
1417
                                                        if(val==LEFTMOUSE) ml->flag |= SELECT;
 
1418
                                                        else ml->flag &= ~SELECT;
 
1419
                                                        break;
 
1420
                                                }
 
1421
                                                if(ml->selcol2==buffer[ (4 * a) + 3 ]) {
 
1422
                                                        ml->flag &= ~MB_SCALE_RAD;
803
1423
                                                        if(val==LEFTMOUSE) ml->flag |= SELECT;
804
1424
                                                        else ml->flag &= ~SELECT;
805
1425
                                                        break;
887
1507
                                base= base->next;
888
1508
                        }
889
1509
                        /* frontbuffer flush */
890
 
                        glFinish();
 
1510
                        glFlush();
891
1511
                        
892
1512
                        allqueue(REDRAWDATASELECT, 0);
893
1513
                        
910
1530
                
911
1531
                allqueue(REDRAWINFO, 0);
912
1532
        }
 
1533
 
 
1534
        if(val) BIF_undo_push("Border select");
 
1535
        
913
1536
} /* end of borderselect() */
914
1537
 
915
1538
/* ------------------------------------------------------------------------- */
923
1546
        XXX These callback functions are still dirty, because they call globals... 
924
1547
  */
925
1548
 
926
 
void mesh_selectionCB(int selecting, Object *editobj, short *mval, float rad)
 
1549
static void mesh_selectionCB(int selecting, Object *editobj, short *mval, float rad)
927
1550
{
 
1551
        extern int em_solidoffs, em_wireoffs;   // let linker solve it... from editmesh_mods.c 
928
1552
        EditMesh *em = G.editMesh;
929
1553
        EditVert *eve;
 
1554
        EditEdge *eed;
 
1555
        EditFace *efa;
930
1556
        float x, y, r;
 
1557
        int index, bbsel=0; // if bbsel we dont clip with screencoords
 
1558
        short rads= (short)(rad+1.0);
 
1559
        
 
1560
        bbsel= EM_init_backbuf_circle(mval[0], mval[1], rads);
 
1561
        
 
1562
        if(G.scene->selectmode & SCE_SELECT_VERTEX) {
 
1563
                if(bbsel==0) calc_meshverts_ext();      /* drawobject.c */
 
1564
                index= em_wireoffs;
 
1565
                for(eve= em->verts.first; eve; eve= eve->next, index++) {
 
1566
                        if(eve->h==0) {
 
1567
                                if(bbsel) {
 
1568
                                        if(EM_check_backbuf_border(index)) {
 
1569
                                                if(selecting==LEFTMOUSE) eve->f|= 1;
 
1570
                                                else eve->f&= 254;
 
1571
                                        }
 
1572
                                }
 
1573
                                else {
 
1574
                                        x= eve->xs-mval[0];
 
1575
                                        y= eve->ys-mval[1];
 
1576
                                        r= sqrt(x*x+y*y);
 
1577
                                        if(r<=rad) {
 
1578
                                                if(selecting==LEFTMOUSE) eve->f|= 1;
 
1579
                                                else eve->f&= 254;
 
1580
                                        }
 
1581
                                }
 
1582
                        }
 
1583
                }
 
1584
        }
931
1585
 
932
 
        calc_meshverts_ext();   /* drawobject.c */
933
 
        eve= em->verts.first;
934
 
        while(eve) {
935
 
                if(eve->h==0) {
936
 
                        x= eve->xs-mval[0];
937
 
                        y= eve->ys-mval[1];
938
 
                        r= sqrt(x*x+y*y);
939
 
                        if(r<=rad) {
940
 
                                if(selecting==LEFTMOUSE) eve->f|= 1;
941
 
                                else eve->f&= 254;
942
 
                        }
943
 
                }
944
 
                eve= eve->next;
945
 
        }
 
1586
        if(G.scene->selectmode & SCE_SELECT_EDGE) {
 
1587
                if(bbsel==0) calc_meshverts_ext_f2();   /* doesnt clip, drawobject.c */
 
1588
                index= em_solidoffs;
 
1589
                for(eed= em->edges.first; eed; eed= eed->next, index++) {
 
1590
                        if(eed->h==0) {
 
1591
                                if(bbsel || edge_inside_circle(mval[0], mval[1], (short)rad, eed->v1->xs, eed->v1->ys,  eed->v2->xs, eed->v2->ys)) {
 
1592
                                        if(EM_check_backbuf_border(index)) {
 
1593
                                                EM_select_edge(eed, selecting==LEFTMOUSE);
 
1594
                                        }
 
1595
                                }
 
1596
                        }
 
1597
                }
 
1598
        }
 
1599
        
 
1600
        if(G.scene->selectmode & SCE_SELECT_FACE) {
 
1601
                if(bbsel==0) calc_mesh_facedots_ext();
 
1602
                index= 1;
 
1603
                for(efa= em->faces.first; efa; efa= efa->next, index++) {
 
1604
                        if(efa->h==0) {
 
1605
                                if(bbsel) {
 
1606
                                        if(EM_check_backbuf_border(index)) {
 
1607
                                                EM_select_face_fgon(efa, selecting==LEFTMOUSE);
 
1608
                                        }
 
1609
                                }
 
1610
                                else {
 
1611
                                        x= efa->xs-mval[0];
 
1612
                                        y= efa->ys-mval[1];
 
1613
                                        r= sqrt(x*x+y*y);
 
1614
                                        if(r<=rad) {
 
1615
                                                EM_select_face_fgon(efa, selecting==LEFTMOUSE);
 
1616
                                        }
 
1617
                                }
 
1618
                        }
 
1619
                }
 
1620
        }
 
1621
        EM_free_backbuf_border();
 
1622
        EM_selectmode_flush();
946
1623
 
947
1624
        draw_sel_circle(0, 0, 0, 0, 0); /* signal */
948
 
        force_draw();
 
1625
        force_draw(0);
949
1626
 
950
1627
}
951
1628
 
952
1629
 
953
 
void nurbscurve_selectionCB(int selecting, Object *editobj, short *mval, float rad)
 
1630
static void nurbscurve_selectionCB(int selecting, Object *editobj, short *mval, float rad)
954
1631
{
955
1632
        Nurb *nu;
956
1633
        BPoint *bp;
1011
1688
                nu= nu->next;
1012
1689
        }
1013
1690
        draw_sel_circle(0, 0, 0, 0, 0); /* signal */
1014
 
        force_draw();
 
1691
        force_draw(0);
1015
1692
 
1016
1693
 
1017
1694
}
1018
1695
 
1019
 
void lattice_selectionCB(int selecting, Object *editobj, short *mval, float rad)
 
1696
static void lattice_selectionCB(int selecting, Object *editobj, short *mval, float rad)
1020
1697
{
1021
1698
        BPoint *bp;
1022
1699
        float x, y, r;
1040
1717
                bp++;
1041
1718
        }
1042
1719
        draw_sel_circle(0, 0, 0, 0, 0); /* signal */
1043
 
        force_draw();
 
1720
        force_draw(0);
1044
1721
}
1045
1722
 
1046
1723
/** Callbacks for selection in Editmode */
1061
1738
        }
1062
1739
}
1063
1740
 
1064
 
/** The circle select function - should be replaced by the callback 
1065
 
  * version circle_selectCB(). Why ? Because it's not nice as it is!
1066
 
  * 
1067
 
  */
1068
 
 
1069
 
void circle_select(void)
1070
 
{
1071
 
        EditMesh *em = G.editMesh;
1072
 
        Nurb *nu;
1073
 
        BPoint *bp;
1074
 
        BezTriple *bezt;
1075
 
        EditVert *eve;
1076
 
        static float rad= 40.0;
1077
 
        float rado, x, y, trad;
1078
 
        int a, firsttime=1;
1079
 
        unsigned short event;
1080
 
        short mvalo[2], mval[2], val;
1081
 
        short selecting=0;
1082
 
        
1083
 
        if(G.obedit==0) return;
1084
 
        
1085
 
        getmouseco_areawin(mvalo);
1086
 
        draw_sel_circle(mvalo, 0, rad, 0.0, selecting);
1087
 
        
1088
 
        rado= rad;
1089
 
        
1090
 
        while(TRUE) {
1091
 
                
1092
 
                /* when a renderwindow is open and mouse enters it (activates sometimes) */
1093
 
 
1094
 
                mywinset(curarea->win);
1095
 
 
1096
 
                getmouseco_areawin(mval);
1097
 
                
1098
 
                if(mval[0]!=mvalo[0] || mval[1]!=mvalo[1] || rado!=rad || firsttime) {
1099
 
                        firsttime= 0;
1100
 
                        
1101
 
                        draw_sel_circle(mval, mvalo, rad, rado, selecting);
1102
 
                
1103
 
                        mvalo[0]= mval[0];
1104
 
                        mvalo[1]= mval[1];
1105
 
                        rado= rad;
1106
 
 
1107
 
                        if(selecting) {
1108
 
                                
1109
 
                                if(G.obedit->type==OB_MESH) {
1110
 
                                        
1111
 
                                        calc_meshverts_ext();   /* drawobject.c */
1112
 
                                        eve= em->verts.first;
1113
 
                                        while(eve) {
1114
 
                                                if(eve->h==0) {
1115
 
                                                        x= eve->xs-mval[0];
1116
 
                                                        y= eve->ys-mval[1];
1117
 
                                                        trad= sqrt(x*x+y*y);
1118
 
                                                        if(trad<=rad) {
1119
 
                                                                if(selecting==LEFTMOUSE) eve->f|= 1;
1120
 
                                                                else eve->f&= 254;
1121
 
                                                        }
1122
 
                                                }
1123
 
                                                eve= eve->next;
1124
 
                                        }
1125
 
                                        draw_sel_circle(0, 0, 0, 0, 0); /* signal */
1126
 
                                        force_draw();
1127
 
                                }
1128
 
                                else if ELEM(G.obedit->type, OB_CURVE, OB_SURF) {
1129
 
                                        
1130
 
                                        calc_nurbverts_ext();   /* drawobject.c */
1131
 
                                        nu= editNurb.first;
1132
 
                                        while(nu) {
1133
 
                                                if((nu->type & 7)==CU_BEZIER) {
1134
 
                                                        bezt= nu->bezt;
1135
 
                                                        a= nu->pntsu;
1136
 
                                                        while(a--) {
1137
 
                                                                if(bezt->hide==0) {
1138
 
                                                                        x= bezt->s[0][0]-mval[0];
1139
 
                                                                        y= bezt->s[0][1]-mval[1];
1140
 
                                                                        trad= sqrt(x*x+y*y);
1141
 
                                                                        if(trad<=rad) {
1142
 
                                                                                if(selecting==LEFTMOUSE) bezt->f1|= 1;
1143
 
                                                                                else bezt->f1 &= ~1;
1144
 
                                                                        }
1145
 
                                                                        x= bezt->s[1][0]-mval[0];
1146
 
                                                                        y= bezt->s[1][1]-mval[1];
1147
 
                                                                        trad= sqrt(x*x+y*y);
1148
 
                                                                        if(trad<=rad) {
1149
 
                                                                                if(selecting==LEFTMOUSE) bezt->f2|= 1;
1150
 
                                                                                else bezt->f2 &= ~1;
1151
 
                                                                        }
1152
 
                                                                        x= bezt->s[2][0]-mval[0];
1153
 
                                                                        y= bezt->s[2][1]-mval[1];
1154
 
                                                                        trad= sqrt(x*x+y*y);
1155
 
                                                                        if(trad<=rad) {
1156
 
                                                                                if(selecting==LEFTMOUSE) bezt->f3|= 1;
1157
 
                                                                                else bezt->f3 &= ~1;
1158
 
                                                                        }
1159
 
                                                                        
1160
 
                                                                }
1161
 
                                                                bezt++;
1162
 
                                                        }
1163
 
                                                }
1164
 
                                                else {
1165
 
                                                        bp= nu->bp;
1166
 
                                                        a= nu->pntsu*nu->pntsv;
1167
 
                                                        while(a--) {
1168
 
                                                                if(bp->hide==0) {
1169
 
                                                                        x= bp->s[0]-mval[0];
1170
 
                                                                        y= bp->s[1]-mval[1];
1171
 
                                                                        trad= sqrt(x*x+y*y);
1172
 
                                                                        if(trad<=rad) {
1173
 
                                                                                if(selecting==LEFTMOUSE) bp->f1|= 1;
1174
 
                                                                                else bp->f1 &= ~1;
1175
 
                                                                        }
1176
 
                                                                }
1177
 
                                                                bp++;
1178
 
                                                        }
1179
 
                                                }
1180
 
                                                nu= nu->next;
1181
 
                                        }
1182
 
                                        draw_sel_circle(0, 0, 0, 0, 0); /* signal */
1183
 
                                        force_draw();
1184
 
                                }
1185
 
                                else if(G.obedit->type==OB_LATTICE) {
1186
 
                                        calc_lattverts_ext();
1187
 
                                        
1188
 
                                        bp= editLatt->def;
1189
 
                
1190
 
                                        a= editLatt->pntsu*editLatt->pntsv*editLatt->pntsw;
1191
 
                                        while(a--) {
1192
 
                                                if(bp->hide==0) {
1193
 
                                                        x= bp->s[0]-mval[0];
1194
 
                                                        y= bp->s[1]-mval[1];
1195
 
                                                        trad= sqrt(x*x+y*y);
1196
 
                                                        if(trad<=rad) {
1197
 
                                                                if(selecting==LEFTMOUSE) bp->f1|= 1;
1198
 
                                                                else bp->f1 &= ~1;
1199
 
                                                        }
1200
 
                                                }
1201
 
                                                bp++;
1202
 
                                        }
1203
 
                                        draw_sel_circle(0, 0, 0, 0, 0); /* signal */
1204
 
                                        force_draw();
1205
 
                                }
1206
 
                        }
1207
 
                }
1208
 
 
1209
 
                event= extern_qread(&val);
1210
 
                if (event) {
1211
 
                        int afbreek= 0;
1212
 
                        
1213
 
                        switch(event) {
1214
 
                        case LEFTMOUSE:
1215
 
                        case MIDDLEMOUSE:
1216
 
                                if(val) selecting= event;
1217
 
                                else selecting= 0;
1218
 
                                firsttime= 1;
1219
 
                                
1220
 
                                break;
1221
 
                        case PADPLUSKEY:
1222
 
                                if(val) if(rad<200.0) rad*= 1.2;
1223
 
                                break;
1224
 
                        case PADMINUS:
1225
 
                                if(val) if(rad>5.0) rad/= 1.2;
1226
 
                                break;
1227
 
                        
1228
 
                        case ESCKEY: case SPACEKEY: case RIGHTMOUSE:
1229
 
                        case GKEY: case SKEY: case RKEY: case XKEY: case EKEY: case TABKEY:
1230
 
                                afbreek= 1;
1231
 
                                break;
1232
 
 
1233
 
                        }
1234
 
                        
1235
 
                        if(afbreek) break;
1236
 
                }
1237
 
        }
1238
 
        
1239
 
        /* clear circle */
1240
 
        draw_sel_circle(0, mvalo, 0, rad, 1);
1241
 
 
1242
 
        countall();
1243
 
        allqueue(REDRAWINFO, 0);
1244
 
}
1245
 
 
1246
1741
void set_render_border(void)
1247
1742
{
1248
1743
        rcti rect;
1296
1791
        
1297
1792
        warp_pointer(cent[0], cent[1]);
1298
1793
        
1299
 
        cent[0]=  (curarea->winx)/2;
1300
 
        cent[1]=  (curarea->winy)/2;
 
1794
        /* we have to rely on events to give proper mousecoords after a warp_pointer */
 
1795
        mval[0]= cent[0]=  (curarea->winx)/2;
 
1796
        mval[1]= cent[1]=  (curarea->winy)/2;
1301
1797
        
1302
1798
        headerprint("Fly");
1303
1799
        
1304
1800
        while(loop) {
1305
 
                getmouseco_areawin(mval);
 
1801
                
1306
1802
 
1307
1803
                while(qtest()) {
1308
1804
                        
1309
1805
                        toets= extern_qread(&val);
1310
1806
                        
1311
1807
                        if(val) {
1312
 
                                if(toets==ESCKEY) {
 
1808
                                if(toets==MOUSEY) getmouseco_areawin(mval);
 
1809
                                else if(toets==ESCKEY) {
1313
1810
                                        VECCOPY(G.vd->camera->loc, oldvec);
1314
1811
                                        VECCOPY(G.vd->camera->rot, oldrot);
1315
1812
                                        loop= 0;
1317
1814
                                }
1318
1815
                                else if(toets==SPACEKEY) {
1319
1816
                                        loop= 0;
 
1817
                                        BIF_undo_push("Fly camera");
1320
1818
                                        break;
1321
1819
                                }
1322
1820
                                else if(toets==LEFTMOUSE) {