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