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

« back to all changes in this revision

Viewing changes to source/blender/src/editmesh_add.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
/**
 
2
 * $Id: 
 
3
 *
 
4
 * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
 
5
 *
 
6
 * This program is free software; you can redistribute it and/or
 
7
 * modify it under the terms of the GNU General Public License
 
8
 * as published by the Free Software Foundation; either version 2
 
9
 * of the License, or (at your option) any later version. The Blender
 
10
 * Foundation also sells licenses for use in proprietary software under
 
11
 * the Blender License.  See http://www.blender.org/BL/ for information
 
12
 * about this.
 
13
 *
 
14
 * This program is distributed in the hope that it will be useful,
 
15
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 
16
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
17
 * GNU General Public License for more details.
 
18
 *
 
19
 * You should have received a copy of the GNU General Public License
 
20
 * along with this program; if not, write to the Free Software Foundation,
 
21
 * Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 
22
 *
 
23
 * The Original Code is Copyright (C) 2004 by NaN Holding BV.
 
24
 * All rights reserved.
 
25
 *
 
26
 * The Original Code is: all of this file.
 
27
 *
 
28
 * Contributor(s): none yet.
 
29
 *
 
30
 * ***** END GPL/BL DUAL LICENSE BLOCK *****
 
31
 */
 
32
 
 
33
 
 
34
#include <stdlib.h>
 
35
#include <string.h>
 
36
#include <math.h>
 
37
 
 
38
#ifdef HAVE_CONFIG_H
 
39
#include <config.h>
 
40
#endif
 
41
 
 
42
#include "MEM_guardedalloc.h"
 
43
 
 
44
 
 
45
#include "DNA_mesh_types.h"
 
46
#include "DNA_meshdata_types.h"
 
47
#include "DNA_object_types.h"
 
48
#include "DNA_scene_types.h"
 
49
#include "DNA_screen_types.h"
 
50
#include "DNA_view3d_types.h"
 
51
 
 
52
#include "BLI_blenlib.h"
 
53
#include "BLI_arithb.h"
 
54
#include "BLI_editVert.h"
 
55
 
 
56
#include "BKE_displist.h"
 
57
#include "BKE_global.h"
 
58
#include "BKE_library.h"
 
59
#include "BKE_mesh.h"
 
60
#include "BKE_object.h"
 
61
#include "BKE_utildefines.h"
 
62
 
 
63
#include "BIF_editmesh.h"
 
64
#include "BIF_graphics.h"
 
65
#include "BIF_interface.h"
 
66
#include "BIF_mywindow.h"
 
67
#include "BIF_screen.h"
 
68
#include "BIF_space.h"
 
69
#include "BIF_toolbox.h"
 
70
#include "BIF_transform.h"
 
71
 
 
72
#include "BDR_editobject.h" 
 
73
 
 
74
#include "BSE_view.h"
 
75
#include "BSE_edit.h"
 
76
 
 
77
#include "mydevice.h"
 
78
#include "blendef.h"
 
79
 
 
80
#include "editmesh.h"
 
81
 
 
82
static float icovert[12][3] = {
 
83
        {0,0,-200}, 
 
84
        {144.72, -105.144,-89.443},
 
85
        {-55.277, -170.128,-89.443}, 
 
86
        {-178.885,0,-89.443},
 
87
        {-55.277,170.128,-89.443}, 
 
88
        {144.72,105.144,-89.443},
 
89
        {55.277,-170.128,89.443},
 
90
        {-144.72,-105.144,89.443},
 
91
        {-144.72,105.144,89.443},
 
92
        {55.277,170.128,89.443},
 
93
        {178.885,0,89.443},
 
94
        {0,0,200}
 
95
};
 
96
static short icoface[20][3] = {
 
97
        {1,0,2},
 
98
        {1,0,5},
 
99
        {2,0,3},
 
100
        {3,0,4},
 
101
        {4,0,5},
 
102
        {1,5,10},
 
103
        {2,1,6},
 
104
        {3,2,7},
 
105
        {4,3,8},
 
106
        {5,4,9},
 
107
        {10,1,6},
 
108
        {6,2,7},
 
109
        {7,3,8},
 
110
        {8,4,9},
 
111
        {9,5,10},
 
112
        {6,10,11},
 
113
        {7,6,11},
 
114
        {8,7,11},
 
115
        {9,8,11},
 
116
        {10,9,11}
 
117
};
 
118
 
 
119
void addvert_mesh(void)
 
