Audaspace (GSoC): First merging commit
[blender.git] / source / blender / editors / mesh / editmesh_tools.c
1  /* $Id$
2  *
3  * ***** BEGIN GPL LICENSE BLOCK *****
4  *
5  * This program is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU General Public License
7  * as published by the Free Software Foundation; either version 2
8  * of the License, or (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program; if not, write to the Free Software Foundation,
17  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18  *
19  * The Original Code is Copyright (C) 2004 by Blender Foundation.
20  * All rights reserved.
21  *
22  * The Original Code is: all of this file.
23  *
24  * Contributor(s): Johnny Matthews, Geoffrey Bantle.
25  *
26  * ***** END GPL LICENSE BLOCK *****
27  */
28
29 /*
30
31 editmesh_tool.c: UI called tools for editmesh, geometry changes here, otherwise in mods.c
32
33 */
34
35 #include <stdlib.h>
36 #include <string.h>
37 #include <math.h>
38 #include <float.h>
39
40 #include "BLO_sys_types.h" // for intptr_t support
41
42 #include "DNA_meshdata_types.h"
43 #include "DNA_modifier_types.h"
44 #include "DNA_object_types.h"
45 #include "DNA_scene_types.h"
46 #include "DNA_key_types.h"
47
48 #include "MEM_guardedalloc.h"
49
50 #include "RNA_define.h"
51 #include "RNA_access.h"
52
53 #include "BLI_blenlib.h"
54 #include "BLI_math.h"
55 #include "BLI_editVert.h"
56 #include "BLI_rand.h"
57 #include "BLI_ghash.h"
58 #include "BLI_linklist.h"
59 #include "BLI_heap.h"
60
61 #include "BKE_context.h"
62 #include "BKE_depsgraph.h"
63 #include "BKE_global.h"
64 #include "BKE_key.h"
65 #include "BKE_mesh.h"
66 #include "BKE_bmesh.h"
67 #include "BKE_report.h"
68
69
70 #include "WM_api.h"
71 #include "WM_types.h"
72
73 #include "ED_mesh.h"
74 #include "ED_screen.h"
75 #include "ED_transform.h"
76 #include "ED_view3d.h"
77 #include "ED_object.h"
78
79
80 #include "mesh_intern.h"
81
82 /* XXX */
83 static void waitcursor(int val) {}
84 #define add_numbut(a, b, c, d, e, f, g) {}
85
86 /* XXX */
87
88 /* RNA corner cut enum property - used in multiple files for tools
89  * that need this property for esubdivideflag() */
90 EnumPropertyItem corner_type_items[] = {
91         {SUBDIV_CORNER_PATH,  "PATH", 0, "Path", ""},
92         {SUBDIV_CORNER_INNERVERT,  "INNER_VERTEX", 0, "Inner Vertex", ""},
93         {SUBDIV_CORNER_FAN,  "FAN",  0, "Fan", ""},
94         {0, NULL, 0, NULL, NULL}};
95
96
97 /* local prototypes ---------------*/
98 static void free_tagged_edges_faces(EditMesh *em, EditEdge *eed, EditFace *efa);
99 int EdgeLoopDelete(EditMesh *em, wmOperator *op);
100
101 /********* qsort routines *********/
102
103
104 typedef struct xvertsort {
105         float x;
106         EditVert *v1;
107 } xvertsort;
108
109 static int vergxco(const void *v1, const void *v2)
110 {
111         const xvertsort *x1=v1, *x2=v2;
112
113         if( x1->x > x2->x ) return 1;
114         else if( x1->x < x2->x) return -1;
115         return 0;
116 }
117
118 struct facesort {
119         uintptr_t x;
120         struct EditFace *efa;
121 };
122
123
124 static int vergface(const void *v1, const void *v2)
125 {
126         const struct facesort *x1=v1, *x2=v2;
127
128         if( x1->x > x2->x ) return 1;
129         else if( x1->x < x2->x) return -1;
130         return 0;
131 }
132
133
134 /* *********************************** */
135
136 static void convert_to_triface(EditMesh *em, int direction)
137 {
138         EditFace *efa, *efan, *next;
139         float fac;
140
141         efa= em->faces.last;
142         while(efa) {
143                 next= efa->prev;
144                 if(efa->v4) {
145                         if(efa->f & SELECT) {
146                                 /* choose shortest diagonal for split */
147                                 fac= len_v3v3(efa->v1->co, efa->v3->co) - len_v3v3(efa->v2->co, efa->v4->co);
148                                 /* this makes sure exact squares get split different in both cases */
149                                 if( (direction==0 && fac<FLT_EPSILON) || (direction && fac>0.0f) ) {
150                                         efan= EM_face_from_faces(em, efa, NULL, 0, 1, 2, -1);
151                                         if(efa->f & SELECT) EM_select_face(efan, 1);
152                                         efan= EM_face_from_faces(em, efa, NULL, 0, 2, 3, -1);
153                                         if(efa->f & SELECT) EM_select_face(efan, 1);
154                                 }
155                                 else {
156                                         efan= EM_face_from_faces(em, efa, NULL, 0, 1, 3, -1);
157                                         if(efa->f & SELECT) EM_select_face(efan, 1);
158                                         efan= EM_face_from_faces(em, efa, NULL, 1, 2, 3, -1);
159                                         if(efa->f & SELECT) EM_select_face(efan, 1);
160                                 }
161
162                                 BLI_remlink(&em->faces, efa);
163                                 free_editface(em, efa);
164                         }
165                 }
166                 efa= next;
167         }
168
169         EM_fgon_flags(em);      // redo flags and indices for fgons
170
171
172 }
173
174 int removedoublesflag(EditMesh *em, short flag, short automerge, float limit)           /* return amount */
175 {
176         /*
177                 flag -          Test with vert->flags
178                 automerge -     Alternative operation, merge unselected into selected.
179                                         Used for "Auto Weld" mode. warning.
180                 limit -         Quick manhattan distance between verts.
181         */
182
183         /* all verts with (flag & 'flag') are being evaluated */
184         EditVert *eve, *v1, *nextve;
185         EditEdge *eed, *e1, *nexted;
186         EditFace *efa, *nextvl;
187         xvertsort *sortblock, *sb, *sb1;
188         struct facesort *vlsortblock, *vsb, *vsb1;
189         int a, b, test, amount;
190
191
192         /* flag 128 is cleared, count */
193
194         /* Normal non weld operation */
195         eve= em->verts.first;
196         amount= 0;
197         while(eve) {
198                 eve->f &= ~128;
199                 if(eve->h==0 && (automerge || (eve->f & flag))) amount++;
200                 eve= eve->next;
201         }
202         if(amount==0) return 0;
203
204         /* allocate memory and qsort */
205         sb= sortblock= MEM_mallocN(sizeof(xvertsort)*amount,"sortremovedoub");
206         eve= em->verts.first;
207         while(eve) {
208                 if(eve->h==0 && (automerge || (eve->f & flag))) {
209                         sb->x= eve->co[0]+eve->co[1]+eve->co[2];
210                         sb->v1= eve;
211                         sb++;
212                 }
213                 eve= eve->next;
214         }
215         qsort(sortblock, amount, sizeof(xvertsort), vergxco);
216
217
218         /* test for doubles */
219         sb= sortblock;
220         if (automerge) {
221                 for(a=0; a<amount; a++, sb++) {
222                         eve= sb->v1;
223                         if( (eve->f & 128)==0 ) {
224                                 sb1= sb+1;
225                                 for(b=a+1; b<amount && (eve->f & 128)==0; b++, sb1++) {
226                                         if(sb1->x - sb->x > limit) break;
227
228                                         /* when automarge, only allow unselected->selected */
229                                         v1= sb1->v1;
230                                         if( (v1->f & 128)==0 ) {
231                                                 if ((eve->f & flag)==0 && (v1->f & flag)==1) {
232                                                         if(     (float)fabs(v1->co[0]-eve->co[0])<=limit &&
233                                                                 (float)fabs(v1->co[1]-eve->co[1])<=limit &&
234                                                                 (float)fabs(v1->co[2]-eve->co[2])<=limit)
235                                                         {       /* unique bit */
236                                                                 eve->f|= 128;
237                                                                 eve->tmp.v = v1;
238                                                         }
239                                                 } else if(      (eve->f & flag)==1 && (v1->f & flag)==0 ) {
240                                                         if(     (float)fabs(v1->co[0]-eve->co[0])<=limit &&
241                                                                 (float)fabs(v1->co[1]-eve->co[1])<=limit &&
242                                                                 (float)fabs(v1->co[2]-eve->co[2])<=limit)
243                                                         {       /* unique bit */
244                                                                 v1->f|= 128;
245                                                                 v1->tmp.v = eve;
246                                                         }
247                                                 }
248                                         }
249                                 }
250                         }
251                 }
252         } else {
253                 for(a=0; a<amount; a++, sb++) {
254                         eve= sb->v1;
255                         if( (eve->f & 128)==0 ) {
256                                 sb1= sb+1;
257                                 for(b=a+1; b<amount; b++, sb1++) {
258                                         /* first test: simpel dist */
259                                         if(sb1->x - sb->x > limit) break;
260                                         v1= sb1->v1;
261
262                                         /* second test: is vertex allowed */
263                                         if( (v1->f & 128)==0 ) {
264                                                 if(     (float)fabs(v1->co[0]-eve->co[0])<=limit &&
265                                                         (float)fabs(v1->co[1]-eve->co[1])<=limit &&
266                                                         (float)fabs(v1->co[2]-eve->co[2])<=limit)
267                                                 {
268                                                         v1->f|= 128;
269                                                         v1->tmp.v = eve;
270                                                 }
271                                         }
272                                 }
273                         }
274                 }
275         }
276         MEM_freeN(sortblock);
277
278         if (!automerge)
279                 for(eve = em->verts.first; eve; eve=eve->next)
280                         if((eve->f & flag) && (eve->f & 128))
281                                 EM_data_interp_from_verts(em, eve, eve->tmp.v, eve->tmp.v, 0.5f);
282
283         /* test edges and insert again */
284         eed= em->edges.first;
285         while(eed) {
286                 eed->f2= 0;
287                 eed= eed->next;
288         }
289         eed= em->edges.last;
290         while(eed) {
291                 nexted= eed->prev;
292
293                 if(eed->f2==0) {
294                         if( (eed->v1->f & 128) || (eed->v2->f & 128) ) {
295                                 remedge(em, eed);
296
297                                 if(eed->v1->f & 128) eed->v1 = eed->v1->tmp.v;
298                                 if(eed->v2->f & 128) eed->v2 = eed->v2->tmp.v;
299                                 e1= addedgelist(em, eed->v1, eed->v2, eed);
300
301                                 if(e1) {
302                                         e1->f2= 1;
303                                         if(eed->f & SELECT)
304                                                 e1->f |= SELECT;
305                                 }
306                                 if(e1!=eed) free_editedge(em, eed);
307                         }
308                 }
309                 eed= nexted;
310         }
311
312         /* first count amount of test faces */
313         efa= (struct EditFace *)em->faces.first;
314         amount= 0;
315         while(efa) {
316                 efa->f1= 0;
317                 if(efa->v1->f & 128) efa->f1= 1;
318                 else if(efa->v2->f & 128) efa->f1= 1;
319                 else if(efa->v3->f & 128) efa->f1= 1;
320                 else if(efa->v4 && (efa->v4->f & 128)) efa->f1= 1;
321
322                 if(efa->f1==1) amount++;
323                 efa= efa->next;
324         }
325
326         /* test faces for double vertices, and if needed remove them */
327         efa= (struct EditFace *)em->faces.first;
328         while(efa) {
329                 nextvl= efa->next;
330                 if(efa->f1==1) {
331
332                         if(efa->v1->f & 128) efa->v1= efa->v1->tmp.v;
333                         if(efa->v2->f & 128) efa->v2= efa->v2->tmp.v;
334                         if(efa->v3->f & 128) efa->v3= efa->v3->tmp.v;
335                         if(efa->v4 && (efa->v4->f & 128)) efa->v4= efa->v4->tmp.v;
336
337                         test= 0;
338                         if(efa->v1==efa->v2) test+=1;
339                         if(efa->v2==efa->v3) test+=2;
340                         if(efa->v3==efa->v1) test+=4;
341                         if(efa->v4==efa->v1) test+=8;
342                         if(efa->v3==efa->v4) test+=16;
343                         if(efa->v2==efa->v4) test+=32;
344
345                         if(test) {
346                                 if(efa->v4) {
347                                         if(test==1 || test==2) {
348                                                 efa->v2= efa->v3;
349                                                 efa->v3= efa->v4;
350                                                 efa->v4= 0;
351
352                                                 EM_data_interp_from_faces(em, efa, NULL, efa, 0, 2, 3, 3);
353
354                                                 test= 0;
355                                         }
356                                         else if(test==8 || test==16) {
357                                                 efa->v4= 0;
358                                                 test= 0;
359                                         }
360                                         else {
361                                                 BLI_remlink(&em->faces, efa);
362                                                 free_editface(em, efa);
363                                                 amount--;
364                                         }
365                                 }
366                                 else {
367                                         BLI_remlink(&em->faces, efa);
368                                         free_editface(em, efa);
369                                         amount--;
370                                 }
371                         }
372
373                         if(test==0) {
374                                 /* set edge pointers */
375                                 efa->e1= findedgelist(em, efa->v1, efa->v2);
376                                 efa->e2= findedgelist(em, efa->v2, efa->v3);
377                                 if(efa->v4==0) {
378                                         efa->e3= findedgelist(em, efa->v3, efa->v1);
379                                         efa->e4= 0;
380                                 }
381                                 else {
382                                         efa->e3= findedgelist(em, efa->v3, efa->v4);
383                                         efa->e4= findedgelist(em, efa->v4, efa->v1);
384                                 }
385                         }
386                 }
387                 efa= nextvl;
388         }
389
390         /* double faces: sort block */
391         /* count again, now all selected faces */
392         amount= 0;
393         efa= em->faces.first;
394         while(efa) {
395                 efa->f1= 0;
396                 if(faceselectedOR(efa, 1)) {
397                         efa->f1= 1;
398                         amount++;
399                 }
400                 efa= efa->next;
401         }
402
403         if(amount) {
404                 /* double faces: sort block */
405                 vsb= vlsortblock= MEM_mallocN(sizeof(struct facesort)*amount, "sortremovedoub");
406                 efa= em->faces.first;
407                 while(efa) {
408                         if(efa->f1 & 1) {
409                                 if(efa->v4) vsb->x= (uintptr_t) MIN4( (uintptr_t)efa->v1, (uintptr_t)efa->v2, (uintptr_t)efa->v3, (uintptr_t)efa->v4);
410                                 else vsb->x= (uintptr_t) MIN3( (uintptr_t)efa->v1, (uintptr_t)efa->v2, (uintptr_t)efa->v3);
411
412                                 vsb->efa= efa;
413                                 vsb++;
414                         }
415                         efa= efa->next;
416                 }
417
418                 qsort(vlsortblock, amount, sizeof(struct facesort), vergface);
419
420                 vsb= vlsortblock;
421                 for(a=0; a<amount; a++) {
422                         efa= vsb->efa;
423                         if( (efa->f1 & 128)==0 ) {
424                                 vsb1= vsb+1;
425
426                                 for(b=a+1; b<amount; b++) {
427
428                                         /* first test: same pointer? */
429                                         if(vsb->x != vsb1->x) break;
430
431                                         /* second test: is test permitted? */
432                                         efa= vsb1->efa;
433                                         if( (efa->f1 & 128)==0 ) {
434                                                 if( compareface(efa, vsb->efa)) efa->f1 |= 128;
435
436                                         }
437                                         vsb1++;
438                                 }
439                         }
440                         vsb++;
441                 }
442
443                 MEM_freeN(vlsortblock);
444
445                 /* remove double faces */
446                 efa= (struct EditFace *)em->faces.first;
447                 while(efa) {
448                         nextvl= efa->next;
449                         if(efa->f1 & 128) {
450                                 BLI_remlink(&em->faces, efa);
451                                 free_editface(em, efa);
452                         }
453                         efa= nextvl;
454                 }
455         }
456
457         /* remove double vertices */
458         a= 0;
459         eve= (struct EditVert *)em->verts.first;
460         while(eve) {
461                 nextve= eve->next;
462                 if(automerge || eve->f & flag) {
463                         if(eve->f & 128) {
464                                 a++;
465                                 BLI_remlink(&em->verts, eve);
466                                 free_editvert(em, eve);
467                         }
468                 }
469                 eve= nextve;
470         }
471
472         return a;       /* amount */
473 }
474
475 static int removedoublesflag_exec(bContext *C, wmOperator *op)
476 {
477         Object *obedit= CTX_data_edit_object(C);
478         EditMesh *em= BKE_mesh_get_editmesh(((Mesh *)obedit->data));
479
480         int count = removedoublesflag(em,1,0,RNA_float_get(op->ptr, "limit"));
481         
482         if(count) {
483                 recalc_editnormals(em);
484
485                 DAG_id_flush_update(obedit->data, OB_RECALC_DATA);
486                 WM_event_add_notifier(C, NC_GEOM|ND_DATA, obedit->data);
487         }
488
489         BKE_reportf(op->reports, RPT_INFO, "Removed %d vertices", count);
490         BKE_mesh_end_editmesh(obedit->data, em);
491
492         return OPERATOR_FINISHED;
493 }
494
495 void MESH_OT_remove_doubles(wmOperatorType *ot)
496 {
497         /* identifiers */
498         ot->name= "Remove Doubles";
499         ot->description= "Remove duplicate vertices";
500         ot->idname= "MESH_OT_remove_doubles";
501
502         /* api callbacks */
503         ot->exec= removedoublesflag_exec;
504         ot->poll= ED_operator_editmesh;
505
506         /* flags */
507         ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
508
509         RNA_def_float(ot->srna, "limit", 0.0001f, 0.000001f, 50.0f, "Merge Threshold", "Minimum distance between merged verts", 0.00001f, 2.0f);
510 }
511
512 // XXX is this needed?
513 /* called from buttons */
514 static void xsortvert_flag__doSetX(void *userData, EditVert *eve, int x, int y, int index)
515 {
516         xvertsort *sortblock = userData;
517
518         sortblock[index].x = x;
519 }
520
521 /* all verts with (flag & 'flag') are sorted */
522 void xsortvert_flag(bContext *C, int flag)
523 {
524         ViewContext vc;
525         EditVert *eve;
526         xvertsort *sortblock;
527         ListBase tbase;
528         int i, amount;
529
530         em_setup_viewcontext(C, &vc);
531
532         amount = BLI_countlist(&vc.em->verts);
533         sortblock = MEM_callocN(sizeof(xvertsort)*amount,"xsort");
534         for (i=0,eve= vc.em->verts.first; eve; i++,eve=eve->next)
535                 if(eve->f & flag)
536                         sortblock[i].v1 = eve;
537
538         ED_view3d_init_mats_rv3d(vc.obedit, vc.rv3d);
539         mesh_foreachScreenVert(&vc, xsortvert_flag__doSetX, sortblock, 0);
540
541         qsort(sortblock, amount, sizeof(xvertsort), vergxco);
542
543                 /* make temporal listbase */
544         tbase.first= tbase.last= 0;
545         for (i=0; i<amount; i++) {
546                 eve = sortblock[i].v1;
547
548                 if (eve) {
549                         BLI_remlink(&vc.em->verts, eve);
550                         BLI_addtail(&tbase, eve);
551                 }
552         }
553
554         addlisttolist(&vc.em->verts, &tbase);
555
556         MEM_freeN(sortblock);
557
558 }
559
560 /* called from buttons */
561 void hashvert_flag(EditMesh *em, int flag)
562 {
563         /* switch vertex order using hash table */
564         EditVert *eve;
565         struct xvertsort *sortblock, *sb, onth, *newsort;
566         ListBase tbase;
567         int amount, a, b;
568
569         /* count */
570         eve= em->verts.first;
571         amount= 0;
572         while(eve) {
573                 if(eve->f & flag) amount++;
574                 eve= eve->next;
575         }
576         if(amount==0) return;
577
578         /* allocate memory */
579         sb= sortblock= (struct xvertsort *)MEM_mallocN(sizeof(struct xvertsort)*amount,"sortremovedoub");
580         eve= em->verts.first;
581         while(eve) {
582                 if(eve->f & flag) {
583                         sb->v1= eve;
584                         sb++;
585                 }
586                 eve= eve->next;
587         }
588
589         BLI_srand(1);
590
591         sb= sortblock;
592         for(a=0; a<amount; a++, sb++) {
593                 b= (int)(amount*BLI_drand());
594                 if(b>=0 && b<amount) {
595                         newsort= sortblock+b;
596                         onth= *sb;
597                         *sb= *newsort;
598                         *newsort= onth;
599                 }
600         }
601
602         /* make temporal listbase */
603         tbase.first= tbase.last= 0;
604         sb= sortblock;
605         while(amount--) {
606                 eve= sb->v1;
607                 BLI_remlink(&em->verts, eve);
608                 BLI_addtail(&tbase, eve);
609                 sb++;
610         }
611
612         addlisttolist(&em->verts, &tbase);
613
614         MEM_freeN(sortblock);
615
616 }
617
618 /* generic extern called extruder */
619 void extrude_mesh(Scene *scene, Object *obedit, EditMesh *em, wmOperator *op, short type)
620 {
621         float nor[3]= {0.0, 0.0, 0.0};
622         short transmode= 0;
623
624         if(type<1) return;
625
626         if(type==1)  transmode= extrudeflag(obedit, em, SELECT, nor, 0);
627         else if(type==4) transmode= extrudeflag_verts_indiv(em, SELECT, nor);
628         else if(type==3) transmode= extrudeflag_edges_indiv(em, SELECT, nor);
629         else transmode= extrudeflag_face_indiv(em, SELECT, nor);
630
631         EM_stats_update(em);
632
633         if(transmode==0) {
634                 BKE_report(op->reports, RPT_ERROR, "Not a valid selection for extrude");
635         }
636         else {
637                 EM_fgon_flags(em);
638
639                         /* We need to force immediate calculation here because
640                         * transform may use derived objects (which are now stale).
641                         *
642                         * This shouldn't be necessary, derived queries should be
643                         * automatically building this data if invalid. Or something.
644                         */
645                 DAG_id_flush_update(obedit->data, OB_RECALC_DATA);
646
647                 /* individual faces? */
648 //              BIF_TransformSetUndo("Extrude");
649                 if(type==2) {
650 //                      initTransform(TFM_SHRINKFATTEN, CTX_NO_PET|CTX_NO_MIRROR);
651 //                      Transform();
652                 }
653                 else {
654 //                      initTransform(TFM_TRANSLATION, CTX_NO_PET|CTX_NO_MIRROR);
655                         if(transmode=='n') {
656                                 mul_m4_v3(obedit->obmat, nor);
657                                 sub_v3_v3(nor, obedit->obmat[3]);
658 //                              BIF_setSingleAxisConstraint(nor, "along normal");
659                         }
660 //                      Transform();
661                 }
662         }
663
664 }
665
666 // XXX should be a menu item
667 static int mesh_extrude_invoke(bContext *C, wmOperator *op, wmEvent *event)
668 {
669         Scene *scene= CTX_data_scene(C);
670         Object *obedit= CTX_data_edit_object(C);
671         EditMesh *em= BKE_mesh_get_editmesh((Mesh *)obedit->data);
672         
673         extrude_mesh(scene, obedit, em, op, RNA_int_get(op->ptr, "type"));
674
675         BKE_mesh_end_editmesh(obedit->data, em);
676
677         DAG_id_flush_update(obedit->data, OB_RECALC_DATA);
678         WM_event_add_notifier(C, NC_GEOM|ND_DATA, obedit->data);
679
680         return OPERATOR_FINISHED;
681 }
682
683 /* extrude without transform */
684 static int mesh_extrude_exec(bContext *C, wmOperator *op)
685 {
686         Scene *scene= CTX_data_scene(C);
687         Object *obedit= CTX_data_edit_object(C);
688         EditMesh *em= BKE_mesh_get_editmesh(obedit->data);
689
690         extrude_mesh(scene, obedit, em, op, RNA_int_get(op->ptr, "type"));
691
692         DAG_id_flush_update(obedit->data, OB_RECALC_DATA);
693         WM_event_add_notifier(C, NC_GEOM|ND_DATA, obedit->data);
694
695         BKE_mesh_end_editmesh(obedit->data, em);
696         return OPERATOR_FINISHED;
697 }
698
699 EnumPropertyItem extrude_items[] = {
700                 {1, "REGION", 0, "Region", ""},
701                 {2, "FACES", 0, "Individual Faces", ""},
702                 {3, "EDGES", 0, "Only Edges", ""},
703                 {4, "VERTS", 0, "Only Vertices", ""},
704                 {0, NULL, 0, NULL, NULL}};
705
706
707 static EnumPropertyItem *extrude_itemf(bContext *C, PointerRNA *ptr, int *free)
708 {
709         EnumPropertyItem *item= NULL;
710         Object *obedit= CTX_data_edit_object(C);
711         EditMesh *em;
712
713         int totitem= 0;
714
715         if(!obedit)
716                 return extrude_items;
717
718         em = BKE_mesh_get_editmesh(obedit->data);
719
720         EM_stats_update(em);
721
722         if(em->selectmode & SCE_SELECT_VERTEX) {
723                 if(em->totvertsel==0) {}
724                 else if(em->totvertsel==1) { RNA_enum_item_add(&item, &totitem, &extrude_items[3]); }
725                 else if(em->totedgesel==0) { RNA_enum_item_add(&item, &totitem, &extrude_items[3]); }
726                 else if(em->totfacesel==0) {
727                         RNA_enum_item_add(&item, &totitem, &extrude_items[2]);
728                         RNA_enum_item_add(&item, &totitem, &extrude_items[3]);
729                 }
730                 else if(em->totfacesel==1) {
731                         RNA_enum_item_add(&item, &totitem, &extrude_items[0]);
732                         RNA_enum_item_add(&item, &totitem, &extrude_items[2]);
733                         RNA_enum_item_add(&item, &totitem, &extrude_items[3]);
734                 }
735                 else {
736                         RNA_enum_item_add(&item, &totitem, &extrude_items[0]);
737                         RNA_enum_item_add(&item, &totitem, &extrude_items[1]);
738                         RNA_enum_item_add(&item, &totitem, &extrude_items[2]);
739                         RNA_enum_item_add(&item, &totitem, &extrude_items[3]);
740                 }
741         }
742         else if(em->selectmode & SCE_SELECT_EDGE) {
743                 if (em->totedgesel==0) {}
744                 else if (em->totedgesel==1) { RNA_enum_item_add(&item, &totitem, &extrude_items[2]); }
745                 else if(em->totfacesel==0) { RNA_enum_item_add(&item, &totitem, &extrude_items[2]); }
746                 else if(em->totfacesel==1) {
747                         RNA_enum_item_add(&item, &totitem, &extrude_items[0]);
748                         RNA_enum_item_add(&item, &totitem, &extrude_items[2]);
749                 }
750                 else {
751                         RNA_enum_item_add(&item, &totitem, &extrude_items[0]);
752                         RNA_enum_item_add(&item, &totitem, &extrude_items[1]);
753                         RNA_enum_item_add(&item, &totitem, &extrude_items[2]);
754                 }
755         }
756         else {
757                 if (em->totfacesel == 0) {}
758                 else if (em->totfacesel == 1) { RNA_enum_item_add(&item, &totitem, &extrude_items[0]); }
759                 else {
760                         RNA_enum_item_add(&item, &totitem, &extrude_items[0]);
761                         RNA_enum_item_add(&item, &totitem, &extrude_items[1]);
762                 }
763         }
764
765         if(item) {
766                 RNA_enum_item_end(&item, &totitem);
767                 *free= 1;
768                 return item;
769         }
770         else {
771                 return NULL;
772         }
773 }
774
775 void MESH_OT_extrude(wmOperatorType *ot)
776 {
777         PropertyRNA *prop;
778
779         /* identifiers */
780         ot->name= "Extrude";
781         ot->description= "Extrude selected vertices, edges or faces";
782         ot->idname= "MESH_OT_extrude";
783
784         /* api callbacks */
785         ot->invoke= mesh_extrude_invoke;
786         ot->exec= mesh_extrude_exec;
787         ot->poll= ED_operator_editmesh;
788
789         /* flags */
790         ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
791
792         /* properties */
793         prop= RNA_def_enum(ot->srna, "type", extrude_items, 0, "Type", "");
794         RNA_def_property_flag(prop, PROP_HIDDEN);
795         RNA_def_enum_funcs(prop, extrude_itemf);
796         ot->prop= prop;
797 }
798
799 static int split_mesh(bContext *C, wmOperator *op)
800 {
801         Object *obedit= CTX_data_edit_object(C);
802         EditMesh *em= BKE_mesh_get_editmesh((Mesh *)obedit->data);
803
804         WM_cursor_wait(1);
805
806         /* make duplicate first */
807         adduplicateflag(em, SELECT);
808         /* old faces have flag 128 set, delete them */
809         delfaceflag(em, 128);
810         recalc_editnormals(em);
811
812         WM_cursor_wait(0);
813
814         DAG_id_flush_update(obedit->data, OB_RECALC_DATA);
815         WM_event_add_notifier(C, NC_GEOM|ND_DATA, obedit->data);
816
817         BKE_mesh_end_editmesh(obedit->data, em);
818         return OPERATOR_FINISHED;
819 }
820
821 void MESH_OT_split(wmOperatorType *ot)
822 {
823         /* identifiers */
824         ot->name= "Split";
825         ot->description= "Split selected geometry into separate disconnected mesh";
826         ot->idname= "MESH_OT_split";
827
828         /* api callbacks */
829         ot->exec= split_mesh;
830         ot->poll= ED_operator_editmesh;
831
832         /* flags */
833         ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
834 }
835
836
837 static int extrude_repeat_mesh(bContext *C, wmOperator *op)
838 {
839         Object *obedit= CTX_data_edit_object(C);
840         EditMesh *em= BKE_mesh_get_editmesh((Mesh *)obedit->data);
841
842         RegionView3D *rv3d = ED_view3d_context_rv3d(C);
843
844         int steps = RNA_int_get(op->ptr,"steps");
845
846         float offs = RNA_float_get(op->ptr,"offset");
847
848         float dvec[3], tmat[3][3], bmat[3][3], nor[3]= {0.0, 0.0, 0.0};
849         short a;
850
851         /* dvec */
852         dvec[0]= rv3d->persinv[2][0];
853         dvec[1]= rv3d->persinv[2][1];
854         dvec[2]= rv3d->persinv[2][2];
855         normalize_v3(dvec);
856         dvec[0]*= offs;
857         dvec[1]*= offs;
858         dvec[2]*= offs;
859
860         /* base correction */
861         copy_m3_m4(bmat, obedit->obmat);
862         invert_m3_m3(tmat, bmat);
863         mul_m3_v3(tmat, dvec);
864
865         for(a=0; a<steps; a++) {
866                 extrudeflag(obedit, em, SELECT, nor, 0);
867                 translateflag(em, SELECT, dvec);
868         }
869
870         recalc_editnormals(em);
871
872         EM_fgon_flags(em);
873
874         DAG_id_flush_update(obedit->data, OB_RECALC_DATA);
875         WM_event_add_notifier(C, NC_GEOM|ND_DATA, obedit->data);
876
877         BKE_mesh_end_editmesh(obedit->data, em);
878         return OPERATOR_FINISHED;
879 }
880
881 void MESH_OT_extrude_repeat(wmOperatorType *ot)
882 {
883         /* identifiers */
884         ot->name= "Extrude Repeat Mesh";
885         ot->description= "Extrude selected vertices, edges or faces repeatedly";
886         ot->idname= "MESH_OT_extrude_repeat";
887
888         /* api callbacks */
889         ot->exec= extrude_repeat_mesh;
890         ot->poll= ED_operator_editmesh;
891
892         /* flags */
893         ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
894
895         /* props */
896         RNA_def_float(ot->srna, "offset", 2.0f, 0.0f, 100.0f, "Offset", "", 0.0f, FLT_MAX);
897         RNA_def_int(ot->srna, "steps", 10, 0, 180, "Steps", "", 0, INT_MAX);
898 }
899
900 /* ************************** spin operator ******************** */
901
902
903 static int spin_mesh(bContext *C, wmOperator *op, float *dvec, int steps, float degr, int dupli )
904 {
905         Object *obedit= CTX_data_edit_object(C);
906         ToolSettings *ts= CTX_data_tool_settings(C);
907         EditMesh *em= BKE_mesh_get_editmesh((Mesh *)obedit->data);
908         EditVert *eve,*nextve;
909         float nor[3]= {0.0f, 0.0f, 0.0f};
910         float si, n[3], q[4], cmat[3][3], imat[3][3], tmat[3][3];
911         float cent[3], bmat[3][3];
912         float phi;
913         short a, ok= 1;
914
915         RNA_float_get_array(op->ptr, "center", cent);
916
917         /* imat and center and size */
918         copy_m3_m4(bmat, obedit->obmat);
919         invert_m3_m3(imat,bmat);
920
921         cent[0]-= obedit->obmat[3][0];
922         cent[1]-= obedit->obmat[3][1];
923         cent[2]-= obedit->obmat[3][2];
924         mul_m3_v3(imat, cent);
925
926         phi= degr*M_PI/360.0;
927         phi/= steps;
928         if(ts->editbutflag & B_CLOCKWISE) phi= -phi;
929
930         RNA_float_get_array(op->ptr, "axis", n);
931         normalize_v3(n);
932
933         q[0]= (float)cos(phi);
934         si= (float)sin(phi);
935         q[1]= n[0]*si;
936         q[2]= n[1]*si;
937         q[3]= n[2]*si;
938         quat_to_mat3( cmat,q);
939
940         mul_m3_m3m3(tmat,cmat,bmat);
941         mul_m3_m3m3(bmat,imat,tmat);
942
943         if(dupli==0)
944                 if(ts->editbutflag & B_KEEPORIG)
945                         adduplicateflag(em, 1);
946
947         for(a=0; a<steps; a++) {
948                 if(dupli==0) ok= extrudeflag(obedit, em, SELECT, nor, 0);
949                 else adduplicateflag(em, SELECT);
950
951                 if(ok==0)
952                         break;
953
954                 rotateflag(em, SELECT, cent, bmat);
955                 if(dvec) {
956                         mul_m3_v3(bmat,dvec);
957                         translateflag(em, SELECT, dvec);
958                 }
959         }
960
961         if(ok==0) {
962                 /* no vertices or only loose ones selected, remove duplicates */
963                 eve= em->verts.first;
964                 while(eve) {
965                         nextve= eve->next;
966                         if(eve->f & SELECT) {
967                                 BLI_remlink(&em->verts,eve);
968                                 free_editvert(em, eve);
969                         }
970                         eve= nextve;
971                 }
972         }
973         else {
974                 recalc_editnormals(em);
975
976                 EM_fgon_flags(em);
977
978                 DAG_id_flush_update(obedit->data, OB_RECALC_DATA);
979         }
980
981         BKE_mesh_end_editmesh(obedit->data, em);
982         return ok;
983 }
984
985 static int spin_mesh_exec(bContext *C, wmOperator *op)
986 {
987         Object *obedit= CTX_data_edit_object(C);
988         int ok;
989
990         ok= spin_mesh(C, op, NULL, RNA_int_get(op->ptr,"steps"), RNA_float_get(op->ptr,"degrees"), RNA_boolean_get(op->ptr,"dupli"));
991         if(ok==0) {
992                 BKE_report(op->reports, RPT_ERROR, "No valid vertices are selected");
993                 return OPERATOR_CANCELLED;
994         }
995
996         DAG_id_flush_update(obedit->data, OB_RECALC_DATA);
997         WM_event_add_notifier(C, NC_GEOM|ND_DATA, obedit->data);
998
999         return OPERATOR_FINISHED;
1000 }
1001
1002 /* get center and axis, in global coords */
1003 static int spin_mesh_invoke(bContext *C, wmOperator *op, wmEvent *event)
1004 {
1005         Scene *scene = CTX_data_scene(C);
1006         View3D *v3d = CTX_wm_view3d(C);
1007         RegionView3D *rv3d= ED_view3d_context_rv3d(C);
1008
1009         RNA_float_set_array(op->ptr, "center", give_cursor(scene, v3d));
1010         RNA_float_set_array(op->ptr, "axis", rv3d->viewinv[2]);
1011
1012         return spin_mesh_exec(C, op);
1013 }
1014
1015 void MESH_OT_spin(wmOperatorType *ot)
1016 {
1017         /* identifiers */
1018         ot->name= "Spin";
1019         ot->description= "Extrude selected vertices in a circle around the cursor in indicated viewport";
1020         ot->idname= "MESH_OT_spin";
1021
1022         /* api callbacks */
1023         ot->invoke= spin_mesh_invoke;
1024         ot->exec= spin_mesh_exec;
1025         ot->poll= EM_view3d_poll;
1026
1027         /* flags */
1028         ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
1029
1030         /* props */
1031         RNA_def_int(ot->srna, "steps", 9, 0, INT_MAX, "Steps", "Steps", 0, 128);
1032         RNA_def_boolean(ot->srna, "dupli", 0, "Dupli", "Make Duplicates");
1033         RNA_def_float(ot->srna, "degrees", 90.0f, -FLT_MAX, FLT_MAX, "Degrees", "Degrees", -360.0f, 360.0f);
1034
1035         RNA_def_float_vector(ot->srna, "center", 3, NULL, -FLT_MAX, FLT_MAX, "Center", "Center in global view space", -FLT_MAX, FLT_MAX);
1036         RNA_def_float_vector(ot->srna, "axis", 3, NULL, -1.0f, 1.0f, "Axis", "Axis in global view space", -FLT_MAX, FLT_MAX);
1037
1038 }
1039
1040 static int screw_mesh_exec(bContext *C, wmOperator *op)
1041 {
1042         Object *obedit= CTX_data_edit_object(C);
1043         EditMesh *em= BKE_mesh_get_editmesh((Mesh *)obedit->data);
1044         EditVert *eve,*v1=0,*v2=0;
1045         EditEdge *eed;
1046         float dvec[3], nor[3];
1047         int steps, turns;
1048
1049         turns= RNA_int_get(op->ptr, "turns");
1050         steps= RNA_int_get(op->ptr, "steps");
1051
1052         /* clear flags */
1053         for(eve= em->verts.first; eve; eve= eve->next)
1054                 eve->f1= 0;
1055
1056         /* edges set flags in verts */
1057         for(eed= em->edges.first; eed; eed= eed->next) {
1058                 if(eed->v1->f & SELECT) {
1059                         if(eed->v2->f & SELECT) {
1060                                 /* watch: f1 is a byte */
1061                                 if(eed->v1->f1<2) eed->v1->f1++;
1062                                 if(eed->v2->f1<2) eed->v2->f1++;
1063                         }
1064                 }
1065         }
1066         /* find two vertices with eve->f1==1, more or less is wrong */
1067         for(eve= em->verts.first; eve; eve= eve->next) {
1068                 if(eve->f1==1) {
1069                         if(v1==NULL) v1= eve;
1070                         else if(v2==NULL) v2= eve;
1071                         else {
1072                                 v1= NULL;
1073                                 break;
1074                         }
1075                 }
1076         }
1077         if(v1==NULL || v2==NULL) {
1078                 BKE_report(op->reports, RPT_ERROR, "You have to select a string of connected vertices too");
1079                 BKE_mesh_end_editmesh(obedit->data, em);
1080                 return OPERATOR_CANCELLED;
1081         }
1082
1083         /* calculate dvec */
1084         dvec[0]= ( v1->co[0]- v2->co[0] )/steps;
1085         dvec[1]= ( v1->co[1]- v2->co[1] )/steps;
1086         dvec[2]= ( v1->co[2]- v2->co[2] )/steps;
1087
1088         VECCOPY(nor, obedit->obmat[2]);
1089
1090         if(nor[0]*dvec[0]+nor[1]*dvec[1]+nor[2]*dvec[2]>0.000) {
1091                 dvec[0]= -dvec[0];
1092                 dvec[1]= -dvec[1];
1093                 dvec[2]= -dvec[2];
1094         }
1095
1096         if(spin_mesh(C, op, dvec, turns*steps, 360.0f*turns, 0)) {
1097                 DAG_id_flush_update(obedit->data, OB_RECALC_DATA);
1098                 WM_event_add_notifier(C, NC_GEOM|ND_DATA, obedit->data);
1099
1100                 BKE_mesh_end_editmesh(obedit->data, em);
1101                 return OPERATOR_FINISHED;
1102         }
1103         else {
1104                 BKE_report(op->reports, RPT_ERROR, "No valid vertices are selected");
1105                 BKE_mesh_end_editmesh(obedit->data, em);
1106                 return OPERATOR_CANCELLED;
1107         }
1108 }
1109
1110 /* get center and axis, in global coords */
1111 static int screw_mesh_invoke(bContext *C, wmOperator *op, wmEvent *event)
1112 {
1113         Scene *scene = CTX_data_scene(C);
1114         View3D *v3d = CTX_wm_view3d(C);
1115         RegionView3D *rv3d= ED_view3d_context_rv3d(C);
1116
1117         RNA_float_set_array(op->ptr, "center", give_cursor(scene, v3d));
1118         RNA_float_set_array(op->ptr, "axis", rv3d->viewinv[1]);
1119
1120         return screw_mesh_exec(C, op);
1121 }
1122
1123 void MESH_OT_screw(wmOperatorType *ot)
1124 {
1125         /* identifiers */
1126         ot->name= "Screw";
1127         ot->description= "Extrude selected vertices in screw-shaped rotation around the cursor in indicated viewport";
1128         ot->idname= "MESH_OT_screw";
1129
1130         /* api callbacks */
1131         ot->invoke= screw_mesh_invoke;
1132         ot->exec= screw_mesh_exec;
1133         ot->poll= EM_view3d_poll;
1134
1135         /* flags */
1136         ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
1137
1138         /*props */
1139         RNA_def_int(ot->srna, "steps", 9, 0, INT_MAX, "Steps", "Steps", 0, 256);
1140         RNA_def_int(ot->srna, "turns", 1, 0, INT_MAX, "Turns", "Turns", 0, 256);
1141
1142         RNA_def_float_vector(ot->srna, "center", 3, NULL, -FLT_MAX, FLT_MAX, "Center", "Center in global view space", -FLT_MAX, FLT_MAX);
1143         RNA_def_float_vector(ot->srna, "axis", 3, NULL, -1.0f, 1.0f, "Axis", "Axis in global view space", -FLT_MAX, FLT_MAX);
1144 }
1145
1146 static void erase_edges(EditMesh *em, ListBase *l)
1147 {
1148         EditEdge *ed, *nexted;
1149
1150         ed = (EditEdge *) l->first;
1151         while(ed) {
1152                 nexted= ed->next;
1153                 if( (ed->v1->f & SELECT) || (ed->v2->f & SELECT) ) {
1154                         remedge(em, ed);
1155                         free_editedge(em, ed);
1156                 }
1157                 ed= nexted;
1158         }
1159 }
1160
1161 static void erase_faces(EditMesh *em, ListBase *l)
1162 {
1163         EditFace *f, *nextf;
1164
1165         f = (EditFace *) l->first;
1166
1167         while(f) {
1168                 nextf= f->next;
1169                 if( faceselectedOR(f, SELECT) ) {
1170                         BLI_remlink(l, f);
1171                         free_editface(em, f);
1172                 }
1173                 f = nextf;
1174         }
1175 }
1176
1177 static void erase_vertices(EditMesh *em, ListBase *l)
1178 {
1179         EditVert *v, *nextv;
1180
1181         v = (EditVert *) l->first;
1182         while(v) {
1183                 nextv= v->next;
1184                 if(v->f & 1) {
1185                         BLI_remlink(l, v);
1186                         free_editvert(em, v);
1187                 }
1188                 v = nextv;
1189         }
1190 }
1191
1192 void delete_mesh(Object *obedit, EditMesh *em, wmOperator *op, int event)
1193 {
1194         EditFace *efa, *nextvl;
1195         EditVert *eve,*nextve;
1196         EditEdge *eed,*nexted;
1197         int count;
1198         char *str="Erase";
1199
1200
1201         if(event<1) return;
1202
1203         if(event==10 ) {
1204                 str= "Erase Vertices";
1205                 erase_edges(em, &em->edges);
1206                 erase_faces(em, &em->faces);
1207                 erase_vertices(em, &em->verts);
1208         }
1209         else if(event==6) {
1210                 if(!EdgeLoopDelete(em, op))
1211                         return;
1212
1213                 str= "Erase Edge Loop";
1214         }
1215         else if(event==4) {
1216                 str= "Erase Edges & Faces";
1217                 efa= em->faces.first;
1218                 while(efa) {
1219                         nextvl= efa->next;
1220                         /* delete only faces with 1 or more edges selected */
1221                         count= 0;
1222                         if(efa->e1->f & SELECT) count++;
1223                         if(efa->e2->f & SELECT) count++;
1224                         if(efa->e3->f & SELECT) count++;
1225                         if(efa->e4 && (efa->e4->f & SELECT)) count++;
1226                         if(count) {
1227                                 BLI_remlink(&em->faces, efa);
1228                                 free_editface(em, efa);
1229                         }
1230                         efa= nextvl;
1231                 }
1232                 eed= em->edges.first;
1233                 while(eed) {
1234                         nexted= eed->next;
1235                         if(eed->f & SELECT) {
1236                                 remedge(em, eed);
1237                                 free_editedge(em, eed);
1238                         }
1239                         eed= nexted;
1240                 }
1241                 efa= em->faces.first;
1242                 while(efa) {
1243                         nextvl= efa->next;
1244                         event=0;
1245                         if( efa->v1->f & SELECT) event++;
1246                         if( efa->v2->f & SELECT) event++;
1247                         if( efa->v3->f & SELECT) event++;
1248                         if(efa->v4 && (efa->v4->f & SELECT)) event++;
1249
1250                         if(event>1) {
1251                                 BLI_remlink(&em->faces, efa);
1252                                 free_editface(em, efa);
1253                         }
1254                         efa= nextvl;
1255                 }
1256         }
1257         else if(event==1) {
1258                 str= "Erase Edges";
1259                 // faces first
1260                 efa= em->faces.first;
1261                 while(efa) {
1262                         nextvl= efa->next;
1263                         event=0;
1264                         if( efa->e1->f & SELECT) event++;
1265                         if( efa->e2->f & SELECT) event++;
1266                         if( efa->e3->f & SELECT) event++;
1267                         if(efa->e4 && (efa->e4->f & SELECT)) event++;
1268
1269                         if(event) {
1270                                 BLI_remlink(&em->faces, efa);
1271                                 free_editface(em, efa);
1272                         }
1273                         efa= nextvl;
1274                 }
1275                 eed= em->edges.first;
1276                 while(eed) {
1277                         nexted= eed->next;
1278                         if(eed->f & SELECT) {
1279                                 remedge(em, eed);
1280                                 free_editedge(em, eed);
1281                         }
1282                         eed= nexted;
1283                 }
1284                 /* to remove loose vertices: */
1285                 eed= em->edges.first;
1286                 while(eed) {
1287                         if( eed->v1->f & SELECT) eed->v1->f-=SELECT;
1288                         if( eed->v2->f & SELECT) eed->v2->f-=SELECT;
1289                         eed= eed->next;
1290                 }
1291                 eve= em->verts.first;
1292                 while(eve) {
1293                         nextve= eve->next;
1294                         if(eve->f & SELECT) {
1295                                 BLI_remlink(&em->verts,eve);
1296                                 free_editvert(em, eve);
1297                         }
1298                         eve= nextve;
1299                 }
1300
1301         }
1302         else if(event==2) {
1303                 str="Erase Faces";
1304                 delfaceflag(em, SELECT);
1305         }
1306         else if(event==3) {
1307                 str= "Erase All";
1308                 if(em->verts.first) free_vertlist(em, &em->verts);
1309                 if(em->edges.first) free_edgelist(em, &em->edges);
1310                 if(em->faces.first) free_facelist(em, &em->faces);
1311                 if(em->selected.first) BLI_freelistN(&(em->selected));
1312         }
1313         else if(event==5) {
1314                 str= "Erase Only Faces";
1315                 efa= em->faces.first;
1316                 while(efa) {
1317                         nextvl= efa->next;
1318                         if(efa->f & SELECT) {
1319                                 BLI_remlink(&em->faces, efa);
1320                                 free_editface(em, efa);
1321                         }
1322                         efa= nextvl;
1323                 }
1324         }
1325
1326         EM_fgon_flags(em);      // redo flags and indices for fgons
1327 }
1328
1329 /* Note, these values must match delete_mesh() event values */
1330 static EnumPropertyItem prop_mesh_delete_types[] = {
1331         {10,"VERT",             0, "Vertices", ""},
1332         {1, "EDGE",             0, "Edges", ""},
1333         {2, "FACE",             0, "Faces", ""},
1334         {3, "ALL",              0, "All", ""},
1335         {4, "EDGE_FACE",0, "Edges & Faces", ""},
1336         {5, "ONLY_FACE",0, "Only Faces", ""},
1337         {6, "EDGE_LOOP",0, "Edge Loop", ""},
1338         {0, NULL, 0, NULL, NULL}
1339 };
1340
1341 static int delete_mesh_exec(bContext *C, wmOperator *op)
1342 {
1343         Object *obedit= CTX_data_edit_object(C);
1344         EditMesh *em= BKE_mesh_get_editmesh((Mesh *)obedit->data);
1345         int type= RNA_enum_get(op->ptr, "type");
1346
1347         if(type==6)
1348                 return WM_operator_name_call(C, "MESH_OT_delete_edgeloop", WM_OP_EXEC_DEFAULT, NULL);
1349
1350         delete_mesh(obedit, em, op, type);
1351
1352         DAG_id_flush_update(obedit->data, OB_RECALC_DATA);
1353         WM_event_add_notifier(C, NC_GEOM|ND_DATA, obedit->data);
1354
1355         BKE_mesh_end_editmesh(obedit->data, em);
1356         return OPERATOR_FINISHED;
1357 }
1358
1359 void MESH_OT_delete(wmOperatorType *ot)
1360 {
1361         /* identifiers */
1362         ot->name= "Delete";
1363         ot->description= "Delete selected vertices, edges or faces";
1364         ot->idname= "MESH_OT_delete";
1365
1366         /* api callbacks */
1367         ot->invoke= WM_menu_invoke;
1368         ot->exec= delete_mesh_exec;
1369
1370         ot->poll= ED_operator_editmesh;
1371
1372         /* flags */
1373         ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
1374
1375         /*props */
1376         ot->prop= RNA_def_enum(ot->srna, "type", prop_mesh_delete_types, 10, "Type", "Method used for deleting mesh data");
1377 }
1378
1379
1380 /*GB*/
1381 /*-------------------------------------------------------------------------------*/
1382 /*--------------------------- Edge Based Subdivide ------------------------------*/
1383
1384 #define EDGENEW 2
1385 #define FACENEW 2
1386 #define EDGEINNER  4
1387 #define EDGEOLD  8
1388
1389 /*used by faceloop cut to select only edges valid for edge slide*/
1390 #define DOUBLEOPFILL 16
1391
1392 /* calculates offset for co, based on fractal, sphere or smooth settings  */
1393 static void alter_co(float *co, EditEdge *edge, float smooth, float fractal, int beauty, float perc)
1394 {
1395         float vec1[3], fac;
1396
1397         if(beauty & B_SMOOTH) {
1398                 /* we calculate an offset vector vec1[], to be added to *co */
1399                 float len, fac, nor[3], nor1[3], nor2[3];
1400
1401                 sub_v3_v3v3(nor, edge->v1->co, edge->v2->co);
1402                 len= 0.5f*normalize_v3(nor);
1403
1404                 VECCOPY(nor1, edge->v1->no);
1405                 VECCOPY(nor2, edge->v2->no);
1406
1407                 /* cosine angle */
1408                 fac= nor[0]*nor1[0] + nor[1]*nor1[1] + nor[2]*nor1[2] ;
1409
1410                 vec1[0]= fac*nor1[0];
1411                 vec1[1]= fac*nor1[1];
1412                 vec1[2]= fac*nor1[2];
1413
1414                 /* cosine angle */
1415                 fac= -nor[0]*nor2[0] - nor[1]*nor2[1] - nor[2]*nor2[2] ;
1416
1417                 vec1[0]+= fac*nor2[0];
1418                 vec1[1]+= fac*nor2[1];
1419                 vec1[2]+= fac*nor2[2];
1420
1421                 /* falloff for multi subdivide */
1422                 smooth *= sqrt(fabs(1.0f - 2.0f*fabs(0.5f-perc)));
1423
1424                 vec1[0]*= smooth*len;
1425                 vec1[1]*= smooth*len;
1426                 vec1[2]*= smooth*len;
1427
1428                 co[0] += vec1[0];
1429                 co[1] += vec1[1];
1430                 co[2] += vec1[2];
1431         }
1432         else if(beauty & B_SPHERE) { /* subdivide sphere */
1433                 normalize_v3(co);
1434                 co[0]*= smooth;
1435                 co[1]*= smooth;
1436                 co[2]*= smooth;
1437         }
1438
1439         if(beauty & B_FRACTAL) {
1440                 fac= fractal*len_v3v3(edge->v1->co, edge->v2->co);
1441                 vec1[0]= fac*(float)(0.5-BLI_drand());
1442                 vec1[1]= fac*(float)(0.5-BLI_drand());
1443                 vec1[2]= fac*(float)(0.5-BLI_drand());
1444                 add_v3_v3(co, vec1);
1445         }
1446 }
1447
1448 /* assumes in the edge is the correct interpolated vertices already */
1449 /* percent defines the interpolation, smooth, fractal and beauty are for special options */
1450 /* results in new vertex with correct coordinate, vertex normal and weight group info */
1451 static EditVert *subdivide_edge_addvert(EditMesh *em, EditEdge *edge, float smooth, float fractal, int beauty, float percent)
1452 {
1453         EditVert *ev;
1454         float co[3];
1455
1456         co[0] = (edge->v2->co[0]-edge->v1->co[0])*percent + edge->v1->co[0];
1457         co[1] = (edge->v2->co[1]-edge->v1->co[1])*percent + edge->v1->co[1];
1458         co[2] = (edge->v2->co[2]-edge->v1->co[2])*percent + edge->v1->co[2];
1459
1460         /* offset for smooth or sphere or fractal */
1461         alter_co(co, edge, smooth, fractal, beauty, percent);
1462
1463         /* clip if needed by mirror modifier */
1464         if (edge->v1->f2) {
1465                 if ( edge->v1->f2 & edge->v2->f2 & 1) {
1466                         co[0]= 0.0f;
1467                 }
1468                 if ( edge->v1->f2 & edge->v2->f2 & 2) {
1469                         co[1]= 0.0f;
1470                 }
1471                 if ( edge->v1->f2 & edge->v2->f2 & 4) {
1472                         co[2]= 0.0f;
1473                 }
1474         }
1475
1476         ev = addvertlist(em, co, NULL);
1477
1478         /* vert data (vgroups, ..) */
1479         EM_data_interp_from_verts(em, edge->v1, edge->v2, ev, percent);
1480
1481         /* normal */
1482         ev->no[0] = (edge->v2->no[0]-edge->v1->no[0])*percent + edge->v1->no[0];
1483         ev->no[1] = (edge->v2->no[1]-edge->v1->no[1])*percent + edge->v1->no[1];
1484         ev->no[2] = (edge->v2->no[2]-edge->v1->no[2])*percent + edge->v1->no[2];
1485         normalize_v3(ev->no);
1486
1487         return ev;
1488 }
1489
1490 static void flipvertarray(EditVert** arr, short size)
1491 {
1492         EditVert *hold;
1493         int i;
1494
1495         for(i=0; i<size/2; i++) {
1496                 hold = arr[i];
1497                 arr[i] = arr[size-i-1];
1498                 arr[size-i-1] = hold;
1499         }
1500 }
1501
1502 static void facecopy(EditMesh *em, EditFace *source, EditFace *target)
1503 {
1504         float *v1 = source->v1->co, *v2 = source->v2->co, *v3 = source->v3->co;
1505         float *v4 = source->v4? source->v4->co: NULL;
1506         float w[4][4];
1507
1508         CustomData_em_copy_data(&em->fdata, &em->fdata, source->data, &target->data);
1509
1510         target->mat_nr = source->mat_nr;
1511         target->flag   = source->flag;
1512         target->h          = source->h;
1513
1514         interp_weights_face_v3( w[0],v1, v2, v3, v4, target->v1->co);
1515         interp_weights_face_v3( w[1],v1, v2, v3, v4, target->v2->co);
1516         interp_weights_face_v3( w[2],v1, v2, v3, v4, target->v3->co);
1517         if (target->v4)
1518                 interp_weights_face_v3( w[3],v1, v2, v3, v4, target->v4->co);
1519
1520         CustomData_em_interp(&em->fdata, &source->data, NULL, (float*)w, 1, target->data);
1521 }
1522
1523 static void fill_quad_single(EditMesh *em, EditFace *efa, struct GHash *gh, int numcuts, int seltype)
1524 {
1525         EditEdge *cedge=NULL;
1526         EditVert *v[4], **verts;
1527         EditFace *hold;
1528         short start=0, end, left, right, vertsize,i;
1529
1530         v[0] = efa->v1;
1531         v[1] = efa->v2;
1532         v[2] = efa->v3;
1533         v[3] = efa->v4;
1534
1535         if(efa->e1->f & SELECT)   { cedge = efa->e1; start = 0;}
1536         else if(efa->e2->f & SELECT) { cedge = efa->e2; start = 1;}
1537         else if(efa->e3->f & SELECT) { cedge = efa->e3; start = 2;}
1538         else if(efa->e4->f & SELECT) { cedge = efa->e4; start = 3;}
1539
1540         // Point verts to the array of new verts for cedge
1541         verts = BLI_ghash_lookup(gh, cedge);
1542         //This is the index size of the verts array
1543         vertsize = numcuts+2;
1544
1545         // Is the original v1 the same as the first vert on the selected edge?
1546         // if not, the edge is running the opposite direction in this face so flip
1547         // the array to the correct direction
1548
1549         if(verts[0] != v[start]) {flipvertarray(verts,numcuts+2);}
1550         end     = (start+1)%4;
1551         left   = (start+2)%4;
1552         right  = (start+3)%4;
1553
1554         /*
1555         We should have something like this now
1556
1557                           end            start
1558                            3   2   1   0
1559                            |---*---*---|
1560                            |               |
1561                            |               |
1562                            |               |
1563                            -------------
1564                           left     right
1565
1566         where start,end,left, right are indexes of EditFace->v1, etc (stored in v)
1567         and 0,1,2... are the indexes of the new verts stored in verts
1568
1569         We will fill this case like this or this depending on even or odd cuts
1570
1571                            |---*---*---|                  |---*---|
1572                            |  /  \  |             |  / \  |
1573                            | /     \ |            | /   \ |
1574                            |/            \|               |/     \|
1575                            -------------                  ---------
1576         */
1577
1578         // Make center face
1579         if(vertsize % 2 == 0) {
1580                 hold = addfacelist(em, verts[(vertsize-1)/2],verts[((vertsize-1)/2)+1],v[left],v[right], NULL,NULL);
1581                 hold->e2->f2 |= EDGEINNER;
1582                 hold->e4->f2 |= EDGEINNER;
1583         }else{
1584                 hold = addfacelist(em, verts[(vertsize-1)/2],v[left],v[right],NULL, NULL,NULL);
1585                 hold->e1->f2 |= EDGEINNER;
1586                 hold->e3->f2 |= EDGEINNER;
1587         }
1588         facecopy(em, efa,hold);
1589
1590         // Make side faces
1591         for(i=0;i<(vertsize-1)/2;i++) {
1592                 hold = addfacelist(em, verts[i],verts[i+1],v[right],NULL,NULL,NULL);
1593                 facecopy(em, efa,hold);
1594                 if(i+1 != (vertsize-1)/2) {
1595                         if(seltype == SUBDIV_SELECT_INNER) {
1596                                 hold->e2->f2 |= EDGEINNER;
1597                         }
1598                 }
1599                 hold = addfacelist(em, verts[vertsize-2-i],verts[vertsize-1-i],v[left],NULL,NULL,NULL);
1600                 facecopy(em, efa,hold);
1601                 if(i+1 != (vertsize-1)/2) {
1602                         if(seltype == SUBDIV_SELECT_INNER) {
1603                                  hold->e3->f2 |= EDGEINNER;
1604                         }
1605                 }
1606         }
1607 }
1608
1609 static void fill_tri_single(EditMesh *em, EditFace *efa, struct GHash *gh, int numcuts, int seltype)
1610 {
1611         EditEdge *cedge=NULL;
1612         EditVert *v[3], **verts;
1613         EditFace *hold;
1614         short start=0, end, op, vertsize,i;
1615
1616         v[0] = efa->v1;
1617         v[1] = efa->v2;
1618         v[2] = efa->v3;
1619
1620         if(efa->e1->f & SELECT)   { cedge = efa->e1; start = 0;}
1621         else if(efa->e2->f & SELECT) { cedge = efa->e2; start = 1;}
1622         else if(efa->e3->f & SELECT) { cedge = efa->e3; start = 2;}
1623
1624         // Point verts to the array of new verts for cedge
1625         verts = BLI_ghash_lookup(gh, cedge);
1626         //This is the index size of the verts array
1627         vertsize = numcuts+2;
1628
1629         // Is the original v1 the same as the first vert on the selected edge?
1630         // if not, the edge is running the opposite direction in this face so flip
1631         // the array to the correct direction
1632
1633         if(verts[0] != v[start]) {flipvertarray(verts,numcuts+2);}
1634            end  = (start+1)%3;
1635            op    = (start+2)%3;
1636
1637         /*
1638         We should have something like this now
1639
1640                           end            start
1641                            3   2   1   0
1642                            |---*---*---|
1643                            \               |
1644                                  \               |
1645                                    \       |
1646                                          \       |
1647                                            \   |
1648                                                  \ |
1649                                                    |op
1650
1651         where start,end,op are indexes of EditFace->v1, etc (stored in v)
1652         and 0,1,2... are the indexes of the new verts stored in verts
1653
1654         We will fill this case like this or this depending on even or odd cuts
1655
1656                            3   2   1   0
1657                            |---*---*---|
1658                            \    \  \   |
1659                                  \      \ \  |
1660                                    \   \ \ |
1661                                          \  \ \|
1662                                            \ \\|
1663                                                  \ |
1664                                                    |op
1665         */
1666
1667         // Make side faces
1668         for(i=0;i<(vertsize-1);i++) {
1669                 hold = addfacelist(em, verts[i],verts[i+1],v[op],NULL,NULL,NULL);
1670                 if(i+1 != vertsize-1) {
1671                         if(seltype == SUBDIV_SELECT_INNER) {
1672                                  hold->e2->f2 |= EDGEINNER;
1673                         }
1674                 }
1675                 facecopy(em, efa,hold);
1676         }
1677 }
1678
1679 static void fill_quad_double_op(EditMesh *em, EditFace *efa, struct GHash *gh, int numcuts)
1680 {
1681         EditEdge *cedge[2]={NULL, NULL};
1682         EditVert *v[4], **verts[2];
1683         EditFace *hold;
1684         short start=0, end, left, right, vertsize,i;
1685
1686         v[0] = efa->v1;
1687         v[1] = efa->v2;
1688         v[2] = efa->v3;
1689         v[3] = efa->v4;
1690
1691         if(efa->e1->f & SELECT)   { cedge[0] = efa->e1;  cedge[1] = efa->e3; start = 0;}
1692         else if(efa->e2->f & SELECT)      { cedge[0] = efa->e2;  cedge[1] = efa->e4; start = 1;}
1693
1694         // Point verts[0] and [1] to the array of new verts for cedge[0] and cedge[1]
1695         verts[0] = BLI_ghash_lookup(gh, cedge[0]);
1696         verts[1] = BLI_ghash_lookup(gh, cedge[1]);
1697         //This is the index size of the verts array
1698         vertsize = numcuts+2;
1699
1700         // Is the original v1 the same as the first vert on the selected edge?
1701         // if not, the edge is running the opposite direction in this face so flip
1702         // the array to the correct direction
1703
1704         if(verts[0][0] != v[start]) {flipvertarray(verts[0],numcuts+2);}
1705         end     = (start+1)%4;
1706         left   = (start+2)%4;
1707         right  = (start+3)%4;
1708         if(verts[1][0] != v[left]) {flipvertarray(verts[1],numcuts+2);}
1709         /*
1710         We should have something like this now
1711
1712                           end            start
1713                            3   2   1   0
1714                            |---*---*---|
1715                            |               |
1716                            |               |
1717                            |               |
1718                            |---*---*---|
1719                            0   1   2   3
1720                           left     right
1721
1722         We will fill this case like this or this depending on even or odd cuts
1723
1724                            |---*---*---|
1725                            |   |   |   |
1726                            |   |   |   |
1727                            |   |   |   |
1728                            |---*---*---|
1729         */
1730
1731         // Make side faces
1732         for(i=0;i<vertsize-1;i++) {
1733                 hold = addfacelist(em, verts[0][i],verts[0][i+1],verts[1][vertsize-2-i],verts[1][vertsize-1-i],NULL,NULL);
1734                 if(i < vertsize-2) {
1735                         hold->e2->f2 |= EDGEINNER;
1736                         hold->e2->f2 |= DOUBLEOPFILL;
1737                 }
1738                 facecopy(em, efa,hold);
1739         }
1740 }
1741
1742 static void fill_quad_double_adj_path(EditMesh *em, EditFace *efa, struct GHash *gh, int numcuts)
1743 {
1744         EditEdge *cedge[2]={NULL, NULL};
1745         EditVert *v[4], **verts[2];
1746         EditFace *hold;
1747         short start=0, start2=0, vertsize,i;
1748         int ctrl= 0; // XXX
1749
1750         v[0] = efa->v1;
1751         v[1] = efa->v2;
1752         v[2] = efa->v3;
1753         v[3] = efa->v4;
1754
1755         if(efa->e1->f & SELECT && efa->e2->f & SELECT) {cedge[0] = efa->e1;  cedge[1] = efa->e2; start = 0; start2 = 1;}
1756         if(efa->e2->f & SELECT && efa->e3->f & SELECT) {cedge[0] = efa->e2;  cedge[1] = efa->e3; start = 1; start2 = 2;}
1757         if(efa->e3->f & SELECT && efa->e4->f & SELECT) {cedge[0] = efa->e3;  cedge[1] = efa->e4; start = 2; start2 = 3;}
1758         if(efa->e4->f & SELECT && efa->e1->f & SELECT) {cedge[0] = efa->e4;  cedge[1] = efa->e1; start = 3; start2 = 0;}
1759
1760         // Point verts[0] and [1] to the array of new verts for cedge[0] and cedge[1]
1761         verts[0] = BLI_ghash_lookup(gh, cedge[0]);
1762         verts[1] = BLI_ghash_lookup(gh, cedge[1]);
1763         //This is the index size of the verts array
1764         vertsize = numcuts+2;
1765
1766         // Is the original v1 the same as the first vert on the selected edge?
1767         // if not, the edge is running the opposite direction in this face so flip
1768         // the array to the correct direction
1769
1770         if(verts[0][0] != v[start]) {flipvertarray(verts[0],numcuts+2);}
1771         if(verts[1][0] != v[start2]) {flipvertarray(verts[1],numcuts+2);}
1772         /*
1773         We should have something like this now
1774
1775                            end           start
1776                                 3   2   1   0
1777                 start2 0|---*---*---|
1778                                 |                  |
1779                            1*              |
1780                                 |                  |
1781                            2*              |
1782                                 |                  |
1783                  end2  3|-----------|
1784
1785         We will fill this case like this or this depending on even or odd cuts
1786                            |---*---*---|
1787                            | /   /   / |
1788                            *   /   /   |
1789                            | /   /       |
1790                            *   /           |
1791                            | /           |
1792                            |-----------|
1793         */
1794
1795         // Make outside tris
1796         hold = addfacelist(em, verts[0][vertsize-2],verts[0][vertsize-1],verts[1][1],NULL,NULL,NULL);
1797         /* when ctrl is depressed, only want verts on the cutline selected */
1798         if (ctrl)
1799                 hold->e3->f2 |= EDGEINNER;
1800         facecopy(em, efa,hold);
1801         hold = addfacelist(em, verts[0][0],verts[1][vertsize-1],v[(start2+2)%4],NULL,NULL,NULL);
1802         /* when ctrl is depressed, only want verts on the cutline selected */
1803         if (ctrl)
1804                 hold->e1->f2 |= EDGEINNER;
1805         facecopy(em, efa,hold);
1806         //if(scene->toolsettings->editbutflag & B_AUTOFGON) {
1807         //      hold->e1->h |= EM_FGON;
1808         //}
1809         // Make side faces
1810
1811         for(i=0;i<numcuts;i++) {
1812                 hold = addfacelist(em, verts[0][i],verts[0][i+1],verts[1][vertsize-1-(i+1)],verts[1][vertsize-1-i],NULL,NULL);
1813                 hold->e2->f2 |= EDGEINNER;
1814                 facecopy(em, efa,hold);
1815         }
1816         //EM_fgon_flags(em);
1817
1818 }
1819
1820 static void fill_quad_double_adj_fan(EditMesh *em, EditFace *efa, struct GHash *gh, int numcuts)
1821 {
1822         EditEdge *cedge[2]={NULL, NULL};
1823         EditVert *v[4], *op=NULL, **verts[2];
1824         EditFace *hold;
1825         short start=0, start2=0, vertsize,i;
1826
1827         v[0] = efa->v1;
1828         v[1] = efa->v2;
1829         v[2] = efa->v3;
1830         v[3] = efa->v4;
1831
1832         if(efa->e1->f & SELECT && efa->e2->f & SELECT) {cedge[0] = efa->e1;  cedge[1] = efa->e2; start = 0; start2 = 1; op = efa->v4;}
1833         if(efa->e2->f & SELECT && efa->e3->f & SELECT) {cedge[0] = efa->e2;  cedge[1] = efa->e3; start = 1; start2 = 2; op = efa->v1;}
1834         if(efa->e3->f & SELECT && efa->e4->f & SELECT) {cedge[0] = efa->e3;  cedge[1] = efa->e4; start = 2; start2 = 3; op = efa->v2;}
1835         if(efa->e4->f & SELECT && efa->e1->f & SELECT) {cedge[0] = efa->e4;  cedge[1] = efa->e1; start = 3; start2 = 0; op = efa->v3;}
1836
1837
1838         // Point verts[0] and [1] to the array of new verts for cedge[0] and cedge[1]
1839         verts[0] = BLI_ghash_lookup(gh, cedge[0]);
1840         verts[1] = BLI_ghash_lookup(gh, cedge[1]);
1841         //This is the index size of the verts array
1842         vertsize = numcuts+2;
1843
1844         // Is the original v1 the same as the first vert on the selected edge?
1845         // if not, the edge is running the opposite direction in this face so flip
1846         // the array to the correct direction
1847
1848         if(verts[0][0] != v[start]) {flipvertarray(verts[0],numcuts+2);}
1849         if(verts[1][0] != v[start2]) {flipvertarray(verts[1],numcuts+2);}
1850         /*
1851         We should have something like this now
1852
1853                            end           start
1854                                 3   2   1   0
1855                 start2 0|---*---*---|
1856                                 |                  |
1857                            1*              |
1858                                 |                  |
1859                            2*              |
1860                                 |                  |
1861                  end2  3|-----------|op
1862
1863         We will fill this case like this or this (warning horrible ascii art follows)
1864                            |---*---*---|
1865                            | \  \   \  |
1866                            *---\  \  \ |
1867                            |   \ \ \  \|
1868                            *---- \ \  \ |
1869                            |    ---  \\\|
1870                            |-----------|
1871         */
1872
1873         for(i=0;i<=numcuts;i++) {
1874                 hold = addfacelist(em, op,verts[1][numcuts-i],verts[1][numcuts-i+1],NULL,NULL,NULL);
1875                 hold->e1->f2 |= EDGEINNER;
1876                 facecopy(em, efa,hold);
1877
1878                 hold = addfacelist(em, op,verts[0][i],verts[0][i+1],NULL,NULL,NULL);
1879                 hold->e3->f2 |= EDGEINNER;
1880                 facecopy(em, efa,hold);
1881         }
1882 }
1883
1884 static void fill_quad_double_adj_inner(EditMesh *em, EditFace *efa, struct GHash *gh, int numcuts)
1885 {
1886         EditEdge *cedge[2]={NULL, NULL};
1887         EditVert *v[4], *op=NULL, **verts[2],**inner;
1888         EditFace *hold;
1889         short start=0, start2=0, vertsize,i;
1890         float co[3];
1891
1892         v[0] = efa->v1;
1893         v[1] = efa->v2;
1894         v[2] = efa->v3;
1895         v[3] = efa->v4;
1896
1897         if(efa->e1->f & SELECT && efa->e2->f & SELECT) {cedge[0] = efa->e1;  cedge[1] = efa->e2; start = 0; start2 = 1; op = efa->v4;}
1898         if(efa->e2->f & SELECT && efa->e3->f & SELECT) {cedge[0] = efa->e2;  cedge[1] = efa->e3; start = 1; start2 = 2; op = efa->v1;}
1899         if(efa->e3->f & SELECT && efa->e4->f & SELECT) {cedge[0] = efa->e3;  cedge[1] = efa->e4; start = 2; start2 = 3; op = efa->v2;}
1900         if(efa->e4->f & SELECT && efa->e1->f & SELECT) {cedge[0] = efa->e4;  cedge[1] = efa->e1; start = 3; start2 = 0; op = efa->v3;}
1901
1902
1903         // Point verts[0] and [1] to the array of new verts for cedge[0] and cedge[1]
1904         verts[0] = BLI_ghash_lookup(gh, cedge[0]);
1905         verts[1] = BLI_ghash_lookup(gh, cedge[1]);
1906         //This is the index size of the verts array
1907         vertsize = numcuts+2;
1908
1909         // Is the original v1 the same as the first vert on the selected edge?
1910         // if not, the edge is running the opposite direction in this face so flip
1911         // the array to the correct direction
1912
1913         if(verts[0][0] != v[start]) {flipvertarray(verts[0],numcuts+2);}
1914         if(verts[1][0] != v[start2]) {flipvertarray(verts[1],numcuts+2);}
1915         /*
1916         We should have something like this now
1917
1918                            end           start
1919                                 3   2   1   0
1920                 start2 0|---*---*---|
1921                                 |                  |
1922                            1*              |
1923                                 |                  |
1924                            2*              |
1925                                 |                  |
1926                  end2  3|-----------|op
1927
1928         We will fill this case like this or this (warning horrible ascii art follows)
1929                            |---*-----*---|
1930                            | *     /     |
1931                            *   \ /       |
1932                            |    *        |
1933                            | /    \          |
1934                            *        \    |
1935                            |           \ |
1936                            |-------------|
1937         */
1938
1939         // Add Inner Vert(s)
1940         inner = MEM_mallocN(sizeof(EditVert*)*numcuts,"New inner verts");
1941
1942         for(i=0;i<numcuts;i++) {
1943                 co[0] = (verts[0][numcuts-i]->co[0] + verts[1][i+1]->co[0] ) / 2 ;
1944                 co[1] = (verts[0][numcuts-i]->co[1] + verts[1][i+1]->co[1] ) / 2 ;
1945                 co[2] = (verts[0][numcuts-i]->co[2] + verts[1][i+1]->co[2] ) / 2 ;
1946                 inner[i] = addvertlist(em, co, NULL);
1947                 inner[i]->f2 |= EDGEINNER;
1948
1949                 EM_data_interp_from_verts(em, verts[0][numcuts-i], verts[1][i+1], inner[i], 0.5f);
1950         }
1951
1952         // Add Corner Quad
1953         hold = addfacelist(em, verts[0][numcuts+1],verts[1][1],inner[0],verts[0][numcuts],NULL,NULL);
1954         hold->e2->f2 |= EDGEINNER;
1955         hold->e3->f2 |= EDGEINNER;
1956         facecopy(em, efa,hold);
1957         // Add Bottom Quads
1958         hold = addfacelist(em, verts[0][0],verts[0][1],inner[numcuts-1],op,NULL,NULL);
1959         hold->e2->f2 |= EDGEINNER;
1960         facecopy(em, efa,hold);
1961
1962         hold = addfacelist(em, op,inner[numcuts-1],verts[1][numcuts],verts[1][numcuts+1],NULL,NULL);
1963         hold->e2->f2 |= EDGEINNER;
1964         facecopy(em, efa,hold);
1965
1966         //if(scene->toolsettings->editbutflag & B_AUTOFGON) {
1967         //      hold->e1->h |= EM_FGON;
1968         //}
1969         // Add Fill Quads (if # cuts > 1)
1970
1971         for(i=0;i<numcuts-1;i++) {
1972                 hold = addfacelist(em, inner[i],verts[1][i+1],verts[1][i+2],inner[i+1],NULL,NULL);
1973                 hold->e1->f2 |= EDGEINNER;
1974                 hold->e3->f2 |= EDGEINNER;
1975                 facecopy(em, efa,hold);
1976
1977                 hold = addfacelist(em, inner[i],inner[i+1],verts[0][numcuts-1-i],verts[0][numcuts-i],NULL,NULL);
1978                 hold->e2->f2 |= EDGEINNER;
1979                 hold->e4->f2 |= EDGEINNER;
1980                 facecopy(em, efa,hold);
1981
1982                 //if(scene->toolsettings->editbutflag & B_AUTOFGON) {
1983                 //      hold->e1->h |= EM_FGON;
1984                 //}
1985         }
1986
1987         //EM_fgon_flags(em);
1988
1989         MEM_freeN(inner);
1990 }
1991
1992 static void fill_tri_double(EditMesh *em, EditFace *efa, struct GHash *gh, int numcuts)
1993 {
1994         EditEdge *cedge[2]={NULL, NULL};
1995         EditVert *v[3], **verts[2];
1996         EditFace *hold;
1997         short start=0, start2=0, vertsize,i;
1998
1999         v[0] = efa->v1;
2000         v[1] = efa->v2;
2001         v[2] = efa->v3;
2002
2003         if(efa->e1->f & SELECT && efa->e2->f & SELECT) {cedge[0] = efa->e1;  cedge[1] = efa->e2; start = 0; start2 = 1;}
2004         if(efa->e2->f & SELECT && efa->e3->f & SELECT) {cedge[0] = efa->e2;  cedge[1] = efa->e3; start = 1; start2 = 2;}
2005         if(efa->e3->f & SELECT && efa->e1->f & SELECT) {cedge[0] = efa->e3;  cedge[1] = efa->e1; start = 2; start2 = 0;}
2006
2007         // Point verts[0] and [1] to the array of new verts for cedge[0] and cedge[1]
2008         verts[0] = BLI_ghash_lookup(gh, cedge[0]);
2009         verts[1] = BLI_ghash_lookup(gh, cedge[1]);
2010         //This is the index size of the verts array
2011         vertsize = numcuts+2;
2012
2013         // Is the original v1 the same as the first vert on the selected edge?
2014         // if not, the edge is running the opposite direction in this face so flip
2015         // the array to the correct direction
2016
2017         if(verts[0][0] != v[start]) {flipvertarray(verts[0],numcuts+2);}
2018         if(verts[1][0] != v[start2]) {flipvertarray(verts[1],numcuts+2);}
2019         /*
2020         We should have something like this now
2021
2022                            end           start
2023                                 3   2   1   0
2024                 start2 0|---*---*---|
2025                                 |                /
2026                            1*      /
2027                                 |        /
2028                            2*   /
2029                                 | /
2030                  end2  3|
2031
2032         We will fill this case like this or this depending on even or odd cuts
2033                            |---*---*---|
2034                            | /   /   /
2035                            *   /   /
2036                            | /   /
2037                            *   /
2038                            | /
2039                            |
2040         */
2041
2042         // Make outside tri
2043         hold = addfacelist(em, verts[0][vertsize-2],verts[0][vertsize-1],verts[1][1],NULL,NULL,NULL);
2044         hold->e3->f2 |= EDGEINNER;
2045         facecopy(em, efa,hold);
2046         // Make side faces
2047
2048         for(i=0;i<numcuts;i++) {
2049                 hold = addfacelist(em, verts[0][i],verts[0][i+1],verts[1][vertsize-1-(i+1)],verts[1][vertsize-1-i],NULL,NULL);
2050                 hold->e2->f2 |= EDGEINNER;
2051                 facecopy(em, efa,hold);
2052         }
2053 }
2054
2055 static void fill_quad_triple(EditMesh *em, EditFace *efa, struct GHash *gh, int numcuts)
2056 {
2057         EditEdge *cedge[3]={0};
2058         EditVert *v[4], **verts[3];
2059         EditFace *hold;
2060         short start=0, start2=0, start3=0, vertsize, i, repeats;
2061
2062         v[0] = efa->v1;
2063         v[1] = efa->v2;
2064         v[2] = efa->v3;
2065         v[3] = efa->v4;
2066
2067         if(!(efa->e1->f & SELECT)) {
2068                 cedge[0] = efa->e2;
2069                 cedge[1] = efa->e3;
2070                 cedge[2] = efa->e4;
2071                 start = 1;start2 = 2;start3 = 3;
2072         }
2073         if(!(efa->e2->f & SELECT)) {
2074                 cedge[0] = efa->e3;
2075                 cedge[1] = efa->e4;
2076                 cedge[2] = efa->e1;
2077                 start = 2;start2 = 3;start3 = 0;
2078         }
2079         if(!(efa->e3->f & SELECT)) {
2080                 cedge[0] = efa->e4;
2081                 cedge[1] = efa->e1;
2082                 cedge[2] = efa->e2;
2083                 start = 3;start2 = 0;start3 = 1;
2084         }
2085         if(!(efa->e4->f & SELECT)) {
2086                 cedge[0] = efa->e1;
2087                 cedge[1] = efa->e2;
2088                 cedge[2] = efa->e3;
2089                 start = 0;start2 = 1;start3 = 2;
2090         }
2091         // Point verts[0] and [1] to the array of new verts for cedge[0] and cedge[1]
2092         verts[0] = BLI_ghash_lookup(gh, cedge[0]);
2093         verts[1] = BLI_ghash_lookup(gh, cedge[1]);
2094         verts[2] = BLI_ghash_lookup(gh, cedge[2]);
2095         //This is the index size of the verts array
2096         vertsize = numcuts+2;
2097
2098         // Is the original v1 the same as the first vert on the selected edge?
2099         // if not, the edge is running the opposite direction in this face so flip
2100         // the array to the correct direction
2101
2102         if(verts[0][0] != v[start]) {flipvertarray(verts[0],numcuts+2);}
2103         if(verts[1][0] != v[start2]) {flipvertarray(verts[1],numcuts+2);}
2104         if(verts[2][0] != v[start3]) {flipvertarray(verts[2],numcuts+2);}
2105         /*
2106          We should have something like this now
2107
2108          start2
2109          3   2   1   0
2110          start3 0|---*---*---|3
2111          |                 |
2112          1*                *2
2113          |                 |
2114          2*                *1
2115          |                 |
2116          3|-----------|0 start
2117
2118          We will fill this case like this or this depending on even or odd cuts
2119          there are a couple of differences. For odd cuts, there is a tri in the
2120          middle as well as 1 quad at the bottom (not including the extra quads
2121          for odd cuts > 1
2122
2123          For even cuts, there is a quad in the middle and 2 quads on the bottom
2124
2125          they are numbered here for clarity
2126
2127          1 outer tris and bottom quads
2128          2 inner tri or quad
2129          3 repeating quads
2130
2131          |---*---*---*---|
2132          |1/   /  \   \ 1|
2133          |/ 3 / \  3 \|
2134          *  /   2   \   *
2135          | /              \  |
2136          |/                     \ |
2137          *---------------*
2138          |        3             |
2139          |                         |
2140          *---------------*
2141          |                         |
2142          |        1             |
2143          |                         |
2144          |---------------|
2145
2146          |---*---*---*---*---|
2147          | 1/   /        \   \ 1|
2148          | /   /           \   \ |
2149          |/ 3 /          \ 3 \|
2150          *   /             \   *
2151          |  /                    \  |
2152          | /       2       \ |
2153          |/                              \|
2154          *-------------------*
2155          |                                 |
2156          |               3               |
2157          |                                 |
2158          *-------------------*
2159          |                                 |
2160          |               1               |
2161          |                                 |
2162          *-------------------*
2163          |                                 |
2164          |              1                 |
2165          |                                 |
2166          |-------------------|
2167
2168          */
2169
2170         // Make outside tris
2171         hold = addfacelist(em, verts[0][vertsize-2],verts[0][vertsize-1],verts[1][1],NULL,NULL,NULL);
2172         hold->e3->f2 |= EDGEINNER;
2173         facecopy(em, efa,hold);
2174         hold = addfacelist(em, verts[1][vertsize-2],verts[1][vertsize-1],verts[2][1],NULL,NULL,NULL);
2175         hold->e3->f2 |= EDGEINNER;
2176         facecopy(em, efa,hold);
2177         // Make bottom quad
2178         hold = addfacelist(em, verts[0][0],verts[0][1],verts[2][vertsize-2],verts[2][vertsize-1],NULL,NULL);
2179         hold->e2->f2 |= EDGEINNER;
2180         facecopy(em, efa,hold);
2181         //If it is even cuts, add the 2nd lower quad
2182         if(numcuts % 2 == 0) {
2183                 hold = addfacelist(em, verts[0][1],verts[0][2],verts[2][vertsize-3],verts[2][vertsize-2],NULL,NULL);
2184                 hold->e2->f2 |= EDGEINNER;
2185                 facecopy(em, efa,hold);
2186                 // Also Make inner quad
2187                 hold = addfacelist(em, verts[1][numcuts/2],verts[1][(numcuts/2)+1],verts[2][numcuts/2],verts[0][(numcuts/2)+1],NULL,NULL);
2188                 hold->e3->f2 |= EDGEINNER;
2189                 //if(scene->toolsettings->editbutflag & B_AUTOFGON) {
2190                 //      hold->e3->h |= EM_FGON;
2191                 //}
2192                 facecopy(em, efa,hold);
2193                 repeats = (numcuts / 2) -1;
2194         } else {
2195                 // Make inner tri
2196                 hold = addfacelist(em, verts[1][(numcuts/2)+1],verts[2][(numcuts/2)+1],verts[0][(numcuts/2)+1],NULL,NULL,NULL);
2197                 hold->e2->f2 |= EDGEINNER;
2198                 //if(scene->toolsettings->editbutflag & B_AUTOFGON) {
2199                 //      hold->e2->h |= EM_FGON;
2200                 //}
2201                 facecopy(em, efa,hold);
2202                 repeats = ((numcuts+1) / 2)-1;
2203         }
2204
2205         // cuts for 1 and 2 do not have the repeating quads
2206         if(numcuts < 3) {repeats = 0;}
2207         for(i=0;i<repeats;i++) {
2208                 //Make side repeating Quads
2209                 hold = addfacelist(em, verts[1][i+1],verts[1][i+2],verts[0][vertsize-i-3],verts[0][vertsize-i-2],NULL,NULL);
2210                 hold->e2->f2 |= EDGEINNER;
2211                 facecopy(em, efa,hold);
2212                 hold = addfacelist(em, verts[1][vertsize-i-3],verts[1][vertsize-i-2],verts[2][i+1],verts[2][i+2],NULL,NULL);
2213                 hold->e4->f2 |= EDGEINNER;
2214                 facecopy(em, efa,hold);
2215         }
2216         // Do repeating bottom quads
2217         for(i=0;i<repeats;i++) {
2218                 if(numcuts % 2 == 1) {
2219                         hold = addfacelist(em, verts[0][1+i],verts[0][2+i],verts[2][vertsize-3-i],verts[2][vertsize-2-i],NULL,NULL);
2220                 } else {
2221                         hold = addfacelist(em, verts[0][2+i],verts[0][3+i],verts[2][vertsize-4-i],verts[2][vertsize-3-i],NULL,NULL);
2222                 }
2223                 hold->e2->f2 |= EDGEINNER;
2224                 facecopy(em, efa,hold);
2225         }
2226         //EM_fgon_flags(em);
2227 }
2228
2229 static void fill_quad_quadruple(EditMesh *em, EditFace *efa, struct GHash *gh, int numcuts, float smooth, float fractal, int beauty)
2230 {
2231         EditVert **verts[4], ***innerverts;
2232         EditFace *hold;
2233         EditEdge temp;
2234         short vertsize, i, j;
2235
2236         // Point verts[0] and [1] to the array of new verts for cedge[0] and cedge[1]
2237         verts[0] = BLI_ghash_lookup(gh, efa->e1);
2238         verts[1] = BLI_ghash_lookup(gh, efa->e2);
2239         verts[2] = BLI_ghash_lookup(gh, efa->e3);
2240         verts[3] = BLI_ghash_lookup(gh, efa->e4);
2241
2242         //This is the index size of the verts array
2243         vertsize = numcuts+2;
2244
2245         // Is the original v1 the same as the first vert on the selected edge?
2246         // if not, the edge is running the opposite direction in this face so flip
2247         // the array to the correct direction
2248
2249         if(verts[0][0] != efa->v1) {flipvertarray(verts[0],numcuts+2);}
2250         if(verts[1][0] != efa->v2) {flipvertarray(verts[1],numcuts+2);}
2251         if(verts[2][0] == efa->v3) {flipvertarray(verts[2],numcuts+2);}
2252         if(verts[3][0] == efa->v4) {flipvertarray(verts[3],numcuts+2);}
2253         /*
2254         We should have something like this now
2255                                           1
2256
2257                                 3   2   1   0
2258                            0|---*---*---|0
2259                                 |           |
2260                            1*           *1
2261                          2  |           |   4
2262                            2*           *2
2263                                 |           |
2264                            3|---*---*---|3
2265                                 3   2   1   0
2266
2267                                           3
2268         // we will fill a 2 dim array of editvert*s to make filling easier
2269         //  the innervert order is shown
2270
2271                                 0   0---1---2---3
2272                                         |   |   |   |
2273                                 1   0---1---2---3
2274                                         |   |   |   |
2275                                 2   0---1---2---3
2276                                         |   |   |   |
2277                                 3   0---1---2---3
2278
2279          */
2280         innerverts = MEM_mallocN(sizeof(EditVert*)*(numcuts+2),"quad-quad subdiv inner verts outer array");
2281         for(i=0;i<numcuts+2;i++) {
2282                 innerverts[i] = MEM_mallocN(sizeof(EditVert*)*(numcuts+2),"quad-quad subdiv inner verts inner array");
2283         }
2284
2285         // first row is e1 last row is e3
2286         for(i=0;i<numcuts+2;i++) {
2287                 innerverts[0][i]                  = verts[0][(numcuts+1)-i];
2288                 innerverts[numcuts+1][i]  = verts[2][(numcuts+1)-i];
2289         }
2290
2291         for(i=1;i<=numcuts;i++) {
2292                 /* we create a fake edge for the next loop */
2293                 temp.v2 = innerverts[i][0]                      = verts[1][i];
2294                 temp.v1 = innerverts[i][numcuts+1]  = verts[3][i];
2295
2296                 for(j=1;j<=numcuts;j++) {
2297                         float percent= (float)j/(float)(numcuts+1);
2298
2299                         innerverts[i][(numcuts+1)-j]= subdivide_edge_addvert(em, &temp, smooth, fractal, beauty, percent);
2300                 }
2301         }
2302         // Fill with faces
2303         for(i=0;i<numcuts+1;i++) {
2304                 for(j=0;j<numcuts+1;j++) {
2305                         hold = addfacelist(em, innerverts[i][j+1],innerverts[i][j],innerverts[i+1][j],innerverts[i+1][j+1],NULL,NULL);
2306                         hold->e1->f2 = EDGENEW;
2307                         hold->e2->f2 = EDGENEW;
2308                         hold->e3->f2 = EDGENEW;
2309                         hold->e4->f2 = EDGENEW;
2310
2311                         if(i != 0) { hold->e1->f2 |= EDGEINNER; }
2312                         if(j != 0) { hold->e2->f2 |= EDGEINNER; }
2313                         if(i != numcuts) { hold->e3->f2 |= EDGEINNER; }
2314                         if(j != numcuts) { hold->e4->f2 |= EDGEINNER; }
2315
2316                         facecopy(em, efa,hold);
2317                 }
2318         }
2319         // Clean up our dynamic multi-dim array
2320         for(i=0;i<numcuts+2;i++) {
2321            MEM_freeN(innerverts[i]);
2322         }
2323         MEM_freeN(innerverts);
2324 }
2325
2326 static void fill_tri_triple(EditMesh *em, EditFace *efa, struct GHash *gh, int numcuts, float smooth, float fractal, int beauty)
2327 {
2328         EditVert **verts[3], ***innerverts;
2329         short vertsize, i, j;
2330         EditFace *hold;
2331         EditEdge temp;
2332
2333         // Point verts[0] and [1] to the array of new verts for cedge[0] and cedge[1]
2334         verts[0] = BLI_ghash_lookup(gh, efa->e1);
2335         verts[1] = BLI_ghash_lookup(gh, efa->e2);
2336         verts[2] = BLI_ghash_lookup(gh, efa->e3);
2337
2338         //This is the index size of the verts array
2339         vertsize = numcuts+2;
2340
2341         // Is the original v1 the same as the first vert on the selected edge?
2342         // if not, the edge is running the opposite direction in this face so flip
2343         // the array to the correct direction
2344
2345         if(verts[0][0] != efa->v1) {flipvertarray(verts[0],numcuts+2);}
2346         if(verts[1][0] != efa->v2) {flipvertarray(verts[1],numcuts+2);}
2347         if(verts[2][0] != efa->v3) {flipvertarray(verts[2],numcuts+2);}
2348         /*
2349         We should have something like this now
2350                                            3
2351
2352                                 3   2   1   0
2353                            0|---*---*---|3
2354                                 |                 /
2355                   1     1*              *2
2356                                 |         /
2357                            2*   *1         2
2358                                 |  /
2359                            3|/
2360                                  0
2361
2362         we will fill a 2 dim array of editvert*s to make filling easier
2363
2364                                                 3
2365
2366                          0  0---1---2---3---4
2367                                 | / | /  |/  | /
2368                          1  0---1----2---3
2369            1            | /  | / | /
2370                          2  0----1---2   2
2371                                 |  / |  /
2372                                 |/   |/
2373                          3  0---1
2374                                 |  /
2375                                 |/
2376                          4  0
2377
2378         */
2379
2380         innerverts = MEM_mallocN(sizeof(EditVert*)*(numcuts+2),"tri-tri subdiv inner verts outer array");
2381         for(i=0;i<numcuts+2;i++) {
2382                   innerverts[i] = MEM_mallocN(sizeof(EditVert*)*((numcuts+2)-i),"tri-tri subdiv inner verts inner array");
2383         }
2384         //top row is e3 backwards
2385         for(i=0;i<numcuts+2;i++) {
2386                   innerverts[0][i]                = verts[2][(numcuts+1)-i];
2387         }
2388
2389         for(i=1;i<=numcuts+1;i++) {
2390                 //fake edge, first vert is from e1, last is from e2
2391                 temp.v1= innerverts[i][0]                         = verts[0][i];
2392                 temp.v2= innerverts[i][(numcuts+1)-i]  = verts[1][(numcuts+1)-i];
2393
2394                 for(j=1;j<(numcuts+1)-i;j++) {
2395                         float percent= (float)j/(float)((numcuts+1)-i);
2396
2397                         innerverts[i][((numcuts+1)-i)-j]= subdivide_edge_addvert(em, &temp, smooth, fractal, beauty, 1-percent);
2398                 }
2399         }
2400
2401         // Now fill the verts with happy little tris :)
2402         for(i=0;i<=numcuts+1;i++) {
2403                 for(j=0;j<(numcuts+1)-i;j++) {
2404                         //We always do the first tri
2405                         hold = addfacelist(em, innerverts[i][j+1],innerverts[i][j],innerverts[i+1][j],NULL,NULL,NULL);
2406                         hold->e1->f2 |= EDGENEW;
2407                         hold->e2->f2 |= EDGENEW;
2408                         hold->e3->f2 |= EDGENEW;
2409                         if(i != 0) { hold->e1->f2 |= EDGEINNER; }
2410                         if(j != 0) { hold->e2->f2 |= EDGEINNER; }
2411                         if(j+1 != (numcuts+1)-i) {hold->e3->f2 |= EDGEINNER;}
2412
2413                         facecopy(em, efa,hold);
2414                         //if there are more to come, we do the 2nd
2415                         if(j+1 <= numcuts-i) {
2416                                 hold = addfacelist(em, innerverts[i+1][j],innerverts[i+1][j+1],innerverts[i][j+1],NULL,NULL,NULL);
2417                                 facecopy(em, efa,hold);
2418                                 hold->e1->f2 |= EDGENEW;
2419                                 hold->e2->f2 |= EDGENEW;
2420                                 hold->e3->f2 |= EDGENEW;
2421                         }
2422                 }
2423         }
2424
2425         // Clean up our dynamic multi-dim array
2426         for(i=0;i<numcuts+2;i++) {
2427                 MEM_freeN(innerverts[i]);
2428         }
2429         MEM_freeN(innerverts);
2430 }
2431
2432 //Next two fill types are for knife exact only and are provided to allow for knifing through vertices
2433 //This means there is no multicut!
2434 static void fill_quad_doublevert(EditMesh *em, EditFace *efa, int v1, int v2)
2435 {
2436         EditFace *hold;
2437         /*
2438                 Depending on which two vertices have been knifed through (v1 and v2), we
2439                 triangulate like the patterns below.
2440                                 X-------|       |-------X
2441                                 | \     |       |     / |
2442                                 |   \   |       |   /   |
2443                                 |         \     |       | /         |
2444                                 --------X       X--------
2445         */
2446
2447         if(v1 == 1 && v2 == 3){
2448                 hold= addfacelist(em, efa->v1, efa->v2, efa->v3, 0, efa, NULL);
2449                 hold->e1->f2 |= EDGENEW;
2450                 hold->e2->f2 |= EDGENEW;
2451                 hold->e3->f2 |= EDGENEW;
2452                 hold->e3->f2 |= EDGEINNER;
2453                 facecopy(em, efa, hold);
2454
2455                 hold= addfacelist(em, efa->v1, efa->v3, efa->v4, 0, efa, NULL);
2456                 hold->e1->f2 |= EDGENEW;
2457                 hold->e2->f2 |= EDGENEW;
2458                 hold->e3->f2 |= EDGENEW;
2459                 hold->e1->f2 |= EDGEINNER;
2460                 facecopy(em, efa, hold);
2461         }
2462         else{
2463                 hold= addfacelist(em, efa->v1, efa->v2, efa->v4, 0, efa, NULL);
2464                 hold->e1->f2 |= EDGENEW;
2465                 hold->e2->f2 |= EDGENEW;
2466                 hold->e3->f2 |= EDGENEW;
2467                 hold->e2->f2 |= EDGEINNER;
2468                 facecopy(em, efa, hold);
2469
2470                 hold= addfacelist(em, efa->v2, efa->v3, efa->v4, 0, efa, NULL);
2471                 hold->e1->f2 |= EDGENEW;
2472                 hold->e2->f2 |= EDGENEW;
2473                 hold->e3->f2 |= EDGENEW;
2474                 hold->e3->f2 |= EDGEINNER;
2475                 facecopy(em, efa, hold);
2476         }
2477 }
2478
2479 static void fill_quad_singlevert(EditMesh *em, EditFace *efa, struct GHash *gh)
2480 {
2481         EditEdge *cedge=NULL;
2482         EditVert *v[4], **verts;
2483         EditFace *hold;
2484         short start=0, end, left, right, vertsize;
2485
2486         v[0] = efa->v1;
2487         v[1] = efa->v2;
2488         v[2] = efa->v3;
2489         v[3] = efa->v4;
2490
2491         if(efa->e1->f & SELECT)   { cedge = efa->e1; start = 0;}
2492         else if(efa->e2->f & SELECT) { cedge = efa->e2; start = 1;}
2493         else if(efa->e3->f & SELECT) { cedge = efa->e3; start = 2;}
2494         else if(efa->e4->f & SELECT) { cedge = efa->e4; start = 3;}
2495
2496         // Point verts to the array of new verts for cedge
2497         verts = BLI_ghash_lookup(gh, cedge);
2498         //This is the index size of the verts array
2499         vertsize = 3;
2500
2501         // Is the original v1 the same as the first vert on the selected edge?
2502         // if not, the edge is running the opposite direction in this face so flip
2503         // the array to the correct direction
2504
2505         if(verts[0] != v[start]) {flipvertarray(verts,3);}
2506         end     = (start+1)%4;
2507         left   = (start+2)%4;
2508         right  = (start+3)%4;
2509
2510 /*
2511         We should have something like this now
2512
2513                           end            start
2514                            2     1     0
2515                            |-----*-----|
2516                            |               |
2517                            |               |
2518                            |               |
2519                            -------------
2520                           left     right
2521
2522         where start,end,left, right are indexes of EditFace->v1, etc (stored in v)
2523         and 0,1,2 are the indexes of the new verts stored in verts. We fill like
2524         this, depending on whether its vertex 'left' or vertex 'right' thats
2525         been knifed through...
2526
2527                                 |---*---|       |---*---|
2528                                 |  /    |       |    \  |
2529                                 | /             |       |         \ |
2530                                 |/              |       |          \|
2531                                 X--------       --------X
2532 */
2533
2534         if(v[left]->f1){
2535                 //triangle is composed of cutvert, end and left
2536                 hold = addfacelist(em, verts[1],v[end],v[left],NULL, NULL,NULL);
2537                 hold->e1->f2 |= EDGENEW;
2538                 hold->e2->f2 |= EDGENEW;
2539                 hold->e3->f2 |= EDGENEW;
2540                 hold->e3->f2 |= EDGEINNER;
2541                 facecopy(em, efa, hold);
2542
2543                 //quad is composed of cutvert, left, right and start
2544                 hold = addfacelist(em, verts[1],v[left],v[right],v[start], NULL, NULL);
2545                 hold->e1->f2 |= EDGENEW;
2546                 hold->e2->f2 |= EDGENEW;
2547                 hold->e3->f2 |= EDGENEW;
2548                 hold->e4->f2 |= EDGENEW;
2549                 hold->e1->f2 |= EDGEINNER;
2550                 facecopy(em, efa, hold);
2551         }
2552         else if(v[right]->f1){
2553                 //triangle is composed of cutvert, right and start
2554                 hold = addfacelist(em, verts[1],v[right],v[start], NULL, NULL, NULL);
2555                 hold->e1->f2 |= EDGENEW;
2556                 hold->e2->f2 |= EDGENEW;
2557                 hold->e3->f2 |= EDGENEW;
2558                 hold->e1->f2 |= EDGEINNER;
2559                 facecopy(em, efa, hold);
2560                 //quad is composed of cutvert, end, left, right
2561                 hold = addfacelist(em, verts[1],v[end], v[left], v[right], NULL, NULL);
2562                 hold->e1->f2 |= EDGENEW;
2563                 hold->e2->f2 |= EDGENEW;
2564                 hold->e3->f2 |= EDGENEW;
2565                 hold->e4->f2 |= EDGENEW;
2566                 hold->e4->f2 |= EDGEINNER;
2567                 facecopy(em, efa, hold);
2568         }
2569
2570 }
2571
2572 // This function takes an example edge, the current point to create and
2573 // the total # of points to create, then creates the point and return the
2574 // editvert pointer to it.
2575 static EditVert *subdivideedgenum(EditMesh *em, EditEdge *edge, int curpoint, int totpoint, float smooth, float fractal, int beauty)
2576 {
2577         EditVert *ev;
2578         float percent;
2579
2580         if (beauty & (B_PERCENTSUBD) && totpoint == 1)
2581                 //percent=(float)(edge->tmp.l)/32768.0f;
2582                 percent= edge->tmp.fp;
2583         else
2584                 percent= (float)curpoint/(float)(totpoint+1);
2585
2586         ev= subdivide_edge_addvert(em, edge, smooth, fractal, beauty, percent);
2587         ev->f = edge->v1->f;
2588
2589         return ev;
2590 }
2591
2592 void esubdivideflag(Object *obedit, EditMesh *em, int flag, float smooth, float fractal, int beauty, int numcuts, int corner_pattern, int seltype)
2593 {
2594         EditFace *ef;
2595         EditEdge *eed, *cedge, *sort[4];
2596         EditVert *eve, **templist;
2597         struct GHash *gh;
2598         float length[4], v1mat[3], v2mat[3], v3mat[3], v4mat[3];
2599         int i, j, edgecount, touchcount, facetype,hold;
2600         ModifierData *md= obedit->modifiers.first;
2601         int ctrl= 0; // XXX
2602
2603         //Set faces f1 to 0 cause we need it later
2604         for(ef=em->faces.first;ef;ef = ef->next) ef->f1 = 0;
2605         for(eve=em->verts.first; eve; eve=eve->next) {
2606                 if(!(beauty & B_KNIFE)) /* knife sets this flag for vertex cuts */
2607                         eve->f1 = 0;
2608                 eve->f2 = 0;
2609         }
2610
2611         for (; md; md=md->next) {
2612                 if (md->type==eModifierType_Mirror) {
2613                         MirrorModifierData *mmd = (MirrorModifierData*) md;
2614
2615                         if(mmd->flag & MOD_MIR_CLIPPING) {
2616                                 for (eve= em->verts.first; eve; eve= eve->next) {
2617                                         eve->f2= 0;
2618                                         switch(mmd->axis){
2619                                                 case 0:
2620                                                         if (fabs(eve->co[0]) < mmd->tolerance)
2621                                                                 eve->f2 |= 1;
2622                                                         break;
2623                                                 case 1:
2624                                                         if (fabs(eve->co[1]) < mmd->tolerance)
2625                                                                 eve->f2 |= 2;
2626                                                         break;
2627                                                 case 2:
2628                                                         if (fabs(eve->co[2]) < mmd->tolerance)
2629                                                                 eve->f2 |= 4;
2630                                                         break;
2631                                         }
2632                                 }
2633                         }
2634                 }
2635         }
2636
2637         //Flush vertex flags upward to the edges
2638         for(eed = em->edges.first;eed;eed = eed->next) {
2639                 //if(eed->f & flag && eed->v1->f == eed->v2->f) {
2640                 //      eed->f |= eed->v1->f;
2641                 // }
2642                 eed->f2 = 0;
2643                 if(eed->f & flag) {
2644                         eed->f2 |= EDGEOLD;
2645                 }
2646         }
2647
2648         // We store an array of verts for each edge that is subdivided,
2649         // we put this array as a value in a ghash which is keyed by the EditEdge*
2650
2651         // Now for beauty subdivide deselect edges based on length
2652         if(beauty & B_BEAUTY) {
2653                 for(ef = em->faces.first;ef;ef = ef->next) {
2654                         if(!ef->v4) {
2655                                 continue;
2656                         }
2657                         if(ef->f & SELECT) {
2658                                 VECCOPY(v1mat, ef->v1->co);
2659                                 VECCOPY(v2mat, ef->v2->co);
2660                                 VECCOPY(v3mat, ef->v3->co);
2661                                 VECCOPY(v4mat, ef->v4->co);
2662                                 mul_mat3_m4_v3(obedit->obmat, v1mat);
2663                                 mul_mat3_m4_v3(obedit->obmat, v2mat);
2664                                 mul_mat3_m4_v3(obedit->obmat, v3mat);
2665                                 mul_mat3_m4_v3(obedit->obmat, v4mat);
2666
2667                                 length[0] = len_v3v3(v1mat, v2mat);
2668                                 length[1] = len_v3v3(v2mat, v3mat);
2669                                 length[2] = len_v3v3(v3mat, v4mat);
2670                                 length[3] = len_v3v3(v4mat, v1mat);
2671                                 sort[0] = ef->e1;
2672                                 sort[1] = ef->e2;
2673                                 sort[2] = ef->e3;
2674                                 sort[3] = ef->e4;
2675
2676
2677                                 // Beauty Short Edges
2678                                 if(beauty & B_BEAUTY_SHORT) {
2679                                         for(j=0;j<2;j++) {
2680                                                 hold = -1;
2681                                                 for(i=0;i<4;i++) {
2682                                                         if(length[i] < 0) {
2683                                                                 continue;
2684                                                         } else if(hold == -1) {
2685                                                                 hold = i;
2686                                                         } else {
2687                                                                 if(length[hold] < length[i]) {
2688                                                                         hold = i;
2689                                                                 }
2690                                                         }
2691                                                 }
2692                                                 if (hold > -1) {
2693                                                         sort[hold]->f &= ~SELECT;
2694                                                         sort[hold]->f2 |= EDGENEW;
2695                                                         length[hold] = -1;
2696                                                 }
2697                                         }
2698                                 }
2699
2700                                 // Beauty Long Edges
2701                                 else {
2702                                          for(j=0;j<2;j++) {
2703                                                 hold = -1;
2704                                                 for(i=0;i<4;i++) {
2705                                                         if(length[i] < 0) {
2706                                                                 continue;
2707                                                         } else if(hold == -1) {
2708                                                                 hold = i;
2709                                                         } else {
2710                                                                 if(length[hold] > length[i]) {
2711                                                                         hold = i;
2712                                                                 }
2713                                                         }
2714                                                 }
2715                                                 if (hold > -1) {
2716                                                         sort[hold]->f &= ~SELECT;
2717                                                         sort[hold]->f2 |= EDGENEW;
2718                                                         length[hold] = -1;
2719                                                 }
2720                                         }
2721                                 }
2722                         }
2723                 }
2724         }
2725
2726         gh = BLI_ghash_new(BLI_ghashutil_ptrhash, BLI_ghashutil_ptrcmp, "subdivideedgenum gh");
2727
2728         // If we are knifing, We only need the selected edges that were cut, so deselect if it was not cut
2729         if(beauty & B_KNIFE) {
2730                 for(eed= em->edges.first;eed;eed=eed->next) {
2731                         if( eed->tmp.fp == 0 ) {
2732                                 EM_select_edge(eed,0);
2733                         }
2734                 }
2735         }
2736         // So for each edge, if it is selected, we allocate an array of size cuts+2
2737         // so we can have a place for the v1, the new verts and v2
2738         for(eed=em->edges.first;eed;eed = eed->next) {
2739                 if(eed->f & flag) {
2740                         templist = MEM_mallocN(sizeof(EditVert*)*(numcuts+2),"vertlist");
2741                         templist[0] = eed->v1;
2742                         for(i=0;i<numcuts;i++) {
2743                                 // This function creates the new vert and returns it back
2744                                 // to the array
2745                                 templist[i+1] = subdivideedgenum(em, eed, i+1, numcuts, smooth, fractal, beauty);
2746                                 //while we are here, we can copy edge info from the original edge
2747                                 cedge = addedgelist(em, templist[i],templist[i+1],eed);
2748                                 // Also set the edge f2 to EDGENEW so that we can use this info later
2749                                 cedge->f2 = EDGENEW;
2750                         }
2751                         templist[i+1] = eed->v2;
2752                         //Do the last edge too
2753                         cedge = addedgelist(em, templist[i],templist[i+1],eed);
2754                         cedge->f2 = EDGENEW;
2755                         // Now that the edge is subdivided, we can put its verts in the ghash
2756                         BLI_ghash_insert(gh, eed, templist);
2757                 }
2758         }
2759
2760 //      DAG_id_flush_update(obedit->data, OB_RECALC_DATA);
2761         // Now for each face in the mesh we need to figure out How many edges were cut
2762         // and which filling method to use for that face
2763         for(ef = em->faces.first;ef;ef = ef->next) {
2764                 edgecount = 0;
2765                 facetype = 3;
2766                 if(ef->e1->f & flag) {edgecount++;}
2767                 if(ef->e2->f & flag) {edgecount++;}
2768                 if(ef->e3->f & flag) {edgecount++;}
2769                 if(ef->v4) {
2770                         facetype = 4;
2771                         if(ef->e4->f & flag) {edgecount++;}
2772                 }
2773                 if(facetype == 4) {
2774                         switch(edgecount) {
2775                                 case 0:
2776                                         if(beauty & B_KNIFE && numcuts == 1){
2777                                                 /*Test for when knifing through two opposite verts but no edges*/
2778                                                 touchcount = 0;
2779                                                 if(ef->v1->f1) touchcount++;
2780                                                 if(ef->v2->f1) touchcount++;
2781                                                 if(ef->v3->f1) touchcount++;
2782                                                 if(ef->v4->f1) touchcount++;
2783                                                 if(touchcount == 2){
2784                                                         if(ef->v1->f1 && ef->v3->f1){
2785                                                                 ef->f1 = SELECT;
2786                                                                 fill_quad_doublevert(em, ef, 1, 3);
2787                                                         }
2788                                                         else if(ef->v2->f1 && ef->v4->f1){
2789                                                                 ef->f1 = SELECT;
2790                                                                 fill_quad_doublevert(em, ef, 2, 4);
2791                                                         }
2792                                                 }
2793                                         }
2794                                         break;
2795
2796                                 case 1:
2797                                         if(beauty & B_KNIFE && numcuts == 1){
2798                                                 /*Test for when knifing through an edge and one vert*/
2799                                                 touchcount = 0;
2800                                                 if(ef->v1->f1) touchcount++;
2801                                                 if(ef->v2->f1) touchcount++;
2802                                                 if(ef->v3->f1) touchcount++;
2803                                                 if(ef->v4->f1) touchcount++;
2804
2805                                                 if(touchcount == 1){
2806                                                         if( (ef->e1->f & flag && ( !ef->e1->v1->f1 && !ef->e1->v2->f1 )) ||
2807                                                                 (ef->e2->f & flag && ( !ef->e2->v1->f1 && !ef->e2->v2->f1 )) ||
2808                                                                 (ef->e3->f & flag && ( !ef->e3->v1->f1 && !ef->e3->v2->f1 )) ||
2809                                                                 (ef->e4->f & flag && ( !ef->e4->v1->f1 && !ef->e4->v2->f1 )) ){
2810
2811                                                                 ef->f1 = SELECT;
2812                                                                 fill_quad_singlevert(em, ef, gh);
2813                                                         }
2814                                                         else{
2815                                                                 ef->f1 = SELECT;
2816                                                                 fill_quad_single(em, ef, gh, numcuts, seltype);
2817                                                         }
2818                                                 }
2819                                                 else{
2820                                                         ef->f1 = SELECT;
2821                                                         fill_quad_single(em, ef, gh, numcuts, seltype);
2822                                                 }
2823                                         }
2824                                         else{
2825                                                 ef->f1 = SELECT;
2826                                                 fill_quad_single(em, ef, gh, numcuts, seltype);
2827                                         }
2828                                         break;
2829                                 case 2: ef->f1 = SELECT;
2830                                         // if there are 2, we check if edge 1 and 3 are either both on or off that way
2831                                         // we can tell if the selected pair is Adjacent or Opposite of each other
2832                                         if((ef->e1->f & flag && ef->e3->f & flag) ||
2833                                            (ef->e2->f & flag && ef->e4->f & flag)) {
2834                                                 fill_quad_double_op(em, ef, gh, numcuts);
2835                                         }else{
2836                                                 switch(corner_pattern) {
2837                                                         case 0: fill_quad_double_adj_path(em, ef, gh, numcuts); break;
2838                                                         case 1: fill_quad_double_adj_inner(em, ef, gh, numcuts); break;
2839                                                         case 2: fill_quad_double_adj_fan(em, ef, gh, numcuts); break;
2840                                                 }
2841
2842                                         }
2843                                                 break;
2844                                 case 3: ef->f1 = SELECT;
2845                                         fill_quad_triple(em, ef, gh, numcuts);
2846                                         break;
2847                                 case 4: ef->f1 = SELECT;
2848                                         fill_quad_quadruple(em, ef, gh, numcuts, smooth, fractal, beauty);
2849                                         break;
2850                         }
2851                 } else {
2852                         switch(edgecount) {
2853                                 case 0: break;
2854                                 case 1: ef->f1 = SELECT;
2855                                         fill_tri_single(em, ef, gh, numcuts, seltype);
2856                                         break;
2857                                 case 2: ef->f1 = SELECT;
2858                                         fill_tri_double(em, ef, gh, numcuts);
2859                                         break;
2860                                 case 3: ef->f1 = SELECT;
2861                                         fill_tri_triple(em, ef, gh, numcuts, smooth, fractal, beauty);
2862                                         break;
2863                         }
2864                 }
2865         }
2866
2867         // Delete Old Edges and Faces
2868         for(eed = em->edges.first;eed;eed = eed->next) {
2869                 if(BLI_ghash_haskey(gh,eed)) {
2870                         eed->f1 = SELECT;
2871                 } else {
2872                         eed->f1 = 0;
2873                 }
2874         }
2875         free_tagged_edges_faces(em, em->edges.first, em->faces.first);
2876
2877         if(seltype == SUBDIV_SELECT_ORIG  && !ctrl) {
2878                 /* bugfix: vertex could get flagged as "not-selected"
2879                 // solution: clear flags before, not at the same time as setting SELECT flag -dg
2880                 */
2881                 for(eed = em->edges.first;eed;eed = eed->next) {
2882                         if(!(eed->f2 & EDGENEW || eed->f2 & EDGEOLD)) {
2883                                 eed->f &= !flag;
2884                                 EM_select_edge(eed,0);
2885                         }
2886                 }
2887                 for(eed = em->edges.first;eed;eed = eed->next) {
2888                         if(eed->f2 & EDGENEW || eed->f2 & EDGEOLD) {
2889                                 eed->f |= flag;
2890                                 EM_select_edge(eed,1);
2891                         }
2892                 }
2893         } else if ((seltype == SUBDIV_SELECT_INNER || seltype == SUBDIV_SELECT_INNER_SEL)|| ctrl) {
2894                 for(eed = em->edges.first;eed;eed = eed->next) {
2895                         if(eed->f2 & EDGEINNER) {
2896                                 eed->f |= flag;
2897                                 EM_select_edge(eed,1);
2898                                 if(eed->v1->f & EDGEINNER) eed->v1->f |= SELECT;
2899                                 if(eed->v2->f & EDGEINNER) eed->v2->f |= SELECT;
2900                         }else{
2901                                 eed->f &= !flag;
2902                                 EM_select_edge(eed,0);
2903                         }
2904                 }
2905         } else if(seltype == SUBDIV_SELECT_LOOPCUT){
2906                 for(eed = em->edges.first;eed;eed = eed->next) {
2907                         if(eed->f2 & DOUBLEOPFILL){
2908                                 eed->f |= flag;
2909                                 EM_select_edge(eed,1);
2910                         }else{
2911                                 eed->f &= !flag;
2912                                 EM_select_edge(eed,0);
2913                         }
2914                 }
2915         }
2916          if(em->selectmode & SCE_SELECT_VERTEX) {
2917                  for(eed = em->edges.first;eed;eed = eed->next) {
2918                         if(eed->f & SELECT) {
2919                                 eed->v1->f |= SELECT;
2920                                 eed->v2->f |= SELECT;
2921                         }
2922                 }
2923         }
2924
2925         //fix hide flags for edges. First pass, hide edges of hidden faces
2926         for(ef=em->faces.first; ef; ef=ef->next){
2927                 if(ef->h){
2928                         ef->e1->h |= 1;
2929                         ef->e2->h |= 1;
2930                         ef->e3->h |= 1;
2931                         if(ef->e4) ef->e4->h |= 1;
2932                 }
2933         }
2934         //second pass: unhide edges of visible faces adjacent to hidden faces
2935         for(ef=em->faces.first; ef; ef=ef->next){
2936                 if(ef->h == 0){
2937                         ef->e1->h &= ~1;
2938                         ef->e2->h &= ~1;
2939                         ef->e3->h &= ~1;
2940                         if(ef->e4) ef->e4->h &= ~1;
2941                 }
2942         }
2943
2944         // Free the ghash and call MEM_freeN on all the value entries to return
2945         // that memory
2946         BLI_ghash_free(gh, NULL, (GHashValFreeFP)MEM_freeN);
2947
2948         EM_selectmode_flush(em);
2949         for(ef=em->faces.first;ef;ef = ef->next) {
2950                 if(ef->e4) {
2951                         if(  (ef->e1->f & SELECT && ef->e2->f & SELECT) &&
2952                          (ef->e3->f & SELECT && ef->e4->f & SELECT) ) {
2953                                 ef->f |= SELECT;
2954                         }
2955                 } else {
2956                         if(  (ef->e1->f & SELECT && ef->e2->f & SELECT) && ef->e3->f & SELECT) {
2957                                 ef->f |= SELECT;
2958                         }
2959                 }
2960         }
2961
2962         recalc_editnormals(em);
2963 }
2964
2965 static int count_selected_edges(EditEdge *ed)
2966 {
2967         int totedge = 0;
2968         while(ed) {
2969                 ed->tmp.p = 0;
2970                 if( ed->f & SELECT ) totedge++;
2971                 ed= ed->next;
2972         }
2973         return totedge;
2974 }
2975
2976 /* hurms, as if this makes code readable! It's pointerpointer hiding... (ton) */
2977 typedef EditFace *EVPtr;
2978 typedef EVPtr EVPTuple[2];
2979
2980 /** builds EVPTuple array efaa of face tuples (in fact pointers to EditFaces)
2981         sharing one edge.
2982         arguments: selected edge list, face list.
2983         Edges will also be tagged accordingly (see eed->f2)               */
2984
2985 static int collect_quadedges(EVPTuple *efaa, EditEdge *eed, EditFace *efa)
2986 {
2987         EditEdge *e1, *e2, *e3;
2988         EVPtr *evp;
2989         int i = 0;
2990
2991         /* run through edges, if selected, set pointer edge-> facearray */
2992         while(eed) {
2993                 eed->f2= 0;
2994                 eed->f1= 0;
2995                 if( eed->f & SELECT ) {
2996                         eed->tmp.p = (EditVert *) (&efaa[i]);
2997                         i++;
2998                 }
2999                 else eed->tmp.p = NULL;
3000
3001                 eed= eed->next;
3002         }
3003
3004
3005         /* find edges pointing to 2 faces by procedure:
3006
3007         - run through faces and their edges, increase
3008           face counter e->f1 for each face
3009         */
3010
3011         while(efa) {
3012                 efa->f1= 0;
3013                 if(efa->v4==0 && (efa->f & SELECT)) {  /* if selected triangle */
3014                         e1= efa->e1;
3015                         e2= efa->e2;
3016                         e3= efa->e3;
3017                         if(e1->f2<3 && e1->tmp.p) {
3018                                 if(e1->f2<2) {
3019                                         evp= (EVPtr *) e1->tmp.p;
3020                                         evp[(int)e1->f2] = efa;
3021                                 }
3022                          &