1 /* SPDX-FileCopyrightText: 2006 Blender Authors
3 * SPDX-License-Identifier: GPL-2.0-or-later */
7 * \brief CustomData interface, see also DNA_customdata_types.h.
14 #include "BLI_implicit_sharing.h"
15 #include "BLI_memory_counter_fwd.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
;
29 struct CustomData_MeshMasks
;
31 struct CustomDataTransferLayerMap
;
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"
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.
57 /* A data type large enough to hold 1 element from any custom-data layer type. */
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. */
78 /** Allocate and set to default, which is usually just zeroed memory. */
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.
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
);
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
,
167 eCustomDataMask mask
,
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
,
178 eCustomDataMask mask
,
179 eCDAllocType alloctype
,
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
,
190 eCustomDataMask mask
,
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
,
198 eCustomDataMask mask
,
199 eCDAllocType alloctype
,
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
,
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
,
219 eCustomDataMask mask
,
220 eCDAllocType alloctype
,
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
,
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
,
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
,
276 blender::StringRef name
);
278 const void *CustomData_add_layer_named_with_data(CustomData
*data
,
279 eCustomDataType type
,
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
,
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
,
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
{
374 struct TrivialDefault
{
379 cd_set_default_value fn
;
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
402 void CustomData_bmesh_copy_block(CustomData
&dst_data
,
403 const BMCustomDataCopyMap
&map
,
404 const void *src_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
,
414 int destination_index
,
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
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
435 void CustomData_interp(const CustomData
*source
,
437 const int *src_indices
,
438 const float *weights
,
439 const float *sub_weights
,
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
,
453 void CustomData_bmesh_interp(CustomData
*data
,
454 const void **src_blocks
,
455 const float *weights
,
456 const float *sub_weights
,
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
,
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
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
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
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
,
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
,
609 eCustomDataMask mask_exclude
);
612 * Query info over types.
614 void CustomData_file_write_info(eCustomDataType type
,
615 const char **r_struct_name
,
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
,
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
,
685 const void **sources
,
686 const float *weights
,
698 * How to filter out some elements (to leave untouched).
699 * Note those options are highly dependent on type of transferred data! */
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,
712 struct CustomDataTransferLayerMap
{
713 CustomDataTransferLayerMap
*next
, *prev
;
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). */
725 /** Index to affect in data_src (used e.g. for vgroups). */
727 /** Index to affect in data_dst (used e.g. for vgroups). */
729 /** Size of one element of data_src/data_dst. */
732 /** Size of actual data we transfer. */
734 /** Offset of actual data we transfer (in element contained in data_src/dst). */
736 /** For bit-flag transfer, flag(s) to affect in transferred data. */
739 /** Opaque pointer, to be used by specific interp callback (e.g. transform-space for normals). */
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
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
,
772 blender::Span
<CustomDataLayer
> layers_to_write
,
774 eCustomDataMask cddata_mask
,
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
);
785 /** Use to inspect mesh data when debugging. */
786 void CustomData_debug_info_from_layers(const CustomData
*data
, const char *indent
, DynStr
*dynstr
);
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