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

« back to all changes in this revision

Viewing changes to source/blender/src/editmesh.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: editmesh.c,v 1.87 2004/05/11 19:08:02 ton Exp $
 
2
 * $Id: editmesh.c,v 1.135 2005/06/11 12:56:39 ton Exp $
3
3
 *
4
4
 * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
5
5
 *
30
30
 * ***** END GPL/BL DUAL LICENSE BLOCK *****
31
31
 */
32
32
 
33
 
/* main mesh editing routines. please note that 'vlak' is used here to denote a 'face'. */
34
 
/* at that time for me a face was something at the frontside of a human head! (ton) */
35
33
 
36
34
#include <stdlib.h>
37
35
#include <string.h>
41
39
#include <config.h>
42
40
#endif
43
41
 
44
 
#ifdef WIN32
45
 
#include "BLI_winstuff.h"
46
 
#endif
47
42
#include "MEM_guardedalloc.h"
48
43
 
49
44
#include "PIL_time.h"
50
45
 
51
 
#include "MTC_matrixops.h"
52
 
 
53
46
#include "DNA_mesh_types.h"
54
47
#include "DNA_meshdata_types.h"
55
48
#include "DNA_object_types.h"
 
49
#include "DNA_object_force.h"
56
50
#include "DNA_screen_types.h"
57
51
#include "DNA_key_types.h"
58
52
#include "DNA_scene_types.h"
64
58
#include "BLI_blenlib.h"
65
59
#include "BLI_arithb.h"
66
60
#include "BLI_editVert.h"
67
 
#include "BLI_rand.h"
68
 
 
 
61
#include "BLI_dynstr.h"
69
62
 
70
63
#include "BKE_utildefines.h"
71
64
#include "BKE_key.h"
72
65
#include "BKE_object.h"
73
 
#include "BKE_texture.h"
74
66
#include "BKE_displist.h"
 
67
#include "BKE_DerivedMesh.h"
75
68
#include "BKE_global.h"
76
69
#include "BKE_library.h"
77
70
#include "BKE_main.h"
78
71
#include "BKE_material.h"
79
72
#include "BKE_mesh.h"
 
73
#include "BKE_texture.h"
80
74
 
81
 
#include "BIF_gl.h"
82
 
#include "BIF_graphics.h"
83
75
#include "BIF_editkey.h"
 
76
#include "BIF_editmesh.h"
 
77
#include "BIF_editmode_undo.h"
 
78
#include "BIF_interface.h"
 
79
#include "BIF_mywindow.h"
84
80
#include "BIF_space.h"
 
81
#include "BIF_screen.h"
85
82
#include "BIF_toolbox.h"
86
 
#include "BIF_screen.h"
87
 
#include "BIF_interface.h"
88
 
#include "BIF_editmesh.h"
89
 
#include "BIF_mywindow.h"
90
 
#include "BIF_resources.h"
91
 
#include "BIF_glutil.h"
92
 
#include "BIF_cursors.h"
93
83
 
94
84
#include "BSE_view.h"
95
85
#include "BSE_edit.h"
102
92
 
103
93
#include "mydevice.h"
104
94
#include "blendef.h"
105
 
#include "nla.h"                /* For __NLA : Important - Do not remove! */
106
 
#include "render.h"
107
 
 
108
 
#include "GHOST_C-api.h"
109
 
#include "winlay.h"
110
 
 
111
 
#ifdef WIN32
112
 
        #ifndef snprintf
113
 
                #define snprintf  _snprintf
114
 
        #endif
115
 
#endif
116
 
 
117
 
/****/
118
 
 
119
 
static float convex(float *v1, float *v2, float *v3, float *v4);
120
 
 
121
 
/* EditMesh Undo */
122
 
void make_editMesh_real(Mesh *me);
123
 
void load_editMesh_real(Mesh *me, int);
124
 
/****/
125
 
 
126
 
 
127
 
/* extern ListBase fillvertbase, filledgebase; */ /* scanfill.c, in
128
 
    the lib... already in BLI_blenlib.h */
129
 
 
130
 
 
131
 
extern short editbutflag;
132
 
 
133
 
static float icovert[12][3] = {
134
 
        {0,0,-200}, 
135
 
        {144.72, -105.144,-89.443},
136
 
        {-55.277, -170.128,-89.443}, 
137
 
        {-178.885,0,-89.443},
138
 
        {-55.277,170.128,-89.443}, 
139
 
        {144.72,105.144,-89.443},
140
 
        {55.277,-170.128,89.443},
141
 
        {-144.72,-105.144,89.443},
142
 
        {-144.72,105.144,89.443},
143
 
        {55.277,170.128,89.443},
144
 
        {178.885,0,89.443},
145
 
        {0,0,200}
146
 
};
147
 
static short icovlak[20][3] = {
148
 
        {1,0,2},
149
 
        {1,0,5},
150
 
        {2,0,3},
151
 
        {3,0,4},
152
 
        {4,0,5},
153
 
        {1,5,10},
154
 
        {2,1,6},
155
 
        {3,2,7},
156
 
        {4,3,8},
157
 
        {5,4,9},
158
 
        {10,1,6},
159
 
        {6,2,7},
160
 
        {7,3,8},
161
 
        {8,4,9},
162
 
        {9,5,10},
163
 
        {6,10,11},
164
 
        {7,6,11},
165
 
        {8,7,11},
166
 
        {9,8,11},
167
 
        {10,9,11}
168
 
};
169
 
 
170
 
/* DEFINES */
171
 
#define UVCOPY(t, s) memcpy(t, s, 2 * sizeof(float));
172
 
 
173
 
#define TEST_EDITMESH   if(G.obedit==0) return; \
174
 
                                                if( (G.vd->lay & G.obedit->lay)==0 ) return;
175
 
 
176
 
#define FACE_MARKCLEAR(f) (f->f1 = 1)
 
95
 
 
96
/* own include */
 
97
#include "editmesh.h"
 
98
 
 
99
/* 
 
100
 
 
101
editmesh.c:
 
102
- add/alloc/free data
 
103
- hashtables
 
104
- enter/exit editmode
 
105
 
 
106
*/
 
107
 
177
108
 
178
109
/* ***************** HASH ********************* */
179
110
 
180
 
/* HASH struct quickly finding of edges */
181
 
struct HashEdge {
182
 
        struct EditEdge *eed;
183
 
        struct HashEdge *next;
184
 
};
185
 
 
186
 
struct HashEdge *hashedgetab=NULL;
187
 
 
188
 
/********* qsort routines *********/
189
 
 
190
 
 
191
 
struct xvertsort {
192
 
        float x;
193
 
        EditVert *v1;
194
 
};
195
 
 
196
 
/* Functions */
197
 
static int vergxco(const void *v1, const void *v2)
198
 
{
199
 
        const struct xvertsort *x1=v1, *x2=v2;
200
 
 
201
 
        if( x1->x > x2->x ) return 1;
202
 
        else if( x1->x < x2->x) return -1;
203
 
        return 0;
204
 
}
205
 
 
206
 
struct vlaksort {
207
 
        long x;
208
 
        struct EditVlak *evl;
209
 
};
210
 
 
211
 
 
212
 
static int vergvlak(const void *v1, const void *v2)
213
 
{
214
 
        const struct vlaksort *x1=v1, *x2=v2;
215
 
        
216
 
        if( x1->x > x2->x ) return 1;
217
 
        else if( x1->x < x2->x) return -1;
218
 
        return 0;
219
 
}
 
111
 
 
112
#define EDHASHSIZE              (512*512)
 
113
#define EDHASH(a, b)    (a % EDHASHSIZE)
220
114
 
221
115
 
222
116
/* ************ ADD / REMOVE / FIND ****************** */
223
117
 
224
 
#define EDHASH(a, b)    ( (a)*256 + (b) )
225
 
#define EDHASHSIZE      65536
 
118
/* used to bypass normal calloc with fast one */
 
119
static void *(*callocvert)(size_t, size_t) = calloc;
 
120
static void *(*callocedge)(size_t, size_t) = calloc;
 
121
static void *(*callocface)(size_t, size_t) = calloc;
226
122
 
227
123
EditVert *addvertlist(float *vec)
228
124
{
229
125
        EditMesh *em = G.editMesh;
230
126
        EditVert *eve;
231
 
        static unsigned char hashnr= 0;
 
127
        static int hashnr= 0;
232
128
 
233
 
        eve= calloc(sizeof(EditVert), 1);
 
129
        eve= callocvert(sizeof(EditVert), 1);
234
130
        BLI_addtail(&em->verts, eve);
235
131
        
236
132
        if(vec) VECCOPY(eve->co, vec);
237
133
 
238
134
        eve->hash= hashnr++;
 
135
        if( hashnr>=EDHASHSIZE) hashnr= 0;
239
136
 
240
137
        /* new verts get keyindex of -1 since they did not
241
138
         * have a pre-editmode vertex order
244
141
        return eve;
245
142
}
246
143
 
 
144
void free_editvert (EditVert *eve)
 
145
{
 
146
        if(eve->dw) MEM_freeN(eve->dw);
 
147
        if(eve->fast==0) free(eve);
 
148
}
 
149
 
 
150
 
247
151
EditEdge *findedgelist(EditVert *v1, EditVert *v2)
248
152
{
249
153
        EditVert *v3;
250
154
        struct HashEdge *he;
251
155
 
252
 
        if(hashedgetab==0) {
253
 
                hashedgetab= MEM_callocN(EDHASHSIZE*sizeof(struct HashEdge), "hashedgetab");
254
 
        }
255
 
        
256
156
        /* swap ? */
257
157
        if( (long)v1 > (long)v2) {
258
158
                v3= v2; 
260
160
                v1= v3;
261
161
        }
262
162
        
263
 
        he= hashedgetab + EDHASH(v1->hash, v2->hash);
 
163
        if(G.editMesh->hashedgetab==NULL)
 
164
                G.editMesh->hashedgetab= MEM_callocN(EDHASHSIZE*sizeof(struct HashEdge), "hashedgetab");
 
165
 
 
166
        he= G.editMesh->hashedgetab + EDHASH(v1->hash, v2->hash);
264
167
        
265
168
        while(he) {
266
169
                
277
180
        
278
181
        struct HashEdge *first, *he;
279
182
 
280
 
        first= hashedgetab + EDHASH(eed->v1->hash, eed->v2->hash);
 
183
        first= G.editMesh->hashedgetab + EDHASH(eed->v1->hash, eed->v2->hash);
281
184
 
282
185
        if( first->eed==0 ) {
283
186
                first->eed= eed;
284
187
        }
285
188
        else {
286
 
                he= (struct HashEdge *)malloc(sizeof(struct HashEdge)); 
 
189
                he= &eed->hash; 
287
190
                he->eed= eed;
288
191
                he->next= first->next;
289
192
                first->next= he;
296
199
        
297
200
        struct HashEdge *first, *he, *prev=NULL;
298
201
 
299
 
 
300
 
        he=first= hashedgetab + EDHASH(eed->v1->hash, eed->v2->hash);
 
202
        he=first= G.editMesh->hashedgetab + EDHASH(eed->v1->hash, eed->v2->hash);
301
203
 
302
204
        while(he) {
303
205
                if(he->eed == eed) {
307
209
                                        he= first->next;
308
210
                                        first->eed= he->eed;
309
211
                                        first->next= he->next;
310
 
                                        free(he);
311
212
                                }
312
213
                                else he->eed= 0;
313
214
                        }
314
215
                        else {
315
216
                                prev->next= he->next;
316
 
                                free(he);
317
217
                        }
318
218
                        return;
319
219
                }
322
222
        }
323
223
}
324
224
 
325
 
void free_hashedgetab(void)
326
 
{
327
 
        struct HashEdge *he, *first, *hen;
328
 
        int a;
329
 
        
330
 
        if(hashedgetab) {
331
 
        
332
 
                first= hashedgetab;
333
 
                for(a=0; a<EDHASHSIZE; a++, first++) {
334
 
                        he= first->next;
335
 
                        while(he) {
336
 
                                hen= he->next;
337
 
                                free(he);
338
 
                                he= hen;
339
 
                        }
340
 
                }
341
 
                MEM_freeN(hashedgetab);
342
 
                hashedgetab= 0;
343
 
        }
344
 
}
345
 
 
346
 
EditEdge *addedgelist(EditVert *v1, EditVert *v2)
 
225
EditEdge *addedgelist(EditVert *v1, EditVert *v2, EditEdge *example)
347
226
{
348
227
        EditMesh *em = G.editMesh;
349
228
        EditVert *v3;
350
229
        EditEdge *eed;
351
230
        int swap= 0;
352
231
        
 
232
        if(v1==v2) return NULL;
 
233
        if(v1==NULL || v2==NULL) return NULL;
 
234
 
353
235
        /* swap ? */
354
236
        if(v1>v2) {
355
237
                v3= v2; 
357
239
                v1= v3;
358
240
                swap= 1;
359
241
        }
360
 
 
361
 
        if(v1==v2) return 0;
362
 
        if(v1==0 || v2==0) return 0;
363
242
        
364
243
        /* find in hashlist */
365
244
        eed= findedgelist(v1, v2);
 
245
 
 
246
        if(eed==NULL) {
366
247
        
367
 
        if(eed==0) {
368
 
 
369
 
                eed= (EditEdge *)calloc(sizeof(EditEdge), 1);
 
248
                eed= (EditEdge *)callocedge(sizeof(EditEdge), 1);
370
249
                eed->v1= v1;
371
250
                eed->v2= v2;
372
251
                BLI_addtail(&em->edges, eed);
373
252
                eed->dir= swap;
374
253
                insert_hashedge(eed);
 
254
                
 
255
                /* copy edge data:
 
256
                   rule is to do this with addedgelist call, before addfacelist */
 
257
                if(example) {
 
258
                        eed->crease= example->crease;
 
259
                        eed->seam = example->seam;
 
260
                        eed->h |= (example->h & EM_FGON);
 
261
                }
375
262
        }
 
263
 
376
264
        return eed;
377
265
}
378
266
 
379
 
static void free_editvert (EditVert *eve)
380
 
{
381
 
        if (eve->dw) MEM_freeN (eve->dw);
382
 
        free (eve);
383
 
}
384
 
 
385
267
void remedge(EditEdge *eed)
386
268
{
387
269
        EditMesh *em = G.editMesh;
390
272
        remove_hashedge(eed);
391
273
}
392
274
 
393
 
static void free_editedge(EditEdge *eed)
394
 
{
395
 
        free(eed);
396
 
}
397
 
 
398
 
static void free_editvlak(EditVlak *evl)
399
 
{
400
 
        free(evl);
401
 
}
402
 
 
403
 
static void free_vertlist(ListBase *edve) 
 
275
void free_editedge(EditEdge *eed)
 
276
{
 
277
        if(eed->fast==0) free(eed);
 
278
}
 
279
 
 
280
void free_editface(EditFace *efa)
 
281
{
 
282
        if(efa->fast==0) free(efa);
 
283
}
 
284
 
 
285
void free_vertlist(ListBase *edve) 
404
286
{
405
287
        EditVert *eve, *next;
406
288
 
415
297
        edve->first= edve->last= NULL;
416
298
}
417
299
 
418
 
static void free_edgelist(ListBase *lb)
 
300
void free_edgelist(ListBase *lb)
419
301
{
420
302
        EditEdge *eed, *next;
421
303
        
428
310
        lb->first= lb->last= NULL;
429
311
}
430
312
 
431
 
static void free_vlaklist(ListBase *lb)
 
313
void free_facelist(ListBase *lb)
432
314
{
433
 
        EditVlak *evl, *next;
 
315
        EditFace *efa, *next;
434
316
        
435
 
        evl= lb->first;
436
 
        while(evl) {
437
 
                next= evl->next;
438
 
                free_editvlak(evl);
439
 
                evl= next;
 
317
        efa= lb->first;
 
318
        while(efa) {
 
319
                next= efa->next;
 
320
                free_editface(efa);
 
321
                efa= next;
440
322
        }
441
323
        lb->first= lb->last= NULL;
442
324
}
443
325
 
444
 
EditVlak *addvlaklist(EditVert *v1, EditVert *v2, EditVert *v3, EditVert *v4, EditVlak *example)
 
326
EditFace *addfacelist(EditVert *v1, EditVert *v2, EditVert *v3, EditVert *v4, EditFace *example, EditFace *exampleEdges)
445
327
{
446
328
        EditMesh *em = G.editMesh;
447
 
        EditVlak *evl;
 
329
        EditFace *efa;
448
330
        EditEdge *e1, *e2=0, *e3=0, *e4=0;
449
 
        
450
331
 
451
332
        /* add face to list and do the edges */
452
 
        e1= addedgelist(v1, v2);
453
 
        if(v3) e2= addedgelist(v2, v3);
454
 
        if(v4) e3= addedgelist(v3, v4); else e3= addedgelist(v3, v1);
455
 
        if(v4) e4= addedgelist(v4, v1);
 
333
        if(exampleEdges) {
 
334
                e1= addedgelist(v1, v2, exampleEdges->e1);
 
335
                e2= addedgelist(v2, v3, exampleEdges->e2);
 
336
                if(v4) e3= addedgelist(v3, v4, exampleEdges->e3); 
 
337
                else e3= addedgelist(v3, v1, exampleEdges->e3);
 
338
                if(v4) e4= addedgelist(v4, v1, exampleEdges->e4);
 
339
        }
 
340
        else {
 
341
                e1= addedgelist(v1, v2, NULL);
 
342
                e2= addedgelist(v2, v3, NULL);
 
343
                if(v4) e3= addedgelist(v3, v4, NULL); 
 
344
                else e3= addedgelist(v3, v1, NULL);
 
345
                if(v4) e4= addedgelist(v4, v1, NULL);
 
346
        }
456
347
        
457
 
        if(v1==v2 || v2==v3 || v1==v3) return 0;
458
 
        if(e2==0) return 0;
459
 
 
460
 
        evl= (EditVlak *)calloc(sizeof(EditVlak), 1);
461
 
        evl->v1= v1;
462
 
        evl->v2= v2;
463
 
        evl->v3= v3;
464
 
        evl->v4= v4;
465
 
 
466
 
        evl->e1= e1;
467
 
        evl->e2= e2;
468
 
        evl->e3= e3;
469
 
        evl->e4= e4;
 
348
        if(v1==v2 || v2==v3 || v1==v3) return NULL;
 
349
        if(e2==0) return NULL;
 
350
 
 
351
        efa= (EditFace *)callocface(sizeof(EditFace), 1);
 
352
        efa->v1= v1;
 
353
        efa->v2= v2;
 
354
        efa->v3= v3;
 
355
        efa->v4= v4;
 
356
 
 
357
        efa->e1= e1;
 
358
        efa->e2= e2;
 
359
        efa->e3= e3;
 
360
        efa->e4= e4;
470
361
 
471
362
        if(example) {
472
 
                evl->mat_nr= example->mat_nr;
473
 
                evl->tf= example->tf;
474
 
                evl->flag= example->flag;
 
363
                efa->mat_nr= example->mat_nr;
 
364
                efa->tf= example->tf;
 
365
                efa->flag= example->flag;
475
366
        }
476
 
        else { 
 
367
        else {
477
368
                if (G.obedit && G.obedit->actcol)
478
 
                        evl->mat_nr= G.obedit->actcol-1;
479
 
                default_uv(evl->tf.uv, 1.0);
 
369
                        efa->mat_nr= G.obedit->actcol-1;
 
370
                default_uv(efa->tf.uv, 1.0);
480
371
 
481
372
                /* Initialize colors */
482
 
                evl->tf.col[0]= evl->tf.col[1]= evl->tf.col[2]= evl->tf.col[3]= vpaint_get_current_col();
483
 
        }
484
 
        
485
 
        BLI_addtail(&em->faces, evl);
486
 
 
487
 
        if(evl->v4) CalcNormFloat4(v1->co, v2->co, v3->co, v4->co, evl->n);
488
 
        else CalcNormFloat(v1->co, v2->co, v3->co, evl->n);
489
 
 
490
 
        return evl;
491
 
}
492
 
 
493
 
/* ********* end add / new / find */
494
 
 
495
 
static int comparevlak(EditVlak *vl1, EditVlak *vl2)
496
 
{
497
 
        EditVert *v1, *v2, *v3, *v4;
498
 
        
499
 
        if(vl1->v4 && vl2->v4) {
500
 
                v1= vl2->v1;
501
 
                v2= vl2->v2;
502
 
                v3= vl2->v3;
503
 
                v4= vl2->v4;
504
 
                
505
 
                if(vl1->v1==v1 || vl1->v2==v1 || vl1->v3==v1 || vl1->v4==v1) {
506
 
                        if(vl1->v1==v2 || vl1->v2==v2 || vl1->v3==v2 || vl1->v4==v2) {
507
 
                                if(vl1->v1==v3 || vl1->v2==v3 || vl1->v3==v3 || vl1->v4==v3) {
508
 
                                        if(vl1->v1==v4 || vl1->v2==v4 || vl1->v3==v4 || vl1->v4==v4) {
509
 
                                                return 1;
510
 
                                        }
511
 
                                }
512
 
                        }
513
 
                }
514
 
        }
515
 
        else if(vl1->v4==0 && vl2->v4==0) {
516
 
                v1= vl2->v1;
517
 
                v2= vl2->v2;
518
 
                v3= vl2->v3;
519
 
 
520
 
                if(vl1->v1==v1 || vl1->v2==v1 || vl1->v3==v1) {
521
 
                        if(vl1->v1==v2 || vl1->v2==v2 || vl1->v3==v2) {
522
 
                                if(vl1->v1==v3 || vl1->v2==v3 || vl1->v3==v3) {
523
 
                                        return 1;
524
 
                                }
525
 
                        }
526
 
                }
527
 
        }
528
 
 
529
 
        return 0;
530
 
}
531
 
 
532
 
static int exist_vlak(EditVert *v1, EditVert *v2, EditVert *v3, EditVert *v4)
533
 
{
534
 
        EditMesh *em = G.editMesh;
535
 
        EditVlak *evl, evltest;
536
 
        
537
 
        evltest.v1= v1;
538
 
        evltest.v2= v2;
539
 
        evltest.v3= v3;
540
 
        evltest.v4= v4;
541
 
        
542
 
        evl= em->faces.first;
543
 
        while(evl) {
544
 
                if(comparevlak(&evltest, evl)) return 1;
545
 
                evl= evl->next;
546
 
        }
547
 
        return 0;
548
 
}
549
 
 
550
 
 
551
 
static int vlakselectedOR(EditVlak *evl, int flag)
552
 
{
553
 
        
554
 
        if(evl->v1->f & flag) return 1;
555
 
        if(evl->v2->f & flag) return 1;
556
 
        if(evl->v3->f & flag) return 1;
557
 
        if(evl->v4 && (evl->v4->f & 1)) return 1;
558
 
        return 0;
559
 
}
560
 
 
561
 
int vlakselectedAND(EditVlak *evl, int flag)
562
 
{
563
 
        if(evl->v1->f & flag) {
564
 
                if(evl->v2->f & flag) {
565
 
                        if(evl->v3->f & flag) {
566
 
                                if(evl->v4) {
567
 
                                        if(evl->v4->f & flag) return 1;
568
 
                                }
569
 
                                else return 1;
570
 
                        }
571
 
                }
572
 
        }
573
 
        return 0;
574
 
}
575
 
 
576
 
void recalc_editnormals(void)
577
 
{
578
 
        EditMesh *em = G.editMesh;
579
 
        EditVlak *evl;
580
 
 
581
 
        evl= em->faces.first;
582
 
        while(evl) {
583
 
                if(evl->v4) CalcNormFloat4(evl->v1->co, evl->v2->co, evl->v3->co, evl->v4->co, evl->n);
584
 
                else CalcNormFloat(evl->v1->co, evl->v2->co, evl->v3->co, evl->n);
585
 
                evl= evl->next;
586
 
        }
587
 
}
588
 
 
589
 
static void flipvlak(EditVlak *evl)
590
 
{
591
 
        if(evl->v4) {
592
 
                SWAP(EditVert *, evl->v2, evl->v4);
593
 
                SWAP(EditEdge *, evl->e1, evl->e4);
594
 
                SWAP(EditEdge *, evl->e2, evl->e3);
595
 
                SWAP(unsigned int, evl->tf.col[1], evl->tf.col[3]);
596
 
                SWAP(float, evl->tf.uv[1][0], evl->tf.uv[3][0]);
597
 
                SWAP(float, evl->tf.uv[1][1], evl->tf.uv[3][1]);
 
373
                efa->tf.col[0]= efa->tf.col[1]= efa->tf.col[2]= efa->tf.col[3]= vpaint_get_current_col();
 
374
        }
 
375
 
 
376
        BLI_addtail(&em->faces, efa);
 
377
 
 
378
        if(efa->v4) {
 
379
                CalcNormFloat4(efa->v1->co, efa->v2->co, efa->v3->co, efa->v4->co, efa->n);
 
380
                CalcCent4f(efa->cent, efa->v1->co, efa->v2->co, efa->v3->co, efa->v4->co);
598
381
        }
599
382
        else {
600
 
                SWAP(EditVert *, evl->v2, evl->v3);
601
 
                SWAP(EditEdge *, evl->e1, evl->e3);
602
 
                SWAP(unsigned int, evl->tf.col[1], evl->tf.col[2]);
603
 
                evl->e2->dir= 1-evl->e2->dir;
604
 
                SWAP(float, evl->tf.uv[1][0], evl->tf.uv[2][0]);
605
 
                SWAP(float, evl->tf.uv[1][1], evl->tf.uv[2][1]);
606
 
        }
607
 
        if(evl->v4) CalcNormFloat4(evl->v1->co, evl->v2->co, evl->v3->co, evl->v4->co, evl->n);
608
 
        else CalcNormFloat(evl->v1->co, evl->v2->co, evl->v3->co, evl->n);
609
 
}
610
 
 
611
 
 
612
 
void flip_editnormals(void)
613
 
{
614
 
        EditMesh *em = G.editMesh;
615
 
        EditVlak *evl;
616
 
        
617
 
        evl= em->faces.first;
618
 
        while(evl) {
619
 
                if( vlakselectedAND(evl, 1) ) {
620
 
                        flipvlak(evl);
 
383
                CalcNormFloat(efa->v1->co, efa->v2->co, efa->v3->co, efa->n);
 
384
                CalcCent3f(efa->cent, efa->v1->co, efa->v2->co, efa->v3->co);
 
385
        }
 
386
 
 
387
        return efa;
 
388
}
 
389
 
 
390
/* ************************ end add/new/find ************  */
 
391
 
 
392
/* ************************ stuct EditMesh manipulation ***************************** */
 
393
 
 
394
/* fake callocs for fastmalloc below */
 
395
static void *calloc_fastvert(size_t size, size_t nr)
 
396
{
 
397
        EditVert *eve= G.editMesh->curvert++;
 
398
        eve->fast= 1;
 
399
        return eve;
 
400
}
 
401
static void *calloc_fastedge(size_t size, size_t nr)
 
402
{
 
403
        EditEdge *eed= G.editMesh->curedge++;
 
404
        eed->fast= 1;
 
405
        return eed;
 
406
}
 
407
static void *calloc_fastface(size_t size, size_t nr)
 
408
{
 
409
        EditFace *efa= G.editMesh->curface++;
 
410
        efa->fast= 1;
 
411
        return efa;
 
412
}
 
413
 
 
414
/* allocate 1 chunk for all vertices, edges, faces. These get tagged to
 
415
   prevent it from being freed
 
416
*/
 
417
static void init_editmesh_fastmalloc(EditMesh *em, int totvert, int totedge, int totface)
 
418
{
 
419
        
 
420
        if(totvert) em->allverts= MEM_callocN(totvert*sizeof(EditVert), "allverts");
 
421
        else em->allverts= NULL;
 
422
        em->curvert= em->allverts;
 
423
        
 
424
        if(totedge==0) totedge= 4*totface;      // max possible
 
425
 
 
426
        if(totedge) em->alledges= MEM_callocN(totedge*sizeof(EditEdge), "alledges");
 
427
        else em->alledges= NULL;
 
428
        em->curedge= em->alledges;
 
429
        
 
430
        if(totface) em->allfaces= MEM_callocN(totface*sizeof(EditFace), "allfaces");
 
431
        else em->allfaces= NULL;
 
432
        em->curface= em->allfaces;
 
433
 
 
434
        callocvert= calloc_fastvert;
 
435
        callocedge= calloc_fastedge;
 
436
        callocface= calloc_fastface;
 
437
}
 
438
 
 
439
static void end_editmesh_fastmalloc(void)
 
440
{
 
441
        callocvert= calloc;
 
442
        callocedge= calloc;
 
443
        callocface= calloc;
 
444
}
 
445
 
 
446
void free_editMesh(EditMesh *em)
 
447
{
 
448
        if(em==NULL) return;
 
449
        
 
450
        if(em->verts.first) free_vertlist(&em->verts);
 
451
        if(em->edges.first) free_edgelist(&em->edges);
 
452
        if(em->faces.first) free_facelist(&em->faces);
 
453
 
 
454
        if(em->derived) {
 
455
                em->derived->release(em->derived);
 
456
                em->derived= NULL;
 
457
        }
 
458
 
 
459
        /* DEBUG: hashtabs are slowest part of enter/exit editmode. here a testprint */
 
460
#if 0
 
461
        if(em->hashedgetab) {
 
462
                HashEdge *he, *hen;
 
463
                int a, used=0, max=0, nr;
 
464
                he= em->hashedgetab;
 
465
                for(a=0; a<EDHASHSIZE; a++, he++) {
 
466
                        if(he->eed) used++;
 
467
                        hen= he->next;
 
468
                        nr= 0;
 
469
                        while(hen) {
 
470
                                nr++;
 
471
                                hen= hen->next;
 
472
                        }
 
473
                        if(max<nr) max= nr;
621
474
                }
622
 
                evl= evl->next;
623
 
        }
624
 
}
625
 
 
626
 
/* ************************ IN & OUT ***************************** */
627
 
 
628
 
static void edge_normal_compare(EditEdge *eed, EditVlak *evl1)
629
 
{
630
 
        EditVlak *evl2;
 
475
                printf("hastab used %d max %d\n", used, max);
 
476
        }
 
477
#endif
 
478
        if(em->hashedgetab) MEM_freeN(em->hashedgetab);
 
479
        em->hashedgetab= NULL;
 
480
        
 
481
        if(em->allverts) MEM_freeN(em->allverts);
 
482
        if(em->alledges) MEM_freeN(em->alledges);
 
483
        if(em->allfaces) MEM_freeN(em->allfaces);
 
484
        
 
485
        em->allverts= em->curvert= NULL;
 
486
        em->alledges= em->curedge= NULL;
 
487
        em->allfaces= em->curface= NULL;
 
488
        
 
489
        G.totvert= G.totface= 0;
 
490
}
 
491
 
 
492
/* on G.editMesh */
 
493
static void editMesh_set_hash(void)
 
494
{
 
495
        EditEdge *eed;
 
496
 
 
497
        G.editMesh->hashedgetab= NULL;
 
498
        
 
499
        for(eed=G.editMesh->edges.first; eed; eed= eed->next)  {
 
500
                if( findedgelist(eed->v1, eed->v2)==NULL )
 
501
                        insert_hashedge(eed);
 
502
        }
 
503
 
 
504
}
 
505
 
 
506
 
 
507
/* ************************ IN & OUT EDITMODE ***************************** */
 
508
 
 
509
 
 
510
static void edge_normal_compare(EditEdge *eed, EditFace *efa1)
 
511
{
 
512
        EditFace *efa2;
631
513
        float cent1[3], cent2[3];
632
514
        float inp;
633
515
        
634
 
        evl2= (EditVlak *)eed->vn;
635
 
        if(evl1==evl2) return;
 
516
        efa2= (EditFace *)eed->vn;
 
517
        if(efa1==efa2) return;
636
518
        
637
 
        inp= evl1->n[0]*evl2->n[0] + evl1->n[1]*evl2->n[1] + evl1->n[2]*evl2->n[2];
638
 
        if(inp<0.999 && inp >-0.999) eed->f= 1;
 
519
        inp= efa1->n[0]*efa2->n[0] + efa1->n[1]*efa2->n[1] + efa1->n[2]*efa2->n[2];
 
520
        if(inp<0.999 && inp >-0.999) eed->f2= 1;
639
521
                
640
 
        if(evl1->v4) CalcCent4f(cent1, evl1->v1->co, evl1->v2->co, evl1->v3->co, evl1->v4->co);
641
 
        else CalcCent3f(cent1, evl1->v1->co, evl1->v2->co, evl1->v3->co);
642
 
        if(evl2->v4) CalcCent4f(cent2, evl2->v1->co, evl2->v2->co, evl2->v3->co, evl2->v4->co);
643
 
        else CalcCent3f(cent2, evl2->v1->co, evl2->v2->co, evl2->v3->co);
 
522
        if(efa1->v4) CalcCent4f(cent1, efa1->v1->co, efa1->v2->co, efa1->v3->co, efa1->v4->co);
 
523
        else CalcCent3f(cent1, efa1->v1->co, efa1->v2->co, efa1->v3->co);
 
524
        if(efa2->v4) CalcCent4f(cent2, efa2->v1->co, efa2->v2->co, efa2->v3->co, efa2->v4->co);
 
525
        else CalcCent3f(cent2, efa2->v1->co, efa2->v2->co, efa2->v3->co);
644
526
        
645
527
        VecSubf(cent1, cent2, cent1);
646
528
        Normalise(cent1);
647
 
        inp= cent1[0]*evl1->n[0] + cent1[1]*evl1->n[1] + cent1[2]*evl1->n[2]; 
 
529
        inp= cent1[0]*efa1->n[0] + cent1[1]*efa1->n[1] + cent1[2]*efa1->n[2]; 
648
530
 
649
531
        if(inp < -0.001 ) eed->f1= 1;
650
532
}
654
536
        EditMesh *em = G.editMesh;
655
537
        EditVert *eve;
656
538
        EditEdge *eed, *e1, *e2, *e3, *e4;
657
 
        EditVlak *evl;
 
539
        EditFace *efa;
658
540
        
659
541
        /* - count number of times edges are used in faces: 0 en 1 time means draw edge
660
542
         * - edges more than 1 time used: in *vn is pointer to first face
675
557
        }
676
558
        eed= em->edges.first;
677
559
        while(eed) {
678
 
                eed->f= eed->f1= 0;
 
560
                eed->f2= eed->f1= 0;
679
561
                eed->vn= 0;
680
562
                eed= eed->next;
681
563
        }
682
564
 
683
 
        evl= em->faces.first;
684
 
        while(evl) {
685
 
                e1= evl->e1;
686
 
                e2= evl->e2;
687
 
                e3= evl->e3;
688
 
                e4= evl->e4;
689
 
                if(e1->f<3) e1->f+= 1;
690
 
                if(e2->f<3) e2->f+= 1;
691
 
                if(e3->f<3) e3->f+= 1;
692
 
                if(e4 && e4->f<3) e4->f+= 1;
693
 
                
694
 
                if(e1->vn==0) e1->vn= (EditVert *)evl;
695
 
                if(e2->vn==0) e2->vn= (EditVert *)evl;
696
 
                if(e3->vn==0) e3->vn= (EditVert *)evl;
697
 
                if(e4 && e4->vn==0) e4->vn= (EditVert *)evl;
698
 
                
699
 
                evl= evl->next;
 
565
        efa= em->faces.first;
 
566
        while(efa) {
 
567
                e1= efa->e1;
 
568
                e2= efa->e2;
 
569
                e3= efa->e3;
 
570
                e4= efa->e4;
 
571
                if(e1->f2<4) e1->f2+= 1;
 
572
                if(e2->f2<4) e2->f2+= 1;
 
573
                if(e3->f2<4) e3->f2+= 1;
 
574
                if(e4 && e4->f2<4) e4->f2+= 1;
 
575
                
 
576
                if(e1->vn==0) e1->vn= (EditVert *)efa;
 
577
                if(e2->vn==0) e2->vn= (EditVert *)efa;
 
578
                if(e3->vn==0) e3->vn= (EditVert *)efa;
 
579
                if(e4 && e4->vn==0) e4->vn= (EditVert *)efa;
 
580
                
 
581
                efa= efa->next;
700
582
        }
701
583
 
702
584
        if(G.f & G_ALLEDGES) {
703
 
                evl= em->faces.first;
704
 
                while(evl) {
705
 
                        if(evl->e1->f>=2) evl->e1->f= 1;
706
 
                        if(evl->e2->f>=2) evl->e2->f= 1;
707
 
                        if(evl->e3->f>=2) evl->e3->f= 1;
708
 
                        if(evl->e4 && evl->e4->f>=2) evl->e4->f= 1;
 
585
                efa= em->faces.first;
 
586
                while(efa) {
 
587
                        if(efa->e1->f2>=2) efa->e1->f2= 1;
 
588
                        if(efa->e2->f2>=2) efa->e2->f2= 1;
 
589
                        if(efa->e3->f2>=2) efa->e3->f2= 1;
 
590
                        if(efa->e4 && efa->e4->f2>=2) efa->e4->f2= 1;
709
591
                        
710
 
                        evl= evl->next;
 
592
                        efa= efa->next;
711
593
                }               
712
594
        }       
713
595
        else {
716
598
                
717
599
                eed= em->edges.first;
718
600
                while(eed) {
719
 
                        if(eed->f==1) eed->f1= 1;
 
601
                        if(eed->f2==1) eed->f1= 1;
720
602
                        eed= eed->next;
721
603
                }
722
604
 
723
605
                /* all faces, all edges with flag==2: compare normal */
724
 
                evl= em->faces.first;
725
 
                while(evl) {
726
 
                        if(evl->e1->f==2) edge_normal_compare(evl->e1, evl);
727
 
                        if(evl->e2->f==2) edge_normal_compare(evl->e2, evl);
728
 
                        if(evl->e3->f==2) edge_normal_compare(evl->e3, evl);
729
 
                        if(evl->e4 && evl->e4->f==2) edge_normal_compare(evl->e4, evl);
730
 
                        
731
 
                        evl= evl->next;
 
606
                efa= em->faces.first;
 
607
                while(efa) {
 
608
                        if(efa->e1->f2==2) edge_normal_compare(efa->e1, efa);
 
609
                        else efa->e1->f2= 1;
 
610
                        if(efa->e2->f2==2) edge_normal_compare(efa->e2, efa);
 
611
                        else efa->e2->f2= 1;
 
612
                        if(efa->e3->f2==2) edge_normal_compare(efa->e3, efa);
 
613
                        else efa->e3->f2= 1;
 
614
                        if(efa->e4) {
 
615
                                if(efa->e4->f2==2) edge_normal_compare(efa->e4, efa);
 
616
                                else efa->e4->f2= 1;
 
617
                        }
 
618
                        efa= efa->next;
732
619
                }
733
620
                
734
621
                /* sphere collision flag */
744
631
        }
745
632
}
746
633
 
747
 
static int contrpuntnorm(float *n, float *puno)  /* dutch: check vertex normal */
748
 
{
749
 
        float inp;
750
 
 
751
 
        inp= n[0]*puno[0]+n[1]*puno[1]+n[2]*puno[2];
752
 
 
753
 
        /* angles 90 degrees: dont flip */
754
 
        if(inp> -0.000001) return 0;
755
 
 
756
 
        return 1;
757
 
}
758
 
 
759
 
void vertexnormals(int testflip)
760
 
{
761
 
        EditMesh *em = G.editMesh;
762
 
        Mesh *me;
763
 
        EditVert *eve;
764
 
        EditVlak *evl;  
765
 
        float n1[3], n2[3], n3[3], n4[3], co[4], fac1, fac2, fac3, fac4, *temp;
766
 
        float *f1, *f2, *f3, *f4, xn, yn, zn;
767
 
        float len;
768
 
        
769
 
        if(G.obedit && G.obedit->type==OB_MESH) {
770
 
                me= G.obedit->data;
771
 
                if((me->flag & ME_TWOSIDED)==0) testflip= 0;
772
 
        }
773
 
 
774
 
        if(G.totvert==0) return;
775
 
 
776
 
        if(G.totface==0) {
777
 
                /* fake vertex normals for 'halo puno'! */
778
 
                eve= em->verts.first;
779
 
                while(eve) {
780
 
                        VECCOPY(eve->no, eve->co);
781
 
                        Normalise( (float *)eve->no);
782
 
                        eve= eve->next;
783
 
                }
784
 
                return;
785
 
        }
786
 
 
787
 
        /* clear normals */     
788
 
        eve= em->verts.first;
789
 
        while(eve) {
790
 
                eve->no[0]= eve->no[1]= eve->no[2]= 0.0;
791
 
                eve= eve->next;
792
 
        }
793
 
        
794
 
        /* calculate cosine angles and add to vertex normal */
795
 
        evl= em->faces.first;
796
 
        while(evl) {
797
 
                VecSubf(n1, evl->v2->co, evl->v1->co);
798
 
                VecSubf(n2, evl->v3->co, evl->v2->co);
799
 
                Normalise(n1);
800
 
                Normalise(n2);
801
 
 
802
 
                if(evl->v4==0) {
803
 
                        VecSubf(n3, evl->v1->co, evl->v3->co);
804
 
                        Normalise(n3);
805
 
                        
806
 
                        co[0]= saacos(-n3[0]*n1[0]-n3[1]*n1[1]-n3[2]*n1[2]);
807
 
                        co[1]= saacos(-n1[0]*n2[0]-n1[1]*n2[1]-n1[2]*n2[2]);
808
 
                        co[2]= saacos(-n2[0]*n3[0]-n2[1]*n3[1]-n2[2]*n3[2]);
809
 
                        
810
 
                }
811
 
                else {
812
 
                        VecSubf(n3, evl->v4->co, evl->v3->co);
813
 
                        VecSubf(n4, evl->v1->co, evl->v4->co);
814
 
                        Normalise(n3);
815
 
                        Normalise(n4);
816
 
                        
817
 
                        co[0]= saacos(-n4[0]*n1[0]-n4[1]*n1[1]-n4[2]*n1[2]);
818
 
                        co[1]= saacos(-n1[0]*n2[0]-n1[1]*n2[1]-n1[2]*n2[2]);
819
 
                        co[2]= saacos(-n2[0]*n3[0]-n2[1]*n3[1]-n2[2]*n3[2]);
820
 
                        co[3]= saacos(-n3[0]*n4[0]-n3[1]*n4[1]-n3[2]*n4[2]);
821
 
                }
822
 
                
823
 
                temp= evl->v1->no;
824
 
                if(testflip && contrpuntnorm(evl->n, temp) ) co[0]= -co[0];
825
 
                temp[0]+= co[0]*evl->n[0];
826
 
                temp[1]+= co[0]*evl->n[1];
827
 
                temp[2]+= co[0]*evl->n[2];
828
 
                
829
 
                temp= evl->v2->no;
830
 
                if(testflip && contrpuntnorm(evl->n, temp) ) co[1]= -co[1];
831
 
                temp[0]+= co[1]*evl->n[0];
832
 
                temp[1]+= co[1]*evl->n[1];
833
 
                temp[2]+= co[1]*evl->n[2];
834
 
                
835
 
                temp= evl->v3->no;
836
 
                if(testflip && contrpuntnorm(evl->n, temp) ) co[2]= -co[2];
837
 
                temp[0]+= co[2]*evl->n[0];
838
 
                temp[1]+= co[2]*evl->n[1];
839
 
                temp[2]+= co[2]*evl->n[2];
840
 
                
841
 
                if(evl->v4) {
842
 
                        temp= evl->v4->no;
843
 
                        if(testflip && contrpuntnorm(evl->n, temp) ) co[3]= -co[3];
844
 
                        temp[0]+= co[3]*evl->n[0];
845
 
                        temp[1]+= co[3]*evl->n[1];
846
 
                        temp[2]+= co[3]*evl->n[2];
847
 
                }
848
 
                
849
 
                evl= evl->next;
850
 
        }
851
 
 
852
 
        /* normalise vertex normals */
853
 
        eve= em->verts.first;
854
 
        while(eve) {
855
 
                len= Normalise(eve->no);
856
 
                if(len==0.0) {
857
 
                        VECCOPY(eve->no, eve->co);
858
 
                        Normalise( eve->no);
859
 
                }
860
 
                eve= eve->next;
861
 
        }
862
 
        
863
 
        /* vertex normal flip-flags for shade (render) */
864
 
        evl= em->faces.first;
865
 
        while(evl) {
866
 
                evl->f=0;                       
867
 
 
868
 
                if(testflip) {
869
 
                        f1= evl->v1->no;
870
 
                        f2= evl->v2->no;
871
 
                        f3= evl->v3->no;
872
 
                        
873
 
                        fac1= evl->n[0]*f1[0] + evl->n[1]*f1[1] + evl->n[2]*f1[2];
874
 
                        if(fac1<0.0) {
875
 
                                evl->f = ME_FLIPV1;
876
 
                        }
877
 
                        fac2= evl->n[0]*f2[0] + evl->n[1]*f2[1] + evl->n[2]*f2[2];
878
 
                        if(fac2<0.0) {
879
 
                                evl->f += ME_FLIPV2;
880
 
                        }
881
 
                        fac3= evl->n[0]*f3[0] + evl->n[1]*f3[1] + evl->n[2]*f3[2];
882
 
                        if(fac3<0.0) {
883
 
                                evl->f += ME_FLIPV3;
884
 
                        }
885
 
                        if(evl->v4) {
886
 
                                f4= evl->v4->no;
887
 
                                fac4= evl->n[0]*f4[0] + evl->n[1]*f4[1] + evl->n[2]*f4[2];
888
 
                                if(fac4<0.0) {
889
 
                                        evl->f += ME_FLIPV4;
890
 
                                }
891
 
                        }
892
 
                }
893
 
                /* projection for cubemap! */
894
 
                xn= fabs(evl->n[0]);
895
 
                yn= fabs(evl->n[1]);
896
 
                zn= fabs(evl->n[2]);
897
 
                
898
 
                if(zn>xn && zn>yn) evl->f += ME_PROJXY;
899
 
                else if(yn>xn && yn>zn) evl->f += ME_PROJXZ;
900
 
                else evl->f += ME_PROJYZ;
901
 
                
902
 
                evl= evl->next;
903
 
        }
904
 
}
905
 
 
906
 
void free_editMesh(void)
907
 
{
908
 
        
909
 
        EditMesh *em = G.editMesh;
910
 
        if(em->verts.first) free_vertlist(&em->verts);
911
 
        if(em->edges.first) free_edgelist(&em->edges);
912
 
        if(em->faces.first) free_vlaklist(&em->faces);
913
 
        free_hashedgetab();
914
 
        G.totvert= G.totface= 0;
915
 
}
916
 
 
917
 
void make_editMesh(void)
918
 
{
919
 
        Mesh *me;       
920
 
 
921
 
        me= get_mesh(G.obedit);
922
 
        if (me != G.undo_last_data) {
923
 
                G.undo_edit_level= -1;
924
 
                G.undo_edit_highest= -1;
925
 
                if (G.undo_clear) G.undo_clear();
926
 
                G.undo_last_data= me;
927
 
                G.undo_clear= undo_clear_mesh;
928
 
        }
929
 
        make_editMesh_real(me);
930
 
}
931
 
 
932
 
void make_editMesh_real(Mesh *me)
933
 
{
934
 
        EditMesh *em = G.editMesh;
 
634
/* turns Mesh into editmesh */
 
635
void make_editMesh()
 
636
{
 
637
        EditMesh *em = G.editMesh;
 
638
        Mesh *me= G.obedit->data;
935
639
        MFace *mface;
936
640
        TFace *tface;
937
641
        MVert *mvert;
938
642
        KeyBlock *actkey=0;
939
643
        EditVert *eve, **evlist, *eve1, *eve2, *eve3, *eve4;
940
 
        EditVlak *evl;
 
644
        EditFace *efa;
941
645
        EditEdge *eed;
942
646
        int tot, a;
943
647
 
944
 
        if(G.obedit==0) return;
 
648
        if(G.obedit==NULL) return;
945
649
 
946
650
        /* because of reload */
947
 
        free_editMesh();
 
651
        free_editMesh(G.editMesh);
948
652
        
949
653
        G.totvert= tot= me->totvert;
950
654
 
955
659
        
956
660
        waitcursor(1);
957
661
 
 
662
        /* initialize fastmalloc for editmesh */
 
663
        init_editmesh_fastmalloc(G.editMesh, me->totvert, me->totedge, me->totface);
 
664
 
958
665
        /* keys? */
959
666
        if(me->key) {
960
667
                actkey= me->key->block.first;
992
699
                 */
993
700
                eve->keyindex = a;
994
701
 
995
 
#ifdef __NLA
996
 
 
997
 
                /* OLD VERSION */
998
 
                /*
999
 
                eve->totweight = mvert->totweight;
1000
 
                if (mvert->dw){
1001
 
                        eve->dw = BLI_callocN (sizeof(MDeformWeight) * mvert->totweight, "deformWeight");
1002
 
                        memcpy (eve->dw, mvert->dw, sizeof(MDeformWeight) * mvert->totweight);
1003
 
                }
1004
 
                */
1005
 
 
1006
 
                /* NEW VERSION */
1007
702
                if (me->dvert){
1008
703
                        eve->totweight = me->dvert[a].totweight;
1009
704
                        if (me->dvert[a].dw){
1012
707
                        }
1013
708
                }
1014
709
 
1015
 
#endif
1016
710
        }
1017
711
 
1018
712
        if(actkey && actkey->totelem!=me->totvert);
1019
713
        else {
1020
714
                unsigned int *mcol;
1021
715
                
1022
 
                /* make edges and faces */
 
716
                /* make edges */
 
717
                if(me->medge) {
 
718
                        MEdge *medge= me->medge;
 
719
                        
 
720
                        for(a=0; a<me->totedge; a++, medge++) {
 
721
                                eed= addedgelist(evlist[medge->v1], evlist[medge->v2], NULL);
 
722
                                eed->crease= ((float)medge->crease)/255.0;
 
723
                                
 
724
                                if(medge->flag & ME_SEAM) eed->seam= 1;
 
725
                                if(medge->flag & SELECT) eed->f |= SELECT;
 
726
                                if(medge->flag & ME_FGON) eed->h= EM_FGON;      // 2 different defines!
 
727
                                if(medge->flag & ME_HIDE) eed->h |= 1;
 
728
                                
 
729
                                EM_select_edge(eed, eed->f & SELECT);           // force edge selection to vertices, seems to be needed ...
 
730
                        }
 
731
 
 
732
                }
 
733
                
 
734
                /* make faces */
1023
735
                mface= me->mface;
1024
736
                tface= me->tface;
1025
737
                mcol= (unsigned int *)me->mcol;
1027
739
                for(a=0; a<me->totface; a++, mface++) {
1028
740
                        eve1= evlist[mface->v1];
1029
741
                        eve2= evlist[mface->v2];
1030
 
                        if(mface->v3) eve3= evlist[mface->v3]; else eve3= 0;
1031
 
                        if(mface->v4) eve4= evlist[mface->v4]; else eve4= 0;
1032
 
                        
1033
 
                        evl= addvlaklist(eve1, eve2, eve3, eve4, NULL);
1034
 
                        
1035
 
                        if(evl) {
1036
 
                                if(mcol) memcpy(evl->tf.col, mcol, 4*sizeof(int));
 
742
                        if(mface->v3) eve3= evlist[mface->v3]; else eve3= NULL;
 
743
                        if(mface->v4) eve4= evlist[mface->v4]; else eve4= NULL;
 
744
                        
 
745
                        efa= addfacelist(eve1, eve2, eve3, eve4, NULL, NULL);
 
746
 
 
747
                        if(efa) {
 
748
                        
 
749
                                if(mcol) memcpy(efa->tf.col, mcol, 4*sizeof(int));
1037
750
 
1038
751
                                if(me->tface) {
1039
 
                                        evl->tf= *tface;
 
752
                                        efa->tf= *tface;
1040
753
 
1041
754
                                        if( tface->flag & TF_SELECT) {
1042
755
                                                if(G.f & G_FACESELECT) {
1043
 
                                                        eve1->f |= 1;
1044
 
                                                        eve2->f |= 1;
1045
 
                                                        if(eve3) eve3->f |= 1;
1046
 
                                                        if(eve4) eve4->f |= 1;
 
756
                                                        EM_select_face(efa, 1);
1047
757
                                                }
1048
758
                                        }
1049
759
                                }
1050
760
                        
1051
 
                                evl->mat_nr= mface->mat_nr;
1052
 
                                evl->flag= mface->flag;
 
761
                                efa->mat_nr= mface->mat_nr;
 
762
                                efa->flag= mface->flag & ~ME_HIDE;
 
763
                                
 
764
                                if((G.f & G_FACESELECT)==0) {
 
765
                                        /* select face flag, if no edges we flush down */
 
766
                                        if(mface->flag & ME_FACE_SEL) {
 
767
                                                efa->f |= SELECT;
 
768
                                                if(me->medge==NULL) EM_select_face(efa, 1);
 
769
                                        }
 
770
                                }
 
771
                                if(mface->flag & ME_HIDE) efa->h= 1;
 
772
                                
1053
773
                        }
1054
774
 
1055
775
                        if(me->tface) tface++;
1057
777
                }
1058
778
        }
1059
779
        
1060
 
        /* intrr: needed because of hidden vertices imported from Mesh */
1061
 
        
1062
 
        eed= em->edges.first;
1063
 
        while(eed) {
1064
 
                if(eed->v1->h || eed->v2->h) eed->h= 1;
1065
 
                else eed->h= 0;
1066
 
                eed= eed->next;
1067
 
        }       
 
780
        /* flush hide flags when no medge */
 
781
        if(me->medge==NULL) {
 
782
                for(eed= em->edges.first; eed; eed= eed->next) {
 
783
                        if(eed->v1->h || eed->v2->h) eed->h |= 1;
 
784
                        else eed->h &= ~1;
 
785
                }       
 
786
        }
1068
787
        
1069
788
        MEM_freeN(evlist);
 
789
 
 
790
        end_editmesh_fastmalloc();      // resets global function pointers
 
791
 
 
792
        /* this creates coherent selections. also needed for older files */
 
793
        EM_selectmode_set();
 
794
        /* paranoia check to enforce hide rules */
 
795
        EM_hide_reset();
 
796
        /* sets helper flags which arent saved */
 
797
        EM_fgon_flags();
1070
798
        
1071
799
        countall();
1072
800
        
1073
 
        if (mesh_uses_displist(me))
1074
 
                makeDispList(G.obedit);
 
801
        if (mesh_uses_displist(me)) makeDispList(G.obedit);
1075
802
        
1076
803
        waitcursor(0);
1077
804
}
1086
813
  * calls/structures, this function resides here.
1087
814
  */
1088
815
 
1089
 
 
1090
 
static void fix_faceindices(MFace *mface, EditVlak *evl, int nr)
 
816
static void fix_faceindices(MFace *mface, EditFace *efa, int nr)
1091
817
{
1092
818
        int a;
1093
819
        float tmpuv[2];
1120
846
                        SWAP(int, mface->v1, mface->v2);
1121
847
                        SWAP(int, mface->v2, mface->v3);
1122
848
                        /* rotate face UV coordinates, too */
1123
 
                        UVCOPY(tmpuv, evl->tf.uv[0]);
1124
 
                        UVCOPY(evl->tf.uv[0], evl->tf.uv[1]);
1125
 
                        UVCOPY(evl->tf.uv[1], evl->tf.uv[2]);
1126
 
                        UVCOPY(evl->tf.uv[2], tmpuv);
 
849
                        UVCOPY(tmpuv, efa->tf.uv[0]);
 
850
                        UVCOPY(efa->tf.uv[0], efa->tf.uv[1]);
 
851
                        UVCOPY(efa->tf.uv[1], efa->tf.uv[2]);
 
852
                        UVCOPY(efa->tf.uv[2], tmpuv);
1127
853
                        /* same with vertex colours */
1128
 
                        tmpcol = evl->tf.col[0];
1129
 
                        evl->tf.col[0] = evl->tf.col[1];
1130
 
                        evl->tf.col[1] = evl->tf.col[2];
1131
 
                        evl->tf.col[2] = tmpcol;
 
854
                        tmpcol = efa->tf.col[0];
 
855
                        efa->tf.col[0] = efa->tf.col[1];
 
856
                        efa->tf.col[1] = efa->tf.col[2];
 
857
                        efa->tf.col[2] = tmpcol;
1132
858
 
1133
859
                        
1134
860
                        a= mface->edcode;
1142
868
                        if(a & ME_FLIPV1) mface->puno |= ME_FLIPV2;
1143
869
                        if(a & ME_FLIPV2) mface->puno |= ME_FLIPV3;
1144
870
                        if(a & ME_FLIPV3) mface->puno |= ME_FLIPV1;
 
871
 
1145
872
                }
1146
873
        }
1147
874
        else if(nr==4) {
1149
876
                        SWAP(int, mface->v1, mface->v3);
1150
877
                        SWAP(int, mface->v2, mface->v4);
1151
878
                        /* swap UV coordinates */
1152
 
                        UVCOPY(tmpuv, evl->tf.uv[0]);
1153
 
                        UVCOPY(evl->tf.uv[0], evl->tf.uv[2]);
1154
 
                        UVCOPY(evl->tf.uv[2], tmpuv);
1155
 
                        UVCOPY(tmpuv, evl->tf.uv[1]);
1156
 
                        UVCOPY(evl->tf.uv[1], evl->tf.uv[3]);
1157
 
                        UVCOPY(evl->tf.uv[3], tmpuv);
 
879
                        UVCOPY(tmpuv, efa->tf.uv[0]);
 
880
                        UVCOPY(efa->tf.uv[0], efa->tf.uv[2]);
 
881
                        UVCOPY(efa->tf.uv[2], tmpuv);
 
882
                        UVCOPY(tmpuv, efa->tf.uv[1]);
 
883
                        UVCOPY(efa->tf.uv[1], efa->tf.uv[3]);
 
884
                        UVCOPY(efa->tf.uv[3], tmpuv);
1158
885
                        /* swap vertex colours */
1159
 
                        tmpcol = evl->tf.col[0];
1160
 
                        evl->tf.col[0] = evl->tf.col[2];
1161
 
                        evl->tf.col[2] = tmpcol;
1162
 
                        tmpcol = evl->tf.col[1];
1163
 
                        evl->tf.col[1] = evl->tf.col[3];
1164
 
                        evl->tf.col[3] = tmpcol;
 
886
                        tmpcol = efa->tf.col[0];
 
887
                        efa->tf.col[0] = efa->tf.col[2];
 
888
                        efa->tf.col[2] = tmpcol;
 
889
                        tmpcol = efa->tf.col[1];
 
890
                        efa->tf.col[1] = efa->tf.col[3];
 
891
                        efa->tf.col[3] = tmpcol;
1165
892
 
1166
893
                        a= mface->edcode;
1167
894
                        mface->edcode= 0;
1176
903
                        if(a & ME_FLIPV2) mface->puno |= ME_FLIPV4;
1177
904
                        if(a & ME_FLIPV3) mface->puno |= ME_FLIPV1;
1178
905
                        if(a & ME_FLIPV4) mface->puno |= ME_FLIPV2;
 
906
 
1179
907
                }
1180
908
        }
1181
 
 
1182
 
}
1183
 
 
1184
 
 
1185
 
 
1186
 
/* load from EditMode to Mesh */
1187
 
 
1188
 
void load_editMesh()
1189
 
{
1190
 
        Mesh *me;
1191
 
 
1192
 
        waitcursor(1);
1193
 
        countall();
1194
 
        me= get_mesh(G.obedit);
1195
 
       
1196
 
        load_editMesh_real(me, 0);
1197
 
}
1198
 
 
1199
 
 
1200
 
void load_editMesh_real(Mesh *me, int undo)
 
909
}
 
910
 
 
911
/* makes Mesh out of editmesh */
 
912
void load_editMesh(void)
1201
913
{
1202
914
        EditMesh *em = G.editMesh;
1203
 
        MFace *mface;
 
915
        Mesh *me= G.obedit->data;
1204
916
        MVert *mvert, *oldverts;
 
917
        MEdge *medge=NULL;
 
918
        MFace *mface;
1205
919
        MSticky *ms;
1206
 
        KeyBlock *actkey=0, *currkey;
 
920
        KeyBlock *actkey=NULL, *currkey;
1207
921
        EditVert *eve;
1208
 
        EditVlak *evl;
 
922
        EditFace *efa;
1209
923
        EditEdge *eed;
1210
924
        float *fp, *newkey, *oldkey, nor[3];
1211
 
        int i, a, ototvert;
1212
 
#ifdef __NLA
 
925
        int i, a, ototvert, totedge=0;
1213
926
        MDeformVert *dvert;
1214
927
        int     usedDvert = 0;
1215
 
#endif
1216
 
 
1217
 
        ototvert= me->totvert;
1218
 
 
1219
 
        /* lets save the old verts just in case we are actually working on
1220
 
         * a key ... we now do processing of the keys at the end*/
1221
 
        oldverts = me->mvert;
 
928
 
 
929
        waitcursor(1);
 
930
        countall();
1222
931
 
1223
932
        /* this one also tests of edges are not in faces: */
1224
 
        /* eed->f==0: not in face, f==1: draw it */
 
933
        /* eed->f2==0: not in face, f2==1: draw it */
1225
934
        /* eed->f1 : flag for dynaface (cylindertest, old engine) */
1226
935
        /* eve->f1 : flag for dynaface (sphere test, old engine) */
 
936
        /* eve->f2 : being used in vertexnormals */
1227
937
        edge_drawflags();
1228
938
        
1229
 
        /* WATCH IT: in evl->f is punoflag (for vertex normal) */
 
939
        /* this sets efa->puno, punoflag (for vertex normal & projection) */
1230
940
        vertexnormals( (me->flag & ME_NOPUNOFLIP)==0 );
1231
 
        
 
941
                
1232
942
        eed= em->edges.first;
1233
943
        while(eed) {
1234
 
                if(eed->f==0) G.totface++;
 
944
                totedge++;
 
945
                if(me->medge==NULL && (eed->f2==0)) G.totface++;
1235
946
                eed= eed->next;
1236
947
        }
1237
948
        
 
949
        /* new Vertex block */
 
950
        if(G.totvert==0) mvert= NULL;
 
951
        else mvert= MEM_callocN(G.totvert*sizeof(MVert), "loadeditMesh vert");
 
952
 
 
953
        /* new Edge block */
 
954
        if(totedge) {
 
955
                if(me->medge==NULL) totedge= 0; // if edges get added is defined by orig mesh
 
956
                else medge= MEM_callocN(totedge*sizeof(MEdge), "loadeditMesh edge");
 
957
        }
 
958
        
1238
959
        /* new Face block */
1239
 
        if(G.totface==0) mface= 0;
1240
 
        else mface= MEM_callocN(G.totface*sizeof(MFace), "loadeditMesh1");
1241
 
        /* nieuw Vertex block */
1242
 
        if(G.totvert==0) mvert= 0;
1243
 
        else mvert= MEM_callocN(G.totvert*sizeof(MVert), "loadeditMesh2");
 
960
        if(G.totface==0) mface= NULL;
 
961
        else mface= MEM_callocN(G.totface*sizeof(MFace), "loadeditMesh face");
 
962
        
1244
963
 
1245
 
#ifdef __NLA
1246
 
        if (G.totvert==0) dvert=0;
 
964
        if (G.totvert==0) dvert= NULL;
1247
965
        else dvert = MEM_callocN(G.totvert*sizeof(MDeformVert), "loadeditMesh3");
1248
966
 
1249
967
        if (me->dvert) free_dverts(me->dvert, me->totvert);
1250
968
        me->dvert=dvert;
1251
 
#endif          
1252
 
 
 
969
 
 
970
        /* lets save the old verts just in case we are actually working on
 
971
         * a key ... we now do processing of the keys at the end */
 
972
        oldverts = me->mvert;
 
973
        ototvert= me->totvert;
 
974
 
 
975
        /* put new data in Mesh */
1253
976
        me->mvert= mvert;
 
977
        me->totvert= G.totvert;
1254
978
 
 
979
        if(me->medge) MEM_freeN(me->medge);
 
980
        me->medge= medge;
 
981
        if(medge) me->totedge= totedge; else me->totedge= 0;
 
982
        
1255
983
        if(me->mface) MEM_freeN(me->mface);
1256
984
        me->mface= mface;
1257
 
        me->totvert= G.totvert;
1258
985
        me->totface= G.totface;
1259
986
                
1260
987
        /* the vertices, abuse ->vn as counter */
1261
988
        eve= em->verts.first;
1262
 
        a=0;
 
989
        a= 0;
1263
990
 
1264
991
        while(eve) {
1265
992
                VECCOPY(mvert->co, eve->co);
1269
996
                VECCOPY(nor, eve->no);
1270
997
                VecMulf(nor, 32767.0);
1271
998
                VECCOPY(mvert->no, nor);
1272
 
#ifdef __NLA
 
999
 
1273
1000
                /* NEW VERSION */
1274
1001
                if (dvert){
1275
1002
                        dvert->totweight=eve->totweight;
1281
1008
                                usedDvert++;
1282
1009
                        }
1283
1010
                }
1284
 
#endif
1285
1011
 
1286
1012
                eve->vn= (EditVert *)(long)(a++);  /* counter */
1287
1013
                        
1288
1014
                mvert->flag= 0;
1289
 
                        
1290
 
                mvert->flag= 0;
1291
1015
                if(eve->f1==1) mvert->flag |= ME_SPHERETEST;
1292
 
                mvert->flag |= (eve->f & 1);
 
1016
                mvert->flag |= (eve->f & SELECT);
1293
1017
                if (eve->h) mvert->flag |= ME_HIDE;                     
1294
1018
                        
1295
1019
                eve= eve->next;
1296
1020
                mvert++;
1297
 
#ifdef __NLA
1298
1021
                dvert++;
1299
 
#endif
1300
1022
        }
1301
1023
        
1302
 
#ifdef __NLA
1303
1024
        /* If we didn't actually need the dverts, get rid of them */
1304
1025
        if (!usedDvert){
1305
1026
                free_dverts(me->dvert, G.totvert);
1306
1027
                me->dvert=NULL;
1307
1028
        }
1308
 
#endif
 
1029
 
 
1030
        /* the edges */
 
1031
        if(medge) {
 
1032
                eed= em->edges.first;
 
1033
                while(eed) {
 
1034
                        medge->v1= (unsigned int) eed->v1->vn;
 
1035
                        medge->v2= (unsigned int) eed->v2->vn;
 
1036
                        
 
1037
                        medge->flag= eed->f & SELECT;
 
1038
                        if(eed->f2<2) medge->flag |= ME_EDGEDRAW;
 
1039
                        if(eed->seam) medge->flag |= ME_SEAM;
 
1040
                        if(eed->h & EM_FGON) medge->flag |= ME_FGON;    // different defines yes
 
1041
                        if(eed->h & 1) medge->flag |= ME_HIDE;
 
1042
                        
 
1043
                        medge->crease= (char)(255.0*eed->crease);
 
1044
 
 
1045
                        medge++;
 
1046
                        eed= eed->next;
 
1047
                }
 
1048
        }
1309
1049
 
1310
1050
        /* the faces */
1311
 
        evl= em->faces.first;
 
1051
        efa= em->faces.first;
1312
1052
        i = 0;
1313
 
        while(evl) {
 
1053
        while(efa) {
1314
1054
                mface= &((MFace *) me->mface)[i];
1315
 
                        
1316
 
                mface->v1= (unsigned int) evl->v1->vn;
1317
 
                mface->v2= (unsigned int) evl->v2->vn;
1318
 
                mface->v3= (unsigned int) evl->v3->vn;
1319
 
                if(evl->v4) mface->v4= (unsigned int) evl->v4->vn;
1320
 
                        
1321
 
                mface->mat_nr= evl->mat_nr;
1322
 
                mface->puno= evl->f;
1323
 
                mface->flag= evl->flag;
1324
 
                        
 
1055
                
 
1056
                mface->v1= (unsigned int) efa->v1->vn;
 
1057
                mface->v2= (unsigned int) efa->v2->vn;
 
1058
                mface->v3= (unsigned int) efa->v3->vn;
 
1059
                if(efa->v4) mface->v4= (unsigned int) efa->v4->vn;
 
1060
                        
 
1061
                mface->mat_nr= efa->mat_nr;
 
1062
                mface->puno= efa->puno;
 
1063
                
 
1064
                mface->flag= efa->flag;
 
1065
                /* bit 0 of flag is already taken for smooth... */
 
1066
                if(efa->f & 1) mface->flag |= ME_FACE_SEL;
 
1067
                else mface->flag &= ~ME_FACE_SEL;
 
1068
                if(efa->h) mface->flag |= ME_HIDE;
 
1069
                
1325
1070
                /* mat_nr in vertex */
1326
1071
                if(me->totcol>1) {
1327
1072
                        mvert= me->mvert+mface->v1;
1336
1081
                        }
1337
1082
                }
1338
1083
                        
1339
 
                /* watch: evl->e1->f==0 means loose edge */ 
 
1084
                /* watch: efa->e1->f2==0 means loose edge */ 
1340
1085
                        
1341
 
                if(evl->e1->f==1) {
 
1086
                if(efa->e1->f2==1) {
1342
1087
                        mface->edcode |= ME_V1V2; 
1343
 
                        evl->e1->f= 2;
 
1088
                        efa->e1->f2= 2;
1344
1089
                }                       
1345
 
                if(evl->e2->f==1) {
 
1090
                if(efa->e2->f2==1) {
1346
1091
                        mface->edcode |= ME_V2V3; 
1347
 
                        evl->e2->f= 2;
 
1092
                        efa->e2->f2= 2;
1348
1093
                }
1349
 
                if(evl->e3->f==1) {
1350
 
                        if(evl->v4) {
 
1094
                if(efa->e3->f2==1) {
 
1095
                        if(efa->v4) {
1351
1096
                                mface->edcode |= ME_V3V4;
1352
1097
                        }
1353
1098
                        else {
1354
1099
                                mface->edcode |= ME_V3V1;
1355
1100
                        }
1356
 
                        evl->e3->f= 2;
 
1101
                        efa->e3->f2= 2;
1357
1102
                }
1358
 
                if(evl->e4 && evl->e4->f==1) {
 
1103
                if(efa->e4 && efa->e4->f2==1) {
1359
1104
                        mface->edcode |= ME_V4V1; 
1360
 
                        evl->e4->f= 2;
 
1105
                        efa->e4->f2= 2;
1361
1106
                }
1362
 
                        
 
1107
 
 
1108
 
1363
1109
                /* no index '0' at location 3 or 4 */
1364
 
                if(evl->v4) fix_faceindices(mface, evl, 4);
1365
 
                else fix_faceindices(mface, evl, 3);
 
1110
                if(efa->v4) fix_faceindices(mface, efa, 4);
 
1111
                else fix_faceindices(mface, efa, 3);
1366
1112
                        
1367
1113
                i++;
1368
 
                evl= evl->next;
 
1114
                efa= efa->next;
1369
1115
        }
1370
1116
                
1371
1117
        /* add loose edges as a face */
1372
 
        eed= em->edges.first;
1373
 
        while(eed) {
1374
 
                if( eed->f==0 ) {
1375
 
                        mface= &((MFace *) me->mface)[i];
1376
 
                        mface->v1= (unsigned int) eed->v1->vn;
1377
 
                        mface->v2= (unsigned int) eed->v2->vn;
1378
 
                        test_index_mface(mface, 2);
1379
 
                        mface->edcode= ME_V1V2;
1380
 
                        i++;
 
1118
        if(medge==NULL) {
 
1119
                eed= em->edges.first;
 
1120
                while(eed) {
 
1121
                        if( eed->f2==0 ) {
 
1122
                                mface= &((MFace *) me->mface)[i];
 
1123
                                mface->v1= (unsigned int) eed->v1->vn;
 
1124
                                mface->v2= (unsigned int) eed->v2->vn;
 
1125
                                test_index_mface(mface, 2);
 
1126
                                mface->edcode= ME_V1V2;
 
1127
                                i++;
 
1128
                        }
 
1129
                        eed= eed->next;
1381
1130
                }
1382
 
                eed= eed->next;
1383
1131
        }
1384
 
                
 
1132
        
1385
1133
        tex_space_mesh(me);
1386
1134
 
1387
 
        /* tface block, always when undo even when it wasnt used, 
1388
 
           this because of empty me pointer */
1389
 
        if( (me->tface || undo) && me->totface ) {
 
1135
        /* tface block */
 
1136
        if( me->tface && me->totface ) {
1390
1137
                TFace *tfn, *tf;
1391
1138
                        
1392
1139
                tf=tfn= MEM_callocN(sizeof(TFace)*me->totface, "tface");
1393
 
                evl= em->faces.first;
1394
 
                while(evl) {
 
1140
                efa= em->faces.first;
 
1141
                while(efa) {
1395
1142
                                
1396
 
                        *tf= evl->tf;
 
1143
                        *tf= efa->tf;
1397
1144
                                
1398
1145
                        if(G.f & G_FACESELECT) {
1399
 
                                if( vlakselectedAND(evl, 1) ) tf->flag |= TF_SELECT;
 
1146
                                if( efa->f & SELECT)  tf->flag |= TF_SELECT;
1400
1147
                                else tf->flag &= ~TF_SELECT;
1401
1148
                        }
1402
1149
                                
1403
1150
                        tf++;
1404
 
                        evl= evl->next;
 
1151
                        efa= efa->next;
1405
1152
                }
1406
 
                /* if undo, me was empty */
 
1153
 
1407
1154
                if(me->tface) MEM_freeN(me->tface);
1408
1155
                me->tface= tfn;
1409
1156
        }
1413
1160
        }
1414
1161
                
1415
1162
        /* mcol: same as tface... */
1416
 
        if( (me->mcol || undo) && me->totface) {
 
1163
        if(me->mcol && me->totface) {
1417
1164
                unsigned int *mcn, *mc;
1418
1165
 
1419
1166
                mc=mcn= MEM_mallocN(4*sizeof(int)*me->totface, "mcol");
1420
 
                evl= em->faces.first;
1421
 
                while(evl) {
1422
 
                        memcpy(mc, evl->tf.col, 4*sizeof(int));
 
1167
                efa= em->faces.first;
 
1168
                while(efa) {
 
1169
                        memcpy(mc, efa->tf.col, 4*sizeof(int));
1423
1170
                                
1424
1171
                        mc+=4;
1425
 
                        evl= evl->next;
 
1172
                        efa= efa->next;
1426
1173
                }
1427
1174
                if(me->mcol) MEM_freeN(me->mcol);
1428
1175
                        me->mcol= (MCol *)mcn;
1447
1194
                 * with the way things were before editmode */
1448
1195
                currkey = me->key->block.first;
1449
1196
                while(currkey) {
1450
 
                        if(currkey->data) {
1451
 
                                fp=newkey= MEM_callocN(me->key->elemsize*G.totvert, 
1452
 
                                                                           "currkey->data");
1453
 
                                oldkey = currkey->data;
1454
 
 
1455
 
                                eve= em->verts.first;
1456
 
 
1457
 
                                i = 0;
1458
 
                                mvert = me->mvert;
1459
 
                                while(eve) {
1460
 
                                        if (eve->keyindex >= 0) {
1461
 
                                                if(currkey == actkey) {
1462
 
                                                        if (actkey == me->key->refkey) {
1463
 
                                                                VECCOPY(fp, mvert->co);
1464
 
                                                        }
1465
 
                                                        else {
1466
 
                                                                VECCOPY(fp, mvert->co);
 
1197
                        
 
1198
                        fp= newkey= MEM_callocN(me->key->elemsize*G.totvert,  "currkey->data");
 
1199
                        oldkey = currkey->data;
 
1200
 
 
1201
                        eve= em->verts.first;
 
1202
 
 
1203
                        i = 0;
 
1204
                        mvert = me->mvert;
 
1205
                        while(eve) {
 
1206
                                if (eve->keyindex >= 0 && eve->keyindex < currkey->totelem) { // valid old vertex
 
1207
                                        if(currkey == actkey) {
 
1208
                                                if (actkey == me->key->refkey) {
 
1209
                                                        VECCOPY(fp, mvert->co);
 
1210
                                                }
 
1211
                                                else {
 
1212
                                                        VECCOPY(fp, mvert->co);
 
1213
                                                        if(oldverts) {
1467
1214
                                                                VECCOPY(mvert->co, oldverts[eve->keyindex].co);
1468
1215
                                                        }
1469
1216
                                                }
1470
 
                                                else {
 
1217
                                        }
 
1218
                                        else {
 
1219
                                                if(oldkey) {
1471
1220
                                                        VECCOPY(fp, oldkey + 3 * eve->keyindex);
1472
1221
                                                }
1473
1222
                                        }
1474
 
                                        else {
1475
 
                                                VECCOPY(fp, mvert->co);
1476
 
                                        }
1477
 
                                        fp+= 3;
1478
 
                                        ++i;
1479
 
                                        ++mvert;
1480
 
                                        eve= eve->next;
1481
 
                                }
1482
 
                                currkey->totelem= G.totvert;
1483
 
                                MEM_freeN(currkey->data);
1484
 
                                currkey->data = newkey;
 
1223
                                }
 
1224
                                else {
 
1225
                                        VECCOPY(fp, mvert->co);
 
1226
                                }
 
1227
                                fp+= 3;
 
1228
                                ++i;
 
1229
                                ++mvert;
 
1230
                                eve= eve->next;
1485
1231
                        }
 
1232
                        currkey->totelem= G.totvert;
 
1233
                        if(currkey->data) MEM_freeN(currkey->data);
 
1234
                        currkey->data = newkey;
 
1235
                        
1486
1236
                        currkey= currkey->next;
1487
1237
                }
1488
1238
 
1492
1242
 
1493
1243
        if(actkey) do_spec_key(me->key);
1494
1244
        
1495
 
        /* te be sure: clear ->vn pointers */
 
1245
        /* to be sure: clear ->vn pointers */
1496
1246
        eve= em->verts.first;
1497
1247
        while(eve) {
1498
1248
                eve->vn= 0;
1499
1249
                eve= eve->next;
1500
1250
        }
1501
 
 
1502
 
        /* displists of all users, including this one */
1503
 
        freedisplist(&me->disp);
1504
 
        freedisplist(&G.obedit->disp);
 
1251
        
 
1252
        /* remake softbody, clear deform or shade displists of all users */
 
1253
        if(me->id.us>1) {
 
1254
                Base *base;
 
1255
                for(base= G.scene->base.first; base; base= base->next) {
 
1256
                        if(base->object->data==me) {
 
1257
                                base->object->softflag |= OB_SB_REDO;
 
1258
                                freedisplist(&base->object->disp);
 
1259
                        }
 
1260
                }
 
1261
        }
 
1262
        /* we do make displist here for dependencies (like particles) */
 
1263
        if (mesh_uses_displist(me)) makeDispList(G.obedit);
1505
1264
        
1506
1265
        /* sticky */
1507
1266
        if(me->msticky) {
1518
1277
 
1519
1278
void remake_editMesh(void)
1520
1279
{
1521
 
        undo_push_mesh("Undo all changes");
1522
1280
        make_editMesh();
1523
1281
        allqueue(REDRAWVIEW3D, 0);
1524
1282
        makeDispList(G.obedit);
1525
 
}
1526
 
 
1527
 
/* *********************  TOOLS  ********************* */
1528
 
 
1529
 
 
1530
 
 
1531
 
void make_sticky(void)
1532
 
{
1533
 
        Object *ob;
1534
 
        Base *base;
1535
 
        MVert *mvert;
1536
 
        Mesh *me;
1537
 
        MSticky *ms;
1538
 
        float ho[4], mat[4][4];
1539
 
        int a;
1540
 
        
1541
 
        if(G.scene->camera==0) return;
1542
 
        
1543
 
        if(G.obedit) {
1544
 
                error("Unable to perform function in EditMode");
1545
 
                return;
1546
 
        }
1547
 
        base= FIRSTBASE;
1548
 
        while(base) {
1549
 
                if TESTBASELIB(base) {
1550
 
                        if(base->object->type==OB_MESH) {
1551
 
                                ob= base->object;
1552
 
                                
1553
 
                                me= ob->data;
1554
 
                                mvert= me->mvert;
1555
 
                                if(me->msticky) MEM_freeN(me->msticky);
1556
 
                                me->msticky= MEM_mallocN(me->totvert*sizeof(MSticky), "sticky");
1557
 
                                
1558
 
                                /* like convert to render data */               
1559
 
                                R.r= G.scene->r;
1560
 
                                R.r.xsch= (R.r.size*R.r.xsch)/100;
1561
 
                                R.r.ysch= (R.r.size*R.r.ysch)/100;
1562
 
                                
1563
 
                                R.afmx= R.r.xsch/2;
1564
 
                                R.afmy= R.r.ysch/2;
1565
 
                                
1566
 
                                R.ycor= ( (float)R.r.yasp)/( (float)R.r.xasp);
1567
 
                
1568
 
                                R.rectx= R.r.xsch; 
1569
 
                                R.recty= R.r.ysch;
1570
 
                                R.xstart= -R.afmx; 
1571
 
                                R.ystart= -R.afmy;
1572
 
                                R.xend= R.xstart+R.rectx-1;
1573
 
                                R.yend= R.ystart+R.recty-1;
1574
 
                
1575
 
                                where_is_object(G.scene->camera);
1576
 
                                Mat4CpyMat4(R.viewinv, G.scene->camera->obmat);
1577
 
                                Mat4Ortho(R.viewinv);
1578
 
                                Mat4Invert(R.viewmat, R.viewinv);
1579
 
                                
1580
 
                                RE_setwindowclip(1, -1);
1581
 
                
1582
 
                                where_is_object(ob);
1583
 
                                Mat4MulMat4(mat, ob->obmat, R.viewmat);
1584
 
                
1585
 
                                ms= me->msticky;
1586
 
                                for(a=0; a<me->totvert; a++, ms++, mvert++) {
1587
 
                                        VECCOPY(ho, mvert->co);
1588
 
                                        Mat4MulVecfl(mat, ho);
1589
 
                                        RE_projectverto(ho, ho);
1590
 
                                        ms->co[0]= ho[0]/ho[3];
1591
 
                                        ms->co[1]= ho[1]/ho[3];
1592
 
                                }
1593
 
                        }
1594
 
                }
1595
 
                base= base->next;
1596
 
        }
1597
 
        allqueue(REDRAWBUTSEDIT, 0);
1598
 
}
1599
 
 
1600
 
void fasterdraw(void)
1601
 
{
1602
 
        Base *base;
1603
 
        Mesh *me;
1604
 
        MFace *mface;
1605
 
        int toggle, a;
1606
 
 
1607
 
        if(G.obedit) return;
1608
 
 
1609
 
        /* reset flags */
1610
 
        me= G.main->mesh.first;
1611
 
        while(me) {
1612
 
                me->flag &= ~ME_ISDONE;
1613
 
                me= me->id.next;
1614
 
        }
1615
 
 
1616
 
        base= FIRSTBASE;
1617
 
        while(base) {
1618
 
                if( TESTBASELIB(base) && (base->object->type==OB_MESH)) {
1619
 
                        me= base->object->data;
1620
 
                        if(me->id.lib==0 && (me->flag & ME_ISDONE)==0) {
1621
 
                                me->flag |= ME_ISDONE;
1622
 
                                mface= me->mface;
1623
 
                                toggle= 0;
1624
 
                                for(a=0; a<me->totface; a++) {
1625
 
                                        if( (mface->edcode & ME_V1V2) && ( (toggle++) & 1) ) {
1626
 
                                                mface->edcode-= ME_V1V2;
1627
 
                                        }
1628
 
                                        if( (mface->edcode & ME_V2V3) && ( (toggle++) & 1)) {
1629
 
                                                mface->edcode-= ME_V2V3;
1630
 
                                        }
1631
 
                                        if( (mface->edcode & ME_V3V1) && ( (toggle++) & 1)) {
1632
 
                                                mface->edcode-= ME_V3V1;
1633
 
                                        }
1634
 
                                        if( (mface->edcode & ME_V4V1) && ( (toggle++) & 1)) {
1635
 
                                                mface->edcode-= ME_V4V1;
1636
 
                                        }
1637
 
                                        if( (mface->edcode & ME_V3V4) && ( (toggle++) & 1)) {
1638
 
                                                mface->edcode-= ME_V3V4;
1639
 
                                        }
1640
 
                                        mface++;
1641
 
                                }
1642
 
                        }
1643
 
                }
1644
 
                base= base->next;
1645
 
        }
1646
 
 
1647
 
        /* important?: reset flags again */
1648
 
        me= G.main->mesh.first;
1649
 
        while(me) {
1650
 
                me->flag &= ~ME_ISDONE;
1651
 
                me= me->id.next;
1652
 
        }
1653
 
 
1654
 
        allqueue(REDRAWVIEW3D, 0);
1655
 
}
1656
 
 
1657
 
void slowerdraw(void)           /* reset fasterdraw */
1658
 
{
1659
 
        Base *base;
1660
 
        Mesh *me;
1661
 
        MFace *mface;
1662
 
        int a;
1663
 
 
1664
 
        if(G.obedit) return;
1665
 
 
1666
 
        base= FIRSTBASE;
1667
 
        while(base) {
1668
 
                if( TESTBASELIB(base) && (base->object->type==OB_MESH)) {
1669
 
                        me= base->object->data;
1670
 
                        if(me->id.lib==0) {
1671
 
                                
1672
 
                                mface= me->mface;
1673
 
                                
1674
 
                                for(a=0; a<me->totface; a++) {
1675
 
                                
1676
 
                                        mface->edcode |= ME_V1V2|ME_V2V3;
1677
 
                                        mface++;
1678
 
                                }
1679
 
                        }
1680
 
                }
1681
 
                base= base->next;
1682
 
        }
1683
 
 
1684
 
        allqueue(REDRAWVIEW3D, 0);
1685
 
}
1686
 
 
1687
 
 
1688
 
void convert_to_triface(int all)
1689
 
{
1690
 
        EditMesh *em = G.editMesh;
1691
 
        EditVlak *evl, *evln, *next;
1692
 
        
1693
 
        undo_push_mesh("Convert to triangles");
1694
 
        
1695
 
        evl= em->faces.first;
1696
 
        while(evl) {
1697
 
                next= evl->next;
1698
 
                if(evl->v4) {
1699
 
                        if(all || vlakselectedAND(evl, 1) ) {
1700
 
                                
1701
 
                                evln= addvlaklist(evl->v1, evl->v2, evl->v3, 0, evl);
1702
 
                                evln= addvlaklist(evl->v1, evl->v3, evl->v4, 0, evl);
1703
 
 
1704
 
                                evln->tf.uv[1][0]= evln->tf.uv[2][0];
1705
 
                                evln->tf.uv[1][1]= evln->tf.uv[2][1];
1706
 
                                evln->tf.uv[2][0]= evln->tf.uv[3][0];
1707
 
                                evln->tf.uv[2][1]= evln->tf.uv[3][1];
1708
 
                                
1709
 
                                evln->tf.col[1]= evln->tf.col[2];
1710
 
                                evln->tf.col[2]= evln->tf.col[3];
1711
 
                                
1712
 
                                BLI_remlink(&em->faces, evl);
1713
 
                                free_editvlak(evl);
1714
 
                        }
1715
 
                }
1716
 
                evl= next;
1717
 
        }
1718
 
        
1719
 
}
1720
 
 
1721
 
 
1722
 
void deselectall_mesh(void)     /* toggle */
1723
 
{
1724
 
        EditMesh *em = G.editMesh;
1725
 
        EditVert *eve;
1726
 
        int a;
1727
 
        
1728
 
        if(G.obedit->lay & G.vd->lay) {
1729
 
                a= 0;
1730
 
                eve= em->verts.first;
1731
 
                while(eve) {
1732
 
                        if(eve->f & 1) {
1733
 
                                a= 1;
1734
 
                                break;
1735
 
                        }
1736
 
                        eve= eve->next;
1737
 
                }
1738
 
                
1739
 
                if (a) undo_push_mesh("Deselect all");
1740
 
                else undo_push_mesh("Select all");
1741
 
                
1742
 
                eve= em->verts.first;
1743
 
                while(eve) {
1744
 
                        if(eve->h==0) {
1745
 
                                if(a) eve->f&= -2;
1746
 
                                else eve->f|= 1;
1747
 
                        }
1748
 
                        eve= eve->next;
1749
 
                }
1750
 
        }
1751
 
        countall();
1752
 
        allqueue(REDRAWVIEW3D, 0);
1753
 
}
1754
 
 
1755
 
 
1756
 
void righthandfaces(int select) /* makes faces righthand turning */
1757
 
{
1758
 
        EditMesh *em = G.editMesh;
1759
 
        EditEdge *eed, *ed1, *ed2, *ed3, *ed4;
1760
 
        EditVlak *evl, *startvl;
1761
 
        float maxx, nor[3], cent[3];
1762
 
        int totsel, found, foundone, direct, turn;
1763
 
 
1764
 
   /* based at a select-connected to witness loose objects */
1765
 
 
1766
 
        /* count per edge the amount of faces */
1767
 
 
1768
 
        /* find the ultimate left, front, upper face */
1769
 
 
1770
 
        /* put normal to the outside, and set the first direction flags in edges */
1771
 
 
1772
 
        /* then check the object, and set directions / direction-flags: but only for edges with 1 or 2 faces */
1773
 
        /* this is in fact the 'select connected' */
1774
 
        
1775
 
        /* in case (selected) faces were not done: start over with 'find the ultimate ...' */
1776
 
 
1777
 
        waitcursor(1);
1778
 
        
1779
 
        eed= em->edges.first;
1780
 
        while(eed) {
1781
 
                eed->f= 0;
1782
 
                eed->f1= 0;
1783
 
                eed= eed->next;
1784
 
        }
1785
 
 
1786
 
        /* count faces and edges */
1787
 
        totsel= 0;
1788
 
        evl= em->faces.first;
1789
 
        while(evl) {
1790
 
                if(select==0 || vlakselectedAND(evl, 1) ) {
1791
 
                        evl->f= 1;
1792
 
                        totsel++;
1793
 
                        evl->e1->f1++;
1794
 
                        evl->e2->f1++;
1795
 
                        evl->e3->f1++;
1796
 
                        if(evl->v4) evl->e4->f1++;
1797
 
                }
1798
 
                else evl->f= 0;
1799
 
 
1800
 
                evl= evl->next;
1801
 
        }
1802
 
 
1803
 
        while(totsel>0) {
1804
 
                /* from the outside to the inside */
1805
 
 
1806
 
                evl= em->faces.first;
1807
 
                startvl= 0;
1808
 
                maxx= -1.0e10;
1809
 
 
1810
 
                while(evl) {
1811
 
                        if(evl->f) {
1812
 
                                CalcCent3f(cent, evl->v1->co, evl->v2->co, evl->v3->co);
1813
 
                                cent[0]= fabs(cent[0])+fabs(cent[1])+fabs(cent[2]);
1814
 
                                
1815
 
                                if(cent[0]>maxx) {
1816
 
                                        maxx= cent[0];
1817
 
                                        startvl= evl;
1818
 
                                }
1819
 
                        }
1820
 
                        evl= evl->next;
1821
 
                }
1822
 
                
1823
 
                /* set first face correct: calc normal */
1824
 
                CalcNormFloat(startvl->v1->co, startvl->v2->co, startvl->v3->co, nor);
1825
 
                CalcCent3f(cent, startvl->v1->co, startvl->v2->co, startvl->v3->co);
1826
 
                
1827
 
                /* first normal is oriented this way or the other */
1828
 
                if(select) {
1829
 
                        if(select==2) {
1830
 
                                if(cent[0]*nor[0]+cent[1]*nor[1]+cent[2]*nor[2] > 0.0) flipvlak(startvl);
1831
 
                        }
1832
 
                        else {
1833
 
                                if(cent[0]*nor[0]+cent[1]*nor[1]+cent[2]*nor[2] < 0.0) flipvlak(startvl);
1834
 
                        }
1835
 
                }
1836
 
                else if(cent[0]*nor[0]+cent[1]*nor[1]+cent[2]*nor[2] < 0.0) flipvlak(startvl);
1837
 
 
1838
 
 
1839
 
                eed= startvl->e1;
1840
 
                if(eed->v1==startvl->v1) eed->f= 1; 
1841
 
                else eed->f= 2;
1842
 
                
1843
 
                eed= startvl->e2;
1844
 
                if(eed->v1==startvl->v2) eed->f= 1; 
1845
 
                else eed->f= 2;
1846
 
                
1847
 
                eed= startvl->e3;
1848
 
                if(eed->v1==startvl->v3) eed->f= 1; 
1849
 
                else eed->f= 2;
1850
 
                
1851
 
                eed= startvl->e4;
1852
 
                if(eed) {
1853
 
                        if(eed->v1==startvl->v4) eed->f= 1; 
1854
 
                        else eed->f= 2;
1855
 
                }
1856
 
                
1857
 
                startvl->f= 0;
1858
 
                totsel--;
1859
 
 
1860
 
                /* test normals */
1861
 
                found= 1;
1862
 
                direct= 1;
1863
 
                while(found) {
1864
 
                        found= 0;
1865
 
                        if(direct) evl= em->faces.first;
1866
 
                        else evl= em->faces.last;
1867
 
                        while(evl) {
1868
 
                                if(evl->f) {
1869
 
                                        turn= 0;
1870
 
                                        foundone= 0;
1871
 
 
1872
 
                                        ed1= evl->e1;
1873
 
                                        ed2= evl->e2;
1874
 
                                        ed3= evl->e3;
1875
 
                                        ed4= evl->e4;
1876
 
 
1877
 
                                        if(ed1->f) {
1878
 
                                                if(ed1->v1==evl->v1 && ed1->f==1) turn= 1;
1879
 
                                                if(ed1->v2==evl->v1 && ed1->f==2) turn= 1;
1880
 
                                                foundone= 1;
1881
 
                                        }
1882
 
                                        else if(ed2->f) {
1883
 
                                                if(ed2->v1==evl->v2 && ed2->f==1) turn= 1;
1884
 
                                                if(ed2->v2==evl->v2 && ed2->f==2) turn= 1;
1885
 
                                                foundone= 1;
1886
 
                                        }
1887
 
                                        else if(ed3->f) {
1888
 
                                                if(ed3->v1==evl->v3 && ed3->f==1) turn= 1;
1889
 
                                                if(ed3->v2==evl->v3 && ed3->f==2) turn= 1;
1890
 
                                                foundone= 1;
1891
 
                                        }
1892
 
                                        else if(ed4 && ed4->f) {
1893
 
                                                if(ed4->v1==evl->v4 && ed4->f==1) turn= 1;
1894
 
                                                if(ed4->v2==evl->v4 && ed4->f==2) turn= 1;
1895
 
                                                foundone= 1;
1896
 
                                        }
1897
 
 
1898
 
                                        if(foundone) {
1899
 
                                                found= 1;
1900
 
                                                totsel--;
1901
 
                                                evl->f= 0;
1902
 
 
1903
 
                                                if(turn) {
1904
 
                                                        if(ed1->v1==evl->v1) ed1->f= 2; 
1905
 
                                                        else ed1->f= 1;
1906
 
                                                        if(ed2->v1==evl->v2) ed2->f= 2; 
1907
 
                                                        else ed2->f= 1;
1908
 
                                                        if(ed3->v1==evl->v3) ed3->f= 2; 
1909
 
                                                        else ed3->f= 1;
1910
 
                                                        if(ed4) {
1911
 
                                                                if(ed4->v1==evl->v4) ed4->f= 2; 
1912
 
                                                                else ed4->f= 1;
1913
 
                                                        }
1914
 
 
1915
 
                                                        flipvlak(evl);
1916
 
 
1917
 
                                                }
1918
 
                                                else {
1919
 
                                                        if(ed1->v1== evl->v1) ed1->f= 1; 
1920
 
                                                        else ed1->f= 2;
1921
 
                                                        if(ed2->v1==evl->v2) ed2->f= 1; 
1922
 
                                                        else ed2->f= 2;
1923
 
                                                        if(ed3->v1==evl->v3) ed3->f= 1; 
1924
 
                                                        else ed3->f= 2;
1925
 
                                                        if(ed4) {
1926
 
                                                                if(ed4->v1==evl->v4) ed4->f= 1; 
1927
 
                                                                else ed4->f= 2;
1928
 
                                                        }
1929
 
                                                }
1930
 
                                        }
1931
 
                                }
1932
 
                                if(direct) evl= evl->next;
1933
 
                                else evl= evl->prev;
1934
 
                        }
1935
 
                        direct= 1-direct;
1936
 
                }
1937
 
        }
1938
 
 
1939
 
        recalc_editnormals();
1940
 
        
1941
 
        makeDispList(G.obedit);
1942
 
        
1943
 
        waitcursor(0);
1944
 
}
1945
 
 
1946
 
static EditVert *findnearestvert(short sel)
1947
 
{
1948
 
        EditMesh *em = G.editMesh;
1949
 
        /* if sel==1 the vertices with flag==1 get a disadvantage */
1950
 
        EditVert *eve,*act=0;
1951
 
        static EditVert *acto=0;
1952
 
        short dist=100,temp,mval[2];
1953
 
 
1954
 
        if(em->verts.first==0) return 0;
1955
 
 
1956
 
        /* do projection */
1957
 
        calc_meshverts_ext();   /* drawobject.c */
1958
 
        
1959
 
        /* we count from acto->next to last, and from first to acto */
1960
 
        /* does acto exist? */
1961
 
        eve= em->verts.first;
1962
 
        while(eve) {
1963
 
                if(eve==acto) break;
1964
 
                eve= eve->next;
1965
 
        }
1966
 
        if(eve==0) acto= em->verts.first;
1967
 
 
1968
 
        if(acto==0) return 0;
1969
 
 
1970
 
        /* is there an indicated vertex? part 1 */
1971
 
        getmouseco_areawin(mval);
1972
 
        eve= acto->next;
1973
 
        while(eve) {
1974
 
                if(eve->h==0) {
1975
 
                        temp= abs(mval[0]- eve->xs)+ abs(mval[1]- eve->ys);
1976
 
                        if( (eve->f & 1)==sel ) temp+=5;
1977
 
                        if(temp<dist) {
1978
 
                                act= eve;
1979
 
                                dist= temp;
1980
 
                                if(dist<4) break;
1981
 
                        }
1982
 
                }
1983
 
                eve= eve->next;
1984
 
        }
1985
 
        /* is there an indicated vertex? part 2 */
1986
 
        if(dist>3) {
1987
 
                eve= em->verts.first;
1988
 
                while(eve) {
1989
 
                        if(eve->h==0) {
1990
 
                                temp= abs(mval[0]- eve->xs)+ abs(mval[1]- eve->ys);
1991
 
                                if( (eve->f & 1)==sel ) temp+=5;
1992
 
                                if(temp<dist) {
1993
 
                                        act= eve;
1994
 
                                        if(temp<4) break;
1995
 
                                        dist= temp;
1996
 
                                }
1997
 
                                if(eve== acto) break;
1998
 
                        }
1999
 
                        eve= eve->next;
2000
 
                }
2001
 
        }
2002
 
 
2003
 
        acto= act;
2004
 
        return act;
2005
 
}
2006
 
 
2007
 
 
2008
 
static EditEdge *findnearestedge()
2009
 
{
2010
 
        EditMesh *em = G.editMesh;
2011
 
        EditEdge *closest, *eed;
2012
 
        EditVert *eve;
2013
 
        short found=0, mval[2];
2014
 
        float distance[2], v1[2], v2[2], mval2[2];
2015
 
        
2016
 
        if(em->edges.first==0) return NULL;
2017
 
        else eed=em->edges.first;       
2018
 
        
2019
 
        /* reset flags */       
2020
 
        for(eve=em->verts.first; eve; eve=eve->next){
2021
 
                eve->f &= ~2;
2022
 
        }       
2023
 
                
2024
 
        calc_meshverts_ext_f2();        /*sets (eve->f & 2) for vertices that aren't visible*/
2025
 
        getmouseco_areawin(mval);
2026
 
        closest=NULL;
2027
 
        
2028
 
        mval2[0] = (float)mval[0];
2029
 
        mval2[1] = (float)mval[1];
2030
 
        
2031
 
        eed=em->edges.first;
2032
 
        /*compare the distance to the rest of the edges and find the closest one*/
2033
 
        while(eed) {
2034
 
                /* Are both vertices of the edge ofscreen or either of them hidden? then don't select the edge*/
2035
 
                if( !((eed->v1->f & 2) && (eed->v2->f & 2)) && (eed->v1->h==0 && eed->v2->h==0)){
2036
 
                        v1[0] = eed->v1->xs;
2037
 
                        v1[1] = eed->v1->ys;
2038
 
                        v2[0] = eed->v2->xs;
2039
 
                        v2[1] = eed->v2->ys;
2040
 
                        
2041
 
                        distance[1] = PdistVL2Dfl(mval2, v1, v2);
2042
 
                        
2043
 
                        if(distance[1]<50){
2044
 
                                /*do we have to compare it to other distances? */                       
2045
 
                                if(found) {
2046
 
                                        if (distance[1]<distance[0]){
2047
 
                                                distance[0]=distance[1];
2048
 
                                                /*save the current closest edge*/
2049
 
                                                closest=eed;    
2050
 
                                        }
2051
 
                                } else {
2052
 
                                        distance[0]=distance[1];
2053
 
                                        closest=eed;
2054
 
                                        found=1;
2055
 
                                }
2056
 
                        }
2057
 
                }
2058
 
                eed= eed->next;
2059
 
        }
2060
 
        
2061
 
        /* reset flags */       
2062
 
        for(eve=em->verts.first; eve; eve=eve->next){
2063
 
                eve->f &= ~2;
2064
 
        }
2065
 
        
2066
 
        if(found) return closest;
2067
 
        else return 0;
2068
 
}
2069
 
 
2070
 
/* does the same as findnearestedge but both vertices of the edge should be on screen*/
2071
 
static EditEdge *findnearestvisibleedge()
2072
 
{
2073
 
        EditMesh *em = G.editMesh;
2074
 
        EditEdge *closest, *eed;
2075
 
        EditVert *eve;
2076
 
        short found=0, mval[2];
2077
 
        float distance[2], v1[2], v2[2], mval2[2];
2078
 
                
2079
 
        if(em->edges.first==0) return NULL;
2080
 
        else eed=em->edges.first;       
2081
 
        
2082
 
        /* reset flags */       
2083
 
        for(eve=em->verts.first; eve; eve=eve->next){
2084
 
                eve->f &= ~2;
2085
 
        }       
2086
 
        calc_meshverts_ext_f2();        /*sets (eve->f & 2) for vertices that aren't visible*/
2087
 
        
2088
 
        closest=NULL;
2089
 
        getmouseco_areawin(mval);
2090
 
        
2091
 
        mval2[0] = (float)mval[0];      /* cast to float because of the pdist function only taking floats...*/
2092
 
        mval2[1] = (float)mval[1];
2093
 
        
2094
 
        eed=em->edges.first;
2095
 
        while(eed) {                                            /* compare the distance to the rest of the edges and find the closest one*/
2096
 
                if( !((eed->v1->f | eed->v2->f) & 2) && (eed->v1->h==0 && eed->v2->h==0) ){     /* only return edges with both vertices on screen */
2097
 
                        v1[0] = eed->v1->xs;                    
2098
 
                        v1[1] = eed->v1->ys;
2099
 
                        v2[0] = eed->v2->xs;
2100
 
                        v2[1] = eed->v2->ys;
2101
 
                        
2102
 
                        distance[1] = PdistVL2Dfl(mval2, v1, v2);
2103
 
                        
2104
 
                        if(distance[1]<50){                     /* TODO: make this maximum selecting distance selectable (the same with vertice select?) */
2105
 
                                if(found) {                     /*do we have to compare it to other distances? */
2106
 
                                        if (distance[1]<distance[0]){
2107
 
                                                distance[0]=distance[1];
2108
 
                                                closest=eed;    /*save the current closest edge*/
2109
 
                                        }
2110
 
                                } else {
2111
 
                                        distance[0]=distance[1];
2112
 
                                        closest=eed;
2113
 
                                        found=1;
2114
 
                                }
2115
 
                        }
2116
 
                }
2117
 
                eed= eed->next;
2118
 
        }
2119
 
        
2120
 
        /* reset flags */       
2121
 
        for(eve=em->verts.first; eve; eve=eve->next){
2122
 
                eve->f &= ~2;
2123
 
        }
2124
 
        
2125
 
        if(found) return closest;
2126
 
        else return 0;
2127
 
}
2128
 
 
2129
 
#if 0
2130
 
/* this is a template function to demonstrate a loop with drawing...
2131
 
   it is a temporal mode, so use with wisdom! if you can avoid, always better. (ton)
2132
 
*/
2133
 
void loop(int mode)
2134
 
{
2135
 
        EditEdge *eed;
2136
 
        int mousemove= 1;
2137
 
 
2138
 
        while(mousemove) {
2139
 
                /* uses callback mechanism to draw it all in current area */
2140
 
                scrarea_do_windraw(curarea); 
2141
 
                
2142
 
                /* do your stuff */
2143
 
                eed= findnearestedge();
2144
 
                
2145
 
                /* set window matrix to perspective, default an area returns with buttons transform */
2146
 
                persp(PERSP_VIEW);
2147
 
                /* make a copy, for safety */
2148
 
                glPushMatrix();
2149
 
                /* multiply with the object transformation */
2150
 
                mymultmatrix(G.obedit->obmat);
2151
 
                
2152
 
                /* draw */
2153
 
                if(eed) {
2154
 
                        glColor3ub(255, 255, 0);
2155
 
                        glBegin(GL_LINES);
2156
 
                        glVertex3fv(eed->v1->co);
2157
 
                        glVertex3fv(eed->v2->co);
2158
 
                        glEnd();
2159
 
                }
2160
 
                
2161
 
                /* restore matrix transform */
2162
 
                glPopMatrix();
2163
 
                
2164
 
                headerprint("We are now in evil edge select mode. Press any key to exit");
2165
 
                
2166
 
                /* this also verifies other area/windows for clean swap */
2167
 
                screen_swapbuffers();
2168
 
                
2169
 
                /* testing for user input... */
2170
 
                while(qtest()) {
2171
 
                        unsigned short val;
2172
 
                        short event= extern_qread(&val);        // extern_qread stores important events for the mainloop to handle 
2173
 
 
2174
 
                        /* val==0 on key-release event */
2175
 
                        if(val && event!=MOUSEY && event!=MOUSEX) {
2176
 
                                mousemove= 0;
2177
 
                        }
2178
 
                }
2179
 
                /* sleep 0.01 second to prevent overload in this poor loop */
2180
 
                PIL_sleep_ms(10);       
2181
 
                
2182
 
        }
2183
 
        
2184
 
        /* send event to redraw this window, does header too */
2185
 
        addqueue(curarea->win, REDRAW, 1); 
2186
 
}
2187
 
#endif
2188
 
 
2189
 
/* 
2190
 
functionality: various loop functions
2191
 
parameters: mode tells the function what it should do with the loop:
2192
 
                LOOP_SELECT = select
2193
 
                LOOP_CUT = cut in half
2194
 
*/      
2195
 
 
2196
 
void loopoperations(char mode)
2197
 
{
2198
 
        EditMesh *em = G.editMesh;
2199
 
        EditVert* look = NULL;
2200
 
 
2201
 
        EditEdge *start, *eed, *opposite,*currente, *oldstart;
2202
 
        EditEdge **tagged = NULL,**taggedsrch = NULL,*close;
2203
 
 
2204
 
        EditVlak *evl,**percentfacesloop = NULL, *currentvl,  *formervl;        
2205
 
 
2206
 
        short lastface=0, foundedge=0, c=0, tri=0, side=1, totface=0, searching=1, event=0, noface=1;
2207
 
        short skip,nextpos,percentfaces;
2208
 
 
2209
 
        int i=0,ect=0,j=0,k=0,cut,smooth,timesthrough=0,inset = 0;
2210
 
 
2211
 
        float percentcut, outcut;
2212
 
 
2213
 
        char mesg[100];
2214
 
 
2215
 
        if ((G.obedit==0) || (em->faces.first==0)) return;
2216
 
        
2217
 
        if(mode==LOOP_CUT)undo_push_mesh("Faceloop Subdivide");
2218
 
        else if(mode==LOOP_SELECT)undo_push_mesh("Faceloop Select");    
2219
 
 
2220
 
        SetBlenderCursor(BC_VLOOPCURSOR);
2221
 
 
2222
 
        start=NULL;
2223
 
        oldstart=NULL;
2224
 
 
2225
 
        while(searching){
2226
 
                
2227
 
                /* reset variables */
2228
 
                start=eed=opposite=currente=0;
2229
 
                evl=currentvl=formervl=0;
2230
 
                side=noface=1;
2231
 
                lastface=foundedge=c=tri=totface=0;             
2232
 
                                
2233
 
                start=findnearestvisibleedge();
2234
 
                                
2235
 
                /* If the edge doesn't belong to a face, it's not a valid starting edge */
2236
 
                if(start){
2237
 
                        start->f |= 16;
2238
 
                        evl=em->faces.first;
2239
 
                        while(evl){
2240
 
                                if(evl->e1->f & 16){                                    
2241
 
                                        noface=0;
2242
 
                                        evl->e1->f &= ~16;
2243
 
                                }
2244
 
                                else if(evl->e2->f & 16){                                       
2245
 
                                        noface=0;
2246
 
                                        evl->e2->f &= ~16;
2247
 
                                }
2248
 
                                else if(evl->e3->f & 16){                                       
2249
 
                                        noface=0;
2250
 
                                        evl->e3->f &= ~16;
2251
 
                                }
2252
 
                                else if(evl->e4 && (evl->e4->f & 16)){                                  
2253
 
                                        noface=0;
2254
 
                                        evl->e4->f &= ~16;
2255
 
                                }
2256
 
                                
2257
 
                                evl=evl->next;
2258
 
                        }                       
2259
 
                }                               
2260
 
                                
2261
 
                /* Did we find anything that is selectable? */
2262
 
                if(start && !noface && (oldstart==NULL || start!=oldstart)){
2263
 
                                        
2264
 
                        /* If we stay in the neighbourhood of this edge, we don't have to recalculate the loop everytime*/
2265
 
                        oldstart=start; 
2266
 
                        
2267
 
                        /* Clear flags */
2268
 
                        for(eed=em->edges.first; eed; eed=eed->next){                   
2269
 
                                eed->f &= ~(2|4|8|32|64);
2270
 
                                eed->v1->f &= ~(2|8|16);
2271
 
                                eed->v2->f &= ~(2|8|16);                                
2272
 
                        }
2273
 
                        
2274
 
                        for(evl= em->faces.first; evl; evl=evl->next){                  
2275
 
                                evl->f &= ~(4|8);
2276
 
                                totface++;                              
2277
 
                        }
2278
 
                                        
2279
 
                        /* Tag the starting edge */
2280
 
                        start->f |= (2|4|8|64);                         
2281
 
                        start->v1->f |= 2;
2282
 
                        start->v2->f |= 2;              
2283
 
                        
2284
 
                        currente=start;                                         
2285
 
                        
2286
 
                        /*-----Limit the Search----- */
2287
 
                        while(!lastface && c<totface+1){
2288
 
                                
2289
 
                                /*----------Get Loop------------------------*/
2290
 
                                tri=foundedge=lastface=0;                                                                                                       
2291
 
                                evl= em->faces.first;           
2292
 
                                while(evl && !foundedge && !tri){
2293
 
                                                                        
2294
 
                                        if(!(evl->v4)){ /* Exception for triangular faces */
2295
 
                                                
2296
 
                                                if((evl->e1->f | evl->e2->f | evl->e3->f) & 2){
2297
 
                                                        if(!(evl->f & 4)){                                                              
2298
 
                                                                tri=1;
2299
 
                                                                currentvl=evl;
2300
 
                                                                if(side==1) evl->f |= 4;
2301
 
                                                        }
2302
 
                                                }                                               
2303
 
                                        }
2304
 
                                        else{
2305
 
                                                
2306
 
                                                if((evl->e1->f | evl->e2->f | evl->e3->f | evl->e4->f) & 2){
2307
 
                                                        
2308
 
                                                        if(c==0){       /* just pick a face, doesn't matter wich side of the edge we go to */
2309
 
                                                                if(!(evl->f & 4)){
2310
 
                                                                        
2311
 
                                                                        if(!(evl->e1->v1->f & 2) && !(evl->e1->v2->f & 2)){
2312
 
                                                                                if(evl->e1->v1->h==0 && evl->e1->v2->h==0){
2313
 
                                                                                        opposite=evl->e1;                                                                                                               
2314
 
                                                                                        foundedge=1;
2315
 
                                                                                }
2316
 
                                                                        }
2317
 
                                                                        else if(!(evl->e2->v1->f & 2) && !(evl->e2->v2->f & 2)){
2318
 
                                                                                if(evl->e2->v1->h==0 && evl->e2->v2->h==0){
2319
 
                                                                                        opposite=evl->e2;
2320
 
                                                                                        foundedge=1;
2321
 
                                                                                }
2322
 
                                                                        }
2323
 
                                                                        else if(!(evl->e3->v1->f & 2) && !(evl->e3->v2->f & 2)){
2324
 
                                                                                if(evl->e3->v1->h==0 && evl->e3->v2->h==0){
2325
 
                                                                                        opposite=evl->e3;
2326
 
                                                                                        foundedge=1;
2327
 
                                                                                }
2328
 
                                                                        }
2329
 
                                                                        else if(!(evl->e4->v1->f & 2) && !(evl->e4->v2->f & 2)){
2330
 
                                                                                if(evl->e4->v1->h==0 && evl->e4->v2->h==0){
2331
 
                                                                                        opposite=evl->e4;
2332
 
                                                                                        foundedge=1;
2333
 
                                                                                }
2334
 
                                                                        }
2335
 
                                                                        
2336
 
                                                                        if(foundedge){
2337
 
                                                                                currentvl=evl;
2338
 
                                                                                formervl=evl;
2339
 
                                                                        
2340
 
                                                                                /* mark this side of the edge so we know in which direction we went */
2341
 
                                                                                if(side==1) evl->f |= 4;
2342
 
                                                                        }
2343
 
                                                                }
2344
 
                                                        }
2345
 
                                                        else {  
2346
 
                                                                if(evl!=formervl){      /* prevent going backwards in the loop */
2347
 
                                                                
2348
 
                                                                        if(!(evl->e1->v1->f & 2) && !(evl->e1->v2->f & 2)){
2349
 
                                                                                if(evl->e1->v1->h==0 && evl->e1->v2->h==0){
2350
 
                                                                                        opposite=evl->e1;                                                                                                               
2351
 
                                                                                        foundedge=1;
2352
 
                                                                                }
2353
 
                                                                        }
2354
 
                                                                        else if(!(evl->e2->v1->f & 2) && !(evl->e2->v2->f & 2)){
2355
 
                                                                                if(evl->e2->v1->h==0 && evl->e2->v2->h==0){
2356
 
                                                                                        opposite=evl->e2;
2357
 
                                                                                        foundedge=1;
2358
 
                                                                                }
2359
 
                                                                        }
2360
 
                                                                        else if(!(evl->e3->v1->f & 2) && !(evl->e3->v2->f & 2)){
2361
 
                                                                                if(evl->e3->v1->h==0 && evl->e3->v2->h==0){
2362
 
                                                                                        opposite=evl->e3;
2363
 
                                                                                        foundedge=1;
2364
 
                                                                                }
2365
 
                                                                        }
2366
 
                                                                        else if(!(evl->e4->v1->f & 2) && !(evl->e4->v2->f & 2)){
2367
 
                                                                                if(evl->e4->v1->h==0 && evl->e4->v2->h==0){
2368
 
                                                                                        opposite=evl->e4;
2369
 
                                                                                        foundedge=1;
2370
 
                                                                                }
2371
 
                                                                        }
2372
 
                                                                        
2373
 
                                                                        currentvl=evl;
2374
 
                                                                }
2375
 
                                                        }
2376
 
                                                }
2377
 
                                        }
2378
 
                                evl=evl->next;
2379
 
                                }
2380
 
                                /*----------END Get Loop------------------------*/
2381
 
                                
2382
 
                        
2383
 
                                /*----------Decisions-----------------------------*/
2384
 
                                if(foundedge){
2385
 
                                        /* mark the edge and face as done */                                    
2386
 
                                        currente->f |= 8;
2387
 
                                        currentvl->f |= 8;
2388
 
 
2389
 
                                        if(opposite->f & 4) lastface=1; /* found the starting edge! close loop */                                                               
2390
 
                                        else{
2391
 
                                                /* un-set the testflags */
2392
 
                                                currente->f &= ~2;
2393
 
                                                currente->v1->f &= ~2;
2394
 
                                                currente->v2->f &= ~2;                                                  
2395
 
                                                
2396
 
                                                /* set the opposite edge to be the current edge */                              
2397
 
                                                currente=opposite;                                                      
2398
 
                                                
2399
 
                                                /* set the current face to be the FORMER face (to prevent going backwards in the loop) */
2400
 
                                                formervl=currentvl;
2401
 
                                                
2402
 
                                                /* set the testflags */
2403
 
                                                currente->f |= 2;
2404
 
                                                currente->v1->f |= 2;
2405
 
                                                currente->v2->f |= 2;                   
2406
 
                                        }
2407
 
                                        c++;
2408
 
                                }
2409
 
                                else{   
2410
 
                                        /* un-set the testflags */
2411
 
                                        currente->f &= ~2;
2412
 
                                        currente->v1->f &= ~2;
2413
 
                                        currente->v2->f &= ~2;
2414
 
                                        
2415
 
                                        /* mark the edge and face as done */
2416
 
                                        currente->f |= 8;
2417
 
                                        currentvl->f |= 8;
2418
 
                                        
2419
 
                                        
2420
 
                                                                                                
2421
 
                                        /* is the the first time we've ran out of possible faces?
2422
 
                                        *  try to start from the beginning but in the opposite direction go as far as possible
2423
 
                                        */                              
2424
 
                                        if(side==1){                                            
2425
 
                                                if(tri)tri=0;
2426
 
                                                currente=start;
2427
 
                                                currente->f |= 2;
2428
 
                                                currente->v1->f |= 2;
2429
 
                                                currente->v2->f |= 2;                                   
2430
 
                                                side++;
2431
 
                                                c=0;
2432
 
                                        }
2433
 
                                        else lastface=1;
2434
 
                                }                               
2435
 
                                /*----------END Decisions-----------------------------*/
2436
 
                                
2437
 
                        }
2438
 
                        /*-----END Limit the Search----- */
2439
 
                        
2440
 
                        
2441
 
                        /*------------- Preview lines--------------- */
2442
 
                        
2443
 
                        /* uses callback mechanism to draw it all in current area */
2444
 
                        scrarea_do_windraw(curarea);                    
2445
 
                        
2446
 
                        /* set window matrix to perspective, default an area returns with buttons transform */
2447
 
                        persp(PERSP_VIEW);
2448
 
                        /* make a copy, for safety */
2449
 
                        glPushMatrix();
2450
 
                        /* multiply with the object transformation */
2451
 
                        mymultmatrix(G.obedit->obmat);
2452
 
                        
2453
 
                        glColor3ub(255, 255, 0);
2454
 
                        
2455
 
                        if(mode==LOOP_SELECT){
2456
 
                                evl= em->faces.first;
2457
 
                                while(evl){
2458
 
                                        if(evl->f & 8){
2459
 
                                                
2460
 
                                                if(!(evl->e1->f & 8)){
2461
 
                                                        glBegin(GL_LINES);                                                      
2462
 
                                                        glVertex3fv(evl->e1->v1->co);
2463
 
                                                        glVertex3fv(evl->e1->v2->co);
2464
 
                                                        glEnd();        
2465
 
                                                }
2466
 
                                                
2467
 
                                                if(!(evl->e2->f & 8)){
2468
 
                                                        glBegin(GL_LINES);                                                      
2469
 
                                                        glVertex3fv(evl->e2->v1->co);
2470
 
                                                        glVertex3fv(evl->e2->v2->co);
2471
 
                                                        glEnd();        
2472
 
                                                }
2473
 
                                                
2474
 
                                                if(!(evl->e3->f & 8)){
2475
 
                                                        glBegin(GL_LINES);                                                      
2476
 
                                                        glVertex3fv(evl->e3->v1->co);
2477
 
                                                        glVertex3fv(evl->e3->v2->co);
2478
 
                                                        glEnd();        
2479
 
                                                }
2480
 
                                                
2481
 
                                                if(evl->e4){
2482
 
                                                        if(!(evl->e4->f & 8)){
2483
 
                                                                glBegin(GL_LINES);                                                      
2484
 
                                                                glVertex3fv(evl->e4->v1->co);
2485
 
                                                                glVertex3fv(evl->e4->v2->co);
2486
 
                                                                glEnd();        
2487
 
                                                        }
2488
 
                                                }
2489
 
                                        }
2490
 
                                        evl=evl->next;
2491
 
                                }
2492
 
                        }
2493
 
                                
2494
 
                        if(mode==LOOP_CUT){
2495
 
                                evl= em->faces.first;
2496
 
                                while(evl){
2497
 
                                        if(evl->f & 8){
2498
 
                                                float cen[2][3];
2499
 
                                                int a=0;                                                
2500
 
                                                
2501
 
                                                evl->v1->f &= ~8;
2502
 
                                                evl->v2->f &= ~8;
2503
 
                                                evl->v3->f &= ~8;
2504
 
                                                if(evl->v4)evl->v4->f &= ~8;
2505
 
                                        
2506
 
                                                if(evl->e1->f & 8){
2507
 
                                                        cen[a][0]= (evl->e1->v1->co[0] + evl->e1->v2->co[0])/2.0;
2508
 
                                                        cen[a][1]= (evl->e1->v1->co[1] + evl->e1->v2->co[1])/2.0;
2509
 
                                                        cen[a][2]= (evl->e1->v1->co[2] + evl->e1->v2->co[2])/2.0;
2510
 
                                                        
2511
 
                                                        evl->e1->v1->f |= 8;
2512
 
                                                        evl->e1->v2->f |= 8;
2513
 
                                                        
2514
 
                                                        a++;
2515
 
                                                }
2516
 
                                                if((evl->e2->f & 8) && a!=2){
2517
 
                                                        cen[a][0]= (evl->e2->v1->co[0] + evl->e2->v2->co[0])/2.0;
2518
 
                                                        cen[a][1]= (evl->e2->v1->co[1] + evl->e2->v2->co[1])/2.0;
2519
 
                                                        cen[a][2]= (evl->e2->v1->co[2] + evl->e2->v2->co[2])/2.0;
2520
 
                                                        
2521
 
                                                        evl->e2->v1->f |= 8;
2522
 
                                                        evl->e2->v2->f |= 8;
2523
 
                                                        
2524
 
                                                        a++;
2525
 
                                                }
2526
 
                                                if((evl->e3->f & 8) && a!=2){
2527
 
                                                        cen[a][0]= (evl->e3->v1->co[0] + evl->e3->v2->co[0])/2.0;
2528
 
                                                        cen[a][1]= (evl->e3->v1->co[1] + evl->e3->v2->co[1])/2.0;
2529
 
                                                        cen[a][2]= (evl->e3->v1->co[2] + evl->e3->v2->co[2])/2.0;
2530
 
                                                        
2531
 
                                                        evl->e3->v1->f |= 8;
2532
 
                                                        evl->e3->v2->f |= 8;
2533
 
                                                        
2534
 
                                                        a++;
2535
 
                                                }
2536
 
                                                
2537
 
                                                if(evl->e4){
2538
 
                                                        if((evl->e4->f & 8) && a!=2){
2539
 
                                                                cen[a][0]= (evl->e4->v1->co[0] + evl->e4->v2->co[0])/2.0;
2540
 
                                                                cen[a][1]= (evl->e4->v1->co[1] + evl->e4->v2->co[1])/2.0;
2541
 
                                                                cen[a][2]= (evl->e4->v1->co[2] + evl->e4->v2->co[2])/2.0;
2542
 
                                                                
2543
 
                                                                evl->e4->v1->f |= 8;
2544
 
                                                                evl->e4->v2->f |= 8;
2545
 
                                                        
2546
 
                                                                a++;
2547
 
                                                        }
2548
 
                                                }
2549
 
                                                else{   /* if it's a triangular face, set the remaining vertex as the cutcurve coordinate */                                                                                                            
2550
 
                                                                if(!(evl->v1->f & 8) && evl->v1->h==0){
2551
 
                                                                        cen[a][0]= evl->v1->co[0];
2552
 
                                                                        cen[a][1]= evl->v1->co[1];
2553
 
                                                                        cen[a][2]= evl->v1->co[2];
2554
 
                                                                        a++;                                                            
2555
 
                                                                }
2556
 
                                                                else if(!(evl->v2->f & 8) && evl->v2->h==0){
2557
 
                                                                        cen[a][0]= evl->v2->co[0];
2558
 
                                                                        cen[a][1]= evl->v2->co[1];
2559
 
                                                                        cen[a][2]= evl->v2->co[2];      
2560
 
                                                                        a++;
2561
 
                                                                }
2562
 
                                                                else if(!(evl->v3->f & 8) && evl->v3->h==0){
2563
 
                                                                        cen[a][0]= evl->v3->co[0];
2564
 
                                                                        cen[a][1]= evl->v3->co[1];
2565
 
                                                                        cen[a][2]= evl->v3->co[2];
2566
 
                                                                        a++;                                                                    
2567
 
                                                                }                                                       
2568
 
                                                }
2569
 
                                                
2570
 
                                                if(a==2){
2571
 
                                                        glBegin(GL_LINES);
2572
 
                                                        
2573
 
                                                        glVertex3fv(cen[0]);
2574
 
                                                        glVertex3fv(cen[1]);    
2575
 
                                                                                                
2576
 
                                                        glEnd();
2577
 
                                                }                                               
2578
 
                                        }
2579
 
                                        evl=evl->next;
2580
 
                                }
2581
 
                                
2582
 
                                eed=em->edges.first; 
2583
 
                                while(eed){
2584
 
                                        if(eed->f & 64){
2585
 
                                                glBegin(GL_LINES);
2586
 
                                                glColor3ub(200, 255, 200);
2587
 
                                                glVertex3fv(eed->v1->co);
2588
 
                                                glVertex3fv(eed->v2->co);
2589
 
                                                glEnd();
2590
 
                                                eed=0;
2591
 
                                        }else{
2592
 
                                                eed = eed->next;
2593
 
                                        }
2594
 
                                }               
2595
 
                        }
2596
 
                        
2597
 
                        /* restore matrix transform */
2598
 
                        glPopMatrix();
2599
 
                        
2600
 
                        headerprint("LMB to confirm, RMB to cancel");
2601
 
                        
2602
 
                        /* this also verifies other area/windows for clean swap */
2603
 
                        screen_swapbuffers();
2604
 
                        
2605
 
                        /*--------- END Preview Lines------------*/
2606
 
                                
2607
 
                }/*if(start!=NULL){ */
2608
 
                
2609
 
                while(qtest()) {
2610
 
                        unsigned short val=0;                   
2611
 
                        event= extern_qread(&val);      /* extern_qread stores important events for the mainloop to handle */
2612
 
 
2613
 
                        /* val==0 on key-release event */
2614
 
                        if(val && (event==ESCKEY || event==RIGHTMOUSE || event==LEFTMOUSE || event==RETKEY || event == MIDDLEMOUSE)){
2615
 
                                searching=0;
2616
 
                        }
2617
 
                }       
2618
 
                
2619
 
        }/*while(event!=ESCKEY && event!=RIGHTMOUSE && event!=LEFTMOUSE && event!=RETKEY){*/
2620
 
        
2621
 
        /*----------Select Loop------------*/
2622
 
        if(mode==LOOP_SELECT && start!=NULL && ((event==LEFTMOUSE || event==RETKEY) || event == MIDDLEMOUSE || event == BKEY)){
2623
 
                                
2624
 
                /* If this is a unmodified select, clear the selection */
2625
 
                if(!(G.qual & LR_SHIFTKEY) && !(G.qual & LR_ALTKEY)){
2626
 
                        for(evl= em->faces.first;evl;evl=evl->next){
2627
 
                                evl->v1->f &= !1;
2628
 
                                evl->v2->f &= !1;
2629
 
                                evl->v3->f &= !1;
2630
 
                                if(evl->v4)evl->v4->f &= !1;                    
2631
 
                        }
2632
 
                }
2633
 
                /* Alt was not pressed, so add to the selection */
2634
 
                if(!(G.qual & LR_ALTKEY)){
2635
 
                        for(evl= em->faces.first;evl;evl=evl->next){
2636
 
                                if(evl->f & 8){
2637
 
                                        evl->v1->f |= 1;
2638
 
                                        evl->v2->f |= 1;
2639
 
                                        evl->v3->f |= 1;
2640
 
                                        if(evl->v4)evl->v4->f |= 1;
2641
 
                                }
2642
 
                        }
2643
 
                }
2644
 
                /* alt was pressed, so subtract from the selection */
2645
 
                else
2646
 
                {
2647
 
                        for(evl= em->faces.first;evl;evl=evl->next){
2648
 
                                if(evl->f & 8){
2649
 
                                        evl->v1->f &= !1;
2650
 
                                        evl->v2->f &= !1;
2651
 
                                        evl->v3->f &= !1;
2652
 
                                        if(evl->v4)evl->v4->f &= !1;
2653
 
                                }
2654
 
                        }
2655
 
                }
2656
 
        
2657
 
        }
2658
 
        /*----------END Select Loop------------*/
2659
 
        
2660
 
        /*----------Cut Loop---------------*/                   
2661
 
        if(mode==LOOP_CUT && start!=NULL && (event==LEFTMOUSE || event==RETKEY)){
2662
 
                
2663
 
                /* count the number of edges in the loop */             
2664
 
                for(eed=em->edges.first; eed; eed = eed->next){
2665
 
                        if(eed->f & 8)
2666
 
                                ect++;
2667
 
                }               
2668
 
                
2669
 
                tagged = MEM_mallocN(ect*sizeof(EditEdge*), "tagged");
2670
 
                taggedsrch = MEM_mallocN(ect*sizeof(EditEdge*), "taggedsrch");
2671
 
                for(i=0;i<ect;i++)
2672
 
                {
2673
 
                        tagged[i] = NULL;
2674
 
                        taggedsrch[i] = NULL;
2675
 
                }
2676
 
                ect = 0;
2677
 
                for(eed=em->edges.first; eed; eed = eed->next){
2678
 
                        if(eed->f & 8)
2679
 
                        {
2680
 
                                if(eed->h==0){
2681
 
                                        eed->v1->f |= 1;
2682
 
                                        eed->v2->f |= 1;
2683
 
                                        tagged[ect] = eed;
2684
 
                                        eed->f &= ~(32);
2685
 
                                        ect++;
2686
 
                                }
2687
 
                        }                       
2688
 
                }
2689
 
                taggedsrch[0] = tagged[0];
2690
 
 
2691
 
                while(timesthrough < 2)
2692
 
                {
2693
 
                        i=0;
2694
 
                        while(i < ect){/*Look at the members of the search array to line up cuts*/
2695
 
                                if(taggedsrch[i]==NULL)break;
2696
 
                                for(j=0;j<ect;j++){                      /*Look through the list of tagged verts for connected edges*/
2697
 
                                        int addededge = 0;
2698
 
                                        if(taggedsrch[i]->f & 32)        /*If this edgee is marked as flipped, use vert 2*/
2699
 
                                                look = taggedsrch[i]->v2;
2700
 
                                        else                                                     /*else use vert 1*/
2701
 
                                                look = taggedsrch[i]->v1;
2702
 
 
2703
 
                                        if(taggedsrch[i] == tagged[j])
2704
 
                                                continue;  /*If we are looking at the same edge, skip it*/
2705
 
        
2706
 
                                        skip = 0;
2707
 
                                        for(k=0;k<ect;k++)      {
2708
 
                                                if(taggedsrch[k] == NULL)       /*go to empty part of search list without finding*/
2709
 
                                                        break;                                                  
2710
 
                                                if(tagged[j] == taggedsrch[k]){         /*We found a match already in the list*/
2711
 
                                                        skip = 1;
2712
 
                                                        break;
2713
 
                                                }
2714
 
                                        }
2715
 
                                        if(skip)
2716
 
                                                continue;
2717
 
                                        nextpos = 0;
2718
 
                                        if(findedgelist(look,tagged[j]->v2)){
2719
 
                                                while(nextpos < ect){ /*Find the first open spot in the search array*/
2720
 
                                                        if(taggedsrch[nextpos] == NULL){
2721
 
                                                                taggedsrch[nextpos] = tagged[j]; /*put tagged[j] in it*/
2722
 
                                                                taggedsrch[nextpos]->f |= 32;
2723
 
                                                                addededge = 1;
2724
 
                                                                break;
2725
 
                                                        }
2726
 
                                                        else
2727
 
                                                                nextpos++;
2728
 
                                                }
2729
 
                                        } /* End else if connected to vert 2*/
2730
 
                                        else if(findedgelist(look,tagged[j]->v1)){   /*If our vert is connected to vert 1 */
2731
 
                                                while(nextpos < ect){ /*Find the first open spot in the search array */
2732
 
                                                        if(taggedsrch[nextpos] == NULL){
2733
 
                                                                taggedsrch[nextpos] = tagged[j]; /*put tagged[j] in it*/
2734
 
                                                                addededge = 1;
2735
 
                                                                break;
2736
 
                                                        }
2737
 
                                                        else 
2738
 
                                                                nextpos++;
2739
 
                                                }
2740
 
                                        }
2741
 
 
2742
 
                                        if(addededge)
2743
 
                                        {
2744
 
                                                break;
2745
 
                                        }                                       
2746
 
                                }/* End Outer For (j)*/
2747
 
                                i++;
2748
 
                        } /* End while(j<ect)*/
2749
 
                        timesthrough++;
2750
 
                } /*end while timesthrough */
2751
 
                percentcut = 0.50;
2752
 
                searching = 1;
2753
 
                cut   = 1;
2754
 
                smooth = 0;
2755
 
                close = NULL;
2756
 
 
2757
 
 
2758
 
                /* Count the Number of Faces in the selected loop*/
2759
 
                percentfaces = 0;
2760
 
                for(evl= em->faces.first; evl ;evl=evl->next){
2761
 
                        if(evl->f & 8)
2762
 
                         {
2763
 
                                percentfaces++; 
2764
 
                         }
2765
 
                }
2766
 
                        
2767
 
                /* create a dynamic array for those face pointers */
2768
 
                percentfacesloop = MEM_mallocN(percentfaces*sizeof(EditVlak*), "percentage");
2769
 
 
2770
 
                /* put those faces in the array */
2771
 
                i=0;
2772
 
                for(evl= em->faces.first; evl ;evl=evl->next){
2773
 
                         if(evl->f & 8)
2774
 
                         {
2775
 
                                percentfacesloop[i] = evl;      
2776
 
                                i++;
2777
 
                         }
2778
 
                }
2779
 
 
2780
 
                while(searching){
2781
 
                        
2782
 
                        /* For the % calculation */
2783
 
                        short mval[2];                  
2784
 
                        float labda, rc[2], len, slen=0.0;
2785
 
                        float v1[2], v2[2], v3[2];
2786
 
 
2787
 
                        /*------------- Percent Cut Preview Lines--------------- */
2788
 
                        scrarea_do_windraw(curarea);                    
2789
 
                        persp(PERSP_VIEW);
2790
 
                        glPushMatrix();
2791
 
                        mymultmatrix(G.obedit->obmat);
2792
 
                        glColor3ub(0, 255, 255);
2793
 
                                
2794
 
                        /*Put the preview lines where they should be for the percentage selected.*/
2795
 
 
2796
 
                        for(i=0;i<percentfaces;i++){
2797
 
                                evl = percentfacesloop[i];
2798
 
                                for(eed = em->edges.first; eed; eed=eed->next){
2799
 
                                        if(eed->f & 64){        /* color the starting edge */                   
2800
 
                                                glBegin(GL_LINES);
2801
 
                                                                                                
2802
 
                                                glColor3ub(200, 255, 200);
2803
 
                                                glVertex3fv(eed->v1->co);                                       
2804
 
                                                glVertex3fv(eed->v2->co);
2805
 
                                                
2806
 
                                                glEnd();
2807
 
 
2808
 
                                                glPointSize(5);
2809
 
                                                glBegin(GL_POINTS);
2810
 
                                                glColor3ub(255,0,255);
2811
 
                                                
2812
 
                                                if(eed->f & 32)
2813
 
                                                        glVertex3fv(eed->v2->co);                       
2814
 
                                                else
2815
 
                                                        glVertex3fv(eed->v1->co);
2816
 
                                                glEnd();
2817
 
 
2818
 
 
2819
 
                                                /*Get Starting Edge Length*/
2820
 
                                                slen = sqrt((eed->v1->co[0]-eed->v2->co[0])*(eed->v1->co[0]-eed->v2->co[0])+
2821
 
                                                                        (eed->v1->co[1]-eed->v2->co[1])*(eed->v1->co[1]-eed->v2->co[1])+
2822
 
                                                                        (eed->v1->co[2]-eed->v2->co[2])*(eed->v1->co[2]-eed->v2->co[2]));
2823
 
                                        }
2824
 
                                }
2825
 
                                
2826
 
                                if(!inset){
2827
 
                                        glColor3ub(0,255,255);
2828
 
                                        if(evl->f & 8)
2829
 
                                        {
2830
 
                                                float cen[2][3];
2831
 
                                                int a=0;                                        
2832
 
                                                
2833
 
                                                evl->v1->f &= ~8;
2834
 
                                                evl->v2->f &= ~8;
2835
 
                                                evl->v3->f &= ~8;
2836
 
                                                if(evl->v4)evl->v4->f &= ~8;
2837
 
                                                
2838
 
                                                if(evl->e1->f & 8){
2839
 
                                                        float pct;
2840
 
                                                        if(evl->e1->f & 32)
2841
 
                                                                pct = 1-percentcut;
2842
 
                                                        else
2843
 
                                                                pct = percentcut;
2844
 
                                                        cen[a][0]= evl->e1->v1->co[0] - ((evl->e1->v1->co[0] - evl->e1->v2->co[0]) * (pct));
2845
 
                                                        cen[a][1]= evl->e1->v1->co[1] - ((evl->e1->v1->co[1] - evl->e1->v2->co[1]) * (pct));
2846
 
                                                        cen[a][2]= evl->e1->v1->co[2] - ((evl->e1->v1->co[2] - evl->e1->v2->co[2]) * (pct));
2847
 
                                                        evl->e1->v1->f |= 8;
2848
 
                                                        evl->e1->v2->f |= 8;
2849
 
                                                        a++;
2850
 
                                                }
2851
 
                                                if((evl->e2->f & 8) && a!=2)
2852
 
                                                {
2853
 
                                                        float pct;
2854
 
                                                        if(evl->e2->f & 32)
2855
 
                                                                pct = 1-percentcut;
2856
 
                                                        else
2857
 
                                                                pct = percentcut;
2858
 
                                                        cen[a][0]= evl->e2->v1->co[0] - ((evl->e2->v1->co[0] - evl->e2->v2->co[0]) * (pct));
2859
 
                                                        cen[a][1]= evl->e2->v1->co[1] - ((evl->e2->v1->co[1] - evl->e2->v2->co[1]) * (pct));
2860
 
                                                        cen[a][2]= evl->e2->v1->co[2] - ((evl->e2->v1->co[2] - evl->e2->v2->co[2]) * (pct));
2861
 
 
2862
 
                                                        evl->e2->v1->f |= 8;
2863
 
                                                        evl->e2->v2->f |= 8;
2864
 
                                                        
2865
 
                                                        a++;
2866
 
                                                }
2867
 
                                                if((evl->e3->f & 8) && a!=2){
2868
 
                                                        float pct;
2869
 
                                                        if(evl->e3->f & 32)
2870
 
                                                                pct = 1-percentcut;
2871
 
                                                        else
2872
 
                                                                pct = percentcut;
2873
 
                                                        cen[a][0]= evl->e3->v1->co[0] - ((evl->e3->v1->co[0] - evl->e3->v2->co[0]) * (pct));
2874
 
                                                        cen[a][1]= evl->e3->v1->co[1] - ((evl->e3->v1->co[1] - evl->e3->v2->co[1]) * (pct));
2875
 
                                                        cen[a][2]= evl->e3->v1->co[2] - ((evl->e3->v1->co[2] - evl->e3->v2->co[2]) * (pct));
2876
 
 
2877
 
                                                        evl->e3->v1->f |= 8;
2878
 
                                                        evl->e3->v2->f |= 8;
2879
 
                                                        
2880
 
                                                        a++;
2881
 
                                                }
2882
 
                                                        
2883
 
                                                if(evl->e4){
2884
 
                                                        if((evl->e4->f & 8) && a!=2){
2885
 
                                                                float pct;
2886
 
                                                                if(evl->e4->f & 32)
2887
 
                                                                        pct = 1-percentcut;
2888
 
                                                                else
2889
 
                                                                        pct = percentcut;
2890
 
                                                                cen[a][0]= evl->e4->v1->co[0] - ((evl->e4->v1->co[0] - evl->e4->v2->co[0]) * (pct));
2891
 
                                                                cen[a][1]= evl->e4->v1->co[1] - ((evl->e4->v1->co[1] - evl->e4->v2->co[1]) * (pct));
2892
 
                                                                cen[a][2]= evl->e4->v1->co[2] - ((evl->e4->v1->co[2] - evl->e4->v2->co[2]) * (pct));
2893
 
 
2894
 
                                                                evl->e4->v1->f |= 8;
2895
 
                                                                evl->e4->v2->f |= 8;
2896
 
                                                        
2897
 
                                                                a++;
2898
 
                                                        }
2899
 
                                                }
2900
 
                                                else {  /* if it's a triangular face, set the remaining vertex as the cutcurve coordinate */
2901
 
                                                        if(!(evl->v1->f & 8) && evl->v1->h==0){
2902
 
                                                                cen[a][0]= evl->v1->co[0];
2903
 
                                                                cen[a][1]= evl->v1->co[1];
2904
 
                                                                cen[a][2]= evl->v1->co[2];
2905
 
                                                                a++;                                                            
2906
 
                                                        }
2907
 
                                                        else if(!(evl->v2->f & 8) && evl->v2->h==0){
2908
 
                                                                cen[a][0]= evl->v2->co[0];
2909
 
                                                                cen[a][1]= evl->v2->co[1];
2910
 
                                                                cen[a][2]= evl->v2->co[2];
2911
 
                                                                a++;                                                            
2912
 
                                                        }
2913
 
                                                        else if(!(evl->v3->f & 8) && evl->v3->h==0){
2914
 
                                                                cen[a][0]= evl->v3->co[0];
2915
 
                                                                cen[a][1]= evl->v3->co[1];
2916
 
                                                                cen[a][2]= evl->v3->co[2];
2917
 
                                                                a++;                                                                                                    
2918
 
                                                        }
2919
 
                                                }
2920
 
                                                
2921
 
                                                if(a==2){
2922
 
                                                        glBegin(GL_LINES);
2923
 
                                                        
2924
 
                                                        glVertex3fv(cen[0]);
2925
 
                                                        glVertex3fv(cen[1]);    
2926
 
                                                                                                
2927
 
                                                        glEnd();
2928
 
                                                }       
2929
 
                                        }
2930
 
                                }/* end preview line drawing */                 
2931
 
                                else{
2932
 
                                        glColor3ub(0,128,255);
2933
 
                                        if(evl->f & 8)
2934
 
                                        {
2935
 
                                                float cen[2][3];
2936
 
                                                int a=0;                                        
2937
 
                                                
2938
 
                                                evl->v1->f &= ~8;
2939
 
                                                evl->v2->f &= ~8;
2940
 
                                                evl->v3->f &= ~8;
2941
 
                                                if(evl->v4)evl->v4->f &= ~8;
2942
 
                                                
2943
 
                                                if(evl->e1->f & 8){                                                     
2944
 
                                                        float nlen,npct;
2945
 
                                                        
2946
 
                                                        nlen = sqrt((evl->e1->v1->co[0] - evl->e1->v2->co[0])*(evl->e1->v1->co[0] - evl->e1->v2->co[0])+
2947
 
                                                                                (evl->e1->v1->co[1] - evl->e1->v2->co[1])*(evl->e1->v1->co[1] - evl->e1->v2->co[1])+
2948
 
                                                                                (evl->e1->v1->co[2] - evl->e1->v2->co[2])*(evl->e1->v1->co[2] - evl->e1->v2->co[2]));
2949
 
                                                        npct = (percentcut*slen)/nlen;
2950
 
                                                        if(npct >= 1) npct = 1;
2951
 
                                                        if(evl->e1->f & 32)     npct = 1-npct;
2952
 
 
2953
 
                                                        cen[a][0]= evl->e1->v1->co[0] - ((evl->e1->v1->co[0] - evl->e1->v2->co[0]) * (npct));
2954
 
                                                        cen[a][1]= evl->e1->v1->co[1] - ((evl->e1->v1->co[1] - evl->e1->v2->co[1]) * (npct));
2955
 
                                                        cen[a][2]= evl->e1->v1->co[2] - ((evl->e1->v1->co[2] - evl->e1->v2->co[2]) * (npct));
2956
 
 
2957
 
                                                        evl->e1->f1 = 32768*(npct);
2958
 
                                                        evl->e1->v1->f |= 8;
2959
 
                                                        evl->e1->v2->f |= 8;
2960
 
                                                        a++;
2961
 
                                                }
2962
 
                                                if((evl->e2->f & 8) && a!=2)
2963
 
                                                {
2964
 
                                                        float nlen,npct;
2965
 
                                                        
2966
 
                                                        nlen = sqrt((evl->e2->v1->co[0] - evl->e2->v2->co[0])*(evl->e2->v1->co[0] - evl->e2->v2->co[0])+
2967
 
                                                                                (evl->e2->v1->co[1] - evl->e2->v2->co[1])*(evl->e2->v1->co[1] - evl->e2->v2->co[1])+
2968
 
                                                                                (evl->e2->v1->co[2] - evl->e2->v2->co[2])*(evl->e2->v1->co[2] - evl->e2->v2->co[2]));
2969
 
                                                        npct = (percentcut*slen)/nlen;
2970
 
                                                        if(npct >= 1) npct = 1;
2971
 
                                                        if(evl->e2->f & 32)     npct = 1-npct;
2972
 
 
2973
 
                                                        cen[a][0]= evl->e2->v1->co[0] - ((evl->e2->v1->co[0] - evl->e2->v2->co[0]) * (npct));
2974
 
                                                        cen[a][1]= evl->e2->v1->co[1] - ((evl->e2->v1->co[1] - evl->e2->v2->co[1]) * (npct));
2975
 
                                                        cen[a][2]= evl->e2->v1->co[2] - ((evl->e2->v1->co[2] - evl->e2->v2->co[2]) * (npct));
2976
 
 
2977
 
                                                        evl->e2->f1 = 32768*(npct);                                                             
2978
 
                                                        evl->e2->v1->f |= 8;
2979
 
                                                        evl->e2->v2->f |= 8;
2980
 
                                                        a++;
2981
 
                                                }
2982
 
                                                if((evl->e3->f & 8) && a!=2){
2983
 
                                                        float nlen,npct;
2984
 
                                                        
2985
 
                                                        nlen = sqrt((evl->e3->v1->co[0] - evl->e3->v2->co[0])*(evl->e3->v1->co[0] - evl->e3->v2->co[0])+
2986
 
                                                                                (evl->e3->v1->co[1] - evl->e3->v2->co[1])*(evl->e3->v1->co[1] - evl->e3->v2->co[1])+
2987
 
                                                                                (evl->e3->v1->co[2] - evl->e3->v2->co[2])*(evl->e3->v1->co[2] - evl->e3->v2->co[2]));
2988
 
                                                        npct = (percentcut*slen)/nlen;
2989
 
                                                        if(npct >= 1) npct = 1;
2990
 
                                                        if(evl->e3->f & 32)     npct = 1-npct;
2991
 
 
2992
 
                                                        cen[a][0]= evl->e3->v1->co[0] - ((evl->e3->v1->co[0] - evl->e3->v2->co[0]) * (npct));
2993
 
                                                        cen[a][1]= evl->e3->v1->co[1] - ((evl->e3->v1->co[1] - evl->e3->v2->co[1]) * (npct));
2994
 
                                                        cen[a][2]= evl->e3->v1->co[2] - ((evl->e3->v1->co[2] - evl->e3->v2->co[2]) * (npct));
2995
 
 
2996
 
                                                        evl->e3->f1 = 32768*(npct);                                                             
2997
 
                                                        evl->e3->v1->f |= 8;
2998
 
                                                        evl->e3->v2->f |= 8;
2999
 
                                                        a++;
3000
 
                                                }
3001
 
                                                        
3002
 
                                                if(evl->e4){
3003
 
                                                        if((evl->e4->f & 8) && a!=2){
3004
 
                                                                float nlen,npct;
3005
 
                                                                
3006
 
                                                                nlen = sqrt((evl->e4->v1->co[0] - evl->e4->v2->co[0])*(evl->e4->v1->co[0] - evl->e4->v2->co[0])+
3007
 
                                                                                        (evl->e4->v1->co[1] - evl->e4->v2->co[1])*(evl->e4->v1->co[1] - evl->e4->v2->co[1])+
3008
 
                                                                                        (evl->e4->v1->co[2] - evl->e4->v2->co[2])*(evl->e4->v1->co[2] - evl->e4->v2->co[2]));
3009
 
                                                        npct = (percentcut*slen)/nlen;
3010
 
                                                        if(npct >= 1) npct = 1;
3011
 
                                                        if(evl->e4->f & 32)     npct = 1-npct;
3012
 
 
3013
 
                                                                cen[a][0]= evl->e4->v1->co[0] - ((evl->e4->v1->co[0] - evl->e4->v2->co[0]) * (npct));
3014
 
                                                                cen[a][1]= evl->e4->v1->co[1] - ((evl->e4->v1->co[1] - evl->e4->v2->co[1]) * (npct));
3015
 
                                                                cen[a][2]= evl->e4->v1->co[2] - ((evl->e4->v1->co[2] - evl->e4->v2->co[2]) * (npct));
3016
 
 
3017
 
                                                                evl->e4->f1 = 32768*(npct);                                                                     
3018
 
                                                                evl->e4->v1->f |= 8;
3019
 
                                                                evl->e4->v2->f |= 8;
3020
 
                                                                a++;
3021
 
                                                        }
3022
 
                                                }
3023
 
                                                else {  /* if it's a triangular face, set the remaining vertex as the cutcurve coordinate */
3024
 
                                                        if(!(evl->v1->f & 8) && evl->v1->h==0){
3025
 
                                                                cen[a][0]= evl->v1->co[0];
3026
 
                                                                cen[a][1]= evl->v1->co[1];
3027
 
                                                                cen[a][2]= evl->v1->co[2];
3028
 
                                                                a++;                                                            
3029
 
                                                        }
3030
 
                                                        else if(!(evl->v2->f & 8) && evl->v2->h==0){
3031
 
                                                                cen[a][0]= evl->v2->co[0];
3032
 
                                                                cen[a][1]= evl->v2->co[1];
3033
 
                                                                cen[a][2]= evl->v2->co[2];
3034
 
                                                                a++;                                                            
3035
 
                                                        }
3036
 
                                                        else if(!(evl->v3->f & 8) && evl->v3->h==0){
3037
 
                                                                cen[a][0]= evl->v3->co[0];
3038
 
                                                                cen[a][1]= evl->v3->co[1];
3039
 
                                                                cen[a][2]= evl->v3->co[2];
3040
 
                                                                a++;                                                                                                    
3041
 
                                                        }
3042
 
                                                }
3043
 
                                                
3044
 
                                                if(a==2){
3045
 
                                                        glBegin(GL_LINES);
3046
 
                                                        
3047
 
                                                        glVertex3fv(cen[0]);
3048
 
                                                        glVertex3fv(cen[1]);    
3049
 
                                                                                                
3050
 
                                                        glEnd();
3051
 
                                                }       
3052
 
                                        }
3053
 
                                }
3054
 
                        }
3055
 
                        /* restore matrix transform */
3056
 
        
3057
 
                        glPopMatrix();
3058
 
 
3059
 
                        /*--------- END Preview Lines------------*/
3060
 
                        while(qtest()) 
3061
 
                        {
3062
 
                                unsigned short val=0;                   
3063
 
                                event= extern_qread(&val);      /* extern_qread stores important events for the mainloop to handle */
3064
 
                                /* val==0 on key-release event */
3065
 
                
3066
 
                                if(val && (event==SKEY))
3067
 
                                {
3068
 
                                        if(smooth)smooth = 0;
3069
 
                                        else smooth = 1;
3070
 
                                }
3071
 
 
3072
 
                                if(val && (event==PKEY))
3073
 
                                {
3074
 
                                        if(inset)inset = 0;
3075
 
                                        else inset = 1;
3076
 
                                }
3077
 
 
3078
 
                                if(val && (event==FKEY))
3079
 
                                {
3080
 
                                                int ct;
3081
 
                                                for(ct = 0; ct < ect; ct++){
3082
 
                                                        if(tagged[ct]->f & 32) 
3083
 
                                                                tagged[ct]->f &= ~32;
3084
 
                                                        else
3085
 
                                                                tagged[ct]->f |= 32;
3086
 
                                                }
3087
 
                                }
3088
 
 
3089
 
                                if(val && (event == MIDDLEMOUSE))
3090
 
                                {
3091
 
                                        cut = 2;
3092
 
                                        searching=0;
3093
 
                                }
3094
 
                                else if(val && (event==LEFTMOUSE || event==RETKEY))
3095
 
                                {
3096
 
                                        searching=0;
3097
 
                                }
3098
 
 
3099
 
                                if(val && (event==ESCKEY || event==RIGHTMOUSE ))
3100
 
                                {
3101
 
                                        searching=0;
3102
 
                                        cut = 0;
3103
 
                                }
3104
 
                                
3105
 
                        }                       
3106
 
                        
3107
 
 
3108
 
                        /* Determine the % on wich the loop should be cut */
3109
 
                        getmouseco_areawin(mval);                       
3110
 
                        v1[0]=(float)mval[0];
3111
 
                        v1[1]=(float)mval[1];
3112
 
                        
3113
 
                        v2[0]=(float)start->v1->xs;
3114
 
                        v2[1]=(float)start->v1->ys;
3115
 
                        
3116
 
                        v3[0]=(float)start->v2->xs;
3117
 
                        v3[1]=(float)start->v2->ys;
3118
 
                        
3119
 
                        rc[0]= v3[0]-v2[0];
3120
 
                        rc[1]= v3[1]-v2[1];
3121
 
                        len= rc[0]*rc[0]+ rc[1]*rc[1];
3122
 
                                
3123
 
                        labda= ( rc[0]*(v1[0]-v2[0]) + rc[1]*(v1[1]-v2[1]) )/len;
3124
 
 
3125
 
 
3126
 
                        if(labda<=0.0) labda=0.0;
3127
 
                        else if(labda>=1.0)labda=1.0;
3128
 
                                                
3129
 
                        percentcut=labda;               
3130
 
                        
3131
 
                        if(start->f & 32)
3132
 
                                percentcut = 1.0-percentcut;
3133
 
 
3134
 
                if(cut == 2){
3135
 
                        percentcut = 0.5;
3136
 
                }
3137
 
 
3138
 
                if (G.qual & LR_SHIFTKEY){
3139
 
 
3140
 
                        percentcut = (int)(percentcut*100.0)/100.0;     
3141
 
                }
3142
 
                else if (G.qual & LR_CTRLKEY)
3143
 
                        percentcut = (int)(percentcut*10.0)/10.0;               
3144
 
        
3145
 
                outcut = (percentcut*100.0);
3146
 
 
3147
 
                /* Build the Header Line */ 
3148
 
 
3149
 
                if(inset)
3150
 
                        sprintf(mesg,"Cut: %0.2f%% ",slen*percentcut);
3151
 
                else
3152
 
                        sprintf(mesg,"Cut: %0.2f%% ",outcut);
3153
 
                
3154
 
 
3155
 
                if(smooth)
3156
 
                        sprintf(mesg,"%s| (f)lip side | (s)mooth on  |",mesg);
3157
 
                else
3158
 
                        sprintf(mesg,"%s| (f)lip side | (s)mooth off |",mesg);
3159
 
 
3160
 
                if(inset)
3161
 
                        sprintf(mesg,"%s (p)roportional on ",mesg);
3162
 
                else
3163
 
                        sprintf(mesg,"%s (p)roportional off",mesg);
3164
 
                
3165
 
                headerprint(mesg);
3166
 
 
3167
 
                screen_swapbuffers();           
3168
 
        }                       
3169
 
        
3170
 
        if(cut){
3171
 
                /* Now that we have selected a cut %, mark the edges for cutting. */
3172
 
                if(!inset){
3173
 
                        for(eed = em->edges.first; eed; eed=eed->next){         
3174
 
                                        if(percentcut == 1.0)
3175
 
                                                percentcut = 0.9999;
3176
 
                                        else if(percentcut == 0.0)
3177
 
                                                percentcut = 0.0001;
3178
 
                                        if(eed->f & 8){
3179
 
                                                if(eed->f & 32)/* Need to offset by a const. (0.5/32768) for consistant roundoff */
3180
 
                                                        eed->f1 = 32768*(1.0-percentcut - 0.0000153);
3181
 
                                                else
3182
 
                                                        eed->f1 = 32768*(percentcut + 0.0000153);
3183
 
                                        }                               
3184
 
                        }
3185
 
                }
3186
 
        /*-------------------------------------*/
3187
 
 
3188
 
                        if(smooth)
3189
 
                                subdivideflag(8, 0, B_KNIFE | B_PERCENTSUBD | B_SMOOTH); /* B_KNIFE tells subdivide that edgeflags are already set */
3190
 
                        else
3191
 
                                subdivideflag(8, 0, B_KNIFE | B_PERCENTSUBD); /* B_KNIFE tells subdivide that edgeflags are already set */
3192
 
                        
3193
 
                        for(eed = em->edges.first; eed; eed=eed->next){                                                 
3194
 
                                if(eed->v1->f & 16) eed->v1->f |= 1;
3195
 
                                else eed->v1->f &= ~1;
3196
 
                                
3197
 
                                if(eed->v2->f & 16) eed->v2->f |= 1;
3198
 
                                else eed->v2->f &= ~1;
3199
 
                        }                       
3200
 
                }
3201
 
        }
3202
 
        /*----------END Cut Loop-----------------------------*/
3203
 
 
3204
 
        
3205
 
 
3206
 
        /* Clear flags */               
3207
 
        for(eed = em->edges.first; eed; eed=eed->next){ 
3208
 
                eed->f &= ~(2|4|8|32|64);
3209
 
                eed->v1->f &= ~(2|16);
3210
 
                eed->v2->f &= ~(2|16);          
3211
 
        }
3212
 
        
3213
 
        for(evl= em->faces.first; evl; evl=evl->next){
3214
 
                evl->f &= ~(4|8);
3215
 
        }
3216
 
        
3217
 
        countall();
3218
 
 
3219
 
        if(tagged)
3220
 
                MEM_freeN(tagged);
3221
 
        if(taggedsrch)
3222
 
                MEM_freeN(taggedsrch);
3223
 
        if(percentfacesloop)
3224
 
                MEM_freeN(percentfacesloop);
3225
 
        
3226
 
        /* send event to redraw this window, does header too */ 
3227
 
        SetBlenderCursor(SYSCURSOR);
3228
 
        addqueue(curarea->win, REDRAW, 1); 
3229
 
}
3230
 
 
3231
 
void edge_select(void)
3232
 
{
3233
 
        EditMesh *em = G.editMesh;
3234
 
        EditEdge *closest=0;
3235
 
        
3236
 
        closest=findnearestedge();      
3237
 
        
3238
 
        if(closest){         /* Did we find anything that is selectable?*/
3239
 
 
3240
 
                if( (G.qual & LR_SHIFTKEY)==0) {
3241
 
                        EditVert *eve;                  
3242
 
                        
3243
 
                        undo_push_mesh("Edge select");
3244
 
                        /* deselectall */
3245
 
                        for(eve= em->verts.first; eve; eve= eve->next) eve->f&= ~1;
3246
 
 
3247
 
                        /* select edge */
3248
 
                        closest->v1->f |= 1;
3249
 
                        closest->v2->f |= 1;
3250
 
                }
3251
 
                else {
3252
 
                        /*  both of the vertices are selected: deselect both*/
3253
 
                        if((closest->v1->f & 1) && (closest->v2->f & 1) ){  
3254
 
                                closest->v1->f &= ~1;
3255
 
                                closest->v2->f &= ~1;
3256
 
                        }
3257
 
                        else { 
3258
 
                                /* select both */
3259
 
                                closest->v1->f |= 1;
3260
 
                                closest->v2->f |= 1;
3261
 
                        }
3262
 
                }
3263
 
                countall();
3264
 
                allqueue(REDRAWVIEW3D, 0);
3265
 
        }
3266
 
}
3267
 
 
3268
 
static void draw_vertices_special(int mode, EditVert *act) /* teken = draw */
3269
 
{
3270
 
        /* (only this view, no other windows) */
3271
 
        /* hackish routine for visual speed:
3272
 
         * mode 0: deselect the selected ones, draw them, except act
3273
 
         * mode 1: only draw act
3274
 
         */
3275
 
        EditMesh *em = G.editMesh;
3276
 
        EditVert *eve;
3277
 
        float size= BIF_GetThemeValuef(TH_VERTEX_SIZE);
3278
 
        char col[3];
3279
 
        
3280
 
        glPointSize(size);
3281
 
 
3282
 
        persp(PERSP_VIEW);
3283
 
        glPushMatrix();
3284
 
        mymultmatrix(G.obedit->obmat);
3285
 
 
3286
 
        if(mode==0) {
3287
 
                BIF_ThemeColor(TH_VERTEX);
3288
 
                
3289
 
                /* set zbuffer on, its default off outside main drawloops */
3290
 
                if(G.vd->drawtype > OB_WIRE) {
3291
 
                        G.zbuf= 1;
3292
 
                        glEnable(GL_DEPTH_TEST);
3293
 
                }
3294
 
 
3295
 
                glBegin(GL_POINTS);
3296
 
                eve= (EditVert *)em->verts.first;
3297
 
                while(eve) {
3298
 
                        if(eve->h==0) {
3299
 
                                if(eve!=act && (eve->f & 1)) {
3300
 
                                        eve->f -= 1;
3301
 
                                        glVertex3fv(eve->co);
3302
 
                                }
3303
 
                        }
3304
 
                        eve= eve->next;
3305
 
                }
3306
 
                glEnd();
3307
 
                
3308
 
                glDisable(GL_DEPTH_TEST);
3309
 
                G.zbuf= 0;
3310
 
        }
3311
 
        
3312
 
        /* draw active vertex */
3313
 
        if(act->f & 1) BIF_GetThemeColor3ubv(TH_VERTEX_SELECT, col);
3314
 
        else BIF_GetThemeColor3ubv(TH_VERTEX, col);
3315
 
        
3316
 
        glColor3ub(col[0], col[1], col[2]);
3317
 
 
3318
 
        glBegin(GL_POINTS);
3319
 
        glVertex3fv(act->co);
3320
 
        glEnd();
3321
 
        
3322
 
        glPointSize(1.0);
3323
 
        glPopMatrix();
3324
 
 
3325
 
        
3326
 
}
3327
 
 
3328
 
void mouse_mesh(void)
3329
 
{
3330
 
        EditVert *act=0;
3331
 
 
3332
 
        if(G.qual & LR_ALTKEY) {
3333
 
                if (G.qual & LR_CTRLKEY) edge_select();
3334
 
        }
3335
 
        else {
3336
 
        
3337
 
                act= findnearestvert(1);
3338
 
                if(act) {
3339
 
                        
3340
 
                        glDrawBuffer(GL_FRONT);
3341
 
 
3342
 
                        undo_push_mesh("Vertex select");
3343
 
 
3344
 
                        if( (act->f & 1)==0) act->f+= 1;
3345
 
                        else if(G.qual & LR_SHIFTKEY) act->f-= 1;
3346
 
 
3347
 
                        if((G.qual & LR_SHIFTKEY)==0) {
3348
 
                                draw_vertices_special(0, act);
3349
 
                        }
3350
 
                        else draw_vertices_special(1, act);
3351
 
 
3352
 
                        countall();
3353
 
 
3354
 
                        glFinish();
3355
 
                        glDrawBuffer(GL_BACK);
3356
 
                        
3357
 
                        /* signal that frontbuf differs from back */
3358
 
                        curarea->win_swap= WIN_FRONT_OK;
3359
 
                        
3360
 
                        if(G.f & (G_FACESELECT|G_DRAWFACES|G_DRAWEDGES)) {
3361
 
                                /* update full view later on */
3362
 
                                allqueue(REDRAWVIEW3D, 0);
3363
 
                        }
3364
 
                        else allqueue(REDRAWVIEW3D, curarea->win);      // all windows except this one
3365
 
                }
3366
 
        
3367
 
                rightmouse_transform();
3368
 
        }
3369
 
}
3370
 
 
3371
 
static void selectconnectedAll(void)
3372
 
{
3373
 
        EditMesh *em = G.editMesh;
3374
 
        EditVert *v1,*v2;
3375
 
        EditEdge *eed;
3376
 
        short flag=1,toggle=0;
3377
 
 
3378
 
        if(em->edges.first==0) return;
3379
 
        
3380
 
        undo_push_mesh("Select Connected (All)");
3381
 
 
3382
 
        while(flag==1) {
3383
 
                flag= 0;
3384
 
                toggle++;
3385
 
                if(toggle & 1) eed= em->edges.first;
3386
 
                else eed= em->edges.last;
3387
 
                while(eed) {
3388
 
                        v1= eed->v1;
3389
 
                        v2= eed->v2;
3390
 
                        if(eed->h==0) {
3391
 
                                if(v1->f & 1) {
3392
 
                                        if( (v2->f & 1)==0 ) {
3393
 
                                                v2->f |= 1;
3394
 
                                                flag= 1;
3395
 
                                        }
3396
 
                                }
3397
 
                                else if(v2->f & 1) {
3398
 
                                        if( (v1->f & 1)==0 ) {
3399
 
                                                v1->f |= 1;
3400
 
                                                flag= 1;
3401
 
                                        }
3402
 
                                }
3403
 
                        }
3404
 
                        if(toggle & 1) eed= eed->next;
3405
 
                        else eed= eed->prev;
3406
 
                }
3407
 
        }
3408
 
        countall();
3409
 
 
3410
 
        allqueue(REDRAWVIEW3D, 0);
3411
 
 
3412
 
}
3413
 
 
3414
 
void selectconnected_mesh(int qual)
3415
 
{
3416
 
        EditMesh *em = G.editMesh;
3417
 
        EditVert *eve,*v1,*v2,*act= 0;
3418
 
        EditEdge *eed;
3419
 
        short flag=1,sel,toggle=0;
3420
 
 
3421
 
        if(em->edges.first==0) return;
3422
 
 
3423
 
        if(qual & LR_CTRLKEY) {
3424
 
                selectconnectedAll();
3425
 
                return;
3426
 
        }
3427
 
 
3428
 
        sel= 3;
3429
 
        if(qual & LR_SHIFTKEY) sel=2;
3430
 
        
3431
 
        act= findnearestvert(sel-2);
3432
 
        if(act==0) {
3433
 
                error(" Nothing indicated ");
3434
 
                return;
3435
 
        }
3436
 
        
3437
 
        undo_push_mesh("Select linked");
3438
 
        /* clear test flags */
3439
 
        eve= em->verts.first;
3440
 
        while(eve) {
3441
 
                eve->f&= ~2;
3442
 
                eve= eve->next;
3443
 
        }
3444
 
        act->f= (act->f & ~3) | sel;
3445
 
 
3446
 
        while(flag==1) {
3447
 
                flag= 0;
3448
 
                toggle++;
3449
 
                if(toggle & 1) eed= em->edges.first;
3450
 
                else eed= em->edges.last;
3451
 
                while(eed) {
3452
 
                        v1= eed->v1;
3453
 
                        v2= eed->v2;
3454
 
                        if(eed->h==0) {
3455
 
                                if(v1->f & 2) {
3456
 
                                        if( (v2->f & 2)==0 ) {
3457
 
                                                v2->f= (v2->f & ~3) | sel;
3458
 
                                                flag= 1;
3459
 
                                        }
3460
 
                                }
3461
 
                                else if(v2->f & 2) {
3462
 
                                        if( (v1->f & 2)==0 ) {
3463
 
                                                v1->f= (v1->f & ~3) | sel;
3464
 
                                                flag= 1;
3465
 
                                        }
3466
 
                                }
3467
 
                        }
3468
 
                        if(toggle & 1) eed= eed->next;
3469
 
                        else eed= eed->prev;
3470
 
                }
3471
 
        }
3472
 
        countall();
3473
 
        
3474
 
        allqueue(REDRAWVIEW3D, 0);
3475
 
}
3476
 
 
3477
 
 
3478
 
short extrudeflag(short flag,short type)
3479
 
{
3480
 
        /* when type=1 old extrusion faces are removed (for spin etc) */
3481
 
        /* all verts with (flag & 'flag'): extrude */
3482
 
        /* from old verts, 'flag' is cleared, in new ones it is set */
3483
 
        EditMesh *em = G.editMesh;
3484
 
        EditVert *eve, *v1, *v2, *v3, *v4, *nextve;
3485
 
        EditEdge *eed, *e1, *e2, *e3, *e4, *nexted;
3486
 
        EditVlak *evl, *evl2, *nextvl;
3487
 
        short sel=0, deloud= 0, smooth= 0;
3488
 
 
3489
 
        if(G.obedit==0 || get_mesh(G.obedit)==0) return 0;
3490
 
 
3491
 
        /* clear vert flag f1, we use this to detext a loose selected vertice */
3492
 
        eve= em->verts.first;
3493
 
        while(eve) {
3494
 
                if(eve->f & flag) eve->f1= 1;
3495
 
                else eve->f1= 0;
3496
 
                eve= eve->next;
3497
 
        }
3498
 
        /* clear edges counter flag, if selected we set it at 1 */
3499
 
        eed= em->edges.first;
3500
 
        while(eed) {
3501
 
                if( (eed->v1->f & flag) && (eed->v2->f & flag) ) {
3502
 
                        eed->f= 1;
3503
 
                        eed->v1->f1= 0;
3504
 
                        eed->v2->f1= 0;
3505
 
                }
3506
 
                else eed->f= 0;
3507
 
                
3508
 
                eed->f1= 1;             /* this indicates it is an 'old' edge (in this routine we make new ones) */
3509
 
                
3510
 
                eed= eed->next;
3511
 
        }
3512
 
 
3513
 
        /* we set a flag in all selected faces, and increase the associated edge counters */
3514
 
 
3515
 
        evl= em->faces.first;
3516
 
        while(evl) {
3517
 
                evl->f= 0;
3518
 
 
3519
 
                if (evl->flag & ME_SMOOTH) {
3520
 
                        if (vlakselectedOR(evl, 1)) smooth= 1;
3521
 
                }
3522
 
                
3523
 
                if(vlakselectedAND(evl, flag)) {
3524
 
                        e1= evl->e1;
3525
 
                        e2= evl->e2;
3526
 
                        e3= evl->e3;
3527
 
                        e4= evl->e4;
3528
 
 
3529
 
                        if(e1->f < 3) e1->f++;
3530
 
                        if(e2->f < 3) e2->f++;
3531
 
                        if(e3->f < 3) e3->f++;
3532
 
                        if(e4 && e4->f < 3) e4->f++;
3533
 
                        evl->f= 1;
3534
 
                }
3535
 
                else if(vlakselectedOR(evl, flag)) {
3536
 
                        e1= evl->e1;
3537
 
                        e2= evl->e2;
3538
 
                        e3= evl->e3;
3539
 
                        e4= evl->e4;
3540
 
                        
3541
 
                        if( (e1->v1->f & flag) && (e1->v2->f & flag) ) e1->f1= 2;
3542
 
                        if( (e2->v1->f & flag) && (e2->v2->f & flag) ) e2->f1= 2;
3543
 
                        if( (e3->v1->f & flag) && (e3->v2->f & flag) ) e3->f1= 2;
3544
 
                        if( e4 && (e4->v1->f & flag) && (e4->v2->f & flag) ) e4->f1= 2;
3545
 
                }
3546
 
                
3547
 
                evl= evl->next;
3548
 
        }
3549
 
 
3550
 
        /* set direction of edges */
3551
 
        evl= em->faces.first;
3552
 
        while(evl) {
3553
 
                if(evl->f== 0) {
3554
 
                        if(evl->e1->f==2) {
3555
 
                                if(evl->e1->v1 == evl->v1) evl->e1->dir= 0;
3556
 
                                else evl->e1->dir= 1;
3557
 
                        }
3558
 
                        if(evl->e2->f==2) {
3559
 
                                if(evl->e2->v1 == evl->v2) evl->e2->dir= 0;
3560
 
                                else evl->e2->dir= 1;
3561
 
                        }
3562
 
                        if(evl->e3->f==2) {
3563
 
                                if(evl->e3->v1 == evl->v3) evl->e3->dir= 0;
3564
 
                                else evl->e3->dir= 1;
3565
 
                        }
3566
 
                        if(evl->e4 && evl->e4->f==2) {
3567
 
                                if(evl->e4->v1 == evl->v4) evl->e4->dir= 0;
3568
 
                                else evl->e4->dir= 1;
3569
 
                        }
3570
 
                }
3571
 
                evl= evl->next;
3572
 
        }       
3573
 
 
3574
 
 
3575
 
        /* the current state now is:
3576
 
                eve->f1==1: loose selected vertex 
3577
 
 
3578
 
                eed->f==0 : edge is not selected, no extrude
3579
 
                eed->f==1 : edge selected, is not part of a face, extrude
3580
 
                eed->f==2 : edge selected, is part of 1 face, extrude
3581
 
                eed->f==3 : edge selected, is part of more faces, no extrude
3582
 
                
3583
 
                eed->f1==0: new edge
3584
 
                eed->f1==1: edge selected, is part of selected face, when eed->f==3: remove
3585
 
                eed->f1==2: edge selected, is not part of a selected face
3586
 
                                        
3587
 
                evl->f==1 : duplicate this face
3588
 
        */
3589
 
 
3590
 
        /* copy all selected vertices, */
3591
 
        /* write pointer to new vert in old struct at eve->vn */
3592
 
        eve= em->verts.last;
3593
 
        while(eve) {
3594
 
                eve->f&= ~128;  /* clear, for later test for loose verts */
3595
 
                if(eve->f & flag) {
3596
 
                        sel= 1;
3597
 
                        v1= addvertlist(0);
3598
 
                        
3599
 
                        VECCOPY(v1->co, eve->co);
3600
 
                        v1->f= eve->f;
3601
 
                        eve->f-= flag;
3602
 
                        eve->vn= v1;
3603
 
                }
3604
 
                else eve->vn= 0;
3605
 
                eve= eve->prev;
3606
 
        }
3607
 
 
3608
 
        if(sel==0) return 0;
3609
 
 
3610
 
        /* all edges with eed->f==1 or eed->f==2 become faces */
3611
 
        /* if deloud==1 then edges with eed->f>2 are removed */
3612
 
        eed= em->edges.last;
3613
 
        while(eed) {
3614
 
                nexted= eed->prev;
3615
 
                if( eed->f<3) {
3616
 
                        eed->v1->f|=128;  /* = no loose vert! */
3617
 
                        eed->v2->f|=128;
3618
 
                }
3619
 
                if( (eed->f==1 || eed->f==2) ) {
3620
 
                        if(eed->f1==2) deloud=1;
3621
 
                        
3622
 
                        if(eed->dir==1) evl2= addvlaklist(eed->v1, eed->v2, eed->v2->vn, eed->v1->vn, NULL);
3623
 
                        else evl2= addvlaklist(eed->v2, eed->v1, eed->v1->vn, eed->v2->vn, NULL);
3624
 
                        if (smooth) evl2->flag |= ME_SMOOTH;
3625
 
                }
3626
 
 
3627
 
                eed= nexted;
3628
 
        }
3629
 
        if(deloud) {
3630
 
                eed= em->edges.first;
3631
 
                while(eed) {
3632
 
                        nexted= eed->next;
3633
 
                        if(eed->f==3 && eed->f1==1) {
3634
 
                                remedge(eed);
3635
 
                                free_editedge(eed);
3636
 
                        }
3637
 
                        eed= nexted;
3638
 
                }
3639
 
        }
3640
 
        /* duplicate faces, if necessart remove old ones  */
3641
 
        evl= em->faces.first;
3642
 
        while(evl) {
3643
 
                nextvl= evl->next;
3644
 
                if(evl->f & 1) {
3645
 
                
3646
 
                        v1= evl->v1->vn;
3647
 
                        v2= evl->v2->vn;
3648
 
                        v3= evl->v3->vn;
3649
 
                        if(evl->v4) v4= evl->v4->vn; else v4= 0;
3650
 
                        
3651
 
                        evl2= addvlaklist(v1, v2, v3, v4, evl);
3652
 
                        
3653
 
                        if(deloud) {
3654
 
                                BLI_remlink(&em->faces, evl);
3655
 
                                free_editvlak(evl);
3656
 
                        }
3657
 
                        if (smooth) evl2->flag |= ME_SMOOTH;                    
3658
 
                }
3659
 
                evl= nextvl;
3660
 
        }
3661
 
        /* for all vertices with eve->vn!=0 
3662
 
                if eve->f1==1: make edge
3663
 
                if flag!=128 : if deloud==1: remove
3664
 
        */
3665
 
        eve= em->verts.last;
3666
 
        while(eve) {
3667
 
                nextve= eve->prev;
3668
 
                if(eve->vn) {
3669
 
                        if(eve->f1==1) addedgelist(eve,eve->vn);
3670
 
                        else if( (eve->f & 128)==0) {
3671
 
                                if(deloud) {
3672
 
                                        BLI_remlink(&em->verts,eve);
3673
 
                                        free_editvert(eve);
3674
 
                                        eve= NULL;
3675
 
                                }
3676
 
                        }
3677
 
                }
3678
 
                if(eve) eve->f&= ~128;
3679
 
                
3680
 
                eve= nextve;
3681
 
        }
3682
 
 
3683
 
        return 1;
3684
 
}
3685
 
 
3686
 
void rotateflag(short flag, float *cent, float rotmat[][3])
3687
 
{
3688
 
        /* all verts with (flag & 'flag') rotate */
3689
 
        EditMesh *em = G.editMesh;
3690
 
        EditVert *eve;
3691
 
 
3692
 
        eve= em->verts.first;
3693
 
        while(eve) {
3694
 
                if(eve->f & flag) {
3695
 
                        eve->co[0]-=cent[0];
3696
 
                        eve->co[1]-=cent[1];
3697
 
                        eve->co[2]-=cent[2];
3698
 
                        Mat3MulVecfl(rotmat,eve->co);
3699
 
                        eve->co[0]+=cent[0];
3700
 
                        eve->co[1]+=cent[1];
3701
 
                        eve->co[2]+=cent[2];
3702
 
                }
3703
 
                eve= eve->next;
3704
 
        }
3705
 
}
3706
 
 
3707
 
void translateflag(short flag, float *vec)
3708
 
{
3709
 
        /* all verts with (flag & 'flag') translate */
3710
 
        EditMesh *em = G.editMesh;
3711
 
        EditVert *eve;
3712
 
 
3713
 
        eve= em->verts.first;
3714
 
        while(eve) {
3715
 
                if(eve->f & flag) {
3716
 
                        eve->co[0]+=vec[0];
3717
 
                        eve->co[1]+=vec[1];
3718
 
                        eve->co[2]+=vec[2];
3719
 
                }
3720
 
                eve= eve->next;
3721
 
        }
3722
 
}
3723
 
 
3724
 
short removedoublesflag(short flag, float limit)                /* return amount */
3725
 
{
3726
 
        EditMesh *em = G.editMesh;
3727
 
        /* all verts with (flag & 'flag') are being evaluated */
3728
 
        EditVert *eve, *v1, *nextve;
3729
 
        EditEdge *eed, *e1, *nexted;
3730
 
        EditVlak *evl, *nextvl;
3731
 
        struct xvertsort *sortblock, *sb, *sb1;
3732
 
        struct vlaksort *vlsortblock, *vsb, *vsb1;
3733
 
        float dist;
3734
 
        int a, b, test, aantal;
3735
 
 
3736
 
        /* flag 128 is cleared, count */
3737
 
        eve= em->verts.first;
3738
 
        aantal= 0;
3739
 
        while(eve) {
3740
 
                eve->f&= ~128;
3741
 
                if(eve->f & flag) aantal++;
3742
 
                eve= eve->next;
3743
 
        }
3744
 
        if(aantal==0) return 0;
3745
 
 
3746
 
        /* allocate memory and qsort */
3747
 
        sb= sortblock= (struct xvertsort *)MEM_mallocN(sizeof(struct xvertsort)*aantal,"sortremovedoub");
3748
 
        eve= em->verts.first;
3749
 
        while(eve) {
3750
 
                if(eve->f & flag) {
3751
 
                        sb->x= eve->co[0]+eve->co[1]+eve->co[2];
3752
 
                        sb->v1= eve;
3753
 
                        sb++;
3754
 
                }
3755
 
                eve= eve->next;
3756
 
        }
3757
 
        qsort(sortblock, aantal, sizeof(struct xvertsort), vergxco);
3758
 
 
3759
 
        /* test for doubles */
3760
 
        sb= sortblock;
3761
 
        for(a=0; a<aantal; a++) {
3762
 
                eve= sb->v1;
3763
 
                if( (eve->f & 128)==0 ) {
3764
 
                        sb1= sb+1;
3765
 
                        for(b=a+1; b<aantal; b++) {
3766
 
                                /* first test: simpel dist */
3767
 
                                dist= sb1->x - sb->x;
3768
 
                                if(dist > limit) break;
3769
 
                                
3770
 
                                /* second test: is vertex allowed */
3771
 
                                v1= sb1->v1;
3772
 
                                if( (v1->f & 128)==0 ) {
3773
 
                                        
3774
 
                                        dist= fabs(v1->co[0]-eve->co[0]);
3775
 
                                        if(dist<=limit) {
3776
 
                                                dist= fabs(v1->co[1]-eve->co[1]);
3777
 
                                                if(dist<=limit) {
3778
 
                                                        dist= fabs(v1->co[2]-eve->co[2]);
3779
 
                                                        if(dist<=limit) {
3780
 
                                                                v1->f|= 128;
3781
 
                                                                v1->vn= eve;
3782
 
                                                        }
3783
 
                                                }
3784
 
                                        }
3785
 
                                }
3786
 
                                sb1++;
3787
 
                        }
3788
 
                }
3789
 
                sb++;
3790
 
        }
3791
 
        MEM_freeN(sortblock);
3792
 
 
3793
 
        /* test edges and insert again */
3794
 
        eed= em->edges.first;
3795
 
        while(eed) {
3796
 
                eed->f= 0;
3797
 
                eed= eed->next;
3798
 
        }
3799
 
        eed= em->edges.last;
3800
 
        while(eed) {
3801
 
                nexted= eed->prev;
3802
 
 
3803
 
                if(eed->f==0) {
3804
 
                        if( (eed->v1->f & 128) || (eed->v2->f & 128) ) {
3805
 
                                remedge(eed);
3806
 
 
3807
 
                                if(eed->v1->f & 128) eed->v1= eed->v1->vn;
3808
 
                                if(eed->v2->f & 128) eed->v2= eed->v2->vn;
3809
 
 
3810
 
                                e1= addedgelist(eed->v1,eed->v2);
3811
 
                                
3812
 
                                if(e1) e1->f= 1;
3813
 
                                if(e1!=eed) free_editedge(eed);
3814
 
                        }
3815
 
                }
3816
 
                eed= nexted;
3817
 
        }
3818
 
 
3819
 
        /* first count amount of test faces */
3820
 
        evl= (struct EditVlak *)em->faces.first;
3821
 
        aantal= 0;
3822
 
        while(evl) {
3823
 
                evl->f= 0;
3824
 
                if(evl->v1->f & 128) evl->f= 1;
3825
 
                else if(evl->v2->f & 128) evl->f= 1;
3826
 
                else if(evl->v3->f & 128) evl->f= 1;
3827
 
                else if(evl->v4 && (evl->v4->f & 128)) evl->f= 1;
3828
 
                
3829
 
                if(evl->f==1) aantal++;
3830
 
                evl= evl->next;
3831
 
        }
3832
 
 
3833
 
        /* test faces for double vertices, and if needed remove them */
3834
 
        evl= (struct EditVlak *)em->faces.first;
3835
 
        while(evl) {
3836
 
                nextvl= evl->next;
3837
 
                if(evl->f==1) {
3838
 
                        
3839
 
                        if(evl->v1->f & 128) evl->v1= evl->v1->vn;
3840
 
                        if(evl->v2->f & 128) evl->v2= evl->v2->vn;
3841
 
                        if(evl->v3->f & 128) evl->v3= evl->v3->vn;
3842
 
                        if(evl->v4 && (evl->v4->f & 128)) evl->v4= evl->v4->vn;
3843
 
                
3844
 
                        test= 0;
3845
 
                        if(evl->v1==evl->v2) test+=1;
3846
 
                        if(evl->v2==evl->v3) test+=2;
3847
 
                        if(evl->v3==evl->v1) test+=4;
3848
 
                        if(evl->v4==evl->v1) test+=8;
3849
 
                        if(evl->v3==evl->v4) test+=16;
3850
 
                        if(evl->v2==evl->v4) test+=32;
3851
 
                        
3852
 
                        if(test) {
3853
 
                                if(evl->v4) {
3854
 
                                        if(test==1 || test==2) {
3855
 
                                                evl->v2= evl->v3;
3856
 
                                                evl->v3= evl->v4;
3857
 
                                                evl->v4= 0;
3858
 
                                                test= 0;
3859
 
                                        }
3860
 
                                        else if(test==8 || test==16) {
3861
 
                                                evl->v4= 0;
3862
 
                                                test= 0;
3863
 
                                        }
3864
 
                                        else {
3865
 
                                                BLI_remlink(&em->faces, evl);
3866
 
                                                free_editvlak(evl);
3867
 
                                                aantal--;
3868
 
                                        }
3869
 
                                }
3870
 
                                else {
3871
 
                                        BLI_remlink(&em->faces, evl);
3872
 
                                        free_editvlak(evl);
3873
 
                                        aantal--;
3874
 
                                }
3875
 
                        }
3876
 
                        
3877
 
                        if(test==0) {
3878
 
                                /* set edge pointers */
3879
 
                                evl->e1= findedgelist(evl->v1, evl->v2);
3880
 
                                evl->e2= findedgelist(evl->v2, evl->v3);
3881
 
                                if(evl->v4==0) {
3882
 
                                        evl->e3= findedgelist(evl->v3, evl->v1);
3883
 
                                        evl->e4= 0;
3884
 
                                }
3885
 
                                else {
3886
 
                                        evl->e3= findedgelist(evl->v3, evl->v4);
3887
 
                                        evl->e4= findedgelist(evl->v4, evl->v1);
3888
 
                                }
3889
 
                        }
3890
 
                }
3891
 
                evl= nextvl;
3892
 
        }
3893
 
 
3894
 
        /* double faces: sort block */
3895
 
        /* count again, now all selected faces */
3896
 
        aantal= 0;
3897
 
        evl= em->faces.first;
3898
 
        while(evl) {
3899
 
                evl->f= 0;
3900
 
                if(vlakselectedAND(evl, 1)) {
3901
 
                        evl->f= 1;
3902
 
                        aantal++;
3903
 
                }
3904
 
                evl= evl->next;
3905
 
        }
3906
 
 
3907
 
        if(aantal) {
3908
 
                /* double faces: sort block */
3909
 
                vsb= vlsortblock= MEM_mallocN(sizeof(struct vlaksort)*aantal, "sortremovedoub");
3910
 
                evl= em->faces.first;
3911
 
                while(evl) {
3912
 
                        if(evl->f & 1) {
3913
 
                                if(evl->v4) vsb->x= (long) MIN4( (long)evl->v1, (long)evl->v2, (long)evl->v3, (long)evl->v4);
3914
 
                                else vsb->x= (long) MIN3( (long)evl->v1, (long)evl->v2, (long)evl->v3);
3915
 
 
3916
 
                                vsb->evl= evl;
3917
 
                                vsb++;
3918
 
                        }
3919
 
                        evl= evl->next;
3920
 
                }
3921
 
                
3922
 
                qsort(vlsortblock, aantal, sizeof(struct vlaksort), vergvlak);
3923
 
                        
3924
 
                vsb= vlsortblock;
3925
 
                for(a=0; a<aantal; a++) {
3926
 
                        evl= vsb->evl;
3927
 
                        if( (evl->f & 128)==0 ) {
3928
 
                                vsb1= vsb+1;
3929
 
 
3930
 
                                for(b=a+1; b<aantal; b++) {
3931
 
                                
3932
 
                                        /* first test: same pointer? */
3933
 
                                        if(vsb->x != vsb1->x) break;
3934
 
                                        
3935
 
                                        /* second test: is test permitted? */
3936
 
                                        evl= vsb1->evl;
3937
 
                                        if( (evl->f & 128)==0 ) {
3938
 
                                                if( comparevlak(evl, vsb->evl)) evl->f |= 128;
3939
 
                                                
3940
 
                                        }
3941
 
                                        vsb1++;
3942
 
                                }
3943
 
                        }
3944
 
                        vsb++;
3945
 
                }
3946
 
                
3947
 
                MEM_freeN(vlsortblock);
3948
 
                
3949
 
                /* remove double faces */
3950
 
                evl= (struct EditVlak *)em->faces.first;
3951
 
                while(evl) {
3952
 
                        nextvl= evl->next;
3953
 
                        if(evl->f & 128) {
3954
 
                                BLI_remlink(&em->faces, evl);
3955
 
                                free_editvlak(evl);
3956
 
                        }
3957
 
                        evl= nextvl;
3958
 
                }
3959
 
        }
3960
 
        
3961
 
        /* remove double vertices */
3962
 
        a= 0;
3963
 
        eve= (struct EditVert *)em->verts.first;
3964
 
        while(eve) {
3965
 
                nextve= eve->next;
3966
 
                if(eve->f & flag) {
3967
 
                        if(eve->f & 128) {
3968
 
                                a++;
3969
 
                                BLI_remlink(&em->verts, eve);
3970
 
                                free_editvert(eve);
3971
 
                        }
3972
 
                }
3973
 
                eve= nextve;
3974
 
        }
3975
 
        return a;       /* amount */
3976
 
}
3977
 
 
3978
 
void xsortvert_flag(int flag)
3979
 
{
3980
 
        EditMesh *em = G.editMesh;
3981
 
        /* all verts with (flag & 'flag') are sorted */
3982
 
        EditVert *eve;
3983
 
        struct xvertsort *sortblock, *sb;
3984
 
        ListBase tbase;
3985
 
        int aantal;
3986
 
        
3987
 
        /* count */
3988
 
        eve= em->verts.first;
3989
 
        aantal= 0;
3990
 
        while(eve) {
3991
 
                if(eve->f & flag) aantal++;
3992
 
                eve= eve->next;
3993
 
        }
3994
 
        if(aantal==0) return;
3995
 
 
3996
 
        undo_push_mesh("Xsort");
3997
 
        
3998
 
        /* allocate memory and sort */
3999
 
        sb= sortblock= (struct xvertsort *)MEM_mallocN(sizeof(struct xvertsort)*aantal,"sortremovedoub");
4000
 
        eve= em->verts.first;
4001
 
        while(eve) {
4002
 
                if(eve->f & flag) {
4003
 
                        sb->x= eve->xs;
4004
 
                        sb->v1= eve;
4005
 
                        sb++;
4006
 
                }
4007
 
                eve= eve->next;
4008
 
        }
4009
 
        qsort(sortblock, aantal, sizeof(struct xvertsort), vergxco);
4010
 
        
4011
 
        /* make temporal listbase */
4012
 
        tbase.first= tbase.last= 0;
4013
 
        sb= sortblock;
4014
 
        while(aantal--) {
4015
 
                eve= sb->v1;
4016
 
                BLI_remlink(&em->verts, eve);
4017
 
                BLI_addtail(&tbase, eve);
4018
 
                sb++;
4019
 
        }
4020
 
        
4021
 
        addlisttolist(&em->verts, &tbase);
4022
 
        
4023
 
        MEM_freeN(sortblock);
4024
 
}
4025
 
 
4026
 
 
4027
 
void hashvert_flag(int flag)
4028
 
{
4029
 
        /* switch vertex order using hash table */
4030
 
        EditMesh *em = G.editMesh;
4031
 
        EditVert *eve;
4032
 
        struct xvertsort *sortblock, *sb, onth, *newsort;
4033
 
        ListBase tbase;
4034
 
        int aantal, a, b;
4035
 
        
4036
 
        /* count */
4037
 
        eve= em->verts.first;
4038
 
        aantal= 0;
4039
 
        while(eve) {
4040
 
                if(eve->f & flag) aantal++;
4041
 
                eve= eve->next;
4042
 
        }
4043
 
        if(aantal==0) return;
4044
 
        
4045
 
        undo_push_mesh("Hash");
4046
 
 
4047
 
        /* allocate memory */
4048
 
        sb= sortblock= (struct xvertsort *)MEM_mallocN(sizeof(struct xvertsort)*aantal,"sortremovedoub");
4049
 
        eve= em->verts.first;
4050
 
        while(eve) {
4051
 
                if(eve->f & flag) {
4052
 
                        sb->v1= eve;
4053
 
                        sb++;
4054
 
                }
4055
 
                eve= eve->next;
4056
 
        }
4057
 
 
4058
 
        BLI_srand(1);
4059
 
        
4060
 
        sb= sortblock;
4061
 
        for(a=0; a<aantal; a++, sb++) {
4062
 
                b= aantal*BLI_drand();
4063
 
                if(b>=0 && b<aantal) {
4064
 
                        newsort= sortblock+b;
4065
 
                        onth= *sb;
4066
 
                        *sb= *newsort;
4067
 
                        *newsort= onth;
4068
 
                }
4069
 
        }
4070
 
 
4071
 
        /* make temporal listbase */
4072
 
        tbase.first= tbase.last= 0;
4073
 
        sb= sortblock;
4074
 
        while(aantal--) {
4075
 
                eve= sb->v1;
4076
 
                BLI_remlink(&em->verts, eve);
4077
 
                BLI_addtail(&tbase, eve);
4078
 
                sb++;
4079
 
        }
4080
 
        
4081
 
        addlisttolist(&em->verts, &tbase);
4082
 
        
4083
 
        MEM_freeN(sortblock);
4084
 
}
4085
 
 
4086
 
static unsigned int cpack_fact(unsigned int col1, unsigned int col2, float fact)
4087
 
{
4088
 
        char *cp1, *cp2, *cp;
4089
 
        unsigned int col=0;
4090
 
        float fact1;
4091
 
        
4092
 
        fact1=1-fact; /*result is fact% col1 and (1-fact) % col2 */
4093
 
                
4094
 
        cp1= (char *)&col1;
4095
 
        cp2= (char *)&col2;
4096
 
        cp=  (char *)&col;
4097
 
        
4098
 
        cp[0]= fact*cp1[0]+fact1*cp2[0];
4099
 
        cp[1]= fact*cp1[1]+fact1*cp2[1];
4100
 
        cp[2]= fact*cp1[2]+fact1*cp2[2];
4101
 
        cp[3]= fact*cp1[3]+fact1*cp2[3];
4102
 
        
4103
 
        return col;
4104
 
}
4105
 
 
4106
 
 
4107
 
static void uv_half(float *uv, float *uv1, float *uv2)
4108
 
{
4109
 
        uv[0]= (uv1[0]+uv2[0])/2.0;
4110
 
        uv[1]= (uv1[1]+uv2[1])/2.0;
4111
 
        
4112
 
}
4113
 
 
4114
 
static void uv_quart(float *uv, float *uv1)
4115
 
{
4116
 
        uv[0]= (uv1[0]+uv1[2]+uv1[4]+uv1[6])/4.0;
4117
 
        uv[1]= (uv1[1]+uv1[3]+uv1[5]+uv1[7])/4.0;
4118
 
}
4119
 
 
4120
 
static void set_wuv(int tot, EditVlak *evl, int v1, int v2, int v3, int v4)
4121
 
{
4122
 
        /* this weird function only to be used for subdivide, the 'w' in the name has no meaning! */
4123
 
        float *uv, uvo[4][2];
4124
 
        unsigned int *col, colo[4], col1, col2;
4125
 
        int a, v;
4126
 
                                                /* Numbers corespond to verts (corner points),  */
4127
 
                                                /* edge->vn's (center edges), the Center        */
4128
 
        memcpy(uvo, evl->tf.uv, sizeof(uvo));   /* And the quincunx points of a face            */
4129
 
        uv= evl->tf.uv[0];                            /* as shown here:                                 */
4130
 
                                                      /*           2         5          1   */
4131
 
        memcpy(colo, evl->tf.col, sizeof(colo));      /*               10         13        */
4132
 
        col= evl->tf.col;                             /*           6         9          8   */
4133
 
                                                  /*               11         12        */
4134
 
        if(tot==4) {                                  /*           3         7          4   */
4135
 
                for(a=0; a<4; a++, uv+=2, col++) {
4136
 
                        if(a==0) v= v1;
4137
 
                        else if(a==1) v= v2;
4138
 
                        else if(a==2) v= v3;
4139
 
                        else v= v4;
4140
 
                        
4141
 
                        if(a==3 && v4==0) break;
4142
 
                        
4143
 
                        if(v<=4) {
4144
 
                                uv[0]= uvo[v-1][0];
4145
 
                                uv[1]= uvo[v-1][1];
4146
 
                                *col= colo[v-1];
4147
 
                        }
4148
 
                        else if(v==8) {
4149
 
                                uv_half(uv, uvo[3], uvo[0]);
4150
 
                                *col= cpack_fact(colo[3], colo[0], 0.5);
4151
 
                        }
4152
 
                        else if(v==9) {
4153
 
                                uv_quart(uv, uvo[0]);
4154
 
                                col1= cpack_fact(colo[1], colo[0], 0.5);
4155
 
                                col2= cpack_fact(colo[2], colo[3], 0.5);
4156
 
                                *col= cpack_fact(col1, col2, 0.5);
4157
 
                        }
4158
 
                        /* Cases for adjacent edge square subdivide  Real voodoo */
4159
 
                        /* 1/2 closest corner + 1/4 adjacent corners */
4160
 
                        else if (v==10){ /* case test==3 in subdivideflag() */  
4161
 
                                uv[0]=(2*uvo[1][0]+uvo[0][0]+uvo[2][0])/4;
4162
 
                                uv[1]=(2*uvo[1][1]+uvo[0][1]+uvo[2][1])/4;
4163
 
                                col1= cpack_fact(colo[1], colo[0], 0.75);
4164
 
                                col2= cpack_fact(colo[2], colo[3], 0.75);
4165
 
                                *col= cpack_fact(col1, col2, 0.75);     
4166
 
                        }
4167
 
                        else if (v==11) { /* case of test==6 */
4168
 
                                uv[0]=(2*uvo[2][0]+uvo[1][0]+uvo[3][0])/4;
4169
 
                                uv[1]=(2*uvo[2][1]+uvo[1][1]+uvo[3][1])/4;
4170
 
                                col1= cpack_fact(colo[1], colo[0], 0.75);
4171
 
                                col2= cpack_fact(colo[2], colo[3], 0.75);
4172
 
                                *col= cpack_fact(col1, col2, 0.25);     
4173
 
                        }
4174
 
                        else if (v==12) { /* case of test==12 */
4175
 
                                uv[0]=(2*uvo[3][0]+uvo[2][0]+uvo[0][0])/4;
4176
 
                                uv[1]=(2*uvo[3][1]+uvo[2][1]+uvo[0][1])/4;
4177
 
                                col1= cpack_fact(colo[1], colo[0], 0.25);
4178
 
                                col2= cpack_fact(colo[2], colo[3], 0.25);
4179
 
                                *col= cpack_fact(col1, col2, 0.25);
4180
 
                        }
4181
 
                        else if (v==13) { /* case of test==9 */
4182
 
                                uv[0]=(2*uvo[0][0]+uvo[1][0]+uvo[3][0])/4;
4183
 
                                uv[1]=(2*uvo[0][1]+uvo[1][1]+uvo[3][1])/4;
4184
 
                                col1= cpack_fact(colo[1], colo[0], 0.25);
4185
 
                                col2= cpack_fact(colo[2], colo[3], 0.25);
4186
 
                                *col= cpack_fact(col1, col2, 0.75);
4187
 
                        }
4188
 
                        /* default for consecutive verts*/
4189
 
                        else { 
4190
 
                                uv_half(uv, uvo[v-5], uvo[v-4]);
4191
 
                                *col= cpack_fact(colo[v-5], colo[v-4], 0.5);
4192
 
                        }
4193
 
                }
4194
 
        }
4195
 
        else {
4196
 
                for(a=0; a<3; a++, uv+=2, col++) {
4197
 
                        if(a==0) v= v1;
4198
 
                        else if(a==1) v= v2;
4199
 
                        else v= v3;
4200
 
                
4201
 
                        if(v<=4) {
4202
 
                                uv[0]= uvo[v-1][0];
4203
 
                                uv[1]= uvo[v-1][1];
4204
 
                                *col= colo[v-1];
4205
 
                        }
4206
 
                        else if(v==7) {
4207
 
                                uv_half(uv, uvo[2], uvo[0]);
4208
 
                                *col= cpack_fact(colo[2], colo[0], 0.5);
4209
 
                        }
4210
 
                        else {
4211
 
                                uv_half(uv, uvo[v-5], uvo[v-4]);
4212
 
                                *col= cpack_fact(colo[v-5], colo[v-4], 0.5);
4213
 
                        }
4214
 
                }
4215
 
        }
4216
 
}
4217
 
 
4218
 
static EditVert *vert_from_number(EditVlak *evl, int nr)
4219
 
{
4220
 
        switch(nr) {
4221
 
        case 0:
4222
 
                return 0;
4223
 
        case 1:
4224
 
                return evl->v1;
4225
 
        case 2:
4226
 
                return evl->v2;
4227
 
        case 3:
4228
 
                return evl->v3;
4229
 
        case 4:
4230
 
                return evl->v4;
4231
 
        case 5:
4232
 
                return evl->e1->vn;
4233
 
        case 6:
4234
 
                return evl->e2->vn;
4235
 
        case 7:
4236
 
                return evl->e3->vn;
4237
 
        case 8:
4238
 
                return evl->e4->vn;
4239
 
        }
4240
 
        
4241
 
        return NULL;
4242
 
}
4243
 
 
4244
 
static void addvlak_subdiv(EditVlak *evl, int val1, int val2, int val3, int val4, EditVert *eve)
4245
 
{
4246
 
        EditVlak *w;
4247
 
        EditVert *v1, *v2, *v3, *v4;
4248
 
        
4249
 
        if(val1>=9) v1= eve;
4250
 
        else v1= vert_from_number(evl, val1);
4251
 
        
4252
 
        if(val2>=9) v2= eve;
4253
 
        else v2= vert_from_number(evl, val2);
4254
 
 
4255
 
        if(val3>=9) v3= eve;
4256
 
        else v3= vert_from_number(evl, val3);
4257
 
 
4258
 
        if(val4>=9) v4= eve;
4259
 
        else v4= vert_from_number(evl, val4);
4260
 
        
4261
 
        w= addvlaklist(v1, v2, v3, v4, evl);
4262
 
        if(w) {
4263
 
                if(evl->v4) set_wuv(4, w, val1, val2, val3, val4);
4264
 
                else set_wuv(3, w, val1, val2, val3, val4);
4265
 
        }
4266
 
}
4267
 
 
4268
 
static float smoothperc= 0.0;
4269
 
 
4270
 
static void smooth_subdiv_vec(float *v1, float *v2, float *n1, float *n2, float *vec)
4271
 
{
4272
 
        float len, fac, nor[3], nor1[3], nor2[3];
4273
 
        
4274
 
        VecSubf(nor, v1, v2);
4275
 
        len= 0.5*Normalise(nor);
4276
 
 
4277
 
        VECCOPY(nor1, n1);
4278
 
        VECCOPY(nor2, n2);
4279
 
 
4280
 
        /* cosine angle */
4281
 
        fac= nor[0]*nor1[0] + nor[1]*nor1[1] + nor[2]*nor1[2] ;
4282
 
        
4283
 
        vec[0]= fac*nor1[0];
4284
 
        vec[1]= fac*nor1[1];
4285
 
        vec[2]= fac*nor1[2];
4286
 
 
4287
 
        /* cosine angle */
4288
 
        fac= -nor[0]*nor2[0] - nor[1]*nor2[1] - nor[2]*nor2[2] ;
4289
 
        
4290
 
        vec[0]+= fac*nor2[0];
4291
 
        vec[1]+= fac*nor2[1];
4292
 
        vec[2]+= fac*nor2[2];
4293
 
 
4294
 
        vec[0]*= smoothperc*len;
4295
 
        vec[1]*= smoothperc*len;
4296
 
        vec[2]*= smoothperc*len;
4297
 
}
4298
 
 
4299
 
static void smooth_subdiv_quad(EditVlak *evl, float *vec)
4300
 
{
4301
 
        
4302
 
        float nor1[3], nor2[3];
4303
 
        float vec1[3], vec2[3];
4304
 
        float cent[3];
4305
 
        
4306
 
        /* vlr->e1->vn is new vertex inbetween v1 / v2 */
4307
 
        
4308
 
        VecMidf(nor1, evl->v1->no, evl->v2->no);
4309
 
        Normalise(nor1);
4310
 
        VecMidf(nor2, evl->v3->no, evl->v4->no);
4311
 
        Normalise(nor2);
4312
 
 
4313
 
        smooth_subdiv_vec( evl->e1->vn->co, evl->e3->vn->co, nor1, nor2, vec1);
4314
 
 
4315
 
        VecMidf(nor1, evl->v2->no, evl->v3->no);
4316
 
        Normalise(nor1);
4317
 
        VecMidf(nor2, evl->v4->no, evl->v1->no);
4318
 
        Normalise(nor2);
4319
 
 
4320
 
        smooth_subdiv_vec( evl->e2->vn->co, evl->e4->vn->co, nor1, nor2, vec2);
4321
 
 
4322
 
        VecAddf(vec1, vec1, vec2);
4323
 
 
4324
 
        CalcCent4f(cent, evl->v1->co,  evl->v2->co,  evl->v3->co,  evl->v4->co);
4325
 
        VecAddf(vec, cent, vec1);
4326
 
}
4327
 
 
4328
 
void subdivideflag(int flag, float rad, int beauty)
4329
 
{
4330
 
        EditMesh *em = G.editMesh;
4331
 
        /* subdivide all with (vertflag & flag) */
4332
 
        /* if rad>0.0 it's a 'sphere' subdivide */
4333
 
        /* if rad<0.0 it's a fractal subdivide */
4334
 
        extern float doublimit;
4335
 
        EditVert *eve;
4336
 
        EditEdge *eed, *e1, *e2, *e3, *e4, *nexted;
4337
 
        EditVlak *evl;
4338
 
        float fac, vec[3], vec1[3], len1, len2, len3, percent;
4339
 
        short test;
4340
 
        
4341
 
        if(beauty & B_SMOOTH) {
4342
 
                short perc= 100;
4343
 
 
4344
 
                if(button(&perc, 10, 500, "Percentage:")==0) return;
4345
 
                
4346
 
                smoothperc= 0.292*perc/100.0;
4347
 
        }
4348
 
 
4349
 
        /* edgeflags */
4350
 
        eed= em->edges.first;
4351
 
        while((eed) && !(beauty & B_KNIFE)) {   
4352
 
                if( (eed->v1->f & flag) && (eed->v2->f & flag) ) eed->f= flag;
4353
 
                else eed->f= 0; 
4354
 
                eed= eed->next;
4355
 
        }
4356
 
        
4357
 
        /* if beauty: test for area and clear edge flags of 'ugly' edges */
4358
 
        if(beauty & B_BEAUTY) {
4359
 
                evl= em->faces.first;
4360
 
                while(evl) {
4361
 
                        if( vlakselectedAND(evl, flag) ) {
4362
 
                                if(evl->v4) {
4363
 
                                
4364
 
                                        /* area */
4365
 
                                        len1= AreaQ3Dfl(evl->v1->co, evl->v2->co, evl->v3->co, evl->v4->co);
4366
 
                                        if(len1 <= doublimit) {
4367
 
                                                evl->e1->f = 0;
4368
 
                                                evl->e2->f = 0;
4369
 
                                                evl->e3->f = 0;
4370
 
                                                evl->e4->f = 0;
4371
 
                                        }
4372
 
                                        else {
4373
 
                                                len1= VecLenf(evl->v1->co, evl->v2->co) + VecLenf(evl->v3->co, evl->v4->co);
4374
 
                                                len2= VecLenf(evl->v2->co, evl->v3->co) + VecLenf(evl->v1->co, evl->v4->co);
4375
 
                                                
4376
 
                                                if(len1 < len2) {
4377
 
                                                        evl->e1->f = 0;
4378
 
                                                        evl->e3->f = 0;
4379
 
                                                }
4380
 
                                                else if(len1 > len2) {
4381
 
                                                        evl->e2->f = 0;
4382
 
                                                        evl->e4->f = 0;
4383
 
                                                }
4384
 
                                        }
4385
 
                                }
4386
 
                                else {
4387
 
                                        /* area */
4388
 
                                        len1= AreaT3Dfl(evl->v1->co, evl->v2->co, evl->v3->co);
4389
 
                                        if(len1 <= doublimit) {
4390
 
                                                evl->e1->f = 0;
4391
 
                                                evl->e2->f = 0;
4392
 
                                                evl->e3->f = 0;
4393
 
                                        }
4394
 
                                        else {
4395
 
                                                len1= VecLenf(evl->v1->co, evl->v2->co) ;
4396
 
                                                len2= VecLenf(evl->v2->co, evl->v3->co) ;
4397
 
                                                len3= VecLenf(evl->v3->co, evl->v1->co) ;
4398
 
                                                
4399
 
                                                if(len1<len2 && len1<len3) {
4400
 
                                                        evl->e1->f = 0;
4401
 
                                                }
4402
 
                                                else if(len2<len3 && len2<len1) {
4403
 
                                                        evl->e2->f = 0;
4404
 
                                                }
4405
 
                                                else if(len3<len2 && len3<len1) {
4406
 
                                                        evl->e3->f = 0;
4407
 
                                                }
4408
 
                                        }
4409
 
                                }
4410
 
                        }
4411
 
                        evl= evl->next;
4412
 
                }
4413
 
        }
4414
 
 
4415
 
        if(beauty & B_SMOOTH) {
4416
 
                
4417
 
                vertexnormals(0);               /* no1*/
4418
 
                        
4419
 
        }
4420
 
        
4421
 
        /* make new normal and put in edge, clear flag! needed for face creation part below */
4422
 
        eed= em->edges.first;
4423
 
        while(eed) {
4424
 
                if(eed->f & flag) {
4425
 
                        /* Subdivide percentage is stored in 1/32768ths in eed->f1 */
4426
 
                        if (beauty & B_PERCENTSUBD) percent=(float)(eed->f1)/32768.0;
4427
 
                        else percent=0.5;
4428
 
                        
4429
 
                        vec[0]= (1-percent)*eed->v1->co[0] + percent*eed->v2->co[0];
4430
 
                        vec[1]= (1-percent)*eed->v1->co[1] + percent*eed->v2->co[1];
4431
 
                        vec[2]= (1-percent)*eed->v1->co[2] + percent*eed->v2->co[2];
4432
 
 
4433
 
                        if(rad > 0.0) {   /* subdivide sphere */
4434
 
                                Normalise(vec);
4435
 
                                vec[0]*= rad;
4436
 
                                vec[1]*= rad;
4437
 
                                vec[2]*= rad;
4438
 
                        }
4439
 
                        else if(rad< 0.0) {  /* fractal subdivide */
4440
 
                                fac= rad* VecLenf(eed->v1->co, eed->v2->co);
4441
 
                                vec1[0]= fac*BLI_drand();
4442
 
                                vec1[1]= fac*BLI_drand();
4443
 
                                vec1[2]= fac*BLI_drand();
4444
 
                                VecAddf(vec, vec, vec1);
4445
 
                        }
4446
 
                        
4447
 
                        if(beauty & B_SMOOTH) {
4448
 
                                smooth_subdiv_vec(eed->v1->co, eed->v2->co, eed->v1->no, eed->v2->no, vec1);
4449
 
                                VecAddf(vec, vec, vec1);
4450
 
                        }
4451
 
                        
4452
 
                        eed->vn= addvertlist(vec);
4453
 
                        eed->vn->f= eed->v1->f;
4454
 
 
4455
 
                }
4456
 
                else eed->vn= 0;
4457
 
                
4458
 
                eed->f= 0; /* needed! */
4459
 
                
4460
 
                eed= eed->next;
4461
 
        }
4462
 
 
4463
 
        /* test all faces for subdivide edges, there are 8 or 16 cases (ugh)! */
4464
 
 
4465
 
        evl= em->faces.last;
4466
 
        while(evl) {
4467
 
                if( vlakselectedOR(evl, flag) ) {
4468
 
                        e1= evl->e1;
4469
 
                        e2= evl->e2;
4470
 
                        e3= evl->e3;
4471
 
                        e4= evl->e4;
4472
 
 
4473
 
                        test= 0;
4474
 
                        if(e1 && e1->vn) { 
4475
 
                                test+= 1; 
4476
 
                                e1->f= 1;
4477
 
                        }
4478
 
                        if(e2 && e2->vn) { 
4479
 
                                test+= 2; 
4480
 
                                e2->f= 1;
4481
 
                        }
4482
 
                        if(e3 && e3->vn) { 
4483
 
                                test+= 4; 
4484
 
                                e3->f= 1;
4485
 
                        }
4486
 
                        if(e4 && e4->vn) { 
4487
 
                                test+= 8; 
4488
 
                                e4->f= 1;
4489
 
                        }
4490
 
                        if(test) {
4491
 
                                if(evl->v4==0) {  /* All the permutations of 3 edges*/
4492
 
                                        if((test & 3)==3) addvlak_subdiv(evl, 2, 2+4, 1+4, 0, 0);
4493
 
                                        if((test & 6)==6) addvlak_subdiv(evl, 3, 3+4, 2+4, 0, 0);
4494
 
                                        if((test & 5)==5) addvlak_subdiv(evl, 1, 1+4, 3+4, 0, 0);
4495
 
 
4496
 
                                        if(test==7) {  /* four new faces, old face renews */
4497
 
                                                evl->v1= e1->vn;
4498
 
                                                evl->v2= e2->vn;
4499
 
                                                evl->v3= e3->vn;
4500
 
                                                set_wuv(3, evl, 1+4, 2+4, 3+4, 0);
4501
 
                                        }
4502
 
                                        else if(test==3) {
4503
 
                                                addvlak_subdiv(evl, 1+4, 2+4, 3, 0, 0);
4504
 
                                                evl->v2= e1->vn;
4505
 
                                                set_wuv(3, evl, 1, 1+4, 3, 0);
4506
 
                                        }
4507
 
                                        else if(test==6) {
4508
 
                                                addvlak_subdiv(evl, 2+4, 3+4, 1, 0, 0);
4509
 
                                                evl->v3= e2->vn;
4510
 
                                                set_wuv(3, evl, 1, 2, 2+4, 0);
4511
 
                                        }
4512
 
                                        else if(test==5) {
4513
 
                                                addvlak_subdiv(evl, 3+4, 1+4, 2, 0, 0);
4514
 
                                                evl->v1= e3->vn;
4515
 
                                                set_wuv(3, evl, 3+4, 2, 3, 0);
4516
 
                                        }
4517
 
                                        else if(test==1) {
4518
 
                                                addvlak_subdiv(evl, 1+4, 2, 3, 0, 0);
4519
 
                                                evl->v2= e1->vn;
4520
 
                                                set_wuv(3, evl, 1, 1+4, 3, 0);
4521
 
                                        }
4522
 
                                        else if(test==2) {
4523
 
                                                addvlak_subdiv(evl, 2+4, 3, 1, 0, 0);
4524
 
                                                evl->v3= e2->vn;
4525
 
                                                set_wuv(3, evl, 1, 2, 2+4, 0);
4526
 
                                        }
4527
 
                                        else if(test==4) {
4528
 
                                                addvlak_subdiv(evl, 3+4, 1, 2, 0, 0);
4529
 
                                                evl->v1= e3->vn;
4530
 
                                                set_wuv(3, evl, 3+4, 2, 3, 0);
4531
 
                                        }
4532
 
                                        evl->e1= addedgelist(evl->v1, evl->v2);
4533
 
                                        evl->e2= addedgelist(evl->v2, evl->v3);
4534
 
                                        evl->e3= addedgelist(evl->v3, evl->v1);
4535
 
                                        
4536
 
                                }
4537
 
                                else {  /* All the permutations of 4 faces */
4538
 
                                        if(test==15) {
4539
 
                                                /* add a new point in center */
4540
 
                                                CalcCent4f(vec, evl->v1->co, evl->v2->co, evl->v3->co, evl->v4->co);
4541
 
                                                
4542
 
                                                if(beauty & B_SMOOTH) {
4543
 
                                                        smooth_subdiv_quad(evl, vec);   /* adds */
4544
 
                                                }
4545
 
                                                eve= addvertlist(vec);
4546
 
                                                
4547
 
                                                eve->f |= flag;
4548
 
                                                
4549
 
                                                addvlak_subdiv(evl, 2, 2+4, 9, 1+4, eve);
4550
 
                                                addvlak_subdiv(evl, 3, 3+4, 9, 2+4, eve);
4551
 
                                                addvlak_subdiv(evl, 4, 4+4, 9, 3+4, eve);
4552
 
 
4553
 
                                                evl->v2= e1->vn;
4554
 
                                                evl->v3= eve;
4555
 
                                                evl->v4= e4->vn;
4556
 
                                                set_wuv(4, evl, 1, 1+4, 9, 4+4);
4557
 
                                        }
4558
 
                                        else { 
4559
 
                                                if(((test & 3)==3)&&(test!=3)) addvlak_subdiv(evl, 1+4, 2, 2+4, 0, 0);
4560
 
                                                if(((test & 6)==6)&&(test!=6)) addvlak_subdiv(evl, 2+4, 3, 3+4, 0, 0);
4561
 
                                                if(((test & 12)==12)&&(test!=12)) addvlak_subdiv(evl, 3+4, 4, 4+4, 0, 0);
4562
 
                                                if(((test & 9)==9)&&(test!=9)) addvlak_subdiv(evl, 4+4, 1, 1+4, 0, 0);
4563
 
                                                
4564
 
                                                if(test==1) { /* Edge 1 has new vert */
4565
 
                                                        addvlak_subdiv(evl, 1+4, 2, 3, 0, 0);
4566
 
                                                        addvlak_subdiv(evl, 1+4, 3, 4, 0, 0);
4567
 
                                                        evl->v2= e1->vn;
4568
 
                                                        evl->v3= evl->v4;
4569
 
                                                        evl->v4= 0;
4570
 
                                                        set_wuv(4, evl, 1, 1+4, 4, 0);
4571
 
                                                }
4572
 
                                                else if(test==2) { /* Edge 2 has new vert */
4573
 
                                                        addvlak_subdiv(evl, 2+4, 3, 4, 0, 0);
4574
 
                                                        addvlak_subdiv(evl, 2+4, 4, 1, 0, 0);
4575
 
                                                        evl->v3= e2->vn;
4576
 
                                                        evl->v4= 0;
4577
 
                                                        set_wuv(4, evl, 1, 2, 2+4, 0);
4578
 
                                                }
4579
 
                                                else if(test==4) { /* Edge 3 has new vert */
4580
 
                                                        addvlak_subdiv(evl, 3+4, 4, 1, 0, 0);
4581
 
                                                        addvlak_subdiv(evl, 3+4, 1, 2, 0, 0);
4582
 
                                                        evl->v1= evl->v2;
4583
 
                                                        evl->v2= evl->v3;
4584
 
                                                        evl->v3= e3->vn;
4585
 
                                                        evl->v4= 0;
4586
 
                                                        set_wuv(4, evl, 2, 3, 3+4, 0);
4587
 
                                                }
4588
 
                                                else if(test==8) { /* Edge 4 has new vert */
4589
 
                                                        addvlak_subdiv(evl, 4+4, 1, 2, 0, 0);
4590
 
                                                        addvlak_subdiv(evl, 4+4, 2, 3, 0, 0);
4591
 
                                                        evl->v1= evl->v3;
4592
 
                                                        evl->v2= evl->v4;
4593
 
                                                        evl->v3= e4->vn;
4594
 
                                                        evl->v4= 0;
4595
 
                                                        set_wuv(4, evl, 3, 4, 4+4, 0);
4596
 
                                                }
4597
 
                                                else if(test==3) { /*edge 1&2 */
4598
 
                                                        /* make new vert in center of new edge */       
4599
 
                                                        vec[0]=(e1->vn->co[0]+e2->vn->co[0])/2;
4600
 
                                                        vec[1]=(e1->vn->co[1]+e2->vn->co[1])/2;
4601
 
                                                        vec[2]=(e1->vn->co[2]+e2->vn->co[2])/2;
4602
 
                                                        eve= addvertlist(vec);
4603
 
                                                        eve->f |= flag;
4604
 
                                                        /* Add new faces */
4605
 
                                                        addvlak_subdiv(evl, 4, 10, 2+4, 3, eve);
4606
 
                                                        addvlak_subdiv(evl, 4, 1, 1+4, 10, eve);        
4607
 
                                                        /* orig face becomes small corner */
4608
 
                                                        evl->v1=e1->vn;
4609
 
                                                        //evl->v2=evl->v2;
4610
 
                                                        evl->v3=e2->vn;
4611
 
                                                        evl->v4=eve;
4612
 
                                                        
4613
 
                                                        set_wuv(4, evl, 1+4, 2, 2+4, 10);
4614
 
                                                }
4615
 
                                                else if(test==6) { /* 2&3 */
4616
 
                                                        /* make new vert in center of new edge */       
4617
 
                                                        vec[0]=(e2->vn->co[0]+e3->vn->co[0])/2;
4618
 
                                                        vec[1]=(e2->vn->co[1]+e3->vn->co[1])/2;
4619
 
                                                        vec[2]=(e2->vn->co[2]+e3->vn->co[2])/2;
4620
 
                                                        eve= addvertlist(vec);
4621
 
                                                        eve->f |= flag;
4622
 
                                                        /*New faces*/
4623
 
                                                        addvlak_subdiv(evl, 1, 11, 3+4, 4, eve);
4624
 
                                                        addvlak_subdiv(evl, 1, 2, 2+4, 11, eve);
4625
 
                                                        /* orig face becomes small corner */
4626
 
                                                        evl->v1=e2->vn;
4627
 
                                                        evl->v2=evl->v3;
4628
 
                                                        evl->v3=e3->vn;
4629
 
                                                        evl->v4=eve;
4630
 
                                                        
4631
 
                                                        set_wuv(4, evl, 2+4, 3, 3+4, 11);
4632
 
                                                }
4633
 
                                                else if(test==12) { /* 3&4 */
4634
 
                                                        /* make new vert in center of new edge */       
4635
 
                                                        vec[0]=(e3->vn->co[0]+e4->vn->co[0])/2;
4636
 
                                                        vec[1]=(e3->vn->co[1]+e4->vn->co[1])/2;
4637
 
                                                        vec[2]=(e3->vn->co[2]+e4->vn->co[2])/2;
4638
 
                                                        eve= addvertlist(vec);
4639
 
                                                        eve->f |= flag;
4640
 
                                                        /*New Faces*/
4641
 
                                                        addvlak_subdiv(evl, 2, 12, 4+4, 1, eve);
4642
 
                                                        addvlak_subdiv(evl, 2, 3, 3+4, 12, eve); 
4643
 
                                                        /* orig face becomes small corner */
4644
 
                                                        evl->v1=e3->vn;
4645
 
                                                        evl->v2=evl->v4;
4646
 
                                                        evl->v3=e4->vn;
4647
 
                                                        evl->v4=eve;
4648
 
                                                        
4649
 
                                                        set_wuv(4, evl, 3+4, 4, 4+4, 12);
4650
 
                                                }
4651
 
                                                else if(test==9) { /* 4&1 */
4652
 
                                                        /* make new vert in center of new edge */       
4653
 
                                                        vec[0]=(e1->vn->co[0]+e4->vn->co[0])/2;
4654
 
                                                        vec[1]=(e1->vn->co[1]+e4->vn->co[1])/2;
4655
 
                                                        vec[2]=(e1->vn->co[2]+e4->vn->co[2])/2;
4656
 
                                                        eve= addvertlist(vec);
4657
 
                                                        eve->f |= flag;
4658
 
                                                        /*New Faces*/
4659
 
                                                        addvlak_subdiv(evl, 3, 13, 1+4, 2, eve);
4660
 
                                                        addvlak_subdiv(evl, 3, 4,  4+4, 13, eve);
4661
 
                                                        /* orig face becomes small corner */
4662
 
                                                        evl->v2=evl->v1;
4663
 
                                                        evl->v1=e4->vn;
4664
 
                                                        evl->v3=e1->vn;
4665
 
                                                        evl->v4=eve;
4666
 
                                                        
4667
 
                                                        set_wuv(4, evl, 4+4, 1, 1+4, 13);
4668
 
                                                }
4669
 
                                                else if(test==5) { /* 1&3 */
4670
 
                                                        addvlak_subdiv(evl, 1+4, 2, 3, 3+4, 0);
4671
 
                                                        evl->v2= e1->vn;
4672
 
                                                        evl->v3= e3->vn;
4673
 
                                                        set_wuv(4, evl, 1, 1+4, 3+4, 4);
4674
 
                                                }
4675
 
                                                else if(test==10) { /* 2&4 */
4676
 
                                                        addvlak_subdiv(evl, 2+4, 3, 4, 4+4, 0);
4677
 
                                                        evl->v3= e2->vn;
4678
 
                                                        evl->v4= e4->vn;
4679
 
                                                        set_wuv(4, evl, 1, 2, 2+4, 4+4);
4680
 
                                                }/* Unfortunately, there is no way to avoid tris on 1 or 3 edges*/
4681
 
                                                else if(test==7) { /*1,2&3 */
4682
 
                                                        addvlak_subdiv(evl, 1+4, 2+4, 3+4, 0, 0);
4683
 
                                                        evl->v2= e1->vn;
4684
 
                                                        evl->v3= e3->vn;
4685
 
                                                        set_wuv(4, evl, 1, 1+4, 3+4, 4);
4686
 
                                                }
4687
 
                                                
4688
 
                                                else if(test==14) { /* 2,3&4 */
4689
 
                                                        addvlak_subdiv(evl, 2+4, 3+4, 4+4, 0, 0);
4690
 
                                                        evl->v3= e2->vn;
4691
 
                                                        evl->v4= e4->vn;
4692
 
                                                        set_wuv(4, evl, 1, 2, 2+4, 4+4);
4693
 
                                                }
4694
 
                                                else if(test==13) {/* 1,3&4 */
4695
 
                                                        addvlak_subdiv(evl, 3+4, 4+4, 1+4, 0, 0);
4696
 
                                                        evl->v4= e3->vn;
4697
 
                                                        evl->v1= e1->vn;
4698
 
                                                        set_wuv(4, evl, 1+4, 3, 3, 3+4);
4699
 
                                                }
4700
 
                                                else if(test==11) { /* 1,2,&4 */
4701
 
                                                        addvlak_subdiv(evl, 4+4, 1+4, 2+4, 0, 0);
4702
 
                                                        evl->v1= e4->vn;
4703
 
                                                        evl->v2= e2->vn;
4704
 
                                                        set_wuv(4, evl, 4+4, 2+4, 3, 4);
4705
 
                                                }
4706
 
                                        }
4707
 
                                        evl->e1= addedgelist(evl->v1, evl->v2);
4708
 
                                        evl->e2= addedgelist(evl->v2, evl->v3);                                 
4709
 
                                        if(evl->v4) evl->e3= addedgelist(evl->v3, evl->v4);
4710
 
                                        else evl->e3= addedgelist(evl->v3, evl->v1);
4711
 
                                        if(evl->v4) evl->e4= addedgelist(evl->v4, evl->v1);
4712
 
                                        else evl->e4= 0;
4713
 
                                }
4714
 
                        }
4715
 
                }
4716
 
                evl= evl->prev;
4717
 
        }
4718
 
 
4719
 
        /* remove all old edges, if needed make new ones */
4720
 
        eed= em->edges.first;
4721
 
        while(eed) {
4722
 
                nexted= eed->next;
4723
 
                if( eed->vn ) {
4724
 
                        eed->vn->f |= 16;                       
4725
 
                        if(eed->f==0) {  /* not used in face */                         
4726
 
                                addedgelist(eed->v1,eed->vn);
4727
 
                                addedgelist(eed->vn,eed->v2);
4728
 
                        }                                               
4729
 
                        remedge(eed);
4730
 
                        free_editedge(eed);
4731
 
                }
4732
 
                eed= nexted;
4733
 
        }
4734
 
        countall();
4735
 
        allqueue(REDRAWVIEW3D, 0);
4736
 
        makeDispList(G.obedit);
4737
 
}
4738
 
 
4739
 
void adduplicateflag(int flag)
4740
 
{
4741
 
        EditMesh *em = G.editMesh;
4742
 
        /* old verts have flag 128 set, and flag 'flag' cleared
4743
 
           new verts have flag 'flag' set */
4744
 
        EditVert *eve, *v1, *v2, *v3, *v4;
4745
 
        EditEdge *eed;
4746
 
        EditVlak *evl;
4747
 
 
4748
 
        /* vertices first */
4749
 
        eve= em->verts.last;
4750
 
        while(eve) {
4751
 
                eve->f&= ~128;
4752
 
                if(eve->f & flag) {
4753
 
                        v1= addvertlist(eve->co);
4754
 
                        v1->f= eve->f;
4755
 
                        eve->f-= flag;
4756
 
                        eve->f|= 128;
4757
 
                        eve->vn= v1;
4758
 
#ifdef __NLA
4759
 
                        /* >>>>> FIXME: Copy deformation weight ? */
4760
 
                        v1->totweight = eve->totweight;
4761
 
                        if (eve->totweight){
4762
 
                                v1->dw = MEM_mallocN (eve->totweight * sizeof(MDeformWeight), "deformWeight");
4763
 
                                memcpy (v1->dw, eve->dw, eve->totweight * sizeof(MDeformWeight));
4764
 
                        }
4765
 
                        else
4766
 
                                v1->dw=NULL;
4767
 
#endif
4768
 
                }
4769
 
                eve= eve->prev;
4770
 
        }
4771
 
        eed= em->edges.first;
4772
 
        while(eed) {
4773
 
                if( (eed->v1->f & 128) && (eed->v2->f & 128) ) {
4774
 
                        v1= eed->v1->vn;
4775
 
                        v2= eed->v2->vn;
4776
 
                        addedgelist(v1,v2);
4777
 
                }
4778
 
                eed= eed->next;
4779
 
        }
4780
 
 
4781
 
        /* then dupicate faces */
4782
 
        evl= em->faces.first;
4783
 
        while(evl) {
4784
 
                if( (evl->v1->f & 128) && (evl->v2->f & 128) && (evl->v3->f & 128) ) {
4785
 
                        if(evl->v4) {
4786
 
                                if(evl->v4->f & 128) {
4787
 
                                        v1= evl->v1->vn;
4788
 
                                        v2= evl->v2->vn;
4789
 
                                        v3= evl->v3->vn;
4790
 
                                        v4= evl->v4->vn;
4791
 
                                        addvlaklist(v1, v2, v3, v4, evl);
4792
 
                                }
4793
 
                        }
4794
 
                        else {
4795
 
                                v1= evl->v1->vn;
4796
 
                                v2= evl->v2->vn;
4797
 
                                v3= evl->v3->vn;
4798
 
                                addvlaklist(v1, v2, v3, 0, evl);
4799
 
                        }
4800
 
                }
4801
 
                evl= evl->next;
4802
 
        }
4803
 
}
4804
 
 
4805
 
static void delvlakflag(int flag)
4806
 
{
4807
 
        EditMesh *em = G.editMesh;
4808
 
        /* delete all faces with 'flag', including edges and loose vertices */
4809
 
        /* in vertices the 'flag' is cleared */
4810
 
        EditVert *eve,*nextve;
4811
 
        EditEdge *eed, *nexted;
4812
 
        EditVlak *evl,*nextvl;
4813
 
 
4814
 
        eed= em->edges.first;
4815
 
        while(eed) {
4816
 
                eed->f= 0;
4817
 
                eed= eed->next;
4818
 
        }
4819
 
 
4820
 
        evl= em->faces.first;
4821
 
        while(evl) {
4822
 
                nextvl= evl->next;
4823
 
                if(vlakselectedAND(evl, flag)) {
4824
 
                        
4825
 
                        evl->e1->f= 1;
4826
 
                        evl->e2->f= 1;
4827
 
                        evl->e3->f= 1;
4828
 
                        if(evl->e4) {
4829
 
                                evl->e4->f= 1;
4830
 
                        }
4831
 
                                                                
4832
 
                        BLI_remlink(&em->faces, evl);
4833
 
                        free_editvlak(evl);
4834
 
                }
4835
 
                evl= nextvl;
4836
 
        }
4837
 
        /* all faces with 1, 2 (3) vertices selected: make sure we keep the edges */
4838
 
        evl= em->faces.first;
4839
 
        while(evl) {
4840
 
                evl->e1->f= 0;
4841
 
                evl->e2->f= 0;
4842
 
                evl->e3->f= 0;
4843
 
                if(evl->e4) {
4844
 
                        evl->e4->f= 0;
4845
 
                }
4846
 
 
4847
 
                evl= evl->next;
4848
 
        }
4849
 
        
4850
 
        /* test all edges for vertices with 'flag', and clear */
4851
 
        eed= em->edges.first;
4852
 
        while(eed) {
4853
 
                nexted= eed->next;
4854
 
                if(eed->f==1) {
4855
 
                        remedge(eed);
4856
 
                        free_editedge(eed);
4857
 
                }
4858
 
                else if( (eed->v1->f & flag) || (eed->v2->f & flag) ) {
4859
 
                        eed->v1->f&= ~flag;
4860
 
                        eed->v2->f&= ~flag;
4861
 
                }
4862
 
                eed= nexted;
4863
 
        }
4864
 
        /* vertices with 'flag' now are the loose ones, and will be removed */
4865
 
        eve= em->verts.first;
4866
 
        while(eve) {
4867
 
                nextve= eve->next;
4868
 
                if(eve->f & flag) {
4869
 
                        BLI_remlink(&em->verts, eve);
4870
 
                        free_editvert(eve);
4871
 
                }
4872
 
                eve= nextve;
4873
 
        }
4874
 
 
4875
 
}
4876
 
 
4877
 
void extrude_mesh(void)
4878
 
{
4879
 
        short a;
4880
 
 
4881
 
        TEST_EDITMESH
4882
 
 
4883
 
        if(okee("Extrude")==0) return;
4884
 
        
4885
 
        waitcursor(1);
4886
 
        undo_push_mesh("Extrude");
4887
 
        
4888
 
        a= extrudeflag(1,1);
4889
 
        waitcursor(0);
4890
 
        if(a==0) {
4891
 
                error("No valid vertices selected");
4892
 
        }
4893
 
        else {
4894
 
                countall();  /* for G.totvert in calc_meshverts() */
4895
 
                calc_meshverts();
4896
 
                transform('d');
4897
 
        }
4898
 
 
4899
 
}
4900
 
 
4901
 
void adduplicate_mesh(void)
4902
 
{
4903
 
 
4904
 
        TEST_EDITMESH
4905
 
 
4906
 
        waitcursor(1);
4907
 
        undo_push_mesh("Duplicate");
4908
 
        adduplicateflag(1);
4909
 
        waitcursor(0);
4910
 
        countall();  /* for G.totvert in calc_meshverts() */
4911
 
        transform('d');
4912
 
}
4913
 
 
4914
 
void split_mesh(void)
4915
 
{
4916
 
 
4917
 
        TEST_EDITMESH
4918
 
 
4919
 
        if(okee(" Split ")==0) return;
4920
 
 
4921
 
        waitcursor(1);
4922
 
        undo_push_mesh("Split");
4923
 
        /* make duplicate first */
4924
 
        adduplicateflag(1);
4925
 
        /* old faces have 3x flag 128 set, delete them */
4926
 
        delvlakflag(128);
4927
 
 
4928
 
        waitcursor(0);
4929
 
 
4930
 
        countall();
4931
 
        allqueue(REDRAWVIEW3D, 0);
4932
 
        makeDispList(G.obedit);
4933
 
}
 
1283
        BIF_undo_push("Undo all changes");
 
1284
}
 
1285
 
 
1286
/* *************** SEPARATE (partial exit editmode) *************/
4934
1287
 
4935
1288
 
4936
1289
void separatemenu(void)
4937
1290
{
4938
1291
        short event;
4939
1292
 
4940
 
        event = pupmenu("Separate (No undo!) %t|Selected%x1|All loose parts%x2");
 
1293
        if(G.editMesh->verts.first==NULL) return;
 
1294
           
 
1295
        event = pupmenu("Separate (No undo!) %t|Selected%x1|All Loose Parts%x2");
4941
1296
        
4942
1297
        if (event==0) return;
4943
1298
        waitcursor(1);
4944
1299
        
4945
1300
        switch (event) {
4946
 
 
4947
 
                case 1: 
4948
 
                        separate_mesh();                    
4949
 
                        break;
4950
 
                case 2:                     
4951
 
                        separate_mesh_loose();              
4952
 
                        break;
 
1301
        case 1: 
 
1302
                separate_mesh();                    
 
1303
                break;
 
1304
        case 2:                     
 
1305
                separate_mesh_loose();              
 
1306
                break;
4953
1307
        }
4954
1308
        waitcursor(0);
4955
1309
}
4958
1312
void separate_mesh(void)
4959
1313
{
4960
1314
        EditMesh *em = G.editMesh;
 
1315
        EditMesh emcopy;
4961
1316
        EditVert *eve, *v1;
4962
1317
        EditEdge *eed, *e1;
4963
 
        EditVlak *evl, *vl1;
 
1318
        EditFace *efa, *vl1;
4964
1319
        Object *oldob;
4965
1320
        Mesh *me, *men;
4966
1321
        Base *base, *oldbase;
4967
1322
        ListBase edve, eded, edvl;
4968
1323
        float trans[9];
4969
 
        int ok, flag;
4970
1324
        
4971
1325
        TEST_EDITMESH   
4972
1326
 
4978
1332
                return;
4979
1333
        }
4980
1334
        
 
1335
        EM_selectmode_set();    // enforce full consistant selection flags 
 
1336
        
4981
1337
        /* we are going to abuse the system as follows:
4982
1338
         * 1. add a duplicate object: this will be the new one, we remember old pointer
4983
1339
         * 2: then do a split if needed.
4984
1340
         * 3. put apart: all NOT selected verts, edges, faces
4985
 
         * 4. call loadobeditdata(): this will be the new object
4986
 
         * 5. freelist en oude verts, eds, vlakken weer terughalen
 
1341
         * 4. call load_editMesh(): this will be the new object
 
1342
         * 5. freelist and get back old verts, edges, facs
4987
1343
         */
4988
1344
        
4989
1345
        /* make only obedit selected */
4996
1352
                base= base->next;
4997
1353
        }
4998
1354
        
4999
 
        /* testen for split */
5000
 
        ok= 0;
5001
 
        eed= em->edges.first;
5002
 
        while(eed) {
5003
 
                flag= (eed->v1->f & 1)+(eed->v2->f & 1);
5004
 
                if(flag==1) {
5005
 
                        ok= 1;
5006
 
                        break;
5007
 
                }
5008
 
                eed= eed->next;
5009
 
        }
5010
 
        if(ok) {
5011
 
                /* SPLIT: first make duplicate */
5012
 
                adduplicateflag(1);
5013
 
                /* SPLIT: old faces have 3x flag 128 set, delete these ones */
5014
 
                delvlakflag(128);
5015
 
        }
 
1355
        /* no test for split, split doesn't split when a loose part is selected */
 
1356
        /* SPLIT: first make duplicate */
 
1357
        adduplicateflag(SELECT);
 
1358
        /* SPLIT: old faces have 3x flag 128 set, delete these ones */
 
1359
        delfaceflag(128);
 
1360
        
 
1361
        /* since we do tricky things with verts/edges/faces, this makes sure all is selected coherent */
 
1362
        EM_selectmode_set();
5016
1363
        
5017
1364
        /* set apart: everything that is not selected */
5018
1365
        edve.first= edve.last= eded.first= eded.last= edvl.first= edvl.last= 0;
5019
1366
        eve= em->verts.first;
5020
1367
        while(eve) {
5021
1368
                v1= eve->next;
5022
 
                if((eve->f & 1)==0) {
 
1369
                if((eve->f & SELECT)==0) {
5023
1370
                        BLI_remlink(&em->verts, eve);
5024
1371
                        BLI_addtail(&edve, eve);
5025
1372
                }
5028
1375
        eed= em->edges.first;
5029
1376
        while(eed) {
5030
1377
                e1= eed->next;
5031
 
                if( (eed->v1->f & 1)==0 || (eed->v2->f & 1)==0 ) {
 
1378
                if((eed->f & SELECT)==0) {
5032
1379
                        BLI_remlink(&em->edges, eed);
5033
1380
                        BLI_addtail(&eded, eed);
5034
1381
                }
5035
1382
                eed= e1;
5036
1383
        }
5037
 
        evl= em->faces.first;
5038
 
        while(evl) {
5039
 
                vl1= evl->next;
5040
 
                if( (evl->v1->f & 1)==0 || (evl->v2->f & 1)==0 || (evl->v3->f & 1)==0 ) {
5041
 
                        BLI_remlink(&em->faces, evl);
5042
 
                        BLI_addtail(&edvl, evl);
 
1384
        efa= em->faces.first;
 
1385
        while(efa) {
 
1386
                vl1= efa->next;
 
1387
                if((efa->f & SELECT)==0) {
 
1388
                        BLI_remlink(&em->faces, efa);
 
1389
                        BLI_addtail(&edvl, efa);
5043
1390
                }
5044
 
                evl= vl1;
 
1391
                efa= vl1;
5045
1392
        }
5046
1393
        
5047
1394
        oldob= G.obedit;
5064
1411
        
5065
1412
        BASACT->flag &= ~SELECT;
5066
1413
        
5067
 
        makeDispList(G.obedit);
5068
 
        free_editMesh();
 
1414
        /* we cannot free the original buffer... */
 
1415
        emcopy= *G.editMesh;
 
1416
        emcopy.allverts= NULL;
 
1417
        emcopy.alledges= NULL;
 
1418
        emcopy.allfaces= NULL;
 
1419
        emcopy.derived= NULL;
 
1420
        free_editMesh(&emcopy);
5069
1421
        
5070
1422
        em->verts= edve;
5071
1423
        em->edges= eded;
5072
1424
        em->faces= edvl;
5073
1425
        
5074
1426
        /* hashedges are freed now, make new! */
5075
 
        eed= em->edges.first;
5076
 
        while(eed) {
5077
 
                if( findedgelist(eed->v1, eed->v2)==NULL )
5078
 
                        insert_hashedge(eed);
5079
 
                eed= eed->next;
5080
 
        }
 
1427
        editMesh_set_hash();
5081
1428
        
5082
1429
        G.obedit= oldob;
5083
1430
        BASACT= oldbase;
5094
1441
void separate_mesh_loose(void)
5095
1442
{
5096
1443
        EditMesh *em = G.editMesh;
 
1444
        EditMesh emcopy;
5097
1445
        EditVert *eve, *v1;
5098
1446
        EditEdge *eed, *e1;
5099
 
        EditVlak *evl, *vl1;
 
1447
        EditFace *efa, *vl1;
5100
1448
        Object *oldob;
5101
1449
        Mesh *me, *men;
5102
1450
        Base *base, *oldbase;
5103
1451
        ListBase edve, eded, edvl;
5104
1452
        float trans[9];
5105
 
        int ok, vertsep=0, flag;        
 
1453
        int vertsep=0;  
5106
1454
        short done=0, check=1;
5107
1455
                
5108
1456
        TEST_EDITMESH
5112
1460
         * 1. add a duplicate object: this will be the new one, we remember old pointer
5113
1461
         * 2: then do a split if needed.
5114
1462
         * 3. put apart: all NOT selected verts, edges, faces
5115
 
         * 4. call loadobeditdata(): this will be the new object
5116
 
         * 5. freelist en oude verts, eds, vlakken weer terughalen
 
1463
         * 4. call load_editMesh(): this will be the new object
 
1464
         * 5. freelist and get back old verts, edges, facs
5117
1465
         */
5118
1466
                        
5119
1467
        
5125
1473
                
5126
1474
                me= get_mesh(G.obedit);
5127
1475
                if(me->key) {
5128
 
                        error("Can't separate with vertex keys");
 
1476
                        error("Can't separate a mesh with vertex keys");
5129
1477
                        return;
5130
1478
                }               
5131
1479
                
5140
1488
                }               
5141
1489
                
5142
1490
                /*--------- Select connected-----------*/               
5143
 
                //sel= 3;
5144
 
                /* clear test flags */
5145
 
                eve= em->verts.first;
5146
 
                while(eve) {
5147
 
                        eve->f&= ~1;                    
5148
 
                        eve= eve->next;
5149
 
                }
5150
1491
                
 
1492
                EM_clear_flag_all(SELECT);
 
1493
 
5151
1494
                /* Select a random vert to start with */
5152
1495
                eve= em->verts.first;
5153
 
                eve->f |= 1;
 
1496
                eve->f |= SELECT;
5154
1497
                
5155
1498
                while(check==1) {
5156
1499
                        check= 0;                       
5157
1500
                        eed= em->edges.first;                   
5158
1501
                        while(eed) {                            
5159
1502
                                if(eed->h==0) {
5160
 
                                        if(eed->v1->f & 1) {
5161
 
                                                if( (eed->v2->f & 1)==0 ) {
5162
 
                                                        eed->v2->f |= 1;
 
1503
                                        if(eed->v1->f & SELECT) {
 
1504
                                                if( (eed->v2->f & SELECT)==0 ) {
 
1505
                                                        eed->v2->f |= SELECT;
5163
1506
                                                        vertsep++;
5164
1507
                                                        check= 1;
5165
1508
                                                }
5166
1509
                                        }
5167
 
                                        else if(eed->v2->f & 1) {
5168
 
                                                if( (eed->v1->f & 1)==0 ) {
5169
 
                                                        eed->v1->f |= 1;
 
1510
                                        else if(eed->v2->f & SELECT) {
 
1511
                                                if( (eed->v1->f & SELECT)==0 ) {
 
1512
                                                        eed->v1->f |= SELECT;
5170
1513
                                                        vertsep++;
5171
 
                                                        check= 1;
 
1514
                                                        check= SELECT;
5172
1515
                                                }
5173
1516
                                        }
5174
1517
                                }
5181
1524
                /* If the amount of vertices that is about to be split == the total amount 
5182
1525
                   of verts in the mesh, it means that there is only 1 unconnected object, so we don't have to separate
5183
1526
                */
5184
 
                if(G.totvert==vertsep)done=1;                           
 
1527
                if(G.totvert==vertsep) done=1;                          
5185
1528
                else{                   
5186
 
                        /* Test for splitting: Separate selected */
5187
 
                        ok= 0;
5188
 
                        eed= em->edges.first;
5189
 
                        while(eed) {
5190
 
                                flag= (eed->v1->f & 1)+(eed->v2->f & 1);
5191
 
                                if(flag==1) {
5192
 
                                        ok= 1;
5193
 
                                        break;
5194
 
                                }
5195
 
                                eed= eed->next;
5196
 
                        }
5197
 
                        if(ok) {
5198
 
                                /* SPLIT: first make duplicate */
5199
 
                                adduplicateflag(1);
5200
 
                                /* SPLIT: old faces have 3x flag 128 set, delete these ones */
5201
 
                                delvlakflag(128);
5202
 
                        }       
5203
 
                        
5204
 
                        
5205
 
                        
 
1529
                        /* No splitting: select connected goes fine */
 
1530
                        
 
1531
                        EM_select_flush();      // from verts->edges->faces
 
1532
 
5206
1533
                        /* set apart: everything that is not selected */
5207
1534
                        edve.first= edve.last= eded.first= eded.last= edvl.first= edvl.last= 0;
5208
1535
                        eve= em->verts.first;
5209
1536
                        while(eve) {
5210
1537
                                v1= eve->next;
5211
 
                                if((eve->f & 1)==0) {
 
1538
                                if((eve->f & SELECT)==0) {
5212
1539
                                        BLI_remlink(&em->verts, eve);
5213
1540
                                        BLI_addtail(&edve, eve);
5214
1541
                                }
5217
1544
                        eed= em->edges.first;
5218
1545
                        while(eed) {
5219
1546
                                e1= eed->next;
5220
 
                                if( (eed->v1->f & 1)==0 || (eed->v2->f & 1)==0 ) {
 
1547
                                if( (eed->f & SELECT)==0 ) {
5221
1548
                                        BLI_remlink(&em->edges, eed);
5222
1549
                                        BLI_addtail(&eded, eed);
5223
1550
                                }
5224
1551
                                eed= e1;
5225
1552
                        }
5226
 
                        evl= em->faces.first;
5227
 
                        while(evl) {
5228
 
                                vl1= evl->next;
5229
 
                                if( (evl->v1->f & 1)==0 || (evl->v2->f & 1)==0 || (evl->v3->f & 1)==0 ) {
5230
 
                                        BLI_remlink(&em->faces, evl);
5231
 
                                        BLI_addtail(&edvl, evl);
 
1553
                        efa= em->faces.first;
 
1554
                        while(efa) {
 
1555
                                vl1= efa->next;
 
1556
                                if( (efa->f & SELECT)==0 ) {
 
1557
                                        BLI_remlink(&em->faces, efa);
 
1558
                                        BLI_addtail(&edvl, efa);
5232
1559
                                }
5233
 
                                evl= vl1;
 
1560
                                efa= vl1;
5234
1561
                        }
5235
1562
                        
5236
1563
                        oldob= G.obedit;
5253
1580
                        
5254
1581
                        BASACT->flag &= ~SELECT;
5255
1582
                        
5256
 
                        makeDispList(G.obedit);
5257
 
                        free_editMesh();
 
1583
                        /* we cannot free the original buffer... */
 
1584
                        emcopy= *G.editMesh;
 
1585
                        emcopy.allverts= NULL;
 
1586
                        emcopy.alledges= NULL;
 
1587
                        emcopy.allfaces= NULL;
 
1588
                        emcopy.derived= NULL;
 
1589
                        free_editMesh(&emcopy);
5258
1590
                        
5259
1591
                        em->verts= edve;
5260
1592
                        em->edges= eded;
5261
1593
                        em->faces= edvl;
5262
1594
                        
5263
1595
                        /* hashedges are freed now, make new! */
5264
 
                        eed= em->edges.first;
5265
 
                        while(eed) {
5266
 
                                if( findedgelist(eed->v1, eed->v2)==NULL )
5267
 
                                        insert_hashedge(eed);
5268
 
                                eed= eed->next;
5269
 
                        }
 
1596
                        editMesh_set_hash();
5270
1597
                        
5271
1598
                        G.obedit= oldob;
5272
1599
                        BASACT= oldbase;
5276
1603
        }
5277
1604
        
5278
1605
        /* unselect the vertices that we (ab)used for the separation*/
5279
 
        eve= em->verts.first;
5280
 
        while(eve) {
5281
 
                eve->f&= ~1;                    
5282
 
                eve= eve->next;
5283
 
        }
5284
 
        
 
1606
        EM_clear_flag_all(SELECT);
 
1607
                
5285
1608
        waitcursor(0);
5286
1609
        countall();
5287
1610
        allqueue(REDRAWVIEW3D, 0);
5288
1611
        makeDispList(G.obedit); 
5289
1612
}
5290
1613
 
5291
 
 
5292
 
void extrude_repeat_mesh(int steps, float offs)
5293
 
{
5294
 
        float dvec[3], tmat[3][3], bmat[3][3];
5295
 
        short a,ok;
5296
 
 
5297
 
        TEST_EDITMESH
5298
 
        waitcursor(1);
5299
 
        
5300
 
        undo_push_mesh("Extrude Repeat");
5301
 
 
5302
 
        /* dvec */
5303
 
        dvec[0]= G.vd->persinv[2][0];
5304
 
        dvec[1]= G.vd->persinv[2][1];
5305
 
        dvec[2]= G.vd->persinv[2][2];
5306
 
        Normalise(dvec);
5307
 
        dvec[0]*= offs;
5308
 
        dvec[1]*= offs;
5309
 
        dvec[2]*= offs;
5310
 
 
5311
 
        /* base correction */
5312
 
        Mat3CpyMat4(bmat, G.obedit->obmat);
5313
 
        Mat3Inv(tmat, bmat);
5314
 
        Mat3MulVecfl(tmat, dvec);
5315
 
 
5316
 
        for(a=0;a<steps;a++) {
5317
 
                ok= extrudeflag(1,1);
5318
 
                if(ok==0) {
5319
 
                        error("No valid vertices selected");
5320
 
                        break;
5321
 
                }
5322
 
                translateflag(1, dvec);
5323
 
        }
5324
 
 
5325
 
        countall();
5326
 
        allqueue(REDRAWVIEW3D, 0);
5327
 
        makeDispList(G.obedit);
5328
 
        waitcursor(0);
5329
 
}
5330
 
 
5331
 
void spin_mesh(int steps,int degr,float *dvec, int mode)
5332
 
{
5333
 
        EditMesh *em = G.editMesh;
5334
 
        EditVert *eve,*nextve;
5335
 
        float *curs, si,n[3],q[4],cmat[3][3],imat[3][3], tmat[3][3];
5336
 
        float cent[3],bmat[3][3];
5337
 
        float phi;
5338
 
        short a,ok;
5339
 
 
5340
 
        TEST_EDITMESH
5341
 
        
5342
 
        waitcursor(1);
5343
 
        
5344
 
        undo_push_mesh("Spin");
5345
 
 
5346
 
        /* imat and centre and size */
5347
 
        Mat3CpyMat4(bmat, G.obedit->obmat);
5348
 
        Mat3Inv(imat,bmat);
5349
 
 
5350
 
        curs= give_cursor();
5351
 
        VECCOPY(cent, curs);
5352
 
        cent[0]-= G.obedit->obmat[3][0];
5353
 
        cent[1]-= G.obedit->obmat[3][1];
5354
 
        cent[2]-= G.obedit->obmat[3][2];
5355
 
        Mat3MulVecfl(imat, cent);
5356
 
 
5357
 
        phi= degr*M_PI/360.0;
5358
 
        phi/= steps;
5359
 
        if(editbutflag & B_CLOCKWISE) phi= -phi;
5360
 
 
5361
 
        if(dvec) {
5362
 
                n[0]=n[1]= 0.0;
5363
 
                n[2]= 1.0;
5364
 
        } else {
5365
 
                n[0]= G.vd->viewinv[2][0];
5366
 
                n[1]= G.vd->viewinv[2][1];
5367
 
                n[2]= G.vd->viewinv[2][2];
5368
 
                Normalise(n);
5369
 
        }
5370
 
 
5371
 
        q[0]= cos(phi);
5372
 
        si= sin(phi);
5373
 
        q[1]= n[0]*si;
5374
 
        q[2]= n[1]*si;
5375
 
        q[3]= n[2]*si;
5376
 
        QuatToMat3(q, cmat);
5377
 
 
5378
 
        Mat3MulMat3(tmat,cmat,bmat);
5379
 
        Mat3MulMat3(bmat,imat,tmat);
5380
 
 
5381
 
        if(mode==0) if(editbutflag & B_KEEPORIG) adduplicateflag(1);
5382
 
        ok= 1;
5383
 
 
5384
 
        for(a=0;a<steps;a++) {
5385
 
                if(mode==0) ok= extrudeflag(1,1);
5386
 
                else adduplicateflag(1);
5387
 
                if(ok==0) {
5388
 
                        error("No valid vertices selected");
5389
 
                        break;
5390
 
                }
5391
 
                rotateflag(1, cent, bmat);
5392
 
                if(dvec) {
5393
 
                        Mat3MulVecfl(bmat,dvec);
5394
 
                        translateflag(1,dvec);
5395
 
                }
5396
 
        }
5397
 
 
5398
 
        waitcursor(0);
5399
 
        if(ok==0) {
5400
 
                /* no vertices or only loose ones selected, remove duplicates */
5401
 
                eve= em->verts.first;
5402
 
                while(eve) {
5403
 
                        nextve= eve->next;
5404
 
                        if(eve->f & 1) {
5405
 
                                BLI_remlink(&em->verts,eve);
5406
 
                                free_editvert(eve);
5407
 
                        }
5408
 
                        eve= nextve;
5409
 
                }
5410
 
        }
5411
 
        countall();
5412
 
        recalc_editnormals();
5413
 
        allqueue(REDRAWVIEW3D, 0);
5414
 
        makeDispList(G.obedit);
5415
 
}
5416
 
 
5417
 
void screw_mesh(int steps,int turns)
5418
 
{
5419
 
        EditMesh *em = G.editMesh;
5420
 
        EditVert *eve,*v1=0,*v2=0;
5421
 
        EditEdge *eed;
5422
 
        float dvec[3], nor[3];
5423
 
 
5424
 
        TEST_EDITMESH
5425
 
 
5426
 
        /* first condition: we need frontview! */
5427
 
        if(G.vd->view!=1) {
5428
 
                error("Only in frontview!");
5429
 
                return;
5430
 
        }
5431
 
        
5432
 
        undo_push_mesh("Screw");
5433
 
        
5434
 
        /* clear flags */
5435
 
        eve= em->verts.first;
5436
 
        while(eve) {
5437
 
                eve->f1= 0;
5438
 
                eve= eve->next;
5439
 
        }
5440
 
        /* edges set flags in verts */
5441
 
        eed= em->edges.first;
5442
 
        while(eed) {
5443
 
                if(eed->v1->f & 1) {
5444
 
                        if(eed->v2->f & 1) {
5445
 
                                /* watch: f1 is a byte */
5446
 
                                if(eed->v1->f1<2) eed->v1->f1++;
5447
 
                                if(eed->v2->f1<2) eed->v2->f1++;
5448
 
                        }
5449
 
                }
5450
 
                eed= eed->next;
5451
 
        }
5452
 
        /* find two vertices with eve->f1==1, more or less is wrong */
5453
 
        eve= em->verts.first;
5454
 
        while(eve) {
5455
 
                if(eve->f1==1) {
5456
 
                        if(v1==0) v1= eve;
5457
 
                        else if(v2==0) v2= eve;
5458
 
                        else {
5459
 
                                v1=0;
5460
 
                                break;
5461
 
                        }
5462
 
                }
5463
 
                eve= eve->next;
5464
 
        }
5465
 
        if(v1==0 || v2==0) {
5466
 
                error("No curve selected");
5467
 
                return;
5468
 
        }
5469
 
 
5470
 
        /* calculate dvec */
5471
 
        dvec[0]= ( (v1->co[0]- v2->co[0]) )/(steps);
5472
 
        dvec[1]= ( (v1->co[1]- v2->co[1]) )/(steps);
5473
 
        dvec[2]= ( (v1->co[2]- v2->co[2]) )/(steps);
5474
 
 
5475
 
        VECCOPY(nor, G.obedit->obmat[2]);
5476
 
 
5477
 
        if(nor[0]*dvec[0]+nor[1]*dvec[1]+nor[2]*dvec[2]>0.000) {
5478
 
                dvec[0]= -dvec[0];
5479
 
                dvec[1]= -dvec[1];
5480
 
                dvec[2]= -dvec[2];
5481
 
        }
5482
 
 
5483
 
        spin_mesh(turns*steps, turns*360, dvec, 0);
5484
 
 
5485
 
}
5486
 
 
5487
 
void selectswap_mesh(void)
5488
 
{
5489
 
        EditMesh *em = G.editMesh;
5490
 
        EditVert *eve;
5491
 
 
5492
 
        eve= em->verts.first;
5493
 
        while(eve) {
5494
 
                if(eve->h==0) {
5495
 
                        if(eve->f & 1) eve->f&= ~1;
5496
 
                        else eve->f|= 1;
5497
 
                }
5498
 
                eve= eve->next;
5499
 
        }
5500
 
        countall();
5501
 
        allqueue(REDRAWVIEW3D, 0);
5502
 
 
5503
 
}
5504
 
 
5505
 
/* *******************************  ADD  ********************* */
5506
 
 
5507
 
void addvert_mesh(void)
5508
 
{
5509
 
        EditMesh *em = G.editMesh;
5510
 
        EditVert *eve,*v1=0;
5511
 
        float *curs, mat[3][3],imat[3][3];
5512
 
 
5513
 
        TEST_EDITMESH
5514
 
 
5515
 
        Mat3CpyMat4(mat, G.obedit->obmat);
5516
 
        Mat3Inv(imat, mat);
5517
 
 
5518
 
        v1= em->verts.first;
5519
 
        while(v1) {
5520
 
                if(v1->f & 1) break;
5521
 
                v1= v1->next;
5522
 
        }
5523
 
        eve= v1;        /* prevent there are more selected */
5524
 
        while(eve) {
5525
 
                eve->f&= ~1;
5526
 
                eve= eve->next;
5527
 
        }
5528
 
 
5529
 
        eve= addvertlist(0);
5530
 
        
5531
 
        curs= give_cursor();
5532
 
        VECCOPY(eve->co, curs);
5533
 
        eve->xs= G.vd->mx;
5534
 
        eve->ys= G.vd->my;
5535
 
        VecSubf(eve->co, eve->co, G.obedit->obmat[3]);
5536
 
 
5537
 
        Mat3MulVecfl(imat, eve->co);
5538
 
        eve->f= 1;
5539
 
 
5540
 
        if(v1) {
5541
 
                addedgelist(v1, eve);
5542
 
                v1->f= 0;
5543
 
        }
5544
 
        countall();
5545
 
        allqueue(REDRAWVIEW3D, 0);
5546
 
        makeDispList(G.obedit);
5547
 
        
5548
 
        while(get_mbut()&R_MOUSE);
5549
 
 
5550
 
}
5551
 
 
5552
 
void addedgevlak_mesh(void)
5553
 
{
5554
 
        EditMesh *em = G.editMesh;
5555
 
        EditVert *eve, *neweve[4];
5556
 
        EditVlak *evl;
5557
 
        float con1, con2, con3;
5558
 
        short aantal=0;
5559
 
 
5560
 
        if( (G.vd->lay & G.obedit->lay)==0 ) return;
5561
 
 
5562
 
        /* how many selected ? */
5563
 
        eve= em->verts.first;
5564
 
        while(eve) {
5565
 
                if(eve->f & 1) {
5566
 
                        aantal++;
5567
 
                        if(aantal>4) break;                     
5568
 
                        neweve[aantal-1]= eve;
5569
 
                }
5570
 
                eve= eve->next;
5571
 
        }
5572
 
        if(aantal==2) {
5573
 
                addedgelist(neweve[0], neweve[1]);
5574
 
                allqueue(REDRAWVIEW3D, 0);
5575
 
                makeDispList(G.obedit);
5576
 
                return;
5577
 
        }
5578
 
        if(aantal<2 || aantal>4) {
5579
 
                error("Can't make edge/face");
5580
 
                return;
5581
 
        }
5582
 
 
5583
 
        evl= NULL; // check later
5584
 
 
5585
 
        if(aantal==3) {
5586
 
                if(exist_vlak(neweve[0], neweve[1], neweve[2], 0)==0) {
5587
 
                        
5588
 
                        evl= addvlaklist(neweve[0], neweve[1], neweve[2], 0, NULL);
5589
 
 
5590
 
                }
5591
 
                else error("Already a face");
5592
 
        }
5593
 
        else if(aantal==4) {
5594
 
                if(exist_vlak(neweve[0], neweve[1], neweve[2], neweve[3])==0) {
5595
 
                
5596
 
                        con1= convex(neweve[0]->co, neweve[1]->co, neweve[2]->co, neweve[3]->co);
5597
 
                        con2= convex(neweve[0]->co, neweve[2]->co, neweve[3]->co, neweve[1]->co);
5598
 
                        con3= convex(neweve[0]->co, neweve[3]->co, neweve[1]->co, neweve[2]->co);
5599
 
 
5600
 
                        if(con1>=con2 && con1>=con3)
5601
 
                                evl= addvlaklist(neweve[0], neweve[1], neweve[2], neweve[3], NULL);
5602
 
                        else if(con2>=con1 && con2>=con3)
5603
 
                                evl= addvlaklist(neweve[0], neweve[2], neweve[3], neweve[1], NULL);
5604
 
                        else 
5605
 
                                evl= addvlaklist(neweve[0], neweve[2], neweve[1], neweve[3], NULL);
5606
 
 
5607
 
                }
5608
 
                else error("Already a face");
5609
 
        }
5610
 
        
5611
 
        if(evl) {       // now we're calculating direction of normal
5612
 
                float inp;      
5613
 
                /* dot product view mat with normal, should give info! */
5614
 
        
5615
 
                CalcNormFloat(evl->v1->co, evl->v2->co, evl->v3->co, evl->n);
5616
 
 
5617
 
                                        inp= evl->n[0]*G.vd->viewmat[0][2] + evl->n[1]*G.vd->viewmat[1][2] + evl->n[2]*G.vd->viewmat[2][2];
5618
 
 
5619
 
                if(inp < 0.0) flipvlak(evl);
5620
 
        }
5621
 
        
5622
 
        countall();
5623
 
        allqueue(REDRAWVIEW3D, 0);
5624
 
        makeDispList(G.obedit);
5625
 
}
5626
 
 
5627
 
static void erase_edges(ListBase *l)
5628
 
{
5629
 
        EditEdge *ed, *nexted;
5630
 
        
5631
 
        ed = (EditEdge *) l->first;
5632
 
        while(ed) {
5633
 
                nexted= ed->next;
5634
 
                if( (ed->v1->f & 1) || (ed->v2->f & 1) ) {
5635
 
                        remedge(ed);
5636
 
                        free_editedge(ed);
5637
 
                }
5638
 
                ed= nexted;
5639
 
        }
5640
 
}
5641
 
 
5642
 
static void erase_faces(ListBase *l)
5643
 
{
5644
 
        EditVlak *f, *nextf;
5645
 
 
5646
 
        f = (EditVlak *) l->first;
5647
 
 
5648
 
        while(f) {
5649
 
                nextf= f->next;
5650
 
                if( vlakselectedOR(f, 1) ) {
5651
 
                        BLI_remlink(l, f);
5652
 
                        free_editvlak(f);
5653
 
                }
5654
 
                f = nextf;
5655
 
        }
5656
 
}       
5657
 
 
5658
 
static void erase_vertices(ListBase *l)
5659
 
{
5660
 
        EditVert *v, *nextv;
5661
 
 
5662
 
        v = (EditVert *) l->first;
5663
 
        while(v) {
5664
 
                nextv= v->next;
5665
 
                if(v->f & 1) {
5666
 
                        BLI_remlink(l, v);
5667
 
                        free_editvert(v);
5668
 
                }
5669
 
                v = nextv;
5670
 
        }
5671
 
}
5672
 
 
5673
 
void delete_mesh(void)
5674
 
{
5675
 
        EditMesh *em = G.editMesh;
5676
 
        EditVlak *evl, *nextvl;
5677
 
        EditVert *eve,*nextve;
5678
 
        EditEdge *eed,*nexted;
5679
 
        short event;
5680
 
        int count;
5681
 
 
5682
 
        TEST_EDITMESH
5683
 
        
5684
 
        event= pupmenu("ERASE %t|Vertices%x10|Edges%x1|Faces%x2|All%x3|Edges & Faces%x4|Only Faces%x5");
5685
 
        if(event<1) return;
5686
 
 
5687
 
        if(event==10 ) {
5688
 
                undo_push_mesh("Erase Vertices");
5689
 
                erase_edges(&em->edges);
5690
 
                erase_faces(&em->faces);
5691
 
                erase_vertices(&em->verts);
5692
 
        } 
5693
 
        else if(event==4) {
5694
 
                undo_push_mesh("Erase Edges & Faces");
5695
 
                evl= em->faces.first;
5696
 
                while(evl) {
5697
 
                        nextvl= evl->next;
5698
 
                        /* delete only faces with 2 or more vertices selected */
5699
 
                        count= 0;
5700
 
                        if(evl->v1->f & 1) count++;
5701
 
                        if(evl->v2->f & 1) count++;
5702
 
                        if(evl->v3->f & 1) count++;
5703
 
                        if(evl->v4 && (evl->v4->f & 1)) count++;
5704
 
                        if(count>1) {
5705
 
                                BLI_remlink(&em->faces, evl);
5706
 
                                free_editvlak(evl);
5707
 
                        }
5708
 
                        evl= nextvl;
5709
 
                }
5710
 
                eed= em->edges.first;
5711
 
                while(eed) {
5712
 
                        nexted= eed->next;
5713
 
                        if( (eed->v1->f & 1) && (eed->v2->f & 1) ) {
5714
 
                                remedge(eed);
5715
 
                                free_editedge(eed);
5716
 
                        }
5717
 
                        eed= nexted;
5718
 
                }
5719
 
                evl= em->faces.first;
5720
 
                while(evl) {
5721
 
                        nextvl= evl->next;
5722
 
                        event=0;
5723
 
                        if( evl->v1->f & 1) event++;
5724
 
                        if( evl->v2->f & 1) event++;
5725
 
                        if( evl->v3->f & 1) event++;
5726
 
                        if(evl->v4 && (evl->v4->f & 1)) event++;
5727
 
                        
5728
 
                        if(event>1) {
5729
 
                                BLI_remlink(&em->faces, evl);
5730
 
                                free_editvlak(evl);
5731
 
                        }
5732
 
                        evl= nextvl;
5733
 
                }
5734
 
        } 
5735
 
        else if(event==1) {
5736
 
                undo_push_mesh("Erase Edges");
5737
 
                eed= em->edges.first;
5738
 
                while(eed) {
5739
 
                        nexted= eed->next;
5740
 
                        if( (eed->v1->f & 1) && (eed->v2->f & 1) ) {
5741
 
                                remedge(eed);
5742
 
                                free_editedge(eed);
5743
 
                        }
5744
 
                        eed= nexted;
5745
 
                }
5746
 
                evl= em->faces.first;
5747
 
                while(evl) {
5748
 
                        nextvl= evl->next;
5749
 
                        event=0;
5750
 
                        if( evl->v1->f & 1) event++;
5751
 
                        if( evl->v2->f & 1) event++;
5752
 
                        if( evl->v3->f & 1) event++;
5753
 
                        if(evl->v4 && (evl->v4->f & 1)) event++;
5754
 
                        
5755
 
                        if(event>1) {
5756
 
                                BLI_remlink(&em->faces, evl);
5757
 
                                free_editvlak(evl);
5758
 
                        }
5759
 
                        evl= nextvl;
5760
 
                }
5761
 
                /* to remove loose vertices: */
5762
 
                eed= em->edges.first;
5763
 
                while(eed) {
5764
 
                        if( eed->v1->f & 1) eed->v1->f-=1;
5765
 
                        if( eed->v2->f & 1) eed->v2->f-=1;
5766
 
                        eed= eed->next;
5767
 
                }
5768
 
                eve= em->verts.first;
5769
 
                while(eve) {
5770
 
                        nextve= eve->next;
5771
 
                        if(eve->f & 1) {
5772
 
                                BLI_remlink(&em->verts,eve);
5773
 
                                free_editvert(eve);
5774
 
                        }
5775
 
                        eve= nextve;
5776
 
                }
5777
 
 
5778
 
        }
5779
 
        else if(event==2) {
5780
 
                undo_push_mesh("Erase Faces");
5781
 
                delvlakflag(1);
5782
 
        }
5783
 
        else if(event==3) {
5784
 
                undo_push_mesh("Erase All");
5785
 
                if(em->verts.first) free_vertlist(&em->verts);
5786
 
                if(em->edges.first) free_edgelist(&em->edges);
5787
 
                if(em->faces.first) free_vlaklist(&em->faces);
5788
 
        }
5789
 
        else if(event==5) {
5790
 
                undo_push_mesh("Erase Only Faces");
5791
 
                evl= em->faces.first;
5792
 
                while(evl) {
5793
 
                        nextvl= evl->next;
5794
 
                        if(vlakselectedAND(evl, 1)) {
5795
 
                                BLI_remlink(&em->faces, evl);
5796
 
                                free_editvlak(evl);
5797
 
                        }
5798
 
                        evl= nextvl;
5799
 
                }
5800
 
        }
5801
 
 
5802
 
        countall();
5803
 
        allqueue(REDRAWVIEW3D, 0);
5804
 
        makeDispList(G.obedit);
5805
 
}
5806
 
 
5807
 
 
5808
 
 
5809
 
void add_primitiveMesh(int type)
5810
 
{
5811
 
        EditMesh *em = G.editMesh;
5812
 
        Mesh *me;
5813
 
        EditVert *eve, *v1=NULL, *v2, *v3, *v4=NULL, *vtop, *vdown;
5814
 
        float *curs, d, dia, phi, phid, cent[3], vec[3], imat[3][3], mat[3][3];
5815
 
        float q[4], cmat[3][3];
5816
 
        static short tot=32, seg=32, subdiv=2;
5817
 
        short a, b, ext=0, fill=0, totoud, newob=0;
5818
 
        
5819
 
        if(G.scene->id.lib) return;
5820
 
 
5821
 
        /* this function also comes from an info window */
5822
 
        if ELEM(curarea->spacetype, SPACE_VIEW3D, SPACE_INFO); else return;
5823
 
        if(G.vd==0) return;
5824
 
 
5825
 
        check_editmode(OB_MESH);
5826
 
        
5827
 
        G.f &= ~(G_VERTEXPAINT+G_FACESELECT+G_TEXTUREPAINT);
5828
 
        setcursor_space(SPACE_VIEW3D, CURSOR_STD);
5829
 
 
5830
 
        /* if no obedit: new object and enter editmode */
5831
 
        if(G.obedit==0) {
5832
 
                /* add_object actually returns an object ! :-)
5833
 
                But it also stores the added object struct in
5834
 
                G.scene->basact->object (BASACT->object) */
5835
 
 
5836
 
                add_object_draw(OB_MESH);
5837
 
 
5838
 
                G.obedit= BASACT->object;
5839
 
                
5840
 
                where_is_object(G.obedit);
5841
 
                
5842
 
                make_editMesh();
5843
 
                setcursor_space(SPACE_VIEW3D, CURSOR_EDIT);
5844
 
                newob= 1;
5845
 
        }
5846
 
        me= G.obedit->data;
5847
 
        
5848
 
        /* deselectall */
5849
 
        eve= em->verts.first;
5850
 
        while(eve) {
5851
 
                if(eve->f & 1) eve->f&= ~1;
5852
 
                eve= eve->next;
5853
 
        }
5854
 
 
5855
 
        totoud= tot; /* store, and restore when cube/plane */
5856
 
        
5857
 
        /* imat and centre and size */
5858
 
        Mat3CpyMat4(mat, G.obedit->obmat);
5859
 
 
5860
 
        curs= give_cursor();
5861
 
        VECCOPY(cent, curs);
5862
 
        cent[0]-= G.obedit->obmat[3][0];
5863
 
        cent[1]-= G.obedit->obmat[3][1];
5864
 
        cent[2]-= G.obedit->obmat[3][2];
5865
 
 
5866
 
        if(type!= 11) {
5867
 
                Mat3CpyMat4(imat, G.vd->viewmat);
5868
 
                Mat3MulVecfl(imat, cent);
5869
 
                Mat3MulMat3(cmat, imat, mat);
5870
 
                Mat3Inv(imat,cmat);
5871
 
        } else {
5872
 
                Mat3Inv(imat, mat);
5873
 
        }
5874
 
        
5875
 
        /* ext==extrudeflag, tot==amount of vertices in basis */
5876
 
 
5877
 
        switch(type) {
5878
 
        case 0:         /* plane */
5879
 
                tot= 4;
5880
 
                ext= 0;
5881
 
                fill= 1;
5882
 
                if(newob) rename_id((ID *)G.obedit, "Plane");
5883
 
                if(newob) rename_id((ID *)me, "Plane");
5884
 
                break;
5885
 
        case 1:         /* cube  */
5886
 
                tot= 4;
5887
 
                ext= 1;
5888
 
                fill= 1;
5889
 
                if(newob) rename_id((ID *)G.obedit, "Cube");
5890
 
                if(newob) rename_id((ID *)me, "Cube");
5891
 
                break;
5892
 
        case 4:         /* circle  */
5893
 
                if(button(&tot,3,100,"Vertices:")==0) return;
5894
 
                ext= 0;
5895
 
                fill= 0;
5896
 
                if(newob) rename_id((ID *)G.obedit, "Circle");
5897
 
                if(newob) rename_id((ID *)me, "Circle");
5898
 
                break;
5899
 
        case 5:         /* cylinder  */
5900
 
                if(button(&tot,3,100,"Vertices:")==0) return;
5901
 
                ext= 1;
5902
 
                fill= 1;
5903
 
                if(newob) rename_id((ID *)G.obedit, "Cylinder");
5904
 
                if(newob) rename_id((ID *)me, "Cylinder");
5905
 
                break;
5906
 
        case 6:         /* tube  */
5907
 
                if(button(&tot,3,100,"Vertices:")==0) return;
5908
 
                ext= 1;
5909
 
                fill= 0;
5910
 
                if(newob) rename_id((ID *)G.obedit, "Tube");
5911
 
                if(newob) rename_id((ID *)me, "Tube");
5912
 
                break;
5913
 
        case 7:         /* cone  */
5914
 
                if(button(&tot,3,100,"Vertices:")==0) return;
5915
 
                ext= 0;
5916
 
                fill= 1;
5917
 
                if(newob) rename_id((ID *)G.obedit, "Cone");
5918
 
                if(newob) rename_id((ID *)me, "Cone");
5919
 
                break;
5920
 
        case 10:        /* grid */
5921
 
                if(button(&tot,2,100,"X res:")==0) return;
5922
 
                if(button(&seg,2,100,"Y res:")==0) return;
5923
 
                if(newob) rename_id((ID *)G.obedit, "Grid");
5924
 
                if(newob) rename_id((ID *)me, "Grid");
5925
 
                break;
5926
 
        case 11:        /* UVsphere */
5927
 
                if(button(&seg,3,100,"Segments:")==0) return;
5928
 
                if(button(&tot,3,100,"Rings:")==0) return;
5929
 
                if(newob) rename_id((ID *)G.obedit, "Sphere");
5930
 
                if(newob) rename_id((ID *)me, "Sphere");
5931
 
                break;
5932
 
        case 12:        /* Icosphere */
5933
 
                if(button(&subdiv,1,5,"Subdivision:")==0) return;
5934
 
                if(newob) rename_id((ID *)G.obedit, "Sphere");
5935
 
                if(newob) rename_id((ID *)me, "Sphere");
5936
 
                break;
5937
 
        case 13:        /* Monkey */
5938
 
                if(newob) rename_id((ID *)G.obedit, "Suzanne");
5939
 
                if(newob) rename_id((ID *)me, "Suzanne");
5940
 
                break;
5941
 
        }
5942
 
 
5943
 
        dia= sqrt(2.0)*G.vd->grid;
5944
 
        d= -G.vd->grid;
5945
 
        phid= 2*M_PI/tot;
5946
 
        phi= .25*M_PI;
5947
 
 
5948
 
 
5949
 
        if(type<10) {   /* all types except grid, sphere... */
5950
 
                if(ext==0 && type!=7) d= 0;
5951
 
        
5952
 
                /* vertices */
5953
 
                vtop= vdown= v1= v2= 0;
5954
 
                for(b=0; b<=ext; b++) {
5955
 
                        for(a=0; a<tot; a++) {
5956
 
                                
5957
 
                                vec[0]= cent[0]+dia*sin(phi);
5958
 
                                vec[1]= cent[1]+dia*cos(phi);
5959
 
                                vec[2]= cent[2]+d;
5960
 
                                
5961
 
                                Mat3MulVecfl(imat, vec);
5962
 
                                eve= addvertlist(vec);
5963
 
                                eve->f= 1;
5964
 
                                if(a==0) {
5965
 
                                        if(b==0) v1= eve;
5966
 
                                        else v2= eve;
5967
 
                                }
5968
 
                                phi+=phid;
5969
 
                        }
5970
 
                        d= -d;
5971
 
                }
5972
 
                /* centre vertices */
5973
 
                if(fill && type>1) {
5974
 
                        VECCOPY(vec,cent);
5975
 
                        vec[2]-= -d;
5976
 
                        Mat3MulVecfl(imat,vec);
5977
 
                        vdown= addvertlist(vec);
5978
 
                        if(ext || type==7) {
5979
 
                                VECCOPY(vec,cent);
5980
 
                                vec[2]-= d;
5981
 
                                Mat3MulVecfl(imat,vec);
5982
 
                                vtop= addvertlist(vec);
5983
 
                        }
5984
 
                } else {
5985
 
                        vdown= v1;
5986
 
                        vtop= v2;
5987
 
                }
5988
 
                if(vtop) vtop->f= 1;
5989
 
                if(vdown) vdown->f= 1;
5990
 
        
5991
 
                /* top and bottom face */
5992
 
                if(fill) {
5993
 
                        if(tot==4 && (type==0 || type==1)) {
5994
 
                                v3= v1->next->next;
5995
 
                                if(ext) v4= v2->next->next;
5996
 
                                
5997
 
                                addvlaklist(v3, v1->next, v1, v3->next, NULL);
5998
 
                                if(ext) addvlaklist(v2, v2->next, v4, v4->next, NULL);
5999
 
                                
6000
 
                        }
6001
 
                        else {
6002
 
                                v3= v1;
6003
 
                                v4= v2;
6004
 
                                for(a=1; a<tot; a++) {
6005
 
                                        addvlaklist(vdown, v3, v3->next, 0, NULL);
6006
 
                                        v3= v3->next;
6007
 
                                        if(ext) {
6008
 
                                                addvlaklist(vtop, v4, v4->next, 0, NULL);
6009
 
                                                v4= v4->next;
6010
 
                                        }
6011
 
                                }
6012
 
                                if(type>1) {
6013
 
                                        addvlaklist(vdown, v3, v1, 0, NULL);
6014
 
                                        if(ext) addvlaklist(vtop, v4, v2, 0, NULL);
6015
 
                                }
6016
 
                        }
6017
 
                }
6018
 
                else if(type==4) {  /* we need edges for a circle */
6019
 
                        v3= v1;
6020
 
                        for(a=1;a<tot;a++) {
6021
 
                                addedgelist(v3,v3->next);
6022
 
                                v3= v3->next;
6023
 
                        }
6024
 
                        addedgelist(v3,v1);
6025
 
                }
6026
 
                /* side faces */
6027
 
                if(ext) {
6028
 
                        v3= v1;
6029
 
                        v4= v2;
6030
 
                        for(a=1; a<tot; a++) {
6031
 
                                addvlaklist(v3, v3->next, v4->next, v4, NULL);
6032
 
                                v3= v3->next;
6033
 
                                v4= v4->next;
6034
 
                        }
6035
 
                        addvlaklist(v3, v1, v2, v4, NULL);
6036
 
                }
6037
 
                else if(type==7) { /* cone */
6038
 
                        v3= v1;
6039
 
                        for(a=1; a<tot; a++) {
6040
 
                                addvlaklist(vtop, v3->next, v3, 0, NULL);
6041
 
                                v3= v3->next;
6042
 
                        }
6043
 
                        addvlaklist(vtop, v1, v3, 0, NULL);
6044
 
                }
6045
 
                
6046
 
                if(type<2) tot= totoud;
6047
 
                
6048
 
        }
6049
 
        else if(type==10) {     /*  grid */
6050
 
                /* clear flags */
6051
 
                eve= em->verts.first;
6052
 
                while(eve) {
6053
 
                        eve->f= 0;
6054
 
                        eve= eve->next;
6055
 
                }
6056
 
                dia= G.vd->grid;
6057
 
                /* one segment first: de X as */
6058
 
                phi= -1.0; 
6059
 
                phid= 2.0/((float)tot-1);
6060
 
                for(a=0;a<tot;a++) {
6061
 
                        vec[0]= cent[0]+dia*phi;
6062
 
                        vec[1]= cent[1]- dia;
6063
 
                        vec[2]= cent[2];
6064
 
                        Mat3MulVecfl(imat,vec);
6065
 
                        eve= addvertlist(vec);
6066
 
                        eve->f= 1+2+4;
6067
 
                        if (a) addedgelist(eve->prev,eve);
6068
 
                        phi+=phid;
6069
 
                }
6070
 
                /* extrude and translate */
6071
 
                vec[0]= vec[2]= 0.0;
6072
 
                vec[1]= dia*phid;
6073
 
                Mat3MulVecfl(imat, vec);
6074
 
                for(a=0;a<seg-1;a++) {
6075
 
                        extrudeflag(2,0);
6076
 
                        translateflag(2, vec);
6077
 
                }
6078
 
        }
6079
 
        else if(type==11) {     /*  UVsphere */
6080
 
                float tmat[3][3];
6081
 
                
6082
 
                /* clear all flags */
6083
 
                eve= em->verts.first;
6084
 
                while(eve) {
6085
 
                        eve->f= 0;
6086
 
                        eve= eve->next;
6087
 
                }
6088
 
                
6089
 
                /* one segment first */
6090
 
                phi= 0; 
6091
 
                phid/=2;
6092
 
                for(a=0; a<=tot; a++) {
6093
 
                        vec[0]= cent[0]+dia*sin(phi);
6094
 
                        vec[1]= cent[1];
6095
 
                        vec[2]= cent[2]+dia*cos(phi);
6096
 
                        Mat3MulVecfl(imat,vec);
6097
 
                        eve= addvertlist(vec);
6098
 
                        eve->f= 1+2+4;
6099
 
                        if(a==0) v1= eve;
6100
 
                        else addedgelist(eve->prev, eve);
6101
 
                        phi+= phid;
6102
 
                }
6103
 
                
6104
 
                /* extrude and rotate */
6105
 
                phi= M_PI/seg;
6106
 
                q[0]= cos(phi);
6107
 
                q[3]= sin(phi);
6108
 
                q[1]=q[2]= 0;
6109
 
                QuatToMat3(q, cmat);
6110
 
                Mat3MulMat3(tmat, cmat, mat);
6111
 
                Mat3MulMat3(cmat, imat, tmat);
6112
 
                
6113
 
                for(a=0; a<seg; a++) {
6114
 
                        extrudeflag(2, 0);
6115
 
                        rotateflag(2, v1->co, cmat);
6116
 
                }
6117
 
                removedoublesflag(4, 0.01);
6118
 
        }
6119
 
        else if(type==12) {     /* Icosphere */
6120
 
                EditVert *eva[12];
6121
 
 
6122
 
                /* clear all flags */
6123
 
                eve= em->verts.first;
6124
 
                while(eve) {
6125
 
                        eve->f= 0;
6126
 
                        eve= eve->next;
6127
 
                }
6128
 
                dia/=200;
6129
 
                for(a=0;a<12;a++) {
6130
 
                        vec[0]= dia*icovert[a][0];
6131
 
                        vec[1]= dia*icovert[a][1];
6132
 
                        vec[2]= dia*icovert[a][2];
6133
 
                        eva[a]= addvertlist(vec);
6134
 
                        eva[a]->f= 1+2;
6135
 
                }
6136
 
                for(a=0;a<20;a++) {
6137
 
                        v1= eva[ icovlak[a][0] ];
6138
 
                        v2= eva[ icovlak[a][1] ];
6139
 
                        v3= eva[ icovlak[a][2] ];
6140
 
                        addvlaklist(v1, v2, v3, 0, NULL);
6141
 
                }
6142
 
 
6143
 
                dia*=200;
6144
 
                for(a=1; a<subdiv; a++) subdivideflag(2, dia, 0);
6145
 
                /* and now do imat */
6146
 
                eve= em->verts.first;
6147
 
                while(eve) {
6148
 
                        if(eve->f & 2) {
6149
 
                                VecAddf(eve->co,eve->co,cent);
6150
 
                                Mat3MulVecfl(imat,eve->co);
6151
 
                        }
6152
 
                        eve= eve->next;
6153
 
                }
6154
 
        } else if (type==13) {  /* Monkey */
6155
 
                extern int monkeyo, monkeynv, monkeynf;
6156
 
                extern signed char monkeyf[][4];
6157
 
                extern signed char monkeyv[][3];
6158
 
                EditVert **tv= MEM_mallocN(sizeof(*tv)*monkeynv*2, "tv");
6159
 
                int i;
6160
 
 
6161
 
                for (i=0; i<monkeynv; i++) {
6162
 
                        float v[3];
6163
 
                        v[0]= (monkeyv[i][0]+127)/128.0, v[1]= monkeyv[i][1]/128.0, v[2]= monkeyv[i][2]/128.0;
6164
 
                        tv[i]= addvertlist(v);
6165
 
                        tv[monkeynv+i]= (fabs(v[0]= -v[0])<0.001)?tv[i]:addvertlist(v);
6166
 
                }
6167
 
                for (i=0; i<monkeynf; i++) {
6168
 
                        addvlaklist(tv[monkeyf[i][0]+i-monkeyo], tv[monkeyf[i][1]+i-monkeyo], tv[monkeyf[i][2]+i-monkeyo], (monkeyf[i][3]!=monkeyf[i][2])?tv[monkeyf[i][3]+i-monkeyo]:NULL, NULL);
6169
 
                        addvlaklist(tv[monkeynv+monkeyf[i][2]+i-monkeyo], tv[monkeynv+monkeyf[i][1]+i-monkeyo], tv[monkeynv+monkeyf[i][0]+i-monkeyo], (monkeyf[i][3]!=monkeyf[i][2])?tv[monkeynv+monkeyf[i][3]+i-monkeyo]:NULL, NULL);
6170
 
                }
6171
 
 
6172
 
                MEM_freeN(tv);
6173
 
        }
6174
 
        
6175
 
        if(type!=0 && type!=10) righthandfaces(1);
6176
 
        countall();
6177
 
 
6178
 
        allqueue(REDRAWINFO, 1);        /* 1, because header->win==0! */        
6179
 
        allqueue(REDRAWALL, 0);
6180
 
        makeDispList(G.obedit);
6181
 
 
6182
 
        if (type==13) notice("Oooh Oooh Oooh");
6183
 
}
6184
 
 
6185
 
void vertexsmooth(void)
6186
 
{
6187
 
        EditMesh *em = G.editMesh;
6188
 
        EditVert *eve;
6189
 
        EditEdge *eed;
6190
 
        float *adror, *adr, fac;
6191
 
        float fvec[3];
6192
 
        int teller=0;
6193
 
 
6194
 
        if(G.obedit==0) return;
6195
 
 
6196
 
        /* count */
6197
 
        eve= em->verts.first;
6198
 
        while(eve) {
6199
 
                if(eve->f & 1) teller++;
6200
 
                eve= eve->next;
6201
 
        }
6202
 
        if(teller==0) return;
6203
 
        
6204
 
        undo_push_mesh("Smooth");
6205
 
 
6206
 
        adr=adror= (float *)MEM_callocN(3*sizeof(float *)*teller, "vertsmooth");
6207
 
        eve= em->verts.first;
6208
 
        while(eve) {
6209
 
                if(eve->f & 1) {
6210
 
                        eve->vn= (EditVert *)adr;
6211
 
                        eve->f1= 0;
6212
 
                        adr+= 3;
6213
 
                }
6214
 
                eve= eve->next;
6215
 
        }
6216
 
        
6217
 
        eed= em->edges.first;
6218
 
        while(eed) {
6219
 
                if( (eed->v1->f & 1) || (eed->v2->f & 1) ) {
6220
 
                        fvec[0]= (eed->v1->co[0]+eed->v2->co[0])/2.0;
6221
 
                        fvec[1]= (eed->v1->co[1]+eed->v2->co[1])/2.0;
6222
 
                        fvec[2]= (eed->v1->co[2]+eed->v2->co[2])/2.0;
6223
 
                        
6224
 
                        if((eed->v1->f & 1) && eed->v1->f1<255) {
6225
 
                                eed->v1->f1++;
6226
 
                                VecAddf((float *)eed->v1->vn, (float *)eed->v1->vn, fvec);
6227
 
                        }
6228
 
                        if((eed->v2->f & 1) && eed->v2->f1<255) {
6229
 
                                eed->v2->f1++;
6230
 
                                VecAddf((float *)eed->v2->vn, (float *)eed->v2->vn, fvec);
6231
 
                        }
6232
 
                }
6233
 
                eed= eed->next;
6234
 
        }
6235
 
 
6236
 
        eve= em->verts.first;
6237
 
        while(eve) {
6238
 
                if(eve->f & 1) {
6239
 
                        if(eve->f1) {
6240
 
                                adr= (float *)eve->vn;
6241
 
                                fac= 0.5/(float)eve->f1;
6242
 
                                
6243
 
                                eve->co[0]= 0.5*eve->co[0]+fac*adr[0];
6244
 
                                eve->co[1]= 0.5*eve->co[1]+fac*adr[1];
6245
 
                                eve->co[2]= 0.5*eve->co[2]+fac*adr[2];
6246
 
                        }
6247
 
                        eve->vn= 0;
6248
 
                }
6249
 
                eve= eve->next;
6250
 
        }
6251
 
        MEM_freeN(adror);
6252
 
 
6253
 
        allqueue(REDRAWVIEW3D, 0);
6254
 
        makeDispList(G.obedit);
6255
 
}
6256
 
 
6257
 
void vertexnoise(void)
6258
 
{
6259
 
        EditMesh *em = G.editMesh;
6260
 
        extern float Tin;
6261
 
        Material *ma;
6262
 
        Tex *tex;
6263
 
        EditVert *eve;
6264
 
        float b2, ofs, vec[3];
6265
 
 
6266
 
        if(G.obedit==0) return;
6267
 
        
6268
 
        undo_push_mesh("Noise");
6269
 
        
6270
 
        ma= give_current_material(G.obedit, G.obedit->actcol);
6271
 
        if(ma==0 || ma->mtex[0]==0 || ma->mtex[0]->tex==0) {
6272
 
                return;
6273
 
        }
6274
 
        tex= ma->mtex[0]->tex;
6275
 
        
6276
 
        ofs= tex->turbul/200.0;
6277
 
        
6278
 
        eve= (struct EditVert *)em->verts.first;
6279
 
        while(eve) {
6280
 
                if(eve->f & 1) {
6281
 
                        
6282
 
                        if(tex->type==TEX_STUCCI) {
6283
 
                                
6284
 
                                b2= BLI_hnoise(tex->noisesize, eve->co[0], eve->co[1], eve->co[2]);
6285
 
                                if(tex->stype) ofs*=(b2*b2);
6286
 
                                vec[0]= 0.2*(b2-BLI_hnoise(tex->noisesize, eve->co[0]+ofs, eve->co[1], eve->co[2]));
6287
 
                                vec[1]= 0.2*(b2-BLI_hnoise(tex->noisesize, eve->co[0], eve->co[1]+ofs, eve->co[2]));
6288
 
                                vec[2]= 0.2*(b2-BLI_hnoise(tex->noisesize, eve->co[0], eve->co[1], eve->co[2]+ofs));
6289
 
                                
6290
 
                                VecAddf(eve->co, eve->co, vec);
6291
 
                        }
6292
 
                        else {
6293
 
                                
6294
 
                                externtex(ma->mtex[0], eve->co);
6295
 
                        
6296
 
                                eve->co[2]+= 0.05*Tin;
6297
 
                        }
6298
 
                }
6299
 
                eve= eve->next;
6300
 
        }
6301
 
 
6302
 
        allqueue(REDRAWVIEW3D, 0);
6303
 
        makeDispList(G.obedit);
6304
 
}
6305
 
 
6306
 
void hide_mesh(int swap)
6307
 
{
6308
 
        EditMesh *em = G.editMesh;
6309
 
        EditVert *eve;
6310
 
        EditEdge *eed;
6311
 
 
6312
 
        if(G.obedit==0) return;
6313
 
 
6314
 
        if(swap) {
6315
 
                eve= em->verts.first;
6316
 
                while(eve) {
6317
 
                        if((eve->f & 1)==0) {
6318
 
                                eve->xs= 3200;
6319
 
                                eve->h= 1;
6320
 
                        }
6321
 
                        eve= eve->next;
6322
 
                }
6323
 
        }
6324
 
        else {
6325
 
                eve= em->verts.first;
6326
 
                while(eve) {
6327
 
                        if(eve->f & 1) {
6328
 
                                eve->f-=1;
6329
 
                                eve->xs= 3200;
6330
 
                                eve->h= 1;
6331
 
                        }
6332
 
                        eve= eve->next;
6333
 
                }
6334
 
        }
6335
 
        eed= em->edges.first;
6336
 
        while(eed) {
6337
 
                if(eed->v1->h || eed->v2->h) eed->h= 1;
6338
 
                else eed->h= 0;
6339
 
                eed= eed->next;
6340
 
        }
6341
 
 
6342
 
        allqueue(REDRAWVIEW3D, 0);
6343
 
        makeDispList(G.obedit);
6344
 
}
6345
 
 
6346
 
 
6347
 
void reveal_mesh(void)
6348
 
{
6349
 
        EditMesh *em = G.editMesh;
6350
 
        EditVert *eve;
6351
 
        EditEdge *eed;
6352
 
 
6353
 
        if(G.obedit==0) return;
6354
 
 
6355
 
        eve= em->verts.first;
6356
 
        while(eve) {
6357
 
                if(eve->h) {
6358
 
                        eve->h= 0;
6359
 
                        eve->f|=1;
6360
 
                }
6361
 
                eve= eve->next;
6362
 
        }
6363
 
 
6364
 
        eed= em->edges.first;
6365
 
        while(eed) {
6366
 
                eed->h= 0;
6367
 
                eed= eed->next;
6368
 
        }
6369
 
 
6370
 
        allqueue(REDRAWVIEW3D, 0);
6371
 
        makeDispList(G.obedit);
6372
 
}
6373
 
 
6374
 
static float convex(float *v1, float *v2, float *v3, float *v4)
6375
 
{
6376
 
        float cross[3], test[3];
6377
 
        float inpr;
6378
 
        
6379
 
        CalcNormFloat(v1, v2, v3, cross);
6380
 
        CalcNormFloat(v1, v3, v4, test);
6381
 
 
6382
 
        inpr= cross[0]*test[0]+cross[1]*test[1]+cross[2]*test[2];
6383
 
 
6384
 
        return inpr;
6385
 
}
6386
 
 
6387
 
/* returns vertices of two adjacent triangles forming a quad 
6388
 
   - can be righthand or lefthand
6389
 
 
6390
 
                        4-----3
6391
 
                        |\    |
6392
 
                        | \ 2 | <- evl1
6393
 
                        |  \  | 
6394
 
          evl-> | 1 \ | 
6395
 
                        |    \| 
6396
 
                        1-----2
6397
 
 
6398
 
*/
6399
 
#define VTEST(face, num, other) \
6400
 
        (face->v##num != other->v1 && face->v##num != other->v2 && face->v##num != other->v3) 
6401
 
 
6402
 
static void givequadverts(EditVlak *evl, EditVlak *evl1, EditVert **v1, EditVert **v2, EditVert **v3, EditVert **v4, float **uv, unsigned int *col)
6403
 
{
6404
 
        if VTEST(evl, 1, evl1) {
6405
 
        //if(evl->v1!=evl1->v1 && evl->v1!=evl1->v2 && evl->v1!=evl1->v3) {
6406
 
                *v1= evl->v1;
6407
 
                *v2= evl->v2;
6408
 
                uv[0] = evl->tf.uv[0];
6409
 
                uv[1] = evl->tf.uv[1];
6410
 
                col[0] = evl->tf.col[0];
6411
 
                col[1] = evl->tf.col[1];
6412
 
        }
6413
 
        else if VTEST(evl, 2, evl1) {
6414
 
        //else if(evl->v2!=evl1->v1 && evl->v2!=evl1->v2 && evl->v2!=evl1->v3) {
6415
 
                *v1= evl->v2;
6416
 
                *v2= evl->v3;
6417
 
                uv[0] = evl->tf.uv[1];
6418
 
                uv[1] = evl->tf.uv[2];
6419
 
                col[0] = evl->tf.col[1];
6420
 
                col[1] = evl->tf.col[2];
6421
 
        }
6422
 
        else if VTEST(evl, 3, evl1) {
6423
 
        // else if(evl->v3!=evl1->v1 && evl->v3!=evl1->v2 && evl->v3!=evl1->v3) {
6424
 
                *v1= evl->v3;
6425
 
                *v2= evl->v1;
6426
 
                uv[0] = evl->tf.uv[2];
6427
 
                uv[1] = evl->tf.uv[0];
6428
 
                col[0] = evl->tf.col[2];
6429
 
                col[1] = evl->tf.col[0];
6430
 
        }
6431
 
        
6432
 
        if VTEST(evl1, 1, evl) {
6433
 
        // if(evl1->v1!=evl->v1 && evl1->v1!=evl->v2 && evl1->v1!=evl->v3) {
6434
 
                *v3= evl1->v1;
6435
 
                uv[2] = evl1->tf.uv[0];
6436
 
                col[2] = evl1->tf.col[0];
6437
 
 
6438
 
                *v4= evl1->v2;
6439
 
                uv[3] = evl1->tf.uv[1];
6440
 
                col[3] = evl1->tf.col[1];
6441
 
/*
6442
 
if(evl1->v2== *v2) {
6443
 
                        *v4= evl1->v3;
6444
 
                        uv[3] = evl1->tf.uv[2];
6445
 
                } else {
6446
 
                        *v4= evl1->v2;
6447
 
                        uv[3] = evl1->tf.uv[1];
6448
 
                }       
6449
 
                */
6450
 
        }
6451
 
        else if VTEST(evl1, 2, evl) {
6452
 
        // else if(evl1->v2!=evl->v1 && evl1->v2!=evl->v2 && evl1->v2!=evl->v3) {
6453
 
                *v3= evl1->v2;
6454
 
                uv[2] = evl1->tf.uv[1];
6455
 
                col[2] = evl1->tf.col[1];
6456
 
 
6457
 
                *v4= evl1->v3;
6458
 
                uv[3] = evl1->tf.uv[2];
6459
 
                col[3] = evl1->tf.col[2];
6460
 
/*
6461
 
if(evl1->v3== *v2) {
6462
 
                        *v4= evl1->v1;
6463
 
                        uv[3] = evl1->tf.uv[0];
6464
 
                } else {        
6465
 
                        *v4= evl1->v3;
6466
 
                        uv[3] = evl1->tf.uv[2];
6467
 
                }       
6468
 
                */
6469
 
        }
6470
 
        else if VTEST(evl1, 3, evl) {
6471
 
        // else if(evl1->v3!=evl->v1 && evl1->v3!=evl->v2 && evl1->v3!=evl->v3) {
6472
 
                *v3= evl1->v3;
6473
 
                uv[2] = evl1->tf.uv[2];
6474
 
                col[2] = evl1->tf.col[2];
6475
 
 
6476
 
                *v4= evl1->v1;
6477
 
                uv[3] = evl1->tf.uv[0];
6478
 
                col[3] = evl1->tf.col[0];
6479
 
/*
6480
 
if(evl1->v1== *v2) {
6481
 
                        *v4= evl1->v2;
6482
 
                        uv[3] = evl1->tf.uv[3];
6483
 
                } else {        
6484
 
                        *v4= evl1->v1;
6485
 
                        uv[3] = evl1->tf.uv[0];
6486
 
                }       
6487
 
                */
6488
 
        }
6489
 
        else {
6490
 
                pupmenu("Wanna crash?%t|Yes Please!%x1");
6491
 
                return;
6492
 
        }
6493
 
        
6494
 
}
6495
 
 
6496
 
 
6497
 
 
6498
 
/* Helper functions for edge/quad edit features*/
6499
 
 
6500
 
static void untag_edges(EditVlak *f)
6501
 
{
6502
 
        f->e1->f = 0;
6503
 
        f->e2->f = 0;
6504
 
        if (f->e3) f->e3->f = 0;
6505
 
        if (f->e4) f->e4->f = 0;
6506
 
}
6507
 
 
6508
 
#if 0
6509
 
static void mark_clear_edges(EditVlak *f)
6510
 
{
6511
 
        f->e1->f1 = 1;
6512
 
        f->e2->f1 = 1;
6513
 
        if (f->e3) f->e3->f1 = 1;
6514
 
        if (f->e4) f->e4->f1 = 1;
6515
 
}
6516
 
#endif
6517
 
 
6518
 
static int count_edges(EditEdge *ed)
6519
 
{
6520
 
        int totedge = 0;
6521
 
        while(ed) {
6522
 
                ed->vn= 0;
6523
 
                if( (ed->v1->f & 1) && (ed->v2->f & 1) ) totedge++;
6524
 
                ed= ed->next;
6525
 
        }
6526
 
        return totedge;
6527
 
}
6528
 
 
6529
 
/** remove and free list of tagged edges */
6530
 
static void free_tagged_edgelist(EditEdge *eed)
6531
 
{
6532
 
        EditEdge *nexted;
6533
 
 
6534
 
        while(eed) {
6535
 
                nexted= eed->next;
6536
 
                if(eed->f1) {
6537
 
                        remedge(eed);
6538
 
                        free_editedge(eed);
6539
 
                }
6540
 
                eed= nexted;
6541
 
        }       
6542
 
}       
6543
 
/** remove and free list of tagged faces */
6544
 
 
6545
 
static void free_tagged_facelist(EditVlak *evl)
6546
 
{       
6547
 
        EditMesh *em = G.editMesh;
6548
 
        EditVlak *nextvl;
6549
 
 
6550
 
        while(evl) {
6551
 
                nextvl= evl->next;
6552
 
                if(evl->f1) {
6553
 
                        BLI_remlink(&em->faces, evl);
6554
 
                        free_editvlak(evl);
6555
 
                }
6556
 
                evl= nextvl;
6557
 
        }
6558
 
}       
6559
 
 
6560
 
typedef EditVlak *EVPtr;
6561
 
typedef EVPtr EVPTuple[2];
6562
 
 
6563
 
/** builds EVPTuple array evla of face tuples (in fact pointers to EditVlaks)
6564
 
    sharing one edge.
6565
 
        arguments: selected edge list, face list.
6566
 
        Edges will also be tagged accordingly (see eed->f)          */
6567
 
 
6568
 
static int collect_quadedges(EVPTuple *evla, EditEdge *eed, EditVlak *evl)
6569
 
{
6570
 
        int i = 0;
6571
 
        EditEdge *e1, *e2, *e3;
6572
 
        EVPtr *evp;
6573
 
 
6574
 
        /* run through edges, if selected, set pointer edge-> facearray */
6575
 
        while(eed) {
6576
 
                eed->f= 0;
6577
 
                eed->f1= 0;
6578
 
                if( (eed->v1->f & 1) && (eed->v2->f & 1) ) {
6579
 
                        eed->vn= (EditVert *) (&evla[i]);
6580
 
                        i++;
6581
 
                }
6582
 
                eed= eed->next;
6583
 
        }
6584
 
                
6585
 
        
6586
 
        /* find edges pointing to 2 faces by procedure:
6587
 
        
6588
 
        - run through faces and their edges, increase
6589
 
          face counter e->f for each face 
6590
 
        */
6591
 
 
6592
 
        while(evl) {
6593
 
                evl->f1= 0;
6594
 
                if(evl->v4==0) {  /* if triangle */
6595
 
                        if(vlakselectedAND(evl, 1)) {
6596
 
                                
6597
 
                                e1= evl->e1;
6598
 
                                e2= evl->e2;
6599
 
                                e3= evl->e3;
6600
 
                                if(e1->f<3) {
6601
 
                                        if(e1->f<2) {
6602
 
                                                evp= (EVPtr *) e1->vn;
6603
 
                                                evp[(int)e1->f]= evl;
6604
 
                                        }
6605
 
                                        e1->f+= 1;
6606
 
                                }
6607
 
                                if(e2->f<3) {
6608
 
                                        if(e2->f<2) {
6609
 
                                                evp= (EVPtr *) e2->vn;
6610
 
                                                evp[(int)e2->f]= evl;
6611
 
                                        }
6612
 
                                        e2->f+= 1;
6613
 
                                }
6614
 
                                if(e3->f<3) {
6615
 
                                        if(e3->f<2) {
6616
 
                                                evp= (EVPtr *) e3->vn;
6617
 
                                                evp[(int)e3->f]= evl;
6618
 
                                        }
6619
 
                                        e3->f+= 1;
6620
 
                                }
6621
 
                        }
6622
 
                }
6623
 
                evl= evl->next;
6624
 
        }
6625
 
        return i;
6626
 
}
6627
 
 
6628
 
 
6629
 
void join_triangles(void)
6630
 
{
6631
 
        EditMesh *em = G.editMesh;
6632
 
        EditVert *v1, *v2, *v3, *v4;
6633
 
        EditVlak *evl, *w;
6634
 
        EVPTuple *evlar;
6635
 
        EVPtr *evla;
6636
 
        EditEdge *eed, *nexted;
6637
 
        int totedge, ok;
6638
 
        float *uv[4];
6639
 
        unsigned int col[4];
6640
 
 
6641
 
 
6642
 
        totedge = count_edges(em->edges.first);
6643
 
        if(totedge==0) return;
6644
 
 
6645
 
        undo_push_mesh("Join triangles");
6646
 
        
6647
 
        evlar= (EVPTuple *) MEM_callocN(totedge * sizeof(EVPTuple), "jointris");
6648
 
 
6649
 
        ok = collect_quadedges(evlar, em->edges.first, em->faces.first);
6650
 
        if (G.f & G_DEBUG) {
6651
 
                printf("edges selected: %d\n", ok);
6652
 
        }       
6653
 
 
6654
 
        eed= em->edges.first;
6655
 
        while(eed) {
6656
 
                nexted= eed->next;
6657
 
                
6658
 
                if(eed->f==2) {  /* points to 2 faces */
6659
 
                        
6660
 
                        evla= (EVPtr *) eed->vn;
6661
 
                        
6662
 
                        /* don't do it if flagged */
6663
 
 
6664
 
                        ok= 1;
6665
 
                        evl= evla[0];
6666
 
                        if(evl->e1->f1 || evl->e2->f1 || evl->e3->f1) ok= 0;
6667
 
                        evl= evla[1];
6668
 
                        if(evl->e1->f1 || evl->e2->f1 || evl->e3->f1) ok= 0;
6669
 
                        
6670
 
                        if(ok) {
6671
 
                                /* test convex */
6672
 
                                givequadverts(evla[0], evla[1], &v1, &v2, &v3, &v4, uv, col);
6673
 
 
6674
 
/*
6675
 
                4-----3        4-----3
6676
 
                |\    |        |     |
6677
 
                | \ 1 |        |     |
6678
 
                |  \  |  ->    |     |  
6679
 
                | 0 \ |        |     | 
6680
 
                |    \|        |     |
6681
 
                1-----2        1-----2
6682
 
*/
6683
 
                                /* make new faces */
6684
 
                                if( convex(v1->co, v2->co, v3->co, v4->co) > 0.01) {
6685
 
                                        if(exist_vlak(v1, v2, v3, v4)==0) {
6686
 
                                                w = addvlaklist(v1, v2, v3, v4, evla[0]);
6687
 
                                                untag_edges(w);
6688
 
 
6689
 
                                                UVCOPY(w->tf.uv[0], uv[0]);
6690
 
                                                UVCOPY(w->tf.uv[1], uv[1]);
6691
 
                                                UVCOPY(w->tf.uv[2], uv[2]);
6692
 
                                                UVCOPY(w->tf.uv[3], uv[3]);
6693
 
 
6694
 
                                                memcpy(w->tf.col, col, sizeof(w->tf.col));
6695
 
                                        }
6696
 
                                        /* tag as to-be-removed */
6697
 
                                        FACE_MARKCLEAR(evla[0]);
6698
 
                                        FACE_MARKCLEAR(evla[1]);
6699
 
                                        eed->f1 = 1; 
6700
 
                                } /* endif test convex */
6701
 
                        }
6702
 
                }
6703
 
                eed= nexted;
6704
 
        }
6705
 
        free_tagged_edgelist(em->edges.first);
6706
 
        free_tagged_facelist(em->faces.first);
6707
 
 
6708
 
        MEM_freeN(evlar);
6709
 
        
6710
 
        allqueue(REDRAWVIEW3D, 0);
6711
 
        makeDispList(G.obedit);
6712
 
 
6713
 
}
6714
 
 
6715
 
/* quick hack, basically a copy of beauty_fill */
6716
 
void edge_flip(void)
6717
 
{
6718
 
        EditMesh *em = G.editMesh;
6719
 
        EditVert *v1, *v2, *v3, *v4;
6720
 
        EditEdge *eed, *nexted;
6721
 
        EditVlak *evl, *w;
6722
 
        //void **evlar, **evla;
6723
 
        EVPTuple *evlar;
6724
 
        EVPtr *evla;
6725
 
 
6726
 
        float *uv[4];
6727
 
        unsigned int col[4];
6728
 
 
6729
 
        int totedge, ok;
6730
 
        
6731
 
        /* - all selected edges with two faces
6732
 
         * - find the faces: store them in edges (using datablock)
6733
 
         * - per edge: - test convex
6734
 
         *                         - test edge: flip?
6735
 
                                                - if true: remedge,  addedge, all edges at the edge get new face pointers
6736
 
         */
6737
 
 
6738
 
        totedge = count_edges(em->edges.first);
6739
 
        if(totedge==0) return;
6740
 
 
6741
 
        undo_push_mesh("Flip edges");
6742
 
        
6743
 
        /* temporary array for : edge -> face[1], face[2] */
6744
 
        evlar= (EVPTuple *) MEM_callocN(totedge * sizeof(EVPTuple), "edgeflip");
6745
 
 
6746
 
        ok = collect_quadedges(evlar, em->edges.first, em->faces.first);
6747
 
        
6748
 
        eed= em->edges.first;
6749
 
        while(eed) {
6750
 
                nexted= eed->next;
6751
 
                
6752
 
                if(eed->f==2) {  /* points to 2 faces */
6753
 
                        
6754
 
                        evla= (EVPtr *) eed->vn;
6755
 
                        
6756
 
                        /* don't do it if flagged */
6757
 
 
6758
 
                        ok= 1;
6759
 
                        evl= evla[0];
6760
 
                        if(evl->e1->f1 || evl->e2->f1 || evl->e3->f1) ok= 0;
6761
 
                        evl= evla[1];
6762
 
                        if(evl->e1->f1 || evl->e2->f1 || evl->e3->f1) ok= 0;
6763
 
                        
6764
 
                        if(ok) {
6765
 
                                /* test convex */
6766
 
                                givequadverts(evla[0], evla[1], &v1, &v2, &v3, &v4, uv, col);
6767
 
 
6768
 
/*
6769
 
                4-----3        4-----3
6770
 
                |\    |        |    /|
6771
 
                | \ 1 |        | 1 / |
6772
 
                |  \  |  ->    |  /  |  
6773
 
                | 0 \ |        | / 0 | 
6774
 
                |    \|        |/    |
6775
 
                1-----2        1-----2
6776
 
*/
6777
 
                                /* make new faces */
6778
 
                                if (v1 && v2 && v3){
6779
 
                                        if( convex(v1->co, v2->co, v3->co, v4->co) > 0.01) {
6780
 
                                                if(exist_vlak(v1, v2, v3, v4)==0) {
6781
 
                                                        w = addvlaklist(v1, v2, v3, 0, evla[1]);
6782
 
                                                        
6783
 
                                                        untag_edges(w);
6784
 
 
6785
 
                                                        UVCOPY(w->tf.uv[0], uv[0]);
6786
 
                                                        UVCOPY(w->tf.uv[1], uv[1]);
6787
 
                                                        UVCOPY(w->tf.uv[2], uv[2]);
6788
 
 
6789
 
                                                        w->tf.col[0] = col[0]; w->tf.col[1] = col[1]; w->tf.col[2] = col[2]; 
6790
 
                                                        
6791
 
                                                        w = addvlaklist(v1, v3, v4, 0, evla[1]);
6792
 
                                                        untag_edges(w);
6793
 
 
6794
 
                                                        UVCOPY(w->tf.uv[0], uv[0]);
6795
 
                                                        UVCOPY(w->tf.uv[1], uv[2]);
6796
 
                                                        UVCOPY(w->tf.uv[2], uv[3]);
6797
 
 
6798
 
                                                        w->tf.col[0] = col[0]; w->tf.col[1] = col[2]; w->tf.col[2] = col[3]; 
6799
 
                                                        
6800
 
                                                        /* erase old faces and edge */
6801
 
                                                }
6802
 
                                                /* tag as to-be-removed */
6803
 
                                                FACE_MARKCLEAR(evla[1]);
6804
 
                                                FACE_MARKCLEAR(evla[0]);
6805
 
                                                eed->f1 = 1; 
6806
 
                                                
6807
 
                                        } /* endif test convex */
6808
 
                                }
6809
 
                        }
6810
 
                }
6811
 
                eed= nexted;
6812
 
        }
6813
 
 
6814
 
        /* clear tagged edges and faces: */
6815
 
        free_tagged_edgelist(em->edges.first);
6816
 
        free_tagged_facelist(em->faces.first);
6817
 
                
6818
 
        MEM_freeN(evlar);
6819
 
        
6820
 
        allqueue(REDRAWVIEW3D, 0);
6821
 
        makeDispList(G.obedit);
6822
 
}
6823
 
                                                
6824
 
void beauty_fill(void)
6825
 
{
6826
 
        EditMesh *em = G.editMesh;
6827
 
    EditVert *v1, *v2, *v3, *v4;
6828
 
    EditEdge *eed, *nexted;
6829
 
    EditEdge dia1, dia2;
6830
 
    EditVlak *evl, *w;
6831
 
    // void **evlar, **evla;
6832
 
    EVPTuple *evlar;
6833
 
    EVPtr *evla;
6834
 
    float *uv[4];
6835
 
    unsigned int col[4];
6836
 
    float len1, len2, len3, len4, len5, len6, opp1, opp2, fac1, fac2;
6837
 
    int totedge, ok, notbeauty=8, onedone;
6838
 
 
6839
 
        /* - all selected edges with two faces
6840
 
                * - find the faces: store them in edges (using datablock)
6841
 
                * - per edge: - test convex
6842
 
                *                          - test edge: flip?
6843
 
                *               - if true: remedge,  addedge, all edges at the edge get new face pointers
6844
 
                */
6845
 
        
6846
 
    totedge = count_edges(em->edges.first);
6847
 
    if(totedge==0) return;
6848
 
 
6849
 
    if(okee("Beauty Fill")==0) return;
6850
 
    
6851
 
    undo_push_mesh("Beauty Fill");
6852
 
 
6853
 
    /* temp block with face pointers */
6854
 
    evlar= (EVPTuple *) MEM_callocN(totedge * sizeof(EVPTuple), "beautyfill");
6855
 
 
6856
 
    while (notbeauty) {
6857
 
        notbeauty--;
6858
 
 
6859
 
        ok = collect_quadedges(evlar, em->edges.first, em->faces.first);
6860
 
 
6861
 
        /* there we go */
6862
 
        onedone= 0;
6863
 
 
6864
 
        eed= em->edges.first;
6865
 
        while(eed) {
6866
 
            nexted= eed->next;
6867
 
 
6868
 
            if(eed->f==2) {
6869
 
 
6870
 
                evla = (EVPtr *) eed->vn;
6871
 
 
6872
 
                /* none of the faces should be treated before */
6873
 
                ok= 1;
6874
 
                evl= evla[0];
6875
 
                if(evl->e1->f1 || evl->e2->f1 || evl->e3->f1) ok= 0;
6876
 
                evl= evla[1];
6877
 
                if(evl->e1->f1 || evl->e2->f1 || evl->e3->f1) ok= 0;
6878
 
 
6879
 
                if(ok) {
6880
 
                    /* test convex */
6881
 
                    givequadverts(evla[0], evla[1], &v1, &v2, &v3, &v4, uv, col);
6882
 
                    if( convex(v1->co, v2->co, v3->co, v4->co) > -0.5) {
6883
 
 
6884
 
                        /* test edges */
6885
 
                        if( ((long)v1) > ((long)v3) ) {
6886
 
                            dia1.v1= v3;
6887
 
                            dia1.v2= v1;
6888
 
                        }
6889
 
                        else {
6890
 
                            dia1.v1= v1;
6891
 
                            dia1.v2= v3;
6892
 
                        }
6893
 
 
6894
 
                        if( ((long)v2) > ((long)v4) ) {
6895
 
                            dia2.v1= v4;
6896
 
                            dia2.v2= v2;
6897
 
                        }
6898
 
                        else {
6899
 
                            dia2.v1= v2;
6900
 
                            dia2.v2= v4;
6901
 
                        }
6902
 
 
6903
 
                        /* testing rule:
6904
 
                         * the area divided by the total edge lengths
6905
 
                         */
6906
 
 
6907
 
                        len1= VecLenf(v1->co, v2->co);
6908
 
                        len2= VecLenf(v2->co, v3->co);
6909
 
                        len3= VecLenf(v3->co, v4->co);
6910
 
                        len4= VecLenf(v4->co, v1->co);
6911
 
                        len5= VecLenf(v1->co, v3->co);
6912
 
                        len6= VecLenf(v2->co, v4->co);
6913
 
 
6914
 
                        opp1= AreaT3Dfl(v1->co, v2->co, v3->co);
6915
 
                        opp2= AreaT3Dfl(v1->co, v3->co, v4->co);
6916
 
 
6917
 
                        fac1= opp1/(len1+len2+len5) + opp2/(len3+len4+len5);
6918
 
 
6919
 
                        opp1= AreaT3Dfl(v2->co, v3->co, v4->co);
6920
 
                        opp2= AreaT3Dfl(v2->co, v4->co, v1->co);
6921
 
 
6922
 
                        fac2= opp1/(len2+len3+len6) + opp2/(len4+len1+len6);
6923
 
 
6924
 
                        ok= 0;
6925
 
                        if(fac1 > fac2) {
6926
 
                            if(dia2.v1==eed->v1 && dia2.v2==eed->v2) {
6927
 
                                eed->f1= 1;
6928
 
                                evl= evla[0];
6929
 
                                evl->f1= 1;
6930
 
                                evl= evla[1];
6931
 
                                evl->f1= 1;
6932
 
 
6933
 
                                w= addvlaklist(v1, v2, v3, 0, evl);
6934
 
 
6935
 
                                                                UVCOPY(w->tf.uv[0], uv[0]);
6936
 
                                                                UVCOPY(w->tf.uv[1], uv[1]);
6937
 
                                                                UVCOPY(w->tf.uv[2], uv[2]);
6938
 
 
6939
 
                                w->tf.col[0] = col[0]; w->tf.col[1] = col[1]; w->tf.col[2] = col[2];
6940
 
                                w= addvlaklist(v1, v3, v4, 0, evl);
6941
 
 
6942
 
                                                                UVCOPY(w->tf.uv[0], uv[0]);
6943
 
                                                                UVCOPY(w->tf.uv[1], uv[2]);
6944
 
                                                                UVCOPY(w->tf.uv[2], uv[3]);
6945
 
 
6946
 
                                w->tf.col[0] = col[0]; w->tf.col[1] = col[2]; w->tf.col[2] = col[3];
6947
 
 
6948
 
                                onedone= 1;
6949
 
                            }
6950
 
                        }
6951
 
                        else if(fac1 < fac2) {
6952
 
                            if(dia1.v1==eed->v1 && dia1.v2==eed->v2) {
6953
 
                                eed->f1= 1;
6954
 
                                evl= evla[0];
6955
 
                                evl->f1= 1;
6956
 
                                evl= evla[1];
6957
 
                                evl->f1= 1;
6958
 
 
6959
 
                                w= addvlaklist(v2, v3, v4, 0, evl);
6960
 
 
6961
 
                                                                UVCOPY(w->tf.uv[0], uv[1]);
6962
 
                                                                UVCOPY(w->tf.uv[1], uv[3]);
6963
 
                                                                UVCOPY(w->tf.uv[2], uv[4]);
6964
 
 
6965
 
                                w= addvlaklist(v1, v2, v4, 0, evl);
6966
 
 
6967
 
                                                                UVCOPY(w->tf.uv[0], uv[0]);
6968
 
                                                                UVCOPY(w->tf.uv[1], uv[1]);
6969
 
                                                                UVCOPY(w->tf.uv[2], uv[3]);
6970
 
 
6971
 
                                onedone= 1;
6972
 
                            }
6973
 
                        }
6974
 
                    }
6975
 
                }
6976
 
 
6977
 
            }
6978
 
            eed= nexted;
6979
 
        }
6980
 
 
6981
 
        free_tagged_edgelist(em->edges.first);
6982
 
        free_tagged_facelist(em->faces.first);
6983
 
 
6984
 
        if(onedone==0) break;
6985
 
    }
6986
 
 
6987
 
    MEM_freeN(evlar);
6988
 
 
6989
 
    allqueue(REDRAWVIEW3D, 0);
6990
 
    makeDispList(G.obedit);
6991
 
}
6992
 
 
6993
 
/** tests whether selected mesh objects have tfaces */
6994
 
static int testSelected_TfaceMesh(void)
6995
 
{
6996
 
        Base *base;
6997
 
        Mesh *me;
6998
 
 
6999
 
        base = FIRSTBASE;
7000
 
        while (base) {
7001
 
                if TESTBASE(base) {
7002
 
                        if(base->object->type==OB_MESH) {
7003
 
                                me= base->object->data;
7004
 
                                if (me->tface) 
7005
 
                                        return 1;
7006
 
                        }               
7007
 
                }                       
7008
 
                base= base->next;
7009
 
        }       
7010
 
        return 0;
7011
 
}       
7012
 
 
7013
 
void join_mesh(void)
7014
 
{
7015
 
        Base *base, *nextb;
7016
 
        Object *ob;
7017
 
        Material **matar, *ma;
7018
 
        Mesh *me;
7019
 
        MVert *mvert, *mvertmain;
7020
 
        MFace *mface = NULL, *mfacemain;
7021
 
        TFace *tface = NULL, *tfacemain;
7022
 
        unsigned int *mcol=NULL, *mcolmain;
7023
 
        float imat[4][4], cmat[4][4];
7024
 
        int a, b, totcol, totvert=0, totface=0, ok=0, vertofs, map[MAXMAT];
7025
 
#ifdef __NLA
7026
 
        int     i, j, index, haskey=0;
7027
 
        bDeformGroup *dg, *odg;
7028
 
        MDeformVert *dvert, *dvertmain;
7029
 
#endif
7030
 
        
7031
 
        if(G.obedit) return;
7032
 
        
7033
 
        ob= OBACT;
7034
 
        if(!ob || ob->type!=OB_MESH) return;
7035
 
        
7036
 
        /* count */
7037
 
        
7038
 
        base= FIRSTBASE;
7039
 
        while(base) {
7040
 
                if TESTBASE(base) {
7041
 
                        if(base->object->type==OB_MESH) {
7042
 
                                me= base->object->data;
7043
 
                                totvert+= me->totvert;
7044
 
                                totface+= me->totface;
7045
 
                                
7046
 
                                if(base->object == ob) ok= 1;
7047
 
                                if(me->key) {
7048
 
                                        haskey= 1;
7049
 
                                        break;
7050
 
                                }
7051
 
                        }
7052
 
                }
7053
 
                base= base->next;
7054
 
        }
7055
 
        
7056
 
        if(haskey) {
7057
 
                error("Join with vertex keys not supported");
7058
 
                return;
7059
 
        }
7060
 
        /* that way the active object is always selected */ 
7061
 
        if(ok==0) return;
7062
 
        
7063
 
        if(totvert==0 || totvert>MESH_MAX_VERTS) return;
7064
 
        
7065
 
        if(okee("Join selected Meshes")==0) return;
7066
 
        
7067
 
        /* new material indices and material array */
7068
 
        matar= MEM_callocN(sizeof(void *)*MAXMAT, "join_mesh");
7069
 
        totcol= ob->totcol;
7070
 
        
7071
 
        /* obact materials in new main array, is nicer start! */
7072
 
        for(a=1; a<=ob->totcol; a++) {
7073
 
                matar[a-1]= give_current_material(ob, a);
7074
 
                id_us_plus((ID *)matar[a-1]);
7075
 
                /* increase id->us : will be lowered later */
7076
 
        }
7077
 
        
7078
 
        base= FIRSTBASE;
7079
 
        while(base) {
7080
 
                if TESTBASE(base) {
7081
 
                        if(ob!=base->object && base->object->type==OB_MESH) {
7082
 
                                me= base->object->data;
7083
 
#ifdef __NLA
7084
 
                                // Join this object's vertex groups to the base one's
7085
 
                                for (dg=base->object->defbase.first; dg; dg=dg->next){
7086
 
                                        /* See if this group exists in the object */
7087
 
                                        for (odg=ob->defbase.first; odg; odg=odg->next){
7088
 
                                                if (!strcmp(odg->name, dg->name)){
7089
 
                                                        break;
7090
 
                                                }
7091
 
                                        }
7092
 
                                        if (!odg){
7093
 
                                                odg = MEM_callocN (sizeof(bDeformGroup), "deformGroup");
7094
 
                                                memcpy (odg, dg, sizeof(bDeformGroup));
7095
 
                                                BLI_addtail(&ob->defbase, odg);
7096
 
                                        }
7097
 
 
7098
 
                                }
7099
 
                                if (ob->defbase.first && ob->actdef==0)
7100
 
                                        ob->actdef=1;
7101
 
#endif
7102
 
                                if(me->totvert) {
7103
 
                                        for(a=1; a<=base->object->totcol; a++) {
7104
 
                                                ma= give_current_material(base->object, a);
7105
 
                                                if(ma) {
7106
 
                                                        for(b=0; b<totcol; b++) {
7107
 
                                                                if(ma == matar[b]) break;
7108
 
                                                        }
7109
 
                                                        if(b==totcol) {
7110
 
                                                                matar[b]= ma;
7111
 
                                                                ma->id.us++;
7112
 
                                                                totcol++;
7113
 
                                                        }
7114
 
                                                        if(totcol>=MAXMAT-1) break;
7115
 
                                                }
7116
 
                                        }
7117
 
                                }
7118
 
                        }
7119
 
                        if(totcol>=MAXMAT-1) break;
7120
 
                }
7121
 
                base= base->next;
7122
 
        }
7123
 
 
7124
 
        me= ob->data;
7125
 
        mvert= mvertmain= MEM_mallocN(totvert*sizeof(MVert), "joinmesh1");
7126
 
 
7127
 
        if (totface) mface= mfacemain= MEM_mallocN(totface*sizeof(MFace), "joinmesh2");
7128
 
        else mfacemain= 0;
7129
 
 
7130
 
        if(me->mcol) mcol= mcolmain= MEM_callocN(totface*4*sizeof(int), "joinmesh3");
7131
 
        else mcolmain= 0;
7132
 
 
7133
 
        /* if active object doesn't have Tfaces, but one in the selection does,
7134
 
           make TFaces for active, so we don't lose texture information in the
7135
 
           join process */
7136
 
        if(me->tface || testSelected_TfaceMesh()) tface= tfacemain= MEM_callocN(totface*4*sizeof(TFace), "joinmesh4");
7137
 
        else
7138
 
                tfacemain= 0;
7139
 
 
7140
 
#ifdef __NLA
7141
 
        if(me->dvert)
7142
 
                dvert= dvertmain= MEM_callocN(totvert*sizeof(MDeformVert), "joinmesh5");
7143
 
        else dvert=dvertmain= NULL;
7144
 
#endif
7145
 
 
7146
 
        vertofs= 0;
7147
 
        
7148
 
        /* inverse transorm all selected meshes in this object */
7149
 
        Mat4Invert(imat, ob->obmat);
7150
 
        
7151
 
        base= FIRSTBASE;
7152
 
        while(base) {
7153
 
                nextb= base->next;
7154
 
                if TESTBASE(base) {
7155
 
                        if(base->object->type==OB_MESH) {
7156
 
                                
7157
 
                                me= base->object->data;
7158
 
                                
7159
 
                                if(me->totvert) {
7160
 
                                        
7161
 
                                        memcpy(mvert, me->mvert, me->totvert*sizeof(MVert));
7162
 
                                        
7163
 
#ifdef __NLA
7164
 
                                        copy_dverts(dvert, me->dvert, me->totvert);
7165
 
 
7166
 
                                        /* NEW VERSION */
7167
 
                                        if (dvertmain){
7168
 
                                                for (i=0; i<me->totvert; i++){
7169
 
                                                        for (j=0; j<dvert[i].totweight; j++){
7170
 
                                                                //      Find the old vertex group
7171
 
                                                                odg = BLI_findlink (&base->object->defbase, dvert[i].dw[j].def_nr);
7172
 
                                                                if(odg) {
7173
 
                                                                        //      Search for a match in the new object
7174
 
                                                                        for (dg=ob->defbase.first, index=0; dg; dg=dg->next, index++){
7175
 
                                                                                if (!strcmp(dg->name, odg->name)){
7176
 
                                                                                        dvert[i].dw[j].def_nr = index;
7177
 
                                                                                        break;
7178
 
                                                                                }
7179
 
                                                                        }
7180
 
                                                                }
7181
 
                                                        }
7182
 
                                                }
7183
 
                                                dvert+=me->totvert;
7184
 
                                        }
7185
 
 
7186
 
#endif
7187
 
                                        if(base->object != ob) {
7188
 
                                                /* watch this: switch matmul order really goes wrong */
7189
 
                                                Mat4MulMat4(cmat, base->object->obmat, imat);
7190
 
                                                
7191
 
                                                a= me->totvert;
7192
 
                                                while(a--) {
7193
 
                                                        Mat4MulVecfl(cmat, mvert->co);
7194
 
                                                        mvert++;
7195
 
                                                }
7196
 
                                        }
7197
 
                                        else mvert+= me->totvert;
7198
 
                                        
7199
 
                                        if(mcolmain) {
7200
 
                                                if(me->mcol) memcpy(mcol, me->mcol, me->totface*4*4);
7201
 
                                                mcol+= 4*me->totface;
7202
 
                                        }
7203
 
                                }
7204
 
                                if(me->totface) {
7205
 
                                
7206
 
                                        /* make mapping for materials */
7207
 
                                        memset(map, 0, 4*MAXMAT);
7208
 
                                        for(a=1; a<=base->object->totcol; a++) {
7209
 
                                                ma= give_current_material(base->object, a);
7210
 
                                                if(ma) {
7211
 
                                                        for(b=0; b<totcol; b++) {
7212
 
                                                                if(ma == matar[b]) {
7213
 
                                                                        map[a-1]= b;
7214
 
                                                                        break;
7215
 
                                                                }
7216
 
                                                        }
7217
 
                                                }
7218
 
                                        }
7219
 
 
7220
 
                                        memcpy(mface, me->mface, me->totface*sizeof(MFace));
7221
 
                                        
7222
 
                                        a= me->totface;
7223
 
                                        while(a--) {
7224
 
                                                mface->v1+= vertofs;
7225
 
                                                mface->v2+= vertofs;
7226
 
                                                if(mface->v3) mface->v3+= vertofs;
7227
 
                                                if(mface->v4) mface->v4+= vertofs;
7228
 
                                                
7229
 
                                                mface->mat_nr= map[(int)mface->mat_nr];
7230
 
                                                
7231
 
                                                mface++;
7232
 
                                        }
7233
 
                                        
7234
 
                                        if(tfacemain) {
7235
 
                                                if(me->tface) memcpy(tface, me->tface, me->totface*sizeof(TFace));
7236
 
                                                tface+= me->totface;
7237
 
                                        }
7238
 
                                        
7239
 
                                }
7240
 
                                vertofs+= me->totvert;
7241
 
                                
7242
 
                                if(base->object!=ob) {
7243
 
                                        free_and_unlink_base(base);
7244
 
                                }
7245
 
                        }
7246
 
                }
7247
 
                base= nextb;
7248
 
        }
7249
 
        
7250
 
        me= ob->data;
7251
 
        
7252
 
        if(me->mface) MEM_freeN(me->mface);
7253
 
        me->mface= mfacemain;
7254
 
        if(me->mvert) MEM_freeN(me->mvert);
7255
 
#ifdef __NLA
7256
 
        if(me->dvert) free_dverts(me->dvert, me->totvert);
7257
 
        me->dvert = dvertmain;
7258
 
#endif
7259
 
        me->mvert= mvertmain;
7260
 
        if(me->mcol) MEM_freeN(me->mcol);
7261
 
        me->mcol= (MCol *)mcolmain;
7262
 
        if(me->tface) MEM_freeN(me->tface);
7263
 
        me->tface= tfacemain;
7264
 
        me->totvert= totvert;
7265
 
        me->totface= totface;
7266
 
        
7267
 
        /* old material array */
7268
 
        for(a=1; a<=ob->totcol; a++) {
7269
 
                ma= ob->mat[a-1];
7270
 
                if(ma) ma->id.us--;
7271
 
        }
7272
 
        for(a=1; a<=me->totcol; a++) {
7273
 
                ma= me->mat[a-1];
7274
 
                if(ma) ma->id.us--;
7275
 
        }
7276
 
        if(ob->mat) MEM_freeN(ob->mat);
7277
 
        if(me->mat) MEM_freeN(me->mat);
7278
 
        ob->mat= me->mat= 0;
7279
 
        
7280
 
        if(totcol) {
7281
 
                me->mat= matar;
7282
 
                ob->mat= MEM_callocN(sizeof(void *)*totcol, "join obmatar");
7283
 
        }
7284
 
        else MEM_freeN(matar);
7285
 
        
7286
 
        ob->totcol= me->totcol= totcol;
7287
 
        ob->colbits= 0;
7288
 
        
7289
 
        /* other mesh users */
7290
 
        test_object_materials((ID *)me);
7291
 
        
7292
 
        enter_editmode();
7293
 
        exit_editmode(1);
7294
 
        
7295
 
        allqueue(REDRAWVIEW3D, 0);
7296
 
        allqueue(REDRAWBUTSSHADING, 0);
7297
 
        makeDispList(G.obedit);
7298
 
 
7299
 
}
7300
 
 
7301
 
void clever_numbuts_mesh(void)
7302
 
{
7303
 
        EditMesh *em = G.editMesh;
7304
 
        EditVert *eve;
7305
 
        
7306
 
        eve= em->verts.first;
7307
 
        while(eve) {
7308
 
                if(eve->f & 1) break;
7309
 
                eve= eve->next;
7310
 
        }
7311
 
        if(eve==0) return;
7312
 
 
7313
 
        add_numbut(0, NUM|FLO, "LocX:", -G.vd->far, G.vd->far, eve->co, 0);
7314
 
        add_numbut(1, NUM|FLO, "LocY:", -G.vd->far, G.vd->far, eve->co+1, 0);
7315
 
        add_numbut(2, NUM|FLO, "LocZ:", -G.vd->far, G.vd->far, eve->co+2, 0);
7316
 
        
7317
 
        do_clever_numbuts("Active Vertex", 3, REDRAW);
7318
 
}
7319
 
 
7320
 
 
7321
 
static void permutate(void *list, int num, int size, int *index)
7322
 
{
7323
 
        void *buf;
7324
 
        int len;
7325
 
        int i;
7326
 
 
7327
 
        len = num * size;
7328
 
 
7329
 
        buf = MEM_mallocN(len, "permutate");
7330
 
        memcpy(buf, list, len);
7331
 
        
7332
 
        for (i = 0; i < num; i++) {
7333
 
                memcpy((char *)list + (i * size), (char *)buf + (index[i] * size), size);
7334
 
        }
7335
 
        MEM_freeN(buf);
7336
 
}
7337
 
 
7338
 
static MVert *mvertbase;
7339
 
static MFace *mfacebase;
7340
 
 
7341
 
static int verg_mface(const void *v1, const void *v2)
7342
 
{
7343
 
        MFace *x1, *x2;
7344
 
 
7345
 
        MVert *ve1, *ve2;
7346
 
        int i1, i2;
7347
 
 
7348
 
        i1 = ((int *) v1)[0];
7349
 
        i2 = ((int *) v2)[0];
7350
 
        
7351
 
        x1 = mfacebase + i1;
7352
 
        x2 = mfacebase + i2;
7353
 
 
7354
 
        ve1= mvertbase+x1->v1;
7355
 
        ve2= mvertbase+x2->v1;
7356
 
        
7357
 
        if( ve1->co[2] > ve2->co[2] ) return 1;
7358
 
        else if( ve1->co[2] < ve2->co[2]) return -1;
7359
 
        return 0;
7360
 
}
7361
 
 
7362
 
 
7363
 
void sort_faces(void)
7364
 
{
7365
 
        Object *ob= OBACT;
7366
 
        Mesh *me;
7367
 
        
7368
 
        int i, *index;
7369
 
        
7370
 
        if(ob==0) return;
7371
 
        if(G.obedit) return;
7372
 
        if(ob->type!=OB_MESH) return;
7373
 
        
7374
 
        if(okee("Sort Faces in Z")==0) return;
7375
 
        me= ob->data;
7376
 
        if(me->totface==0) return;
7377
 
 
7378
 
/*      create index list */
7379
 
        index = (int *) MEM_mallocN(sizeof(int) * me->totface, "sort faces");
7380
 
        for (i = 0; i < me->totface; i++) {
7381
 
                index[i] = i;
7382
 
        }
7383
 
        mvertbase= me->mvert;
7384
 
        mfacebase = me->mface;
7385
 
 
7386
 
/* sort index list instead of faces itself 
7387
 
   and apply this permutation to the face list plus
7388
 
   to the texture faces */
7389
 
        qsort(index, me->totface, sizeof(int), verg_mface);
7390
 
 
7391
 
        permutate(mfacebase, me->totface, sizeof(MFace), index);
7392
 
        if (me->tface) 
7393
 
                permutate(me->tface, me->totface, sizeof(TFace), index);
7394
 
 
7395
 
        MEM_freeN(index);
7396
 
 
7397
 
        allqueue(REDRAWVIEW3D, 0);
7398
 
        makeDispList(G.obedit);
7399
 
}
7400
 
 
7401
 
void vertices_to_sphere(void)
7402
 
{
7403
 
        EditMesh *em = G.editMesh;
7404
 
        EditVert *eve;
7405
 
        Object *ob= OBACT;
7406
 
        float *curs, len, vec[3], cent[3], fac, facm, imat[3][3], bmat[3][3];
7407
 
        int tot;
7408
 
        short perc=100;
7409
 
        
7410
 
        if(ob==0) return;
7411
 
        TEST_EDITMESH
7412
 
        
7413
 
        if(button(&perc, 1, 100, "Percentage:")==0) return;
7414
 
        
7415
 
        undo_push_mesh("To Sphere");
7416
 
        
7417
 
        fac= perc/100.0;
7418
 
        facm= 1.0-fac;
7419
 
        
7420
 
        Mat3CpyMat4(bmat, ob->obmat);
7421
 
        Mat3Inv(imat, bmat);
7422
 
 
7423
 
        /* centre */
7424
 
        curs= give_cursor();
7425
 
        cent[0]= curs[0]-ob->obmat[3][0];
7426
 
        cent[1]= curs[1]-ob->obmat[3][1];
7427
 
        cent[2]= curs[2]-ob->obmat[3][2];
7428
 
        Mat3MulVecfl(imat, cent);
7429
 
 
7430
 
        len= 0.0;
7431
 
        tot= 0;
7432
 
        eve= em->verts.first;
7433
 
        while(eve) {
7434
 
                if(eve->f & 1) {
7435
 
                        tot++;
7436
 
                        len+= VecLenf(cent, eve->co);
7437
 
                }
7438
 
                eve= eve->next;
7439
 
        }
7440
 
        len/=tot;
7441
 
        
7442
 
        if(len==0.0) len= 10.0;
7443
 
        
7444
 
        eve= em->verts.first;
7445
 
        while(eve) {
7446
 
                if(eve->f & 1) {
7447
 
                        vec[0]= eve->co[0]-cent[0];
7448
 
                        vec[1]= eve->co[1]-cent[1];
7449
 
                        vec[2]= eve->co[2]-cent[2];
7450
 
                        
7451
 
                        Normalise(vec);
7452
 
                        
7453
 
                        eve->co[0]= fac*(cent[0]+vec[0]*len) + facm*eve->co[0];
7454
 
                        eve->co[1]= fac*(cent[1]+vec[1]*len) + facm*eve->co[1];
7455
 
                        eve->co[2]= fac*(cent[2]+vec[2]*len) + facm*eve->co[2];
7456
 
                        
7457
 
                }
7458
 
                eve= eve->next;
7459
 
        }
7460
 
        
7461
 
        allqueue(REDRAWVIEW3D, 0);
7462
 
        makeDispList(G.obedit);
7463
 
}
7464
 
 
7465
 
/* Got this from scanfill.c. You will need to juggle around the
7466
 
 * callbacks for the scanfill.c code a bit for this to work. */
7467
 
void fill_mesh(void)
7468
 
{
7469
 
        EditMesh *em = G.editMesh;
7470
 
        EditVert *eve,*v1;
7471
 
        EditEdge *eed,*e1,*nexted;
7472
 
        EditVlak *evl,*nextvl;
7473
 
        short ok;
7474
 
 
7475
 
        if(G.obedit==0 || (G.obedit->type!=OB_MESH)) return;
7476
 
 
7477
 
        waitcursor(1);
7478
 
 
7479
 
        undo_push_mesh("Fill");
7480
 
 
7481
 
        /* copy all selected vertices */
7482
 
        eve= em->verts.first;
7483
 
        while(eve) {
7484
 
                if(eve->f & 1) {
7485
 
                        v1= BLI_addfillvert(eve->co);
7486
 
                        eve->vn= v1;
7487
 
                        v1->vn= eve;
7488
 
                        v1->h= 0;
7489
 
                }
7490
 
                eve= eve->next;
7491
 
        }
7492
 
        /* copy all selected edges */
7493
 
        eed= em->edges.first;
7494
 
        while(eed) {
7495
 
                if( (eed->v1->f & 1) && (eed->v2->f & 1) ) {
7496
 
                        e1= BLI_addfilledge(eed->v1->vn, eed->v2->vn);
7497
 
                        e1->v1->h++; 
7498
 
                        e1->v2->h++;
7499
 
                }
7500
 
                eed= eed->next;
7501
 
        }
7502
 
        /* from all selected faces: remove vertices and edges verwijderen to prevent doubles */
7503
 
        /* all edges add values, faces subtract,
7504
 
           then remove edges with vertices ->h<2 */
7505
 
        evl= em->faces.first;
7506
 
        ok= 0;
7507
 
        while(evl) {
7508
 
                nextvl= evl->next;
7509
 
                if( vlakselectedAND(evl, 1) ) {
7510
 
                        evl->v1->vn->h--;
7511
 
                        evl->v2->vn->h--;
7512
 
                        evl->v3->vn->h--;
7513
 
                        if(evl->v4) evl->v4->vn->h--;
7514
 
                        ok= 1;
7515
 
                        
7516
 
                }
7517
 
                evl= nextvl;
7518
 
        }
7519
 
        if(ok) {        /* there are faces selected */
7520
 
                eed= filledgebase.first;
7521
 
                while(eed) {
7522
 
                        nexted= eed->next;
7523
 
                        if(eed->v1->h<2 || eed->v2->h<2) {
7524
 
                                BLI_remlink(&filledgebase,eed);
7525
 
                        }
7526
 
                        eed= nexted;
7527
 
                }
7528
 
        }
7529
 
 
7530
 
        /* to make edgefill work */
7531
 
        BLI_setScanFillObjectRef(G.obedit);
7532
 
        BLI_setScanFillColourRef(&G.obedit->actcol);
7533
 
 
7534
 
        ok= BLI_edgefill(0);
7535
 
 
7536
 
        /* printf("time: %d\n",(clock()-tijd)/1000); */
7537
 
 
7538
 
        if(ok) {
7539
 
                evl= fillvlakbase.first;
7540
 
                while(evl) {
7541
 
                        addvlaklist(evl->v1->vn, evl->v2->vn, evl->v3->vn, 0, evl);
7542
 
                        evl= evl->next;
7543
 
                }
7544
 
        }
7545
 
        /* else printf("fill error\n"); */
7546
 
 
7547
 
        BLI_end_edgefill();
7548
 
 
7549
 
        waitcursor(0);
7550
 
 
7551
 
        countall();
7552
 
        allqueue(REDRAWVIEW3D, 0);
7553
 
        makeDispList(G.obedit);
7554
 
}
7555
 
 
7556
 
/* ***************** */
7557
 
 
7558
 
/* this one for NOT in editmode 
7559
 
 
7560
 
(only used by external modules, that is, until now by the 
7561
 
python NMesh module) 
7562
 
 
7563
 
TODO: Probably it's better to convert the mesh into a EditMesh, call
7564
 
vertexnormals() and convert it back to a Mesh again.
7565
 
 
7566
 
*/
7567
 
 
7568
 
void vertexnormals_mesh(Mesh *me, float *extverts)
7569
 
{
7570
 
        MVert *mvert;
7571
 
        MFace *mface;
7572
 
        float n1[3], n2[3], n3[3], n4[3], co[4], fac1, fac2, fac3, fac4, *temp;
7573
 
        float *f1, *f2, *f3, *f4, xn, yn, zn, *normals;
7574
 
        float *v1, *v2, *v3, *v4, len, vnor[3];
7575
 
        int a, testflip;
7576
 
 
7577
 
        if(me->totvert==0) return;
7578
 
 
7579
 
        testflip= (me->flag & ME_NOPUNOFLIP)==0;
7580
 
        if((me->flag & ME_TWOSIDED)==0) testflip= 0;    /* large angles */
7581
 
        
7582
 
        if(me->totface==0) {
7583
 
                /* fake vertex normals for 'halopuno' (render option) */
7584
 
                mvert= me->mvert;
7585
 
                for(a=0; a<me->totvert; a++, mvert++) {
7586
 
                        VECCOPY(n1, mvert->co);
7587
 
                        Normalise(n1);
7588
 
                        mvert->no[0]= 32767.0*n1[0];
7589
 
                        mvert->no[1]= 32767.0*n1[1];
7590
 
                        mvert->no[2]= 32767.0*n1[2];
7591
 
                }
7592
 
                return;
7593
 
        }
7594
 
 
7595
 
        normals= MEM_callocN(me->totvert*3*sizeof(float), "normals");
7596
 
        
7597
 
        /* calculate cosine angles, and add to vertex normal */
7598
 
        mface= me->mface;
7599
 
        mvert= me->mvert;
7600
 
        for(a=0; a<me->totface; a++, mface++) {
7601
 
                
7602
 
                if(mface->v3==0) continue;
7603
 
                
7604
 
                if(extverts) {
7605
 
                        v1= extverts+3*mface->v1;
7606
 
                        v2= extverts+3*mface->v2;
7607
 
                        v3= extverts+3*mface->v3;
7608
 
                        v4= extverts+3*mface->v4;
7609
 
                }
7610
 
                else {          
7611
 
                        v1= (mvert+mface->v1)->co;
7612
 
                        v2= (mvert+mface->v2)->co;
7613
 
                        v3= (mvert+mface->v3)->co;
7614
 
                        v4= (mvert+mface->v4)->co;
7615
 
                }
7616
 
                
7617
 
                VecSubf(n1, v2, v1);
7618
 
                VecSubf(n2, v3, v2);
7619
 
                Normalise(n1);
7620
 
                Normalise(n2);
7621
 
 
7622
 
                if(mface->v4==0) {
7623
 
                        VecSubf(n3, v1, v3);
7624
 
                        Normalise(n3);
7625
 
                        
7626
 
                        co[0]= saacos(-n3[0]*n1[0]-n3[1]*n1[1]-n3[2]*n1[2]);
7627
 
                        co[1]= saacos(-n1[0]*n2[0]-n1[1]*n2[1]-n1[2]*n2[2]);
7628
 
                        co[2]= saacos(-n2[0]*n3[0]-n2[1]*n3[1]-n2[2]*n3[2]);
7629
 
                        
7630
 
                }
7631
 
                else {
7632
 
                        VecSubf(n3, v4, v3);
7633
 
                        VecSubf(n4, v1, v4);
7634
 
                        Normalise(n3);
7635
 
                        Normalise(n4);
7636
 
 
7637
 
                        co[0]= saacos(-n4[0]*n1[0]-n4[1]*n1[1]-n4[2]*n1[2]);
7638
 
                        co[1]= saacos(-n1[0]*n2[0]-n1[1]*n2[1]-n1[2]*n2[2]);
7639
 
                        co[2]= saacos(-n2[0]*n3[0]-n2[1]*n3[1]-n2[2]*n3[2]);
7640
 
                        co[3]= saacos(-n3[0]*n4[0]-n3[1]*n4[1]-n3[2]*n4[2]);
7641
 
                }
7642
 
                
7643
 
                CalcNormFloat(v1, v2, v3, vnor);
7644
 
                
7645
 
                temp= normals+3*mface->v1;
7646
 
                if(testflip && contrpuntnorm(vnor, temp) ) co[0]= -co[0];
7647
 
                temp[0]+= co[0]*vnor[0];
7648
 
                temp[1]+= co[0]*vnor[1];
7649
 
                temp[2]+= co[0]*vnor[2];
7650
 
                
7651
 
                temp= normals+3*mface->v2;
7652
 
                if(testflip && contrpuntnorm(vnor, temp) ) co[1]= -co[1];
7653
 
                temp[0]+= co[1]*vnor[0];
7654
 
                temp[1]+= co[1]*vnor[1];
7655
 
                temp[2]+= co[1]*vnor[2];
7656
 
                
7657
 
                temp= normals+3*mface->v3;
7658
 
                if(testflip && contrpuntnorm(vnor, temp) ) co[2]= -co[2];
7659
 
                temp[0]+= co[2]*vnor[0];
7660
 
                temp[1]+= co[2]*vnor[1];
7661
 
                temp[2]+= co[2]*vnor[2];
7662
 
                
7663
 
                if(mface->v4) {
7664
 
                        temp= normals+3*mface->v4;
7665
 
                        if(testflip && contrpuntnorm(vnor, temp) ) co[3]= -co[3];
7666
 
                        temp[0]+= co[3]*vnor[0];
7667
 
                        temp[1]+= co[3]*vnor[1];
7668
 
                        temp[2]+= co[3]*vnor[2];
7669
 
                }
7670
 
        }
7671
 
 
7672
 
        /* normalize vertex normals */
7673
 
        mvert= me->mvert;
7674
 
        for(a=0; a<me->totvert; a++, mvert++) {
7675
 
                len= Normalise(normals+3*a);
7676
 
                if(len!=0.0) {
7677
 
                        VECCOPY(n1, normals+3*a);
7678
 
                        Normalise(n1);
7679
 
 
7680
 
                        mvert->no[0]= 32767.0*n1[0];
7681
 
                        mvert->no[1]= 32767.0*n1[1];
7682
 
                        mvert->no[2]= 32767.0*n1[2];
7683
 
                }
7684
 
        }
7685
 
        
7686
 
        /* vertex normal flipping flags, for during render */
7687
 
        mface= me->mface;
7688
 
        mvert= me->mvert;
7689
 
        for(a=0; a<me->totface; a++, mface++) {
7690
 
                mface->puno=0;                  
7691
 
                
7692
 
                if(mface->v3==0) continue;
7693
 
                
7694
 
                if(extverts) {
7695
 
                        v1= extverts+3*mface->v1;
7696
 
                        v2= extverts+3*mface->v2;
7697
 
                        v3= extverts+3*mface->v3;
7698
 
                }
7699
 
                else {          
7700
 
                        v1= (mvert+mface->v1)->co;
7701
 
                        v2= (mvert+mface->v2)->co;
7702
 
                        v3= (mvert+mface->v3)->co;
7703
 
                }
7704
 
 
7705
 
                CalcNormFloat(v1, v2, v3, vnor);
7706
 
 
7707
 
                if(testflip) {
7708
 
                        f1= normals + 3*mface->v1;
7709
 
                        f2= normals + 3*mface->v2;
7710
 
                        f3= normals + 3*mface->v3;
7711
 
 
7712
 
                        fac1= vnor[0]*f1[0] + vnor[1]*f1[1] + vnor[2]*f1[2];
7713
 
                        if(fac1<0.0) {
7714
 
                                mface->puno = ME_FLIPV1;
7715
 
                        }
7716
 
                        fac2= vnor[0]*f2[0] + vnor[1]*f2[1] + vnor[2]*f2[2];
7717
 
                        if(fac2<0.0) {
7718
 
                                mface->puno += ME_FLIPV2;
7719
 
                        }
7720
 
                        fac3= vnor[0]*f3[0] + vnor[1]*f3[1] + vnor[2]*f3[2];
7721
 
                        if(fac3<0.0) {
7722
 
                                mface->puno += ME_FLIPV3;
7723
 
                        }
7724
 
                        if(mface->v4) {
7725
 
                                f4= normals + 3*mface->v4;
7726
 
                                fac4= vnor[0]*f4[0] + vnor[1]*f4[1] + vnor[2]*f4[2];
7727
 
                                if(fac4<0.0) {
7728
 
                                        mface->puno += ME_FLIPV4;
7729
 
                                }
7730
 
                        }
7731
 
                }
7732
 
                /* proj for cubemap! */
7733
 
                xn= fabs(vnor[0]);
7734
 
                yn= fabs(vnor[1]);
7735
 
                zn= fabs(vnor[2]);
7736
 
                
7737
 
                if(zn>xn && zn>yn) mface->puno += ME_PROJXY;
7738
 
                else if(yn>xn && yn>zn) mface->puno += ME_PROJXZ;
7739
 
                else mface->puno += ME_PROJYZ;
7740
 
                
7741
 
        }
7742
 
        
7743
 
        MEM_freeN(normals);
7744
 
}
7745
 
 
7746
 
/***/
7747
 
 
7748
 
static int editmesh_nfaces_selected(void)
7749
 
{
7750
 
        EditMesh *em = G.editMesh;
7751
 
        EditVlak *evl;
7752
 
        int count= 0;
7753
 
 
7754
 
        for (evl= em->faces.first; evl; evl= evl->next)
7755
 
                if (vlakselectedAND(evl, SELECT))
7756
 
                        count++;
7757
 
 
7758
 
        return count;
7759
 
}
7760
 
 
7761
 
static int editmesh_nvertices_selected(void)
7762
 
{
7763
 
        EditMesh *em = G.editMesh;
7764
 
        EditVert *eve;
7765
 
        int count= 0;
7766
 
 
7767
 
        for (eve= em->verts.first; eve; eve= eve->next)
7768
 
                if (eve->f & SELECT)
7769
 
                        count++;
7770
 
 
7771
 
        return count;
7772
 
}
7773
 
 
7774
 
static void editmesh_calc_selvert_center(float cent_r[3])
7775
 
{
7776
 
        EditMesh *em = G.editMesh;
7777
 
        EditVert *eve;
7778
 
        int nsel= 0;
7779
 
 
7780
 
        cent_r[0]= cent_r[1]= cent_r[0]= 0.0;
7781
 
 
7782
 
        for (eve= em->verts.first; eve; eve= eve->next) {
7783
 
                if (eve->f & SELECT) {
7784
 
                        cent_r[0]+= eve->co[0];
7785
 
                        cent_r[1]+= eve->co[1];
7786
 
                        cent_r[2]+= eve->co[2];
7787
 
                        nsel++;
7788
 
                }
7789
 
        }
7790
 
 
7791
 
        if (nsel) {
7792
 
                cent_r[0]/= nsel;
7793
 
                cent_r[1]/= nsel;
7794
 
                cent_r[2]/= nsel;
7795
 
        }
7796
 
}
7797
 
 
7798
 
static int tface_is_selected(TFace *tf)
7799
 
{
7800
 
        return (!(tf->flag & TF_HIDE) && (tf->flag & TF_SELECT));
7801
 
}
7802
 
 
7803
 
static int faceselect_nfaces_selected(Mesh *me)
7804
 
{
7805
 
        int i, count= 0;
7806
 
 
7807
 
        for (i=0; i<me->totface; i++) {
7808
 
                MFace *mf= ((MFace*) me->mface) + i;
7809
 
                TFace *tf= ((TFace*) me->tface) + i;
7810
 
 
7811
 
                if (mf->v3 && tface_is_selected(tf))
7812
 
                        count++;
7813
 
        }
7814
 
 
7815
 
        return count;
7816
 
}
7817
 
 
7818
 
        /* XXX, code for both these functions should be abstract,
7819
 
         * then unified, then written for other things (like objects,
7820
 
         * which would use same as vertices method), then added
7821
 
         * to interface! Hoera! - zr
7822
 
         */
7823
 
void faceselect_align_view_to_selected(View3D *v3d, Mesh *me, int axis)
7824
 
{
7825
 
        if (!faceselect_nfaces_selected(me)) {
7826
 
                error("No faces selected.");
7827
 
        } else {
7828
 
                float norm[3];
7829
 
                int i;
7830
 
 
7831
 
                norm[0]= norm[1]= norm[2]= 0.0;
7832
 
                for (i=0; i<me->totface; i++) {
7833
 
                        MFace *mf= ((MFace*) me->mface) + i;
7834
 
                        TFace *tf= ((TFace*) me->tface) + i;
7835
 
        
7836
 
                        if (mf->v3 && tface_is_selected(tf)) {
7837
 
                                float *v1, *v2, *v3, fno[3];
7838
 
 
7839
 
                                v1= me->mvert[mf->v1].co;
7840
 
                                v2= me->mvert[mf->v2].co;
7841
 
                                v3= me->mvert[mf->v3].co;
7842
 
                                if (mf->v4) {
7843
 
                                        float *v4= me->mvert[mf->v4].co;
7844
 
                                        CalcNormFloat4(v1, v2, v3, v4, fno);
7845
 
                                } else {
7846
 
                                        CalcNormFloat(v1, v2, v3, fno);
7847
 
                                }
7848
 
 
7849
 
                                norm[0]+= fno[0];
7850
 
                                norm[1]+= fno[1];
7851
 
                                norm[2]+= fno[2];
7852
 
                        }
7853
 
                }
7854
 
 
7855
 
                view3d_align_axis_to_vector(v3d, axis, norm);
7856
 
        }
7857
 
}
7858
 
 
7859
 
void editmesh_align_view_to_selected(View3D *v3d, int axis)
7860
 
{
7861
 
        EditMesh *em = G.editMesh;
7862
 
        int nselverts= editmesh_nvertices_selected();
7863
 
 
7864
 
        if (nselverts<3) {
7865
 
                if (nselverts==0) {
7866
 
                        error("No faces or vertices selected.");
7867
 
                } else {
7868
 
                        error("At least one face or three vertices must be selected.");
7869
 
                }
7870
 
        } else if (editmesh_nfaces_selected()) {
7871
 
                float norm[3];
7872
 
                EditVlak *evl;
7873
 
 
7874
 
                norm[0]= norm[1]= norm[2]= 0.0;
7875
 
                for (evl= em->faces.first; evl; evl= evl->next) {
7876
 
                        if (vlakselectedAND(evl, SELECT)) {
7877
 
                                float fno[3];
7878
 
                                if (evl->v4) CalcNormFloat4(evl->v1->co, evl->v2->co, evl->v3->co, evl->v4->co, fno);
7879
 
                                else CalcNormFloat(evl->v1->co, evl->v2->co, evl->v3->co, fno);
7880
 
                                                /* XXX, fixme, should be flipped intp a 
7881
 
                                                 * consistent direction. -zr
7882
 
                                                 */
7883
 
                                norm[0]+= fno[0];
7884
 
                                norm[1]+= fno[1];
7885
 
                                norm[2]+= fno[2];
7886
 
                        }
7887
 
                }
7888
 
 
7889
 
                Mat4Mul3Vecfl(G.obedit->obmat, norm);
7890
 
                view3d_align_axis_to_vector(v3d, axis, norm);
7891
 
        } else {
7892
 
                float cent[3], norm[3];
7893
 
                EditVert *eve, *leve= NULL;
7894
 
 
7895
 
                norm[0]= norm[1]= norm[2]= 0.0;
7896
 
                editmesh_calc_selvert_center(cent);
7897
 
                for (eve= em->verts.first; eve; eve= eve->next) {
7898
 
                        if (eve->f & SELECT) {
7899
 
                                if (leve) {
7900
 
                                        float tno[3];
7901
 
                                        CalcNormFloat(cent, leve->co, eve->co, tno);
7902
 
                                        
7903
 
                                                /* XXX, fixme, should be flipped intp a 
7904
 
                                                 * consistent direction. -zr
7905
 
                                                 */
7906
 
                                        norm[0]+= tno[0];
7907
 
                                        norm[1]+= tno[1];
7908
 
                                        norm[2]+= tno[2];
7909
 
                                }
7910
 
                                leve= eve;
7911
 
                        }
7912
 
                }
7913
 
 
7914
 
                Mat4Mul3Vecfl(G.obedit->obmat, norm);
7915
 
                view3d_align_axis_to_vector(v3d, axis, norm);
7916
 
        }
7917
 
}
7918
 
 
7919
 
/*  
7920
 
 
7921
 
Read a trail of mouse coords and return them as an array of CutCurve structs
7922
 
len returns number of mouse coords read before commiting with RETKEY   
7923
 
It is up to the caller to free the block when done with it,
7924
 
 
7925
 
this doesn't belong here.....
7926
 
 */
7927
 
 
7928
 
CutCurve *get_mouse_trail(int *len, char mode){
7929
 
 
7930
 
        CutCurve *curve,*temp;
7931
 
        short event, val, ldown=0, restart=0, rubberband=0;
7932
 
        short  mval[2], lockaxis=0, lockx=0, locky=0, lastx=0, lasty=0;
7933
 
        int i=0, j, blocks=1, lasti=0;
7934
 
        
7935
 
        *len=0;
7936
 
        curve=(CutCurve *)MEM_callocN(1024*sizeof(CutCurve), "MouseTrail");
7937
 
 
7938
 
        if (!curve) {
7939
 
                printf("failed to allocate memory in get_mouse_trail()\n");
7940
 
                return(NULL);
7941
 
        }
7942
 
        mywinset(curarea->win);
7943
 
        glDrawBuffer(GL_FRONT);
7944
 
        
7945
 
        headerprint("LMB to draw, Enter to finish, ESC to abort.");
7946
 
 
7947
 
        persp(PERSP_WIN);
7948
 
        
7949
 
        glColor3ub(200, 200, 0);
7950
 
        
7951
 
        while(TRUE) {
7952
 
                
7953
 
                event=extern_qread(&val);       /* Enter or RMB indicates finish */
7954
 
                if(val) {
7955
 
                        if(event==RETKEY || event==PADENTER) break;
7956
 
                }
7957
 
                
7958
 
                if( event==ESCKEY || event==RIGHTMOUSE ) {
7959
 
                        if (curve) MEM_freeN(curve);
7960
 
                        *len=0;
7961
 
                        glFinish();
7962
 
                        glDrawBuffer(GL_BACK);
7963
 
                        return(NULL);
7964
 
                        break;
7965
 
                }       
7966
 
                
7967
 
                if (rubberband)  { /* rubberband mode, undraw last rubberband */
7968
 
                        glLineWidth(2.0);
7969
 
                        sdrawXORline(curve[i-1].x, curve[i-1].y,mval[0], mval[1]); 
7970
 
                        glLineWidth(1.0);
7971
 
                        glFinish();
7972
 
                        rubberband=0;
7973
 
                }
7974
 
                
7975
 
                getmouseco_areawin(mval);
7976
 
                
7977
 
                if (lockaxis==1) mval[1]=locky;
7978
 
                if (lockaxis==2) mval[0]=lockx;
7979
 
                
7980
 
                if ( ((i==0) || (mval[0]!=curve[i-1].x) || (mval[1]!=curve[i-1].y))
7981
 
                        && (get_mbut() & L_MOUSE) ){ /* record changes only, if LMB down */
7982
 
                        
7983
 
                        lastx=curve[i].x=mval[0];
7984
 
                        lasty=curve[i].y=mval[1];
7985
 
                        
7986
 
                        lockaxis=0;
7987
 
                        
7988
 
                        i++; 
7989
 
                        
7990
 
                        ldown=1;
7991
 
                        if (restart) { 
7992
 
                                for(j=1;j<i;j++) sdrawXORline(curve[j-1].x, curve[j-1].y, curve[j].x, curve[j].y);
7993
 
                                if (rubberband) sdrawXORline(curve[j].x, curve[j].y, mval[0], mval[1]);
7994
 
                                glFinish();
7995
 
                                rubberband=0;
7996
 
                                lasti=i=0;
7997
 
                                restart=0;
7998
 
                                ldown=0;
7999
 
                        }
8000
 
                }
8001
 
                
8002
 
                if ((event==MIDDLEMOUSE)&&(get_mbut()&M_MOUSE)&&(i)){/*MMB Down*/
8003
 
                /*determine which axis to lock to, or clear if locked */
8004
 
                        if (lockaxis) lockaxis=0;
8005
 
                        else if (abs(curve[i-1].x-mval[0]) > abs(curve[i-1].y-mval[1])) lockaxis=1;
8006
 
                        else lockaxis=2;
8007
 
                        
8008
 
                        if (lockaxis) {
8009
 
                                lockx=lastx;
8010
 
                                locky=lasty;
8011
 
                        }
8012
 
                }
8013
 
                
8014
 
                if ((i>1)&&(i!=lasti)) {  /*Draw recorded part of curve */
8015
 
                        sdrawline(curve[i-2].x, curve[i-2].y, curve[i-1].x, curve[i-1].y);
8016
 
                        glFinish();
8017
 
                }
8018
 
                
8019
 
                if ((i==lasti)&&(i>0)) { /*Draw rubberband */
8020
 
                        glLineWidth(2.0);
8021
 
                        sdrawXORline(curve[i-1].x, curve[i-1].y,mval[0], mval[1]);
8022
 
                        glLineWidth(1.0);
8023
 
                        glFinish();
8024
 
                        rubberband=1;
8025
 
                }
8026
 
                lasti=i;
8027
 
 
8028
 
                if (i>=blocks*1024) { /* reallocate data if out of room */
8029
 
                        temp=curve;
8030
 
                        curve=(CutCurve *)MEM_callocN((blocks+1)*1024*sizeof(CutCurve), "MouseTrail");
8031
 
                        if (!curve) {
8032
 
                                printf("failed to re-allocate memory in get_mouse_trail()\n");
8033
 
                                return(NULL);
8034
 
                        }
8035
 
                        memcpy(curve, temp, blocks*1024*sizeof(CutCurve));
8036
 
                        blocks++;
8037
 
                        MEM_freeN(temp);
8038
 
                }
8039
 
        }
8040
 
 
8041
 
        glFinish();
8042
 
        glDrawBuffer(GL_BACK);
8043
 
        persp(PERSP_VIEW);
8044
 
 
8045
 
        *len=i;
8046
 
 
8047
 
        return(curve);
8048
 
}
8049
 
 
8050
 
/* ******************************************************************** */
8051
 
/* Knife Subdivide Tool.  Subdivides edges intersected by a mouse trail
8052
 
        drawn by user.
8053
 
        
8054
 
        Currently mapped to KKey when in MeshEdit mode.
8055
 
        Usage:
8056
 
                Hit Shift K, Select Centers or Exact
8057
 
                Hold LMB down to draw path, hit RETKEY.
8058
 
                ESC cancels as expected.
8059
 
   
8060
 
        Contributed by Robert Wenzlaff (Det. Thorn).
8061
 
*/
8062
 
 
8063
 
void KnifeSubdivide(char mode){
8064
 
        EditMesh *em = G.editMesh;
8065
 
        int oldcursor, len=0;
8066
 
        short isect=0;
8067
 
        CutCurve *curve;                
8068
 
        EditEdge *eed; 
8069
 
        Window *win;    
8070
 
        
8071
 
        if (G.obedit==0) return;
8072
 
 
8073
 
        if (editmesh_nvertices_selected() < 2) {
8074
 
                error("No edges are selected to operate on");
8075
 
                return;
8076
 
        }
8077
 
 
8078
 
        if (mode==KNIFE_PROMPT) {
8079
 
                short val= pupmenu("Cut Type %t|Exact Line%x1|Midpoints%x2");
8080
 
                if(val<1) return;
8081
 
                mode= val;      // warning, mode is char, pupmenu returns -1 with ESC
8082
 
        }
8083
 
 
8084
 
        undo_push_mesh("Knife");
8085
 
        
8086
 
        calc_meshverts_ext();  /*Update screen coords for current window */
8087
 
        
8088
 
        /* Set a knife cursor here */
8089
 
        oldcursor=get_cursor();
8090
 
 
8091
 
        win=winlay_get_active_window();
8092
 
        
8093
 
        SetBlenderCursor(BC_KNIFECURSOR);
8094
 
        
8095
 
        curve=get_mouse_trail(&len, TRAIL_MIXED);
8096
 
        
8097
 
        if (curve && len && mode){
8098
 
                eed= em->edges.first;           
8099
 
                while(eed) {    
8100
 
                        if((eed->v1->f&1)&&(eed->v2->f&1)){
8101
 
                                isect=seg_intersect(eed, curve, len);
8102
 
                                if (isect) eed->f=1;
8103
 
                                else eed->f=0;
8104
 
                                eed->f1=isect;
8105
 
                                //printf("isect=%i\n", isect);
8106
 
                        }
8107
 
                        else {
8108
 
                                eed->f=0;
8109
 
                                eed->f1=0;
8110
 
                        }
8111
 
                        eed= eed->next;
8112
 
                }
8113
 
                
8114
 
                if (mode==1) subdivideflag(1, 0, B_KNIFE|B_PERCENTSUBD);
8115
 
                else if (mode==2) subdivideflag(1, 0, B_KNIFE);
8116
 
                
8117
 
                eed=em->edges.first;
8118
 
                while(eed){
8119
 
                        eed->f=0;
8120
 
                        eed->f1=0;
8121
 
                        eed=eed->next;
8122
 
                }       
8123
 
        }
8124
 
        /* Return to old cursor and flags...*/
8125
 
        
8126
 
        addqueue(curarea->win,  REDRAW, 0);
8127
 
        window_set_cursor(win, oldcursor);
8128
 
        if (curve) MEM_freeN(curve);
8129
 
}
8130
 
 
8131
 
/* seg_intersect() Determines if and where a mouse trail intersects an EditEdge */
8132
 
 
8133
 
short seg_intersect(EditEdge *e, CutCurve *c, int len){
8134
 
#define MAXSLOPE 100000
8135
 
        short isect=0;
8136
 
        float  x11, y11, x12=0, y12=0, x2max, x2min, y2max;
8137
 
        float  y2min, dist, lastdist=0, xdiff2, xdiff1;
8138
 
        float  m1, b1, m2, b2, x21, x22, y21, y22, xi;
8139
 
        float  yi, x1min, x1max, y1max, y1min, perc=0; 
8140
 
        float  scr[2], co[4];
8141
 
        int  i;
8142
 
        
8143
 
        /* Get screen coords of verts (v->xs and v->ys clip if off screen */
8144
 
        VECCOPY(co, e->v1->co);
8145
 
        co[3]= 1.0;
8146
 
        Mat4MulVec4fl(G.obedit->obmat, co);
8147
 
        project_float(co, scr);
8148
 
        x21=scr[0];
8149
 
        y21=scr[1];
8150
 
        
8151
 
        VECCOPY(co, e->v2->co);
8152
 
        co[3]= 1.0;
8153
 
        Mat4MulVec4fl(G.obedit->obmat, co);
8154
 
        project_float(co, scr);
8155
 
        x22=scr[0];
8156
 
        y22=scr[1];
8157
 
        
8158
 
        xdiff2=(x22-x21);  
8159
 
        if (xdiff2) {
8160
 
                m2=(y22-y21)/xdiff2;
8161
 
                b2= ((x22*y21)-(x21*y22))/xdiff2;
8162
 
        }
8163
 
        else {
8164
 
                m2=MAXSLOPE;  /* Verticle slope  */
8165
 
                b2=x22;      
8166
 
        }
8167
 
        for (i=0; i<len; i++){
8168
 
                if (i>0){
8169
 
                        x11=x12;
8170
 
                        y11=y12;
8171
 
                }
8172
 
                else {
8173
 
                        x11=c[i].x;
8174
 
                        y11=c[i].y;
8175
 
                }
8176
 
                x12=c[i].x;
8177
 
                y12=c[i].y;
8178
 
 
8179
 
                /* Perp. Distance from point to line */
8180
 
                if (m2!=MAXSLOPE) dist=(y12-m2*x12-b2);/* /sqrt(m2*m2+1); Only looking for */
8181
 
                                                       /* change in sign.  Skip extra math */   
8182
 
                else dist=x22-x12;      
8183
 
                
8184
 
                if (i==0) lastdist=dist;
8185
 
                
8186
 
                /* if dist changes sign, and intersect point in edge's Bound Box*/
8187
 
                if ((lastdist*dist)<=0){
8188
 
                        xdiff1=(x12-x11); /* Equation of line between last 2 points */
8189
 
                        if (xdiff1){
8190
 
                                m1=(y12-y11)/xdiff1;
8191
 
                                b1= ((x12*y11)-(x11*y12))/xdiff1;
8192
 
                        }
8193
 
                        else{
8194
 
                                m1=MAXSLOPE;
8195
 
                                b1=x12;
8196
 
                        }
8197
 
                        x2max=MAX2(x21,x22)+0.001; /* prevent missed edges   */
8198
 
                        x2min=MIN2(x21,x22)-0.001; /* due to round off error */
8199
 
                        y2max=MAX2(y21,y22)+0.001;
8200
 
                        y2min=MIN2(y21,y22)-0.001;
8201
 
                        
8202
 
                        /* Found an intersect,  calc intersect point */
8203
 
                        if (m1==m2){            /* co-incident lines */
8204
 
                                                /* cut at 50% of overlap area*/
8205
 
                                x1max=MAX2(x11, x12);
8206
 
                                x1min=MIN2(x11, x12);
8207
 
                                xi= (MIN2(x2max,x1max)+MAX2(x2min,x1min))/2.0;  
8208
 
                                
8209
 
                                y1max=MAX2(y11, y12);
8210
 
                                y1min=MIN2(y11, y12);
8211
 
                                yi= (MIN2(y2max,y1max)+MAX2(y2min,y1min))/2.0;
8212
 
                        }                       
8213
 
                        else if (m2==MAXSLOPE){ 
8214
 
                                xi=x22;
8215
 
                                yi=m1*x22+b1;
8216
 
                        }
8217
 
                        else if (m1==MAXSLOPE){ 
8218
 
                                xi=x12;
8219
 
                                yi=m2*x12+b2;
8220
 
                        }
8221
 
                        else {
8222
 
                                xi=(b1-b2)/(m2-m1);
8223
 
                                yi=(b1*m2-m1*b2)/(m2-m1);
8224
 
                        }
8225
 
                        
8226
 
                        /* Intersect inside bounding box of edge?*/
8227
 
                        if ((xi>=x2min)&&(xi<=x2max)&&(yi<=y2max)&&(yi>=y2min)){
8228
 
                                if ((m2<=1.0)&&(m2>=-1.0)) perc = (xi-x21)/(x22-x21);   
8229
 
                                else perc=(yi-y21)/(y22-y21); /*lower slope more accurate*/
8230
 
                                isect=32768.0*(perc+0.0000153); /* Percentage in 1/32768ths */
8231
 
                                break;
8232
 
                        }
8233
 
                }       
8234
 
                lastdist=dist;
8235
 
        }
8236
 
        return(isect);
8237
 
8238
 
 
8239
 
 
8240
 
void LoopMenu(){ /* Called by KKey */
8241
 
 
8242
 
        short ret;
8243
 
        
8244
 
        ret=pupmenu("Loop/Cut Menu %t|Face Loop Select %x1|Face Loop Cut %x2|"
8245
 
                                "Knife (Exact) %x3|Knife (Midpoints)%x4|");
8246
 
                                
8247
 
        switch (ret){
8248
 
                case 1:
8249
 
                        loopoperations(LOOP_SELECT);
8250
 
                        break;
8251
 
                case 2:
8252
 
                        loopoperations(LOOP_CUT);
8253
 
                        break;
8254
 
                case 3: 
8255
 
                        KnifeSubdivide(KNIFE_EXACT);
8256
 
                        break;
8257
 
                case 4:
8258
 
                        KnifeSubdivide(KNIFE_MIDPOINT);
8259
 
        }
8260
 
 
8261
 
}
8262
 
 
8263
 
/*********************** EDITMESH UNDO ********************************/
8264
 
/* Mesh Edit undo by Alexander Ewring,                                */
8265
 
/* ported by Robert Wenzlaff                                          */
8266
 
/*                                                                    */
8267
 
/* Any meshedit function wishing to create an undo step, calls        */
8268
 
/*     undo_push_mesh("menu_name_of_step");                           */
8269
 
 
8270
 
Mesh *undo_new_mesh(void)
8271
 
{
8272
 
       return(MEM_callocN(sizeof(Mesh), "undo_mesh"));
8273
 
}
8274
 
 
8275
 
void undo_free_mesh(Mesh *me)
8276
 
{
8277
 
       if(me->mat) MEM_freeN(me->mat);
8278
 
       if(me->orco) MEM_freeN(me->orco);
8279
 
       if(me->mface) MEM_freeN(me->mface);
8280
 
       if(me->tface) MEM_freeN(me->tface);
8281
 
       if(me->mvert) MEM_freeN(me->mvert);
8282
 
       if(me->dvert) free_dverts(me->dvert, me->totvert);
8283
 
       if(me->mcol) MEM_freeN(me->mcol);
8284
 
       if(me->msticky) MEM_freeN(me->msticky);
8285
 
       if(me->bb) MEM_freeN(me->bb);
8286
 
       if(me->disp.first) freedisplist(&me->disp);
8287
 
       MEM_freeN(me);
8288
 
}
8289
 
 
8290
 
 
 
1614
/* ******************************************** */
 
1615
 
 
1616
/* *************** UNDO ***************************** */
 
1617
/* new mesh undo, based on pushing editmesh data itself */
 
1618
/* reuses same code as for global and curve undo... unify that (ton) */
 
1619
 
 
1620
/* only one 'hack', to save memory it doesn't store the first push, but does a remake editmesh */
 
1621
 
 
1622
/* a compressed version of editmesh data */
 
1623
typedef struct EditVertC
 
1624
{
 
1625
        float no[3];
 
1626
        float co[3];
 
1627
        unsigned char f, h;
 
1628
        short totweight;
 
1629
        struct MDeformWeight *dw;
 
1630
        int keyindex; 
 
1631
} EditVertC;
 
1632
 
 
1633
typedef struct EditEdgeC
 
1634
{
 
1635
        int v1, v2;
 
1636
        unsigned char f, h, seam, pad;
 
1637
        short crease, fgoni;
 
1638
} EditEdgeC;
 
1639
 
 
1640
typedef struct EditFaceC
 
1641
{
 
1642
        int v1, v2, v3, v4;
 
1643
        unsigned char mat_nr, flag, f, h, puno, fgonf;
 
1644
        short pad1;
 
1645
} EditFaceC;
 
1646
 
 
1647
typedef struct UndoMesh {
 
1648
        EditVertC *verts;
 
1649
        EditEdgeC *edges;
 
1650
        EditFaceC *faces;
 
1651
        TFace *tfaces;
 
1652
        int totvert, totedge, totface;
 
1653
} UndoMesh;
 
1654
 
 
1655
 
 
1656
/* for callbacks */
 
1657
 
 
1658
static void free_undoMesh(void *umv)
 
1659
{
 
1660
        UndoMesh *um= umv;
 
1661
        EditVertC *evec;
 
1662
        int a;
 
1663
        
 
1664
        for(a=0, evec= um->verts; a<um->totvert; a++, evec++) {
 
1665
                if(evec->dw) MEM_freeN(evec->dw);
 
1666
        }
 
1667
        
 
1668
        if(um->verts) MEM_freeN(um->verts);
 
1669
        if(um->edges) MEM_freeN(um->edges);
 
1670
        if(um->faces) MEM_freeN(um->faces);
 
1671
        if(um->tfaces) MEM_freeN(um->tfaces);
 
1672
        MEM_freeN(um);
 
1673
}
 
1674
 
 
1675
static void *editMesh_to_undoMesh(void)
 
1676
{
 
1677
        EditMesh *em= G.editMesh;
 
1678
        UndoMesh *um;
 
1679
        Mesh *me= G.obedit->data;
 
1680
        EditVert *eve;
 
1681
        EditEdge *eed;
 
1682
        EditFace *efa;
 
1683
        EditVertC *evec=NULL;
 
1684
        EditEdgeC *eedc=NULL;
 
1685
        EditFaceC *efac=NULL;
 
1686
        TFace *tface= NULL;
 
1687
        int a=0;
 
1688
        
 
1689
        um= MEM_callocN(sizeof(UndoMesh), "undomesh");
 
1690
 
 
1691
        for(eve=em->verts.first; eve; eve= eve->next) um->totvert++;
 
1692
        for(eed=em->edges.first; eed; eed= eed->next) um->totedge++;
 
1693
        for(efa=em->faces.first; efa; efa= efa->next) um->totface++;
 
1694
 
 
1695
        /* malloc blocks */
 
1696
        
 
1697
        if(um->totvert) evec= um->verts= MEM_callocN(um->totvert*sizeof(EditVertC), "allvertsC");
 
1698
        if(um->totedge) eedc= um->edges= MEM_callocN(um->totedge*sizeof(EditEdgeC), "alledgesC");
 
1699
        if(um->totface) efac= um->faces= MEM_callocN(um->totface*sizeof(EditFaceC), "allfacesC");
 
1700
 
 
1701
        if(me->tface) tface= um->tfaces= MEM_mallocN(um->totface*sizeof(TFace), "all tfacesC");
 
1702
 
 
1703
                //printf("copy editmesh %d\n", um->totvert*sizeof(EditVert) + um->totedge*sizeof(EditEdge) + um->totface*sizeof(EditFace));
 
1704
                //printf("copy undomesh %d\n", um->totvert*sizeof(EditVertC) + um->totedge*sizeof(EditEdgeC) + um->totface*sizeof(EditFaceC));
 
1705
        
 
1706
        /* now copy vertices */
 
1707
        for(eve=em->verts.first; eve; eve= eve->next, evec++, a++) {
 
1708
                VECCOPY(evec->co, eve->co);
 
1709
                VECCOPY(evec->no, eve->no);
 
1710
 
 
1711
                evec->f= eve->f;
 
1712
                evec->h= eve->h;
 
1713
                evec->keyindex= eve->keyindex;
 
1714
                evec->totweight= eve->totweight;
 
1715
                evec->dw= MEM_dupallocN(eve->dw);
 
1716
                
 
1717
                eve->vn= (EditVert *)a;
 
1718
        }
 
1719
        
 
1720
        /* copy edges */
 
1721
        for(eed=em->edges.first; eed; eed= eed->next, eedc++)  {
 
1722
                eedc->v1= (int)eed->v1->vn;
 
1723
                eedc->v2= (int)eed->v2->vn;
 
1724
                eedc->f= eed->f;
 
1725
                eedc->h= eed->h;
 
1726
                eedc->seam= eed->seam;
 
1727
                eedc->crease= (short)(eed->crease*255.0);
 
1728
                eedc->fgoni= eed->fgoni;
 
1729
        }
 
1730
        
 
1731
        /* copy faces */
 
1732
        for(efa=em->faces.first; efa; efa= efa->next, efac++) {
 
1733
                efac->v1= (int)efa->v1->vn;
 
1734
                efac->v2= (int)efa->v2->vn;
 
1735
                efac->v3= (int)efa->v3->vn;
 
1736
                if(efa->v4) efac->v4= (int)efa->v4->vn;
 
1737
                else efac->v4= -1;
 
1738
                
 
1739
                efac->mat_nr= efa->mat_nr;
 
1740
                efac->flag= efa->flag;
 
1741
                efac->f= efa->f;
 
1742
                efac->h= efa->h;
 
1743
                efac->puno= efa->puno;
 
1744
                efac->fgonf= efa->fgonf;
 
1745
                
 
1746
                if(tface) {
 
1747
                        *tface= efa->tf;
 
1748
                        tface++;
 
1749
                }
 
1750
        }
 
1751
        
 
1752
        return um;
 
1753
}
 
1754
 
 
1755
static void undoMesh_to_editMesh(void *umv)
 
1756
{
 
1757
        UndoMesh *um= umv;
 
1758
        EditMesh *em= G.editMesh;
 
1759
        EditVert *eve, **evar=NULL;
 
1760
        EditEdge *eed;
 
1761
        EditFace *efa;
 
1762
        EditVertC *evec;
 
1763
        EditEdgeC *eedc;
 
1764
        EditFaceC *efac;
 
1765
        TFace *tface;
 
1766
        int a=0;
 
1767
        
 
1768
        free_editMesh(G.editMesh);
 
1769
        
 
1770
        /* malloc blocks */
 
1771
        memset(em, 0, sizeof(EditMesh));
 
1772
 
 
1773
        init_editmesh_fastmalloc(em, um->totvert, um->totedge, um->totface);
 
1774
 
 
1775
        /* now copy vertices */
 
1776
        if(um->totvert) evar= MEM_mallocN(um->totvert*sizeof(EditVert *), "vertex ar");
 
1777
        for(a=0, evec= um->verts; a<um->totvert; a++, evec++) {
 
1778
                eve= addvertlist(evec->co);
 
1779
                evar[a]= eve;
 
1780
 
 
1781
                VECCOPY(eve->no, evec->no);
 
1782
                eve->f= evec->f;
 
1783
                eve->h= evec->h;
 
1784
                eve->totweight= evec->totweight;
 
1785
                eve->keyindex= evec->keyindex;
 
1786
                eve->dw= MEM_dupallocN(evec->dw);
 
1787
        }
 
1788
 
 
1789
        /* copy edges */
 
1790
        for(a=0, eedc= um->edges; a<um->totedge; a++, eedc++) {
 
1791
                eed= addedgelist(evar[eedc->v1], evar[eedc->v2], NULL);
 
1792
 
 
1793
                eed->f= eedc->f;
 
1794
                eed->h= eedc->h;
 
1795
                eed->seam= eedc->seam;
 
1796
                eed->fgoni= eedc->fgoni;
 
1797
                eed->crease= ((float)eedc->crease)/255.0;
 
1798
        }
 
1799
        
 
1800
        /* copy faces */
 
1801
        tface= um->tfaces;
 
1802
        for(a=0, efac= um->faces; a<um->totface; a++, efac++) {
 
1803
                if(efac->v4 != -1)
 
1804
                        efa= addfacelist(evar[efac->v1], evar[efac->v2], evar[efac->v3], evar[efac->v4], NULL, NULL);
 
1805
                else 
 
1806
                        efa= addfacelist(evar[efac->v1], evar[efac->v2], evar[efac->v3], NULL, NULL ,NULL);
 
1807
 
 
1808
                efa->mat_nr= efac->mat_nr;
 
1809
                efa->flag= efac->flag;
 
1810
                efa->f= efac->f;
 
1811
                efa->h= efac->h;
 
1812
                efa->puno= efac->puno;
 
1813
                efa->fgonf= efac->fgonf;
 
1814
                
 
1815
                if(tface) {
 
1816
                        efa->tf= *tface;
 
1817
                        tface++;
 
1818
                }
 
1819
        }
 
1820
        
 
1821
        end_editmesh_fastmalloc();
 
1822
        if(evar) MEM_freeN(evar);
 
1823
}
 
1824
 
 
1825
 
 
1826
/* and this is all the undo system needs to know */
8291
1827
void undo_push_mesh(char *name)
8292
1828
{
8293
 
       Mesh *me;
8294
 
       int i;
8295
 
 
8296
 
       countall();
8297
 
 
8298
 
       G.undo_edit_level++;
8299
 
 
8300
 
       if (G.undo_edit_level<0) {
8301
 
               printf("undo: ERROR: G.undo_edit_level negative\n");
8302
 
               return;
8303
 
       }
8304
 
 
8305
 
 
8306
 
       if (G.undo_edit[G.undo_edit_level].datablock != 0) {
8307
 
               undo_free_mesh(G.undo_edit[G.undo_edit_level].datablock);
8308
 
       }
8309
 
       if (strcmp(name, "U")!=0) {
8310
 
               for (i=G.undo_edit_level+1; i<(U.undosteps-1); i++) {
8311
 
                       if (G.undo_edit[i].datablock != 0) {
8312
 
                               undo_free_mesh(G.undo_edit[i].datablock);
8313
 
                               G.undo_edit[i].datablock= 0;
8314
 
                       }
8315
 
               }
8316
 
               G.undo_edit_highest= G.undo_edit_level;
8317
 
       }
8318
 
 
8319
 
       me= undo_new_mesh();
8320
 
 
8321
 
       if (G.undo_edit_level>=U.undosteps) {
8322
 
               G.undo_edit_level--;
8323
 
               undo_free_mesh((Mesh*)G.undo_edit[0].datablock);
8324
 
               G.undo_edit[0].datablock= 0;
8325
 
               for (i=0; i<(U.undosteps-1); i++) {
8326
 
                       G.undo_edit[i]= G.undo_edit[i+1];
8327
 
               }
8328
 
       }
8329
 
 
8330
 
       if (strcmp(name, "U")!=0) strcpy(G.undo_edit[G.undo_edit_level].name, name);
8331
 
       //printf("undo: saving block: %d [%s]\n", G.undo_edit_level, G.undo_edit[G.undo_edit_level].name);
8332
 
 
8333
 
       G.undo_edit[G.undo_edit_level].datablock= (void*)me;
8334
 
       load_editMesh_real(me, 1);
8335
 
}
8336
 
 
8337
 
void undo_pop_mesh(int steps)  /* steps == 1 is one step */
8338
 
{
8339
 
       if (G.undo_edit_level > (steps-2)) {
8340
 
                undo_push_mesh("U");
8341
 
                G.undo_edit_level-= steps;
8342
 
//printf("undo: restoring block: %d [%s]\n", G.undo_edit_level, G.undo_edit[G.undo_edit_level].name);    -
8343
 
               make_editMesh_real((Mesh*)G.undo_edit[G.undo_edit_level].datablock);
8344
 
               allqueue(REDRAWVIEW3D, 0);
8345
 
               makeDispList(G.obedit);
8346
 
               G.undo_edit_level--;
8347
 
       } else error("Can't undo");
8348
 
}
8349
 
 
8350
 
 
8351
 
void undo_redo_mesh(void)
8352
 
{
8353
 
       if ( (G.undo_edit[G.undo_edit_level+2].datablock) &&
8354
 
            ( (G.undo_edit_level+1) <= G.undo_edit_highest ) ) {
8355
 
               G.undo_edit_level++;
8356
 
               //printf("redo: restoring block: %d [%s]\n", G.undo_edit_level+1, G.undo_edit[G.undo_edit_level+1].name);-
8357
 
               make_editMesh_real((Mesh*)G.undo_edit[G.undo_edit_level+1].datablock);
8358
 
               allqueue(REDRAWVIEW3D, 0);
8359
 
               makeDispList(G.obedit);
8360
 
       } else error("Can't redo");
8361
 
}
8362
 
 
8363
 
void undo_clear_mesh(void)
8364
 
{
8365
 
       int i;
8366
 
       Mesh *me;
8367
 
 
8368
 
       for (i=0; i<=UNDO_EDIT_MAX; i++) {
8369
 
               me= (Mesh*) G.undo_edit[i].datablock;
8370
 
               if (me) {
8371
 
                       //printf("undo: freeing %d\n", i);
8372
 
                       undo_free_mesh(me);
8373
 
                       G.undo_edit[i].datablock= 0;
8374
 
               }
8375
 
       }
8376
 
}
8377
 
 
8378
 
void undo_menu_mesh(void)
8379
 
{
8380
 
        short event=66;
8381
 
        int i;
8382
 
        char menu[2080], temp[64];
8383
 
 
8384
 
        TEST_EDITMESH
8385
 
 
8386
 
        strcpy(menu, "UNDO %t|%l");
8387
 
        strcat(menu, "|All changes%x1|%l");
8388
 
        
8389
 
        for (i=G.undo_edit_level; i>=0; i--) {
8390
 
                        snprintf(temp, 64, "|%s%%x%d", G.undo_edit[i].name, i+2);
8391
 
                        strcat(menu, temp);
8392
 
        }
8393
 
 
8394
 
        event=pupmenu_col(menu, 20);
8395
 
 
8396
 
        if(event<1) return;
8397
 
 
8398
 
        if (event==1) remake_editMesh();
8399
 
        else undo_pop_mesh(G.undo_edit_level-event+3);
8400
 
}
8401
 
 
8402
 
/******************* BEVEL CODE STARTS HERE ********************/
8403
 
 
8404
 
void bevel_displace_vec(float *midvec, float *v1, float *v2, float *v3, float d, float no[3])
8405
 
{
8406
 
        float a[3], c[3], n_a[3], n_c[3], mid[3], ac, ac2, fac;
8407
 
 
8408
 
        VecSubf(a, v1, v2);
8409
 
        VecSubf(c, v3, v2);
8410
 
 
8411
 
        Crossf(n_a, a, no);
8412
 
        Normalise(n_a);
8413
 
        Crossf(n_c, no, c);
8414
 
        Normalise(n_c);
8415
 
 
8416
 
        Normalise(a);
8417
 
        Normalise(c);
8418
 
        ac = Inpf(a, c);
8419
 
 
8420
 
        if (ac == 1 || ac == -1) {
8421
 
                midvec[0] = midvec[1] = midvec[2] = 0;
8422
 
                return;
8423
 
        }
8424
 
        ac2 = ac * ac;
8425
 
        fac = sqrt((ac2 + 2*ac + 1)/(1 - ac2) + 1);
8426
 
        VecAddf(mid, n_c, n_a);
8427
 
        Normalise(mid);
8428
 
        VecMulf(mid, d * fac);
8429
 
        VecAddf(mid, mid, v2);
8430
 
        VecCopyf(midvec, mid);
8431
 
}
8432
 
 
8433
 
/*      Finds the new point using the sinus law to extrapolate a triangle
8434
 
        Lots of sqrts which would not be good for a real time algo
8435
 
        Using the mid  point of the extrapolation of both sides 
8436
 
        Useless for coplanar quads, but that doesn't happen too often */
8437
 
void fix_bevel_wrap(float *midvec, float *v1, float *v2, float *v3, float *v4, float d, float no[3]) {
8438
 
        float a[3], b[3], c[3], l_a, l_b, l_c, s_a, s_b, s_c, Pos1[3], Pos2[3], Dir[3];
8439
 
 
8440
 
        VecSubf(a, v3, v2);
8441
 
        l_a = Normalise(a);
8442
 
        VecSubf(b, v4, v3);
8443
 
        Normalise(b);
8444
 
        VecSubf(c, v1, v2);
8445
 
        Normalise(c);
8446
 
 
8447
 
        s_b = Inpf(a, c);
8448
 
        s_b = sqrt(1 - (s_b * s_b));
8449
 
        s_a = Inpf(b, c);
8450
 
        s_a = sqrt(1 - (s_a * s_a));
8451
 
        VecMulf(a, -1);
8452
 
        s_c = Inpf(a, b);
8453
 
        s_c = sqrt(1 - (s_c * s_c));
8454
 
 
8455
 
        l_b = s_b * l_a / s_a;
8456
 
        l_c = s_c * l_a / s_a;
8457
 
 
8458
 
        VecMulf(b, l_b);
8459
 
        VecMulf(c, l_c);
8460
 
 
8461
 
        VecAddf(Pos1, v2, c);
8462
 
        VecAddf(Pos2, v3, b);
8463
 
 
8464
 
        VecAddf(Dir, Pos1, Pos2);
8465
 
        VecMulf(Dir, 0.5);
8466
 
 
8467
 
        bevel_displace_vec(midvec, v3, Dir, v2, d, no);
8468
 
 
8469
 
}
8470
 
 
8471
 
 
8472
 
char detect_wrap(float *o_v1, float *o_v2, float *v1, float *v2, float *no) {
8473
 
        float o_a[3], a[3], o_c[3], c[3];
8474
 
 
8475
 
        VecSubf(o_a, o_v1, o_v2);
8476
 
        VecSubf(a, v1, v2);
8477
 
 
8478
 
        Crossf(o_c, o_a, no);
8479
 
        Crossf(c, a, no);
8480
 
 
8481
 
        if (Inpf(c, o_c) <= 0)
8482
 
                return 1;
8483
 
        else
8484
 
                return 0;
8485
 
}
8486
 
 
8487
 
// Detects and fix a quad wrapping after the resize
8488
 
// Arguments are the orginal verts followed by the final verts and then the bevel size and the normal
8489
 
void fix_bevel_quad_wrap(float *o_v1, float *o_v2, float *o_v3, float *o_v4, float *v1, float *v2, float *v3, float *v4, float d, float *no) {
8490
 
        float vec[3];
8491
 
        char wrap[4];
8492
 
        
8493
 
        // Quads can wrap partially. Watch out
8494
 
        wrap[0] = detect_wrap(o_v1, o_v2, v1, v2, no); // Edge 1-2
8495
 
        wrap[1] = detect_wrap(o_v2, o_v3, v2, v3, no); // Edge 2-3
8496
 
        wrap[2] = detect_wrap(o_v3, o_v4, v3, v4, no); // Edge 3-4
8497
 
        wrap[3] = detect_wrap(o_v4, o_v1, v4, v1, no); // Edge 4-1
8498
 
 
8499
 
        // Edge 1 inverted
8500
 
        if (wrap[0] == 1 && wrap[1] == 0 && wrap[2] == 0 && wrap[3] == 0) {
8501
 
                fix_bevel_wrap(vec, o_v2, o_v3, o_v4, o_v1, d, no);
8502
 
                VECCOPY(v1, vec);
8503
 
                VECCOPY(v2, vec);
8504
 
        }
8505
 
        // Edge 2 inverted
8506
 
        else if (wrap[0] == 0 && wrap[1] == 1 && wrap[2] == 0 && wrap[3] == 0) {
8507
 
                fix_bevel_wrap(vec, o_v3, o_v4, o_v1, o_v2, d, no);
8508
 
                VECCOPY(v2, vec);
8509
 
                VECCOPY(v3, vec);
8510
 
        }
8511
 
        // Edge 3 inverted
8512
 
        else if (wrap[0] == 0 && wrap[1] == 0 && wrap[2] == 1 && wrap[3] == 0) {
8513
 
                fix_bevel_wrap(vec, o_v4, o_v1, o_v2, o_v3, d, no);
8514
 
                VECCOPY(v3, vec);
8515
 
                VECCOPY(v4, vec);
8516
 
        }
8517
 
        // Edge 4 inverted
8518
 
        else if (wrap[0] == 0 && wrap[1] == 0 && wrap[2] == 0 && wrap[3] == 1) {
8519
 
                fix_bevel_wrap(vec, o_v1, o_v2, o_v3, o_v4, d, no);
8520
 
                VECCOPY(v4, vec);
8521
 
                VECCOPY(v1, vec);
8522
 
        }
8523
 
        // Edge 2 and 4 inverted
8524
 
        else if (wrap[0] == 0 && wrap[1] == 1 && wrap[2] == 0 && wrap[3] == 1) {
8525
 
                VecAddf(vec, v2, v3);
8526
 
                VecMulf(vec, 0.5);
8527
 
                VECCOPY(v2, vec);
8528
 
                VECCOPY(v3, vec);
8529
 
                VecAddf(vec, v1, v4);
8530
 
                VecMulf(vec, 0.5);
8531
 
                VECCOPY(v1, vec);
8532
 
                VECCOPY(v4, vec);
8533
 
        }
8534
 
        // Edge 1 and 3 inverted
8535
 
        else if (wrap[0] == 1 && wrap[1] == 0 && wrap[2] == 1 && wrap[3] == 0) {
8536
 
                VecAddf(vec, v1, v2);
8537
 
                VecMulf(vec, 0.5);
8538
 
                VECCOPY(v1, vec);
8539
 
                VECCOPY(v2, vec);
8540
 
                VecAddf(vec, v3, v4);
8541
 
                VecMulf(vec, 0.5);
8542
 
                VECCOPY(v3, vec);
8543
 
                VECCOPY(v4, vec);
8544
 
        }
8545
 
        // Totally inverted
8546
 
        else if (wrap[0] == 1 && wrap[1] == 1 && wrap[2] == 1 && wrap[3] == 1) {
8547
 
                VecAddf(vec, v1, v2);
8548
 
                VecAddf(vec, vec, v3);
8549
 
                VecAddf(vec, vec, v4);
8550
 
                VecMulf(vec, 0.25);
8551
 
                VECCOPY(v1, vec);
8552
 
                VECCOPY(v2, vec);
8553
 
                VECCOPY(v3, vec);
8554
 
                VECCOPY(v4, vec);
8555
 
        }
8556
 
 
8557
 
}
8558
 
 
8559
 
// Detects and fix a tri wrapping after the resize
8560
 
// Arguments are the orginal verts followed by the final verts and the normal
8561
 
// Triangles cannot wrap partially (not in this situation
8562
 
void fix_bevel_tri_wrap(float *o_v1, float *o_v2, float *o_v3, float *v1, float *v2, float *v3, float *no) {
8563
 
        if (detect_wrap(o_v1, o_v2, v1, v2, no)) {
8564
 
                float vec[3];
8565
 
                VecAddf(vec, o_v1, o_v2);
8566
 
                VecAddf(vec, vec, o_v3);
8567
 
                VecMulf(vec, 1.0/3.0);
8568
 
                VECCOPY(v1, vec);
8569
 
                VECCOPY(v2, vec);
8570
 
                VECCOPY(v3, vec);
8571
 
        }
8572
 
}
8573
 
 
8574
 
void bevel_shrink_faces(float d, int flag)
8575
 
{
8576
 
        EditMesh *em = G.editMesh;
8577
 
        EditVlak *evl;
8578
 
        float vec[3], no[3], v1[3], v2[3], v3[3], v4[3];
8579
 
 
8580
 
        /* move edges of all faces with evl->f1 & flag closer towards their centres */
8581
 
        evl= em->faces.first;
8582
 
        while (evl) {
8583
 
                if (evl->f1 & flag) {
8584
 
                        VECCOPY(v1, evl->v1->co);
8585
 
                        VECCOPY(v2, evl->v2->co);                       
8586
 
                        VECCOPY(v3, evl->v3->co);       
8587
 
                        VECCOPY(no, evl->n);
8588
 
                        if (evl->v4 == NULL) {
8589
 
                                bevel_displace_vec(vec, v1, v2, v3, d, no);
8590
 
                                VECCOPY(evl->v2->co, vec);
8591
 
                                bevel_displace_vec(vec, v2, v3, v1, d, no);
8592
 
                                VECCOPY(evl->v3->co, vec);              
8593
 
                                bevel_displace_vec(vec, v3, v1, v2, d, no);
8594
 
                                VECCOPY(evl->v1->co, vec);
8595
 
 
8596
 
                                fix_bevel_tri_wrap(v1, v2, v3, evl->v1->co, evl->v2->co, evl->v3->co, no);
8597
 
                        } else {
8598
 
                                VECCOPY(v4, evl->v4->co);
8599
 
                                bevel_displace_vec(vec, v1, v2, v3, d, no);
8600
 
                                VECCOPY(evl->v2->co, vec);
8601
 
                                bevel_displace_vec(vec, v2, v3, v4, d, no);
8602
 
                                VECCOPY(evl->v3->co, vec);              
8603
 
                                bevel_displace_vec(vec, v3, v4, v1, d, no);
8604
 
                                VECCOPY(evl->v4->co, vec);              
8605
 
                                bevel_displace_vec(vec, v4, v1, v2, d, no);
8606
 
                                VECCOPY(evl->v1->co, vec);
8607
 
 
8608
 
                                fix_bevel_quad_wrap(v1, v2, v3, v4, evl->v1->co, evl->v2->co, evl->v3->co, evl->v4->co, d, no);
8609
 
                        }
8610
 
                }
8611
 
                evl= evl->next;
8612
 
        }       
8613
 
}
8614
 
 
8615
 
void bevel_shrink_draw(float d, int flag)
8616
 
{
8617
 
        EditMesh *em = G.editMesh;
8618
 
        EditVlak *evl;
8619
 
        float vec[3], no[3], v1[3], v2[3], v3[3], v4[3], fv1[3], fv2[3], fv3[3], fv4[3];
8620
 
 
8621
 
        /* move edges of all faces with evl->f1 & flag closer towards their centres */
8622
 
        evl= em->faces.first;
8623
 
        while (evl) {
8624
 
                VECCOPY(v1, evl->v1->co);
8625
 
                VECCOPY(v2, evl->v2->co);                       
8626
 
                VECCOPY(v3, evl->v3->co);       
8627
 
                VECCOPY(no, evl->n);
8628
 
                if (evl->v4 == NULL) {
8629
 
                        bevel_displace_vec(vec, v1, v2, v3, d, no);
8630
 
                        VECCOPY(fv2, vec);
8631
 
                        bevel_displace_vec(vec, v2, v3, v1, d, no);
8632
 
                        VECCOPY(fv3, vec);              
8633
 
                        bevel_displace_vec(vec, v3, v1, v2, d, no);
8634
 
                        VECCOPY(fv1, vec);
8635
 
 
8636
 
                        fix_bevel_tri_wrap(v1, v2, v3, fv1, fv2, fv3, no);
8637
 
 
8638
 
                        glBegin(GL_LINES);
8639
 
                        glVertex3fv(fv1);
8640
 
                        glVertex3fv(fv2);
8641
 
                        glEnd();                                                
8642
 
                        glBegin(GL_LINES);
8643
 
                        glVertex3fv(fv2);
8644
 
                        glVertex3fv(fv3);
8645
 
                        glEnd();                                                
8646
 
                        glBegin(GL_LINES);
8647
 
                        glVertex3fv(fv1);
8648
 
                        glVertex3fv(fv3);
8649
 
                        glEnd();                                                
8650
 
                } else {
8651
 
                        VECCOPY(v4, evl->v4->co);
8652
 
                        bevel_displace_vec(vec, v4, v1, v2, d, no);
8653
 
                        VECCOPY(fv1, vec);
8654
 
                        bevel_displace_vec(vec, v1, v2, v3, d, no);
8655
 
                        VECCOPY(fv2, vec);
8656
 
                        bevel_displace_vec(vec, v2, v3, v4, d, no);
8657
 
                        VECCOPY(fv3, vec);              
8658
 
                        bevel_displace_vec(vec, v3, v4, v1, d, no);
8659
 
                        VECCOPY(fv4, vec);              
8660
 
 
8661
 
                        fix_bevel_quad_wrap(v1, v2, v3, v4, fv1, fv2, fv3, fv4, d, no);
8662
 
 
8663
 
                        glBegin(GL_LINES);
8664
 
                        glVertex3fv(fv1);
8665
 
                        glVertex3fv(fv2);
8666
 
                        glEnd();                                                
8667
 
                        glBegin(GL_LINES);
8668
 
                        glVertex3fv(fv2);
8669
 
                        glVertex3fv(fv3);
8670
 
                        glEnd();                                                
8671
 
                        glBegin(GL_LINES);
8672
 
                        glVertex3fv(fv3);
8673
 
                        glVertex3fv(fv4);
8674
 
                        glEnd();                                                
8675
 
                        glBegin(GL_LINES);
8676
 
                        glVertex3fv(fv1);
8677
 
                        glVertex3fv(fv4);
8678
 
                        glEnd();                                                
8679
 
                }
8680
 
                evl= evl->next;
8681
 
        }       
8682
 
}
8683
 
 
8684
 
void bevel_mesh(float bsize, int allfaces)
8685
 
{
8686
 
        EditMesh *em = G.editMesh;
8687
 
//#define BEV_DEBUG
8688
 
/* Enables debug printfs and assigns material indices: */
8689
 
/* 2 = edge quad                                       */
8690
 
/* 3 = fill polygon (vertex clusters)                  */
8691
 
 
8692
 
        EditVlak *evl, *example; //, *nextvl;
8693
 
        EditEdge *eed, *eed2;
8694
 
        EditVert *neweve[1024], *eve, *eve2, *eve3, *v1, *v2, *v3, *v4; //, *eve4;
8695
 
        float con1, con2, con3;
8696
 
        //short found4,  search;
8697
 
        //float f1, f2, f3, f4;
8698
 
        float cent[3], min[3], max[3];
8699
 
        int a, b, c;
8700
 
        float limit= 0.001;
8701
 
 
8702
 
        waitcursor(1);
8703
 
 
8704
 
        removedoublesflag(1, limit);
8705
 
 
8706
 
        /* tag all original faces */
8707
 
        evl= em->faces.first;
8708
 
        while (evl) {
8709
 
                if (vlakselectedAND(evl, 1)||allfaces) {
8710
 
                        evl->f1= 1;
8711
 
                        evl->v1->f |= 128;
8712
 
                        evl->v2->f |= 128;
8713
 
                        evl->v3->f |= 128;
8714
 
                        if (evl->v4) evl->v4->f |= 128;                 
8715
 
                }
8716
 
                evl->v1->f &= ~64;
8717
 
                evl->v2->f &= ~64;
8718
 
                evl->v3->f &= ~64;
8719
 
                if (evl->v4) evl->v4->f &= ~64;         
8720
 
 
8721
 
                evl= evl->next;
8722
 
        }
8723
 
 
8724
 
#ifdef BEV_DEBUG
8725
 
        fprintf(stderr,"bevel_mesh: split\n");
8726
 
#endif
8727
 
        
8728
 
        evl= em->faces.first;
8729
 
        while (evl) {
8730
 
                if (evl->f1 & 1) {
8731
 
                        evl->f1-= 1;
8732
 
                        v1= addvertlist(evl->v1->co);
8733
 
                        v1->f= evl->v1->f & ~128;
8734
 
                        evl->v1->vn= v1;
8735
 
#ifdef __NLA
8736
 
                        v1->totweight = evl->v1->totweight;
8737
 
                        if (evl->v1->totweight){
8738
 
                                v1->dw = MEM_mallocN (evl->v1->totweight * sizeof(MDeformWeight), "deformWeight");
8739
 
                                memcpy (v1->dw, evl->v1->dw, evl->v1->totweight * sizeof(MDeformWeight));
8740
 
                        }
8741
 
                        else
8742
 
                                v1->dw=NULL;
8743
 
#endif
8744
 
                        v1= addvertlist(evl->v2->co);
8745
 
                        v1->f= evl->v2->f & ~128;
8746
 
                        evl->v2->vn= v1;
8747
 
#ifdef __NLA
8748
 
                        v1->totweight = evl->v2->totweight;
8749
 
                        if (evl->v2->totweight){
8750
 
                                v1->dw = MEM_mallocN (evl->v2->totweight * sizeof(MDeformWeight), "deformWeight");
8751
 
                                memcpy (v1->dw, evl->v2->dw, evl->v2->totweight * sizeof(MDeformWeight));
8752
 
                        }
8753
 
                        else
8754
 
                                v1->dw=NULL;
8755
 
#endif
8756
 
                        v1= addvertlist(evl->v3->co);
8757
 
                        v1->f= evl->v3->f & ~128;
8758
 
                        evl->v3->vn= v1;
8759
 
#ifdef __NLA
8760
 
                        v1->totweight = evl->v3->totweight;
8761
 
                        if (evl->v3->totweight){
8762
 
                                v1->dw = MEM_mallocN (evl->v3->totweight * sizeof(MDeformWeight), "deformWeight");
8763
 
                                memcpy (v1->dw, evl->v3->dw, evl->v3->totweight * sizeof(MDeformWeight));
8764
 
                        }
8765
 
                        else
8766
 
                                v1->dw=NULL;
8767
 
#endif
8768
 
                        if (evl->v4) {
8769
 
                                v1= addvertlist(evl->v4->co);
8770
 
                                v1->f= evl->v4->f & ~128;
8771
 
                                evl->v4->vn= v1;
8772
 
#ifdef __NLA
8773
 
                                v1->totweight = evl->v4->totweight;
8774
 
                                if (evl->v4->totweight){
8775
 
                                        v1->dw = MEM_mallocN (evl->v4->totweight * sizeof(MDeformWeight), "deformWeight");
8776
 
                                        memcpy (v1->dw, evl->v4->dw, evl->v4->totweight * sizeof(MDeformWeight));
8777
 
                                }
8778
 
                                else
8779
 
                                        v1->dw=NULL;
8780
 
#endif
8781
 
                        }
8782
 
 
8783
 
                        addedgelist(evl->e1->v1->vn,evl->e1->v2->vn);
8784
 
                        addedgelist(evl->e2->v1->vn,evl->e2->v2->vn);                           
8785
 
                        addedgelist(evl->e3->v1->vn,evl->e3->v2->vn);                           
8786
 
                        if (evl->e4) addedgelist(evl->e4->v1->vn,evl->e4->v2->vn);                                              
8787
 
 
8788
 
                        if(evl->v4) {
8789
 
                                v1= evl->v1->vn;
8790
 
                                v2= evl->v2->vn;
8791
 
                                v3= evl->v3->vn;
8792
 
                                v4= evl->v4->vn;
8793
 
                                addvlaklist(v1, v2, v3, v4, evl);
8794
 
                        } else {
8795
 
                                v1= evl->v1->vn;
8796
 
                                v2= evl->v2->vn;
8797
 
                                v3= evl->v3->vn;
8798
 
                                addvlaklist(v1, v2, v3, 0, evl);
8799
 
                        }
8800
 
 
8801
 
                        evl= evl-> next;
8802
 
                } else {
8803
 
                        evl= evl->next;
8804
 
                }
8805
 
        }
8806
 
        
8807
 
        delvlakflag(128);
8808
 
 
8809
 
        /* tag all faces for shrink*/
8810
 
        evl= em->faces.first;
8811
 
        while (evl) {
8812
 
                if (vlakselectedAND(evl, 1)||allfaces) {
8813
 
                        evl->f1= 2;
8814
 
                }
8815
 
                evl= evl->next;
8816
 
        }
8817
 
 
8818
 
#ifdef BEV_DEBUG
8819
 
        fprintf(stderr,"bevel_mesh: make edge quads\n");
8820
 
#endif
8821
 
 
8822
 
        /* find edges that are on each other and make quads between them */
8823
 
 
8824
 
        eed= em->edges.first;
8825
 
        while(eed) {
8826
 
                eed->f= eed->f1= 0;
8827
 
                if ( ((eed->v1->f & eed->v2->f) & 1) || allfaces) eed->f1 |= 4; /* original edges */
8828
 
                eed->vn= 0;
8829
 
                eed= eed->next;
8830
 
        }
8831
 
 
8832
 
        eed= em->edges.first;
8833
 
        while (eed) {
8834
 
                if ( ((eed->f1 & 2)==0) && (eed->f1 & 4) ) {
8835
 
                        eed2= em->edges.first;
8836
 
                        while (eed2) {
8837
 
                                if ( (eed2 != eed) && ((eed2->f1 & 2)==0) && (eed->f1 & 4) ) {
8838
 
                                        if (
8839
 
                                           (eed->v1 != eed2->v1) &&
8840
 
                                           (eed->v1 != eed2->v2) &&                                        
8841
 
                                           (eed->v2 != eed2->v1) &&
8842
 
                                           (eed->v2 != eed2->v2) &&     (
8843
 
                                           ( VecCompare(eed->v1->co, eed2->v1->co, limit) &&
8844
 
                                                 VecCompare(eed->v2->co, eed2->v2->co, limit) ) ||
8845
 
                                           ( VecCompare(eed->v1->co, eed2->v2->co, limit) &&
8846
 
                                                 VecCompare(eed->v2->co, eed2->v1->co, limit) ) ) )
8847
 
                                                {
8848
 
                                                
8849
 
#ifdef BEV_DEBUG                                                
8850
 
                                                fprintf(stderr, "bevel_mesh: edge quad\n");
8851
 
#endif                                          
8852
 
                                                
8853
 
                                                eed->f1 |= 2;   /* these edges are finished */
8854
 
                                                eed2->f1 |= 2;
8855
 
                                                
8856
 
                                                example= NULL;
8857
 
                                                evl= em->faces.first;   /* search example vlak (for mat_nr, ME_SMOOTH, ...) */
8858
 
                                                while (evl) {
8859
 
                                                        if ( (evl->e1 == eed) ||
8860
 
                                                             (evl->e2 == eed) ||
8861
 
                                                             (evl->e3 == eed) ||
8862
 
                                                             (evl->e4 && (evl->e4 == eed)) ) {
8863
 
                                                            example= evl;
8864
 
                                                                evl= NULL;
8865
 
                                                        }
8866
 
                                                        if (evl) evl= evl->next;
8867
 
                                                }
8868
 
                                                
8869
 
                                                neweve[0]= eed->v1; neweve[1]= eed->v2;
8870
 
                                                neweve[2]= eed2->v1; neweve[3]= eed2->v2;
8871
 
                                                
8872
 
                                                if(exist_vlak(neweve[0], neweve[1], neweve[2], neweve[3])==0) {
8873
 
                                                        evl= NULL;
8874
 
 
8875
 
                                                        if (VecCompare(eed->v1->co, eed2->v2->co, limit)) {
8876
 
                                                                evl= addvlaklist(neweve[0], neweve[1], neweve[2], neweve[3], example);
8877
 
                                                        } else {
8878
 
                                                                evl= addvlaklist(neweve[0], neweve[2], neweve[3], neweve[1], example);
8879
 
                                                        }
8880
 
                                                
8881
 
                                                        if(evl) {
8882
 
                                                                float inp;      
8883
 
                                                                CalcNormFloat(evl->v1->co, evl->v2->co, evl->v3->co, evl->n);
8884
 
                                                                inp= evl->n[0]*G.vd->viewmat[0][2] + evl->n[1]*G.vd->viewmat[1][2] + evl->n[2]*G.vd->viewmat[2][2];
8885
 
                                                                if(inp < 0.0) flipvlak(evl);
8886
 
#ifdef BEV_DEBUG
8887
 
                                                                evl->mat_nr= 1;
8888
 
#endif
8889
 
                                                        } else fprintf(stderr,"bevel_mesh: error creating face\n");
8890
 
                                                }
8891
 
                                                eed2= NULL;
8892
 
                                        }
8893
 
                                }
8894
 
                                if (eed2) eed2= eed2->next;
8895
 
                        }
8896
 
                }
8897
 
                eed= eed->next;
8898
 
        }
8899
 
 
8900
 
        eed= em->edges.first;
8901
 
        while(eed) {
8902
 
                eed->f= eed->f1= 0;
8903
 
                eed->f1= 0;
8904
 
                eed->v1->f1 &= ~1;
8905
 
                eed->v2->f1 &= ~1;              
8906
 
                eed->vn= 0;
8907
 
                eed= eed->next;
8908
 
        }
8909
 
 
8910
 
#ifdef BEV_DEBUG
8911
 
        fprintf(stderr,"bevel_mesh: find clusters\n");
8912
 
#endif  
8913
 
 
8914
 
        /* Look for vertex clusters */
8915
 
 
8916
 
        eve= em->verts.first;
8917
 
        while (eve) {
8918
 
                eve->f &= ~(64|128);
8919
 
                eve->vn= NULL;
8920
 
                eve= eve->next;
8921
 
        }
8922
 
        
8923
 
        /* eve->f: 128: first vertex in a list (->vn) */
8924
 
        /*          64: vertex is in a list */
8925
 
        
8926
 
        eve= em->verts.first;
8927
 
        while (eve) {
8928
 
                eve2= em->verts.first;
8929
 
                eve3= NULL;
8930
 
                while (eve2) {
8931
 
                        if ((eve2 != eve) && ((eve2->f & (64|128))==0)) {
8932
 
                                if (VecCompare(eve->co, eve2->co, limit)) {
8933
 
                                        if ((eve->f & (128|64)) == 0) {
8934
 
                                                /* fprintf(stderr,"Found vertex cluster:\n  *\n  *\n"); */
8935
 
                                                eve->f |= 128;
8936
 
                                                eve->vn= eve2;
8937
 
                                                eve3= eve2;
8938
 
                                        } else if ((eve->f & 64) == 0) {
8939
 
                                                /* fprintf(stderr,"  *\n"); */
8940
 
                                                if (eve3) eve3->vn= eve2;
8941
 
                                                eve2->f |= 64;
8942
 
                                                eve3= eve2;
8943
 
                                        }
8944
 
                                }
8945
 
                        }
8946
 
                        eve2= eve2->next;
8947
 
                        if (!eve2) {
8948
 
                                if (eve3) eve3->vn= NULL;
8949
 
                        }
8950
 
                }
8951
 
                eve= eve->next;
8952
 
        }
8953
 
 
8954
 
#ifdef BEV_DEBUG
8955
 
        fprintf(stderr,"bevel_mesh: shrink faces\n");
8956
 
#endif  
8957
 
 
8958
 
        bevel_shrink_faces(bsize, 2);
8959
 
 
8960
 
#ifdef BEV_DEBUG
8961
 
        fprintf(stderr,"bevel_mesh: fill clusters\n");
8962
 
#endif
8963
 
        
8964
 
        /* Make former vertex clusters faces */
8965
 
 
8966
 
        eve= em->verts.first;
8967
 
        while (eve) {
8968
 
                eve->f &= ~64;
8969
 
                eve= eve->next;
8970
 
        }
8971
 
 
8972
 
        eve= em->verts.first;
8973
 
        while (eve) {
8974
 
                if (eve->f & 128) {
8975
 
                        eve->f &= ~128;
8976
 
                        a= 0;
8977
 
                        neweve[a]= eve;
8978
 
                        eve2= eve->vn;
8979
 
                        while (eve2) {
8980
 
                                a++;
8981
 
                                neweve[a]= eve2;
8982
 
                                eve2= eve2->vn;
8983
 
                        }
8984
 
                        a++;
8985
 
                        evl= NULL;
8986
 
                        if (a>=3) {
8987
 
                                example= NULL;
8988
 
                                evl= em->faces.first;   /* search example vlak */
8989
 
                                while (evl) {
8990
 
                                        if ( (evl->v1 == neweve[0]) ||
8991
 
                                             (evl->v2 == neweve[0]) ||
8992
 
                                             (evl->v3 == neweve[0]) ||
8993
 
                                             (evl->v4 && (evl->v4 == neweve[0])) ) {
8994
 
                                            example= evl;
8995
 
                                                evl= NULL;
8996
 
                                        }
8997
 
                                        if (evl) evl= evl->next;
8998
 
                                }
8999
 
#ifdef BEV_DEBUG                                
9000
 
                                fprintf(stderr,"bevel_mesh: Making %d-gon\n", a);
9001
 
#endif                          
9002
 
                                if (a>4) {
9003
 
                                        cent[0]= cent[1]= cent[2]= 0.0;                         
9004
 
                                        INIT_MINMAX(min, max);                          
9005
 
                                        for (b=0; b<a; b++) {
9006
 
                                                VecAddf(cent, cent, neweve[b]->co);
9007
 
                                                DO_MINMAX(neweve[b]->co, min, max);
9008
 
                                        }
9009
 
                                        cent[0]= (min[0]+max[0])/2;
9010
 
                                        cent[1]= (min[1]+max[1])/2;
9011
 
                                        cent[2]= (min[2]+max[2])/2;
9012
 
                                        eve2= addvertlist(cent);
9013
 
                                        eve2->f |= 1;
9014
 
                                        eed= em->edges.first;
9015
 
                                        while (eed) {
9016
 
                                                c= 0;
9017
 
                                                for (b=0; b<a; b++) 
9018
 
                                                        if ((neweve[b]==eed->v1) || (neweve[b]==eed->v2)) c++;
9019
 
                                                if (c==2) {
9020
 
                                                        if(exist_vlak(eed->v1, eed->v2, eve2, 0)==0) {
9021
 
                                                                evl= addvlaklist(eed->v1, eed->v2, eve2, 0, example);
9022
 
#ifdef BEV_DEBUG
9023
 
                                                                evl->mat_nr= 2;
9024
 
#endif                                                          
9025
 
                                                        }
9026
 
                                                }
9027
 
                                                eed= eed->next;
9028
 
                                        }
9029
 
                                } else if (a==4) {
9030
 
                                        if(exist_vlak(neweve[0], neweve[1], neweve[2], neweve[3])==0) {
9031
 
                                                con1= convex(neweve[0]->co, neweve[1]->co, neweve[2]->co, neweve[3]->co);
9032
 
                                                con2= convex(neweve[0]->co, neweve[2]->co, neweve[3]->co, neweve[1]->co);
9033
 
                                                con3= convex(neweve[0]->co, neweve[3]->co, neweve[1]->co, neweve[2]->co);
9034
 
                                                if(con1>=con2 && con1>=con3)
9035
 
                                                        evl= addvlaklist(neweve[0], neweve[1], neweve[2], neweve[3], example);
9036
 
                                                else if(con2>=con1 && con2>=con3)
9037
 
                                                        evl= addvlaklist(neweve[0], neweve[2], neweve[3], neweve[1], example);
9038
 
                                                else 
9039
 
                                                        evl= addvlaklist(neweve[0], neweve[2], neweve[1], neweve[3], example);
9040
 
                                        }                               
9041
 
                                }
9042
 
                                else if (a==3) {
9043
 
                                        if(exist_vlak(neweve[0], neweve[1], neweve[2], 0)==0)
9044
 
                                                evl= addvlaklist(neweve[0], neweve[1], neweve[2], 0, example);
9045
 
                                }
9046
 
                                if(evl) {
9047
 
                                        float inp;      
9048
 
                                        CalcNormFloat(neweve[0]->co, neweve[1]->co, neweve[2]->co, evl->n);
9049
 
                                        inp= evl->n[0]*G.vd->viewmat[0][2] + evl->n[1]*G.vd->viewmat[1][2] + evl->n[2]*G.vd->viewmat[2][2];
9050
 
                                        if(inp < 0.0) flipvlak(evl);
9051
 
#ifdef BEV_DEBUG
9052
 
                                                evl->mat_nr= 2;
9053
 
#endif                                                                                          
9054
 
                                }                               
9055
 
                        }
9056
 
                }
9057
 
                eve= eve->next;
9058
 
        }
9059
 
 
9060
 
        eve= em->verts.first;
9061
 
        while (eve) {
9062
 
                eve->f1= 0;
9063
 
                eve->f &= ~(128|64);
9064
 
                eve->vn= NULL;
9065
 
                eve= eve->next;
9066
 
        }
9067
 
        
9068
 
        recalc_editnormals();
9069
 
        waitcursor(0);
9070
 
        countall();
9071
 
        allqueue(REDRAWVIEW3D, 0);
9072
 
        makeDispList(G.obedit);
9073
 
        
9074
 
        removedoublesflag(1, limit);
9075
 
 
9076
 
#undef BEV_DEBUG
9077
 
}
9078
 
 
9079
 
void bevel_mesh_recurs(float bsize, short recurs, int allfaces) 
9080
 
{
9081
 
        float d;
9082
 
        short nr;
9083
 
 
9084
 
        d= bsize;
9085
 
        for (nr=0; nr<recurs; nr++) {
9086
 
                bevel_mesh(d, allfaces);
9087
 
                if (nr==0) d /= 3; else d /= 2;
9088
 
        }
9089
 
}
9090
 
 
9091
 
void bevel_menu()
9092
 
{
9093
 
        char Finished = 0, Canceled = 0, str[100], Recalc = 0;
9094
 
        short mval[2], oval[2], curval[2], event = 0, recurs = 1, nr;
9095
 
        float vec[3], d, drawd=0.0, centre[3], fac = 1;
9096
 
 
9097
 
        getmouseco_areawin(mval);
9098
 
        oval[0] = mval[0]; oval[1] = mval[1];
9099
 
 
9100
 
        // Silly hackish code to initialise the variable (warning if not done)
9101
 
        // while still drawing in the first iteration (and without using another variable)
9102
 
        curval[0] = mval[0] + 1; curval[1] = mval[1] + 1;
9103
 
 
9104
 
        window_to_3d(centre, mval[0], mval[1]);
9105
 
 
9106
 
        if(button(&recurs, 1, 4, "Recurs:")==0) return;
9107
 
 
9108
 
        for (nr=0; nr<recurs-1; nr++) {
9109
 
                if (nr==0) fac += 1.0/3.0; else fac += 1.0/(3 * nr * 2.0);
9110
 
        }
9111
 
 
9112
 
        SetBlenderCursor(SYSCURSOR);
9113
 
 
9114
 
        while (Finished == 0)
9115
 
        {
9116
 
                getmouseco_areawin(mval);
9117
 
                if (mval[0] != curval[0] || mval[1] != curval[1] || (Recalc == 1))
9118
 
                {
9119
 
                        Recalc = 0;
9120
 
                        curval[0] = mval[0];
9121
 
                        curval[1] = mval[1];
9122
 
 
9123
 
                        window_to_3d(vec, mval[0]-oval[0], mval[1]-oval[1]);
9124
 
                        d = Normalise(vec) / 10;
9125
 
 
9126
 
 
9127
 
                        drawd = d * fac;
9128
 
                        if (G.qual & LR_CTRLKEY)
9129
 
                                drawd = (float) floor(drawd * 10.0)/10.0;
9130
 
                        if (G.qual & LR_SHIFTKEY)
9131
 
                                drawd /= 10;
9132
 
 
9133
 
                        /*------------- Preview lines--------------- */
9134
 
                        
9135
 
                        /* uses callback mechanism to draw it all in current area */
9136
 
                        scrarea_do_windraw(curarea);                    
9137
 
                        
9138
 
                        /* set window matrix to perspective, default an area returns with buttons transform */
9139
 
                        persp(PERSP_VIEW);
9140
 
                        /* make a copy, for safety */
9141
 
                        glPushMatrix();
9142
 
                        /* multiply with the object transformation */
9143
 
                        mymultmatrix(G.obedit->obmat);
9144
 
                        
9145
 
                        glColor3ub(255, 255, 0);
9146
 
 
9147
 
                        // PREVIEW CODE GOES HERE
9148
 
                        bevel_shrink_draw(drawd, 2);
9149
 
 
9150
 
                        /* restore matrix transform */
9151
 
                        glPopMatrix();
9152
 
                        
9153
 
                        sprintf(str, "Bevel Size: %.4f        LMB to confirm, RMB to cancel, SPACE to input directly.", drawd);
9154
 
                        headerprint(str);
9155
 
 
9156
 
                        /* this also verifies other area/windows for clean swap */
9157
 
                        screen_swapbuffers();
9158
 
 
9159
 
                        persp(PERSP_WIN);
9160
 
                        
9161
 
                        glDrawBuffer(GL_FRONT);
9162
 
                        
9163
 
                        BIF_ThemeColor(TH_WIRE);
9164
 
 
9165
 
                        setlinestyle(3);
9166
 
                        glBegin(GL_LINE_STRIP); 
9167
 
                                glVertex2sv(mval); 
9168
 
                                glVertex2sv(oval); 
9169
 
                        glEnd();
9170
 
                        setlinestyle(0);
9171
 
                        
9172
 
                        persp(PERSP_VIEW);
9173
 
                        glFinish(); // flush display for frontbuffer
9174
 
                        glDrawBuffer(GL_BACK);
9175
 
                }
9176
 
                while(qtest()) {
9177
 
                        unsigned short val=0;                   
9178
 
                        event= extern_qread(&val);      // extern_qread stores important events for the mainloop to handle 
9179
 
 
9180
 
                        /* val==0 on key-release event */
9181
 
                        if(val && (event==ESCKEY || event==RIGHTMOUSE || event==LEFTMOUSE || event==RETKEY || event==ESCKEY)){
9182
 
                                if (event==RIGHTMOUSE || event==ESCKEY)
9183
 
                                        Canceled = 1;
9184
 
                                Finished = 1;
9185
 
                        }
9186
 
                        else if (val && event==SPACEKEY) {
9187
 
                                if (fbutton(&d, 0.000, 10.000, 10, 0, "Width:")!=0) {
9188
 
                                        drawd = d * fac;
9189
 
                                        Finished = 1;
9190
 
                                }
9191
 
                        }
9192
 
                        else if (val) {
9193
 
                                /* On any other keyboard event, recalc */
9194
 
                                Recalc = 1;
9195
 
                        }
9196
 
 
9197
 
                }       
9198
 
        }
9199
 
        if (Canceled==0) {
9200
 
                SetBlenderCursor(BC_WAITCURSOR);
9201
 
                undo_push_mesh("Bevel");
9202
 
                bevel_mesh_recurs(drawd/fac, recurs, 1);
9203
 
                righthandfaces(1);
9204
 
                SetBlenderCursor(SYSCURSOR);
9205
 
        }
9206
 
}
9207
 
 
9208
 
void select_non_manifold(void)
9209
 
{
9210
 
        EditMesh *em = G.editMesh;
9211
 
        EditVert *eve;
9212
 
        EditEdge *eed;
9213
 
        EditVlak *evl;
9214
 
 
9215
 
        /* Selects isolated verts, and edges that do not have 2 neighboring
9216
 
         * faces
9217
 
         */
9218
 
 
9219
 
 
9220
 
        eve= em->verts.first;
9221
 
        while(eve) {
9222
 
                /* this will count how many edges are connected
9223
 
                 * to this vert */
9224
 
                eve->f1= 0;
9225
 
                eve= eve->next;
9226
 
        }
9227
 
 
9228
 
        eed= em->edges.first;
9229
 
        while(eed) {
9230
 
                /* this will count how many faces are connected to
9231
 
                 * this edge */
9232
 
                eed->f1= 0;
9233
 
                /* increase edge count for verts */
9234
 
                ++eed->v1->f1;
9235
 
                ++eed->v2->f1;
9236
 
                eed= eed->next;
9237
 
        }
9238
 
 
9239
 
        evl= em->faces.first;
9240
 
        while(evl) {
9241
 
                /* increase face count for edges */
9242
 
                ++evl->e1->f1;
9243
 
                ++evl->e2->f1;
9244
 
                ++evl->e3->f1;
9245
 
                if (evl->e4)
9246
 
                        ++evl->e4->f1;                  
9247
 
                evl= evl->next;
9248
 
        }
9249
 
 
9250
 
        /* select verts that are attached to an edge that does not
9251
 
         * have 2 neighboring faces */
9252
 
        eed= em->edges.first;
9253
 
        while(eed) {
9254
 
                if (eed->f1 != 2) {
9255
 
                        if (!eed->v1->h) eed->v1->f |= 1;
9256
 
                        if (!eed->v2->h) eed->v2->f |= 1;
9257
 
                }
9258
 
                eed= eed->next;
9259
 
        }
9260
 
 
9261
 
        /* select isolated verts */
9262
 
        eve= em->verts.first;
9263
 
        while(eve) {
9264
 
                if (eve->f1 == 0) {
9265
 
                        if (!eve->h) eve->f |= 1;
9266
 
                }
9267
 
                eve= eve->next;
9268
 
        }
9269
 
 
9270
 
        countall();
9271
 
        addqueue(curarea->win,  REDRAW, 0);
9272
 
 
9273
 
}
9274
 
 
9275
 
void select_more(void)
9276
 
{
9277
 
        EditMesh *em = G.editMesh;
9278
 
        EditVert *eve;
9279
 
        EditEdge *eed;
9280
 
 
9281
 
        eve= em->verts.first;
9282
 
        while(eve) {
9283
 
                eve->f1 = 0;
9284
 
                eve= eve->next;
9285
 
        }
9286
 
 
9287
 
        eed= em->edges.first;
9288
 
        while(eed) {
9289
 
                if (eed->v1->f & 1)
9290
 
                        eed->v2->f1 = 1;
9291
 
                if (eed->v2->f & 1)
9292
 
                        eed->v1->f1 = 1;
9293
 
 
9294
 
                eed= eed->next;
9295
 
        }
9296
 
 
9297
 
        eve= em->verts.first;
9298
 
        while(eve) {
9299
 
                if (eve->f1 == 1)
9300
 
                        if (!eve->h) eve->f |= 1;
9301
 
 
9302
 
                eve= eve->next;
9303
 
        }
9304
 
 
9305
 
        countall();
9306
 
        addqueue(curarea->win,  REDRAW, 0);
9307
 
}
9308
 
 
9309
 
void select_less(void)
9310
 
{
9311
 
        EditMesh *em = G.editMesh;
9312
 
        EditVert *eve;
9313
 
        EditEdge *eed;
9314
 
        EditVlak *evl;
9315
 
 
9316
 
        /* eve->f1 & 1 => isolated   */
9317
 
        /* eve->f1 & 2 => on an edge */
9318
 
        /* eve->f1 & 4 => shares edge with a deselected vert */ 
9319
 
        /* eve->f1 & 8 => at most one neighbor */ 
9320
 
 
9321
 
        eve= em->verts.first;
9322
 
        while(eve) {
9323
 
                /* assume vert is isolated unless proven otherwise, */
9324
 
                /* assume at most one neighbor too */
9325
 
                eve->f1 = 1 | 8;
9326
 
 
9327
 
                eve= eve->next;
9328
 
        }
9329
 
 
9330
 
        eed= em->edges.first;
9331
 
        while(eed) {
9332
 
                /* this will count how many faces are connected to
9333
 
                 * this edge */
9334
 
                eed->f1= 0;
9335
 
 
9336
 
                /* if vert wasn't isolated, it now has more than one neighbor */
9337
 
                if (~eed->v1->f1 & 1) eed->v1->f1 &= ~8;
9338
 
                if (~eed->v2->f1 & 1) eed->v2->f1 &= ~8;
9339
 
 
9340
 
                /* verts on edge are clearly not isolated */
9341
 
                eed->v1->f1 &= ~1;
9342
 
                eed->v2->f1 &= ~1;
9343
 
 
9344
 
                /* if one of the verts on the edge is deselected, 
9345
 
                 * deselect the other */
9346
 
                if ( !(eed->v1->h) && (~eed->v1->f & 1) )
9347
 
                        eed->v2->f1 |= 4;
9348
 
                if ( !(eed->v2->h) && (~eed->v2->f & 1) )
9349
 
                        eed->v1->f1 |= 4;
9350
 
 
9351
 
                eed= eed->next;
9352
 
        }
9353
 
 
9354
 
        evl= em->faces.first;
9355
 
        while(evl) {
9356
 
                /* increase face count for edges */
9357
 
                ++evl->e1->f1;
9358
 
                ++evl->e2->f1;
9359
 
                ++evl->e3->f1;
9360
 
                if (evl->e4)
9361
 
                        ++evl->e4->f1;                  
9362
 
 
9363
 
                evl= evl->next;
9364
 
        }
9365
 
 
9366
 
        eed= em->edges.first;
9367
 
        while(eed) {
9368
 
                /* if the edge has only one neighboring face, then
9369
 
                 * deselect attached verts */
9370
 
                if (eed->f1 == 1) {
9371
 
                        eed->v1->f1 |= 2;
9372
 
                        eed->v2->f1 |= 2;
9373
 
                }
9374
 
 
9375
 
                eed= eed->next;
9376
 
        }
9377
 
 
9378
 
        /* deselect verts */
9379
 
        eve= em->verts.first;
9380
 
        while(eve) {
9381
 
                if (eve->f1) {
9382
 
                        eve->f &= ~1;
9383
 
                }
9384
 
 
9385
 
                eve= eve->next;
9386
 
        }
9387
 
 
9388
 
        countall();
9389
 
        allqueue(REDRAWVIEW3D, 0);
9390
 
}
9391
 
 
9392
 
 
9393
 
void selectrandom_mesh(void) /* randomly selects a user-set % of vertices */
9394
 
{
9395
 
        EditMesh *em = G.editMesh;
9396
 
        EditVert *eve;
9397
 
        int newsel = 0; /* to decide whether to redraw or not */
9398
 
        short randfac = 50;
9399
 
 
9400
 
        if(G.obedit==0) return;
9401
 
 
9402
 
        /* Get the percentage of vertices to randomly select as 'randfac' */
9403
 
        if(button(&randfac,0, 100,"Percentage:")==0) return;
9404
 
                
9405
 
        if(G.obedit->lay & G.vd->lay) {
9406
 
                eve= em->verts.first;
9407
 
                while(eve) {
9408
 
                        BLI_srand( BLI_rand() ); /* random seed */
9409
 
                        if ( (BLI_frand() * 100) < randfac) {
9410
 
                                        eve->f |= SELECT;
9411
 
                                        newsel = 1;
9412
 
                        } else {
9413
 
                                /* Deselect other vertices
9414
 
                                 *
9415
 
                                 * - Commenting this out makes it add to the selection, 
9416
 
                                 * rather than replace it.
9417
 
                                 * eve->f &= ~SELECT;
9418
 
                                 */
9419
 
                        }
9420
 
                        eve= eve->next;
9421
 
                }
9422
 
                countall();
9423
 
                allqueue(REDRAWVIEW3D, 0);
9424
 
        }
9425
 
}
9426
 
 
9427
 
/* this utility function checks to see if 2 edit edges share a face,
9428
 
        returns 1 if they do
9429
 
        returns 0 if they do not, or if the function is passed the same edge 2 times
9430
 
*/
9431
 
short sharesFace(EditEdge* e1, EditEdge* e2)
9432
 
{
9433
 
        EditMesh *em = G.editMesh;
9434
 
        EditVlak *search=NULL;
9435
 
        search = em->faces.first;
9436
 
        if (e1 == e2){
9437
 
                return 0 ;
9438
 
        }
9439
 
        while(search){
9440
 
                if(
9441
 
                        ((search->e1 == e1 || search->e2 == e1) || (search->e3 == e1 || search->e4 == e1)) &&
9442
 
                        ((search->e1 == e2 || search->e2 == e2) || (search->e3 == e2 || search->e4 == e2))
9443
 
                        ) {
9444
 
                        return 1;
9445
 
                }
9446
 
                search = search->next;
9447
 
        }
9448
 
        return 0;
9449
 
}
9450
 
/* This function selects a vertex loop based on a each succesive edge having a valance of 4
9451
 
   and not sharing a face with the previous edge */
9452
 
void vertex_loop_select() 
9453
 
{
9454
 
        EditMesh *em = G.editMesh;
9455
 
        EditVert *v1=NULL,*v2=NULL;
9456
 
        EditEdge *search=NULL,*startEdge=NULL,*valSearch = NULL,*nearest = NULL,*compEdge;
9457
 
        EditEdge *EdgeVal[5] = {NULL,NULL,NULL,NULL,NULL};
9458
 
        short numEdges=0,curEdge = 0,looking = 1,edgeValCount = 0,i=0,looped = 0,choosing = 1,event,noloop=0,cancel=0, val;
9459
 
 
9460
 
        short mvalo[2] = {0,0}, mval[2];
9461
 
 
9462
 
        undo_push_mesh("Vertex Loop Select");
9463
 
        SetBlenderCursor(BC_VLOOPCURSOR);
9464
 
        for(search=em->edges.first;search;search=search->next)
9465
 
                numEdges++;
9466
 
 
9467
 
        /* start with v1 and go in one direction. */
9468
 
        while(choosing){
9469
 
 
9470
 
                getmouseco_areawin(mval);
9471
 
                if (mval[0] != mvalo[0] || mval[1] != mvalo[1]) {
9472
 
 
9473
 
                        mvalo[0] = mval[0];
9474
 
                        mvalo[1] = mval[1];
9475
 
 
9476
 
                        scrarea_do_windraw(curarea);
9477
 
                        nearest = findnearestedge();
9478
 
                        if (nearest) {
9479
 
                                for(search = em->edges.first;search;search=search->next)
9480
 
                                        search->f &= ~32;
9481
 
                                        
9482
 
                                compEdge = startEdge = nearest;
9483
 
                                nearest->f |= 32;
9484
 
                                curEdge = 0;
9485
 
                                v1 = startEdge->v1;
9486
 
                                v2 = startEdge->v2;
9487
 
                                looking = 1;
9488
 
                                while(looking){
9489
 
                                        /*Find Edges that have v1*/
9490
 
                                        edgeValCount = -1;
9491
 
                                        EdgeVal[0] = EdgeVal[1] = EdgeVal[2] = NULL;
9492
 
                                        
9493
 
                                        for(valSearch = em->edges.first;valSearch;valSearch = valSearch->next){
9494
 
                                                if(valSearch->v1 == v1 || valSearch->v2 == v1){
9495
 
                                                        if(valSearch != compEdge){
9496
 
                                                                if((valSearch->v1->h == 0) && (valSearch->v2->h == 0)){
9497
 
                                                                        edgeValCount++;                                                 
9498
 
                                                                        EdgeVal[edgeValCount] = valSearch;
9499
 
                                                                }
9500
 
                                                        }
9501
 
                                                }
9502
 
                                                if(edgeValCount == 3)break;
9503
 
                                        }
9504
 
                                        /* Check that there was a valance of 4*/
9505
 
                                        if(edgeValCount != 2){
9506
 
                                                noloop = 1;
9507
 
                                                looking = 0;
9508
 
                                                break;
9509
 
                                        }
9510
 
                                        else{
9511
 
                                        /* There were 3 edges, so find the one that does not share the previous edge */
9512
 
                                                for(i=0;i<3;i++){
9513
 
                                                        if(sharesFace(compEdge,EdgeVal[i]) == 0){
9514
 
                                                                /* We went all the way around the loop */
9515
 
                                                                if(EdgeVal[i] == nearest){
9516
 
                                                                        looking = 0;
9517
 
                                                                        looped = 1;
9518
 
                                                                        break;
9519
 
                                                                }
9520
 
                                                                else{
9521
 
                                                                        /* we are still in the loop, so add the next edge*/
9522
 
                                                                        curEdge++;
9523
 
                                                                        EdgeVal[i]->f |= 32;
9524
 
                                                                        compEdge = EdgeVal[i];
9525
 
                                                                        if(compEdge->v1 == v1)
9526
 
                                                                                v1 = compEdge->v2;
9527
 
                                                                        else
9528
 
                                                                                v1 = compEdge->v1;
9529
 
                                                                }
9530
 
                                                        }
9531
 
                                                }
9532
 
                                        }
9533
 
                                }       
9534
 
                                compEdge = nearest;
9535
 
                                looking = 1;
9536
 
                                while(looking/* && !looped*/){
9537
 
                                        /*Find Edges that have v1*/
9538
 
                                        edgeValCount = -1;
9539
 
                                        EdgeVal[0] = EdgeVal[1] = EdgeVal[2] = NULL;
9540
 
                                        
9541
 
                                        for(valSearch = em->edges.first;valSearch;valSearch = valSearch->next){
9542
 
                                                if(valSearch->v1 == v2 || valSearch->v2 == v2){
9543
 
                                                        if(valSearch != compEdge){
9544
 
                                                                if((valSearch->v1->h == 0) && (valSearch->v2->h == 0)){
9545
 
                                                                        edgeValCount++;                                                 
9546
 
                                                                        EdgeVal[edgeValCount] = valSearch;
9547
 
                                                                }
9548
 
                                                        }
9549
 
                                                }
9550
 
                                                if(edgeValCount == 3)break;
9551
 
                                        }
9552
 
                                        /* Check that there was a valance of 4*/
9553
 
                                        if(edgeValCount != 2){
9554
 
                                                noloop = 1;
9555
 
                                                looking = 0;
9556
 
                                                break;
9557
 
                                        }
9558
 
                                        else{
9559
 
                                        /* There were 3 edges, so find the one that does not share the previous edge */
9560
 
                                                for(i=0;i<3;i++){
9561
 
                                                        if(sharesFace(compEdge,EdgeVal[i]) == 0){
9562
 
                                                                /* We went all the way around the loop */
9563
 
                                                                if(EdgeVal[i] == nearest){
9564
 
                                                                        looking = 0;
9565
 
                                                                        looped = 1;
9566
 
                                                                        break;
9567
 
                                                                }
9568
 
                                                                else{
9569
 
                                                                        /* we are still in the loop, so add the next edge*/
9570
 
                                                                        curEdge++;
9571
 
                                                                        EdgeVal[i]->f |= 32;
9572
 
                                                                        compEdge = EdgeVal[i];
9573
 
                                                                        if(compEdge->v1 == v2)
9574
 
                                                                                v2 = compEdge->v2;
9575
 
                                                                        else
9576
 
                                                                                v2 = compEdge->v1;
9577
 
                                                                }
9578
 
                                                        }
9579
 
                                                }
9580
 
                                        }
9581
 
                                }
9582
 
                                /* set up for opengl drawing in the 3d window */
9583
 
                                persp(PERSP_VIEW);
9584
 
                                glPushMatrix();
9585
 
                                mymultmatrix(G.obedit->obmat);
9586
 
                                glColor3ub(0, 255, 255);
9587
 
                                for(search = em->edges.first;search;search= search->next){
9588
 
                                        if(search->f & 32){
9589
 
                                                glBegin(GL_LINES);                      
9590
 
                                                glVertex3f(search->v1->co[0],search->v1->co[1],search->v1->co[2]);
9591
 
                                                glVertex3f(search->v2->co[0],search->v2->co[1],search->v2->co[2]);
9592
 
                                                glEnd();
9593
 
                                        }
9594
 
                                }               
9595
 
 
9596
 
                                glPopMatrix();
9597
 
                        }
9598
 
                }
9599
 
 
9600
 
                screen_swapbuffers();
9601
 
 
9602
 
 
9603
 
                while(qtest()) 
9604
 
                {
9605
 
                        val=0;
9606
 
                        event= extern_qread(&val);
9607
 
                        if(val && ((event==LEFTMOUSE || event==RETKEY) || event == MIDDLEMOUSE))
9608
 
                        {
9609
 
                                if (nearest==NULL)
9610
 
                                        cancel = 1;
9611
 
                                choosing=0;
9612
 
                                break;
9613
 
                        }
9614
 
                        if(val && (event==ESCKEY || event==RIGHTMOUSE ))
9615
 
                        {
9616
 
                                choosing=0;
9617
 
                                cancel = 1;
9618
 
                                break;
9619
 
                        }
9620
 
                        if(val && (event==BKEY && G.qual==LR_ALTKEY ))
9621
 
                        {                       
9622
 
                                
9623
 
                                SetBlenderCursor(SYSCURSOR);
9624
 
                                loopoperations(LOOP_SELECT);
9625
 
                                return;
9626
 
                        }
9627
 
                }
9628
 
        }
9629
 
        if(!cancel){
9630
 
                /* If this is a unmodified select, clear the selection */
9631
 
                if(!(G.qual & LR_SHIFTKEY) && !(G.qual & LR_ALTKEY)){
9632
 
                        for(search = em->edges.first;search;search= search->next){
9633
 
                                search->v1->f &= !1;
9634
 
                                search->v2->f &= !1;
9635
 
                        }
9636
 
                }
9637
 
                /* Alt was not pressed, so add to the selection */
9638
 
                if(!(G.qual & LR_ALTKEY)){
9639
 
                        for(search = em->edges.first;search;search= search->next){
9640
 
                                if(search->f & 32){
9641
 
                                        search->v1->f |= 1;
9642
 
                                        search->v2->f |= 1;
9643
 
                                }
9644
 
                                search->f &= ~32;
9645
 
                        }
9646
 
                }
9647
 
                /* alt was pressed, so subtract from the selection */
9648
 
                else
9649
 
                {
9650
 
                        for(search = em->edges.first;search;search= search->next){
9651
 
                                if(search->f & 32){
9652
 
                                        search->v1->f &= !1;
9653
 
                                        search->v2->f &= !1;
9654
 
                                }
9655
 
                                search->f &= ~32;
9656
 
                        }
9657
 
                }
9658
 
        }
9659
 
        else
9660
 
                undo_pop_mesh(1);
9661
 
        addqueue(curarea->win, REDRAW, 1); 
9662
 
        SetBlenderCursor(SYSCURSOR);
9663
 
        return;
9664
 
}
9665
 
 
9666
 
void editmesh_select_by_material(int index) {
9667
 
        EditMesh *em = G.editMesh;
9668
 
        EditVlak *evl;
9669
 
        
9670
 
        for (evl=em->faces.first; evl; evl= evl->next) {
9671
 
                if (evl->mat_nr==index) {
9672
 
                        if(evl->v1->h==0) evl->v1->f |= 1;
9673
 
                        if(evl->v2->h==0) evl->v2->f |= 1;
9674
 
                        if(evl->v3->h==0) evl->v3->f |= 1;
9675
 
                        if(evl->v4 && evl->v4->h==0) evl->v4->f |= 1;
9676
 
                }
9677
 
        }
9678
 
}
9679
 
 
9680
 
void editmesh_deselect_by_material(int index) {
9681
 
        EditMesh *em = G.editMesh;
9682
 
        EditVlak *evl;
9683
 
        
9684
 
        for (evl=em->faces.first; evl; evl= evl->next) {
9685
 
                if (evl->mat_nr==index) {
9686
 
                        if(evl->v1->h==0) evl->v1->f &= ~1;
9687
 
                        if(evl->v2->h==0) evl->v2->f &= ~1;
9688
 
                        if(evl->v3->h==0) evl->v3->f &= ~1;
9689
 
                        if(evl->v4 && evl->v4->h==0) evl->v4->f &= ~1;
9690
 
                }
9691
 
        }
9692
 
}
 
1829
        undo_editmode_push(name, free_undoMesh, undoMesh_to_editMesh, editMesh_to_undoMesh);
 
1830
}
 
1831
 
 
1832
 
 
1833
 
 
1834
/* *************** END UNDO *************/
 
1835
 
 
1836