GPv3: Initial Geometry Nodes support #112535
|
@ -199,6 +199,12 @@ bool CustomData_merge_layout(const struct CustomData *source,
|
|||
*/
|
||||
void CustomData_realloc(struct CustomData *data, int old_size, int new_size);
|
||||
|
||||
/**
|
||||
* Grow the custom data by \a grow_size and shift the elements after \a index to the end.
|
||||
* After being resized, the #CustomData does not contain any referenced layers.
|
||||
*/
|
||||
void CustomData_grow_and_shift(CustomData *data, int old_size, int grow_size, int index);
|
||||
|
||||
/**
|
||||
* 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
|
||||
|
|
|
@ -2419,6 +2419,23 @@ void CustomData_ensure_data_is_mutable(CustomDataLayer *layer, const int totelem
|
|||
ensure_layer_data_is_mutable(*layer, totelem);
|
||||
}
|
||||
|
||||
static void CustomData_replace_layer_data(CustomDataLayer *layer,
|
||||
const int new_size,
|
||||
void *new_layer_data)
|
||||
{
|
||||
/* Remove ownership of old array */
|
||||
if (layer->sharing_info) {
|
||||
layer->sharing_info->remove_user_and_delete_if_last();
|
||||
layer->sharing_info = nullptr;
|
||||
}
|
||||
/* Take ownership of new array. */
|
||||
layer->data = new_layer_data;
|
||||
if (layer->data) {
|
||||
layer->sharing_info = make_implicit_sharing_info_for_layer(
|
||||
eCustomDataType(layer->type), layer->data, new_size);
|
||||
}
|
||||
}
|
||||
|
||||
void CustomData_realloc(CustomData *data, const int old_size, const int new_size)
|
||||
{
|
||||
BLI_assert(new_size >= 0);
|
||||
|
@ -2439,17 +2456,8 @@ void CustomData_realloc(CustomData *data, const int old_size, const int new_size
|
|||
memcpy(new_layer_data, layer->data, std::min(old_size_in_bytes, new_size_in_bytes));
|
||||
}
|
||||
}
|
||||
/* Remove ownership of old array */
|
||||
if (layer->sharing_info) {
|
||||
layer->sharing_info->remove_user_and_delete_if_last();
|
||||
layer->sharing_info = nullptr;
|
||||
}
|
||||
/* Take ownership of new array. */
|
||||
layer->data = new_layer_data;
|
||||
if (layer->data) {
|
||||
layer->sharing_info = make_implicit_sharing_info_for_layer(
|
||||
eCustomDataType(layer->type), layer->data, new_size);
|
||||
}
|
||||
|
||||
CustomData_replace_layer_data(layer, new_size, new_layer_data);
|
||||
|
||||
if (new_size > old_size) {
|
||||
/* Initialize new values for non-trivial types. */
|
||||
|
@ -2461,6 +2469,46 @@ void CustomData_realloc(CustomData *data, const int old_size, const int new_size
|
|||
}
|
||||
}
|
||||
|
||||
void CustomData_grow_and_shift(CustomData *data,
|
||||
const int old_size,
|
||||
const int grow_size,
|
||||
const int index)
|
||||
{
|
||||
BLI_assert(grow_size > 0);
|
||||
BLI_assert(index < old_size);
|
||||
const int new_size = old_size + grow_size;
|
||||
for (int i = 0; i < data->totlayer; i++) {
|
||||
CustomDataLayer *layer = &data->layers[i];
|
||||
const LayerTypeInfo *typeInfo = layerType_getInfo(eCustomDataType(layer->type));
|
||||
const int64_t new_size_in_bytes = int64_t(new_size) * typeInfo->size;
|
||||
|
||||
void *new_layer_data = MEM_mallocN(new_size_in_bytes, __func__);
|
||||
if (typeInfo->copy) {
|
||||
if (index > 0) {
|
||||
typeInfo->copy(layer->data, new_layer_data, index);
|
||||
}
|
||||
typeInfo->copy(POINTER_OFFSET(layer->data, index * typeInfo->size),
|
||||
POINTER_OFFSET(new_layer_data, (index + grow_size) * typeInfo->size),
|
||||
old_size - index);
|
||||
}
|
||||
else {
|
||||
BLI_assert(layer->data != nullptr);
|
||||
if (index > 0) {
|
||||
memcpy(new_layer_data, layer->data, index * typeInfo->size);
|
||||
}
|
||||
memcpy(POINTER_OFFSET(new_layer_data, (index + grow_size) * typeInfo->size),
|
||||
POINTER_OFFSET(layer->data, index * typeInfo->size),
|
||||
(old_size - index) * typeInfo->size);
|
||||
}
|
||||
|
||||
CustomData_replace_layer_data(layer, new_size, new_layer_data);
|
||||
|
||||
if (typeInfo->construct) {
|
||||
typeInfo->construct(POINTER_OFFSET(layer->data, index * typeInfo->size), grow_size);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CustomData_copy(const CustomData *source, CustomData *dest, eCustomDataMask mask, int totelem)
|
||||
{
|
||||
CustomData_reset(dest);
|
||||
|
|
|
@ -1876,7 +1876,15 @@ blender::bke::greasepencil::Layer &GreasePencil::add_layer(
|
|||
{
|
||||
using namespace blender;
|
||||
std::string unique_name = unique_layer_name(*this, name);
|
||||
CustomData_realloc(&this->layers_data, this->layers().size(), this->layers().size() + 1);
|
||||
|
||||
const Span<const bke::greasepencil::Layer *> layers = this->layers();
|
||||
if (layers.size() == 0) {
|
||||
CustomData_realloc(&this->layers_data, layers.size(), layers.size() + 1);
|
||||
return parent_group.add_layer(unique_name);
|
||||
}
|
||||
int insertion_index = layers.first_index(parent_group.layers().last());
|
||||
CustomData_grow_and_shift(&this->layers_data, layers.size(), 1, insertion_index);
|
||||
|
||||
return parent_group.add_layer(unique_name);
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue