tornavis/source/blender/blenkernel/BKE_customdata.hh

Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

766 lines
30 KiB
C++
Raw Normal View History

/* SPDX-FileCopyrightText: 2006 Blender Authors
*
* SPDX-License-Identifier: GPL-2.0-or-later */
/** \file
* \ingroup bke
* \brief CustomData interface, see also DNA_customdata_types.h.
*/
#pragma once
#include "BLI_cpp_type.hh"
Custom Data: support implicit sharing for custom data layers This integrates the new implicit-sharing system (from fbcddfcd68adc72f) with `CustomData`. Now the potentially long arrays referenced by custom data layers can be shared between different systems but most importantly between different geometries. This makes e.g. copying a mesh much cheaper because none of the attributes has to be copied. Only when an attribute is modified does it have to be copied. Also see the original design task: #95845. This reduces memory and improves performance by avoiding unnecessary data copies. For example, the used memory after loading a highly subdivided mesh is reduced from 2.4GB to 1.79GB. This is about 25% less which is the expected amount because in `main` there are 4 copies of the data: 1. The original data which is allocated when the file is loaded. 2. The copy for the depsgraph allocated during depsgraph evaluation. 3. The copy for the undo system allocated when the first undo step is created right after loading the file. 4. GPU buffers allocated for drawing. This patch only gets rid of copy number 2 for the depsgraph. In theory the other copies can be removed as part of follow up PRs as well though. ----- The patch has three main components: * Slightly modified `CustomData` API to make it work better with implicit sharing: * `CD_REFERENCE` and `CD_DUPLICATE` have been removed because they are meaningless when implicit-sharing is used. * `CD_ASSIGN` has been removed as well because it's not an allocation type anyway. The functionality of using existing arrays as custom data layers has not been removed though. * This can still be done with `CustomData_add_layer_with_data` which also has a new argument that allows passing in information about whether the array is shared. * `CD_FLAG_NOFREE` has been removed because it's no longer necessary. It only existed because of `CD_REFERENCE`. * `CustomData_copy` and `CustomData_merge` have been split up into a functions that do copy the actual attribute values and those that do not. The latter functions now have the `_layout` suffix (e.g. `CustomData_copy_layout`). * Changes in `customdata.cc` to make it actually use implicit-sharing. * Changes in various other files to adapt to the changes in `BKE_customdata.h`. Pull Request: https://projects.blender.org/blender/blender/pulls/106228
2023-04-13 14:57:57 +02:00
#include "BLI_implicit_sharing.h"
#include "BLI_set.hh"
#include "BLI_span.hh"
#include "BLI_string_ref.hh"
#include "BLI_sys_types.h"
#include "BLI_utildefines.h"
#include "BLI_vector.hh"
#include "DNA_customdata_types.h"
2020-09-30 03:51:13 +02:00
struct BlendDataReader;
struct BlendWriter;
struct BMesh;
struct CustomData_MeshMasks;
struct CustomData;
struct CustomDataTransferLayerMap;
struct ID;
struct MeshPairRemap;
using eCustomDataMask = uint64_t;
Mesh: Move UV layers to generic attributes Currently the `MLoopUV` struct stores UV coordinates and flags related to editing UV maps in the UV editor. This patch changes the coordinates to use the generic 2D vector type, and moves the flags into three separate boolean attributes. This follows the design in T95965, with the ultimate intention of simplifying code and improving performance. Importantly, the change allows exporters and renderers to use UVs "touched" by geometry nodes, which only creates generic attributes. It also allows geometry nodes to create "proper" UV maps from scratch, though only with the Store Named Attribute node for now. The new design considers any 2D vector attribute on the corner domain to be a UV map. In the future, they might be distinguished from regular 2D vectors with attribute metadata, which may be helpful because they are often interpolated differently. Most of the code changes deal with passing around UV BMesh custom data offsets and tracking the boolean "sublayers". The boolean layers are use the following prefixes for attribute names: vert selection: `.vs.`, edge selection: `.es.`, pinning: `.pn.`. Currently these are short to avoid using up the maximum length of attribute names. To accommodate for these 4 extra characters, the name length limit is enlarged to 68 bytes, while the maximum user settable name length is still 64 bytes. Unfortunately Python/RNA API access to the UV flag data becomes slower. Accessing the boolean layers directly is be better for performance in general. Like the other mesh SoA refactors, backward and forward compatibility aren't affected, and won't be changed until 4.0. We pay for that by making mesh reading and writing more expensive with conversions. Resolves T85962 Differential Revision: https://developer.blender.org/D14365
2023-01-10 06:47:04 +01:00
/* These names are used as prefixes for UV layer names to find the associated boolean
* layers. They should never be longer than 2 chars, as #MAX_CUSTOMDATA_LAYER_NAME
Mesh: Move UV layers to generic attributes Currently the `MLoopUV` struct stores UV coordinates and flags related to editing UV maps in the UV editor. This patch changes the coordinates to use the generic 2D vector type, and moves the flags into three separate boolean attributes. This follows the design in T95965, with the ultimate intention of simplifying code and improving performance. Importantly, the change allows exporters and renderers to use UVs "touched" by geometry nodes, which only creates generic attributes. It also allows geometry nodes to create "proper" UV maps from scratch, though only with the Store Named Attribute node for now. The new design considers any 2D vector attribute on the corner domain to be a UV map. In the future, they might be distinguished from regular 2D vectors with attribute metadata, which may be helpful because they are often interpolated differently. Most of the code changes deal with passing around UV BMesh custom data offsets and tracking the boolean "sublayers". The boolean layers are use the following prefixes for attribute names: vert selection: `.vs.`, edge selection: `.es.`, pinning: `.pn.`. Currently these are short to avoid using up the maximum length of attribute names. To accommodate for these 4 extra characters, the name length limit is enlarged to 68 bytes, while the maximum user settable name length is still 64 bytes. Unfortunately Python/RNA API access to the UV flag data becomes slower. Accessing the boolean layers directly is be better for performance in general. Like the other mesh SoA refactors, backward and forward compatibility aren't affected, and won't be changed until 4.0. We pay for that by making mesh reading and writing more expensive with conversions. Resolves T85962 Differential Revision: https://developer.blender.org/D14365
2023-01-10 06:47:04 +01:00
* has 4 extra bytes above what can be used for the base layer name, and these
* prefixes are placed between 2 '.'s at the start of the layer name.
* For example The uv vert selection layer of a layer named `UVMap.001`
* will be called `.vs.UVMap.001`. */
Mesh: Move UV layers to generic attributes Currently the `MLoopUV` struct stores UV coordinates and flags related to editing UV maps in the UV editor. This patch changes the coordinates to use the generic 2D vector type, and moves the flags into three separate boolean attributes. This follows the design in T95965, with the ultimate intention of simplifying code and improving performance. Importantly, the change allows exporters and renderers to use UVs "touched" by geometry nodes, which only creates generic attributes. It also allows geometry nodes to create "proper" UV maps from scratch, though only with the Store Named Attribute node for now. The new design considers any 2D vector attribute on the corner domain to be a UV map. In the future, they might be distinguished from regular 2D vectors with attribute metadata, which may be helpful because they are often interpolated differently. Most of the code changes deal with passing around UV BMesh custom data offsets and tracking the boolean "sublayers". The boolean layers are use the following prefixes for attribute names: vert selection: `.vs.`, edge selection: `.es.`, pinning: `.pn.`. Currently these are short to avoid using up the maximum length of attribute names. To accommodate for these 4 extra characters, the name length limit is enlarged to 68 bytes, while the maximum user settable name length is still 64 bytes. Unfortunately Python/RNA API access to the UV flag data becomes slower. Accessing the boolean layers directly is be better for performance in general. Like the other mesh SoA refactors, backward and forward compatibility aren't affected, and won't be changed until 4.0. We pay for that by making mesh reading and writing more expensive with conversions. Resolves T85962 Differential Revision: https://developer.blender.org/D14365
2023-01-10 06:47:04 +01:00
#define UV_VERTSEL_NAME "vs"
#define UV_EDGESEL_NAME "es"
#define UV_PINNED_NAME "pn"
/**
* UV map related customdata offsets into BMesh attribute blocks. See #BM_uv_map_get_offsets.
* Defined in #BKE_customdata.hh to avoid including bmesh.h in many unrelated areas.
Mesh: Move UV layers to generic attributes Currently the `MLoopUV` struct stores UV coordinates and flags related to editing UV maps in the UV editor. This patch changes the coordinates to use the generic 2D vector type, and moves the flags into three separate boolean attributes. This follows the design in T95965, with the ultimate intention of simplifying code and improving performance. Importantly, the change allows exporters and renderers to use UVs "touched" by geometry nodes, which only creates generic attributes. It also allows geometry nodes to create "proper" UV maps from scratch, though only with the Store Named Attribute node for now. The new design considers any 2D vector attribute on the corner domain to be a UV map. In the future, they might be distinguished from regular 2D vectors with attribute metadata, which may be helpful because they are often interpolated differently. Most of the code changes deal with passing around UV BMesh custom data offsets and tracking the boolean "sublayers". The boolean layers are use the following prefixes for attribute names: vert selection: `.vs.`, edge selection: `.es.`, pinning: `.pn.`. Currently these are short to avoid using up the maximum length of attribute names. To accommodate for these 4 extra characters, the name length limit is enlarged to 68 bytes, while the maximum user settable name length is still 64 bytes. Unfortunately Python/RNA API access to the UV flag data becomes slower. Accessing the boolean layers directly is be better for performance in general. Like the other mesh SoA refactors, backward and forward compatibility aren't affected, and won't be changed until 4.0. We pay for that by making mesh reading and writing more expensive with conversions. Resolves T85962 Differential Revision: https://developer.blender.org/D14365
2023-01-10 06:47:04 +01:00
* An offset of -1 means that the corresponding layer does not exist.
*/
struct BMUVOffsets {
Mesh: Move UV layers to generic attributes Currently the `MLoopUV` struct stores UV coordinates and flags related to editing UV maps in the UV editor. This patch changes the coordinates to use the generic 2D vector type, and moves the flags into three separate boolean attributes. This follows the design in T95965, with the ultimate intention of simplifying code and improving performance. Importantly, the change allows exporters and renderers to use UVs "touched" by geometry nodes, which only creates generic attributes. It also allows geometry nodes to create "proper" UV maps from scratch, though only with the Store Named Attribute node for now. The new design considers any 2D vector attribute on the corner domain to be a UV map. In the future, they might be distinguished from regular 2D vectors with attribute metadata, which may be helpful because they are often interpolated differently. Most of the code changes deal with passing around UV BMesh custom data offsets and tracking the boolean "sublayers". The boolean layers are use the following prefixes for attribute names: vert selection: `.vs.`, edge selection: `.es.`, pinning: `.pn.`. Currently these are short to avoid using up the maximum length of attribute names. To accommodate for these 4 extra characters, the name length limit is enlarged to 68 bytes, while the maximum user settable name length is still 64 bytes. Unfortunately Python/RNA API access to the UV flag data becomes slower. Accessing the boolean layers directly is be better for performance in general. Like the other mesh SoA refactors, backward and forward compatibility aren't affected, and won't be changed until 4.0. We pay for that by making mesh reading and writing more expensive with conversions. Resolves T85962 Differential Revision: https://developer.blender.org/D14365
2023-01-10 06:47:04 +01:00
int uv;
int select_vert;
int select_edge;
int pin;
};
Mesh: Move UV layers to generic attributes Currently the `MLoopUV` struct stores UV coordinates and flags related to editing UV maps in the UV editor. This patch changes the coordinates to use the generic 2D vector type, and moves the flags into three separate boolean attributes. This follows the design in T95965, with the ultimate intention of simplifying code and improving performance. Importantly, the change allows exporters and renderers to use UVs "touched" by geometry nodes, which only creates generic attributes. It also allows geometry nodes to create "proper" UV maps from scratch, though only with the Store Named Attribute node for now. The new design considers any 2D vector attribute on the corner domain to be a UV map. In the future, they might be distinguished from regular 2D vectors with attribute metadata, which may be helpful because they are often interpolated differently. Most of the code changes deal with passing around UV BMesh custom data offsets and tracking the boolean "sublayers". The boolean layers are use the following prefixes for attribute names: vert selection: `.vs.`, edge selection: `.es.`, pinning: `.pn.`. Currently these are short to avoid using up the maximum length of attribute names. To accommodate for these 4 extra characters, the name length limit is enlarged to 68 bytes, while the maximum user settable name length is still 64 bytes. Unfortunately Python/RNA API access to the UV flag data becomes slower. Accessing the boolean layers directly is be better for performance in general. Like the other mesh SoA refactors, backward and forward compatibility aren't affected, and won't be changed until 4.0. We pay for that by making mesh reading and writing more expensive with conversions. Resolves T85962 Differential Revision: https://developer.blender.org/D14365
2023-01-10 06:47:04 +01:00
/* A data type large enough to hold 1 element from any custom-data layer type. */
struct CDBlockBytes {
unsigned char data[64];
};
extern const CustomData_MeshMasks CD_MASK_BAREMESH;
extern const CustomData_MeshMasks CD_MASK_BAREMESH_ORIGINDEX;
extern const CustomData_MeshMasks CD_MASK_MESH;
extern const CustomData_MeshMasks CD_MASK_DERIVEDMESH;
extern const CustomData_MeshMasks CD_MASK_BMESH;
extern const CustomData_MeshMasks CD_MASK_EVERYTHING;
Added custom vertex/edge/face data for meshes: All data layers, including MVert/MEdge/MFace, are now managed as custom data layers. The pointers like Mesh.mvert, Mesh.dvert or Mesh.mcol are still used of course, but allocating, copying or freeing these arrays should be done through the CustomData API. Work in progress documentation on this is here: http://mediawiki.blender.org/index.php/BlenderDev/BlenderArchitecture/CustomData Replaced TFace by MTFace: This is the same struct, except that it does not contain color, that now always stays separated in MCol. This was not a good design decision to begin with, and it is needed for adding multiple color layers later. Note that this does mean older Blender versions will not be able to read UV coordinates from the next release, due to an SDNA limitation. Removed DispListMesh: This now fully replaced by DerivedMesh. To provide access to arrays of vertices, edges and faces, like DispListMesh does. The semantics of the DerivedMesh.getVertArray() and similar functions were changed to return a pointer to an array if one exists, or otherwise allocate a temporary one. On releasing the DerivedMesh, this temporary array will be removed automatically. Removed ssDM and meshDM DerivedMesh backends: The ssDM backend was for DispListMesh, so that became obsolete automatically. The meshDM backend was replaced by the custom data backend, that now figures out which layers need to be modified, and only duplicates those. This changes code in many places, and overall removes 2514 lines of code. So, there's a good chance this might break some stuff, although I've been testing it for a few days now. The good news is, adding multiple color and uv layers should now become easy.
2006-11-20 05:28:02 +01:00
/* for ORIGINDEX layer type, indicates no original index for this element */
#define ORIGINDEX_NONE -1
/* initializes a CustomData object with the same layer setup as source and
Added custom vertex/edge/face data for meshes: All data layers, including MVert/MEdge/MFace, are now managed as custom data layers. The pointers like Mesh.mvert, Mesh.dvert or Mesh.mcol are still used of course, but allocating, copying or freeing these arrays should be done through the CustomData API. Work in progress documentation on this is here: http://mediawiki.blender.org/index.php/BlenderDev/BlenderArchitecture/CustomData Replaced TFace by MTFace: This is the same struct, except that it does not contain color, that now always stays separated in MCol. This was not a good design decision to begin with, and it is needed for adding multiple color layers later. Note that this does mean older Blender versions will not be able to read UV coordinates from the next release, due to an SDNA limitation. Removed DispListMesh: This now fully replaced by DerivedMesh. To provide access to arrays of vertices, edges and faces, like DispListMesh does. The semantics of the DerivedMesh.getVertArray() and similar functions were changed to return a pointer to an array if one exists, or otherwise allocate a temporary one. On releasing the DerivedMesh, this temporary array will be removed automatically. Removed ssDM and meshDM DerivedMesh backends: The ssDM backend was for DispListMesh, so that became obsolete automatically. The meshDM backend was replaced by the custom data backend, that now figures out which layers need to be modified, and only duplicates those. This changes code in many places, and overall removes 2514 lines of code. So, there's a good chance this might break some stuff, although I've been testing it for a few days now. The good news is, adding multiple color and uv layers should now become easy.
2006-11-20 05:28:02 +01:00
* memory space for totelem elements. mask must be an array of length
* CD_NUMTYPES elements, that indicate if a layer can be copied. */
2019-04-18 07:21:26 +02:00
/** Add/copy/merge allocation types. */
2018-05-30 10:28:24 +02:00
typedef enum eCDAllocType {
2022-08-30 21:54:53 +02:00
/** Allocate and set to default, which is usually just zeroed memory. */
CD_SET_DEFAULT = 2,
/**
* Default construct new layer values. Does nothing for trivial types. This should be used
* if all layer values will be set by the caller after creating the layer.
*/
CD_CONSTRUCT = 5,
2018-05-30 10:28:24 +02:00
} eCDAllocType;
#define CD_TYPE_AS_MASK(_type) (eCustomDataMask)((eCustomDataMask)1 << (eCustomDataMask)(_type))
void customData_mask_layers__print(const CustomData_MeshMasks *mask);
typedef void (*cd_interp)(
const void **sources, const float *weights, const float *sub_weights, int count, void *dest);
typedef void (*cd_copy)(const void *source, void *dest, int count);
typedef bool (*cd_validate)(void *item, uint totitems, bool do_fixes);
/**
* Update mask_dst with layers defined in mask_src (equivalent to a bit-wise OR).
*/
void CustomData_MeshMasks_update(CustomData_MeshMasks *mask_dst,
const CustomData_MeshMasks *mask_src);
/**
* Return True if all layers set in \a mask_required are also set in \a mask_ref
*/
bool CustomData_MeshMasks_are_matching(const CustomData_MeshMasks *mask_ref,
const CustomData_MeshMasks *mask_required);
2012-03-18 08:38:51 +01:00
/**
* Checks if the layer at physical offset \a layer_n (in data->layers) support math
* the below operations.
*/
bool CustomData_layer_has_math(const CustomData *data, int layer_n);
bool CustomData_layer_has_interp(const CustomData *data, int layer_n);
/**
* Checks if any of the custom-data layers has math.
*/
bool CustomData_has_math(const CustomData *data);
bool CustomData_has_interp(const CustomData *data);
/**
* A non bmesh version would have to check `layer->data`.
*/
bool CustomData_bmesh_has_free(const CustomData *data);
/**
* Checks if any of the custom-data layers is referenced.
*/
bool CustomData_has_referenced(const CustomData *data);
/**
2023-03-27 03:08:14 +02:00
* Copies the "value" (e.g. `mloopuv` UV or `mloopcol` colors) from one block to
* another, while not overwriting anything else (e.g. flags). probably only
2023-03-27 03:08:14 +02:00
* implemented for `mloopuv/mloopcol`, for now.
*/
void CustomData_data_copy_value(eCustomDataType type, const void *source, void *dest);
void CustomData_data_set_default_value(eCustomDataType type, void *elem);
/**
2023-03-27 03:08:14 +02:00
* Mixes the "value" (e.g. `mloopuv` UV or `mloopcol` colors) from one block into
* another, while not overwriting anything else (e.g. flags).
*/
void CustomData_data_mix_value(
eCustomDataType type, const void *source, void *dest, int mixmode, float mixfactor);
/**
2023-03-27 03:08:14 +02:00
* Compares if data1 is equal to data2. type is a valid #CustomData type
Mesh: Move UV layers to generic attributes Currently the `MLoopUV` struct stores UV coordinates and flags related to editing UV maps in the UV editor. This patch changes the coordinates to use the generic 2D vector type, and moves the flags into three separate boolean attributes. This follows the design in T95965, with the ultimate intention of simplifying code and improving performance. Importantly, the change allows exporters and renderers to use UVs "touched" by geometry nodes, which only creates generic attributes. It also allows geometry nodes to create "proper" UV maps from scratch, though only with the Store Named Attribute node for now. The new design considers any 2D vector attribute on the corner domain to be a UV map. In the future, they might be distinguished from regular 2D vectors with attribute metadata, which may be helpful because they are often interpolated differently. Most of the code changes deal with passing around UV BMesh custom data offsets and tracking the boolean "sublayers". The boolean layers are use the following prefixes for attribute names: vert selection: `.vs.`, edge selection: `.es.`, pinning: `.pn.`. Currently these are short to avoid using up the maximum length of attribute names. To accommodate for these 4 extra characters, the name length limit is enlarged to 68 bytes, while the maximum user settable name length is still 64 bytes. Unfortunately Python/RNA API access to the UV flag data becomes slower. Accessing the boolean layers directly is be better for performance in general. Like the other mesh SoA refactors, backward and forward compatibility aren't affected, and won't be changed until 4.0. We pay for that by making mesh reading and writing more expensive with conversions. Resolves T85962 Differential Revision: https://developer.blender.org/D14365
2023-01-10 06:47:04 +01:00
* enum (e.g. #CD_PROP_FLOAT). the layer type's equal function is used to compare
* the data, if it exists, otherwise #memcmp is used.
*/
bool CustomData_data_equals(eCustomDataType type, const void *data1, const void *data2);
void CustomData_data_initminmax(eCustomDataType type, void *min, void *max);
void CustomData_data_dominmax(eCustomDataType type, const void *data, void *min, void *max);
void CustomData_data_multiply(eCustomDataType type, void *data, float fac);
void CustomData_data_add(eCustomDataType type, void *data1, const void *data2);
/**
Custom Data: support implicit sharing for custom data layers This integrates the new implicit-sharing system (from fbcddfcd68adc72f) with `CustomData`. Now the potentially long arrays referenced by custom data layers can be shared between different systems but most importantly between different geometries. This makes e.g. copying a mesh much cheaper because none of the attributes has to be copied. Only when an attribute is modified does it have to be copied. Also see the original design task: #95845. This reduces memory and improves performance by avoiding unnecessary data copies. For example, the used memory after loading a highly subdivided mesh is reduced from 2.4GB to 1.79GB. This is about 25% less which is the expected amount because in `main` there are 4 copies of the data: 1. The original data which is allocated when the file is loaded. 2. The copy for the depsgraph allocated during depsgraph evaluation. 3. The copy for the undo system allocated when the first undo step is created right after loading the file. 4. GPU buffers allocated for drawing. This patch only gets rid of copy number 2 for the depsgraph. In theory the other copies can be removed as part of follow up PRs as well though. ----- The patch has three main components: * Slightly modified `CustomData` API to make it work better with implicit sharing: * `CD_REFERENCE` and `CD_DUPLICATE` have been removed because they are meaningless when implicit-sharing is used. * `CD_ASSIGN` has been removed as well because it's not an allocation type anyway. The functionality of using existing arrays as custom data layers has not been removed though. * This can still be done with `CustomData_add_layer_with_data` which also has a new argument that allows passing in information about whether the array is shared. * `CD_FLAG_NOFREE` has been removed because it's no longer necessary. It only existed because of `CD_REFERENCE`. * `CustomData_copy` and `CustomData_merge` have been split up into a functions that do copy the actual attribute values and those that do not. The latter functions now have the `_layout` suffix (e.g. `CustomData_copy_layout`). * Changes in `customdata.cc` to make it actually use implicit-sharing. * Changes in various other files to adapt to the changes in `BKE_customdata.h`. Pull Request: https://projects.blender.org/blender/blender/pulls/106228
2023-04-13 14:57:57 +02:00
* Initializes a CustomData object with the same layer setup as source. `mask` is a bit-field where
* `(mask & (1 << (layer type)))` indicates if a layer should be copied or not. Data layers using
* implicit-sharing will not actually be copied but will be shared between source and destination.
*/
void CustomData_copy(const CustomData *source,
CustomData *dest,
eCustomDataMask mask,
2018-05-30 10:28:24 +02:00
int totelem);
Custom Data: support implicit sharing for custom data layers This integrates the new implicit-sharing system (from fbcddfcd68adc72f) with `CustomData`. Now the potentially long arrays referenced by custom data layers can be shared between different systems but most importantly between different geometries. This makes e.g. copying a mesh much cheaper because none of the attributes has to be copied. Only when an attribute is modified does it have to be copied. Also see the original design task: #95845. This reduces memory and improves performance by avoiding unnecessary data copies. For example, the used memory after loading a highly subdivided mesh is reduced from 2.4GB to 1.79GB. This is about 25% less which is the expected amount because in `main` there are 4 copies of the data: 1. The original data which is allocated when the file is loaded. 2. The copy for the depsgraph allocated during depsgraph evaluation. 3. The copy for the undo system allocated when the first undo step is created right after loading the file. 4. GPU buffers allocated for drawing. This patch only gets rid of copy number 2 for the depsgraph. In theory the other copies can be removed as part of follow up PRs as well though. ----- The patch has three main components: * Slightly modified `CustomData` API to make it work better with implicit sharing: * `CD_REFERENCE` and `CD_DUPLICATE` have been removed because they are meaningless when implicit-sharing is used. * `CD_ASSIGN` has been removed as well because it's not an allocation type anyway. The functionality of using existing arrays as custom data layers has not been removed though. * This can still be done with `CustomData_add_layer_with_data` which also has a new argument that allows passing in information about whether the array is shared. * `CD_FLAG_NOFREE` has been removed because it's no longer necessary. It only existed because of `CD_REFERENCE`. * `CustomData_copy` and `CustomData_merge` have been split up into a functions that do copy the actual attribute values and those that do not. The latter functions now have the `_layout` suffix (e.g. `CustomData_copy_layout`). * Changes in `customdata.cc` to make it actually use implicit-sharing. * Changes in various other files to adapt to the changes in `BKE_customdata.h`. Pull Request: https://projects.blender.org/blender/blender/pulls/106228
2023-04-13 14:57:57 +02:00
/**
* Initializes a CustomData object with the same layers as source. The data is not copied from the
* source. Instead, the new layers are initialized using the given `alloctype`.
*/
void CustomData_copy_layout(const CustomData *source,
CustomData *dest,
Custom Data: support implicit sharing for custom data layers This integrates the new implicit-sharing system (from fbcddfcd68adc72f) with `CustomData`. Now the potentially long arrays referenced by custom data layers can be shared between different systems but most importantly between different geometries. This makes e.g. copying a mesh much cheaper because none of the attributes has to be copied. Only when an attribute is modified does it have to be copied. Also see the original design task: #95845. This reduces memory and improves performance by avoiding unnecessary data copies. For example, the used memory after loading a highly subdivided mesh is reduced from 2.4GB to 1.79GB. This is about 25% less which is the expected amount because in `main` there are 4 copies of the data: 1. The original data which is allocated when the file is loaded. 2. The copy for the depsgraph allocated during depsgraph evaluation. 3. The copy for the undo system allocated when the first undo step is created right after loading the file. 4. GPU buffers allocated for drawing. This patch only gets rid of copy number 2 for the depsgraph. In theory the other copies can be removed as part of follow up PRs as well though. ----- The patch has three main components: * Slightly modified `CustomData` API to make it work better with implicit sharing: * `CD_REFERENCE` and `CD_DUPLICATE` have been removed because they are meaningless when implicit-sharing is used. * `CD_ASSIGN` has been removed as well because it's not an allocation type anyway. The functionality of using existing arrays as custom data layers has not been removed though. * This can still be done with `CustomData_add_layer_with_data` which also has a new argument that allows passing in information about whether the array is shared. * `CD_FLAG_NOFREE` has been removed because it's no longer necessary. It only existed because of `CD_REFERENCE`. * `CustomData_copy` and `CustomData_merge` have been split up into a functions that do copy the actual attribute values and those that do not. The latter functions now have the `_layout` suffix (e.g. `CustomData_copy_layout`). * Changes in `customdata.cc` to make it actually use implicit-sharing. * Changes in various other files to adapt to the changes in `BKE_customdata.h`. Pull Request: https://projects.blender.org/blender/blender/pulls/106228
2023-04-13 14:57:57 +02:00
eCustomDataMask mask,
eCDAllocType alloctype,
int totelem);
/* BMESH_TODO, not really a public function but `readfile.cc` needs it. */
void CustomData_update_typemap(CustomData *data);
/**
Custom Data: support implicit sharing for custom data layers This integrates the new implicit-sharing system (from fbcddfcd68adc72f) with `CustomData`. Now the potentially long arrays referenced by custom data layers can be shared between different systems but most importantly between different geometries. This makes e.g. copying a mesh much cheaper because none of the attributes has to be copied. Only when an attribute is modified does it have to be copied. Also see the original design task: #95845. This reduces memory and improves performance by avoiding unnecessary data copies. For example, the used memory after loading a highly subdivided mesh is reduced from 2.4GB to 1.79GB. This is about 25% less which is the expected amount because in `main` there are 4 copies of the data: 1. The original data which is allocated when the file is loaded. 2. The copy for the depsgraph allocated during depsgraph evaluation. 3. The copy for the undo system allocated when the first undo step is created right after loading the file. 4. GPU buffers allocated for drawing. This patch only gets rid of copy number 2 for the depsgraph. In theory the other copies can be removed as part of follow up PRs as well though. ----- The patch has three main components: * Slightly modified `CustomData` API to make it work better with implicit sharing: * `CD_REFERENCE` and `CD_DUPLICATE` have been removed because they are meaningless when implicit-sharing is used. * `CD_ASSIGN` has been removed as well because it's not an allocation type anyway. The functionality of using existing arrays as custom data layers has not been removed though. * This can still be done with `CustomData_add_layer_with_data` which also has a new argument that allows passing in information about whether the array is shared. * `CD_FLAG_NOFREE` has been removed because it's no longer necessary. It only existed because of `CD_REFERENCE`. * `CustomData_copy` and `CustomData_merge` have been split up into a functions that do copy the actual attribute values and those that do not. The latter functions now have the `_layout` suffix (e.g. `CustomData_copy_layout`). * Changes in `customdata.cc` to make it actually use implicit-sharing. * Changes in various other files to adapt to the changes in `BKE_customdata.h`. Pull Request: https://projects.blender.org/blender/blender/pulls/106228
2023-04-13 14:57:57 +02:00
* Copies all layers from source to destination that don't exist there yet.
*/
bool CustomData_merge(const CustomData *source,
CustomData *dest,
eCustomDataMask mask,
2018-05-30 10:28:24 +02:00
int totelem);
Custom Data: support implicit sharing for custom data layers This integrates the new implicit-sharing system (from fbcddfcd68adc72f) with `CustomData`. Now the potentially long arrays referenced by custom data layers can be shared between different systems but most importantly between different geometries. This makes e.g. copying a mesh much cheaper because none of the attributes has to be copied. Only when an attribute is modified does it have to be copied. Also see the original design task: #95845. This reduces memory and improves performance by avoiding unnecessary data copies. For example, the used memory after loading a highly subdivided mesh is reduced from 2.4GB to 1.79GB. This is about 25% less which is the expected amount because in `main` there are 4 copies of the data: 1. The original data which is allocated when the file is loaded. 2. The copy for the depsgraph allocated during depsgraph evaluation. 3. The copy for the undo system allocated when the first undo step is created right after loading the file. 4. GPU buffers allocated for drawing. This patch only gets rid of copy number 2 for the depsgraph. In theory the other copies can be removed as part of follow up PRs as well though. ----- The patch has three main components: * Slightly modified `CustomData` API to make it work better with implicit sharing: * `CD_REFERENCE` and `CD_DUPLICATE` have been removed because they are meaningless when implicit-sharing is used. * `CD_ASSIGN` has been removed as well because it's not an allocation type anyway. The functionality of using existing arrays as custom data layers has not been removed though. * This can still be done with `CustomData_add_layer_with_data` which also has a new argument that allows passing in information about whether the array is shared. * `CD_FLAG_NOFREE` has been removed because it's no longer necessary. It only existed because of `CD_REFERENCE`. * `CustomData_copy` and `CustomData_merge` have been split up into a functions that do copy the actual attribute values and those that do not. The latter functions now have the `_layout` suffix (e.g. `CustomData_copy_layout`). * Changes in `customdata.cc` to make it actually use implicit-sharing. * Changes in various other files to adapt to the changes in `BKE_customdata.h`. Pull Request: https://projects.blender.org/blender/blender/pulls/106228
2023-04-13 14:57:57 +02:00
/**
* Copies all layers from source to destination that don't exist there yet. The layer data is not
* copied. Instead the newly created layers are initialized using the given `alloctype`.
*/
bool CustomData_merge_layout(const CustomData *source,
CustomData *dest,
Custom Data: support implicit sharing for custom data layers This integrates the new implicit-sharing system (from fbcddfcd68adc72f) with `CustomData`. Now the potentially long arrays referenced by custom data layers can be shared between different systems but most importantly between different geometries. This makes e.g. copying a mesh much cheaper because none of the attributes has to be copied. Only when an attribute is modified does it have to be copied. Also see the original design task: #95845. This reduces memory and improves performance by avoiding unnecessary data copies. For example, the used memory after loading a highly subdivided mesh is reduced from 2.4GB to 1.79GB. This is about 25% less which is the expected amount because in `main` there are 4 copies of the data: 1. The original data which is allocated when the file is loaded. 2. The copy for the depsgraph allocated during depsgraph evaluation. 3. The copy for the undo system allocated when the first undo step is created right after loading the file. 4. GPU buffers allocated for drawing. This patch only gets rid of copy number 2 for the depsgraph. In theory the other copies can be removed as part of follow up PRs as well though. ----- The patch has three main components: * Slightly modified `CustomData` API to make it work better with implicit sharing: * `CD_REFERENCE` and `CD_DUPLICATE` have been removed because they are meaningless when implicit-sharing is used. * `CD_ASSIGN` has been removed as well because it's not an allocation type anyway. The functionality of using existing arrays as custom data layers has not been removed though. * This can still be done with `CustomData_add_layer_with_data` which also has a new argument that allows passing in information about whether the array is shared. * `CD_FLAG_NOFREE` has been removed because it's no longer necessary. It only existed because of `CD_REFERENCE`. * `CustomData_copy` and `CustomData_merge` have been split up into a functions that do copy the actual attribute values and those that do not. The latter functions now have the `_layout` suffix (e.g. `CustomData_copy_layout`). * Changes in `customdata.cc` to make it actually use implicit-sharing. * Changes in various other files to adapt to the changes in `BKE_customdata.h`. Pull Request: https://projects.blender.org/blender/blender/pulls/106228
2023-04-13 14:57:57 +02:00
eCustomDataMask mask,
eCDAllocType alloctype,
int totelem);
/**
* Reallocate custom data to a new element count. If the new size is larger, the new values use
* the #CD_CONSTRUCT behavior, so trivial types must be initialized by the caller. After being
* resized, the #CustomData does not contain any referenced layers.
*/
void CustomData_realloc(CustomData *data,
int old_size,
int new_size,
eCDAllocType alloctype = CD_CONSTRUCT);
/**
Custom Data: support implicit sharing for custom data layers This integrates the new implicit-sharing system (from fbcddfcd68adc72f) with `CustomData`. Now the potentially long arrays referenced by custom data layers can be shared between different systems but most importantly between different geometries. This makes e.g. copying a mesh much cheaper because none of the attributes has to be copied. Only when an attribute is modified does it have to be copied. Also see the original design task: #95845. This reduces memory and improves performance by avoiding unnecessary data copies. For example, the used memory after loading a highly subdivided mesh is reduced from 2.4GB to 1.79GB. This is about 25% less which is the expected amount because in `main` there are 4 copies of the data: 1. The original data which is allocated when the file is loaded. 2. The copy for the depsgraph allocated during depsgraph evaluation. 3. The copy for the undo system allocated when the first undo step is created right after loading the file. 4. GPU buffers allocated for drawing. This patch only gets rid of copy number 2 for the depsgraph. In theory the other copies can be removed as part of follow up PRs as well though. ----- The patch has three main components: * Slightly modified `CustomData` API to make it work better with implicit sharing: * `CD_REFERENCE` and `CD_DUPLICATE` have been removed because they are meaningless when implicit-sharing is used. * `CD_ASSIGN` has been removed as well because it's not an allocation type anyway. The functionality of using existing arrays as custom data layers has not been removed though. * This can still be done with `CustomData_add_layer_with_data` which also has a new argument that allows passing in information about whether the array is shared. * `CD_FLAG_NOFREE` has been removed because it's no longer necessary. It only existed because of `CD_REFERENCE`. * `CustomData_copy` and `CustomData_merge` have been split up into a functions that do copy the actual attribute values and those that do not. The latter functions now have the `_layout` suffix (e.g. `CustomData_copy_layout`). * Changes in `customdata.cc` to make it actually use implicit-sharing. * Changes in various other files to adapt to the changes in `BKE_customdata.h`. Pull Request: https://projects.blender.org/blender/blender/pulls/106228
2023-04-13 14:57:57 +02:00
* BMesh version of CustomData_merge_layout; merges the layouts of source and `dest`,
* then goes through the mesh and makes sure all the custom-data blocks are
* consistent with the new layout.
*/
bool CustomData_bmesh_merge_layout(const CustomData *source,
CustomData *dest,
Custom Data: support implicit sharing for custom data layers This integrates the new implicit-sharing system (from fbcddfcd68adc72f) with `CustomData`. Now the potentially long arrays referenced by custom data layers can be shared between different systems but most importantly between different geometries. This makes e.g. copying a mesh much cheaper because none of the attributes has to be copied. Only when an attribute is modified does it have to be copied. Also see the original design task: #95845. This reduces memory and improves performance by avoiding unnecessary data copies. For example, the used memory after loading a highly subdivided mesh is reduced from 2.4GB to 1.79GB. This is about 25% less which is the expected amount because in `main` there are 4 copies of the data: 1. The original data which is allocated when the file is loaded. 2. The copy for the depsgraph allocated during depsgraph evaluation. 3. The copy for the undo system allocated when the first undo step is created right after loading the file. 4. GPU buffers allocated for drawing. This patch only gets rid of copy number 2 for the depsgraph. In theory the other copies can be removed as part of follow up PRs as well though. ----- The patch has three main components: * Slightly modified `CustomData` API to make it work better with implicit sharing: * `CD_REFERENCE` and `CD_DUPLICATE` have been removed because they are meaningless when implicit-sharing is used. * `CD_ASSIGN` has been removed as well because it's not an allocation type anyway. The functionality of using existing arrays as custom data layers has not been removed though. * This can still be done with `CustomData_add_layer_with_data` which also has a new argument that allows passing in information about whether the array is shared. * `CD_FLAG_NOFREE` has been removed because it's no longer necessary. It only existed because of `CD_REFERENCE`. * `CustomData_copy` and `CustomData_merge` have been split up into a functions that do copy the actual attribute values and those that do not. The latter functions now have the `_layout` suffix (e.g. `CustomData_copy_layout`). * Changes in `customdata.cc` to make it actually use implicit-sharing. * Changes in various other files to adapt to the changes in `BKE_customdata.h`. Pull Request: https://projects.blender.org/blender/blender/pulls/106228
2023-04-13 14:57:57 +02:00
eCustomDataMask mask,
eCDAllocType alloctype,
BMesh *bm,
Custom Data: support implicit sharing for custom data layers This integrates the new implicit-sharing system (from fbcddfcd68adc72f) with `CustomData`. Now the potentially long arrays referenced by custom data layers can be shared between different systems but most importantly between different geometries. This makes e.g. copying a mesh much cheaper because none of the attributes has to be copied. Only when an attribute is modified does it have to be copied. Also see the original design task: #95845. This reduces memory and improves performance by avoiding unnecessary data copies. For example, the used memory after loading a highly subdivided mesh is reduced from 2.4GB to 1.79GB. This is about 25% less which is the expected amount because in `main` there are 4 copies of the data: 1. The original data which is allocated when the file is loaded. 2. The copy for the depsgraph allocated during depsgraph evaluation. 3. The copy for the undo system allocated when the first undo step is created right after loading the file. 4. GPU buffers allocated for drawing. This patch only gets rid of copy number 2 for the depsgraph. In theory the other copies can be removed as part of follow up PRs as well though. ----- The patch has three main components: * Slightly modified `CustomData` API to make it work better with implicit sharing: * `CD_REFERENCE` and `CD_DUPLICATE` have been removed because they are meaningless when implicit-sharing is used. * `CD_ASSIGN` has been removed as well because it's not an allocation type anyway. The functionality of using existing arrays as custom data layers has not been removed though. * This can still be done with `CustomData_add_layer_with_data` which also has a new argument that allows passing in information about whether the array is shared. * `CD_FLAG_NOFREE` has been removed because it's no longer necessary. It only existed because of `CD_REFERENCE`. * `CustomData_copy` and `CustomData_merge` have been split up into a functions that do copy the actual attribute values and those that do not. The latter functions now have the `_layout` suffix (e.g. `CustomData_copy_layout`). * Changes in `customdata.cc` to make it actually use implicit-sharing. * Changes in various other files to adapt to the changes in `BKE_customdata.h`. Pull Request: https://projects.blender.org/blender/blender/pulls/106228
2023-04-13 14:57:57 +02:00
char htype);
/**
* Remove layers that aren't stored in BMesh or are stored as flags on BMesh.
* The `layers` array of the returned #CustomData must be freed, but may be null.
* Used during conversion of #Mesh data to #BMesh storage format.
*/
CustomData CustomData_shallow_copy_remove_non_bmesh_attributes(const CustomData *src,
eCustomDataMask mask);
/**
* NULL's all members and resets the #CustomData.typemap.
*/
void CustomData_reset(CustomData *data);
/**
* Frees data associated with a CustomData object (doesn't free the object itself, though).
*/
void CustomData_free(CustomData *data, int totelem);
Added custom vertex/edge/face data for meshes: All data layers, including MVert/MEdge/MFace, are now managed as custom data layers. The pointers like Mesh.mvert, Mesh.dvert or Mesh.mcol are still used of course, but allocating, copying or freeing these arrays should be done through the CustomData API. Work in progress documentation on this is here: http://mediawiki.blender.org/index.php/BlenderDev/BlenderArchitecture/CustomData Replaced TFace by MTFace: This is the same struct, except that it does not contain color, that now always stays separated in MCol. This was not a good design decision to begin with, and it is needed for adding multiple color layers later. Note that this does mean older Blender versions will not be able to read UV coordinates from the next release, due to an SDNA limitation. Removed DispListMesh: This now fully replaced by DerivedMesh. To provide access to arrays of vertices, edges and faces, like DispListMesh does. The semantics of the DerivedMesh.getVertArray() and similar functions were changed to return a pointer to an array if one exists, or otherwise allocate a temporary one. On releasing the DerivedMesh, this temporary array will be removed automatically. Removed ssDM and meshDM DerivedMesh backends: The ssDM backend was for DispListMesh, so that became obsolete automatically. The meshDM backend was replaced by the custom data backend, that now figures out which layers need to be modified, and only duplicates those. This changes code in many places, and overall removes 2514 lines of code. So, there's a good chance this might break some stuff, although I've been testing it for a few days now. The good news is, adding multiple color and uv layers should now become easy.
2006-11-20 05:28:02 +01:00
/**
* Same as above, but only frees layers which matches the given mask.
*/
void CustomData_free_typemask(CustomData *data, int totelem, eCustomDataMask mask);
/**
Custom Data: support implicit sharing for custom data layers This integrates the new implicit-sharing system (from fbcddfcd68adc72f) with `CustomData`. Now the potentially long arrays referenced by custom data layers can be shared between different systems but most importantly between different geometries. This makes e.g. copying a mesh much cheaper because none of the attributes has to be copied. Only when an attribute is modified does it have to be copied. Also see the original design task: #95845. This reduces memory and improves performance by avoiding unnecessary data copies. For example, the used memory after loading a highly subdivided mesh is reduced from 2.4GB to 1.79GB. This is about 25% less which is the expected amount because in `main` there are 4 copies of the data: 1. The original data which is allocated when the file is loaded. 2. The copy for the depsgraph allocated during depsgraph evaluation. 3. The copy for the undo system allocated when the first undo step is created right after loading the file. 4. GPU buffers allocated for drawing. This patch only gets rid of copy number 2 for the depsgraph. In theory the other copies can be removed as part of follow up PRs as well though. ----- The patch has three main components: * Slightly modified `CustomData` API to make it work better with implicit sharing: * `CD_REFERENCE` and `CD_DUPLICATE` have been removed because they are meaningless when implicit-sharing is used. * `CD_ASSIGN` has been removed as well because it's not an allocation type anyway. The functionality of using existing arrays as custom data layers has not been removed though. * This can still be done with `CustomData_add_layer_with_data` which also has a new argument that allows passing in information about whether the array is shared. * `CD_FLAG_NOFREE` has been removed because it's no longer necessary. It only existed because of `CD_REFERENCE`. * `CustomData_copy` and `CustomData_merge` have been split up into a functions that do copy the actual attribute values and those that do not. The latter functions now have the `_layout` suffix (e.g. `CustomData_copy_layout`). * Changes in `customdata.cc` to make it actually use implicit-sharing. * Changes in various other files to adapt to the changes in `BKE_customdata.h`. Pull Request: https://projects.blender.org/blender/blender/pulls/106228
2023-04-13 14:57:57 +02:00
* Adds a layer of the given type to the #CustomData object. The new layer is initialized based on
* the given alloctype.
* \return The layer data.
*/
void *CustomData_add_layer(CustomData *data,
eCustomDataType type,
eCDAllocType alloctype,
int totelem);
Custom Data: support implicit sharing for custom data layers This integrates the new implicit-sharing system (from fbcddfcd68adc72f) with `CustomData`. Now the potentially long arrays referenced by custom data layers can be shared between different systems but most importantly between different geometries. This makes e.g. copying a mesh much cheaper because none of the attributes has to be copied. Only when an attribute is modified does it have to be copied. Also see the original design task: #95845. This reduces memory and improves performance by avoiding unnecessary data copies. For example, the used memory after loading a highly subdivided mesh is reduced from 2.4GB to 1.79GB. This is about 25% less which is the expected amount because in `main` there are 4 copies of the data: 1. The original data which is allocated when the file is loaded. 2. The copy for the depsgraph allocated during depsgraph evaluation. 3. The copy for the undo system allocated when the first undo step is created right after loading the file. 4. GPU buffers allocated for drawing. This patch only gets rid of copy number 2 for the depsgraph. In theory the other copies can be removed as part of follow up PRs as well though. ----- The patch has three main components: * Slightly modified `CustomData` API to make it work better with implicit sharing: * `CD_REFERENCE` and `CD_DUPLICATE` have been removed because they are meaningless when implicit-sharing is used. * `CD_ASSIGN` has been removed as well because it's not an allocation type anyway. The functionality of using existing arrays as custom data layers has not been removed though. * This can still be done with `CustomData_add_layer_with_data` which also has a new argument that allows passing in information about whether the array is shared. * `CD_FLAG_NOFREE` has been removed because it's no longer necessary. It only existed because of `CD_REFERENCE`. * `CustomData_copy` and `CustomData_merge` have been split up into a functions that do copy the actual attribute values and those that do not. The latter functions now have the `_layout` suffix (e.g. `CustomData_copy_layout`). * Changes in `customdata.cc` to make it actually use implicit-sharing. * Changes in various other files to adapt to the changes in `BKE_customdata.h`. Pull Request: https://projects.blender.org/blender/blender/pulls/106228
2023-04-13 14:57:57 +02:00
/**
* Adds a layer of the given type to the #CustomData object. The new layer takes ownership of the
* passed in `layer_data`. If a #ImplicitSharingInfoHandle is passed in, its user count is
* increased.
*/
const void *CustomData_add_layer_with_data(CustomData *data,
eCustomDataType type,
void *layer_data,
Custom Data: support implicit sharing for custom data layers This integrates the new implicit-sharing system (from fbcddfcd68adc72f) with `CustomData`. Now the potentially long arrays referenced by custom data layers can be shared between different systems but most importantly between different geometries. This makes e.g. copying a mesh much cheaper because none of the attributes has to be copied. Only when an attribute is modified does it have to be copied. Also see the original design task: #95845. This reduces memory and improves performance by avoiding unnecessary data copies. For example, the used memory after loading a highly subdivided mesh is reduced from 2.4GB to 1.79GB. This is about 25% less which is the expected amount because in `main` there are 4 copies of the data: 1. The original data which is allocated when the file is loaded. 2. The copy for the depsgraph allocated during depsgraph evaluation. 3. The copy for the undo system allocated when the first undo step is created right after loading the file. 4. GPU buffers allocated for drawing. This patch only gets rid of copy number 2 for the depsgraph. In theory the other copies can be removed as part of follow up PRs as well though. ----- The patch has three main components: * Slightly modified `CustomData` API to make it work better with implicit sharing: * `CD_REFERENCE` and `CD_DUPLICATE` have been removed because they are meaningless when implicit-sharing is used. * `CD_ASSIGN` has been removed as well because it's not an allocation type anyway. The functionality of using existing arrays as custom data layers has not been removed though. * This can still be done with `CustomData_add_layer_with_data` which also has a new argument that allows passing in information about whether the array is shared. * `CD_FLAG_NOFREE` has been removed because it's no longer necessary. It only existed because of `CD_REFERENCE`. * `CustomData_copy` and `CustomData_merge` have been split up into a functions that do copy the actual attribute values and those that do not. The latter functions now have the `_layout` suffix (e.g. `CustomData_copy_layout`). * Changes in `customdata.cc` to make it actually use implicit-sharing. * Changes in various other files to adapt to the changes in `BKE_customdata.h`. Pull Request: https://projects.blender.org/blender/blender/pulls/106228
2023-04-13 14:57:57 +02:00
int totelem,
const ImplicitSharingInfoHandle *sharing_info);
/**
* Same as above but accepts a name.
*/
void *CustomData_add_layer_named(
CustomData *data, eCustomDataType type, eCDAllocType alloctype, int totelem, const char *name);
Custom Data: support implicit sharing for custom data layers This integrates the new implicit-sharing system (from fbcddfcd68adc72f) with `CustomData`. Now the potentially long arrays referenced by custom data layers can be shared between different systems but most importantly between different geometries. This makes e.g. copying a mesh much cheaper because none of the attributes has to be copied. Only when an attribute is modified does it have to be copied. Also see the original design task: #95845. This reduces memory and improves performance by avoiding unnecessary data copies. For example, the used memory after loading a highly subdivided mesh is reduced from 2.4GB to 1.79GB. This is about 25% less which is the expected amount because in `main` there are 4 copies of the data: 1. The original data which is allocated when the file is loaded. 2. The copy for the depsgraph allocated during depsgraph evaluation. 3. The copy for the undo system allocated when the first undo step is created right after loading the file. 4. GPU buffers allocated for drawing. This patch only gets rid of copy number 2 for the depsgraph. In theory the other copies can be removed as part of follow up PRs as well though. ----- The patch has three main components: * Slightly modified `CustomData` API to make it work better with implicit sharing: * `CD_REFERENCE` and `CD_DUPLICATE` have been removed because they are meaningless when implicit-sharing is used. * `CD_ASSIGN` has been removed as well because it's not an allocation type anyway. The functionality of using existing arrays as custom data layers has not been removed though. * This can still be done with `CustomData_add_layer_with_data` which also has a new argument that allows passing in information about whether the array is shared. * `CD_FLAG_NOFREE` has been removed because it's no longer necessary. It only existed because of `CD_REFERENCE`. * `CustomData_copy` and `CustomData_merge` have been split up into a functions that do copy the actual attribute values and those that do not. The latter functions now have the `_layout` suffix (e.g. `CustomData_copy_layout`). * Changes in `customdata.cc` to make it actually use implicit-sharing. * Changes in various other files to adapt to the changes in `BKE_customdata.h`. Pull Request: https://projects.blender.org/blender/blender/pulls/106228
2023-04-13 14:57:57 +02:00
const void *CustomData_add_layer_named_with_data(CustomData *data,
eCustomDataType type,
void *layer_data,
int totelem,
Custom Data: support implicit sharing for custom data layers This integrates the new implicit-sharing system (from fbcddfcd68adc72f) with `CustomData`. Now the potentially long arrays referenced by custom data layers can be shared between different systems but most importantly between different geometries. This makes e.g. copying a mesh much cheaper because none of the attributes has to be copied. Only when an attribute is modified does it have to be copied. Also see the original design task: #95845. This reduces memory and improves performance by avoiding unnecessary data copies. For example, the used memory after loading a highly subdivided mesh is reduced from 2.4GB to 1.79GB. This is about 25% less which is the expected amount because in `main` there are 4 copies of the data: 1. The original data which is allocated when the file is loaded. 2. The copy for the depsgraph allocated during depsgraph evaluation. 3. The copy for the undo system allocated when the first undo step is created right after loading the file. 4. GPU buffers allocated for drawing. This patch only gets rid of copy number 2 for the depsgraph. In theory the other copies can be removed as part of follow up PRs as well though. ----- The patch has three main components: * Slightly modified `CustomData` API to make it work better with implicit sharing: * `CD_REFERENCE` and `CD_DUPLICATE` have been removed because they are meaningless when implicit-sharing is used. * `CD_ASSIGN` has been removed as well because it's not an allocation type anyway. The functionality of using existing arrays as custom data layers has not been removed though. * This can still be done with `CustomData_add_layer_with_data` which also has a new argument that allows passing in information about whether the array is shared. * `CD_FLAG_NOFREE` has been removed because it's no longer necessary. It only existed because of `CD_REFERENCE`. * `CustomData_copy` and `CustomData_merge` have been split up into a functions that do copy the actual attribute values and those that do not. The latter functions now have the `_layout` suffix (e.g. `CustomData_copy_layout`). * Changes in `customdata.cc` to make it actually use implicit-sharing. * Changes in various other files to adapt to the changes in `BKE_customdata.h`. Pull Request: https://projects.blender.org/blender/blender/pulls/106228
2023-04-13 14:57:57 +02:00
const char *name,
const ImplicitSharingInfoHandle *sharing_info);
void *CustomData_add_layer_anonymous(CustomData *data,
eCustomDataType type,
eCDAllocType alloctype,
int totelem,
const AnonymousAttributeIDHandle *anonymous_id);
Custom Data: support implicit sharing for custom data layers This integrates the new implicit-sharing system (from fbcddfcd68adc72f) with `CustomData`. Now the potentially long arrays referenced by custom data layers can be shared between different systems but most importantly between different geometries. This makes e.g. copying a mesh much cheaper because none of the attributes has to be copied. Only when an attribute is modified does it have to be copied. Also see the original design task: #95845. This reduces memory and improves performance by avoiding unnecessary data copies. For example, the used memory after loading a highly subdivided mesh is reduced from 2.4GB to 1.79GB. This is about 25% less which is the expected amount because in `main` there are 4 copies of the data: 1. The original data which is allocated when the file is loaded. 2. The copy for the depsgraph allocated during depsgraph evaluation. 3. The copy for the undo system allocated when the first undo step is created right after loading the file. 4. GPU buffers allocated for drawing. This patch only gets rid of copy number 2 for the depsgraph. In theory the other copies can be removed as part of follow up PRs as well though. ----- The patch has three main components: * Slightly modified `CustomData` API to make it work better with implicit sharing: * `CD_REFERENCE` and `CD_DUPLICATE` have been removed because they are meaningless when implicit-sharing is used. * `CD_ASSIGN` has been removed as well because it's not an allocation type anyway. The functionality of using existing arrays as custom data layers has not been removed though. * This can still be done with `CustomData_add_layer_with_data` which also has a new argument that allows passing in information about whether the array is shared. * `CD_FLAG_NOFREE` has been removed because it's no longer necessary. It only existed because of `CD_REFERENCE`. * `CustomData_copy` and `CustomData_merge` have been split up into a functions that do copy the actual attribute values and those that do not. The latter functions now have the `_layout` suffix (e.g. `CustomData_copy_layout`). * Changes in `customdata.cc` to make it actually use implicit-sharing. * Changes in various other files to adapt to the changes in `BKE_customdata.h`. Pull Request: https://projects.blender.org/blender/blender/pulls/106228
2023-04-13 14:57:57 +02:00
const void *CustomData_add_layer_anonymous_with_data(
CustomData *data,
Custom Data: support implicit sharing for custom data layers This integrates the new implicit-sharing system (from fbcddfcd68adc72f) with `CustomData`. Now the potentially long arrays referenced by custom data layers can be shared between different systems but most importantly between different geometries. This makes e.g. copying a mesh much cheaper because none of the attributes has to be copied. Only when an attribute is modified does it have to be copied. Also see the original design task: #95845. This reduces memory and improves performance by avoiding unnecessary data copies. For example, the used memory after loading a highly subdivided mesh is reduced from 2.4GB to 1.79GB. This is about 25% less which is the expected amount because in `main` there are 4 copies of the data: 1. The original data which is allocated when the file is loaded. 2. The copy for the depsgraph allocated during depsgraph evaluation. 3. The copy for the undo system allocated when the first undo step is created right after loading the file. 4. GPU buffers allocated for drawing. This patch only gets rid of copy number 2 for the depsgraph. In theory the other copies can be removed as part of follow up PRs as well though. ----- The patch has three main components: * Slightly modified `CustomData` API to make it work better with implicit sharing: * `CD_REFERENCE` and `CD_DUPLICATE` have been removed because they are meaningless when implicit-sharing is used. * `CD_ASSIGN` has been removed as well because it's not an allocation type anyway. The functionality of using existing arrays as custom data layers has not been removed though. * This can still be done with `CustomData_add_layer_with_data` which also has a new argument that allows passing in information about whether the array is shared. * `CD_FLAG_NOFREE` has been removed because it's no longer necessary. It only existed because of `CD_REFERENCE`. * `CustomData_copy` and `CustomData_merge` have been split up into a functions that do copy the actual attribute values and those that do not. The latter functions now have the `_layout` suffix (e.g. `CustomData_copy_layout`). * Changes in `customdata.cc` to make it actually use implicit-sharing. * Changes in various other files to adapt to the changes in `BKE_customdata.h`. Pull Request: https://projects.blender.org/blender/blender/pulls/106228
2023-04-13 14:57:57 +02:00
eCustomDataType type,
const AnonymousAttributeIDHandle *anonymous_id,
int totelem,
void *layer_data,
const ImplicitSharingInfoHandle *sharing_info);
/**
* Frees the active or first data layer with the give type.
* returns 1 on success, 0 if no layer with the given type is found
*
* In edit-mode, use #EDBM_data_layer_free instead of this function.
*/
bool CustomData_free_layer(CustomData *data, eCustomDataType type, int totelem, int index);
bool CustomData_free_layer_named(CustomData *data, const char *name, const int totelem);
/**
* Frees the layer index with the give type.
* returns 1 on success, 0 if no layer with the given type is found.
*
* In edit-mode, use #EDBM_data_layer_free instead of this function.
*/
bool CustomData_free_layer_active(CustomData *data, eCustomDataType type, int totelem);
/**
* Same as above, but free all layers with type.
*/
void CustomData_free_layers(CustomData *data, eCustomDataType type, int totelem);
/**
* Returns true if a layer with the specified type exists.
*/
bool CustomData_has_layer(const CustomData *data, eCustomDataType type);
bool CustomData_has_layer_named(const CustomData *data, eCustomDataType type, const char *name);
/**
* Returns the number of layers with this type.
*/
int CustomData_number_of_layers(const CustomData *data, eCustomDataType type);
int CustomData_number_of_anonymous_layers(const CustomData *data, eCustomDataType type);
int CustomData_number_of_layers_typemask(const CustomData *data, eCustomDataMask mask);
/**
* Set the #CD_FLAG_NOCOPY flag in custom data layers where the mask is
* zero for the layer type, so only layer types specified by the mask will be copied
*/
void CustomData_set_only_copy(const CustomData *data, eCustomDataMask mask);
/**
* Copies data from one CustomData object to another
* objects need not be compatible, each source layer is copied to the
* first dest layer of correct type (if there is none, the layer is skipped).
*/
void CustomData_copy_data(
const CustomData *source, CustomData *dest, int source_index, int dest_index, int count);
void CustomData_copy_data_layer(const CustomData *source,
CustomData *dest,
int src_layer_index,
int dst_layer_index,
int src_index,
int dst_index,
int count);
void CustomData_copy_data_named(
const CustomData *source, CustomData *dest, int source_index, int dest_index, int count);
void CustomData_copy_elements(eCustomDataType type,
void *src_data_ofs,
void *dst_data_ofs,
int count);
void CustomData_bmesh_copy_data(const CustomData *source,
CustomData *dest,
2018-06-17 17:05:51 +02:00
void *src_block,
2011-12-28 10:14:09 +01:00
void **dest_block);
void CustomData_bmesh_copy_data_exclude_by_type(const CustomData *source,
CustomData *dest,
void *src_block,
void **dest_block,
eCustomDataMask mask_exclude);
/**
* Copies data of a single layer of a given type.
*/
void CustomData_copy_layer_type_data(const CustomData *source,
CustomData *destination,
eCustomDataType type,
int source_index,
int destination_index,
int count);
/**
* Frees data in a #CustomData object. This is only expected to be called if the data layers are
* not shared (#CustomData_ensure_layers_are_mutable).
*/
void CustomData_free_elem(CustomData *data, int index, int count);
/**
* Interpolate given custom data source items into a single destination one.
*
* \param src_indices: Indices of every source items to interpolate into the destination one.
* \param weights: The weight to apply to each source value individually. If NULL, they will be
* averaged.
* \param sub_weights: The weights of sub-items, only used to affect each corners of a
* tessellated face data (should always be and array of four values).
* \param count: The number of source items to interpolate.
* \param dest_index: Index of the destination item, in which to put the result of the
* interpolation.
*/
void CustomData_interp(const CustomData *source,
CustomData *dest,
2016-05-16 19:07:40 +02:00
const int *src_indices,
const float *weights,
const float *sub_weights,
int count,
int dest_index);
/**
* \note src_blocks_ofs & dst_block_ofs
* must be pointers to the data, offset by layer->offset already.
*/
void CustomData_bmesh_interp_n(CustomData *data,
const void **src_blocks,
const float *weights,
const float *sub_weights,
int count,
void *dst_block_ofs,
int n);
void CustomData_bmesh_interp(CustomData *data,
const void **src_blocks,
const float *weights,
const float *sub_weights,
int count,
void *dst_block);
Added custom vertex/edge/face data for meshes: All data layers, including MVert/MEdge/MFace, are now managed as custom data layers. The pointers like Mesh.mvert, Mesh.dvert or Mesh.mcol are still used of course, but allocating, copying or freeing these arrays should be done through the CustomData API. Work in progress documentation on this is here: http://mediawiki.blender.org/index.php/BlenderDev/BlenderArchitecture/CustomData Replaced TFace by MTFace: This is the same struct, except that it does not contain color, that now always stays separated in MCol. This was not a good design decision to begin with, and it is needed for adding multiple color layers later. Note that this does mean older Blender versions will not be able to read UV coordinates from the next release, due to an SDNA limitation. Removed DispListMesh: This now fully replaced by DerivedMesh. To provide access to arrays of vertices, edges and faces, like DispListMesh does. The semantics of the DerivedMesh.getVertArray() and similar functions were changed to return a pointer to an array if one exists, or otherwise allocate a temporary one. On releasing the DerivedMesh, this temporary array will be removed automatically. Removed ssDM and meshDM DerivedMesh backends: The ssDM backend was for DispListMesh, so that became obsolete automatically. The meshDM backend was replaced by the custom data backend, that now figures out which layers need to be modified, and only duplicates those. This changes code in many places, and overall removes 2514 lines of code. So, there's a good chance this might break some stuff, although I've been testing it for a few days now. The good news is, adding multiple color and uv layers should now become easy.
2006-11-20 05:28:02 +01:00
/**
* Swap data inside each item, for all layers.
* This only applies to item types that may store several sub-item data
* (e.g. corner data [UVs, VCol, ...] of tessellated faces).
*
* \param corner_indices: A mapping 'new_index -> old_index' of sub-item data.
*/
void CustomData_swap_corners(CustomData *data, int index, const int *corner_indices);
/**
* Custom data layers can be shared through implicit sharing (`BLI_implicit_sharing.h`). This
* function makes sure that the layer is unshared if it was shared, which makes it mutable.
*/
void CustomData_ensure_data_is_mutable(CustomDataLayer *layer, int totelem);
void CustomData_ensure_layers_are_mutable(CustomData *data, int totelem);
/**
* Retrieve a pointer to an element of the active layer of the given \a type, chosen by the
* \a index, if it exists.
*/
void *CustomData_get_for_write(CustomData *data, int index, eCustomDataType type, int totelem);
/**
* Retrieve a pointer to an element of the \a nth layer of the given \a type, chosen by the
* \a index, if it exists.
*/
void *CustomData_get_n_for_write(
CustomData *data, eCustomDataType type, int index, int n, int totelem);
/* BMesh Custom Data Functions.
* Should replace edit-mesh ones with these as well, due to more efficient memory alloc. */
void *CustomData_bmesh_get(const CustomData *data, void *block, eCustomDataType type);
void *CustomData_bmesh_get_n(const CustomData *data, void *block, eCustomDataType type, int n);
/**
* Gets from the layer at physical index `n`,
* \note doesn't check type.
*/
void *CustomData_bmesh_get_layer_n(const CustomData *data, void *block, int n);
bool CustomData_set_layer_name(CustomData *data, eCustomDataType type, int n, const char *name);
const char *CustomData_get_layer_name(const CustomData *data, eCustomDataType type, int n);
/**
* Retrieve the data array of the active layer of the given \a type, if it exists. Return null
* otherwise.
*/
const void *CustomData_get_layer(const CustomData *data, eCustomDataType type);
void *CustomData_get_layer_for_write(CustomData *data, eCustomDataType type, int totelem);
/**
* Retrieve the data array of the \a nth layer of the given \a type, if it exists. Return null
* otherwise.
*/
const void *CustomData_get_layer_n(const CustomData *data, eCustomDataType type, int n);
void *CustomData_get_layer_n_for_write(CustomData *data, eCustomDataType type, int n, int totelem);
/**
* Retrieve the data array of the layer with the given \a name and \a type, if it exists. Return
* null otherwise.
*/
const void *CustomData_get_layer_named(const CustomData *data,
eCustomDataType type,
const char *name);
void *CustomData_get_layer_named_for_write(CustomData *data,
eCustomDataType type,
const char *name,
int totelem);
int CustomData_get_offset(const CustomData *data, eCustomDataType type);
int CustomData_get_offset_named(const CustomData *data, eCustomDataType type, const char *name);
int CustomData_get_n_offset(const CustomData *data, eCustomDataType type, int n);
int CustomData_get_layer_index(const CustomData *data, eCustomDataType type);
int CustomData_get_layer_index_n(const CustomData *data, eCustomDataType type, int n);
int CustomData_get_named_layer_index(const CustomData *data,
eCustomDataType type,
const char *name);
int CustomData_get_named_layer_index_notype(const CustomData *data, const char *name);
int CustomData_get_active_layer_index(const CustomData *data, eCustomDataType type);
int CustomData_get_render_layer_index(const CustomData *data, eCustomDataType type);
int CustomData_get_clone_layer_index(const CustomData *data, eCustomDataType type);
int CustomData_get_stencil_layer_index(const CustomData *data, eCustomDataType type);
int CustomData_get_named_layer(const CustomData *data, eCustomDataType type, const char *name);
int CustomData_get_active_layer(const CustomData *data, eCustomDataType type);
int CustomData_get_render_layer(const CustomData *data, eCustomDataType type);
int CustomData_get_clone_layer(const CustomData *data, eCustomDataType type);
int CustomData_get_stencil_layer(const CustomData *data, eCustomDataType type);
/**
* Returns name of the active layer of the given type or NULL
* if no such active layer is defined.
*/
const char *CustomData_get_active_layer_name(const CustomData *data, eCustomDataType type);
/**
* Returns name of the default layer of the given type or NULL
* if no such active layer is defined.
*/
const char *CustomData_get_render_layer_name(const CustomData *data, eCustomDataType type);
bool CustomData_layer_is_anonymous(const CustomData *data, eCustomDataType type, int n);
void CustomData_bmesh_set(const CustomData *data,
2015-02-23 05:55:48 +01:00
void *block,
eCustomDataType type,
2015-02-23 05:55:48 +01:00
const void *source);
2015-02-23 05:55:48 +01:00
void CustomData_bmesh_set_n(
CustomData *data, void *block, eCustomDataType type, int n, const void *source);
/**
* Sets the nth layer of type as active.
*/
void CustomData_set_layer_active(CustomData *data, eCustomDataType type, int n);
void CustomData_set_layer_render(CustomData *data, eCustomDataType type, int n);
void CustomData_set_layer_clone(CustomData *data, eCustomDataType type, int n);
void CustomData_set_layer_stencil(CustomData *data, eCustomDataType type, int n);
/**
* For using with an index from #CustomData_get_active_layer_index and
* #CustomData_get_render_layer_index.
*/
void CustomData_set_layer_active_index(CustomData *data, eCustomDataType type, int n);
void CustomData_set_layer_render_index(CustomData *data, eCustomDataType type, int n);
void CustomData_set_layer_clone_index(CustomData *data, eCustomDataType type, int n);
void CustomData_set_layer_stencil_index(CustomData *data, eCustomDataType type, int n);
/**
* Adds flag to the layer flags.
*/
void CustomData_set_layer_flag(CustomData *data, eCustomDataType type, int flag);
void CustomData_clear_layer_flag(CustomData *data, eCustomDataType type, int flag);
void CustomData_bmesh_set_default(CustomData *data, void **block);
void CustomData_bmesh_free_block(CustomData *data, void **block);
void CustomData_bmesh_alloc_block(CustomData *data, void **block);
/**
* Same as #CustomData_bmesh_free_block but zero the memory rather than freeing.
*/
void CustomData_bmesh_free_block_data(CustomData *data, void *block);
/**
* A selective version of #CustomData_bmesh_free_block_data.
*/
void CustomData_bmesh_free_block_data_exclude_by_type(CustomData *data,
void *block,
eCustomDataMask mask_exclude);
/**
* Query info over types.
*/
void CustomData_file_write_info(eCustomDataType type,
const char **r_struct_name,
int *r_struct_num);
int CustomData_sizeof(eCustomDataType type);
Added custom vertex/edge/face data for meshes: All data layers, including MVert/MEdge/MFace, are now managed as custom data layers. The pointers like Mesh.mvert, Mesh.dvert or Mesh.mcol are still used of course, but allocating, copying or freeing these arrays should be done through the CustomData API. Work in progress documentation on this is here: http://mediawiki.blender.org/index.php/BlenderDev/BlenderArchitecture/CustomData Replaced TFace by MTFace: This is the same struct, except that it does not contain color, that now always stays separated in MCol. This was not a good design decision to begin with, and it is needed for adding multiple color layers later. Note that this does mean older Blender versions will not be able to read UV coordinates from the next release, due to an SDNA limitation. Removed DispListMesh: This now fully replaced by DerivedMesh. To provide access to arrays of vertices, edges and faces, like DispListMesh does. The semantics of the DerivedMesh.getVertArray() and similar functions were changed to return a pointer to an array if one exists, or otherwise allocate a temporary one. On releasing the DerivedMesh, this temporary array will be removed automatically. Removed ssDM and meshDM DerivedMesh backends: The ssDM backend was for DispListMesh, so that became obsolete automatically. The meshDM backend was replaced by the custom data backend, that now figures out which layers need to be modified, and only duplicates those. This changes code in many places, and overall removes 2514 lines of code. So, there's a good chance this might break some stuff, although I've been testing it for a few days now. The good news is, adding multiple color and uv layers should now become easy.
2006-11-20 05:28:02 +01:00
/**
* Get the name of a layer type.
*/
const char *CustomData_layertype_name(eCustomDataType type);
/**
* Can only ever be one of these.
*/
bool CustomData_layertype_is_singleton(eCustomDataType type);
/**
* Has dynamically allocated members.
* This is useful to know if operations such as #memcmp are
* valid when comparing data from two layers.
*/
bool CustomData_layertype_is_dynamic(eCustomDataType type);
/**
* \return Maximum number of layers of given \a type, -1 means 'no limit'.
*/
int CustomData_layertype_layers_max(eCustomDataType type);
/** \return The maximum size in bytes needed for a layer name with the given prefix. */
int CustomData_name_maxncpy_calc(blender::StringRef name);
Mesh: Move UV layers to generic attributes Currently the `MLoopUV` struct stores UV coordinates and flags related to editing UV maps in the UV editor. This patch changes the coordinates to use the generic 2D vector type, and moves the flags into three separate boolean attributes. This follows the design in T95965, with the ultimate intention of simplifying code and improving performance. Importantly, the change allows exporters and renderers to use UVs "touched" by geometry nodes, which only creates generic attributes. It also allows geometry nodes to create "proper" UV maps from scratch, though only with the Store Named Attribute node for now. The new design considers any 2D vector attribute on the corner domain to be a UV map. In the future, they might be distinguished from regular 2D vectors with attribute metadata, which may be helpful because they are often interpolated differently. Most of the code changes deal with passing around UV BMesh custom data offsets and tracking the boolean "sublayers". The boolean layers are use the following prefixes for attribute names: vert selection: `.vs.`, edge selection: `.es.`, pinning: `.pn.`. Currently these are short to avoid using up the maximum length of attribute names. To accommodate for these 4 extra characters, the name length limit is enlarged to 68 bytes, while the maximum user settable name length is still 64 bytes. Unfortunately Python/RNA API access to the UV flag data becomes slower. Accessing the boolean layers directly is be better for performance in general. Like the other mesh SoA refactors, backward and forward compatibility aren't affected, and won't be changed until 4.0. We pay for that by making mesh reading and writing more expensive with conversions. Resolves T85962 Differential Revision: https://developer.blender.org/D14365
2023-01-10 06:47:04 +01:00
/**
* Make sure the name of layer at index is unique.
*/
void CustomData_set_layer_unique_name(CustomData *data, int index);
void CustomData_validate_layer_name(const CustomData *data,
eCustomDataType type,
const char *name,
char *outname);
/**
* For file reading compatibility, returns false if the layer was freed,
* only after this test passes, `layer->data` should be assigned.
*/
bool CustomData_verify_versions(CustomData *data, int index);
/* BMesh specific custom-data stuff. */
void CustomData_bmesh_init_pool(CustomData *data, int totelem, char htype);
/**
* Validate and fix data of \a layer,
* if possible (needs relevant callback in layer's type to be defined).
*
* \return True if some errors were found.
*/
bool CustomData_layer_validate(CustomDataLayer *layer, uint totitems, bool do_fixes);
/* External file storage */
void CustomData_external_add(
CustomData *data, ID *id, eCustomDataType type, int totelem, const char *filepath);
void CustomData_external_remove(CustomData *data, ID *id, eCustomDataType type, int totelem);
bool CustomData_external_test(CustomData *data, eCustomDataType type);
void CustomData_external_write(
CustomData *data, ID *id, eCustomDataMask mask, int totelem, int free);
void CustomData_external_read(CustomData *data, ID *id, eCustomDataMask mask, int totelem);
void CustomData_external_reload(CustomData *data, ID *id, eCustomDataMask mask, int totelem);
/* Mesh-to-mesh transfer data. */
using cd_datatransfer_interp = void (*)(const CustomDataTransferLayerMap *laymap,
void *dest,
const void **sources,
const float *weights,
int count,
float mix_factor);
/**
* Fake CD_LAYERS (those are actually 'real' data stored directly into elements' structs,
* or otherwise not (directly) accessible to usual CDLayer system). */
enum {
CD_FAKE = 1 << 8,
/* Vertices. */
CD_FAKE_MDEFORMVERT = CD_FAKE | CD_MDEFORMVERT, /* *sigh* due to how vgroups are stored :(. */
CD_FAKE_SHAPEKEY = CD_FAKE |
CD_SHAPEKEY, /* Not available as real CD layer in non-bmesh context. */
/* Edges. */
CD_FAKE_SEAM = CD_FAKE | 100, /* UV seam flag for edges. */
/* Multiple types of mesh elements... */
Mesh: Move UV layers to generic attributes Currently the `MLoopUV` struct stores UV coordinates and flags related to editing UV maps in the UV editor. This patch changes the coordinates to use the generic 2D vector type, and moves the flags into three separate boolean attributes. This follows the design in T95965, with the ultimate intention of simplifying code and improving performance. Importantly, the change allows exporters and renderers to use UVs "touched" by geometry nodes, which only creates generic attributes. It also allows geometry nodes to create "proper" UV maps from scratch, though only with the Store Named Attribute node for now. The new design considers any 2D vector attribute on the corner domain to be a UV map. In the future, they might be distinguished from regular 2D vectors with attribute metadata, which may be helpful because they are often interpolated differently. Most of the code changes deal with passing around UV BMesh custom data offsets and tracking the boolean "sublayers". The boolean layers are use the following prefixes for attribute names: vert selection: `.vs.`, edge selection: `.es.`, pinning: `.pn.`. Currently these are short to avoid using up the maximum length of attribute names. To accommodate for these 4 extra characters, the name length limit is enlarged to 68 bytes, while the maximum user settable name length is still 64 bytes. Unfortunately Python/RNA API access to the UV flag data becomes slower. Accessing the boolean layers directly is be better for performance in general. Like the other mesh SoA refactors, backward and forward compatibility aren't affected, and won't be changed until 4.0. We pay for that by making mesh reading and writing more expensive with conversions. Resolves T85962 Differential Revision: https://developer.blender.org/D14365
2023-01-10 06:47:04 +01:00
CD_FAKE_UV =
CD_FAKE |
CD_PROP_FLOAT2, /* UV flag, because we handle both loop's UVs and face's textures. */
CD_FAKE_LNOR = CD_FAKE |
CD_CUSTOMLOOPNORMAL, /* Because we play with clnor and temp lnor layers here. */
CD_FAKE_SHARP = CD_FAKE | 200, /* Sharp flag for edges, smooth flag for faces. */
CD_FAKE_BWEIGHT = CD_FAKE | 300,
CD_FAKE_CREASE = CD_FAKE | 400,
};
enum {
ME_VERT = 1 << 0,
ME_EDGE = 1 << 1,
ME_POLY = 1 << 2,
ME_LOOP = 1 << 3,
};
/**
* How to filter out some elements (to leave untouched).
* Note those options are highly dependent on type of transferred data! */
enum {
CDT_MIX_NOMIX = -1, /* Special case, only used because we abuse 'copy' CD callback. */
CDT_MIX_TRANSFER = 0,
CDT_MIX_REPLACE_ABOVE_THRESHOLD = 1,
CDT_MIX_REPLACE_BELOW_THRESHOLD = 2,
CDT_MIX_MIX = 16,
CDT_MIX_ADD = 17,
CDT_MIX_SUB = 18,
CDT_MIX_MUL = 19,
/* Etc. */
};
struct CustomDataTransferLayerMap {
CustomDataTransferLayerMap *next, *prev;
int data_type;
int mix_mode;
float mix_factor;
/** If non-NULL, array of weights, one for each dest item, replaces mix_factor. */
const float *mix_weights;
2023-01-16 03:57:10 +01:00
/** Data source array (can be regular CD data, vertices/edges/etc., key-blocks...). */
const void *data_src;
/** Data dest array (same type as dat_src). */
void *data_dst;
/** Index to affect in data_src (used e.g. for vgroups). */
int data_src_n;
/** Index to affect in data_dst (used e.g. for vgroups). */
int data_dst_n;
/** Size of one element of data_src/data_dst. */
size_t elem_size;
/** Size of actual data we transfer. */
size_t data_size;
/** Offset of actual data we transfer (in element contained in data_src/dst). */
size_t data_offset;
2022-08-17 07:43:17 +02:00
/** For bit-flag transfer, flag(s) to affect in transferred data. */
uint64_t data_flag;
2023-01-16 03:57:10 +01:00
/** Opaque pointer, to be used by specific interp callback (e.g. transform-space for normals). */
void *interp_data;
cd_datatransfer_interp interp;
};
/**
* Those functions assume src_n and dst_n layers of given type exist in resp. src and dst.
*/
void CustomData_data_transfer(const MeshPairRemap *me_remap,
const CustomDataTransferLayerMap *laymap);
/* .blend file I/O */
/**
* Prepare given custom data for file writing.
*
* \param data: The custom-data to tweak for .blend file writing (modified in place).
* \param layers_to_write: A reduced set of layers to be written to file.
*
* \warning This function invalidates the custom data struct by changing the layer counts and the
* #layers pointer, and by invalidating the type map. It expects to work on a shallow copy of
* the struct.
*/
void CustomData_blend_write_prepare(CustomData &data,
blender::Vector<CustomDataLayer, 16> &layers_to_write,
const blender::Set<std::string> &skip_names = {});
/**
* \param layers_to_write: Layers created by #CustomData_blend_write_prepare.
*/
void CustomData_blend_write(BlendWriter *writer,
CustomData *data,
blender::Span<CustomDataLayer> layers_to_write,
int count,
eCustomDataMask cddata_mask,
ID *id);
void CustomData_blend_read(BlendDataReader *reader, CustomData *data, int count);
size_t CustomData_get_elem_size(const CustomDataLayer *layer);
Sculpt: New attribute API New unified attribute API for sculpt code. = Basic Design = The sculpt attribute API can create temporary or permanent attributes (only supported in `PBVH_FACES` mode). Attributes are created via `BKE_sculpt_attribute_ensure.` Attributes can be explicit CustomData attributes or simple array-based pseudo-attributes (this is useful for PBVH_GRIDS and PBVH_BMESH). == `SculptAttributePointers` == There is a structure in `SculptSession` for convenience attribute pointers, `ss->attrs`. Standard attributes should assign these; the attribute API will automatically clear them when the associated attributes are released. For example, the automasking code stores its factor attribute layer in `ss->attrs.automasking_factor`. == Naming == Temporary attributes should use the SCULPT_ATTRIBUTE_NAME macro for naming, it takes an entry in `SculptAttributePointers` and builds a layer name. == `SculptAttribute` == Attributes are referenced by a special `SculptAttribute` structure, which holds all the info needed to look up elements of an attribute at run time. All of these structures live in a preallocated flat array in `SculptSession`, `ss->temp_attributes`. This is extremely important. Since any change to the `CustomData` layout can in principle invalidate every extant `SculptAttribute`, having them all in one block of memory whose location doesn't change allows us to update them transparently. This makes for much simpler code and eliminates bugs. To see why this is tricky to get right, imagine we want to create three attributes in PBVH_BMESH mode and we provide our own `SculptAttribute` structs for the API to fill in. Each new layer will invalidate the `CustomData` block offsets in the prior one, leading to memory corruption. Reviewed by: Brecht Van Lommel Differential Revision: https://developer.blender.org/D15496 Ref D15496
2022-09-16 21:20:28 +02:00
#ifndef NDEBUG
struct DynStr;
/** Use to inspect mesh data when debugging. */
void CustomData_debug_info_from_layers(const CustomData *data, const char *indent, DynStr *dynstr);
#endif /* NDEBUG */
namespace blender::bke {
const CPPType *custom_data_type_to_cpp_type(eCustomDataType type);
eCustomDataType cpp_type_to_custom_data_type(const CPPType &type);
} // namespace blender::bke