diff options
Diffstat (limited to 'source/blender/blenkernel/intern/idprop_create.cc')
-rw-r--r-- | source/blender/blenkernel/intern/idprop_create.cc | 140 |
1 files changed, 140 insertions, 0 deletions
diff --git a/source/blender/blenkernel/intern/idprop_create.cc b/source/blender/blenkernel/intern/idprop_create.cc new file mode 100644 index 00000000000..12f2fdc6a63 --- /dev/null +++ b/source/blender/blenkernel/intern/idprop_create.cc @@ -0,0 +1,140 @@ +/* + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * The Original Code is Copyright (C) 2021 by Blender Foundation. + */ + +#include <type_traits> + +#include "DNA_ID.h" + +#include "BKE_idprop.hh" + +namespace blender::bke::idprop { + +/* -------------------------------------------------------------------- */ +/** \name Create Functions + * \{ */ + +std::unique_ptr<IDProperty, IDPropertyDeleter> create(const StringRefNull prop_name, int32_t value) +{ + IDPropertyTemplate prop_template{0}; + prop_template.i = value; + IDProperty *property = IDP_New(IDP_INT, &prop_template, prop_name.c_str()); + return std::unique_ptr<IDProperty, IDPropertyDeleter>(property); +} + +std::unique_ptr<IDProperty, IDPropertyDeleter> create(const StringRefNull prop_name, float value) +{ + IDPropertyTemplate prop_template{0}; + prop_template.f = value; + IDProperty *property = IDP_New(IDP_FLOAT, &prop_template, prop_name.c_str()); + return std::unique_ptr<IDProperty, IDPropertyDeleter>(property); +} + +std::unique_ptr<IDProperty, IDPropertyDeleter> create(const StringRefNull prop_name, double value) +{ + IDPropertyTemplate prop_template{0}; + prop_template.d = value; + IDProperty *property = IDP_New(IDP_DOUBLE, &prop_template, prop_name.c_str()); + return std::unique_ptr<IDProperty, IDPropertyDeleter>(property); +} + +std::unique_ptr<IDProperty, IDPropertyDeleter> create(const StringRefNull prop_name, + const StringRefNull value) +{ + IDProperty *property = IDP_NewString(value.c_str(), prop_name.c_str(), value.size() + 1); + return std::unique_ptr<IDProperty, IDPropertyDeleter>(property); +} + +static std::unique_ptr<IDProperty, IDPropertyDeleter> array_create(const StringRefNull prop_name, + eIDPropertyType subtype, + size_t array_len) +{ + IDPropertyTemplate prop_template{0}; + prop_template.array.len = array_len; + prop_template.array.type = subtype; + IDProperty *property = IDP_New(IDP_ARRAY, &prop_template, prop_name.c_str()); + return std::unique_ptr<IDProperty, IDPropertyDeleter>(property); +} + +static void array_values_set(IDProperty *property, + const void *values, + size_t values_len, + size_t value_size) +{ + BLI_assert(values); + BLI_assert(property->len == values_len); + memcpy(IDP_Array(property), values, values_len * value_size); +} + +/** + * Create a IDProperty array of `id_property_subtype` and fill it with the given values. + */ +template< + /** C-Primitive type of the array. Can be int32_t, float, double. */ + typename PrimitiveType, + /** Subtype of the ID_ARRAY. Must match PrimitiveType. */ + eIDPropertyType id_property_subtype> +std::unique_ptr<IDProperty, IDPropertyDeleter> create_array(StringRefNull prop_name, + Span<PrimitiveType> values) +{ + static_assert(std::is_same_v<PrimitiveType, int32_t> || std::is_same_v<PrimitiveType, float_t> || + std::is_same_v<PrimitiveType, double>, + "Allowed values for PrimitiveType are int32_t, float and double."); + static_assert(!std::is_same_v<PrimitiveType, int32_t> || id_property_subtype == IDP_INT, + "PrimitiveType and id_property_type do not match (int32_t)."); + static_assert(!std::is_same_v<PrimitiveType, float> || id_property_subtype == IDP_FLOAT, + "PrimitiveType and id_property_type do not match (float)."); + static_assert(!std::is_same_v<PrimitiveType, double> || id_property_subtype == IDP_DOUBLE, + "PrimitiveType and id_property_type do not match (double)."); + + const int64_t values_len = values.size(); + BLI_assert(values_len > 0); + std::unique_ptr<IDProperty, IDPropertyDeleter> property = array_create( + prop_name.c_str(), id_property_subtype, values_len); + array_values_set( + property.get(), static_cast<const void *>(values.data()), values_len, sizeof(PrimitiveType)); + return property; +} + +std::unique_ptr<IDProperty, IDPropertyDeleter> create(const StringRefNull prop_name, + Span<int32_t> values) +{ + return create_array<int32_t, IDP_INT>(prop_name, values); +} + +std::unique_ptr<IDProperty, IDPropertyDeleter> create(const StringRefNull prop_name, + Span<float> values) +{ + return create_array<float, IDP_FLOAT>(prop_name, values); +} + +std::unique_ptr<IDProperty, IDPropertyDeleter> create(const StringRefNull prop_name, + Span<double> values) +{ + return create_array<double, IDP_DOUBLE>(prop_name, values); +} + +std::unique_ptr<IDProperty, IDPropertyDeleter> create_group(const StringRefNull prop_name) +{ + IDPropertyTemplate prop_template{0}; + IDProperty *property = IDP_New(IDP_GROUP, &prop_template, prop_name.c_str()); + return std::unique_ptr<IDProperty, IDPropertyDeleter>(property); +} + +/* \} */ + +} // namespace blender::bke::idprop |