Blender  V2.93
bmesh_mesh_duplicate.c
Go to the documentation of this file.
1 /*
2  * This program is free software; you can redistribute it and/or
3  * modify it under the terms of the GNU General Public License
4  * as published by the Free Software Foundation; either version 2
5  * of the License, or (at your option) any later version.
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10  * GNU General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License
13  * along with this program; if not, write to the Free Software Foundation,
14  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
15  */
16 
23 #include "DNA_object_types.h"
24 
25 #include "MEM_guardedalloc.h"
26 
27 #include "BLI_alloca.h"
28 #include "BLI_math_vector.h"
29 
30 #include "bmesh.h"
31 #include "intern/bmesh_private.h" /* for element checking */
32 
33 static BMVert *bm_vert_copy(BMesh *bm_src, BMesh *bm_dst, BMVert *v_src)
34 {
35  BMVert *v_dst = BM_vert_create(bm_dst, v_src->co, NULL, BM_CREATE_SKIP_CD);
36  BM_elem_attrs_copy(bm_src, bm_dst, v_src, v_dst);
37  return v_dst;
38 }
39 
41  BMesh *bm_dst,
42  BMEdge *e_src,
43  BMVert **verts_dst)
44 {
45  BMVert *e_dst_v1 = verts_dst[BM_elem_index_get(e_src->v1)];
46  BMVert *e_dst_v2 = verts_dst[BM_elem_index_get(e_src->v2)];
47  BMEdge *e_dst = BM_edge_create(bm_dst, e_dst_v1, e_dst_v2, NULL, BM_CREATE_SKIP_CD);
48  BM_elem_attrs_copy(bm_src, bm_dst, e_src, e_dst);
49  return e_dst;
50 }
51 
53  BMesh *bm_src, BMesh *bm_dst, BMFace *f_src, BMVert **verts_dst, BMEdge **edges_dst)
54 {
55  BMFace *f_dst;
56  BMVert **vtar = BLI_array_alloca(vtar, f_src->len);
57  BMEdge **edar = BLI_array_alloca(edar, f_src->len);
58  BMLoop *l_iter_src, *l_iter_dst, *l_first_src;
59  int i;
60 
61  l_first_src = BM_FACE_FIRST_LOOP(f_src);
62 
63  /* Lookup verts & edges. */
64  l_iter_src = l_first_src;
65  i = 0;
66  do {
67  vtar[i] = verts_dst[BM_elem_index_get(l_iter_src->v)];
68  edar[i] = edges_dst[BM_elem_index_get(l_iter_src->e)];
69  i++;
70  } while ((l_iter_src = l_iter_src->next) != l_first_src);
71 
72  /* Create new face. */
73  f_dst = BM_face_create(bm_dst, vtar, edar, f_src->len, NULL, BM_CREATE_SKIP_CD);
74 
75  /* Copy attributes. */
76  BM_elem_attrs_copy(bm_src, bm_dst, f_src, f_dst);
77 
78  /* Copy per-loop custom data. */
79  l_iter_src = l_first_src;
80  l_iter_dst = BM_FACE_FIRST_LOOP(f_dst);
81  do {
82  BM_elem_attrs_copy(bm_src, bm_dst, l_iter_src, l_iter_dst);
83  } while ((void)(l_iter_dst = l_iter_dst->next), (l_iter_src = l_iter_src->next) != l_first_src);
84 
85  return f_dst;
86 }
87 
92  BMesh *bm_dst,
93  BMVert **verts_src,
94  uint verts_src_len,
95  BMEdge **edges_src,
96  uint edges_src_len,
97  BMFace **faces_src,
98  uint faces_src_len)
99 {
100  /* Vertices. */
101  BMVert **verts_dst = MEM_mallocN(sizeof(*verts_dst) * verts_src_len, __func__);
102  for (uint i = 0; i < verts_src_len; i++) {
103  BMVert *v_src = verts_src[i];
104  BM_elem_index_set(v_src, i); /* set_dirty! */
105 
106  BMVert *v_dst = bm_vert_copy(bm_src, bm_dst, v_src);
107  BM_elem_index_set(v_dst, i); /* set_ok */
108  verts_dst[i] = v_dst;
109  }
110  bm_src->elem_index_dirty |= BM_VERT;
111  bm_dst->elem_index_dirty &= ~BM_VERT;
112 
113  /* Edges. */
114  BMEdge **edges_dst = MEM_mallocN(sizeof(*edges_dst) * edges_src_len, __func__);
115  for (uint i = 0; i < edges_src_len; i++) {
116  BMEdge *e_src = edges_src[i];
117  BM_elem_index_set(e_src, i); /* set_dirty! */
118 
119  BMEdge *e_dst = bm_edge_copy_with_arrays(bm_src, bm_dst, e_src, verts_dst);
120  BM_elem_index_set(e_dst, i);
121  edges_dst[i] = e_dst;
122  }
123  bm_src->elem_index_dirty |= BM_EDGE;
124  bm_dst->elem_index_dirty &= ~BM_EDGE;
125 
126  /* Faces. */
127  for (uint i = 0; i < faces_src_len; i++) {
128  BMFace *f_src = faces_src[i];
129  BMFace *f_dst = bm_face_copy_with_arrays(bm_src, bm_dst, f_src, verts_dst, edges_dst);
130  BM_elem_index_set(f_dst, i);
131  }
132  bm_dst->elem_index_dirty &= ~BM_FACE;
133 
134  /* Cleanup. */
135  MEM_freeN(verts_dst);
136  MEM_freeN(edges_dst);
137 }
#define BLI_array_alloca(arr, realsize)
Definition: BLI_alloca.h:36
unsigned int uint
Definition: BLI_sys_types.h:83
Object is a sort of wrapper for general info.
Read Guarded memory(de)allocation.
@ BM_FACE
Definition: bmesh_class.h:386
@ BM_VERT
Definition: bmesh_class.h:383
@ BM_EDGE
Definition: bmesh_class.h:384
#define BM_FACE_FIRST_LOOP(p)
Definition: bmesh_class.h:553
void BM_elem_attrs_copy(BMesh *bm_src, BMesh *bm_dst, const void *ele_src, void *ele_dst)
BMVert * BM_vert_create(BMesh *bm, const float co[3], const BMVert *v_example, const eBMCreateFlag create_flag)
Main function for creating a new vertex.
Definition: bmesh_core.c:58
BMFace * BM_face_create(BMesh *bm, BMVert **verts, BMEdge **edges, const int len, const BMFace *f_example, const eBMCreateFlag create_flag)
Definition: bmesh_core.c:428
BMEdge * BM_edge_create(BMesh *bm, BMVert *v1, BMVert *v2, const BMEdge *e_example, const eBMCreateFlag create_flag)
Main function for creating a new edge.
Definition: bmesh_core.c:147
@ BM_CREATE_SKIP_CD
Definition: bmesh_core.h:33
#define BM_elem_index_get(ele)
Definition: bmesh_inline.h:124
#define BM_elem_index_set(ele, index)
Definition: bmesh_inline.h:125
static BMFace * bm_face_copy_with_arrays(BMesh *bm_src, BMesh *bm_dst, BMFace *f_src, BMVert **verts_dst, BMEdge **edges_dst)
void BM_mesh_copy_arrays(BMesh *bm_src, BMesh *bm_dst, BMVert **verts_src, uint verts_src_len, BMEdge **edges_src, uint edges_src_len, BMFace **faces_src, uint faces_src_len)
static BMEdge * bm_edge_copy_with_arrays(BMesh *bm_src, BMesh *bm_dst, BMEdge *e_src, BMVert **verts_dst)
static BMVert * bm_vert_copy(BMesh *bm_src, BMesh *bm_dst, BMVert *v_src)
void(* MEM_freeN)(void *vmemh)
Definition: mallocn.c:41
void *(* MEM_mallocN)(size_t len, const char *str)
Definition: mallocn.c:47
BMVert * v1
Definition: bmesh_class.h:134
BMVert * v2
Definition: bmesh_class.h:134
int len
Definition: bmesh_class.h:279
struct BMVert * v
Definition: bmesh_class.h:165
struct BMEdge * e
Definition: bmesh_class.h:176
struct BMLoop * next
Definition: bmesh_class.h:245
float co[3]
Definition: bmesh_class.h:99
char elem_index_dirty
Definition: bmesh_class.h:305