Style Cleanup
[blender.git] / source / blender / bmesh / intern / bmesh_construct.c
1 /*
2  * ***** BEGIN GPL LICENSE BLOCK *****
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License
6  * as published by the Free Software Foundation; either version 2
7  * of the License, or (at your option) any later version.
8  * about this.
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) 2007 Blender Foundation.
20  * All rights reserved.
21  *
22  * The Original Code is: all of this file.
23  *
24  * Contributor(s): Geoffrey Bantle.
25  *
26  * ***** END GPL LICENSE BLOCK *****
27  */
28
29 /** \file blender/bmesh/intern/bmesh_construct.c
30  *  \ingroup bmesh
31  *
32  * BM construction functions.
33  */
34
35 #include "MEM_guardedalloc.h"
36
37 #include "BKE_customdata.h"
38 #include "BKE_utildefines.h"
39
40 #include "BLI_array.h"
41 #include "BLI_utildefines.h"
42
43 #include "DNA_meshdata_types.h"
44 #include "DNA_mesh_types.h"
45
46 #include "BLI_math.h"
47 #include "BLI_utildefines.h"
48
49 #include "bmesh.h"
50 #include "bmesh_private.h"
51
52 #include <math.h>
53 #include <stdio.h>
54 #include <string.h>
55
56 #define SELECT 1
57
58 /* prototypes */
59 static void bm_copy_loop_attributes(BMesh *source_mesh, BMesh *target_mesh,
60                                     const BMLoop *source_loop, BMLoop *target_loop);
61 #if 0
62
63 /*
64  * BM_CONSTRUCT.C
65  *
66  * This file contains functions for making and destroying
67  * individual elements like verts, edges and faces.
68  *
69  */
70
71 /*
72  * BMESH MAKE VERT
73  *
74  * Creates a new vertex and returns a pointer
75  * to it. If a pointer to an example vertex is
76  * passed in, it's custom data and properties
77  * will be copied to the new vertex.
78  *
79  */
80
81 BMVert *BM_Make_Vert(BMesh *bm, float co[3], BMVert *example)
82 {
83         BMVert *v = NULL;
84         v = bmesh_mv(bm, co);
85         if (example)
86                 CustomData_bmesh_copy_data(&bm->vdata, &bm->vdata, example->head.data, &v->head.data);
87         return v;
88 }
89
90 /*
91  * BMESH MAKE EDGE
92  *
93  * Creates a new edge betweeen two vertices and returns a
94  * pointer to it. If 'nodouble' equals 1, then a check is
95  * is done to make sure that an edge between those two vertices
96  * does not already exist. If it does, that edge is returned instead
97  * of creating a new one.
98  *
99  * If a new edge is created, and a pointer to an example edge is
100  * provided, it's custom data and properties will be copied to the
101  * new edge.
102  *
103  */
104
105 BMEdge *BM_Make_Edge(BMesh *bm, BMVert *v1, BMVert *v2, BMEdge *example, int nodouble)
106 {
107         BMEdge *e = NULL;
108         
109         if (nodouble) /* test if edge already exists. */
110                 e = BM_Edge_Exist(v1, v2);
111
112         if (!e) {
113                 e = bmesh_me(bm, v1, v2);
114
115                 if (example)
116                         CustomData_bmesh_copy_data(&bm->edata, &bm->edata, example->head.data, &e->head.data);
117         }
118         
119         return e;
120         
121 }
122 #endif
123
124 /*
125  * BMESH MAKE QUADTRIANGLE
126  *
127  * Creates a new quad or triangle from
128  * a list of 3 or 4 vertices. If nodouble
129  * equals 1, then a check is done to see
130  * if a face with these vertices already
131  * exists and returns it instead. If a pointer
132  * to an example face is provided, it's custom
133  * data and properties will be copied to the new
134  * face.
135  *
136  * Note that the winding of the face is determined
137  * by the order of the vertices in the vertex array
138  */
139
140 BMFace *BM_Make_Face_QuadTri(BMesh *bm,
141                              BMVert *v1, BMVert *v2, BMVert *v3, BMVert *v4,
142                              const BMFace *example, const int nodouble)
143 {
144         BMVert *vtar[4] = {v1, v2, v3, v4};
145         return BM_Make_Face_QuadTri_v(bm, vtar, v4 ? 4 : 3, example, nodouble);
146 }
147
148 /* remove the edge array bits from this. Its not really needed? */
149 BMFace *BM_Make_Face_QuadTri_v(BMesh *bm, BMVert **verts, int len, const BMFace *example, const int nodouble)
150 {
151         BMEdge *edar[4] = {NULL};
152         BMFace *f = NULL;
153         int overlap = 0;
154
155         edar[0] = BM_Edge_Exist(verts[0], verts[1]);
156         edar[1] = BM_Edge_Exist(verts[1], verts[2]);
157         if (len == 4) {
158                 edar[2] = BM_Edge_Exist(verts[2], verts[3]);
159                 edar[3] = BM_Edge_Exist(verts[3], verts[0]);
160         }
161         else {
162                 edar[2] = BM_Edge_Exist(verts[2], verts[0]);
163         }
164
165         if (nodouble) {
166                 /* check if face exists or overlaps */
167                 if (len == 4) {
168                         overlap = BM_Exist_Face_Overlaps(bm, verts, len, &f);
169                 }
170                 else {
171                         overlap = BM_Exist_Face_Overlaps(bm, verts, len, &f);
172                 }
173         }
174
175         /* make new face */
176         if ((!f) && (!overlap)) {
177                 if (!edar[0]) edar[0] = BM_Make_Edge(bm, verts[0], verts[1], NULL, FALSE);
178                 if (!edar[1]) edar[1] = BM_Make_Edge(bm, verts[1], verts[2], NULL, FALSE);
179                 if (len == 4) {
180                         if (!edar[2]) edar[2] = BM_Make_Edge(bm, verts[2], verts[3], NULL, FALSE);
181                         if (!edar[3]) edar[3] = BM_Make_Edge(bm, verts[3], verts[0], NULL, FALSE);
182                 }
183                 else {
184                         if (!edar[2]) edar[2] = BM_Make_Edge(bm, verts[2], verts[0], NULL, FALSE);
185                 }
186         
187                 f = BM_Make_Face(bm, verts, edar, len, FALSE);
188         
189                 if (example && f) {
190                         BM_Copy_Attributes(bm, bm, example, f);
191                 }
192         }
193
194         return f;
195 }
196
197
198 /* copies face data from shared adjacent faces */
199 void BM_Face_CopyShared(BMesh *bm, BMFace *f)
200 {
201         BMIter iter;
202         BMLoop *l, *l2;
203
204         if (!f) return;
205
206         l = BMIter_New(&iter, bm, BM_LOOPS_OF_FACE, f);
207         for ( ; l; l = BMIter_Step(&iter)) {
208                 l2 = l->radial_next;
209                 
210                 if (l2 && l2 != l) {
211                         if (l2->v == l->v) {
212                                 bm_copy_loop_attributes(bm, bm, l2, l);
213                         }
214                         else {
215                                 l2 = l2->next;
216                                 bm_copy_loop_attributes(bm, bm, l2, l);
217                         }
218                 }
219         }
220 }
221
222 /*
223  * BMESH MAKE NGON
224  *
225  * Attempts to make a new Ngon from a list of edges.
226  * If nodouble equals one, a check for overlaps or existing
227  *
228  * The edges are not required to be ordered, simply to to form
229  * a single closed loop as a whole
230  *
231  * Note that while this function will work fine when the edges
232  * are already sorted, if the edges are always going to be sorted,
233  * BM_Make_Face should be considered over this function as it
234  * avoids some unnecessary work.
235  */
236 BMFace *BM_Make_Ngon(BMesh *bm, BMVert *v1, BMVert *v2, BMEdge **edges, int len, int nodouble)
237 {
238         BMEdge **edges2 = NULL;
239         BLI_array_staticdeclare(edges2, BM_NGON_STACK_SIZE);
240         BMVert **verts = NULL, *v;
241         BLI_array_staticdeclare(verts, BM_NGON_STACK_SIZE);
242         BMFace *f = NULL;
243         BMEdge *e;
244         BMVert *ev1, *ev2;
245         int i, /* j, */ v1found, reverse;
246
247         /* this code is hideous, yeek.  I'll have to think about ways of
248          *  cleaning it up.  basically, it now combines the old BM_Make_Ngon
249          *  _and_ the old bmesh_mf functions, so its kindof smashed together
250          * - joeedh */
251
252         if (!len || !v1 || !v2 || !edges || !bm)
253                 return NULL;
254
255         /* put edges in correct order */
256         for (i = 0; i < len; i++) {
257                 bmesh_api_setflag(edges[i], _FLAG_MF);
258         }
259
260         ev1 = edges[0]->v1;
261         ev2 = edges[0]->v2;
262
263         if (v1 == ev2) {
264                 /* Swapping here improves performance and consistency of face
265                  * structure in the special case that the edges are already in
266                  * the correct order and winding */
267                 SWAP(BMVert *, ev1, ev2);
268         }
269
270         BLI_array_append(verts, ev1);
271         v = ev2;
272         e = edges[0];
273         do {
274                 BMEdge *e2 = e;
275
276                 BLI_array_append(verts, v);
277                 BLI_array_append(edges2, e);
278
279                 do {
280                         e2 = bmesh_disk_nextedge(e2, v);
281                         if (e2 != e && bmesh_api_getflag(e2, _FLAG_MF)) {
282                                 v = BM_OtherEdgeVert(e2, v);
283                                 break;
284                         }
285                 } while (e2 != e);
286
287                 if (e2 == e)
288                         goto err; /* the edges do not form a closed loop */
289
290                 e = e2;
291         } while (e != edges[0]);
292
293         if (BLI_array_count(edges2) != len) {
294                 goto err; /* we didn't use all edges in forming the boundary loop */
295         }
296
297         /* ok, edges are in correct order, now ensure they are going
298          * in the correct direction */
299         v1found = reverse = FALSE;
300         for (i = 0; i < len; i++) {
301                 if (BM_Vert_In_Edge(edges2[i], v1)) {
302                         /* see if v1 and v2 are in the same edge */
303                         if (BM_Vert_In_Edge(edges2[i], v2)) {
304                                 /* if v1 is shared by the *next* edge, then the winding
305                                  * is incorrect */
306                                 if (BM_Vert_In_Edge(edges2[(i + 1) % len], v1)) {
307                                         reverse = TRUE;
308                                         break;
309                                 }
310                         }
311
312                         v1found = TRUE;
313                 }
314
315                 if ((v1found == FALSE) && BM_Vert_In_Edge(edges2[i], v2)) {
316                         reverse = TRUE;
317                         break;
318                 }
319         }
320
321         if (reverse) {
322                 for (i = 0; i < len / 2; i++) {
323                         v = verts[i];
324                         verts[i] = verts[len - i - 1];
325                         verts[len - i - 1] = v;
326                 }
327         }
328
329         for (i = 0; i < len; i++) {
330                 edges2[i] = BM_Edge_Exist(verts[i], verts[(i + 1) % len]);
331                 if (!edges2[i]) {
332                         goto err;
333                 }
334         }
335
336         f = BM_Make_Face(bm, verts, edges2, len, nodouble);
337
338         /* clean up flags */
339         for (i = 0; i < len; i++) {
340                 bmesh_api_clearflag(edges2[i], _FLAG_MF);
341         }
342
343         BLI_array_free(verts);
344         BLI_array_free(edges2);
345
346         return f;
347
348 err:
349         for (i = 0; i < len; i++) {
350                 bmesh_api_clearflag(edges[i], _FLAG_MF);
351         }
352
353         BLI_array_free(verts);
354         BLI_array_free(edges2);
355
356         return NULL;
357 }
358
359
360 /* bmesh_make_face_from_face(BMesh *bm, BMFace *source, BMFace *target) */
361
362
363 /*
364  * REMOVE TAGGED XXX
365  *
366  * Called by operators to remove elements that they have marked for
367  * removal.
368  *
369  */
370
371 void BMO_remove_tagged_faces(BMesh *bm, const short oflag)
372 {
373         BMFace *f;
374         BMIter iter;
375
376         BM_ITER(f, &iter, bm, BM_FACES_OF_MESH, NULL) {
377                 if (BMO_TestFlag(bm, f, oflag)) {
378                         BM_Kill_Face(bm, f);
379                 }
380         }
381 }
382
383 void BMO_remove_tagged_edges(BMesh *bm, const short oflag)
384 {
385         BMEdge *e;
386         BMIter iter;
387
388         BM_ITER(e, &iter, bm, BM_EDGES_OF_MESH, NULL) {
389                 if (BMO_TestFlag(bm, e, oflag)) {
390                         BM_Kill_Edge(bm, e);
391                 }
392         }
393 }
394
395 void BMO_remove_tagged_verts(BMesh *bm, const short oflag)
396 {
397         BMVert *v;
398         BMIter iter;
399
400         BM_ITER(v, &iter, bm, BM_VERTS_OF_MESH, NULL) {
401                 if (BMO_TestFlag(bm, v, oflag)) {
402                         BM_Kill_Vert(bm, v);
403                 }
404         }
405 }
406
407 /*************************************************************/
408 /* you need to make remove tagged verts/edges/faces
409  * api functions that take a filter callback.....
410  * and this new filter type will be for opstack flags.
411  * This is because the BM_remove_taggedXXX functions bypass iterator API.
412  *  - Ops dont care about 'UI' considerations like selection state, hide state, ect.
413  *    If you want to work on unhidden selections for instance,
414  *    copy output from a 'select context' operator to another operator....
415  */
416
417 static void bmo_remove_tagged_context_verts(BMesh *bm, const short oflag)
418 {
419         BMVert *v;
420         BMEdge *e;
421         BMLoop *f;
422
423         BMIter verts;
424         BMIter edges;
425         BMIter faces;
426
427         for (v = BMIter_New(&verts, bm, BM_VERTS_OF_MESH, bm); v; v = BMIter_Step(&verts)) {
428                 if (BMO_TestFlag(bm, (BMHeader *)v, oflag)) {
429                         /* Visit edge */
430                         for (e = BMIter_New(&edges, bm, BM_EDGES_OF_VERT, v); e; e = BMIter_Step(&edges))
431                                 BMO_SetFlag(bm, (BMHeader *)e, oflag);
432                         /* Visit face */
433                         for (f = BMIter_New(&faces, bm, BM_FACES_OF_VERT, v); f; f = BMIter_Step(&faces))
434                                 BMO_SetFlag(bm, (BMHeader *)f, oflag);
435                 }
436         }
437
438         BMO_remove_tagged_faces(bm, oflag);
439         BMO_remove_tagged_edges(bm, oflag);
440         BMO_remove_tagged_verts(bm, oflag);
441 }
442
443 static void bmo_remove_tagged_context_edges(BMesh *bm, const short oflag)
444 {
445         BMEdge *e;
446         BMFace *f;
447
448         BMIter edges;
449         BMIter faces;
450
451         for (e = BMIter_New(&edges, bm, BM_EDGES_OF_MESH, bm); e; e = BMIter_Step(&edges)) {
452                 if (BMO_TestFlag(bm, (BMHeader *)e, oflag)) {
453                         for (f = BMIter_New(&faces, bm, BM_FACES_OF_EDGE, e); f; f = BMIter_Step(&faces)) {
454                                 BMO_SetFlag(bm, (BMHeader *)f, oflag);
455                         }
456                 }
457         }
458         BMO_remove_tagged_faces(bm, oflag);
459         BMO_remove_tagged_edges(bm, oflag);
460 }
461
462 #define DEL_WIREVERT    (1 << 10)
463
464 /* warning, oflag applies to different types in some contexts,
465  * not just the type being removed */
466 void BMO_remove_tagged_context(BMesh *bm, const short oflag, const int type)
467 {
468         BMVert *v;
469         BMEdge *e;
470         BMFace *f;
471
472         BMIter verts;
473         BMIter edges;
474         BMIter faces;
475
476         switch (type) {
477                 case DEL_VERTS:
478                 {
479                         bmo_remove_tagged_context_verts(bm, oflag);
480
481                         break;
482                 }
483                 case DEL_EDGES:
484                 {
485                         /* flush down to vert */
486                         for (e = BMIter_New(&edges, bm, BM_EDGES_OF_MESH, bm); e; e = BMIter_Step(&edges)) {
487                                 if (BMO_TestFlag(bm, (BMHeader *)e, oflag)) {
488                                         BMO_SetFlag(bm, (BMHeader *)(e->v1), oflag);
489                                         BMO_SetFlag(bm, (BMHeader *)(e->v2), oflag);
490                                 }
491                         }
492                         bmo_remove_tagged_context_edges(bm, oflag);
493                         /* remove loose vertice */
494                         for (v = BMIter_New(&verts, bm, BM_VERTS_OF_MESH, bm); v; v = BMIter_Step(&verts)) {
495                                 if (BMO_TestFlag(bm, (BMHeader *)v, oflag) && (!(v->e)))
496                                         BMO_SetFlag(bm, (BMHeader *)v, DEL_WIREVERT);
497                         }
498                         BMO_remove_tagged_verts(bm, DEL_WIREVERT);
499
500                         break;
501                 }
502                 case DEL_EDGESFACES:
503                 {
504                         bmo_remove_tagged_context_edges(bm, oflag);
505
506                         break;
507                 }
508                 case DEL_ONLYFACES:
509                 {
510                         BMO_remove_tagged_faces(bm, oflag);
511
512                         break;
513                 }
514                 case DEL_ONLYTAGGED:
515                 {
516                         BMO_remove_tagged_faces(bm, oflag);
517                         BMO_remove_tagged_edges(bm, oflag);
518                         BMO_remove_tagged_verts(bm, oflag);
519
520                         break;
521                 }
522                 case DEL_FACES:
523                 {
524                         /* go through and mark all edges and all verts of all faces for delet */
525                         for (f = BMIter_New(&faces, bm, BM_FACES_OF_MESH, bm); f; f = BMIter_Step(&faces)) {
526                                 if (BMO_TestFlag(bm, (BMHeader *)f, oflag)) {
527                                         for (e = BMIter_New(&edges, bm, BM_EDGES_OF_FACE, f); e; e = BMIter_Step(&edges))
528                                                 BMO_SetFlag(bm, (BMHeader *)e, oflag);
529                                         for (v = BMIter_New(&verts, bm, BM_VERTS_OF_FACE, f); v; v = BMIter_Step(&verts))
530                                                 BMO_SetFlag(bm, (BMHeader *)v, oflag);
531                                 }
532                         }
533                         /* now go through and mark all remaining faces all edges for keeping */
534                         for (f = BMIter_New(&faces, bm, BM_FACES_OF_MESH, bm); f; f = BMIter_Step(&faces)) {
535                                 if (!BMO_TestFlag(bm, (BMHeader *)f, oflag)) {
536                                         for (e = BMIter_New(&edges, bm, BM_EDGES_OF_FACE, f); e; e = BMIter_Step(&edges)) {
537                                                 BMO_ClearFlag(bm, (BMHeader *)e, oflag);
538                                         }
539                                         for (v = BMIter_New(&verts, bm, BM_VERTS_OF_FACE, f); v; v = BMIter_Step(&verts)) {
540                                                 BMO_ClearFlag(bm, (BMHeader *)v, oflag);
541                                         }
542                                 }
543                         }
544                         /* also mark all the vertices of remaining edges for keeping */
545                         for (e = BMIter_New(&edges, bm, BM_EDGES_OF_MESH, bm); e; e = BMIter_Step(&edges)) {
546                                 if (!BMO_TestFlag(bm, (BMHeader *)e, oflag)) {
547                                         BMO_ClearFlag(bm, (BMHeader *)e->v1, oflag);
548                                         BMO_ClearFlag(bm, (BMHeader *)e->v2, oflag);
549                                 }
550                         }
551                         /* now delete marked face */
552                         BMO_remove_tagged_faces(bm, oflag);
553                         /* delete marked edge */
554                         BMO_remove_tagged_edges(bm, oflag);
555                         /* remove loose vertice */
556                         BMO_remove_tagged_verts(bm, oflag);
557
558                         break;
559                 }
560                 case DEL_ALL:
561                 {
562                         /* does this option even belong in here? */
563                         for (f = BMIter_New(&faces, bm, BM_FACES_OF_MESH, bm); f; f = BMIter_Step(&faces))
564                                 BMO_SetFlag(bm, (BMHeader *)f, oflag);
565                         for (e = BMIter_New(&edges, bm, BM_EDGES_OF_MESH, bm); e; e = BMIter_Step(&edges))
566                                 BMO_SetFlag(bm, (BMHeader *)e, oflag);
567                         for (v = BMIter_New(&verts, bm, BM_VERTS_OF_MESH, bm); v; v = BMIter_Step(&verts))
568                                 BMO_SetFlag(bm, (BMHeader *)v, oflag);
569
570                         BMO_remove_tagged_faces(bm, oflag);
571                         BMO_remove_tagged_edges(bm, oflag);
572                         BMO_remove_tagged_verts(bm, oflag);
573
574                         break;
575                 }
576         }
577 }
578 /*************************************************************/
579
580
581
582
583
584
585
586 static void bm_copy_vert_attributes(BMesh *source_mesh, BMesh *target_mesh,
587                                     const BMVert *source_vertex, BMVert *target_vertex)
588 {
589         if ((source_mesh == target_mesh) && (source_vertex == target_vertex)) {
590                 return;
591         }
592         copy_v3_v3(target_vertex->no, source_vertex->no);
593         CustomData_bmesh_free_block(&target_mesh->vdata, &target_vertex->head.data);
594         CustomData_bmesh_copy_data(&source_mesh->vdata, &target_mesh->vdata,
595                                    source_vertex->head.data, &target_vertex->head.data);
596 }
597
598 static void bm_copy_edge_attributes(BMesh *source_mesh, BMesh *target_mesh,
599                                     const BMEdge *source_edge, BMEdge *target_edge)
600 {
601         if ((source_mesh == target_mesh) && (source_edge == target_edge)) {
602                 return;
603         }
604         CustomData_bmesh_free_block(&target_mesh->edata, &target_edge->head.data);
605         CustomData_bmesh_copy_data(&source_mesh->edata, &target_mesh->edata,
606                                    source_edge->head.data, &target_edge->head.data);
607 }
608
609 static void bm_copy_loop_attributes(BMesh *source_mesh, BMesh *target_mesh,
610                                     const BMLoop *source_loop, BMLoop *target_loop)
611 {
612         if ((source_mesh == target_mesh) && (source_loop == target_loop)) {
613                 return;
614         }
615         CustomData_bmesh_free_block(&target_mesh->ldata, &target_loop->head.data);
616         CustomData_bmesh_copy_data(&source_mesh->ldata, &target_mesh->ldata,
617                                    source_loop->head.data, &target_loop->head.data);
618 }
619
620 static void bm_copy_face_attributes(BMesh *source_mesh, BMesh *target_mesh,
621                                     const BMFace *source_face, BMFace *target_face)
622 {
623         if ((source_mesh == target_mesh) && (source_face == target_face)) {
624                 return;
625         }
626         copy_v3_v3(target_face->no, source_face->no);
627         CustomData_bmesh_free_block(&target_mesh->pdata, &target_face->head.data);
628         CustomData_bmesh_copy_data(&source_mesh->pdata, &target_mesh->pdata,
629                                    source_face->head.data, &target_face->head.data);
630         target_face->mat_nr = source_face->mat_nr;
631 }
632
633 /* BMESH_TODO: Special handling for hide flags? */
634
635 void BM_Copy_Attributes(BMesh *source_mesh, BMesh *target_mesh, const void *source, void *target)
636 {
637         const BMHeader *sheader = source;
638         BMHeader *theader = target;
639         
640         if (sheader->htype != theader->htype)
641                 return;
642
643         /* First we copy select */
644         if (BM_Selected(source_mesh, source)) BM_Select(target_mesh, target, TRUE);
645         
646         /* Now we copy flags */
647         theader->hflag = sheader->hflag;
648         
649         /* Copy specific attributes */
650         if (theader->htype == BM_VERT)
651                 bm_copy_vert_attributes(source_mesh, target_mesh, (const BMVert *)source, (BMVert *)target);
652         else if (theader->htype == BM_EDGE)
653                 bm_copy_edge_attributes(source_mesh, target_mesh, (const BMEdge *)source, (BMEdge *)target);
654         else if (theader->htype == BM_LOOP)
655                 bm_copy_loop_attributes(source_mesh, target_mesh, (const BMLoop *)source, (BMLoop *)target);
656         else if (theader->htype == BM_FACE)
657                 bm_copy_face_attributes(source_mesh, target_mesh, (const BMFace *)source, (BMFace *)target);
658 }
659
660 BMesh *BM_Copy_Mesh(BMesh *bmold)
661 {
662         BMesh *bm;
663         BMVert *v, *v2, **vtable = NULL;
664         BMEdge *e, *e2, **edges = NULL, **etable = NULL;
665         BLI_array_declare(edges);
666         BMLoop *l, /* *l2, */ **loops = NULL;
667         BLI_array_declare(loops);
668         BMFace *f, *f2, **ftable = NULL;
669         BMEditSelection *ese;
670         BMIter iter, liter;
671         int allocsize[4] = {512, 512, 2048, 512};
672         int i, j;
673
674         /* allocate a bmesh */
675         bm = BM_Make_Mesh(bmold->ob, allocsize);
676
677         CustomData_copy(&bmold->vdata, &bm->vdata, CD_MASK_BMESH, CD_CALLOC, 0);
678         CustomData_copy(&bmold->edata, &bm->edata, CD_MASK_BMESH, CD_CALLOC, 0);
679         CustomData_copy(&bmold->ldata, &bm->ldata, CD_MASK_BMESH, CD_CALLOC, 0);
680         CustomData_copy(&bmold->pdata, &bm->pdata, CD_MASK_BMESH, CD_CALLOC, 0);
681
682         CustomData_bmesh_init_pool(&bm->vdata, allocsize[0]);
683         CustomData_bmesh_init_pool(&bm->edata, allocsize[1]);
684         CustomData_bmesh_init_pool(&bm->ldata, allocsize[2]);
685         CustomData_bmesh_init_pool(&bm->pdata, allocsize[3]);
686
687         vtable = MEM_mallocN(sizeof(BMVert *) * bmold->totvert, "BM_Copy_Mesh vtable");
688         etable = MEM_mallocN(sizeof(BMEdge *) * bmold->totedge, "BM_Copy_Mesh etable");
689         ftable = MEM_mallocN(sizeof(BMFace *) * bmold->totface, "BM_Copy_Mesh ftable");
690
691         v = BMIter_New(&iter, bmold, BM_VERTS_OF_MESH, NULL);
692         for (i = 0; v; v = BMIter_Step(&iter), i++) {
693                 v2 = BM_Make_Vert(bm, v->co, NULL); /* copy between meshes so cant use 'example' argument */
694                 BM_Copy_Attributes(bmold, bm, v, v2);
695                 vtable[i] = v2;
696                 BM_SetIndex(v, i); /* set_inline */
697                 BM_SetIndex(v2, i); /* set_inline */
698         }
699         bmold->elem_index_dirty &= ~BM_VERT;
700         bm->elem_index_dirty &= ~BM_VERT;
701
702         /* safety check */
703         BLI_assert(i == bmold->totvert);
704         
705         e = BMIter_New(&iter, bmold, BM_EDGES_OF_MESH, NULL);
706         for (i = 0; e; e = BMIter_Step(&iter), i++) {
707                 e2 = BM_Make_Edge(bm,
708                                   vtable[BM_GetIndex(e->v1)],
709                                   vtable[BM_GetIndex(e->v2)],
710                                   e, FALSE);
711
712                 BM_Copy_Attributes(bmold, bm, e, e2);
713                 etable[i] = e2;
714                 BM_SetIndex(e, i); /* set_inline */
715                 BM_SetIndex(e2, i); /* set_inline */
716         }
717         bmold->elem_index_dirty &= ~BM_EDGE;
718         bm->elem_index_dirty &= ~BM_EDGE;
719
720         /* safety check */
721         BLI_assert(i == bmold->totedge);
722         
723         f = BMIter_New(&iter, bmold, BM_FACES_OF_MESH, NULL);
724         for (i = 0; f; f = BMIter_Step(&iter), i++) {
725                 BM_SetIndex(f, i); /* set_inline */
726
727                 BLI_array_empty(loops);
728                 BLI_array_empty(edges);
729                 BLI_array_growitems(loops, f->len);
730                 BLI_array_growitems(edges, f->len);
731
732                 l = BMIter_New(&liter, bmold, BM_LOOPS_OF_FACE, f);
733                 for (j = 0; j < f->len; j++, l = BMIter_Step(&liter)) {
734                         loops[j] = l;
735                         edges[j] = etable[BM_GetIndex(l->e)];
736                 }
737
738                 v = vtable[BM_GetIndex(loops[0]->v)];
739                 v2 = vtable[BM_GetIndex(loops[1]->v)];
740
741                 if (!bmesh_verts_in_edge(v, v2, edges[0])) {
742                         v = vtable[BM_GetIndex(loops[BLI_array_count(loops) - 1]->v)];
743                         v2 = vtable[BM_GetIndex(loops[0]->v)];
744                 }
745
746                 f2 = BM_Make_Ngon(bm, v, v2, edges, f->len, FALSE);
747                 if (!f2)
748                         continue;
749                 /* use totface incase adding some faces fails */
750                 BM_SetIndex(f2, (bm->totface - 1)); /* set_inline */
751
752                 ftable[i] = f2;
753
754                 BM_Copy_Attributes(bmold, bm, f, f2);
755                 copy_v3_v3(f2->no, f->no);
756
757                 l = BMIter_New(&liter, bm, BM_LOOPS_OF_FACE, f2);
758                 for (j = 0; j < f->len; j++, l = BMIter_Step(&liter)) {
759                         BM_Copy_Attributes(bmold, bm, loops[j], l);
760                 }
761
762                 if (f == bmold->act_face) bm->act_face = f2;
763         }
764         bmold->elem_index_dirty &= ~BM_FACE;
765         bm->elem_index_dirty &= ~BM_FACE;
766
767         /* safety check */
768         BLI_assert(i == bmold->totface);
769
770         /* copy over edit selection history */
771         for (ese = bmold->selected.first; ese; ese = ese->next) {
772                 void *ele = NULL;
773
774                 if (ese->htype == BM_VERT)
775                         ele = vtable[BM_GetIndex(ese->data)];
776                 else if (ese->htype == BM_EDGE)
777                         ele = etable[BM_GetIndex(ese->data)];
778                 else if (ese->htype == BM_FACE) {
779                         ele = ftable[BM_GetIndex(ese->data)];
780                 }
781                 else {
782                         BLI_assert(0);
783                 }
784                 
785                 if (ele)
786                         BM_store_selection(bm, ele);
787         }
788
789         MEM_freeN(etable);
790         MEM_freeN(vtable);
791         MEM_freeN(ftable);
792
793         BLI_array_free(loops);
794         BLI_array_free(edges);
795
796         return bm;
797 }
798
799 /* ME -> BM */
800 char BM_Vert_Flag_From_MEFlag(const char  meflag)
801 {
802     return ( ((meflag & SELECT)       ? BM_SELECT : 0) |
803              ((meflag & ME_HIDE)      ? BM_HIDDEN : 0)
804              );
805 }
806 char BM_Edge_Flag_From_MEFlag(const short meflag)
807 {
808         return ( ((meflag & SELECT)       ? BM_SELECT : 0) |
809                  ((meflag & ME_SEAM)      ? BM_SEAM   : 0) |
810                  ((meflag & ME_SHARP)     ? BM_SHARP  : 0) |
811                  ((meflag & ME_HIDE)      ? BM_HIDDEN : 0)
812                  );
813 }
814 char BM_Face_Flag_From_MEFlag(const char  meflag)
815 {
816     return ( ((meflag & ME_FACE_SEL)  ? BM_SELECT : 0) |
817              ((meflag & ME_SMOOTH)    ? BM_SMOOTH : 0) |
818              ((meflag & ME_HIDE)      ? BM_HIDDEN : 0)
819              );
820 }
821
822 /* BM -> ME */
823 char  BM_Vert_Flag_To_MEFlag(BMVert *eve)
824 {
825     const char hflag = eve->head.hflag;
826
827     return ( ((hflag & BM_SELECT)  ? SELECT  : 0) |
828              ((hflag & BM_HIDDEN)  ? ME_HIDE : 0)
829              );
830 }
831 short BM_Edge_Flag_To_MEFlag(BMEdge *eed)
832 {
833         const char hflag = eed->head.hflag;
834
835         return ( ((hflag & BM_SELECT)       ? SELECT    : 0) |
836                  ((hflag & BM_SEAM)         ? ME_SEAM   : 0) |
837                  ((hflag & BM_SHARP)        ? ME_SHARP  : 0) |
838                  ((hflag & BM_HIDDEN)       ? ME_HIDE   : 0) |
839                  ((BM_Wire_Edge(NULL, eed)) ? ME_LOOSEEDGE : 0) | /* not typical */
840                  (ME_EDGEDRAW | ME_EDGERENDER)
841                  );
842 }
843 char  BM_Face_Flag_To_MEFlag(BMFace *efa)
844 {
845     const char hflag = efa->head.hflag;
846
847     return ( ((hflag & BM_SELECT) ? ME_FACE_SEL : 0) |
848              ((hflag & BM_SMOOTH) ? ME_SMOOTH   : 0) |
849              ((hflag & BM_HIDDEN) ? ME_HIDE     : 0)
850              );
851 }
852
853 /* unused, type spesific functions below */
854 #if 0
855 /*
856   BM FLAGS TO ME FLAGS
857
858   Returns the flags stored in element,
859   which much be either a BMVert, BMEdge,
860   or BMFace, converted to mesh flags.
861  */
862 short BMFlags_To_MEFlags(void *element)
863 {
864         const char src_htype = ((BMHeader *)element)->htype;
865
866         if (src_htype == BM_FACE) {
867                 return BM_Face_Flag_To_MEFlag(element);
868         }
869         else if (src_htype == BM_EDGE) {
870                 return BM_Edge_Flag_To_MEFlag(element);
871         }
872         else if (src_htype == BM_VERT) {
873                 return BM_Vert_Flag_To_MEFlag(element);
874         }
875         else {
876                 return 0;
877         }
878 }
879
880 /*
881   BM FLAGS TO ME FLAGS
882
883   Returns the flags stored in element,
884   which much be either a MVert, MEdge,
885   or MPoly, converted to mesh flags.
886   type must be either BM_VERT, BM_EDGE,
887   or BM_FACE.
888  */
889 char MEFlags_To_BMFlags(const short hflag, const char htype)
890 {
891         if (htype == BM_FACE) {
892                 return BM_Face_Flag_From_MEFlag(hflag);
893         }
894         else if (htype == BM_EDGE) {
895                 return BM_Edge_Flag_From_MEFlag(hflag);
896         }
897         else if (htype == BM_VERT) {
898                 return BM_Vert_Flag_From_MEFlag(hflag);
899         }
900         else {
901                 return 0;
902         }
903 }
904 #endif