120
{
 
121
        EditMesh *em = G.editMesh;
 
122
        EditVert *eve,*v1=0;
 
123
        float *curs, mat[3][3],imat[3][3];
 
124
 
 
125
        // hurms, yah...
 
126
        if(G.scene->selectmode==SCE_SELECT_FACE) return;
 
127
 
 
128
        TEST_EDITMESH
 
129
 
 
130
        Mat3CpyMat4(mat, G.obedit->obmat);
 
131
        Mat3Inv(imat, mat);
 
132
 
 
133
        v1= em->verts.first;
 
134
        while(v1) {
 
135
                if(v1->f & SELECT) break;
 
136
                v1= v1->next;
 
137
        }
 
138
        eve= v1;
 
139
 
 
140
        /* prevent there are more selected */
 
141
        EM_clear_flag_all(SELECT);
 
142
        
 
143
        eve= addvertlist(0);
 
144
        
 
145
        curs= give_cursor();
 
146
        VECCOPY(eve->co, curs);
 
147
        eve->xs= G.vd->mx;
 
148
        eve->ys= G.vd->my;
 
149
        VecSubf(eve->co, eve->co, G.obedit->obmat[3]);
 
150
 
 
151
        Mat3MulVecfl(imat, eve->co);
 
152
        eve->f= SELECT;
 
153
 
 
154
        if(v1) {
 
155
                addedgelist(v1, eve, NULL);
 
156
                v1->f= 0;
 
157
        }
 
158
        countall();
 
159
 
 
160
        BIF_undo_push("Add vertex");
 
161
        allqueue(REDRAWVIEW3D, 0);
 
162
        makeDispList(G.obedit);
 
163
        
 
164
        while(get_mbut()&R_MOUSE);
 
165
 
 
166
}
 
167
 
 
168
/* selected faces get hidden edges */
 
169
static void make_fgon(void)
 
170
{
 
171
        EditMesh *em = G.editMesh;
 
172
        EditFace *efa;
 
173
        EditEdge *eed;
 
174
        EditVert *eve;
 
175
        float *nor=NULL;        // reference
 
176
        int done=0, ret;
 
177
        
 
178
        ret= pupmenu("FGon %t|Make|Clear");
 
179
        if(ret<1) return;
 
180
        
 
181
        if(ret==2) {
 
182
                for(efa= em->faces.first; efa; efa= efa->next) {
 
183
                        if(efa->f & SELECT) {
 
184
                                efa->fgonf= 0;
 
185
                                efa->e1->h &= ~EM_FGON;
 
186
                                efa->e2->h &= ~EM_FGON;
 
187
                                efa->e3->h &= ~EM_FGON;
 
188
                                if(efa->e4) efa->e4->h &= ~EM_FGON;
 
189
                        }
 
190
                }
 
191
                allqueue(REDRAWVIEW3D, 0);
 
192
                EM_fgon_flags();        // redo flags and indices for fgons
 
193
                makeDispList(G.obedit);
 
194
                BIF_undo_push("Clear FGon");
 
195
                return;
 
196
        }
 
197
 
 
198
        /* tagging edges. rule is:
 
199
           - edge used by exactly 2 selected faces
 
200
           - no vertices allowed with only tagged edges (return)
 
201
           - face normals are allowed to difffer
 
202
         
 
203
        */
 
204
        for(eed= em->edges.first; eed; eed= eed->next) {
 
205
                eed->f1= 0;     // amount of selected
 
206
                eed->f2= 0; // amount of unselected
 
207
        }
 
208
        
 
209
        for(efa= em->faces.first; efa; efa= efa->next) {
 
210
                if(efa->f & SELECT) {
 
211
                        if(nor==NULL) nor= efa->n;
 
212
                        if(efa->e1->f1 < 3) efa->e1->f1++;
 
213
                        if(efa->e2->f1 < 3) efa->e2->f1++;
 
214
                        if(efa->e3->f1 < 3) efa->e3->f1++;
 
215
                        if(efa->e4 && efa->e4->f1 < 3) efa->e4->f1++;
 
216
                }
 
217
                else {
 
218
                        if(efa->e1->f2 < 3) efa->e1->f2++;
 
219
                        if(efa->e2->f2 < 3) efa->e2->f2++;
 
220
                        if(efa->e3->f2 < 3) efa->e3->f2++;
 
221
                        if(efa->e4 && efa->e4->f2 < 3) efa->e4->f2++;
 
222
                }
 
223
        }
 
224
        // now eed->f1 becomes tagged edge
 
225
        for(eed= em->edges.first; eed; eed= eed->next) {
 
226
                if(eed->f1==2 && eed->f2==0) eed->f1= 1;
 
227
                else eed->f1= 0;
 
228
        }
 
229
        
 
230
        // no vertices allowed with only tagged edges
 
231
        for(eve= em->verts.first; eve; eve= eve->next) eve->f1= 0;
 
232
        for(eed= em->edges.first; eed; eed= eed->next) {
 
233
                if(eed->f1) {
 
234
                        eed->v1->f1 |= 1;
 
235
                        eed->v2->f1 |= 1;
 
236
                }
 
237
                else {
 
238
                        eed->v1->f1 |= 2;
 
239
                        eed->v2->f1 |= 2;
 
240
                }
 
241
        }
 
242
        for(eve= em->verts.first; eve; eve= eve->next) {
 
243
                if(eve->f1==1) break;
 
244
        }
 
245
        if(eve) {
 
246
                error("Cannot make polygon with interior vertices");
 
247
                return;
 
248
        }
 
249
        
 
250
        // check for faces
 
251
        if(nor==NULL) {
 
252
                error("No faces selected to make FGon");
 
253
                return;
 
254
        }
 
255
 
 
256
        // and there we go
 
257
        for(eed= em->edges.first; eed; eed= eed->next) {
 
258
                if(eed->f1) {
 
259
                        eed->h |= EM_FGON;
 
260
                        done= 1;
 
261
                }
 
262
        }
 
263
        
 
264
        if(done==0) {
 
265
                error("Didn't find FGon to create");
 
266
        }
 
267
        else {
 
268
                Mesh *me= G.obedit->data;
 
269
                // signal to save edges with ngon flags
 
270
                if(!me->medge)
 
271
                        me->medge= MEM_callocN(sizeof(MEdge), "fake mesh edge");
 
272
                
 
273
                EM_fgon_flags();        // redo flags and indices for fgons
 
274
 
 
275
                allqueue(REDRAWVIEW3D, 0);
 
276
                makeDispList(G.obedit);
 
277
                BIF_undo_push("Make FGon");
 
278
        }
 
279
}
 
