Attributes: Add quaternion rotation type #108678
|
@ -9,7 +9,9 @@
|
||||||
#include "BLI_cpp_type.hh"
|
#include "BLI_cpp_type.hh"
|
||||||
#include "BLI_generic_span.hh"
|
#include "BLI_generic_span.hh"
|
||||||
#include "BLI_generic_virtual_array.hh"
|
#include "BLI_generic_virtual_array.hh"
|
||||||
|
#include "BLI_math_axis_angle.hh"
|
||||||
#include "BLI_math_color.hh"
|
#include "BLI_math_color.hh"
|
||||||
|
#include "BLI_math_quaternion.hh"
|
||||||
#include "BLI_math_vector.h"
|
#include "BLI_math_vector.h"
|
||||||
#include "BLI_math_vector.hh"
|
#include "BLI_math_vector.hh"
|
||||||
|
|
||||||
|
@ -31,7 +33,8 @@ inline void convert_to_static_type(const CPPType &cpp_type, const Func &func)
|
||||||
bool,
|
bool,
|
||||||
int8_t,
|
int8_t,
|
||||||
ColorGeometry4f,
|
ColorGeometry4f,
|
||||||
ColorGeometry4b>([&](auto type_tag) {
|
ColorGeometry4b,
|
||||||
|
math::Quaternion>([&](auto type_tag) {
|
||||||
using T = typename decltype(type_tag)::type;
|
using T = typename decltype(type_tag)::type;
|
||||||
if constexpr (std::is_same_v<T, void>) {
|
if constexpr (std::is_same_v<T, void>) {
|
||||||
/* It's expected that the given cpp type is one of the supported ones. */
|
/* It's expected that the given cpp type is one of the supported ones. */
|
||||||
|
@ -400,7 +403,10 @@ class BooleanPropagationMixer {
|
||||||
* This mixer accumulates values in a type that is different from the one that is mixed.
|
* This mixer accumulates values in a type that is different from the one that is mixed.
|
||||||
* Some types cannot encode the floating point weights in their values (e.g. int and bool).
|
* Some types cannot encode the floating point weights in their values (e.g. int and bool).
|
||||||
*/
|
*/
|
||||||
template<typename T, typename AccumulationT, T (*ConvertToT)(const AccumulationT &value)>
|
template<typename T,
|
||||||
|
typename AccumulationT,
|
||||||
|
AccumulationT (*ValueToAccumulate)(const T &value),
|
||||||
|
T (*AccumulateToValue)(const AccumulationT &value)>
|
||||||
class SimpleMixerWithAccumulationType {
|
class SimpleMixerWithAccumulationType {
|
||||||
private:
|
private:
|
||||||
struct Item {
|
struct Item {
|
||||||
|
@ -432,7 +438,7 @@ class SimpleMixerWithAccumulationType {
|
||||||
|
|
||||||
void set(const int64_t index, const T &value, const float weight = 1.0f)
|
void set(const int64_t index, const T &value, const float weight = 1.0f)
|
||||||
{
|
{
|
||||||
const AccumulationT converted_value = static_cast<AccumulationT>(value);
|
const AccumulationT converted_value = ValueToAccumulate(value);
|
||||||
Item &item = accumulation_buffer_[index];
|
Item &item = accumulation_buffer_[index];
|
||||||
item.value = converted_value * weight;
|
item.value = converted_value * weight;
|
||||||
item.weight = weight;
|
item.weight = weight;
|
||||||
|
@ -440,7 +446,7 @@ class SimpleMixerWithAccumulationType {
|
||||||
|
|
||||||
void mix_in(const int64_t index, const T &value, const float weight = 1.0f)
|
void mix_in(const int64_t index, const T &value, const float weight = 1.0f)
|
||||||
{
|
{
|
||||||
const AccumulationT converted_value = static_cast<AccumulationT>(value);
|
const AccumulationT converted_value = ValueToAccumulate(value);
|
||||||
Item &item = accumulation_buffer_[index];
|
Item &item = accumulation_buffer_[index];
|
||||||
item.value += converted_value * weight;
|
item.value += converted_value * weight;
|
||||||
item.weight += weight;
|
item.weight += weight;
|
||||||
|
@ -457,7 +463,7 @@ class SimpleMixerWithAccumulationType {
|
||||||
const Item &item = accumulation_buffer_[i];
|
const Item &item = accumulation_buffer_[i];
|
||||||
if (item.weight > 0.0f) {
|
if (item.weight > 0.0f) {
|
||||||
const float weight_inv = 1.0f / item.weight;
|
const float weight_inv = 1.0f / item.weight;
|
||||||
const T converted_value = ConvertToT(item.value * weight_inv);
|
const T converted_value = AccumulateToValue(item.value * weight_inv);
|
||||||
buffer_[i] = converted_value;
|
buffer_[i] = converted_value;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
@ -532,40 +538,68 @@ template<> struct DefaultMixerStruct<ColorGeometry4b> {
|
||||||
using type = ColorGeometry4bMixer;
|
using type = ColorGeometry4bMixer;
|
||||||
};
|
};
|
||||||
template<> struct DefaultMixerStruct<int> {
|
template<> struct DefaultMixerStruct<int> {
|
||||||
|
static double int_to_double(const int &value)
|
||||||
|
{
|
||||||
|
return double(value);
|
||||||
|
}
|
||||||
static int double_to_int(const double &value)
|
static int double_to_int(const double &value)
|
||||||
{
|
{
|
||||||
return int(std::round(value));
|
return int(std::round(value));
|
||||||
}
|
}
|
||||||
/* Store interpolated ints in a double temporarily, so that weights are handled correctly. It
|
/* Store interpolated ints in a double temporarily, so that weights are handled correctly. It
|
||||||
* uses double instead of float so that it is accurate for all 32 bit integers. */
|
* uses double instead of float so that it is accurate for all 32 bit integers. */
|
||||||
using type = SimpleMixerWithAccumulationType<int, double, double_to_int>;
|
using type = SimpleMixerWithAccumulationType<int, double, int_to_double, double_to_int>;
|
||||||
};
|
};
|
||||||
template<> struct DefaultMixerStruct<int2> {
|
template<> struct DefaultMixerStruct<int2> {
|
||||||
|
static double2 int_to_double(const int2 &value)
|
||||||
|
{
|
||||||
|
return double2(value);
|
||||||
|
}
|
||||||
static int2 double_to_int(const double2 &value)
|
static int2 double_to_int(const double2 &value)
|
||||||
{
|
{
|
||||||
return int2(math::round(value));
|
return int2(math::round(value));
|
||||||
}
|
}
|
||||||
/* Store interpolated ints in a double temporarily, so that weights are handled correctly. It
|
/* Store interpolated ints in a double temporarily, so that weights are handled correctly. It
|
||||||
* uses double instead of float so that it is accurate for all 32 bit integers. */
|
* uses double instead of float so that it is accurate for all 32 bit integers. */
|
||||||
using type = SimpleMixerWithAccumulationType<int2, double2, double_to_int>;
|
using type = SimpleMixerWithAccumulationType<int2, double2, int_to_double, double_to_int>;
|
||||||
};
|
};
|
||||||
template<> struct DefaultMixerStruct<bool> {
|
template<> struct DefaultMixerStruct<bool> {
|
||||||
|
static float bool_to_float(const bool &value)
|
||||||
|
{
|
||||||
|
return value ? 1.0f : 0.0f;
|
||||||
|
}
|
||||||
static bool float_to_bool(const float &value)
|
static bool float_to_bool(const float &value)
|
||||||
{
|
{
|
||||||
return value >= 0.5f;
|
return value >= 0.5f;
|
||||||
}
|
}
|
||||||
/* Store interpolated booleans in a float temporary.
|
/* Store interpolated booleans in a float temporary.
|
||||||
* Otherwise information provided by weights is easily rounded away. */
|
* Otherwise information provided by weights is easily rounded away. */
|
||||||
using type = SimpleMixerWithAccumulationType<bool, float, float_to_bool>;
|
using type = SimpleMixerWithAccumulationType<bool, float, bool_to_float, float_to_bool>;
|
||||||
};
|
};
|
||||||
|
|
||||||
template<> struct DefaultMixerStruct<int8_t> {
|
template<> struct DefaultMixerStruct<int8_t> {
|
||||||
|
static float int8_t_to_float(const int8_t &value)
|
||||||
|
{
|
||||||
|
return float(value);
|
||||||
|
}
|
||||||
static int8_t float_to_int8_t(const float &value)
|
static int8_t float_to_int8_t(const float &value)
|
||||||
{
|
{
|
||||||
return int8_t(std::round(value));
|
return int8_t(std::round(value));
|
||||||
}
|
}
|
||||||
/* Store interpolated 8 bit integers in a float temporarily to increase accuracy. */
|
/* Store interpolated 8 bit integers in a float temporarily to increase accuracy. */
|
||||||
using type = SimpleMixerWithAccumulationType<int8_t, float, float_to_int8_t>;
|
using type = SimpleMixerWithAccumulationType<int8_t, float, int8_t_to_float, float_to_int8_t>;
|
||||||
|
};
|
||||||
|
template<> struct DefaultMixerStruct<math::Quaternion> {
|
||||||
|
static float3 quat_to_expmap(const math::Quaternion &value)
|
||||||
|
{
|
||||||
|
return value.expmap();
|
||||||
|
}
|
||||||
|
static math::Quaternion expmap_to_quat(const float3 &value)
|
||||||
|
{
|
||||||
|
return math::Quaternion::expmap(value);
|
||||||
|
}
|
||||||
|
using type =
|
||||||
|
SimpleMixerWithAccumulationType<math::Quaternion, float3, quat_to_expmap, expmap_to_quat>;
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename T> struct DefaultPropagationMixerStruct {
|
template<typename T> struct DefaultPropagationMixerStruct {
|
||||||
|
|
|
@ -107,11 +107,13 @@ static int attribute_data_type_complexity(const eCustomDataType data_type)
|
||||||
return 6;
|
return 6;
|
||||||
case CD_PROP_BYTE_COLOR:
|
case CD_PROP_BYTE_COLOR:
|
||||||
return 7;
|
return 7;
|
||||||
case CD_PROP_COLOR:
|
case CD_PROP_QUATERNION:
|
||||||
return 8;
|
return 8;
|
||||||
|
case CD_PROP_COLOR:
|
||||||
|
return 9;
|
||||||
#if 0 /* These attribute types are not supported yet. */
|
#if 0 /* These attribute types are not supported yet. */
|
||||||
case CD_PROP_STRING:
|
case CD_PROP_STRING:
|
||||||
return 9;
|
return 10;
|
||||||
#endif
|
#endif
|
||||||
default:
|
default:
|
||||||
/* Only accept "generic" custom data types used by the attribute system. */
|
/* Only accept "generic" custom data types used by the attribute system. */
|
||||||
|
|
|
@ -3,11 +3,39 @@
|
||||||
* SPDX-License-Identifier: GPL-2.0-or-later */
|
* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||||
|
|
||||||
#include "BLI_array_utils.hh"
|
#include "BLI_array_utils.hh"
|
||||||
|
#include "BLI_math_quaternion.hh"
|
||||||
|
|
||||||
#include "BKE_attribute_math.hh"
|
#include "BKE_attribute_math.hh"
|
||||||
|
|
||||||
namespace blender::bke::attribute_math {
|
namespace blender::bke::attribute_math {
|
||||||
|
|
||||||
|
template<>
|
||||||
|
math::Quaternion mix2(const float factor, const math::Quaternion &a, const math::Quaternion &b)
|
||||||
|
{
|
||||||
|
return math::interpolate(a, b, factor);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<>
|
||||||
|
math::Quaternion mix3(const float3 &weights,
|
||||||
|
const math::Quaternion &v0,
|
||||||
|
const math::Quaternion &v1,
|
||||||
|
const math::Quaternion &v2)
|
||||||
|
{
|
||||||
|
const float3 expmap_mixed = mix3(weights, v0.expmap(), v1.expmap(), v2.expmap());
|
||||||
|
return math::Quaternion::expmap(expmap_mixed);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<>
|
||||||
|
math::Quaternion mix4(const float4 &weights,
|
||||||
|
const math::Quaternion &v0,
|
||||||
|
const math::Quaternion &v1,
|
||||||
|
const math::Quaternion &v2,
|
||||||
|
const math::Quaternion &v3)
|
||||||
|
{
|
||||||
|
const float3 expmap_mixed = mix4(weights, v0.expmap(), v1.expmap(), v2.expmap(), v3.expmap());
|
||||||
|
return math::Quaternion::expmap(expmap_mixed);
|
||||||
|
}
|
||||||
|
|
||||||
ColorGeometry4fMixer::ColorGeometry4fMixer(MutableSpan<ColorGeometry4f> buffer,
|
ColorGeometry4fMixer::ColorGeometry4fMixer(MutableSpan<ColorGeometry4f> buffer,
|
||||||
ColorGeometry4f default_color)
|
ColorGeometry4f default_color)
|
||||||
: ColorGeometry4fMixer(buffer, buffer.index_range(), default_color)
|
: ColorGeometry4fMixer(buffer, buffer.index_range(), default_color)
|
||||||
|
|
|
@ -24,6 +24,7 @@
|
||||||
#include "BLI_index_range.hh"
|
#include "BLI_index_range.hh"
|
||||||
#include "BLI_math.h"
|
#include "BLI_math.h"
|
||||||
#include "BLI_math_color_blend.h"
|
#include "BLI_math_color_blend.h"
|
||||||
|
#include "BLI_math_quaternion_types.hh"
|
||||||
#include "BLI_math_vector.hh"
|
#include "BLI_math_vector.hh"
|
||||||
#include "BLI_mempool.h"
|
#include "BLI_mempool.h"
|
||||||
#include "BLI_path_util.h"
|
#include "BLI_path_util.h"
|
||||||
|
@ -1933,6 +1934,8 @@ static const LayerTypeInfo LAYERTYPEINFO[CD_NUMTYPES] = {
|
||||||
nullptr},
|
nullptr},
|
||||||
/* 51: CD_HAIRLENGTH */
|
/* 51: CD_HAIRLENGTH */
|
||||||
{sizeof(float), "float", 1, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr},
|
{sizeof(float), "float", 1, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr},
|
||||||
|
/* 52: CD_PROP_QUATERNION */
|
||||||
|
{sizeof(float[4]), "vec4f", 1, N_("Quaternion"), nullptr, nullptr, nullptr, nullptr, nullptr},
|
||||||
};
|
};
|
||||||
|
|
||||||
static const char *LAYERTYPENAMES[CD_NUMTYPES] = {
|
static const char *LAYERTYPENAMES[CD_NUMTYPES] = {
|
||||||
|
@ -5354,6 +5357,8 @@ const blender::CPPType *custom_data_type_to_cpp_type(const eCustomDataType type)
|
||||||
return &CPPType::get<int8_t>();
|
return &CPPType::get<int8_t>();
|
||||||
case CD_PROP_BYTE_COLOR:
|
case CD_PROP_BYTE_COLOR:
|
||||||
return &CPPType::get<ColorGeometry4b>();
|
return &CPPType::get<ColorGeometry4b>();
|
||||||
|
case CD_PROP_QUATERNION:
|
||||||
|
return &CPPType::get<math::Quaternion>();
|
||||||
case CD_PROP_STRING:
|
case CD_PROP_STRING:
|
||||||
return &CPPType::get<MStringProperty>();
|
return &CPPType::get<MStringProperty>();
|
||||||
default:
|
default:
|
||||||
|
@ -5390,6 +5395,9 @@ eCustomDataType cpp_type_to_custom_data_type(const blender::CPPType &type)
|
||||||
if (type.is<ColorGeometry4b>()) {
|
if (type.is<ColorGeometry4b>()) {
|
||||||
return CD_PROP_BYTE_COLOR;
|
return CD_PROP_BYTE_COLOR;
|
||||||
}
|
}
|
||||||
|
if (type.is<math::Quaternion>()) {
|
||||||
|
return CD_PROP_QUATERNION;
|
||||||
|
}
|
||||||
if (type.is<MStringProperty>()) {
|
if (type.is<MStringProperty>()) {
|
||||||
return CD_PROP_STRING;
|
return CD_PROP_STRING;
|
||||||
}
|
}
|
||||||
|
|
|
@ -661,6 +661,26 @@ static int customdata_compare(
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case CD_PROP_QUATERNION: {
|
||||||
|
const float(*l1_data)[4] = (float(*)[4])l1->data;
|
||||||
|
const float(*l2_data)[4] = (float(*)[4])l2->data;
|
||||||
|
|
||||||
|
for (int i = 0; i < total_length; i++) {
|
||||||
|
if (compare_threshold_relative(l1_data[i][0], l2_data[i][0], thresh)) {
|
||||||
|
return MESHCMP_ATTRIBUTE_VALUE_MISMATCH;
|
||||||
|
}
|
||||||
|
if (compare_threshold_relative(l1_data[i][1], l2_data[i][1], thresh)) {
|
||||||
|
return MESHCMP_ATTRIBUTE_VALUE_MISMATCH;
|
||||||
|
}
|
||||||
|
if (compare_threshold_relative(l1_data[i][2], l2_data[i][2], thresh)) {
|
||||||
|
return MESHCMP_ATTRIBUTE_VALUE_MISMATCH;
|
||||||
|
}
|
||||||
|
if (compare_threshold_relative(l1_data[i][3], l2_data[i][3], thresh)) {
|
||||||
|
return MESHCMP_ATTRIBUTE_VALUE_MISMATCH;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
case CD_PROP_INT32: {
|
case CD_PROP_INT32: {
|
||||||
const int *l1_data = (int *)l1->data;
|
const int *l1_data = (int *)l1->data;
|
||||||
const int *l2_data = (int *)l2->data;
|
const int *l2_data = (int *)l2->data;
|
||||||
|
|
|
@ -18,6 +18,7 @@
|
||||||
#include "BLI_endian_switch.h"
|
#include "BLI_endian_switch.h"
|
||||||
#include "BLI_fileops.hh"
|
#include "BLI_fileops.hh"
|
||||||
#include "BLI_math_matrix_types.hh"
|
#include "BLI_math_matrix_types.hh"
|
||||||
|
#include "BLI_math_quaternion_types.hh"
|
||||||
#include "BLI_path_util.h"
|
#include "BLI_path_util.h"
|
||||||
|
|
||||||
#include "RNA_access.h"
|
#include "RNA_access.h"
|
||||||
|
@ -778,6 +779,10 @@ static std::shared_ptr<io::serialize::Value> serialize_primitive_value(
|
||||||
const ColorGeometry4f value = *static_cast<const ColorGeometry4f *>(value_ptr);
|
const ColorGeometry4f value = *static_cast<const ColorGeometry4f *>(value_ptr);
|
||||||
return serialize_float_array({&value.r, 4});
|
return serialize_float_array({&value.r, 4});
|
||||||
}
|
}
|
||||||
|
case CD_PROP_QUATERNION: {
|
||||||
|
const math::Quaternion value = *static_cast<const math::Quaternion *>(value_ptr);
|
||||||
|
return serialize_float_array({&value.x, 4});
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -966,6 +971,9 @@ template<typename T>
|
||||||
case CD_PROP_COLOR: {
|
case CD_PROP_COLOR: {
|
||||||
return deserialize_float_array(io_value, {static_cast<float *>(r_value), 4});
|
return deserialize_float_array(io_value, {static_cast<float *>(r_value), 4});
|
||||||
}
|
}
|
||||||
|
case CD_PROP_QUATERNION: {
|
||||||
|
return deserialize_float_array(io_value, {static_cast<float *>(r_value), 4});
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,6 +11,7 @@
|
||||||
#include "BLI_index_mask.hh"
|
#include "BLI_index_mask.hh"
|
||||||
#include "BLI_math_base.hh"
|
#include "BLI_math_base.hh"
|
||||||
#include "BLI_math_color.hh"
|
#include "BLI_math_color.hh"
|
||||||
|
#include "BLI_math_quaternion.hh"
|
||||||
|
|||||||
#include "BLI_math_vector.hh"
|
#include "BLI_math_vector.hh"
|
||||||
|
|
||||||
namespace blender::length_parameterize {
|
namespace blender::length_parameterize {
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
#include "BLI_cpp_type_make.hh"
|
#include "BLI_cpp_type_make.hh"
|
||||||
#include "BLI_cpp_types_make.hh"
|
#include "BLI_cpp_types_make.hh"
|
||||||
#include "BLI_math_matrix_types.hh"
|
#include "BLI_math_matrix_types.hh"
|
||||||
|
#include "BLI_math_quaternion_types.hh"
|
||||||
#include "BLI_math_vector_types.hh"
|
#include "BLI_math_vector_types.hh"
|
||||||
|
|
||||||
namespace blender {
|
namespace blender {
|
||||||
|
@ -65,6 +66,8 @@ BLI_CPP_TYPE_MAKE(uint64_t, CPPTypeFlags::BasicType)
|
||||||
BLI_CPP_TYPE_MAKE(blender::ColorGeometry4f, CPPTypeFlags::BasicType)
|
BLI_CPP_TYPE_MAKE(blender::ColorGeometry4f, CPPTypeFlags::BasicType)
|
||||||
BLI_CPP_TYPE_MAKE(blender::ColorGeometry4b, CPPTypeFlags::BasicType)
|
BLI_CPP_TYPE_MAKE(blender::ColorGeometry4b, CPPTypeFlags::BasicType)
|
||||||
|
|
||||||
|
BLI_CPP_TYPE_MAKE(blender::math::Quaternion, CPPTypeFlags::BasicType)
|
||||||
|
|
||||||
BLI_CPP_TYPE_MAKE(std::string, CPPTypeFlags::BasicType)
|
BLI_CPP_TYPE_MAKE(std::string, CPPTypeFlags::BasicType)
|
||||||
|
|
||||||
BLI_VECTOR_CPP_TYPE_MAKE(std::string)
|
BLI_VECTOR_CPP_TYPE_MAKE(std::string)
|
||||||
|
@ -94,6 +97,8 @@ void register_cpp_types()
|
||||||
BLI_CPP_TYPE_REGISTER(blender::ColorGeometry4f);
|
BLI_CPP_TYPE_REGISTER(blender::ColorGeometry4f);
|
||||||
BLI_CPP_TYPE_REGISTER(blender::ColorGeometry4b);
|
BLI_CPP_TYPE_REGISTER(blender::ColorGeometry4b);
|
||||||
|
|
||||||
|
BLI_CPP_TYPE_REGISTER(math::Quaternion);
|
||||||
|
|
||||||
BLI_CPP_TYPE_REGISTER(std::string);
|
BLI_CPP_TYPE_REGISTER(std::string);
|
||||||
|
|
||||||
BLI_VECTOR_CPP_TYPE_REGISTER(std::string);
|
BLI_VECTOR_CPP_TYPE_REGISTER(std::string);
|
||||||
|
|
|
@ -83,7 +83,7 @@ bool drw_custom_data_match_attribute(const CustomData *custom_data,
|
||||||
int *r_layer_index,
|
int *r_layer_index,
|
||||||
eCustomDataType *r_type)
|
eCustomDataType *r_type)
|
||||||
{
|
{
|
||||||
const eCustomDataType possible_attribute_types[9] = {
|
const eCustomDataType possible_attribute_types[10] = {
|
||||||
CD_PROP_BOOL,
|
CD_PROP_BOOL,
|
||||||
CD_PROP_INT8,
|
CD_PROP_INT8,
|
||||||
CD_PROP_INT32_2D,
|
CD_PROP_INT32_2D,
|
||||||
|
@ -92,6 +92,7 @@ bool drw_custom_data_match_attribute(const CustomData *custom_data,
|
||||||
CD_PROP_FLOAT2,
|
CD_PROP_FLOAT2,
|
||||||
CD_PROP_FLOAT3,
|
CD_PROP_FLOAT3,
|
||||||
CD_PROP_COLOR,
|
CD_PROP_COLOR,
|
||||||
|
CD_PROP_QUATERNION,
|
||||||
CD_PROP_BYTE_COLOR,
|
CD_PROP_BYTE_COLOR,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -392,6 +392,7 @@ static DRW_MeshCDMask mesh_cd_calc_used_gpu_layers(const Object *object,
|
||||||
}
|
}
|
||||||
case CD_PROP_BYTE_COLOR:
|
case CD_PROP_BYTE_COLOR:
|
||||||
case CD_PROP_COLOR:
|
case CD_PROP_COLOR:
|
||||||
|
case CD_PROP_QUATERNION:
|
||||||
case CD_PROP_FLOAT3:
|
case CD_PROP_FLOAT3:
|
||||||
case CD_PROP_BOOL:
|
case CD_PROP_BOOL:
|
||||||
case CD_PROP_INT8:
|
case CD_PROP_INT8:
|
||||||
|
|
|
@ -107,6 +107,7 @@ static uint gpu_component_size_for_attribute_type(eCustomDataType type)
|
||||||
return 3;
|
return 3;
|
||||||
case CD_PROP_COLOR:
|
case CD_PROP_COLOR:
|
||||||
case CD_PROP_BYTE_COLOR:
|
case CD_PROP_BYTE_COLOR:
|
||||||
|
case CD_PROP_QUATERNION:
|
||||||
return 4;
|
return 4;
|
||||||
default:
|
default:
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -315,6 +316,7 @@ static void extract_attr(const MeshRenderData *mr,
|
||||||
case CD_PROP_FLOAT3:
|
case CD_PROP_FLOAT3:
|
||||||
extract_attr_generic<float3>(mr, vbo, request);
|
extract_attr_generic<float3>(mr, vbo, request);
|
||||||
break;
|
break;
|
||||||
|
case CD_PROP_QUATERNION:
|
||||||
case CD_PROP_COLOR:
|
case CD_PROP_COLOR:
|
||||||
extract_attr_generic<float4>(mr, vbo, request);
|
extract_attr_generic<float4>(mr, vbo, request);
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -8,6 +8,7 @@
|
||||||
|
|
||||||
#include "BLI_color.hh"
|
#include "BLI_color.hh"
|
||||||
#include "BLI_generic_pointer.hh"
|
#include "BLI_generic_pointer.hh"
|
||||||
|
#include "BLI_math_quaternion.hh"
|
||||||
|
|
||||||
#include "BKE_attribute.h"
|
#include "BKE_attribute.h"
|
||||||
#include "BKE_context.h"
|
#include "BKE_context.h"
|
||||||
|
@ -106,6 +107,8 @@ static StringRefNull rna_property_name_for_type(const eCustomDataType type)
|
||||||
return "value_int";
|
return "value_int";
|
||||||
case CD_PROP_INT32_2D:
|
case CD_PROP_INT32_2D:
|
||||||
return "value_int_vector_2d";
|
return "value_int_vector_2d";
|
||||||
|
case CD_PROP_QUATERNION:
|
||||||
|
return "value_quat";
|
||||||
default:
|
default:
|
||||||
BLI_assert_unreachable();
|
BLI_assert_unreachable();
|
||||||
return "";
|
return "";
|
||||||
|
@ -198,6 +201,12 @@ static int mesh_set_attribute_exec(bContext *C, wmOperator *op)
|
||||||
case CD_PROP_COLOR:
|
case CD_PROP_COLOR:
|
||||||
RNA_float_get_array(op->ptr, prop_name.c_str(), static_cast<float *>(buffer));
|
RNA_float_get_array(op->ptr, prop_name.c_str(), static_cast<float *>(buffer));
|
||||||
break;
|
break;
|
||||||
|
case CD_PROP_QUATERNION: {
|
||||||
|
float4 value;
|
||||||
|
RNA_float_get_array(op->ptr, prop_name.c_str(), value);
|
||||||
|
*static_cast<math::Quaternion *>(buffer) = math::normalize(math::Quaternion(value));
|
||||||
|
break;
|
||||||
|
}
|
||||||
case CD_PROP_BYTE_COLOR:
|
case CD_PROP_BYTE_COLOR:
|
||||||
ColorGeometry4f value;
|
ColorGeometry4f value;
|
||||||
RNA_float_get_array(op->ptr, prop_name.c_str(), value);
|
RNA_float_get_array(op->ptr, prop_name.c_str(), value);
|
||||||
|
@ -330,6 +339,11 @@ static int mesh_set_attribute_invoke(bContext *C, wmOperator *op, const wmEvent
|
||||||
case CD_PROP_INT32_2D:
|
case CD_PROP_INT32_2D:
|
||||||
RNA_property_int_set_array(op->ptr, prop, *active_value.get<int2>());
|
RNA_property_int_set_array(op->ptr, prop, *active_value.get<int2>());
|
||||||
break;
|
break;
|
||||||
|
case CD_PROP_QUATERNION: {
|
||||||
|
const math::Quaternion value = math::normalize(*active_value.get<math::Quaternion>());
|
||||||
|
RNA_property_float_set_array(op->ptr, prop, float4(value));
|
||||||
|
break;
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
BLI_assert_unreachable();
|
BLI_assert_unreachable();
|
||||||
}
|
}
|
||||||
|
@ -408,6 +422,16 @@ void MESH_OT_attribute_set(wmOperatorType *ot)
|
||||||
RNA_def_float_color(
|
RNA_def_float_color(
|
||||||
ot->srna, "value_color", 4, color_default, -FLT_MAX, FLT_MAX, "Value", "", 0.0f, 1.0f);
|
ot->srna, "value_color", 4, color_default, -FLT_MAX, FLT_MAX, "Value", "", 0.0f, 1.0f);
|
||||||
RNA_def_boolean(ot->srna, "value_bool", false, "Value", "");
|
RNA_def_boolean(ot->srna, "value_bool", false, "Value", "");
|
||||||
|
RNA_def_float_array(ot->srna,
|
||||||
|
"value_quat",
|
||||||
|
4,
|
||||||
|
rna_default_quaternion,
|
||||||
|
-FLT_MAX,
|
||||||
|
FLT_MAX,
|
||||||
|
"Value",
|
||||||
|
"",
|
||||||
|
FLT_MAX,
|
||||||
|
FLT_MAX);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** \} */
|
/** \} */
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
#include "BLI_cpp_type_make.hh"
|
#include "BLI_cpp_type_make.hh"
|
||||||
#include "BLI_cpp_types_make.hh"
|
#include "BLI_cpp_types_make.hh"
|
||||||
#include "BLI_math_matrix_types.hh"
|
#include "BLI_math_matrix_types.hh"
|
||||||
|
#include "BLI_math_quaternion_types.hh"
|
||||||
#include "BLI_math_vector_types.hh"
|
#include "BLI_math_vector_types.hh"
|
||||||
|
|
||||||
#include "FN_field_cpp_type_make.hh"
|
#include "FN_field_cpp_type_make.hh"
|
||||||
|
@ -16,6 +17,7 @@ FN_FIELD_CPP_TYPE_MAKE(blender::float2);
|
||||||
FN_FIELD_CPP_TYPE_MAKE(blender::float3);
|
FN_FIELD_CPP_TYPE_MAKE(blender::float3);
|
||||||
FN_FIELD_CPP_TYPE_MAKE(blender::ColorGeometry4f);
|
FN_FIELD_CPP_TYPE_MAKE(blender::ColorGeometry4f);
|
||||||
FN_FIELD_CPP_TYPE_MAKE(blender::ColorGeometry4b);
|
FN_FIELD_CPP_TYPE_MAKE(blender::ColorGeometry4b);
|
||||||
|
FN_FIELD_CPP_TYPE_MAKE(blender::math::Quaternion);
|
||||||
FN_FIELD_CPP_TYPE_MAKE(bool);
|
FN_FIELD_CPP_TYPE_MAKE(bool);
|
||||||
FN_FIELD_CPP_TYPE_MAKE(int8_t);
|
FN_FIELD_CPP_TYPE_MAKE(int8_t);
|
||||||
FN_FIELD_CPP_TYPE_MAKE(int32_t);
|
FN_FIELD_CPP_TYPE_MAKE(int32_t);
|
||||||
|
@ -31,6 +33,7 @@ void FN_register_cpp_types()
|
||||||
FN_FIELD_CPP_TYPE_REGISTER(blender::float3);
|
FN_FIELD_CPP_TYPE_REGISTER(blender::float3);
|
||||||
FN_FIELD_CPP_TYPE_REGISTER(blender::ColorGeometry4f);
|
FN_FIELD_CPP_TYPE_REGISTER(blender::ColorGeometry4f);
|
||||||
FN_FIELD_CPP_TYPE_REGISTER(blender::ColorGeometry4b);
|
FN_FIELD_CPP_TYPE_REGISTER(blender::ColorGeometry4b);
|
||||||
|
FN_FIELD_CPP_TYPE_REGISTER(blender::math::Quaternion);
|
||||||
FN_FIELD_CPP_TYPE_REGISTER(bool);
|
FN_FIELD_CPP_TYPE_REGISTER(bool);
|
||||||
FN_FIELD_CPP_TYPE_REGISTER(int8_t);
|
FN_FIELD_CPP_TYPE_REGISTER(int8_t);
|
||||||
FN_FIELD_CPP_TYPE_REGISTER(int32_t);
|
FN_FIELD_CPP_TYPE_REGISTER(int32_t);
|
||||||
|
|
|
@ -84,8 +84,7 @@ typedef struct CustomData {
|
||||||
* MUST be >= CD_NUMTYPES, but we can't use a define here.
|
* MUST be >= CD_NUMTYPES, but we can't use a define here.
|
||||||
* Correct size is ensured in CustomData_update_typemap assert().
|
* Correct size is ensured in CustomData_update_typemap assert().
|
||||||
*/
|
*/
|
||||||
int typemap[52];
|
int typemap[53];
|
||||||
char _pad[4];
|
|
||||||
/** Number of layers, size of layers array. */
|
/** Number of layers, size of layers array. */
|
||||||
HooglyBoogly marked this conversation as resolved
Outdated
Jacques Lucke
commented
Remove padding line. Remove padding line.
|
|||||||
int totlayer, maxlayer;
|
int totlayer, maxlayer;
|
||||||
/** In editmode, total size of all data layers. */
|
/** In editmode, total size of all data layers. */
|
||||||
|
@ -181,8 +180,9 @@ typedef enum eCustomDataType {
|
||||||
CD_PROP_BOOL = 50,
|
CD_PROP_BOOL = 50,
|
||||||
|
|
||||||
CD_HAIRLENGTH = 51,
|
CD_HAIRLENGTH = 51,
|
||||||
|
CD_PROP_QUATERNION = 52,
|
||||||
|
|
||||||
CD_NUMTYPES = 52,
|
CD_NUMTYPES = 53,
|
||||||
} eCustomDataType;
|
} eCustomDataType;
|
||||||
|
|
||||||
/* Bits for eCustomDataMask */
|
/* Bits for eCustomDataMask */
|
||||||
|
@ -224,6 +224,7 @@ typedef enum eCustomDataType {
|
||||||
#define CD_MASK_PROP_BOOL (1ULL << CD_PROP_BOOL)
|
#define CD_MASK_PROP_BOOL (1ULL << CD_PROP_BOOL)
|
||||||
#define CD_MASK_PROP_INT8 (1ULL << CD_PROP_INT8)
|
#define CD_MASK_PROP_INT8 (1ULL << CD_PROP_INT8)
|
||||||
#define CD_MASK_PROP_INT32_2D (1ULL << CD_PROP_INT32_2D)
|
#define CD_MASK_PROP_INT32_2D (1ULL << CD_PROP_INT32_2D)
|
||||||
|
#define CD_MASK_PROP_QUATERNION (1ULL << CD_PROP_QUATERNION)
|
||||||
|
|
||||||
#define CD_MASK_HAIRLENGTH (1ULL << CD_HAIRLENGTH)
|
#define CD_MASK_HAIRLENGTH (1ULL << CD_HAIRLENGTH)
|
||||||
|
|
||||||
|
@ -237,7 +238,7 @@ typedef enum eCustomDataType {
|
||||||
#define CD_MASK_PROP_ALL \
|
#define CD_MASK_PROP_ALL \
|
||||||
(CD_MASK_PROP_FLOAT | CD_MASK_PROP_FLOAT2 | CD_MASK_PROP_FLOAT3 | CD_MASK_PROP_INT32 | \
|
(CD_MASK_PROP_FLOAT | CD_MASK_PROP_FLOAT2 | CD_MASK_PROP_FLOAT3 | CD_MASK_PROP_INT32 | \
|
||||||
CD_MASK_PROP_COLOR | CD_MASK_PROP_STRING | CD_MASK_PROP_BYTE_COLOR | CD_MASK_PROP_BOOL | \
|
CD_MASK_PROP_COLOR | CD_MASK_PROP_STRING | CD_MASK_PROP_BYTE_COLOR | CD_MASK_PROP_BOOL | \
|
||||||
CD_MASK_PROP_INT8 | CD_MASK_PROP_INT32_2D)
|
CD_MASK_PROP_INT8 | CD_MASK_PROP_INT32_2D | CD_MASK_PROP_QUATERNION)
|
||||||
|
|
||||||
/* All color attributes */
|
/* All color attributes */
|
||||||
#define CD_MASK_COLOR_ALL (CD_MASK_PROP_COLOR | CD_MASK_PROP_BYTE_COLOR)
|
#define CD_MASK_COLOR_ALL (CD_MASK_PROP_COLOR | CD_MASK_PROP_BYTE_COLOR)
|
||||||
|
|
|
@ -49,11 +49,11 @@ typedef struct vec3d {
|
||||||
typedef struct vec4i {
|
typedef struct vec4i {
|
||||||
int x, y, z, w;
|
int x, y, z, w;
|
||||||
} vec4i;
|
} vec4i;
|
||||||
|
*/
|
||||||
typedef struct vec4f {
|
typedef struct vec4f {
|
||||||
float x, y, z, w;
|
float x, y, z, w;
|
||||||
} vec4f;
|
} vec4f;
|
||||||
|
/*
|
||||||
typedef struct vec4d {
|
typedef struct vec4d {
|
||||||
double x, y, z, w;
|
double x, y, z, w;
|
||||||
} vec4d;
|
} vec4d;
|
||||||
|
|
|
@ -42,6 +42,7 @@ const EnumPropertyItem rna_enum_attribute_type_items[] = {
|
||||||
{CD_PROP_FLOAT2, "FLOAT2", 0, "2D Vector", "2D vector with floating-point values"},
|
{CD_PROP_FLOAT2, "FLOAT2", 0, "2D Vector", "2D vector with floating-point values"},
|
||||||
{CD_PROP_INT8, "INT8", 0, "8-Bit Integer", "Smaller integer with a range from -128 to 127"},
|
{CD_PROP_INT8, "INT8", 0, "8-Bit Integer", "Smaller integer with a range from -128 to 127"},
|
||||||
{CD_PROP_INT32_2D, "INT32_2D", 0, "2D Integer Vector", "32-bit signed integer vector"},
|
{CD_PROP_INT32_2D, "INT32_2D", 0, "2D Integer Vector", "32-bit signed integer vector"},
|
||||||
|
{CD_PROP_QUATERNION, "QUATERNION", 0, "Quaternion", "Floating point quaternion rotation"},
|
||||||
{0, NULL, 0, NULL, NULL},
|
{0, NULL, 0, NULL, NULL},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -70,6 +71,7 @@ const EnumPropertyItem rna_enum_attribute_type_with_auto_items[] = {
|
||||||
{CD_PROP_FLOAT2, "FLOAT2", 0, "2D Vector", "2D vector with floating-point values"},
|
{CD_PROP_FLOAT2, "FLOAT2", 0, "2D Vector", "2D vector with floating-point values"},
|
||||||
{CD_PROP_FLOAT2, "FLOAT2", 0, "2D Vector", "2D vector with floating-point values"},
|
{CD_PROP_FLOAT2, "FLOAT2", 0, "2D Vector", "2D vector with floating-point values"},
|
||||||
{CD_PROP_INT32_2D, "INT32_2D", 0, "2D Integer Vector", "32-bit signed integer vector"},
|
{CD_PROP_INT32_2D, "INT32_2D", 0, "2D Integer Vector", "32-bit signed integer vector"},
|
||||||
|
{CD_PROP_QUATERNION, "QUATERNION", 0, "Quaternion", "Floating point quaternion rotation"},
|
||||||
{0, NULL, 0, NULL, NULL},
|
{0, NULL, 0, NULL, NULL},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -168,6 +170,8 @@ static StructRNA *srna_by_custom_data_layer_type(const eCustomDataType type)
|
||||||
return &RNA_ByteIntAttribute;
|
return &RNA_ByteIntAttribute;
|
||||||
case CD_PROP_INT32_2D:
|
case CD_PROP_INT32_2D:
|
||||||
return &RNA_Int2Attribute;
|
return &RNA_Int2Attribute;
|
||||||
|
case CD_PROP_QUATERNION:
|
||||||
|
return &RNA_QuaternionAttribute;
|
||||||
default:
|
default:
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
@ -301,6 +305,9 @@ static void rna_Attribute_data_begin(CollectionPropertyIterator *iter, PointerRN
|
||||||
case CD_PROP_INT32_2D:
|
case CD_PROP_INT32_2D:
|
||||||
struct_size = sizeof(int[2]);
|
struct_size = sizeof(int[2]);
|
||||||
break;
|
break;
|
||||||
|
case CD_PROP_QUATERNION:
|
||||||
|
struct_size = sizeof(float[4]);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
struct_size = 0;
|
struct_size = 0;
|
||||||
length = 0;
|
length = 0;
|
||||||
|
@ -1069,6 +1076,40 @@ static void rna_def_attribute_int2(BlenderRNA *brna)
|
||||||
RNA_def_property_update(prop, 0, "rna_Attribute_update_data");
|
RNA_def_property_update(prop, 0, "rna_Attribute_update_data");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void rna_def_attribute_quaternion(BlenderRNA *brna)
|
||||||
|
{
|
||||||
|
StructRNA *srna;
|
||||||
|
PropertyRNA *prop;
|
||||||
|
|
||||||
|
srna = RNA_def_struct(brna, "QuaternionAttribute", "Attribute");
|
||||||
|
RNA_def_struct_sdna(srna, "CustomDataLayer");
|
||||||
|
RNA_def_struct_ui_text(srna, "Quaternion Attribute", "Geometry attribute that stores rotation");
|
||||||
|
|
||||||
|
prop = RNA_def_property(srna, "data", PROP_COLLECTION, PROP_NONE);
|
||||||
|
RNA_def_property_struct_type(prop, "QuaternionAttributeValue");
|
||||||
|
RNA_def_property_override_flag(prop, PROPOVERRIDE_IGNORE);
|
||||||
|
RNA_def_property_collection_funcs(prop,
|
||||||
|
"rna_Attribute_data_begin",
|
||||||
|
"rna_iterator_array_next",
|
||||||
|
"rna_iterator_array_end",
|
||||||
|
"rna_iterator_array_get",
|
||||||
|
"rna_Attribute_data_length",
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
NULL);
|
||||||
|
|
||||||
|
srna = RNA_def_struct(brna, "QuaternionAttributeValue", NULL);
|
||||||
|
RNA_def_struct_sdna(srna, "vec4f");
|
||||||
|
RNA_def_struct_ui_text(
|
||||||
|
srna, "Quaternion Attribute Value", "Rotation value in geometry attribute");
|
||||||
|
|
||||||
|
prop = RNA_def_property(srna, "value", PROP_FLOAT, PROP_NONE);
|
||||||
|
RNA_def_property_ui_text(prop, "Value", "Quaternion");
|
||||||
|
RNA_def_property_float_sdna(prop, NULL, "x");
|
||||||
|
RNA_def_property_array(prop, 4);
|
||||||
|
RNA_def_property_update(prop, 0, "rna_Attribute_update_data");
|
||||||
|
}
|
||||||
|
|
||||||
static void rna_def_attribute_float2(BlenderRNA *brna)
|
static void rna_def_attribute_float2(BlenderRNA *brna)
|
||||||
{
|
{
|
||||||
StructRNA *srna;
|
StructRNA *srna;
|
||||||
|
@ -1149,6 +1190,7 @@ static void rna_def_attribute(BlenderRNA *brna)
|
||||||
rna_def_attribute_byte_color(brna);
|
rna_def_attribute_byte_color(brna);
|
||||||
rna_def_attribute_int(brna);
|
rna_def_attribute_int(brna);
|
||||||
rna_def_attribute_int2(brna);
|
rna_def_attribute_int2(brna);
|
||||||
|
rna_def_attribute_quaternion(brna);
|
||||||
rna_def_attribute_string(brna);
|
rna_def_attribute_string(brna);
|
||||||
rna_def_attribute_bool(brna);
|
rna_def_attribute_bool(brna);
|
||||||
rna_def_attribute_float2(brna);
|
rna_def_attribute_float2(brna);
|
||||||
|
|
Loading…
Reference in New Issue
Why this include?
Currently that's the best way I found to solve this build error. But I don't fully understand why isn't necessary. I thought I'd just be able to include it in
resample_curves.cc
, rather than the header. It's the same reason thatBLI_math_color.hh
is there though.