Welcome to mirror list, hosted at ThFree Co, Russian Federation.

idprop_create.cc « intern « blenkernel « blender « source - git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
blob: f549393fd129ee47db46e6dbfefe903100840148 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
/* SPDX-License-Identifier: GPL-2.0-or-later
 * Copyright 2021 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