280
 
 
281
/* precondition; 4 vertices selected, check for 4 edges and create face */
 
282
static EditFace *addface_from_edges(void)
 
283
{
 
284
        EditMesh *em = G.editMesh;
 
285
        EditEdge *eed, *eedar[4]={NULL, NULL, NULL, NULL};
 
286
        EditVert *v1=NULL, *v2=NULL, *v3=NULL, *v4=NULL;
 
287
        int a;
 
288
        
 
289
        /* find the 4 edges */
 
290
        for(eed= em->edges.first; eed; eed= eed->next) {
 
291
                if(eed->f & SELECT) {
 
292
                        if(eedar[0]==NULL) eedar[0]= eed;
 
293
                        else if(eedar[1]==NULL) eedar[1]= eed;
 
294
                        else if(eedar[2]==NULL) eedar[2]= eed;
 
295
                        else eedar[3]= eed;
 
296
                }
 
297
        }
 
298
        if(eedar[3]) {
 
299
                /* first 2 points */
 
300
                v1= eedar[0]->v1;
 
301
                v2= eedar[0]->v2;
 
302
                
 
303
                /* find the 2 edges connected to first edge */
 
304
                for(a=1; a<4; a++) {
 
305
                        if( eedar[a]->v1 == v2) v3= eedar[a]->v2;
 
306
                        else if(eedar[a]->v2 == v2) v3= eedar[a]->v1;
 
307
                        else if( eedar[a]->v1 == v1) v4= eedar[a]->v2;
 
308
                        else if(eedar[a]->v2 == v1) v4= eedar[a]->v1;
 
309
                }
 
310
                
 
311
                /* verify if last edge exists */
 
312
                if(v3 && v4) {
 
313
                        for(a=1; a<4; a++) {
 
314
                                if( eedar[a]->v1==v3 && eedar[a]->v2==v4) break;
 
315
                                if( eedar[a]->v2==v3 && eedar[a]->v1==v4) break;
 
316
                        }
 
317
                        if(a!=4) {
 
318
                                return addfacelist(v1, v2, v3, v4, NULL, NULL);
 
319
                        }
 
320
                }
 
321
        }
 
322
        return NULL;
 
323
}
 
324
 
 
325
void addedgeface_mesh(void)
 
