81776d673e7ec55354874b17d4cf654830dec2c8
[blender.git] / source / blender / bmesh / operators / extrudeops.c
1 #include "MEM_guardedalloc.h"
2
3 #include "BKE_utildefines.h"
4
5 #include "BLI_ghash.h"
6 #include "BLI_memarena.h"
7 #include "BLI_blenlib.h"
8 #include "BLI_arithb.h"
9
10 #include "bmesh.h"
11 #include "bmesh_operators_private.h"
12
13 #define EXT_INPUT       1
14 #define EXT_KEEP        2
15 #define EXT_DEL         4
16
17 void extrude_edge_context_exec(BMesh *bm, BMOperator *op)
18 {
19         BMOperator dupeop, delop;
20         BMOIter siter;
21         BMIter iter, fiter, viter;
22         BMEdge *e, *newedge, *e2;
23         BMLoop *l, *l2;
24         BMVert *verts[4], *v;
25         BMFace *f;
26         int rlen, found, delorig=0, i;
27
28         /*initialize our sub-operators*/
29         BMO_Init_Op(&dupeop, BMOP_DUPE);
30         BMO_Init_Op(&delop, BMOP_DEL);
31         
32         BMO_Flag_Buffer(bm, op, BMOP_EXFACE_EDGEFACEIN, EXT_INPUT);
33
34 #if 1
35         for (e=BMIter_New(&iter, bm, BM_EDGES, NULL);e;e=BMIter_Step(&iter)) {
36                 found = 0;
37                 f = BMIter_New(&fiter, bm, BM_FACES_OF_EDGE, e);
38                 for (rlen=0; f; f=BMIter_Step(&fiter), rlen++) {
39                         if (!BMO_TestFlag(bm, f, EXT_INPUT)) {
40                                 found = 1;
41                                 delorig = 1;
42                                 break;
43                         }
44                 }
45                 
46                 if (!found && (rlen > 1)) BMO_SetFlag(bm, e, EXT_DEL);
47         }
48
49         /*calculate verts to delete*/
50         for (v = BMIter_New(&iter, bm, BM_VERTS, NULL); v; v=BMIter_Step(&iter)) {
51                 found = 0;
52
53                 l = BMIter_New(&viter, bm, BM_LOOPS_OF_VERT, v);
54                 for (; l; l=BMIter_Step(&viter)) {
55                         if (!BMO_TestFlag(bm, l->e, EXT_INPUT)) {
56                                 found = 1;
57                                 break;
58                         }
59                         if (!BMO_TestFlag(bm, l->f, EXT_INPUT)) {
60                                 found = 1;
61                                 break;
62                         }
63
64                         if (found) break;
65                 }
66
67                 if (!found) {
68                         BMO_SetFlag(bm, v, EXT_DEL);
69                 }
70         }
71         
72         for (f=BMIter_New(&fiter, bm, BM_FACES, NULL); f; f=BMIter_Step(&fiter)) {
73                 if (BMO_TestFlag(bm, f, EXT_INPUT))
74                         BMO_SetFlag(bm, f, EXT_DEL);
75         }
76 #endif
77         if (delorig) BMO_Flag_To_Slot(bm, &delop, BMOP_DEL_MULTIN, EXT_DEL, BM_ALL);
78         BMO_Set_Int(&delop, BMOP_DEL_CONTEXT, DEL_ONLYTAGGED);
79
80         BMO_CopySlot(op, &dupeop, BMOP_EXFACE_EDGEFACEIN, BMOP_DUPE_MULTIN);
81         
82         BMO_Exec_Op(bm, &dupeop);
83         if (delorig) BMO_Exec_Op(bm, &delop);
84
85         BMO_CopySlot(&dupeop, op, BMOP_DUPE_NEW, BMOP_EXFACE_MULTOUT);
86         e = BMO_IterNew(&siter, bm, &dupeop, BMOP_DUPE_BOUNDS_EDGEMAP);
87         for (; e; e=BMO_IterStep(&siter)) {
88                 if (BMO_InMap(bm, op, BMOP_EXFACE_EXCLUDEMAP, e)) continue;
89
90                 newedge = BMO_IterMapVal(&siter);
91                 if (!newedge) continue;
92                 newedge = *(BMEdge**)newedge;
93
94                 verts[0] = e->v1;
95                 verts[1] = e->v2;
96                 verts[2] = newedge->v2;
97                 verts[3] = newedge->v1;
98                 
99                 //not sure what to do about example face, pass NULL for now.
100                 f = BM_Make_Quadtriangle(bm, verts, NULL, 4, NULL, 0);          
101
102                 /*copy attributes*/
103                 l=BMIter_New(&iter, bm, BM_LOOPS_OF_FACE, f);
104                 for (; l; l=BMIter_Step(&iter)) {
105                         l2 = l->radial.next->data;
106                         
107                         if (l2 && l2 != l) {
108                                 /*copy data*/
109                                 if (l2->v == l->v) {
110                                         BM_Copy_Attributes(bm, bm, l2, l);
111                                         l2 = (BMLoop*) l2->head.next;
112                                         l = (BMLoop*) l->head.next;
113                                         BM_Copy_Attributes(bm, bm, l2, l);
114                                 } else {
115                                         l2 = (BMLoop*) l2->head.next;
116                                         BM_Copy_Attributes(bm, bm, l2, l);
117                                         l2 = (BMLoop*) l2->head.prev;
118                                         l = (BMLoop*) l->head.next;
119                                         BM_Copy_Attributes(bm, bm, l2, l);
120                                 }
121                         }
122                 }
123         }
124
125         
126         /*cleanup*/
127         BMO_Finish_Op(bm, &delop);
128         BMO_Finish_Op(bm, &dupeop);
129 }