Cleanup: Subdiv: Remove common_ prefix
[blender.git] / source / blender / blenkernel / BKE_customdata.hh
blob93e3bdd1efedf8ccaa00318eb08695c2b745f568
1 /* SPDX-FileCopyrightText: 2006 Blender Authors
3 * SPDX-License-Identifier: GPL-2.0-or-later */
5 /** \file
6 * \ingroup bke
7 * \brief CustomData interface, see also DNA_customdata_types.h.
8 */
10 #pragma once
12 #include <optional>
14 #include "BLI_implicit_sharing.h"
15 #include "BLI_memory_counter_fwd.hh"
16 #include "BLI_set.hh"
17 #include "BLI_span.hh"
18 #include "BLI_string_ref.hh"
19 #include "BLI_sys_types.h"
20 #include "BLI_vector.hh"
22 #include "BKE_volume_enums.hh"
24 #include "DNA_customdata_types.h"
26 struct BlendDataReader;
27 struct BlendWriter;
28 struct BMesh;
29 struct CustomData_MeshMasks;
30 struct CustomData;
31 struct CustomDataTransferLayerMap;
32 struct ID;
33 struct MeshPairRemap;
35 /* These names are used as prefixes for UV layer names to find the associated boolean
36 * layers. They should never be longer than 2 chars, as #MAX_CUSTOMDATA_LAYER_NAME
37 * has 4 extra bytes above what can be used for the base layer name, and these
38 * prefixes are placed between 2 '.'s at the start of the layer name.
39 * For example The uv vert selection layer of a layer named `UVMap.001`
40 * will be called `.vs.UVMap.001`. */
41 #define UV_VERTSEL_NAME "vs"
42 #define UV_EDGESEL_NAME "es"
43 #define UV_PINNED_NAME "pn"
45 /**
46 * UV map related customdata offsets into BMesh attribute blocks. See #BM_uv_map_get_offsets.
47 * Defined in #BKE_customdata.hh to avoid including bmesh.hh in many unrelated areas.
48 * An offset of -1 means that the corresponding layer does not exist.
50 struct BMUVOffsets {
51 int uv;
52 int select_vert;
53 int select_edge;
54 int pin;
57 /* A data type large enough to hold 1 element from any custom-data layer type. */
58 struct CDBlockBytes {
59 unsigned char data[64];
62 extern const CustomData_MeshMasks CD_MASK_BAREMESH;
63 extern const CustomData_MeshMasks CD_MASK_BAREMESH_ORIGINDEX;
64 extern const CustomData_MeshMasks CD_MASK_MESH;
65 extern const CustomData_MeshMasks CD_MASK_DERIVEDMESH;
66 extern const CustomData_MeshMasks CD_MASK_BMESH;
67 extern const CustomData_MeshMasks CD_MASK_EVERYTHING;
69 /* for ORIGINDEX layer type, indicates no original index for this element */
70 #define ORIGINDEX_NONE -1
72 /* initializes a CustomData object with the same layer setup as source and
73 * memory space for totelem elements. mask must be an array of length
74 * CD_NUMTYPES elements, that indicate if a layer can be copied. */
76 /** Add/copy/merge allocation types. */
77 enum eCDAllocType {
78 /** Allocate and set to default, which is usually just zeroed memory. */
79 CD_SET_DEFAULT = 2,
80 /**
81 * Default construct new layer values. Does nothing for trivial types. This should be used
82 * if all layer values will be set by the caller after creating the layer.
84 CD_CONSTRUCT = 5,
87 #define CD_TYPE_AS_MASK(_type) (eCustomDataMask)((eCustomDataMask)1 << (eCustomDataMask)(_type))
89 void customData_mask_layers__print(const CustomData_MeshMasks *mask);
91 using cd_interp = void (*)(
92 const void **sources, const float *weights, const float *sub_weights, int count, void *dest);
93 using cd_copy = void (*)(const void *source, void *dest, int count);
94 using cd_set_default_value = void (*)(void *data, int count);
95 using cd_free = void (*)(void *data, int count);
96 using cd_validate = bool (*)(void *item, uint totitems, bool do_fixes);
98 /**
99 * Update mask_dst with layers defined in mask_src (equivalent to a bit-wise OR).
101 void CustomData_MeshMasks_update(CustomData_MeshMasks *mask_dst,
102 const CustomData_MeshMasks *mask_src);
104 * Return True if all layers set in \a mask_required are also set in \a mask_ref
106 bool CustomData_MeshMasks_are_matching(const CustomData_MeshMasks *mask_ref,
107 const CustomData_MeshMasks *mask_required);
110 * Checks if the layer at physical offset \a layer_n (in data->layers) support math
111 * the below operations.
113 bool CustomData_layer_has_math(const CustomData *data, int layer_n);
114 bool CustomData_layer_has_interp(const CustomData *data, int layer_n);
117 * Checks if any of the custom-data layers has math.
119 bool CustomData_has_math(const CustomData *data);
120 bool CustomData_has_interp(const CustomData *data);
122 * A non bmesh version would have to check `layer->data`.
124 bool CustomData_bmesh_has_free(const CustomData *data);
127 * Checks if any of the custom-data layers is referenced.
129 bool CustomData_has_referenced(const CustomData *data);
132 * Copies the "value" (e.g. `mloopuv` UV or `mloopcol` colors) from one block to
133 * another, while not overwriting anything else (e.g. flags). probably only
134 * implemented for `mloopuv/mloopcol`, for now.
136 void CustomData_data_copy_value(eCustomDataType type, const void *source, void *dest);
137 void CustomData_data_set_default_value(eCustomDataType type, void *elem);
140 * Mixes the "value" (e.g. `mloopuv` UV or `mloopcol` colors) from one block into
141 * another, while not overwriting anything else (e.g. flags).
143 void CustomData_data_mix_value(
144 eCustomDataType type, const void *source, void *dest, int mixmode, float mixfactor);
147 * Compares if data1 is equal to data2. type is a valid #CustomData type
148 * enum (e.g. #CD_PROP_FLOAT). the layer type's equal function is used to compare
149 * the data, if it exists, otherwise #memcmp is used.
151 bool CustomData_data_equals(eCustomDataType type, const void *data1, const void *data2);
152 void CustomData_data_initminmax(eCustomDataType type, void *min, void *max);
153 void CustomData_data_dominmax(eCustomDataType type, const void *data, void *min, void *max);
154 void CustomData_data_multiply(eCustomDataType type, void *data, float fac);
155 void CustomData_data_add(eCustomDataType type, void *data1, const void *data2);
158 * Initializes a CustomData object with the same layer setup as source. `mask` is a bit-field where
159 * `(mask & (1 << (layer type)))` indicates if a layer should be copied or not. Data layers using
160 * implicit-sharing will not actually be copied but will be shared between source and destination.
162 * \warning Does not free or release any internal resources in `dest` CustomData, code must call
163 * #CustomData_free first if needed.
165 void CustomData_init_from(const CustomData *source,
166 CustomData *dest,
167 eCustomDataMask mask,
168 int totelem);
170 * Initializes a CustomData object with the same layers as source. The data is not copied from the
171 * source. Instead, the new layers are initialized using the given `alloctype`.
173 * \warning Does not free or release any internal resources in `dest` CustomData, code must call
174 * #CustomData_free first if needed.
176 void CustomData_init_layout_from(const CustomData *source,
177 CustomData *dest,
178 eCustomDataMask mask,
179 eCDAllocType alloctype,
180 int totelem);
182 /* BMESH_TODO, not really a public function but `readfile.cc` needs it. */
183 void CustomData_update_typemap(CustomData *data);
186 * Copies all layers from source to destination that don't exist there yet.
188 bool CustomData_merge(const CustomData *source,
189 CustomData *dest,
190 eCustomDataMask mask,
191 int totelem);
193 * Copies all layers from source to destination that don't exist there yet. The layer data is not
194 * copied. Instead the newly created layers are initialized using the given `alloctype`.
196 bool CustomData_merge_layout(const CustomData *source,
197 CustomData *dest,
198 eCustomDataMask mask,
199 eCDAllocType alloctype,
200 int totelem);
203 * Reallocate custom data to a new element count. If the new size is larger, the new values use
204 * the #CD_CONSTRUCT behavior, so trivial types must be initialized by the caller. After being
205 * resized, the #CustomData does not contain any referenced layers.
207 void CustomData_realloc(CustomData *data,
208 int old_size,
209 int new_size,
210 eCDAllocType alloctype = CD_CONSTRUCT);
213 * BMesh version of CustomData_merge_layout; merges the layouts of source and `dest`,
214 * then goes through the mesh and makes sure all the custom-data blocks are
215 * consistent with the new layout.
217 bool CustomData_bmesh_merge_layout(const CustomData *source,
218 CustomData *dest,
219 eCustomDataMask mask,
220 eCDAllocType alloctype,
221 BMesh *bm,
222 char htype);
225 * Remove layers that aren't stored in BMesh or are stored as flags on BMesh.
226 * The `layers` array of the returned #CustomData must be freed, but may be null.
227 * Used during conversion of #Mesh data to #BMesh storage format.
229 CustomData CustomData_shallow_copy_remove_non_bmesh_attributes(const CustomData *src,
230 eCustomDataMask mask);
233 * NULL's all members and resets the #CustomData.typemap.
235 * \warning Does not free or release any internal resources.
237 void CustomData_reset(CustomData *data);
240 * Frees data associated with a CustomData object (doesn't free the object itself, though).
242 void CustomData_free(CustomData *data, int totelem);
245 * Same as #CustomData_free, but only frees layers which matches the given mask.
247 void CustomData_free_typemask(CustomData *data, int totelem, eCustomDataMask mask);
250 * Adds a layer of the given type to the #CustomData object. The new layer is initialized based on
251 * the given alloctype.
252 * \return The layer data.
254 void *CustomData_add_layer(CustomData *data,
255 eCustomDataType type,
256 eCDAllocType alloctype,
257 int totelem);
260 * Adds a layer of the given type to the #CustomData object. The new layer takes ownership of the
261 * passed in `layer_data`. If a #ImplicitSharingInfo is passed in, its user count is increased.
263 const void *CustomData_add_layer_with_data(CustomData *data,
264 eCustomDataType type,
265 void *layer_data,
266 int totelem,
267 const blender::ImplicitSharingInfo *sharing_info);
270 * Same as #CustomData_add_layer but accepts a name.
272 void *CustomData_add_layer_named(CustomData *data,
273 eCustomDataType type,
274 eCDAllocType alloctype,
275 int totelem,
276 blender::StringRef name);
278 const void *CustomData_add_layer_named_with_data(CustomData *data,
279 eCustomDataType type,
280 void *layer_data,
281 int totelem,
282 blender::StringRef name,
283 const blender::ImplicitSharingInfo *sharing_info);
286 * Frees the active or first data layer with the give type.
287 * returns 1 on success, 0 if no layer with the given type is found
289 * In edit-mode, use #EDBM_data_layer_free instead of this function.
291 bool CustomData_free_layer(CustomData *data, eCustomDataType type, int totelem, int index);
292 bool CustomData_free_layer_named(CustomData *data, blender::StringRef name, const int totelem);
295 * Frees the layer index with the give type.
296 * returns 1 on success, 0 if no layer with the given type is found.
298 * In edit-mode, use #EDBM_data_layer_free instead of this function.
300 bool CustomData_free_layer_active(CustomData *data, eCustomDataType type, int totelem);
303 * Same as #CustomData_free_layer_active, but free all layers with type.
305 void CustomData_free_layers(CustomData *data, eCustomDataType type, int totelem);
308 * Returns true if a layer with the specified type exists.
310 bool CustomData_has_layer(const CustomData *data, eCustomDataType type);
311 bool CustomData_has_layer_named(const CustomData *data,
312 eCustomDataType type,
313 blender::StringRef name);
316 * Returns the number of layers with this type.
318 int CustomData_number_of_layers(const CustomData *data, eCustomDataType type);
319 int CustomData_number_of_anonymous_layers(const CustomData *data, eCustomDataType type);
320 int CustomData_number_of_layers_typemask(const CustomData *data, eCustomDataMask mask);
323 * Set the #CD_FLAG_NOCOPY flag in custom data layers where the mask is
324 * zero for the layer type, so only layer types specified by the mask will be copied
326 void CustomData_set_only_copy(const CustomData *data, eCustomDataMask mask);
329 * Copies data from one CustomData object to another
330 * objects need not be compatible, each source layer is copied to the
331 * first dest layer of correct type (if there is none, the layer is skipped).
333 * NOTE: It's expected that the destination layers are mutable
334 * (#CustomData_ensure_layers_are_mutable). These copy-functions could ensure that internally, but
335 * that would cause additional overhead when copying few elements at a time. It would also be
336 * necessary to pass the total size of the destination layers as parameter if to make them mutable
337 * though. In most cases, these functions are used right after creating a new geometry, in which
338 * case there are no shared layers anyway.
340 void CustomData_copy_data(
341 const CustomData *source, CustomData *dest, int source_index, int dest_index, int count);
342 void CustomData_copy_data_layer(const CustomData *source,
343 CustomData *dest,
344 int src_layer_index,
345 int dst_layer_index,
346 int src_index,
347 int dst_index,
348 int count);
349 void CustomData_copy_data_named(
350 const CustomData *source, CustomData *dest, int source_index, int dest_index, int count);
351 void CustomData_copy_elements(eCustomDataType type,
352 void *src_data_ofs,
353 void *dst_data_ofs,
354 int count);
357 * Copy all layers from the source to the destination block.
358 * Allocate the result block if necessary, otherwise free its existing layer data.
360 void CustomData_bmesh_copy_block(CustomData &data, void *src_block, void **dst_block);
362 /** Holds the minimal data necessary to copy data blocks from one custom data format to another. */
363 struct BMCustomDataCopyMap {
364 struct TrivialCopy {
365 int size;
366 int src_offset;
367 int dst_offset;
369 struct Copy {
370 cd_copy fn;
371 int src_offset;
372 int dst_offset;
374 struct TrivialDefault {
375 int size;
376 int dst_offset;
378 struct Default {
379 cd_set_default_value fn;
380 int dst_offset;
382 struct Free {
383 cd_free fn;
384 int dst_offset;
386 blender::Vector<TrivialCopy> trivial_copies;
387 blender::Vector<Copy> copies;
388 blender::Vector<TrivialDefault> trivial_defaults;
389 blender::Vector<Default> defaults;
390 blender::Vector<Free> free;
393 /** Precalculate a map for more efficient copying between custom data formats. */
394 BMCustomDataCopyMap CustomData_bmesh_copy_map_calc(const CustomData &src,
395 const CustomData &dst,
396 eCustomDataMask mask_exclude = 0);
399 * Copy custom data layers for one element between two potentially different formats with a
400 * precalculated map.
402 void CustomData_bmesh_copy_block(CustomData &dst_data,
403 const BMCustomDataCopyMap &map,
404 const void *src_block,
405 void **dst_block);
408 * Copies data of a single layer of a given type.
410 void CustomData_copy_layer_type_data(const CustomData *source,
411 CustomData *destination,
412 eCustomDataType type,
413 int source_index,
414 int destination_index,
415 int count);
418 * Frees data in a #CustomData object. This is only expected to be called if the data layers are
419 * not shared (#CustomData_ensure_layers_are_mutable).
421 void CustomData_free_elem(CustomData *data, int index, int count);
424 * Interpolate given custom data source items into a single destination one.
426 * \param src_indices: Indices of every source items to interpolate into the destination one.
427 * \param weights: The weight to apply to each source value individually. If NULL, they will be
428 * averaged.
429 * \param sub_weights: The weights of sub-items, only used to affect each corners of a
430 * tessellated face data (should always be and array of four values).
431 * \param count: The number of source items to interpolate.
432 * \param dest_index: Index of the destination item, in which to put the result of the
433 * interpolation.
435 void CustomData_interp(const CustomData *source,
436 CustomData *dest,
437 const int *src_indices,
438 const float *weights,
439 const float *sub_weights,
440 int count,
441 int dest_index);
443 * \note src_blocks_ofs & dst_block_ofs
444 * must be pointers to the data, offset by layer->offset already.
446 void CustomData_bmesh_interp_n(CustomData *data,
447 const void **src_blocks,
448 const float *weights,
449 const float *sub_weights,
450 int count,
451 void *dst_block_ofs,
452 int n);
453 void CustomData_bmesh_interp(CustomData *data,
454 const void **src_blocks,
455 const float *weights,
456 const float *sub_weights,
457 int count,
458 void *dst_block);
461 * Swap data inside each item, for all layers.
462 * This only applies to item types that may store several sub-item data
463 * (e.g. corner data [UVs, VCol, ...] of tessellated faces).
465 * \param corner_indices: A mapping 'new_index -> old_index' of sub-item data.
467 void CustomData_swap_corners(CustomData *data, int index, const int *corner_indices);
470 * Custom data layers can be shared through implicit sharing (`BLI_implicit_sharing.h`). This
471 * function makes sure that the layer is unshared if it was shared, which makes it mutable.
473 void CustomData_ensure_data_is_mutable(CustomDataLayer *layer, int totelem);
474 void CustomData_ensure_layers_are_mutable(CustomData *data, int totelem);
477 * Retrieve a pointer to an element of the active layer of the given \a type, chosen by the
478 * \a index, if it exists.
480 void *CustomData_get_for_write(CustomData *data, int index, eCustomDataType type, int totelem);
482 * Retrieve a pointer to an element of the \a nth layer of the given \a type, chosen by the
483 * \a index, if it exists.
485 void *CustomData_get_n_for_write(
486 CustomData *data, eCustomDataType type, int index, int n, int totelem);
488 /* BMesh Custom Data Functions.
489 * Should replace edit-mesh ones with these as well, due to more efficient memory alloc. */
491 void *CustomData_bmesh_get(const CustomData *data, void *block, eCustomDataType type);
492 void *CustomData_bmesh_get_n(const CustomData *data, void *block, eCustomDataType type, int n);
495 * Gets from the layer at physical index `n`,
496 * \note doesn't check type.
498 void *CustomData_bmesh_get_layer_n(const CustomData *data, void *block, int n);
500 bool CustomData_set_layer_name(CustomData *data,
501 eCustomDataType type,
502 int n,
503 blender::StringRef name);
504 const char *CustomData_get_layer_name(const CustomData *data, eCustomDataType type, int n);
507 * Retrieve the data array of the active layer of the given \a type, if it exists. Return null
508 * otherwise.
510 const void *CustomData_get_layer(const CustomData *data, eCustomDataType type);
511 void *CustomData_get_layer_for_write(CustomData *data, eCustomDataType type, int totelem);
514 * Retrieve the data array of the \a nth layer of the given \a type, if it exists. Return null
515 * otherwise.
517 const void *CustomData_get_layer_n(const CustomData *data, eCustomDataType type, int n);
518 void *CustomData_get_layer_n_for_write(CustomData *data, eCustomDataType type, int n, int totelem);
521 * Retrieve the data array of the layer with the given \a name and \a type, if it exists. Return
522 * null otherwise.
524 const void *CustomData_get_layer_named(const CustomData *data,
525 eCustomDataType type,
526 blender::StringRef name);
527 void *CustomData_get_layer_named_for_write(CustomData *data,
528 eCustomDataType type,
529 blender::StringRef name,
530 int totelem);
532 int CustomData_get_offset(const CustomData *data, eCustomDataType type);
533 int CustomData_get_offset_named(const CustomData *data,
534 eCustomDataType type,
535 blender::StringRef name);
536 int CustomData_get_n_offset(const CustomData *data, eCustomDataType type, int n);
538 int CustomData_get_layer_index(const CustomData *data, eCustomDataType type);
539 int CustomData_get_layer_index_n(const CustomData *data, eCustomDataType type, int n);
540 int CustomData_get_named_layer_index(const CustomData *data,
541 eCustomDataType type,
542 blender::StringRef name);
543 int CustomData_get_named_layer_index_notype(const CustomData *data, blender::StringRef name);
544 int CustomData_get_active_layer_index(const CustomData *data, eCustomDataType type);
545 int CustomData_get_render_layer_index(const CustomData *data, eCustomDataType type);
546 int CustomData_get_clone_layer_index(const CustomData *data, eCustomDataType type);
547 int CustomData_get_stencil_layer_index(const CustomData *data, eCustomDataType type);
548 int CustomData_get_named_layer(const CustomData *data,
549 eCustomDataType type,
550 blender::StringRef name);
551 int CustomData_get_active_layer(const CustomData *data, eCustomDataType type);
552 int CustomData_get_render_layer(const CustomData *data, eCustomDataType type);
553 int CustomData_get_clone_layer(const CustomData *data, eCustomDataType type);
554 int CustomData_get_stencil_layer(const CustomData *data, eCustomDataType type);
557 * Returns name of the active layer of the given type or NULL
558 * if no such active layer is defined.
560 const char *CustomData_get_active_layer_name(const CustomData *data, eCustomDataType type);
563 * Returns name of the default layer of the given type or NULL
564 * if no such active layer is defined.
566 const char *CustomData_get_render_layer_name(const CustomData *data, eCustomDataType type);
568 bool CustomData_layer_is_anonymous(const CustomData *data, eCustomDataType type, int n);
570 void CustomData_bmesh_set_n(
571 CustomData *data, void *block, eCustomDataType type, int n, const void *source);
574 * Sets the nth layer of type as active.
576 void CustomData_set_layer_active(CustomData *data, eCustomDataType type, int n);
577 void CustomData_set_layer_render(CustomData *data, eCustomDataType type, int n);
578 void CustomData_set_layer_clone(CustomData *data, eCustomDataType type, int n);
579 void CustomData_set_layer_stencil(CustomData *data, eCustomDataType type, int n);
582 * For using with an index from #CustomData_get_active_layer_index and
583 * #CustomData_get_render_layer_index.
585 void CustomData_set_layer_active_index(CustomData *data, eCustomDataType type, int n);
586 void CustomData_set_layer_render_index(CustomData *data, eCustomDataType type, int n);
587 void CustomData_set_layer_clone_index(CustomData *data, eCustomDataType type, int n);
588 void CustomData_set_layer_stencil_index(CustomData *data, eCustomDataType type, int n);
591 * Adds flag to the layer flags.
593 void CustomData_set_layer_flag(CustomData *data, eCustomDataType type, int flag);
594 void CustomData_clear_layer_flag(CustomData *data, eCustomDataType type, int flag);
596 void CustomData_bmesh_set_default(CustomData *data, void **block);
597 void CustomData_bmesh_free_block(CustomData *data, void **block);
598 void CustomData_bmesh_alloc_block(CustomData *data, void **block);
601 * Same as #CustomData_bmesh_free_block but zero the memory rather than freeing.
603 void CustomData_bmesh_free_block_data(CustomData *data, void *block);
605 * A selective version of #CustomData_bmesh_free_block_data.
607 void CustomData_bmesh_free_block_data_exclude_by_type(CustomData *data,
608 void *block,
609 eCustomDataMask mask_exclude);
612 * Query info over types.
614 void CustomData_file_write_info(eCustomDataType type,
615 const char **r_struct_name,
616 int *r_struct_num);
617 int CustomData_sizeof(eCustomDataType type);
620 * Get the name of a layer type.
622 const char *CustomData_layertype_name(eCustomDataType type);
624 * Can only ever be one of these.
626 bool CustomData_layertype_is_singleton(eCustomDataType type);
628 * Has dynamically allocated members.
629 * This is useful to know if operations such as #memcmp are
630 * valid when comparing data from two layers.
632 bool CustomData_layertype_is_dynamic(eCustomDataType type);
634 * \return Maximum number of layers of given \a type, -1 means 'no limit'.
636 int CustomData_layertype_layers_max(eCustomDataType type);
638 /** \return The maximum size in bytes needed for a layer name with the given prefix. */
639 int CustomData_name_maxncpy_calc(blender::StringRef name);
642 * Make sure the name of layer at index is unique.
644 void CustomData_set_layer_unique_name(CustomData *data, int index);
646 void CustomData_validate_layer_name(const CustomData *data,
647 eCustomDataType type,
648 blender::StringRef name,
649 char *outname);
652 * For file reading compatibility, returns false if the layer was freed,
653 * only after this test passes, `layer->data` should be assigned.
655 bool CustomData_verify_versions(CustomData *data, int index);
657 /* BMesh specific custom-data stuff. */
659 void CustomData_bmesh_init_pool(CustomData *data, int totelem, char htype);
662 * Validate and fix data of \a layer,
663 * if possible (needs relevant callback in layer's type to be defined).
665 * \return True if some errors were found.
667 bool CustomData_layer_validate(CustomDataLayer *layer, uint totitems, bool do_fixes);
669 /* External file storage */
671 void CustomData_external_add(
672 CustomData *data, ID *id, eCustomDataType type, int totelem, const char *filepath);
673 void CustomData_external_remove(CustomData *data, ID *id, eCustomDataType type, int totelem);
674 bool CustomData_external_test(CustomData *data, eCustomDataType type);
676 void CustomData_external_write(
677 CustomData *data, ID *id, eCustomDataMask mask, int totelem, int free);
678 void CustomData_external_read(CustomData *data, ID *id, eCustomDataMask mask, int totelem);
679 void CustomData_external_reload(CustomData *data, ID *id, eCustomDataMask mask, int totelem);
681 /* Mesh-to-mesh transfer data. */
683 using cd_datatransfer_interp = void (*)(const CustomDataTransferLayerMap *laymap,
684 void *dest,
685 const void **sources,
686 const float *weights,
687 int count,
688 float mix_factor);
690 enum {
691 ME_VERT = 1 << 0,
692 ME_EDGE = 1 << 1,
693 ME_POLY = 1 << 2,
694 ME_LOOP = 1 << 3,
698 * How to filter out some elements (to leave untouched).
699 * Note those options are highly dependent on type of transferred data! */
700 enum {
701 CDT_MIX_NOMIX = -1, /* Special case, only used because we abuse 'copy' CD callback. */
702 CDT_MIX_TRANSFER = 0,
703 CDT_MIX_REPLACE_ABOVE_THRESHOLD = 1,
704 CDT_MIX_REPLACE_BELOW_THRESHOLD = 2,
705 CDT_MIX_MIX = 16,
706 CDT_MIX_ADD = 17,
707 CDT_MIX_SUB = 18,
708 CDT_MIX_MUL = 19,
709 /* Etc. */
712 struct CustomDataTransferLayerMap {
713 CustomDataTransferLayerMap *next, *prev;
715 int data_type;
716 int mix_mode;
717 float mix_factor;
718 /** If non-NULL, array of weights, one for each dest item, replaces mix_factor. */
719 const float *mix_weights;
721 /** Data source array (can be regular CD data, vertices/edges/etc., key-blocks...). */
722 const void *data_src;
723 /** Data dest array (same type as dat_src). */
724 void *data_dst;
725 /** Index to affect in data_src (used e.g. for vgroups). */
726 int data_src_n;
727 /** Index to affect in data_dst (used e.g. for vgroups). */
728 int data_dst_n;
729 /** Size of one element of data_src/data_dst. */
730 size_t elem_size;
732 /** Size of actual data we transfer. */
733 size_t data_size;
734 /** Offset of actual data we transfer (in element contained in data_src/dst). */
735 size_t data_offset;
736 /** For bit-flag transfer, flag(s) to affect in transferred data. */
737 uint64_t data_flag;
739 /** Opaque pointer, to be used by specific interp callback (e.g. transform-space for normals). */
740 void *interp_data;
742 cd_datatransfer_interp interp;
746 * Those functions assume src_n and dst_n layers of given type exist in resp. src and dst.
748 void CustomData_data_transfer(const MeshPairRemap *me_remap,
749 const CustomDataTransferLayerMap *laymap);
751 /* .blend file I/O */
754 * Prepare given custom data for file writing.
756 * \param data: The custom-data to tweak for .blend file writing (modified in place).
757 * \param layers_to_write: A reduced set of layers to be written to file.
759 * \warning This function invalidates the custom data struct by changing the layer counts and the
760 * #layers pointer, and by invalidating the type map. It expects to work on a shallow copy of
761 * the struct.
763 void CustomData_blend_write_prepare(CustomData &data,
764 blender::Vector<CustomDataLayer, 16> &layers_to_write,
765 const blender::Set<std::string> &skip_names = {});
768 * \param layers_to_write: Layers created by #CustomData_blend_write_prepare.
770 void CustomData_blend_write(BlendWriter *writer,
771 CustomData *data,
772 blender::Span<CustomDataLayer> layers_to_write,
773 int count,
774 eCustomDataMask cddata_mask,
775 ID *id);
777 void CustomData_blend_read(BlendDataReader *reader, CustomData *data, int count);
779 size_t CustomData_get_elem_size(const CustomDataLayer *layer);
781 void CustomData_count_memory(const CustomData &data, int totelem, blender::MemoryCounter &memory);
783 #ifndef NDEBUG
784 struct DynStr;
785 /** Use to inspect mesh data when debugging. */
786 void CustomData_debug_info_from_layers(const CustomData *data, const char *indent, DynStr *dynstr);
787 #endif /* !NDEBUG */
789 namespace blender::bke {
790 std::optional<VolumeGridType> custom_data_type_to_volume_grid_type(eCustomDataType type);
791 std::optional<eCustomDataType> volume_grid_type_to_custom_data_type(VolumeGridType type);
792 } // namespace blender::bke