split dissolve_disk into dissolve_vert dissolve_disk as agreed. also made dissolve...
[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                 if (!BMO_TestFlag(bm, e, EXT_INPUT)) continue;
37
38                 found = 0;
39                 f = BMIter_New(&fiter, bm, BM_FACES_OF_EDGE, e);
40                 for (rlen=0; f; f=BMIter_Step(&fiter), rlen++) {
41                         if (!BMO_TestFlag(bm, f, EXT_INPUT)) {
42                                 found = 1;
43                                 delorig = 1;
44                                 break;
45                         }
46                 }
47                 
48                 if (!found && (rlen > 1)) BMO_SetFlag(bm, e, EXT_DEL);
49         }
50
51         /*calculate verts to delete*/
52         for (v = BMIter_New(&iter, bm, BM_VERTS, NULL); v; v=BMIter_Step(&iter)) {
53                 found = 0;
54
55                 l = BMIter_New(&viter, bm, BM_LOOPS_OF_VERT, v);
56                 for (; l; l=BMIter_Step(&viter)) {
57                         if (!BMO_TestFlag(bm, l->e, EXT_INPUT)) {
58                                 found = 1;
59                                 break;
60                         }
61                         if (!BMO_TestFlag(bm, l->f, EXT_INPUT)) {
62                                 found = 1;
63                                 break;
64                         }
65
66                         if (found) break;
67                 }
68
69                 if (!found) {
70                         BMO_SetFlag(bm, v, EXT_DEL);
71                 }
72         }
73         
74         for (f=BMIter_New(&fiter, bm, BM_FACES, NULL); f; f=BMIter_Step(&fiter)) {
75                 if (BMO_TestFlag(bm, f, EXT_INPUT))
76                         BMO_SetFlag(bm, f, EXT_DEL);
77         }
78 #endif
79         if (delorig) BMO_Flag_To_Slot(bm, &delop, BMOP_DEL_MULTIN, EXT_DEL, BM_ALL);
80         BMO_Set_Int(&delop, BMOP_DEL_CONTEXT, DEL_ONLYTAGGED);
81
82         BMO_CopySlot(op, &dupeop, BMOP_EXFACE_EDGEFACEIN, BMOP_DUPE_MULTIN);
83         
84         BMO_Exec_Op(bm, &dupeop);
85         if (delorig) BMO_Exec_Op(bm, &delop);
86
87         BMO_CopySlot(&dupeop, op, BMOP_DUPE_NEW, BMOP_EXFACE_MULTOUT);
88         e = BMO_IterNew(&siter, bm, &dupeop, BMOP_DUPE_BOUNDS_EDGEMAP);
89         for (; e; e=BMO_IterStep(&siter)) {
90                 if (BMO_InMap(bm, op, BMOP_EXFACE_EXCLUDEMAP, e)) continue;
91
92                 newedge = BMO_IterMapVal(&siter);
93                 if (!newedge) continue;
94                 newedge = *(BMEdge**)newedge;
95
96                 verts[0] = e->v1;
97                 verts[1] = e->v2;
98                 verts[2] = newedge->v2;
99                 verts[3] = newedge->v1;
100                 
101                 //not sure what to do about example face, pass NULL for now.
102                 f = BM_Make_Quadtriangle(bm, verts, NULL, 4, NULL, 0);          
103
104                 /*copy attributes*/
105                 l=BMIter_New(&iter, bm, BM_LOOPS_OF_FACE, f);
106                 for (; l; l=BMIter_Step(&iter)) {
107                         l2 = l->radial.next->data;
108                         
109                         if (l2 && l2 != l) {
110                                 /*copy data*/
111                                 if (l2->v == l->v) {
112                                         BM_Copy_Attributes(bm, bm, l2, l);
113                                         l2 = (BMLoop*) l2->head.next;
114                                         l = (BMLoop*) l->head.next;
115                                         BM_Copy_Attributes(bm, bm, l2, l);
116                                 } else {
117                                         l2 = (BMLoop*) l2->head.next;
118                                         BM_Copy_Attributes(bm, bm, l2, l);
119                                         l2 = (BMLoop*) l2->head.prev;
120                                         l = (BMLoop*) l->head.next;
121                                         BM_Copy_Attributes(bm, bm, l2, l);
122                                 }
123                         }
124                 }
125         }
126
127         
128         /*cleanup*/
129         BMO_Finish_Op(bm, &delop);
130         BMO_Finish_Op(bm, &dupeop);
131 }