Made Suzanne speechless again... what was i thinking.
[blender.git] / source / blender / src / editmesh_add.c
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 #ifdef WIN32
43 #include "BLI_winstuff.h"
44 #endif
45 #include "MEM_guardedalloc.h"
46
47
48 #include "DNA_mesh_types.h"
49 #include "DNA_meshdata_types.h"
50 #include "DNA_object_types.h"
51 #include "DNA_scene_types.h"
52 #include "DNA_screen_types.h"
53 #include "DNA_view3d_types.h"
54
55 #include "BLI_blenlib.h"
56 #include "BLI_arithb.h"
57 #include "BLI_editVert.h"
58
59 #include "BKE_displist.h"
60 #include "BKE_global.h"
61 #include "BKE_library.h"
62 #include "BKE_mesh.h"
63 #include "BKE_object.h"
64 #include "BKE_utildefines.h"
65
66 #include "BIF_editmesh.h"
67 #include "BIF_graphics.h"
68 #include "BIF_interface.h"
69 #include "BIF_mywindow.h"
70 #include "BIF_screen.h"
71 #include "BIF_space.h"
72 #include "BIF_toolbox.h"
73
74 #include "BDR_editobject.h" 
75
76 #include "BSE_view.h"
77 #include "BSE_edit.h"
78
79 #include "mydevice.h"
80 #include "blendef.h"
81
82 #include "editmesh.h"
83
84 static float icovert[12][3] = {
85         {0,0,-200}, 
86         {144.72, -105.144,-89.443},
87         {-55.277, -170.128,-89.443}, 
88         {-178.885,0,-89.443},
89         {-55.277,170.128,-89.443}, 
90         {144.72,105.144,-89.443},
91         {55.277,-170.128,89.443},
92         {-144.72,-105.144,89.443},
93         {-144.72,105.144,89.443},
94         {55.277,170.128,89.443},
95         {178.885,0,89.443},
96         {0,0,200}
97 };
98 static short icoface[20][3] = {
99         {1,0,2},
100         {1,0,5},
101         {2,0,3},
102         {3,0,4},
103         {4,0,5},
104         {1,5,10},
105         {2,1,6},
106         {3,2,7},
107         {4,3,8},
108         {5,4,9},
109         {10,1,6},
110         {6,2,7},
111         {7,3,8},
112         {8,4,9},
113         {9,5,10},
114         {6,10,11},
115         {7,6,11},
116         {8,7,11},
117         {9,8,11},
118         {10,9,11}
119 };
120
121 void addvert_mesh(void)
122 {
123         EditMesh *em = G.editMesh;
124         EditVert *eve,*v1=0;
125         float *curs, mat[3][3],imat[3][3];
126
127         // hurms, yah...
128         if(G.scene->selectmode==SCE_SELECT_FACE) return;
129
130         TEST_EDITMESH
131
132         Mat3CpyMat4(mat, G.obedit->obmat);
133         Mat3Inv(imat, mat);
134
135         v1= em->verts.first;
136         while(v1) {
137                 if(v1->f & SELECT) break;
138                 v1= v1->next;
139         }
140         eve= v1;
141
142         /* prevent there are more selected */
143         EM_clear_flag_all(SELECT);
144         
145         eve= addvertlist(0);
146         
147         curs= give_cursor();
148         VECCOPY(eve->co, curs);
149         eve->xs= G.vd->mx;
150         eve->ys= G.vd->my;
151         VecSubf(eve->co, eve->co, G.obedit->obmat[3]);
152
153         Mat3MulVecfl(imat, eve->co);
154         eve->f= SELECT;
155
156         if(v1) {
157                 addedgelist(v1, eve, NULL);
158                 v1->f= 0;
159         }
160         countall();
161
162         BIF_undo_push("Add vertex");
163         allqueue(REDRAWVIEW3D, 0);
164         makeDispList(G.obedit);
165         
166         while(get_mbut()&R_MOUSE);
167
168 }
169
170 /* selected faces get hidden edges */
171 static void make_fgon(void)
172 {
173         EditMesh *em = G.editMesh;
174         EditFace *efa;
175         EditEdge *eed;
176         EditVert *eve;
177         float *nor=NULL;        // reference
178         int done=0, ret;
179         
180         ret= pupmenu("FGon %t|Make|Clear");
181         if(ret<1) return;
182         
183         if(ret==2) {
184                 for(efa= em->faces.first; efa; efa= efa->next) {
185                         if(efa->f & SELECT) {
186                                 efa->fgonf= 0;
187                                 efa->e1->h &= ~EM_FGON;
188                                 efa->e2->h &= ~EM_FGON;
189                                 efa->e3->h &= ~EM_FGON;
190                                 if(efa->e4) efa->e4->h &= ~EM_FGON;
191                         }
192                 }
193                 allqueue(REDRAWVIEW3D, 0);
194                 EM_fgon_flags();        // redo flags and indices for fgons
195                 makeDispList(G.obedit);
196                 BIF_undo_push("Clear FGon");
197                 return;
198         }
199
200         /* tagging edges. rule is:
201            - edge used by exactly 2 selected faces
202            - no vertices allowed with only tagged edges (return)
203            - face normals are allowed to difffer
204          
205         */
206         for(eed= em->edges.first; eed; eed= eed->next) {
207                 eed->f1= 0;     // amount of selected
208                 eed->f2= 0; // amount of unselected
209         }
210         
211         for(efa= em->faces.first; efa; efa= efa->next) {
212                 if(efa->f & SELECT) {
213                         if(nor==NULL) nor= efa->n;
214                         if(efa->e1->f1 < 3) efa->e1->f1++;
215                         if(efa->e2->f1 < 3) efa->e2->f1++;
216                         if(efa->e3->f1 < 3) efa->e3->f1++;
217                         if(efa->e4 && efa->e4->f1 < 3) efa->e4->f1++;
218                 }
219                 else {
220                         if(efa->e1->f2 < 3) efa->e1->f2++;
221                         if(efa->e2->f2 < 3) efa->e2->f2++;
222                         if(efa->e3->f2 < 3) efa->e3->f2++;
223                         if(efa->e4 && efa->e4->f2 < 3) efa->e4->f2++;
224                 }
225         }
226         // now eed->f1 becomes tagged edge
227         for(eed= em->edges.first; eed; eed= eed->next) {
228                 if(eed->f1==2 && eed->f2==0) eed->f1= 1;
229                 else eed->f1= 0;
230         }
231         
232         // no vertices allowed with only tagged edges
233         for(eve= em->verts.first; eve; eve= eve->next) eve->f1= 0;
234         for(eed= em->edges.first; eed; eed= eed->next) {
235                 if(eed->f1) {
236                         eed->v1->f1 |= 1;
237                         eed->v2->f1 |= 1;
238                 }
239                 else {
240                         eed->v1->f1 |= 2;
241                         eed->v2->f1 |= 2;
242                 }
243         }
244         for(eve= em->verts.first; eve; eve= eve->next) {
245                 if(eve->f1==1) break;
246         }
247         if(eve) {
248                 error("Cannot make polygon with interior vertices");
249                 return;
250         }
251         
252         // check for faces
253         if(nor==NULL) {
254                 error("No faces selected to make FGon");
255                 return;
256         }
257
258         // and there we go
259         for(eed= em->edges.first; eed; eed= eed->next) {
260                 if(eed->f1) {
261                         eed->h |= EM_FGON;
262                         done= 1;
263                 }
264         }
265         
266         if(done==0) {
267                 error("Didn't find FGon to create");
268         }
269         else {
270                 Mesh *me= G.obedit->data;
271                 // signal to save edges with ngon flags
272                 if(!me->medge)
273                         me->medge= MEM_callocN(sizeof(MEdge), "fake mesh edge");
274                 
275                 EM_fgon_flags();        // redo flags and indices for fgons
276
277                 allqueue(REDRAWVIEW3D, 0);
278                 makeDispList(G.obedit);
279                 BIF_undo_push("Make FGon");
280         }
281 }
282
283 /* precondition; 4 vertices selected, check for 4 edges and create face */
284 static EditFace *addface_from_edges(void)
285 {
286         EditMesh *em = G.editMesh;
287         EditEdge *eed, *eedar[4]={NULL, NULL, NULL, NULL};
288         EditVert *v1=NULL, *v2=NULL, *v3=NULL, *v4=NULL;
289         int a;
290         
291         /* find the 4 edges */
292         for(eed= em->edges.first; eed; eed= eed->next) {
293                 if(eed->f & SELECT) {
294                         if(eedar[0]==NULL) eedar[0]= eed;
295                         else if(eedar[1]==NULL) eedar[1]= eed;
296                         else if(eedar[2]==NULL) eedar[2]= eed;
297                         else eedar[3]= eed;
298                 }
299         }
300         if(eedar[3]) {
301                 /* first 2 points */
302                 v1= eedar[0]->v1;
303                 v2= eedar[0]->v2;
304                 
305                 /* find the 2 edges connected to first edge */
306                 for(a=1; a<4; a++) {
307                         if( eedar[a]->v1 == v2) v3= eedar[a]->v2;
308                         else if(eedar[a]->v2 == v2) v3= eedar[a]->v1;
309                         else if( eedar[a]->v1 == v1) v4= eedar[a]->v2;
310                         else if(eedar[a]->v2 == v1) v4= eedar[a]->v1;
311                 }
312                 
313                 /* verify if last edge exists */
314                 if(v3 && v4) {
315                         for(a=1; a<4; a++) {
316                                 if( eedar[a]->v1==v3 && eedar[a]->v2==v4) break;
317                                 if( eedar[a]->v2==v3 && eedar[a]->v1==v4) break;
318                         }
319                         if(a!=4) {
320                                 return addfacelist(v1, v2, v3, v4, NULL, NULL);
321                         }
322                 }
323         }
324         return NULL;
325 }
326
327 void addedgeface_mesh(void)
328 {
329         EditMesh *em = G.editMesh;
330         EditVert *eve, *neweve[4];
331         EditEdge *eed;
332         EditFace *efa;
333         short amount=0;
334
335         if( (G.vd->lay & G.obedit->lay)==0 ) return;
336
337         /* how many selected ? */
338         if(G.scene->selectmode & SCE_SELECT_EDGE) {
339                 /* in edge mode finding selected vertices means flushing down edge codes... */
340                 /* can't make face with only edge selection info... */
341                 EM_selectmode_set();
342         }
343         
344         for(eve= em->verts.first; eve; eve= eve->next) {
345                 if(eve->f & SELECT) {
346                         amount++;
347                         if(amount>4) break;                     
348                         neweve[amount-1]= eve;
349                 }
350         }
351         if(amount==2) {
352                 eed= addedgelist(neweve[0], neweve[1], NULL);
353                 EM_select_edge(eed, 1);
354                 BIF_undo_push("Add edge");
355                 allqueue(REDRAWVIEW3D, 0);
356                 makeDispList(G.obedit);
357                 return;
358         }
359         else if(amount > 4) {
360                 make_fgon();
361                 return;
362         }
363         else if(amount<2) {
364                 error("Incorrect number of vertices to make edge/face");
365                 return;
366         }
367
368         efa= NULL; // check later
369
370         if(amount==3) {
371                 if(exist_face(neweve[0], neweve[1], neweve[2], 0)==0) {
372                         
373                         efa= addfacelist(neweve[0], neweve[1], neweve[2], 0, NULL, NULL);
374                         EM_select_face(efa, 1);
375                 }
376                 else error("The selected vertices already form a face");
377         }
378         else if(amount==4) {
379                 if(exist_face(neweve[0], neweve[1], neweve[2], neweve[3])==0) {
380                         int tria= 0;
381                         
382                         /* remove trias if they exist, 4 cases.... */
383                         if(exist_face(neweve[0], neweve[1], neweve[2], NULL)) tria++;
384                         if(exist_face(neweve[0], neweve[1], neweve[3], NULL)) tria++;
385                         if(exist_face(neweve[0], neweve[2], neweve[3], NULL)) tria++;
386                         if(exist_face(neweve[1], neweve[2], neweve[3], NULL)) tria++;
387                 
388                         if(tria==2) join_triangles();
389                         else {
390                                 
391                                 /* if 4 edges exist, we just create the face, convex or not */
392                                 efa= addface_from_edges();
393                                 if(efa==NULL) {
394                                         /* the order of vertices can be anything, three cases to check */
395                                         if( convex(neweve[0]->co, neweve[1]->co, neweve[2]->co, neweve[3]->co) ) {
396                                                 efa= addfacelist(neweve[0], neweve[1], neweve[2], neweve[3], NULL, NULL);
397                                         }
398                                         else if( convex(neweve[0]->co, neweve[2]->co, neweve[3]->co, neweve[1]->co) ) {
399                                                 efa= addfacelist(neweve[0], neweve[2], neweve[3], neweve[1], NULL, NULL);
400                                         }
401                                         else if( convex(neweve[0]->co, neweve[2]->co, neweve[1]->co, neweve[3]->co) ) {
402                                                 efa= addfacelist(neweve[0], neweve[2], neweve[1], neweve[3], NULL, NULL);
403                                         }
404                                         else error("The selected vertices form a concave quad");
405                                 }
406                         }
407
408                 }
409                 else error("The selected vertices already form a face");
410         }
411         
412         if(efa) {       // now we're calculating direction of normal
413                 float inp;      
414                 /* dot product view mat with normal, should give info! */
415         
416                 EM_select_face(efa, 1);
417                 CalcNormFloat(efa->v1->co, efa->v2->co, efa->v3->co, efa->n);
418
419                 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];
420
421                 if(inp < 0.0) flipface(efa);
422                 BIF_undo_push("Add face");
423         }
424         
425         countall();
426         allqueue(REDRAWVIEW3D, 0);
427         makeDispList(G.obedit);
428 }
429
430
431 void adduplicate_mesh(void)
432 {
433
434         TEST_EDITMESH
435
436         waitcursor(1);
437
438         adduplicateflag(SELECT);
439
440         waitcursor(0);
441         countall(); 
442         transform('d');
443 }
444
445
446
447 void add_primitiveMesh(int type)
448 {
449         EditMesh *em = G.editMesh;
450         Mesh *me;
451         EditVert *eve, *v1=NULL, *v2, *v3, *v4=NULL, *vtop, *vdown;
452         float *curs, d, dia, phi, phid, cent[3], vec[3], imat[3][3], mat[3][3];
453         float q[4], cmat[3][3];
454         static short tot=32, seg=32, subdiv=2;
455         short a, b, ext=0, fill=0, totoud, newob=0;
456         char *undostr="Add Primitive";
457         
458         if(G.scene->id.lib) return;
459
460         /* this function also comes from an info window */
461         if ELEM(curarea->spacetype, SPACE_VIEW3D, SPACE_INFO); else return;
462         if(G.vd==0) return;
463
464         /* if editmode exists for other type, it exits */
465         check_editmode(OB_MESH);
466         
467         if(G.f & (G_VERTEXPAINT+G_FACESELECT+G_TEXTUREPAINT)) {
468                 G.f &= ~(G_VERTEXPAINT+G_FACESELECT+G_TEXTUREPAINT);
469                 setcursor_space(SPACE_VIEW3D, CURSOR_EDIT);
470         }
471         
472         /* if no obedit: new object and enter editmode */
473         if(G.obedit==NULL) {
474                 /* add_object actually returns an object ! :-)
475                 But it also stores the added object struct in
476                 G.scene->basact->object (BASACT->object) */
477
478                 add_object_draw(OB_MESH);
479
480                 G.obedit= BASACT->object;
481                 
482                 where_is_object(G.obedit);
483                 
484                 make_editMesh();
485                 setcursor_space(SPACE_VIEW3D, CURSOR_EDIT);
486                 newob= 1;
487         }
488         me= G.obedit->data;
489         
490         /* deselectall */
491         EM_clear_flag_all(SELECT);
492
493         totoud= tot; /* store, and restore when cube/plane */
494         
495         /* imat and centre and size */
496         Mat3CpyMat4(mat, G.obedit->obmat);
497
498         curs= give_cursor();
499         VECCOPY(cent, curs);
500         cent[0]-= G.obedit->obmat[3][0];
501         cent[1]-= G.obedit->obmat[3][1];
502         cent[2]-= G.obedit->obmat[3][2];
503
504         if(type!= 31) {
505                 Mat3CpyMat4(imat, G.vd->viewmat);
506                 Mat3MulVecfl(imat, cent);
507                 Mat3MulMat3(cmat, imat, mat);
508                 Mat3Inv(imat,cmat);
509         } else {
510                 Mat3Inv(imat, mat);
511         }
512         
513         /* ext==extrudeflag, tot==amount of vertices in basis */
514
515         switch(type) {
516         case 0:         /* plane */
517                 tot= 4;
518                 ext= 0;
519                 fill= 1;
520                 if(newob) rename_id((ID *)G.obedit, "Plane");
521                 if(newob) rename_id((ID *)me, "Plane");
522                 undostr="Add Plane";
523                 break;
524         case 1:         /* cube  */
525                 tot= 4;
526                 ext= 1;
527                 fill= 1;
528                 if(newob) rename_id((ID *)G.obedit, "Cube");
529                 if(newob) rename_id((ID *)me, "Cube");
530                 undostr="Add Cube";
531                 break;
532         case 4:         /* circle  */
533                 if(button(&tot,3,100,"Vertices:")==0) return;
534                 ext= 0;
535                 fill= 0;
536                 if(newob) rename_id((ID *)G.obedit, "Circle");
537                 if(newob) rename_id((ID *)me, "Circle");
538                 if(G.scene->selectmode==SCE_SELECT_FACE) notice("Circle is not visible in face mode");
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: de X as */
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) addedgelist(eve->prev, eve, NULL);
717                         phi-=phid;
718                 }
719                 /* extrude and translate */
720                 vec[0]= vec[2]= 0.0;
721                 vec[1]= dia*phid;
722                 Mat3MulVecfl(imat, vec);
723                 for(a=0;a<seg-1;a++) {
724                         extrudeflag_vert(2);
725                         translateflag(2, vec);
726                 }
727                 recalc_editnormals();   // does face centers too
728         }
729         else if(type==11) {     /*  UVsphere */
730                 
731                 /* clear all flags */
732                 eve= em->verts.first;
733                 while(eve) {
734                         eve->f= 0;
735                         eve= eve->next;
736                 }
737                 
738                 /* one segment first */
739                 phi= 0; 
740                 phid/=2;
741                 for(a=0; a<=tot; a++) {
742                         vec[0]= dia*sin(phi);
743                         vec[1]= 0.0;
744                         vec[2]= dia*cos(phi);
745                         eve= addvertlist(vec);
746                         eve->f= 1+2+4;
747                         if(a==0) v1= eve;
748                         else addedgelist(eve->prev, eve, NULL);
749                         phi+= phid;
750                 }
751                 
752                 /* extrude and rotate */
753                 phi= M_PI/seg;
754                 q[0]= cos(phi);
755                 q[3]= sin(phi);
756                 q[1]=q[2]= 0;
757                 QuatToMat3(q, cmat);
758                 
759                 for(a=0; a<seg; a++) {
760                         extrudeflag_vert(2);
761                         rotateflag(2, v1->co, cmat);
762                 }
763
764                 removedoublesflag(4, 0.0001);
765
766                 /* and now do imat */
767                 eve= em->verts.first;
768                 while(eve) {
769                         if(eve->f & SELECT) {
770                                 VecAddf(eve->co,eve->co,cent);
771                                 Mat3MulVecfl(imat,eve->co);
772                         }
773                         eve= eve->next;
774                 }
775         }
776         else if(type==12) {     /* Icosphere */
777                 EditVert *eva[12];
778
779                 /* clear all flags */
780                 eve= em->verts.first;
781                 while(eve) {
782                         eve->f= 0;
783                         eve= eve->next;
784                 }
785                 dia/=200;
786                 for(a=0;a<12;a++) {
787                         vec[0]= dia*icovert[a][0];
788                         vec[1]= dia*icovert[a][1];
789                         vec[2]= dia*icovert[a][2];
790                         eva[a]= addvertlist(vec);
791                         eva[a]->f= 1+2;
792                 }
793                 for(a=0;a<20;a++) {
794                         v1= eva[ icoface[a][0] ];
795                         v2= eva[ icoface[a][1] ];
796                         v3= eva[ icoface[a][2] ];
797                         addfacelist(v1, v2, v3, 0, NULL, NULL);
798                 }
799
800                 dia*=200;
801                 for(a=1; a<subdiv; a++) subdivideflag(2, dia, 0);
802                 /* and now do imat */
803                 eve= em->verts.first;
804                 while(eve) {
805                         if(eve->f & 2) {
806                                 VecAddf(eve->co,eve->co,cent);
807                                 Mat3MulVecfl(imat,eve->co);
808                         }
809                         eve= eve->next;
810                 }
811         } else if (type==13) {  /* Monkey */
812                 extern int monkeyo, monkeynv, monkeynf;
813                 extern signed char monkeyf[][4];
814                 extern signed char monkeyv[][3];
815                 EditVert **tv= MEM_mallocN(sizeof(*tv)*monkeynv*2, "tv");
816                 int i;
817
818                 for (i=0; i<monkeynv; i++) {
819                         float v[3];
820                         v[0]= (monkeyv[i][0]+127)/128.0, v[1]= monkeyv[i][1]/128.0, v[2]= monkeyv[i][2]/128.0;
821                         tv[i]= addvertlist(v);
822                         tv[i]->f |= SELECT;
823                         tv[monkeynv+i]= (fabs(v[0]= -v[0])<0.001)?tv[i]:addvertlist(v);
824                         tv[monkeynv+i]->f |= SELECT;
825                 }
826                 for (i=0; i<monkeynf; i++) {
827                         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);
828                         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);
829                 }
830
831                 MEM_freeN(tv);
832
833                 /* and now do imat */
834                 eve= em->verts.first;
835                 while(eve) {
836                         if(eve->f & SELECT) {
837                                 VecAddf(eve->co,eve->co,cent);
838                                 Mat3MulVecfl(imat,eve->co);
839                         }
840                         eve= eve->next;
841                 }
842         }
843         
844         // simple selection flush OK, based on fact it's a single model
845         EM_select_flush(); // flushes vertex -> edge -> face selection
846         
847         if(type!=0 && type!=10) righthandfaces(1);
848         countall();
849
850         allqueue(REDRAWINFO, 1);        /* 1, because header->win==0! */        
851         allqueue(REDRAWALL, 0);
852         makeDispList(G.obedit);
853
854         /* if a new object was created, it stores it in Mesh, for reload original data and undo */
855         if(newob) load_editMesh();      
856         BIF_undo_push(undostr);
857 }
858