2
* ***** BEGIN GPL LICENSE BLOCK *****
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.
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.
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.
18
* The Original Code is Copyright (C) 2005 by the Blender Foundation.
19
* All rights reserved.
21
* Contributor(s): Joseph Eagar
23
* ***** END GPL LICENSE BLOCK *****
27
/** \file blender/blenkernel/intern/modifiers_bmesh.c
33
#include "MEM_guardedalloc.h"
35
#include "DNA_object_types.h"
37
#include "BLI_array.h"
39
#include "BKE_DerivedMesh.h"
40
#include "BKE_bmesh.h"
41
#include "BKE_tessmesh.h"
43
/* main function for copying DerivedMesh data into BMesh */
44
void DM_to_bmesh_ex(DerivedMesh *dm, BMesh *bm)
48
MPoly /* *mpoly, */ /* UNUSED */ *mp;
50
BMVert *v, **vtable, **verts = NULL;
51
BMEdge *e, **etable, **edges = NULL;
52
float has_face_normals;
55
BLI_array_declare(verts);
56
BLI_array_declare(edges);
57
int i, j, k, totvert, totedge /* , totface */ /* UNUSED */ ;
59
/*merge custom data layout*/
60
CustomData_bmesh_merge(&dm->vertData, &bm->vdata, CD_MASK_DERIVEDMESH, CD_CALLOC, bm, BM_VERT);
61
CustomData_bmesh_merge(&dm->edgeData, &bm->edata, CD_MASK_DERIVEDMESH, CD_CALLOC, bm, BM_EDGE);
62
CustomData_bmesh_merge(&dm->loopData, &bm->ldata, CD_MASK_DERIVEDMESH, CD_CALLOC, bm, BM_LOOP);
63
CustomData_bmesh_merge(&dm->polyData, &bm->pdata, CD_MASK_DERIVEDMESH, CD_CALLOC, bm, BM_FACE);
65
totvert = dm->getNumVerts(dm);
66
totedge = dm->getNumEdges(dm);
67
/* totface = dm->getNumPolys(dm); */ /* UNUSED */
69
/* add crease layer */
70
BM_data_layer_add(bm, &bm->edata, CD_CREASE);
71
/* add bevel weight layers */
72
BM_data_layer_add(bm, &bm->edata, CD_BWEIGHT);
73
BM_data_layer_add(bm, &bm->vdata, CD_BWEIGHT);
75
vtable = MEM_callocN(sizeof(void**) * totvert, "vert table in BMDM_Copy");
76
etable = MEM_callocN(sizeof(void**) * totedge, "edge table in BMDM_Copy");
79
mv = mvert = dm->dupVertArray(dm);
80
for (i = 0; i < totvert; i++, mv++) {
81
v = BM_vert_create(bm, mv->co, NULL);
82
normal_short_to_float_v3(v->no, mv->no);
83
v->head.hflag = BM_vert_flag_from_mflag(mv->flag);
85
CustomData_to_bmesh_block(&dm->vertData, &bm->vdata, i, &v->head.data);
87
/* add bevel weight */
88
BM_elem_float_data_set(&bm->vdata, v, CD_BWEIGHT, (float)mv->bweight / 255.0f);
94
me = medge = dm->dupEdgeArray(dm);
95
for (i = 0; i < totedge; i++, me++) {
96
e = BM_edge_create(bm, vtable[me->v1], vtable[me->v2], NULL, FALSE);
98
e->head.hflag = BM_edge_flag_from_mflag(me->flag);
100
CustomData_to_bmesh_block(&dm->edgeData, &bm->edata, i, &e->head.data);
104
BM_elem_float_data_set(&bm->edata, e, CD_CREASE, (float)me->crease / 255.0f);
105
/* add bevel weight */
106
BM_elem_float_data_set(&bm->edata, e, CD_BWEIGHT, (float)me->bweight / 255.0f);
111
mp = dm->getPolyArray(dm);
112
mloop = dm->getLoopArray(dm);
113
has_face_normals = CustomData_has_layer(&dm->polyData, CD_NORMAL);
114
for (i = 0; i < dm->numPolyData; i++, mp++) {
117
BLI_array_empty(verts);
118
BLI_array_empty(edges);
120
BLI_array_growitems(verts, mp->totloop);
121
BLI_array_growitems(edges, mp->totloop);
123
ml = mloop + mp->loopstart;
124
for (j = 0; j < mp->totloop; j++, ml++) {
126
verts[j] = vtable[ml->v];
127
edges[j] = etable[ml->e];
130
f = BM_face_create_ngon(bm, verts[0], verts[1], edges, mp->totloop, FALSE);
135
f->head.hflag = BM_face_flag_from_mflag(mp->flag);
136
f->mat_nr = mp->mat_nr;
138
l = BM_iter_new(&liter, bm, BM_LOOPS_OF_FACE, f);
140
for (k = mp->loopstart; l; l = BM_iter_step(&liter), k++) {
141
CustomData_to_bmesh_block(&dm->loopData, &bm->ldata, k, &l->head.data);
144
CustomData_to_bmesh_block(&dm->polyData, &bm->pdata, i, &f->head.data);
146
if (has_face_normals) {
149
fno = CustomData_bmesh_get(&bm->pdata, &f->head.data, CD_NORMAL);
150
copy_v3_v3(f->no, fno);
157
BLI_array_free(verts);
158
BLI_array_free(edges);
161
/* converts a cddm to a BMEditMesh. if existing is non-NULL, the
162
* new geometry will be put in there.*/
163
BMEditMesh *DM_to_editbmesh(DerivedMesh *dm, BMEditMesh *existing, int do_tessellate)
165
BMEditMesh *em = existing;
172
bm = BM_mesh_create(&bm_mesh_allocsize_default);
175
DM_to_bmesh_ex(dm, bm);
178
em = BMEdit_Create(bm, do_tessellate);
182
BMEdit_RecalcTessellation(em);
189
BMesh *DM_to_bmesh(DerivedMesh *dm)
193
bm = BM_mesh_create(&bm_mesh_allocsize_default);
195
DM_to_bmesh_ex(dm, bm);