first pass at the uv code. uv editor now mostly uses new bmesh structures for uvs.
[blender-staging.git] / source / blender / bmesh / intern / bmesh_mesh.c
1 /**
2  * BME_mesh.c    jan 2007
3  *
4  *      BM mesh level functions.
5  *
6  * $Id: BME_eulers.c,v 1.00 2007/01/17 17:42:01 Briggs Exp $
7  *
8  * ***** BEGIN GPL LICENSE BLOCK *****
9  *
10  * This program is free software; you can redistribute it and/or
11  * modify it under the terms of the GNU General Public License
12  * as published by the Free Software Foundation; either version 2
13  * of the License, or (at your option) any later version.
14  * about this.  
15  *
16  * This program is distributed in the hope that it will be useful,
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19  * GNU General Public License for more details.
20  *
21  * You should have received a copy of the GNU General Public License
22  * along with this program; if not, write to the Free Software Foundation,
23  * Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
24  *
25  * The Original Code is Copyright (C) 2007 Blender Foundation.
26  * All rights reserved.
27  *
28  * The Original Code is: all of this file.
29  *
30  * Contributor(s): Geoffrey Bantle.
31  *
32  * ***** END GPL LICENSE BLOCK *****
33  */
34
35 #include "MEM_guardedalloc.h"
36 #include "DNA_listBase.h"
37 #include "BLI_blenlib.h"
38 #include "BLI_arithb.h"
39 #include "BKE_utildefines.h"
40
41 #include "bmesh.h"
42 #include "bmesh_private.h"
43
44 void BME_error(void);
45
46 /*bmesh_error stub*/
47 void bmesh_error(void)
48 {
49         printf("BM modelling error!");
50 }
51
52 /*
53  * BMESH SET SYSFLAG
54  *
55  * Sets a bitflag for a given element.
56  *
57 */
58
59 void bmesh_set_sysflag(BMHeader *head, int flag)
60 {
61         head->flag |= flag;
62 }
63
64 /*
65  * BMESH CLEAR SYSFLAG
66  * 
67  * Clears a bitflag for a given element.
68  *
69 */
70
71 void bmesh_clear_sysflag(BMHeader *head, int flag)
72 {
73         head->flag &= ~flag;
74 }
75
76
77 /*
78  * BMESH TEST SYSFLAG
79  *
80  * Tests whether a bitflag is set for a given element.
81  *
82 */
83
84 int bmesh_test_sysflag(BMHeader *head, int flag)
85 {
86         if(head->flag & flag)
87                 return 1;
88         return 0;
89 }
90
91 /*      
92  *      BMESH MAKE MESH
93  *
94  *  Allocates a new BMesh structure.
95  *  Returns -
96  *  Pointer to a BM
97  *
98 */
99
100 BMesh *BM_Make_Mesh(int allocsize[4])
101 {
102         /*allocate the structure*/
103         BMesh *bm = MEM_callocN(sizeof(BMesh),"BM");
104         /*allocate the memory pools for the mesh elements*/
105         bm->vpool = BLI_mempool_create(sizeof(BMVert), allocsize[0], allocsize[0]);
106         bm->epool = BLI_mempool_create(sizeof(BMEdge), allocsize[1], allocsize[1]);
107         bm->lpool = BLI_mempool_create(sizeof(BMLoop), allocsize[2], allocsize[2]);
108         bm->ppool = BLI_mempool_create(sizeof(BMFace), allocsize[3], allocsize[3]);
109
110         /*allocate one flag pool that we dont get rid of.*/
111         bm->flagpool = BLI_mempool_create(sizeof(BMFlagLayer), 512, 512);
112         bm->totflags = 1;
113
114         return bm;
115 }
116 /*      
117  *      BMESH FREE MESH
118  *
119  *      Frees a BMesh structure.
120 */
121
122 void BM_Free_Mesh_Data(BMesh *bm)
123 {
124         BMVert *v;
125         BMEdge *e;
126         BMLoop *l;
127         BMFace *f;
128         
129
130         BMIter verts;
131         BMIter edges;
132         BMIter faces;
133         BMIter loops;
134         
135         for(v = BMIter_New(&verts, bm, BM_VERTS_OF_MESH, bm ); v; v = BMIter_Step(&verts)) CustomData_bmesh_free_block( &(bm->vdata), &(v->head.data) );
136         for(e = BMIter_New(&edges, bm, BM_EDGES_OF_MESH, bm ); e; e = BMIter_Step(&edges)) CustomData_bmesh_free_block( &(bm->edata), &(e->head.data) );
137         for(f = BMIter_New(&faces, bm, BM_FACES_OF_MESH, bm ); f; f = BMIter_Step(&faces)){
138                 CustomData_bmesh_free_block( &(bm->pdata), &(f->head.data) );
139                 for(l = BMIter_New(&loops, bm, BM_LOOPS_OF_FACE, f ); l; l = BMIter_Step(&loops)) CustomData_bmesh_free_block( &(bm->ldata), &(l->head.data) );
140         }
141
142         /*Free custom data pools, This should probably go in CustomData_free?*/
143         if(bm->vdata.totlayer) BLI_mempool_destroy(bm->vdata.pool);
144         if(bm->edata.totlayer) BLI_mempool_destroy(bm->edata.pool);
145         if(bm->ldata.totlayer) BLI_mempool_destroy(bm->ldata.pool);
146         if(bm->pdata.totlayer) BLI_mempool_destroy(bm->pdata.pool);
147
148         /*free custom data*/
149         CustomData_free(&bm->vdata,0);
150         CustomData_free(&bm->edata,0);
151         CustomData_free(&bm->ldata,0);
152         CustomData_free(&bm->pdata,0);
153
154         /*destroy element pools*/
155         BLI_mempool_destroy(bm->vpool);
156         BLI_mempool_destroy(bm->epool);
157         BLI_mempool_destroy(bm->ppool);
158         BLI_mempool_destroy(bm->lpool);
159
160         /*destroy flag pool*/
161         BLI_mempool_destroy(bm->flagpool);
162         
163         if (bm->edar) MEM_freeN(bm->edar);
164         if (bm->vtar) MEM_freeN(bm->vtar);
165         if (bm->plar) MEM_freeN(bm->plar);
166
167         BLI_freelistN(&bm->selected);
168
169         BMO_ClearStack(bm);
170 }
171
172 void BM_Free_Mesh(BMesh *bm)
173 {
174         BM_Free_Mesh_Data(bm);
175         MEM_freeN(bm);
176 }
177
178 /*
179  *  BMESH COMPUTE NORMALS
180  *
181  *  Updates the normals of a mesh.
182  *  Note that this can only be called  
183  *
184 */
185
186 void BM_Compute_Normals(BMesh *bm)
187 {
188         BMVert *v;
189         BMFace *f;
190         BMLoop *l;
191         
192         BMIter verts;
193         BMIter faces;
194         BMIter loops;
195         
196         unsigned int maxlength = 0;
197         float (*projectverts)[3];
198         
199         /*first, find out the largest face in mesh*/
200         for(f = BMIter_New(&faces, bm, BM_FACES_OF_MESH, bm ); f; f = BMIter_Step(&faces)){
201                 if(f->len > maxlength) maxlength = f->len;
202         }
203         
204         /*make sure we actually have something to do*/
205         if(maxlength < 3) return; 
206         
207         /*allocate projectverts array*/
208         projectverts = MEM_callocN(sizeof(float) * maxlength * 3, "BM normal computation array");
209         
210         /*calculate all face normals*/
211         for(f = BMIter_New(&faces, bm, BM_FACES_OF_MESH, bm ); f; f = BMIter_Step(&faces)){
212                 if (f->head.flag & BM_NONORMCALC) continue;
213                 bmesh_update_face_normal(bm, f, projectverts);          
214         }
215         
216         /*Zero out vertex normals*/
217         for(v = BMIter_New(&verts, bm, BM_VERTS_OF_MESH, bm ); v; v = BMIter_Step(&verts)) v->no[0] = v->no[1] = v->no[2] = 0.0;
218
219         /*add face normals to vertices*/
220         for(f = BMIter_New(&faces, bm, BM_FACES_OF_MESH, bm ); f; f = BMIter_Step(&faces)){
221                 for(l = BMIter_New(&loops, bm, BM_LOOPS_OF_FACE, f ); l; l = BMIter_Step(&loops)) VecAddf(l->v->no, l->v->no, f->no);
222         }
223         
224         /*average the vertex normals*/
225         for(v = BMIter_New(&verts, bm, BM_VERTS_OF_MESH, bm ); v; v= BMIter_Step(&verts)){
226                 if (Normalize(v->no)==0.0) {
227                         VECCOPY(v->no, v->co);
228                         Normalize(v->no);
229                 }
230         }
231         
232         MEM_freeN(projectverts);
233 }
234
235 /*      
236  *      BMESH BEGIN/END EDIT
237  *
238  *      Functions for setting up a mesh for editing and cleaning up after 
239  *  the editing operations are done. These are called by the tools/operator 
240  *  API for each time a tool is executed.
241  *
242  *  Returns -
243  *  Nothing
244  *
245 */
246
247 void bmesh_begin_edit(BMesh *bm){
248
249         /*Initialize some scratch pointer arrays used by eulers*/
250         bm->vtar = MEM_callocN(sizeof(BMVert *) * 1024, "BM scratch vert array");
251         bm->edar = MEM_callocN(sizeof(BMEdge *) * 1024, "BM scratch edge array");
252         bm->lpar = MEM_callocN(sizeof(BMLoop *) * 1024, "BM scratch loop array");
253         bm->plar = MEM_callocN(sizeof(BMFace *) * 1024, "BM scratch poly array");
254
255         bm->vtarlen = bm->edarlen = bm->lparlen = bm->plarlen = 1024;
256 }
257
258 void bmesh_end_edit(BMesh *bm, int flag){
259         int totvert, totedge, totface;
260         /*verify element counts*/
261         totvert = BLI_countlist(&(bm->verts));
262         totedge = BLI_countlist(&(bm->edges));
263         totface = BLI_countlist(&(bm->polys));
264
265         if(bm->totvert!=totvert || bm->totedge!=totedge || bm->totface!=totface) BME_error();
266
267         /*free temp storage*/
268         if(bm->vtar) MEM_freeN(bm->vtar);
269         if(bm->edar) MEM_freeN(bm->edar);
270         if(bm->lpar) MEM_freeN(bm->lpar);
271         if(bm->plar) MEM_freeN(bm->plar);
272
273         /*zero out pointers*/
274         bm->vtar = NULL;
275         bm->edar = NULL;
276         bm->lpar = NULL;
277         bm->plar = NULL;
278         bm->vtarlen = bm->edarlen = bm->lparlen = bm->plarlen = 0;
279
280         /*compute normals, clear temp flags and flush selections*/
281         BM_Compute_Normals(bm);
282         BM_SelectMode_Flush(bm);
283 }