Blender V4.3
mesh_legacy_derived_mesh.cc
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2005 Blender Authors
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
5#include "BLI_math_vector.h"
6
7#include "DNA_mesh_types.h"
9
10#include "BKE_customdata.hh"
12
13/* -------------------------------------------------------------------- */
14
15static float *dm_getVertArray(DerivedMesh *dm)
16{
17 float(*positions)[3] = (float(*)[3])CustomData_get_layer_named_for_write(
18 &dm->vertData, CD_PROP_FLOAT3, "position", dm->getNumVerts(dm));
19
20 if (!positions) {
21 positions = (float(*)[3])CustomData_add_layer_named(
22 &dm->vertData, CD_PROP_FLOAT3, CD_SET_DEFAULT, dm->getNumVerts(dm), "position");
24 dm->copyVertArray(dm, positions);
25 }
26
27 return (float *)positions;
28}
29
31{
33 &dm->edgeData, CD_PROP_INT32_2D, ".edge_verts", dm->getNumEdges(dm));
34
35 if (!edge) {
37 &dm->edgeData, CD_PROP_INT32_2D, CD_SET_DEFAULT, dm->getNumEdges(dm), ".edge_verts");
39 dm->copyEdgeArray(dm, edge);
40 }
41
42 return edge;
43}
44
46{
47 int *corner_verts = (int *)CustomData_get_layer_named_for_write(
48 &dm->loopData, CD_PROP_INT32, ".corner_vert", dm->getNumLoops(dm));
49
50 if (!corner_verts) {
51 corner_verts = (int *)CustomData_add_layer_named(
52 &dm->loopData, CD_PROP_INT32, CD_SET_DEFAULT, dm->getNumLoops(dm), ".corner_vert");
53 dm->copyCornerVertArray(dm, corner_verts);
54 }
55
56 return corner_verts;
57}
58
60{
61 int *corner_edges = (int *)CustomData_get_layer_named(
62 &dm->loopData, CD_PROP_INT32, ".corner_edge");
63
64 if (!corner_edges) {
65 corner_edges = (int *)CustomData_add_layer_named(
66 &dm->loopData, CD_PROP_INT32, CD_SET_DEFAULT, dm->getNumLoops(dm), ".corner_edge");
67 dm->copyCornerEdgeArray(dm, corner_edges);
68 }
69
70 return corner_edges;
71}
72
74{
75 if (!dm->face_offsets) {
76 dm->face_offsets = MEM_cnew_array<int>(dm->getNumPolys(dm) + 1, __func__);
77 dm->copyPolyArray(dm, dm->face_offsets);
78 }
79 return dm->face_offsets;
80}
81
96
98 DerivedMeshType type,
99 int numVerts,
100 int numEdges,
101 int numTessFaces,
102 int numLoops,
103 int numPolys)
104{
105 dm->type = type;
106 dm->numVertData = numVerts;
107 dm->numEdgeData = numEdges;
108 dm->numTessFaceData = numTessFaces;
109 dm->numLoopData = numLoops;
110 dm->numPolyData = numPolys;
111
112 DM_init_funcs(dm);
113
114 /* Don't use #CustomData_reset because we don't want to touch custom-data. */
120}
121
123 DerivedMesh *source,
124 DerivedMeshType type,
125 int numVerts,
126 int numEdges,
127 int numTessFaces,
128 int numLoops,
129 int numPolys)
130{
133 &source->vertData, &dm->vertData, mask->vmask, CD_SET_DEFAULT, numVerts);
135 &source->edgeData, &dm->edgeData, mask->emask, CD_SET_DEFAULT, numEdges);
137 &source->faceData, &dm->faceData, mask->fmask, CD_SET_DEFAULT, numTessFaces);
139 &source->loopData, &dm->loopData, mask->lmask, CD_SET_DEFAULT, numLoops);
141 &source->polyData, &dm->polyData, mask->pmask, CD_SET_DEFAULT, numPolys);
142 dm->face_offsets = static_cast<int *>(MEM_dupallocN(source->face_offsets));
143
144 dm->type = type;
145 dm->numVertData = numVerts;
146 dm->numEdgeData = numEdges;
147 dm->numTessFaceData = numTessFaces;
148 dm->numLoopData = numLoops;
149 dm->numPolyData = numPolys;
150
151 DM_init_funcs(dm);
152}
153
163
165{
166 CustomData_set_only_copy(&dm->vertData, mask->vmask);
167 CustomData_set_only_copy(&dm->edgeData, mask->emask);
168 CustomData_set_only_copy(&dm->faceData, mask->fmask);
169 /* this wasn't in 2.63 and is disabled for 2.64 because it gives problems with
170 * weight paint mode when there are modifiers applied, needs further investigation,
171 * see replies to r50969, Campbell */
172#if 0
173 CustomData_set_only_copy(&dm->loopData, mask->lmask);
174 Custom(&dm->polyData, mask->pmask);
175#endif
176}
177
179{
180 return CustomData_get_layer_for_write(&dm->vertData, type, dm->getNumVerts(dm));
181}
182
184{
185 return CustomData_get_layer_for_write(&dm->edgeData, type, dm->getNumEdges(dm));
186}
187
189{
190 return CustomData_get_layer_for_write(&dm->polyData, type, dm->getNumPolys(dm));
191}
192
194{
195 return CustomData_get_layer_for_write(&dm->loopData, type, dm->getNumLoops(dm));
196}
197
199 const DerivedMesh *source, DerivedMesh *dest, int source_index, int dest_index, int count)
200{
201 CustomData_copy_data(&source->vertData, &dest->vertData, source_index, dest_index, count);
202}
203
205 DerivedMesh *dest,
206 int *src_indices,
207 float *weights,
208 int count,
209 int dest_index)
210{
212 &source->vertData, &dest->vertData, src_indices, weights, nullptr, count, dest_index);
213}
214
217
218 /* these point to data in the DerivedMesh custom data layers,
219 * they are only here for efficiency and convenience */
225};
226
227/**************** DerivedMesh interface functions ****************/
229{
230 return dm->numVertData;
231}
232
234{
235 return dm->numEdgeData;
236}
237
239{
240 return dm->numLoopData;
241}
242
244{
245 return dm->numPolyData;
246}
247
248static void cdDM_copyVertArray(DerivedMesh *dm, float (*r_positions)[3])
249{
250 CDDerivedMesh *cddm = (CDDerivedMesh *)dm;
251 memcpy(r_positions, cddm->vert_positions, sizeof(float[3]) * dm->numVertData);
252}
253
255{
256 CDDerivedMesh *cddm = (CDDerivedMesh *)dm;
257 memcpy(r_edge, cddm->medge, sizeof(*r_edge) * dm->numEdgeData);
258}
259
260static void cdDM_copyCornerVertArray(DerivedMesh *dm, int *r_corner_verts)
261{
262 CDDerivedMesh *cddm = (CDDerivedMesh *)dm;
263 memcpy(r_corner_verts, cddm->corner_verts, sizeof(*r_corner_verts) * dm->numLoopData);
264}
265
266static void cdDM_copyCornerEdgeArray(DerivedMesh *dm, int *r_corner_edges)
267{
268 CDDerivedMesh *cddm = (CDDerivedMesh *)dm;
269 memcpy(r_corner_edges, cddm->corner_edges, sizeof(*r_corner_edges) * dm->numLoopData);
270}
271
272static void cdDM_copyPolyArray(DerivedMesh *dm, int *r_face_offsets)
273{
274 memcpy(r_face_offsets, dm->face_offsets, sizeof(int) * (dm->numPolyData + 1));
275}
276
277static void cdDM_release(DerivedMesh *dm)
278{
279 CDDerivedMesh *cddm = (CDDerivedMesh *)dm;
280
281 DM_release(dm);
282 MEM_freeN(cddm);
283}
284
285/**************** CDDM interface functions ****************/
286static CDDerivedMesh *cdDM_create(const char *desc)
287{
288 CDDerivedMesh *cddm = MEM_cnew<CDDerivedMesh>(desc);
289 DerivedMesh *dm = &cddm->dm;
290
295
301
304
305 dm->release = cdDM_release;
306
307 return cddm;
308}
309
311{
312 CDDerivedMesh *cddm = cdDM_create(__func__);
313 DerivedMesh *dm = &cddm->dm;
314 CustomData_MeshMasks cddata_masks = *mask;
315
316 cddata_masks.lmask &= ~CD_MASK_MDISPS;
317
318 /* this does a referenced copy, with an exception for fluidsim */
319
320 DM_init(dm,
322 mesh->verts_num,
323 mesh->edges_num,
324 0 /* `mesh->totface` */,
325 mesh->corners_num,
326 mesh->faces_num);
327
328 CustomData_merge(&mesh->vert_data, &dm->vertData, cddata_masks.vmask, mesh->verts_num);
329 CustomData_merge(&mesh->edge_data, &dm->edgeData, cddata_masks.emask, mesh->edges_num);
330 CustomData_merge(&mesh->fdata_legacy,
331 &dm->faceData,
332 cddata_masks.fmask | CD_MASK_ORIGINDEX,
333 0 /* `mesh->totface` */);
334 CustomData_merge(&mesh->corner_data, &dm->loopData, cddata_masks.lmask, mesh->corners_num);
335 CustomData_merge(&mesh->face_data, &dm->polyData, cddata_masks.pmask, mesh->faces_num);
336
337 cddm->vert_positions = static_cast<float(*)[3]>(CustomData_get_layer_named_for_write(
338 &dm->vertData, CD_PROP_FLOAT3, "position", mesh->verts_num));
340 &dm->edgeData, CD_PROP_INT32_2D, ".edge_verts", mesh->edges_num));
341 cddm->corner_verts = static_cast<int *>(CustomData_get_layer_named_for_write(
342 &dm->loopData, CD_PROP_INT32, ".corner_vert", mesh->corners_num));
343 cddm->corner_edges = static_cast<int *>(CustomData_get_layer_named_for_write(
344 &dm->loopData, CD_PROP_INT32, ".corner_edge", mesh->corners_num));
345 dm->face_offsets = static_cast<int *>(MEM_dupallocN(mesh->face_offset_indices));
346#if 0
348#else
349 cddm->mface = nullptr;
350#endif
351
352 /* commented since even when CD_ORIGINDEX was first added this line fails
353 * on the default cube, (after editmode toggle too) - campbell */
354#if 0
356#endif
357
358 return dm;
359}
360
362{
363 return cdDM_from_mesh_ex(mesh, &CD_MASK_MESH);
364}
CustomData interface, see also DNA_customdata_types.h.
void * CustomData_get_layer_named_for_write(CustomData *data, eCustomDataType type, blender::StringRef name, int totelem)
void CustomData_set_only_copy(const CustomData *data, eCustomDataMask mask)
const void * CustomData_get_layer(const CustomData *data, eCustomDataType type)
void CustomData_set_layer_flag(CustomData *data, eCustomDataType type, int flag)
@ CD_SET_DEFAULT
void CustomData_interp(const CustomData *source, CustomData *dest, const int *src_indices, const float *weights, const float *sub_weights, int count, int dest_index)
const void * CustomData_get_layer_named(const CustomData *data, eCustomDataType type, blender::StringRef name)
void * CustomData_add_layer_named(CustomData *data, eCustomDataType type, eCDAllocType alloctype, int totelem, blender::StringRef name)
void CustomData_free(CustomData *data, int totelem)
bool CustomData_merge(const CustomData *source, CustomData *dest, eCustomDataMask mask, int totelem)
void CustomData_init_layout_from(const CustomData *source, CustomData *dest, eCustomDataMask mask, eCDAllocType alloctype, int totelem)
void * CustomData_get_layer_for_write(CustomData *data, eCustomDataType type, int totelem)
void CustomData_copy_data(const CustomData *source, CustomData *dest, int source_index, int dest_index, int count)
bool CustomData_has_layer(const CustomData *data, eCustomDataType type)
const CustomData_MeshMasks CD_MASK_DERIVEDMESH
const CustomData_MeshMasks CD_MASK_MESH
#define BLI_assert(a)
Definition BLI_assert.h:50
void copy_vn_i(int *array_tar, int size, int val)
#define CD_MASK_ORIGINDEX
@ CD_FLAG_TEMPORARY
@ CD_PROP_FLOAT3
@ CD_PROP_INT32_2D
@ CD_PROP_INT32
#define MEM_SAFE_FREE(v)
draw_view in_light_buf[] float
int count
void MEM_freeN(void *vmemh)
Definition mallocn.cc:105
void *(* MEM_dupallocN)(const void *vmemh)
Definition mallocn.cc:39
ccl_device_inline float4 mask(const int4 mask, const float4 a)
void * DM_get_loop_data_layer(DerivedMesh *dm, const eCustomDataType type)
void * DM_get_edge_data_layer(DerivedMesh *dm, const eCustomDataType type)
void * DM_get_poly_data_layer(DerivedMesh *dm, const eCustomDataType type)
void DM_release(DerivedMesh *dm)
static int cdDM_getNumLoops(DerivedMesh *dm)
static void cdDM_copyEdgeArray(DerivedMesh *dm, blender::int2 *r_edge)
static int * dm_getPolyArray(DerivedMesh *dm)
void DM_interp_vert_data(const DerivedMesh *source, DerivedMesh *dest, int *src_indices, float *weights, int count, int dest_index)
void * DM_get_vert_data_layer(DerivedMesh *dm, const eCustomDataType type)
void DM_init(DerivedMesh *dm, DerivedMeshType type, int numVerts, int numEdges, int numTessFaces, int numLoops, int numPolys)
static DerivedMesh * cdDM_from_mesh_ex(Mesh *mesh, const CustomData_MeshMasks *mask)
void DM_from_template(DerivedMesh *dm, DerivedMesh *source, DerivedMeshType type, int numVerts, int numEdges, int numTessFaces, int numLoops, int numPolys)
static int cdDM_getNumVerts(DerivedMesh *dm)
static blender::int2 * dm_getEdgeArray(DerivedMesh *dm)
static int * dm_getCornerVertArray(DerivedMesh *dm)
void DM_copy_vert_data(const DerivedMesh *source, DerivedMesh *dest, int source_index, int dest_index, int count)
static float * dm_getVertArray(DerivedMesh *dm)
static int cdDM_getNumEdges(DerivedMesh *dm)
static void cdDM_release(DerivedMesh *dm)
void DM_init_funcs(DerivedMesh *dm)
static int cdDM_getNumPolys(DerivedMesh *dm)
static void cdDM_copyPolyArray(DerivedMesh *dm, int *r_face_offsets)
DerivedMesh * CDDM_from_mesh(Mesh *mesh)
static void cdDM_copyCornerVertArray(DerivedMesh *dm, int *r_corner_verts)
static void cdDM_copyCornerEdgeArray(DerivedMesh *dm, int *r_corner_edges)
static void cdDM_copyVertArray(DerivedMesh *dm, float(*r_positions)[3])
static int * dm_getCornerEdgeArray(DerivedMesh *dm)
static CDDerivedMesh * cdDM_create(const char *desc)
void DM_set_only_copy(DerivedMesh *dm, const CustomData_MeshMasks *mask)
void *(* getEdgeDataArray)(DerivedMesh *dm, eCustomDataType type)
int *(* getPolyArray)(DerivedMesh *dm)
int(* getNumVerts)(DerivedMesh *dm)
int *(* getCornerVertArray)(DerivedMesh *dm)
void *(* getPolyDataArray)(DerivedMesh *dm, eCustomDataType type)
int(* getNumPolys)(DerivedMesh *dm)
void(* copyVertArray)(DerivedMesh *dm, float(*r_positions)[3])
void(* copyCornerEdgeArray)(DerivedMesh *dm, int *r_corner_edges)
int(* getNumEdges)(DerivedMesh *dm)
void *(* getVertDataArray)(DerivedMesh *dm, eCustomDataType type)
void(* copyEdgeArray)(DerivedMesh *dm, blender::int2 *r_edge)
float *(* getVertArray)(DerivedMesh *dm)
void(* copyPolyArray)(DerivedMesh *dm, int *r_face_offsets)
void *(* getLoopDataArray)(DerivedMesh *dm, eCustomDataType type)
blender::int2 *(* getEdgeArray)(DerivedMesh *dm)
void(* copyCornerVertArray)(DerivedMesh *dm, int *r_corner_verts)
int *(* getCornerEdgeArray)(DerivedMesh *dm)
void(* release)(DerivedMesh *dm)
int(* getNumLoops)(DerivedMesh *dm)