326
{
 
327
        EditMesh *em = G.editMesh;
 
328
        EditVert *eve, *neweve[4];
 
329
        EditEdge *eed;
 
330
        EditFace *efa;
 
331
        short amount=0;
 
332
 
 
333
        if( (G.vd->lay & G.obedit->lay)==0 ) return;
 
334
 
 
335
        /* how many selected ? */
 
336
        if(G.scene->selectmode & SCE_SELECT_EDGE) {
 
337
                /* in edge mode finding selected vertices means flushing down edge codes... */
 
338
                /* can't make face with only edge selection info... */
 
339
                EM_selectmode_set();
 
340
        }
 
341
        
 
342
        for(eve= em->verts.first; eve; eve= eve->next) {
 
343
                if(eve->f & SELECT) {
 
344
                        amount++;
 
345
                        if(amount>4) break;                     
 
346
                        neweve[amount-1]= eve;
 
347
                }
 
348
        }
 
349
        if(amount==2) {
 
350
                eed= addedgelist(neweve[0], neweve[1], NULL);
 
351
                EM_select_edge(eed, 1);
 
352
                BIF_undo_push("Add edge");
 
353
                allqueue(REDRAWVIEW3D, 0);
 
354
                countall();
 
355
                makeDispList(G.obedit);
 
356
                return;
 
357
        }
 
358
        else if(amount > 4) {
 
359
                make_fgon();
 
360
                return;
 
361
        }
 
362
        else if(amount<2) {
 
363
                error("Incorrect number of vertices to make edge/face");
 
364
                return;
 
365
        }
 
366
 
 
367
        efa= NULL; // check later
 
368
 
 
369
        if(amount==3) {
 
370
                if(exist_face(neweve[0], neweve[1], neweve[2], 0)==0) {
 
371
                        
 
372
                        efa= addfacelist(neweve[0], neweve[1], neweve[2], 0, NULL, NULL);
 
373
                        EM_select_face(efa, 1);
 
374
                }
 
375
                else error("The selected vertices already form a face");
 
376
        }
 
377
        else if(amount==4) {
 
378
                if(exist_face(neweve[0], neweve[1], neweve[2], neweve[3])==0) {
 
379
                        int tria= 0;
 
380
                        
 
381
                        /* remove trias if they exist, 4 cases.... */
 
382
                        if(exist_face(neweve[0], neweve[1], neweve[2], NULL)) tria++;
 
383
                        if(exist_face(neweve[0], neweve[1], neweve[3], NULL)) tria++;
 
384
                        if(exist_face(neweve[0], neweve[2], neweve[3], NULL)) tria++;
 
385
                        if(exist_face(neweve[1], neweve[2], neweve[3], NULL)) tria++;
 
386
                
 
387
                        if(tria==2) join_triangles();
 
388
                        else {
 
389
                                
 
390
                                /* if 4 edges exist, we just create the face, convex or not */
 
391
                                efa= addface_from_edges();
 
392
                                if(efa==NULL) {
 
393
                                        /* the order of vertices can be anything, three cases to check */
 
394
                                        if( convex(neweve[0]->co, neweve[1]->co, neweve[2]->co, neweve[3]->co) ) {
 
395
                                                efa= addfacelist(neweve[0], neweve[1], neweve[2], neweve[3], NULL, NULL);
 
396
                                        }
 
397
                                        else if( convex(neweve[0]->co, neweve[2]->co, neweve[3]->co, neweve[1]->co) ) {
 
398
                                                efa= addfacelist(neweve[0], neweve[2], neweve[3], neweve[1], NULL, NULL);
 
399
                                        }
 
400
                                        else if( convex(neweve[0]->co, neweve[2]->co, neweve[1]->co, neweve[3]->co) ) {
 
401
                                                efa= addfacelist(neweve[0], neweve[2], neweve[1], neweve[3], NULL, NULL);
 
402
                                        }
 
403
                                        else error("The selected vertices form a concave quad");
 
404
                                }
 
405
                        }
 
406
 
 
407
                }
 
408
                else error("The selected vertices already form a face");
 
409
        }
 
410
        
 
411
        if(efa) {       // now we're calculating direction of normal
 
412
                float inp;      
 
413
                /* dot product view mat with normal, should give info! */
 
414
        
 
415
                EM_select_face(efa, 1);
 
416
                CalcNormFloat(efa->v1->co, efa->v2->co, efa->v3->co, efa->n);
 
417
 
 
418
                inp= efa->n[0]*G.vd->viewmat[0][2] + efa->n[1]*G.vd->viewmat[1][2] + efa->n[2]*G.vd->viewmat[2][2];
 
419
 
 
420
                if(inp < 0.0) flipface(efa);
 
421
                BIF_undo_push("Add face");
 
422
        }
 
423
        
 
424
        countall();
 
425
        allqueue(REDRAWVIEW3D, 0);
 
426
        makeDispList(G.obedit);
 
427
}
 
428
 
 
429
 
 
430
void adduplicate_mesh(void)
 
431
{
 
432
 
 
433
        TEST_EDITMESH
 
434
 
 
435
        waitcursor(1);
 
436
 
 
437
        adduplicateflag(SELECT);
 
438
 
 
439
        waitcursor(0);
 
440
        countall(); 
 
441
        BIF_TransformSetUndo("Add Duplicate");
 
442
        initTransform(TFM_TRANSLATION, CTX_NO_PET);
 
443
        Transform();
 
444
}
 
445
 
 
446
 
 
447
 
 
448
void add_primitiveMesh(int type)
 
449
{
 
450
        EditMesh *em = G.editMesh;
 
451
        Mesh *me;
 
452
        EditVert *eve, *v1=NULL, *v2, *v3, *v4=NULL, *vtop, *vdown;
 
453
        float *curs, d, dia, phi, phid, cent[3], vec[3], imat[3][3], mat[3][3];
 
454
        float q[4], cmat[3][3], nor[3]= {0.0, 0.0, 0.0};
 
455
        static short tot=32, seg=32, subdiv=2;
 
456
        short a, b, ext=0, fill=0, totoud, newob=0;
 
457
        char *undostr="Add Primitive";
 
458
        
 
459
        if(G.scene->id.lib) return;
 
460
 
 
461
        /* this function also comes from an info window */
 
462
        if ELEM(curarea->spacetype, SPACE_VIEW3D, SPACE_INFO); else return;
 
463
        if(G.vd==0) return;
 
464
 
 
465
        /* if editmode exists for other type, it exits */
 
466
        check_editmode(OB_MESH);
 
467
        
 
468
        if(G.f & (G_VERTEXPAINT+G_FACESELECT+G_TEXTUREPAINT)) {
 
469
                G.f &= ~(G_VERTEXPAINT+G_FACESELECT+G_TEXTUREPAINT);
 
470
                setcursor_space(SPACE_VIEW3D, CURSOR_EDIT);
 
471
        }
 
472
        
 
473
        /* if no obedit: new object and enter editmode */
 
474
        if(G.obedit==NULL) {
 
475
                /* add_object actually returns an object ! :-)
 
476
                But it also stores the added object struct in
 
477
                G.scene->basact->object (BASACT->object) */
 
478
 
 
479
                add_object_draw(OB_MESH);
 
480
 
 
481
                G.obedit= BASACT->object;
 
482
                
 
483
                where_is_object(G.obedit);
 
484
                
 
485
                make_editMesh();
 
486
                setcursor_space(SPACE_VIEW3D, CURSOR_EDIT);
 
487
                newob= 1;
 
488
        }
 
489
        me= G.obedit->data;
 
490
        
 
491
        /* deselectall */
 
492
        EM_clear_flag_all(SELECT);
 
493
 
 
494
        totoud= tot; /* store, and restore when cube/plane */
 
495
        
 
496
        /* imat and centre and size */
 
497
        Mat3CpyMat4(mat, G.obedit->obmat);
 
498
 
 
499
        curs= give_cursor();
 
500
        VECCOPY(cent, curs);
 
501
        cent[0]-= G.obedit->obmat[3][0];
 
502
        cent[1]-= G.obedit->obmat[3][1];
 
503
        cent[2]-= G.obedit->obmat[3][2];
 
504
 
 
505
        if(type!= 31) {
 
506
                Mat3CpyMat4(imat, G.vd->viewmat);
 
507
                Mat3MulVecfl(imat, cent);
 
508
                Mat3MulMat3(cmat, imat, mat);
 
509
                Mat3Inv(imat,cmat);
 
510
        } else {
 
511
                Mat3Inv(imat, mat);
 
512
        }
 
513
        
 
514
        /* ext==extrudeflag, tot==amount of vertices in basis */
 
515
 
 
516
        switch(type) {
 
517
        case 0:         /* plane */
 
518
                tot= 4;
 
519
                ext= 0;
 
520
                fill= 1;
 
521
                if(newob) rename_id((ID *)G.obedit, "Plane");
 
522
                if(newob) rename_id((ID *)me, "Plane");
 
523
                undostr="Add Plane";
 
524
                break;
 
525
        case 1:         /* cube  */
 
526
                tot= 4;
 
527
                ext= 1;
 
528
                fill= 1;
 
529
                if(newob) rename_id((ID *)G.obedit, "Cube");
 
530
                if(newob) rename_id((ID *)me, "Cube");
 
531
                undostr="Add Cube";
 
532
                break;
 
533
        case 4:         /* circle  */
 
534
                if(button(&tot,3,100,"Vertices:")==0) return;
 
535
                ext= 0;
 
536
                fill= 0;
 
537
                if(newob) rename_id((ID *)G.obedit, "Circle");
 
538
                if(newob) rename_id((ID *)me, "Circle");
 
539
                undostr="Add Circle";
 
540
                break;
 
541
        case 5:         /* cylinder  */
 
542
                if(button(&tot,3,100,"Vertices:")==0) return;
 
543
                ext= 1;
 
544
                fill= 1;
 
545
                if(newob) rename_id((ID *)G.obedit, "Cylinder");
 
546
                if(newob) rename_id((ID *)me, "Cylinder");
 
547
                undostr="Add Cylinder";
 
548
                break;
 
549
        case 6:         /* tube  */
 
550
                if(button(&tot,3,100,"Vertices:")==0) return;
 
551
                ext= 1;
 
552
                fill= 0;
 
553
                if(newob) rename_id((ID *)G.obedit, "Tube");
 
554
                if(newob) rename_id((ID *)me, "Tube");
 
555
                undostr="Add Tube";
 
556
                break;
 
557
        case 7:         /* cone  */
 
558
                if(button(&tot,3,100,"Vertices:")==0) return;
 
559
                ext= 0;
 
560
                fill= 1;
 
561
                if(newob) rename_id((ID *)G.obedit, "Cone");
 
562
                if(newob) rename_id((ID *)me, "Cone");
 
563
                undostr="Add Cone";
 
564
                break;
 
565
        case 10:        /* grid */
 
566
                if(button(&tot,2,100,"X res:")==0) return;
 
567
                if(button(&seg,2,100,"Y res:")==0) return;
 
568
                if(newob) rename_id((ID *)G.obedit, "Grid");
 
569
                if(newob) rename_id((ID *)me, "Grid");
 
570
                undostr="Add Grid";
 
571
                break;
 
572
        case 11:        /* UVsphere */
 
573
                if(button(&seg,3,100,"Segments:")==0) return;
 
574
                if(button(&tot,3,100,"Rings:")==0) return;
 
575
                if(newob) rename_id((ID *)G.obedit, "Sphere");
 
576
                if(newob) rename_id((ID *)me, "Sphere");
 
577
                undostr="Add UV Sphere";
 
578
                break;
 
579
        case 12:        /* Icosphere */
 
580
                if(button(&subdiv,1,5,"Subdivision:")==0) return;
 
581
                if(newob) rename_id((ID *)G.obedit, "Sphere");
 
582
                if(newob) rename_id((ID *)me, "Sphere");
 
583
                undostr="Add Ico Sphere";
 
584
                break;
 
585
        case 13:        /* Monkey */
 
586
                if(newob) rename_id((ID *)G.obedit, "Suzanne");
 
587
                if(newob) rename_id((ID *)me, "Suzanne");
 
588
                undostr="Add Monkey";
 
589
                break;
 
590
        }
 
591
 
 
592
        dia= sqrt(2.0)*G.vd->grid;
 
593
        d= -G.vd->grid;
 
594
        phid= 2*M_PI/tot;
 
595
        phi= .25*M_PI;
 
596
 
 
597
 
 
598
        if(type<10) {   /* all types except grid, sphere... */
 
599
                if(ext==0 && type!=7) d= 0;
 
600
        
 
601
                /* vertices */
 
602
                vtop= vdown= v1= v2= 0;
 
603
                for(b=0; b<=ext; b++) {
 
604
                        for(a=0; a<tot; a++) {
 
605
                                
 
606
                                vec[0]= cent[0]+dia*sin(phi);
 
607
                                vec[1]= cent[1]+dia*cos(phi);
 
608
                                vec[2]= cent[2]+d;
 
609
                                
 
610
                                Mat3MulVecfl(imat, vec);
 
611
                                eve= addvertlist(vec);
 
612
                                eve->f= SELECT;
 
613
                                if(a==0) {
 
614
                                        if(b==0) v1= eve;
 
615
                                        else v2= eve;
 
616
                                }
 
617
                                phi+=phid;
 
618
                        }
 
619
                        d= -d;
 
620
                }
 
621
                /* centre vertices */
 
622
                if(fill && type>1) {
 
623
                        VECCOPY(vec,cent);
 
624
                        vec[2]-= -d;
 
625
                        Mat3MulVecfl(imat,vec);
 
626
                        vdown= addvertlist(vec);
 
627
                        if(ext || type==7) {
 
628
                                VECCOPY(vec,cent);
 
629
                                vec[2]-= d;
 
630
                                Mat3MulVecfl(imat,vec);
 
631
                                vtop= addvertlist(vec);
 
632
                        }
 
633
                } else {
 
634
                        vdown= v1;
 
635
                        vtop= v2;
 
636
                }
 
637
                if(vtop) vtop->f= SELECT;
 
638
                if(vdown) vdown->f= SELECT;
 
639
        
 
640
                /* top and bottom face */
 
641
                if(fill) {
 
642
                        if(tot==4 && (type==0 || type==1)) {
 
643
                                v3= v1->next->next;
 
644
                                if(ext) v4= v2->next->next;
 
645
                                
 
646
                                addfacelist(v3, v1->next, v1, v3->next, NULL, NULL);
 
647
                                if(ext) addfacelist(v2, v2->next, v4, v4->next, NULL, NULL);
 
648
                                
 
649
                        }
 
650
                        else {
 
651
                                v3= v1;
 
652
                                v4= v2;
 
653
                                for(a=1; a<tot; a++) {
 
654
                                        addfacelist(vdown, v3, v3->next, 0, NULL, NULL);
 
655
                                        v3= v3->next;
 
656
                                        if(ext) {
 
657
                                                addfacelist(vtop, v4, v4->next, 0, NULL, NULL);
 
658
                                                v4= v4->next;
 
659
                                        }
 
660
                                }
 
661
                                if(type>1) {
 
662
                                        addfacelist(vdown, v3, v1, 0, NULL, NULL);
 
663
                                        if(ext) addfacelist(vtop, v4, v2, 0, NULL, NULL);
 
664
                                }
 
665
                        }
 
666
                }
 
667
                else if(type==4) {  /* we need edges for a circle */
 
668
                        v3= v1;
 
669
                        for(a=1;a<tot;a++) {
 
670
                                addedgelist(v3, v3->next, NULL);
 
671
                                v3= v3->next;
 
672
                        }
 
673
                        addedgelist(v3, v1, NULL);
 
674
                }
 
675
                /* side faces */
 
676
                if(ext) {
 
677
                        v3= v1;
 
678
                        v4= v2;
 
679
                        for(a=1; a<tot; a++) {
 
680
                                addfacelist(v3, v3->next, v4->next, v4, NULL, NULL);
 
681
                                v3= v3->next;
 
682
                                v4= v4->next;
 
683
                        }
 
684
                        addfacelist(v3, v1, v2, v4, NULL, NULL);
 
685
                }
 
686
                else if(type==7) { /* cone */
 
687
                        v3= v1;
 
688
                        for(a=1; a<tot; a++) {
 
689
                                addfacelist(vtop, v3->next, v3, 0, NULL, NULL);
 
690
                                v3= v3->next;
 
691
                        }
 
692
                        addfacelist(vtop, v1, v3, 0, NULL, NULL);
 
693
                }
 
694
                
 
695
                if(type<2) tot= totoud;
 
696
                
 
697
        }
 
698
        else if(type==10) {     /*  grid */
 
699
                /* clear flags */
 
700
                eve= em->verts.first;
 
701
                while(eve) {
 
702
                        eve->f= 0;
 
703
                        eve= eve->next;
 
704
                }
 
705
                dia= G.vd->grid;
 
706
                /* one segment first: the X axis */
 
707
                phi= 1.0; 
 
708
                phid= 2.0/((float)tot-1);
 
709
                for(a=0;a<tot;a++) {
 
710
                        vec[0]= cent[0]+dia*phi;
 
711
                        vec[1]= cent[1]- dia;
 
712
                        vec[2]= cent[2];
 
713
                        Mat3MulVecfl(imat,vec);
 
714
                        eve= addvertlist(vec);
 
715
                        eve->f= 1+2+4;
 
716
                        if (a) {
 
717
                                addedgelist(eve->prev, eve, NULL);
 
718
                        }
 
719
                        phi-=phid;
 
720
                }
 
721
                /* extrude and translate */
 
722
                vec[0]= vec[2]= 0.0;
 
723
                vec[1]= dia*phid;
 
724
                Mat3MulVecfl(imat, vec);
 
725
                for(a=0;a<seg-1;a++) {
 
726
                        extrudeflag_vert(2, nor);       // nor unused
 
727
                        translateflag(2, vec);
 
728
                }
 
729
        }
 
730
        else if(type==11) {     /*  UVsphere */
 
731
                
 
732
                /* clear all flags */
 
733
                eve= em->verts.first;
 
734
                while(eve) {
 
735
                        eve->f= 0;
 
736
                        eve= eve->next;
 
737
                }
 
738
                
 
739
                /* one segment first */
 
740
                phi= 0; 
 
741
                phid/=2;
 
742
                for(a=0; a<=tot; a++) {
 
743
                        vec[0]= dia*sin(phi);
 
744
                        vec[1]= 0.0;
 
745
                        vec[2]= dia*cos(phi);
 
746
                        eve= addvertlist(vec);
 
747
                        eve->f= 1+2+4;
 
748
                        if(a==0) v1= eve;
 
749
                        else addedgelist(eve->prev, eve, NULL);
 
750
                        phi+= phid;
 
751
                }
 
752
                
 
753
                /* extrude and rotate */
 
754
                phi= M_PI/seg;
 
755
                q[0]= cos(phi);
 
756
                q[3]= sin(phi);
 
757
                q[1]=q[2]= 0;
 
758
                QuatToMat3(q, cmat);
 
759
                
 
760
                for(a=0; a<seg; a++) {
 
761
                        extrudeflag_vert(2, nor); // nor unused
 
762
                        rotateflag(2, v1->co, cmat);
 
763
                }
 
764
 
 
765
                removedoublesflag(4, 0.0001);
 
766
 
 
767
                /* and now do imat */
 
768
                eve= em->verts.first;
 
769
                while(eve) {
 
770
                        if(eve->f & SELECT) {
 
771
                                VecAddf(eve->co,eve->co,cent);
 
772
                                Mat3MulVecfl(imat,eve->co);
 
773
                        }
 
774
                        eve= eve->next;
 
775
                }
 
776
        }
 
777
        else if(type==12) {     /* Icosphere */
 
778
                EditVert *eva[12];
 
779
 
 
780
                /* clear all flags */
 
781
                eve= em->verts.first;
 
782
                while(eve) {
 
783
                        eve->f= 0;
 
784
                        eve= eve->next;
 
785
                }
 
786
                dia/=200;
 
787
                for(a=0;a<12;a++) {
 
788
                        vec[0]= dia*icovert[a][0];
 
789
                        vec[1]= dia*icovert[a][1];
 
790
                        vec[2]= dia*icovert[a][2];
 
791
                        eva[a]= addvertlist(vec);
 
792
                        eva[a]->f= 1+2;
 
793
                }
 
794
                for(a=0;a<20;a++) {
 
795
                        v1= eva[ icoface[a][0] ];
 
796
                        v2= eva[ icoface[a][1] ];
 
797
                        v3= eva[ icoface[a][2] ];
 
798
                        addfacelist(v1, v2, v3, 0, NULL, NULL);
 
799
                }
 
800
 
 
801
                dia*=200;
 
802
                for(a=1; a<subdiv; a++) subdivideflag(2, dia, 0);
 
803
                /* and now do imat */
 
804
                eve= em->verts.first;
 
805
                while(eve) {
 
806
                        if(eve->f & 2) {
 
807
                                VecAddf(eve->co,eve->co,cent);
 
808
                                Mat3MulVecfl(imat,eve->co);
 
809
                        }
 
810
                        eve= eve->next;
 
811
                }
 
812
        } else if (type==13) {  /* Monkey */
 
813
                extern int monkeyo, monkeynv, monkeynf;
 
814
                extern signed char monkeyf[][4];
 
815
                extern signed char monkeyv[][3];
 
816
                EditVert **tv= MEM_mallocN(sizeof(*tv)*monkeynv*2, "tv");
 
817
                EditFace *efa;
 
818
                int i;
 
819
 
 
820
                for (i=0; i<monkeynv; i++) {
 
821
                        float v[3];
 
822
                        v[0]= (monkeyv[i][0]+127)/128.0, v[1]= monkeyv[i][1]/128.0, v[2]= monkeyv[i][2]/128.0;
 
823
                        tv[i]= addvertlist(v);
 
824
                        tv[i]->f |= SELECT;
 
825
                        tv[monkeynv+i]= (fabs(v[0]= -v[0])<0.001)?tv[i]:addvertlist(v);
 
826
                        tv[monkeynv+i]->f |= SELECT;
 
827
                }
 
828
                for (i=0; i<monkeynf; i++) {
 
829
                        efa= addfacelist(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, NULL);
 
830
                        efa= addfacelist(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, NULL);
 
831
                }
 
832
 
 
833
                MEM_freeN(tv);
 
834
 
 
835
                /* and now do imat */
 
836
                for(eve= em->verts.first; eve; eve= eve->next) {
 
837
                        if(eve->f & SELECT) {
 
838
                                VecAddf(eve->co,eve->co,cent);
 
839
                                Mat3MulVecfl(imat,eve->co);
 
840
                        }
 
841
                }
 
842
                recalc_editnormals();
 
843
        }
 
844
        
 
845
        // simple selection flush OK, based on fact it's a single model
 
846
        EM_select_flush(); // flushes vertex -> edge -> face selection
 
847
        
 
848
        if(type!=0 && type!=13) righthandfaces(1);      // otherwise monkey has eyes in wrong direction...
 
849
        countall();
 
850
 
 
851
        allqueue(REDRAWINFO, 1);        /* 1, because header->win==0! */        
 
852
        allqueue(REDRAWALL, 0);
 
853
        makeDispList(G.obedit);
 
854
 
 
855
        /* if a new object was created, it stores it in Mesh, for reload original data and undo */
 
856
        if(newob) load_editMesh();      
 
857
        BIF_undo_push(undostr);
 
858
}
 
859