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