GPv3: Initial Geometry Nodes support #112535

Merged
Falk David merged 61 commits from filedescriptor/blender:gpv3-geometry-nodes into main 2023-10-10 16:49:39 +02:00
3 changed files with 74 additions and 12 deletions
Showing only changes of commit 929e93ba7a - Show all commits

View File

@ -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

View File

@ -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);

View File

@ -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);
}