BLI: improve CPPType system
* Support bidirectional type lookups. E.g. finding the base type of a field was supported, but not the other way around. This also removes the todo in `get_vector_type`. To achieve this, types have to be registered up-front. * Separate `CPPType` from other "type traits". For example, previously `ValueOrFieldCPPType` adds additional behavior on top of `CPPType`. Previously, it was a subclass, now it just contains a reference to the `CPPType` it corresponds to. This follows the composition-over-inheritance idea. This makes it easier to have self-contained "type traits" without having to put everything into `CPPType`. Differential Revision: https://developer.blender.org/D16479
This commit is contained in:
parent
a145b96396
commit
a6c822733a
16
source/blender/blenkernel/BKE_cpp_types.h
Normal file
16
source/blender/blenkernel/BKE_cpp_types.h
Normal file
@ -0,0 +1,16 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Register cpp types and their relations for later use.
|
||||
*/
|
||||
void BKE_cpp_types_init(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
@ -102,6 +102,7 @@ set(SRC
|
||||
intern/compute_contexts.cc
|
||||
intern/constraint.c
|
||||
intern/context.c
|
||||
intern/cpp_types.cc
|
||||
intern/crazyspace.cc
|
||||
intern/cryptomatte.cc
|
||||
intern/curve.cc
|
||||
@ -354,6 +355,7 @@ set(SRC
|
||||
BKE_compute_contexts.hh
|
||||
BKE_constraint.h
|
||||
BKE_context.h
|
||||
BKE_cpp_types.h
|
||||
BKE_crazyspace.h
|
||||
BKE_crazyspace.hh
|
||||
BKE_cryptomatte.h
|
||||
|
48
source/blender/blenkernel/intern/cpp_types.cc
Normal file
48
source/blender/blenkernel/intern/cpp_types.cc
Normal file
@ -0,0 +1,48 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
#include "BLI_cpp_type_make.hh"
|
||||
#include "BLI_cpp_types_make.hh"
|
||||
|
||||
#include "BKE_cpp_types.h"
|
||||
#include "BKE_geometry_set.hh"
|
||||
#include "BKE_instances.hh"
|
||||
|
||||
#include "DNA_meshdata_types.h"
|
||||
|
||||
#include "FN_init.h"
|
||||
|
||||
struct Tex;
|
||||
struct Image;
|
||||
struct Material;
|
||||
|
||||
BLI_CPP_TYPE_MAKE(GeometrySet, CPPTypeFlags::Printable);
|
||||
BLI_CPP_TYPE_MAKE(blender::bke::InstanceReference, CPPTypeFlags::None)
|
||||
|
||||
BLI_VECTOR_CPP_TYPE_MAKE(GeometrySet);
|
||||
|
||||
BLI_CPP_TYPE_MAKE(Object *, CPPTypeFlags::BasicType)
|
||||
BLI_CPP_TYPE_MAKE(Collection *, CPPTypeFlags::BasicType)
|
||||
BLI_CPP_TYPE_MAKE(Tex *, CPPTypeFlags::BasicType)
|
||||
BLI_CPP_TYPE_MAKE(Image *, CPPTypeFlags::BasicType)
|
||||
BLI_CPP_TYPE_MAKE(Material *, CPPTypeFlags::BasicType)
|
||||
|
||||
BLI_CPP_TYPE_MAKE(MStringProperty, CPPTypeFlags::None);
|
||||
|
||||
void BKE_cpp_types_init()
|
||||
{
|
||||
blender::register_cpp_types();
|
||||
FN_register_cpp_types();
|
||||
|
||||
BLI_CPP_TYPE_REGISTER(GeometrySet);
|
||||
BLI_CPP_TYPE_REGISTER(blender::bke::InstanceReference);
|
||||
|
||||
BLI_VECTOR_CPP_TYPE_REGISTER(GeometrySet);
|
||||
|
||||
BLI_CPP_TYPE_REGISTER(Object *);
|
||||
BLI_CPP_TYPE_REGISTER(Collection *);
|
||||
BLI_CPP_TYPE_REGISTER(Tex *);
|
||||
BLI_CPP_TYPE_REGISTER(Image *);
|
||||
BLI_CPP_TYPE_REGISTER(Material *);
|
||||
|
||||
BLI_CPP_TYPE_REGISTER(MStringProperty);
|
||||
}
|
@ -19,7 +19,6 @@
|
||||
|
||||
#include "BLI_bitmap.h"
|
||||
#include "BLI_color.hh"
|
||||
#include "BLI_cpp_type_make.hh"
|
||||
#include "BLI_endian_switch.h"
|
||||
#include "BLI_index_range.hh"
|
||||
#include "BLI_math.h"
|
||||
@ -5407,5 +5406,3 @@ size_t CustomData_get_elem_size(CustomDataLayer *layer)
|
||||
{
|
||||
return LAYERTYPEINFO[layer->type].size;
|
||||
}
|
||||
|
||||
BLI_CPP_TYPE_MAKE(MStringProperty, MStringProperty, CPPTypeFlags::None);
|
||||
|
@ -1,7 +1,6 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
#include "BLI_array_utils.hh"
|
||||
#include "BLI_cpp_type_make.hh"
|
||||
#include "BLI_rand.hh"
|
||||
#include "BLI_task.hh"
|
||||
|
||||
@ -9,8 +8,6 @@
|
||||
#include "BKE_geometry_set.hh"
|
||||
#include "BKE_instances.hh"
|
||||
|
||||
BLI_CPP_TYPE_MAKE(InstanceReference, blender::bke::InstanceReference, CPPTypeFlags::None)
|
||||
|
||||
namespace blender::bke {
|
||||
|
||||
InstanceReference::InstanceReference(GeometrySet geometry_set)
|
||||
|
@ -74,6 +74,7 @@
|
||||
#include "BLI_index_mask.hh"
|
||||
#include "BLI_map.hh"
|
||||
#include "BLI_math_base.h"
|
||||
#include "BLI_parameter_pack_utils.hh"
|
||||
#include "BLI_string_ref.hh"
|
||||
#include "BLI_utility_mixins.hh"
|
||||
|
||||
@ -94,10 +95,6 @@ ENUM_OPERATORS(CPPTypeFlags, CPPTypeFlags::EqualityComparable)
|
||||
|
||||
namespace blender {
|
||||
|
||||
/** Utility class to pass template parameters to constructor of `CPPType`. */
|
||||
template<typename T, CPPTypeFlags Flags> struct CPPTypeParam {
|
||||
};
|
||||
|
||||
class CPPType : NonCopyable, NonMovable {
|
||||
private:
|
||||
int64_t size_ = 0;
|
||||
@ -148,7 +145,8 @@ class CPPType : NonCopyable, NonMovable {
|
||||
std::string debug_name_;
|
||||
|
||||
public:
|
||||
template<typename T, CPPTypeFlags Flags> CPPType(CPPTypeParam<T, Flags>, StringRef debug_name);
|
||||
template<typename T, CPPTypeFlags Flags>
|
||||
CPPType(TypeTag<T> /*type*/, TypeForValue<CPPTypeFlags, Flags> /*flags*/, StringRef debug_name);
|
||||
virtual ~CPPType() = default;
|
||||
|
||||
/**
|
||||
@ -173,7 +171,7 @@ class CPPType : NonCopyable, NonMovable {
|
||||
template<typename T> static const CPPType &get()
|
||||
{
|
||||
/* Store the #CPPType locally to avoid making the function call in most cases. */
|
||||
static const CPPType &type = CPPType::get_impl<std::remove_cv_t<T>>();
|
||||
static const CPPType &type = CPPType::get_impl<std::decay_t<T>>();
|
||||
return type;
|
||||
}
|
||||
template<typename T> static const CPPType &get_impl();
|
||||
@ -745,30 +743,26 @@ class CPPType : NonCopyable, NonMovable {
|
||||
}
|
||||
}
|
||||
|
||||
template<typename T> struct type_tag {
|
||||
using type = T;
|
||||
};
|
||||
|
||||
private:
|
||||
template<typename Fn> struct TypeTagExecutor {
|
||||
const Fn &fn;
|
||||
|
||||
template<typename T> void operator()() const
|
||||
{
|
||||
fn(type_tag<T>{});
|
||||
fn(TypeTag<T>{});
|
||||
}
|
||||
|
||||
void operator()() const
|
||||
{
|
||||
fn(type_tag<void>{});
|
||||
fn(TypeTag<void>{});
|
||||
}
|
||||
};
|
||||
|
||||
public:
|
||||
/**
|
||||
* Similar to #to_static_type but is easier to use with a lambda function. The function is
|
||||
* expected to take a single `auto type_tag` parameter. To extract the static type, use:
|
||||
* `using T = typename decltype(type_tag)::type;`
|
||||
* expected to take a single `auto TypeTag` parameter. To extract the static type, use:
|
||||
* `using T = typename decltype(TypeTag)::type;`
|
||||
*
|
||||
* If the current #CPPType is not in #Types, the type tag is `void`.
|
||||
*/
|
||||
@ -779,6 +773,11 @@ class CPPType : NonCopyable, NonMovable {
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Initialize and register basic cpp types.
|
||||
*/
|
||||
void register_cpp_types();
|
||||
|
||||
} // namespace blender
|
||||
|
||||
/* Utility for allocating an uninitialized buffer for a single value of the given #CPPType. */
|
||||
|
@ -206,7 +206,9 @@ template<typename T> uint64_t hash_cb(const void *value)
|
||||
namespace blender {
|
||||
|
||||
template<typename T, CPPTypeFlags Flags>
|
||||
CPPType::CPPType(CPPTypeParam<T, Flags> /* unused */, StringRef debug_name)
|
||||
CPPType::CPPType(TypeTag<T> /*type*/,
|
||||
TypeForValue<CPPTypeFlags, Flags> /*flags*/,
|
||||
const StringRef debug_name)
|
||||
{
|
||||
using namespace cpp_type_util;
|
||||
|
||||
@ -278,9 +280,15 @@ CPPType::CPPType(CPPTypeParam<T, Flags> /* unused */, StringRef debug_name)
|
||||
|
||||
} // namespace blender
|
||||
|
||||
#define BLI_CPP_TYPE_MAKE(IDENTIFIER, TYPE_NAME, FLAGS) \
|
||||
/** Create a new #CPPType that can be accessed through `CPPType::get<T>()`. */
|
||||
#define BLI_CPP_TYPE_MAKE(TYPE_NAME, FLAGS) \
|
||||
template<> const blender::CPPType &blender::CPPType::get_impl<TYPE_NAME>() \
|
||||
{ \
|
||||
static CPPType cpp_type{blender::CPPTypeParam<TYPE_NAME, FLAGS>(), STRINGIFY(IDENTIFIER)}; \
|
||||
return cpp_type; \
|
||||
static CPPType type{blender::TypeTag<TYPE_NAME>(), \
|
||||
TypeForValue<CPPTypeFlags, FLAGS>(), \
|
||||
STRINGIFY(TYPE_NAME)}; \
|
||||
return type; \
|
||||
}
|
||||
|
||||
/** Register a #CPPType created with #BLI_CPP_TYPE_MAKE. */
|
||||
#define BLI_CPP_TYPE_REGISTER(TYPE_NAME) blender::CPPType::get<TYPE_NAME>()
|
||||
|
44
source/blender/blenlib/BLI_cpp_types.hh
Normal file
44
source/blender/blenlib/BLI_cpp_types.hh
Normal file
@ -0,0 +1,44 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "BLI_cpp_type.hh"
|
||||
#include "BLI_vector.hh"
|
||||
|
||||
namespace blender {
|
||||
|
||||
/**
|
||||
* Contains information about how to deal with a #Vector<T> generically.
|
||||
*/
|
||||
class VectorCPPType {
|
||||
public:
|
||||
/** The #Vector<T> itself. */
|
||||
const CPPType &self;
|
||||
/** The type stored in the vector. */
|
||||
const CPPType &value;
|
||||
|
||||
template<typename ValueType> VectorCPPType(TypeTag<ValueType> /*value_type*/);
|
||||
|
||||
/**
|
||||
* Try to find the #VectorCPPType that corresponds to a #CPPType.
|
||||
*/
|
||||
static const VectorCPPType *get_from_self(const CPPType &self);
|
||||
/**
|
||||
* Try to find the #VectorCPPType that wraps a vector containing the given value type.
|
||||
* This only works when the vector type has been created with #BLI_VECTOR_CPP_TYPE_MAKE.
|
||||
*/
|
||||
static const VectorCPPType *get_from_value(const CPPType &value);
|
||||
|
||||
template<typename ValueType> static const VectorCPPType &get()
|
||||
{
|
||||
static const VectorCPPType &type = VectorCPPType::get_impl<std::decay_t<ValueType>>();
|
||||
return type;
|
||||
}
|
||||
|
||||
template<typename ValueType> static const VectorCPPType &get_impl();
|
||||
|
||||
private:
|
||||
void register_self();
|
||||
};
|
||||
|
||||
} // namespace blender
|
29
source/blender/blenlib/BLI_cpp_types_make.hh
Normal file
29
source/blender/blenlib/BLI_cpp_types_make.hh
Normal file
@ -0,0 +1,29 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "BLI_cpp_type_make.hh"
|
||||
#include "BLI_cpp_types.hh"
|
||||
|
||||
namespace blender {
|
||||
|
||||
template<typename ValueType>
|
||||
inline VectorCPPType::VectorCPPType(TypeTag<ValueType> /*value_type*/)
|
||||
: self(CPPType::get<Vector<ValueType>>()), value(CPPType::get<ValueType>())
|
||||
{
|
||||
this->register_self();
|
||||
}
|
||||
|
||||
} // namespace blender
|
||||
|
||||
/** Create a new #VectorCPPType that can be accessed through `VectorCPPType::get<T>()`. */
|
||||
#define BLI_VECTOR_CPP_TYPE_MAKE(VALUE_TYPE) \
|
||||
BLI_CPP_TYPE_MAKE(blender::Vector<VALUE_TYPE>, CPPTypeFlags::None) \
|
||||
template<> const blender::VectorCPPType &blender::VectorCPPType::get_impl<VALUE_TYPE>() \
|
||||
{ \
|
||||
static blender::VectorCPPType type{blender::TypeTag<VALUE_TYPE>{}}; \
|
||||
return type; \
|
||||
}
|
||||
|
||||
/** Register a #VectorCPPType created with #BLI_VECTOR_CPP_TYPE_MAKE. */
|
||||
#define BLI_VECTOR_CPP_TYPE_REGISTER(VALUE_TYPE) blender::VectorCPPType::get<VALUE_TYPE>()
|
@ -23,6 +23,13 @@ template<typename T, T Element> struct TypeForValue {
|
||||
static constexpr T value = Element;
|
||||
};
|
||||
|
||||
/**
|
||||
* A struct that allows passing in a type as a function parameter.
|
||||
*/
|
||||
template<typename T> struct TypeTag {
|
||||
using type = T;
|
||||
};
|
||||
|
||||
/**
|
||||
* A type that encodes a list of values of the same type.
|
||||
* This is similar to #std::integer_sequence, but a bit more general. It's main purpose it to also
|
||||
|
@ -57,7 +57,7 @@ set(SRC
|
||||
intern/cache_mutex.cc
|
||||
intern/compute_context.cc
|
||||
intern/convexhull_2d.c
|
||||
intern/cpp_type.cc
|
||||
intern/cpp_types.cc
|
||||
intern/delaunay_2d.cc
|
||||
intern/dot_export.cc
|
||||
intern/dynlib.c
|
||||
@ -190,6 +190,8 @@ set(SRC
|
||||
BLI_convexhull_2d.h
|
||||
BLI_cpp_type.hh
|
||||
BLI_cpp_type_make.hh
|
||||
BLI_cpp_types.hh
|
||||
BLI_cpp_types_make.hh
|
||||
BLI_delaunay_2d.h
|
||||
BLI_devirtualize_parameters.hh
|
||||
BLI_dial_2d.h
|
||||
|
@ -1,29 +0,0 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
#include "BLI_color.hh"
|
||||
#include "BLI_cpp_type_make.hh"
|
||||
#include "BLI_float4x4.hh"
|
||||
#include "BLI_math_vec_types.hh"
|
||||
|
||||
BLI_CPP_TYPE_MAKE(bool, bool, CPPTypeFlags::BasicType)
|
||||
|
||||
BLI_CPP_TYPE_MAKE(float, float, CPPTypeFlags::BasicType)
|
||||
BLI_CPP_TYPE_MAKE(float2, blender::float2, CPPTypeFlags::BasicType)
|
||||
BLI_CPP_TYPE_MAKE(float3, blender::float3, CPPTypeFlags::BasicType)
|
||||
BLI_CPP_TYPE_MAKE(float4x4, blender::float4x4, CPPTypeFlags::BasicType)
|
||||
|
||||
BLI_CPP_TYPE_MAKE(int8, int8_t, CPPTypeFlags::BasicType)
|
||||
BLI_CPP_TYPE_MAKE(int16, int16_t, CPPTypeFlags::BasicType)
|
||||
BLI_CPP_TYPE_MAKE(int32, int32_t, CPPTypeFlags::BasicType)
|
||||
BLI_CPP_TYPE_MAKE(int64, int64_t, CPPTypeFlags::BasicType)
|
||||
|
||||
BLI_CPP_TYPE_MAKE(uint8, uint8_t, CPPTypeFlags::BasicType)
|
||||
BLI_CPP_TYPE_MAKE(uint16, uint16_t, CPPTypeFlags::BasicType)
|
||||
BLI_CPP_TYPE_MAKE(uint32, uint32_t, CPPTypeFlags::BasicType)
|
||||
BLI_CPP_TYPE_MAKE(uint64, uint64_t, CPPTypeFlags::BasicType)
|
||||
|
||||
BLI_CPP_TYPE_MAKE(ColorGeometry4f, blender::ColorGeometry4f, CPPTypeFlags::BasicType)
|
||||
BLI_CPP_TYPE_MAKE(ColorGeometry4b, blender::ColorGeometry4b, CPPTypeFlags::BasicType)
|
||||
|
||||
BLI_CPP_TYPE_MAKE(string, std::string, CPPTypeFlags::BasicType)
|
||||
BLI_CPP_TYPE_MAKE(StringVector, blender::Vector<std::string>, CPPTypeFlags::None)
|
98
source/blender/blenlib/intern/cpp_types.cc
Normal file
98
source/blender/blenlib/intern/cpp_types.cc
Normal file
@ -0,0 +1,98 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
#include "BLI_color.hh"
|
||||
#include "BLI_cpp_type_make.hh"
|
||||
#include "BLI_cpp_types_make.hh"
|
||||
#include "BLI_float4x4.hh"
|
||||
#include "BLI_math_vec_types.hh"
|
||||
|
||||
namespace blender {
|
||||
|
||||
static auto &get_vector_from_self_map()
|
||||
{
|
||||
static Map<const CPPType *, const VectorCPPType *> map;
|
||||
return map;
|
||||
}
|
||||
|
||||
static auto &get_vector_from_value_map()
|
||||
{
|
||||
static Map<const CPPType *, const VectorCPPType *> map;
|
||||
return map;
|
||||
}
|
||||
|
||||
void VectorCPPType::register_self()
|
||||
{
|
||||
get_vector_from_self_map().add_new(&this->self, this);
|
||||
get_vector_from_value_map().add_new(&this->value, this);
|
||||
}
|
||||
|
||||
const VectorCPPType *VectorCPPType::get_from_self(const CPPType &self)
|
||||
{
|
||||
const VectorCPPType *type = get_vector_from_self_map().lookup_default(&self, nullptr);
|
||||
BLI_assert(type == nullptr || type->self == self);
|
||||
return type;
|
||||
}
|
||||
|
||||
const VectorCPPType *VectorCPPType::get_from_value(const CPPType &value)
|
||||
{
|
||||
const VectorCPPType *type = get_vector_from_value_map().lookup_default(&value, nullptr);
|
||||
BLI_assert(type == nullptr || type->value == value);
|
||||
return type;
|
||||
}
|
||||
|
||||
} // namespace blender
|
||||
|
||||
BLI_CPP_TYPE_MAKE(bool, CPPTypeFlags::BasicType)
|
||||
|
||||
BLI_CPP_TYPE_MAKE(float, CPPTypeFlags::BasicType)
|
||||
BLI_CPP_TYPE_MAKE(blender::float2, CPPTypeFlags::BasicType)
|
||||
BLI_CPP_TYPE_MAKE(blender::float3, CPPTypeFlags::BasicType)
|
||||
BLI_CPP_TYPE_MAKE(blender::float4x4, CPPTypeFlags::BasicType)
|
||||
|
||||
BLI_CPP_TYPE_MAKE(int8_t, CPPTypeFlags::BasicType)
|
||||
BLI_CPP_TYPE_MAKE(int16_t, CPPTypeFlags::BasicType)
|
||||
BLI_CPP_TYPE_MAKE(int32_t, CPPTypeFlags::BasicType)
|
||||
BLI_CPP_TYPE_MAKE(int64_t, CPPTypeFlags::BasicType)
|
||||
|
||||
BLI_CPP_TYPE_MAKE(uint8_t, CPPTypeFlags::BasicType)
|
||||
BLI_CPP_TYPE_MAKE(uint16_t, CPPTypeFlags::BasicType)
|
||||
BLI_CPP_TYPE_MAKE(uint32_t, CPPTypeFlags::BasicType)
|
||||
BLI_CPP_TYPE_MAKE(uint64_t, CPPTypeFlags::BasicType)
|
||||
|
||||
BLI_CPP_TYPE_MAKE(blender::ColorGeometry4f, CPPTypeFlags::BasicType)
|
||||
BLI_CPP_TYPE_MAKE(blender::ColorGeometry4b, CPPTypeFlags::BasicType)
|
||||
|
||||
BLI_CPP_TYPE_MAKE(std::string, CPPTypeFlags::BasicType)
|
||||
|
||||
BLI_VECTOR_CPP_TYPE_MAKE(std::string)
|
||||
|
||||
namespace blender {
|
||||
|
||||
void register_cpp_types()
|
||||
{
|
||||
BLI_CPP_TYPE_REGISTER(bool);
|
||||
|
||||
BLI_CPP_TYPE_REGISTER(float);
|
||||
BLI_CPP_TYPE_REGISTER(blender::float2);
|
||||
BLI_CPP_TYPE_REGISTER(blender::float3);
|
||||
BLI_CPP_TYPE_REGISTER(blender::float4x4);
|
||||
|
||||
BLI_CPP_TYPE_REGISTER(int8_t);
|
||||
BLI_CPP_TYPE_REGISTER(int16_t);
|
||||
BLI_CPP_TYPE_REGISTER(int32_t);
|
||||
BLI_CPP_TYPE_REGISTER(int64_t);
|
||||
|
||||
BLI_CPP_TYPE_REGISTER(uint8_t);
|
||||
BLI_CPP_TYPE_REGISTER(uint16_t);
|
||||
BLI_CPP_TYPE_REGISTER(uint32_t);
|
||||
BLI_CPP_TYPE_REGISTER(uint64_t);
|
||||
|
||||
BLI_CPP_TYPE_REGISTER(blender::ColorGeometry4f);
|
||||
BLI_CPP_TYPE_REGISTER(blender::ColorGeometry4b);
|
||||
|
||||
BLI_CPP_TYPE_REGISTER(std::string);
|
||||
|
||||
BLI_VECTOR_CPP_TYPE_REGISTER(std::string);
|
||||
}
|
||||
|
||||
} // namespace blender
|
@ -76,7 +76,7 @@ struct TestType {
|
||||
|
||||
} // namespace blender::tests
|
||||
|
||||
BLI_CPP_TYPE_MAKE(TestType, blender::tests::TestType, CPPTypeFlags::BasicType)
|
||||
BLI_CPP_TYPE_MAKE(blender::tests::TestType, CPPTypeFlags::BasicType)
|
||||
|
||||
namespace blender::tests {
|
||||
|
||||
|
@ -13,6 +13,7 @@ set(INC_SYS
|
||||
set(SRC
|
||||
intern/cpp_types.cc
|
||||
intern/field.cc
|
||||
intern/field_cpp_type.cc
|
||||
intern/lazy_function.cc
|
||||
intern/lazy_function_execute.cc
|
||||
intern/lazy_function_graph.cc
|
||||
@ -27,6 +28,8 @@ set(SRC
|
||||
|
||||
FN_field.hh
|
||||
FN_field_cpp_type.hh
|
||||
FN_field_cpp_type_make.hh
|
||||
FN_init.h
|
||||
FN_lazy_function.hh
|
||||
FN_lazy_function_execute.hh
|
||||
FN_lazy_function_graph.hh
|
||||
|
@ -6,49 +6,15 @@
|
||||
* \ingroup fn
|
||||
*/
|
||||
|
||||
#include "BLI_cpp_type_make.hh"
|
||||
#include "FN_field.hh"
|
||||
|
||||
namespace blender::fn {
|
||||
|
||||
template<typename T> struct FieldCPPTypeParam {
|
||||
};
|
||||
|
||||
class FieldCPPType : public CPPType {
|
||||
/**
|
||||
* Contains information about how to deal with a `ValueOrField<T>` generically.
|
||||
*/
|
||||
class ValueOrFieldCPPType {
|
||||
private:
|
||||
const CPPType &base_type_;
|
||||
|
||||
public:
|
||||
template<typename T>
|
||||
FieldCPPType(FieldCPPTypeParam<Field<T>> /* unused */, StringRef debug_name)
|
||||
: CPPType(CPPTypeParam<Field<T>, CPPTypeFlags::None>(), debug_name),
|
||||
base_type_(CPPType::get<T>())
|
||||
{
|
||||
}
|
||||
|
||||
const CPPType &base_type() const
|
||||
{
|
||||
return base_type_;
|
||||
}
|
||||
|
||||
/* Ensure that #GField and #Field<T> have the same layout, to enable casting between the two. */
|
||||
static_assert(sizeof(Field<int>) == sizeof(GField));
|
||||
static_assert(sizeof(Field<int>) == sizeof(Field<std::string>));
|
||||
|
||||
const GField &get_gfield(const void *field) const
|
||||
{
|
||||
return *(const GField *)field;
|
||||
}
|
||||
|
||||
void construct_from_gfield(void *r_value, const GField &gfield) const
|
||||
{
|
||||
new (r_value) GField(gfield);
|
||||
}
|
||||
};
|
||||
|
||||
class ValueOrFieldCPPType : public CPPType {
|
||||
private:
|
||||
const CPPType &base_type_;
|
||||
void (*construct_from_value_)(void *dst, const void *value);
|
||||
void (*construct_from_field_)(void *dst, GField field);
|
||||
const void *(*get_value_ptr_)(const void *value_or_field);
|
||||
@ -57,35 +23,12 @@ class ValueOrFieldCPPType : public CPPType {
|
||||
GField (*as_field_)(const void *value_or_field);
|
||||
|
||||
public:
|
||||
template<typename T>
|
||||
ValueOrFieldCPPType(FieldCPPTypeParam<ValueOrField<T>> /* unused */, StringRef debug_name)
|
||||
: CPPType(CPPTypeParam<ValueOrField<T>, CPPTypeFlags::Printable>(), debug_name),
|
||||
base_type_(CPPType::get<T>())
|
||||
{
|
||||
construct_from_value_ = [](void *dst, const void *value_or_field) {
|
||||
new (dst) ValueOrField<T>(*(const T *)value_or_field);
|
||||
};
|
||||
construct_from_field_ = [](void *dst, GField field) {
|
||||
new (dst) ValueOrField<T>(Field<T>(std::move(field)));
|
||||
};
|
||||
get_value_ptr_ = [](const void *value_or_field) {
|
||||
return (const void *)&((ValueOrField<T> *)value_or_field)->value;
|
||||
};
|
||||
get_field_ptr_ = [](const void *value_or_field) -> const GField * {
|
||||
return &((ValueOrField<T> *)value_or_field)->field;
|
||||
};
|
||||
is_field_ = [](const void *value_or_field) {
|
||||
return ((ValueOrField<T> *)value_or_field)->is_field();
|
||||
};
|
||||
as_field_ = [](const void *value_or_field) -> GField {
|
||||
return ((ValueOrField<T> *)value_or_field)->as_field();
|
||||
};
|
||||
}
|
||||
/** The #ValueOrField<T> itself. */
|
||||
const CPPType &self;
|
||||
/** The type stored in the field. */
|
||||
const CPPType &value;
|
||||
|
||||
const CPPType &base_type() const
|
||||
{
|
||||
return base_type_;
|
||||
}
|
||||
template<typename ValueType> ValueOrFieldCPPType(TypeTag<ValueType> /*value_type*/);
|
||||
|
||||
void construct_from_value(void *dst, const void *value) const
|
||||
{
|
||||
@ -122,22 +65,29 @@ class ValueOrFieldCPPType : public CPPType {
|
||||
{
|
||||
return as_field_(value_or_field);
|
||||
}
|
||||
|
||||
/**
|
||||
* Try to find the #ValueOrFieldCPPType that corresponds to a #CPPType.
|
||||
*/
|
||||
static const ValueOrFieldCPPType *get_from_self(const CPPType &self);
|
||||
|
||||
/**
|
||||
* Try to find the #ValueOrFieldCPPType that wraps a #ValueOrField containing the given value
|
||||
* type. This only works when the type has been created with #FN_FIELD_CPP_TYPE_MAKE.
|
||||
*/
|
||||
static const ValueOrFieldCPPType *get_from_value(const CPPType &value);
|
||||
|
||||
template<typename ValueType> static const ValueOrFieldCPPType &get()
|
||||
{
|
||||
static const ValueOrFieldCPPType &type =
|
||||
ValueOrFieldCPPType::get_impl<std::decay_t<ValueType>>();
|
||||
return type;
|
||||
}
|
||||
|
||||
private:
|
||||
template<typename ValueType> static const ValueOrFieldCPPType &get_impl();
|
||||
|
||||
void register_self();
|
||||
};
|
||||
|
||||
} // namespace blender::fn
|
||||
|
||||
#define MAKE_FIELD_CPP_TYPE(DEBUG_NAME, FIELD_TYPE) \
|
||||
template<> const blender::CPPType &blender::CPPType::get_impl<blender::fn::Field<FIELD_TYPE>>() \
|
||||
{ \
|
||||
static blender::fn::FieldCPPType cpp_type{ \
|
||||
blender::fn::FieldCPPTypeParam<blender::fn::Field<FIELD_TYPE>>(), STRINGIFY(DEBUG_NAME)}; \
|
||||
return cpp_type; \
|
||||
} \
|
||||
template<> \
|
||||
const blender::CPPType &blender::CPPType::get_impl<blender::fn::ValueOrField<FIELD_TYPE>>() \
|
||||
{ \
|
||||
static blender::fn::ValueOrFieldCPPType cpp_type{ \
|
||||
blender::fn::FieldCPPTypeParam<blender::fn::ValueOrField<FIELD_TYPE>>(), \
|
||||
STRINGIFY(DEBUG_NAME##OrValue)}; \
|
||||
return cpp_type; \
|
||||
}
|
||||
|
51
source/blender/functions/FN_field_cpp_type_make.hh
Normal file
51
source/blender/functions/FN_field_cpp_type_make.hh
Normal file
@ -0,0 +1,51 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "FN_field_cpp_type.hh"
|
||||
|
||||
namespace blender::fn {
|
||||
|
||||
template<typename ValueType>
|
||||
inline ValueOrFieldCPPType::ValueOrFieldCPPType(TypeTag<ValueType> /*value_type*/)
|
||||
: self(CPPType::get<ValueOrField<ValueType>>()), value(CPPType::get<ValueType>())
|
||||
{
|
||||
using T = ValueType;
|
||||
construct_from_value_ = [](void *dst, const void *value_or_field) {
|
||||
new (dst) ValueOrField<T>(*(const T *)value_or_field);
|
||||
};
|
||||
construct_from_field_ = [](void *dst, GField field) {
|
||||
new (dst) ValueOrField<T>(Field<T>(std::move(field)));
|
||||
};
|
||||
get_value_ptr_ = [](const void *value_or_field) {
|
||||
return (const void *)&((ValueOrField<T> *)value_or_field)->value;
|
||||
};
|
||||
get_field_ptr_ = [](const void *value_or_field) -> const GField * {
|
||||
return &((ValueOrField<T> *)value_or_field)->field;
|
||||
};
|
||||
is_field_ = [](const void *value_or_field) {
|
||||
return ((ValueOrField<T> *)value_or_field)->is_field();
|
||||
};
|
||||
as_field_ = [](const void *value_or_field) -> GField {
|
||||
return ((ValueOrField<T> *)value_or_field)->as_field();
|
||||
};
|
||||
this->register_self();
|
||||
}
|
||||
|
||||
} // namespace blender::fn
|
||||
|
||||
/**
|
||||
* Create a new #ValueOrFieldCPPType that can be accessed through `ValueOrFieldCPPType::get<T>()`.
|
||||
*/
|
||||
#define FN_FIELD_CPP_TYPE_MAKE(VALUE_TYPE) \
|
||||
BLI_CPP_TYPE_MAKE(blender::fn::ValueOrField<VALUE_TYPE>, CPPTypeFlags::None) \
|
||||
template<> \
|
||||
const blender::fn::ValueOrFieldCPPType & \
|
||||
blender::fn::ValueOrFieldCPPType::get_impl<VALUE_TYPE>() \
|
||||
{ \
|
||||
static blender::fn::ValueOrFieldCPPType type{blender::TypeTag<VALUE_TYPE>{}}; \
|
||||
return type; \
|
||||
}
|
||||
|
||||
/** Register a #ValueOrFieldCPPType created with #FN_FIELD_CPP_TYPE_MAKE. */
|
||||
#define FN_FIELD_CPP_TYPE_REGISTER(VALUE_TYPE) blender::fn::ValueOrFieldCPPType::get<VALUE_TYPE>()
|
13
source/blender/functions/FN_init.h
Normal file
13
source/blender/functions/FN_init.h
Normal file
@ -0,0 +1,13 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
void FN_register_cpp_types(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
@ -2,20 +2,36 @@
|
||||
|
||||
#include "BLI_color.hh"
|
||||
#include "BLI_cpp_type_make.hh"
|
||||
#include "BLI_cpp_types_make.hh"
|
||||
#include "BLI_float4x4.hh"
|
||||
#include "BLI_math_vec_types.hh"
|
||||
|
||||
#include "FN_field_cpp_type.hh"
|
||||
#include "FN_field_cpp_type_make.hh"
|
||||
#include "FN_init.h"
|
||||
|
||||
MAKE_FIELD_CPP_TYPE(FloatField, float);
|
||||
MAKE_FIELD_CPP_TYPE(Float2Field, blender::float2);
|
||||
MAKE_FIELD_CPP_TYPE(Float3Field, blender::float3);
|
||||
MAKE_FIELD_CPP_TYPE(ColorGeometry4fField, blender::ColorGeometry4f);
|
||||
MAKE_FIELD_CPP_TYPE(ColorGeometry4bField, blender::ColorGeometry4b);
|
||||
MAKE_FIELD_CPP_TYPE(BoolField, bool);
|
||||
MAKE_FIELD_CPP_TYPE(Int8Field, int8_t);
|
||||
MAKE_FIELD_CPP_TYPE(Int32Field, int32_t);
|
||||
MAKE_FIELD_CPP_TYPE(StringField, std::string);
|
||||
BLI_CPP_TYPE_MAKE(StringValueOrFieldVector,
|
||||
blender::Vector<blender::fn::ValueOrField<std::string>>,
|
||||
CPPTypeFlags::None);
|
||||
FN_FIELD_CPP_TYPE_MAKE(float);
|
||||
FN_FIELD_CPP_TYPE_MAKE(blender::float2);
|
||||
FN_FIELD_CPP_TYPE_MAKE(blender::float3);
|
||||
FN_FIELD_CPP_TYPE_MAKE(blender::ColorGeometry4f);
|
||||
FN_FIELD_CPP_TYPE_MAKE(blender::ColorGeometry4b);
|
||||
FN_FIELD_CPP_TYPE_MAKE(bool);
|
||||
FN_FIELD_CPP_TYPE_MAKE(int8_t);
|
||||
FN_FIELD_CPP_TYPE_MAKE(int32_t);
|
||||
FN_FIELD_CPP_TYPE_MAKE(std::string);
|
||||
|
||||
BLI_VECTOR_CPP_TYPE_MAKE(blender::fn::ValueOrField<std::string>);
|
||||
|
||||
void FN_register_cpp_types()
|
||||
{
|
||||
FN_FIELD_CPP_TYPE_REGISTER(float);
|
||||
FN_FIELD_CPP_TYPE_REGISTER(blender::float2);
|
||||
FN_FIELD_CPP_TYPE_REGISTER(blender::float3);
|
||||
FN_FIELD_CPP_TYPE_REGISTER(blender::ColorGeometry4f);
|
||||
FN_FIELD_CPP_TYPE_REGISTER(blender::ColorGeometry4b);
|
||||
FN_FIELD_CPP_TYPE_REGISTER(bool);
|
||||
FN_FIELD_CPP_TYPE_REGISTER(int8_t);
|
||||
FN_FIELD_CPP_TYPE_REGISTER(int32_t);
|
||||
FN_FIELD_CPP_TYPE_REGISTER(std::string);
|
||||
|
||||
BLI_VECTOR_CPP_TYPE_REGISTER(blender::fn::ValueOrField<std::string>);
|
||||
}
|
||||
|
39
source/blender/functions/intern/field_cpp_type.cc
Normal file
39
source/blender/functions/intern/field_cpp_type.cc
Normal file
@ -0,0 +1,39 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
#include "FN_field_cpp_type.hh"
|
||||
|
||||
namespace blender::fn {
|
||||
|
||||
static auto &get_from_self_map()
|
||||
{
|
||||
static Map<const CPPType *, const ValueOrFieldCPPType *> map;
|
||||
return map;
|
||||
}
|
||||
|
||||
static auto &get_from_value_map()
|
||||
{
|
||||
static Map<const CPPType *, const ValueOrFieldCPPType *> map;
|
||||
return map;
|
||||
}
|
||||
|
||||
void ValueOrFieldCPPType::register_self()
|
||||
{
|
||||
get_from_value_map().add_new(&this->value, this);
|
||||
get_from_self_map().add_new(&this->self, this);
|
||||
}
|
||||
|
||||
const ValueOrFieldCPPType *ValueOrFieldCPPType::get_from_self(const CPPType &self)
|
||||
{
|
||||
const ValueOrFieldCPPType *type = get_from_self_map().lookup_default(&self, nullptr);
|
||||
BLI_assert(type == nullptr || type->self == self);
|
||||
return type;
|
||||
}
|
||||
|
||||
const ValueOrFieldCPPType *ValueOrFieldCPPType::get_from_value(const CPPType &value)
|
||||
{
|
||||
const ValueOrFieldCPPType *type = get_from_value_map().lookup_default(&value, nullptr);
|
||||
BLI_assert(type == nullptr || type->value == value);
|
||||
return type;
|
||||
}
|
||||
|
||||
} // namespace blender::fn
|
@ -817,11 +817,10 @@ static void initialize_group_input(NodesModifierData &nmd,
|
||||
auto attribute_input = std::make_shared<blender::bke::AttributeFieldInput>(
|
||||
attribute_name, *socket_type.base_cpp_type);
|
||||
GField attribute_field{std::move(attribute_input), 0};
|
||||
const blender::fn::ValueOrFieldCPPType *cpp_type =
|
||||
dynamic_cast<const blender::fn::ValueOrFieldCPPType *>(
|
||||
socket_type.geometry_nodes_cpp_type);
|
||||
BLI_assert(cpp_type != nullptr);
|
||||
cpp_type->construct_from_field(r_value, std::move(attribute_field));
|
||||
const auto *value_or_field_cpp_type = ValueOrFieldCPPType::get_from_self(
|
||||
*socket_type.geometry_nodes_cpp_type);
|
||||
BLI_assert(value_or_field_cpp_type != nullptr);
|
||||
value_or_field_cpp_type->construct_from_field(r_value, std::move(attribute_field));
|
||||
}
|
||||
else {
|
||||
init_socket_cpp_value_from_property(*property, socket_data_type, r_value);
|
||||
@ -984,9 +983,9 @@ static MultiValueMap<eAttrDomain, OutputAttributeInfo> find_output_attributes_to
|
||||
|
||||
const int index = socket->index();
|
||||
const GPointer value = output_values[index];
|
||||
const ValueOrFieldCPPType *cpp_type = dynamic_cast<const ValueOrFieldCPPType *>(value.type());
|
||||
BLI_assert(cpp_type != nullptr);
|
||||
const GField field = cpp_type->as_field(value.get());
|
||||
const auto *value_or_field_type = ValueOrFieldCPPType::get_from_self(*value.type());
|
||||
BLI_assert(value_or_field_type != nullptr);
|
||||
const GField field = value_or_field_type->as_field(value.get());
|
||||
|
||||
const bNodeSocket *interface_socket = (const bNodeSocket *)BLI_findlink(
|
||||
&nmd.node_group->outputs, index);
|
||||
|
@ -173,7 +173,6 @@ set(SRC
|
||||
nodes/node_geo_volume_cube.cc
|
||||
nodes/node_geo_volume_to_mesh.cc
|
||||
|
||||
node_geometry_exec.cc
|
||||
node_geometry_tree.cc
|
||||
node_geometry_util.cc
|
||||
|
||||
|
@ -1,7 +0,0 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
#include "BLI_cpp_type_make.hh"
|
||||
#include "NOD_geometry_exec.hh"
|
||||
|
||||
BLI_CPP_TYPE_MAKE(GeometrySet, GeometrySet, CPPTypeFlags::Printable);
|
||||
BLI_CPP_TYPE_MAKE(GeometrySetVector, blender::Vector<GeometrySet>, CPPTypeFlags::None);
|
@ -16,6 +16,7 @@
|
||||
#include "NOD_multi_function.hh"
|
||||
#include "NOD_node_declaration.hh"
|
||||
|
||||
#include "BLI_cpp_types.hh"
|
||||
#include "BLI_lazy_threading.hh"
|
||||
#include "BLI_map.hh"
|
||||
|
||||
@ -53,14 +54,11 @@ static const CPPType *get_socket_cpp_type(const bNodeSocket &socket)
|
||||
|
||||
static const CPPType *get_vector_type(const CPPType &type)
|
||||
{
|
||||
/* This could be generalized in the future. For now we only support a small set of vectors. */
|
||||
if (type.is<GeometrySet>()) {
|
||||
return &CPPType::get<Vector<GeometrySet>>();
|
||||
const VectorCPPType *vector_type = VectorCPPType::get_from_value(type);
|
||||
if (vector_type == nullptr) {
|
||||
return nullptr;
|
||||
}
|
||||
if (type.is<ValueOrField<std::string>>()) {
|
||||
return &CPPType::get<Vector<ValueOrField<std::string>>>();
|
||||
}
|
||||
return nullptr;
|
||||
return &vector_type->self;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -296,19 +294,17 @@ static void execute_multi_function_on_value_or_field(
|
||||
|
||||
for (const int i : input_types.index_range()) {
|
||||
const ValueOrFieldCPPType &type = *input_types[i];
|
||||
const CPPType &base_type = type.base_type();
|
||||
const void *value_or_field = input_values[i];
|
||||
const void *value = type.get_value_ptr(value_or_field);
|
||||
params.add_readonly_single_input(GVArray::ForSingleRef(base_type, 1, value));
|
||||
params.add_readonly_single_input(GVArray::ForSingleRef(type.value, 1, value));
|
||||
}
|
||||
for (const int i : output_types.index_range()) {
|
||||
const ValueOrFieldCPPType &type = *output_types[i];
|
||||
const CPPType &base_type = type.base_type();
|
||||
void *value_or_field = output_values[i];
|
||||
type.default_construct(value_or_field);
|
||||
type.self.default_construct(value_or_field);
|
||||
void *value = type.get_value_ptr(value_or_field);
|
||||
base_type.destruct(value);
|
||||
params.add_uninitialized_single_output(GMutableSpan{base_type, value, 1});
|
||||
type.value.destruct(value);
|
||||
params.add_uninitialized_single_output(GMutableSpan{type.value, value, 1});
|
||||
}
|
||||
fn.call(IndexRange(1), params, context);
|
||||
}
|
||||
@ -380,16 +376,14 @@ class LazyFunctionForMutedNode : public LazyFunction {
|
||||
}
|
||||
/* Perform a type conversion and then format the value. */
|
||||
const bke::DataTypeConversions &conversions = bke::get_implicit_type_conversions();
|
||||
const auto *from_field_type = dynamic_cast<const ValueOrFieldCPPType *>(&input_type);
|
||||
const auto *to_field_type = dynamic_cast<const ValueOrFieldCPPType *>(&output_type);
|
||||
if (from_field_type != nullptr && to_field_type != nullptr) {
|
||||
const CPPType &from_base_type = from_field_type->base_type();
|
||||
const CPPType &to_base_type = to_field_type->base_type();
|
||||
if (conversions.is_convertible(from_base_type, to_base_type)) {
|
||||
const auto *from_type = ValueOrFieldCPPType::get_from_self(input_type);
|
||||
const auto *to_type = ValueOrFieldCPPType::get_from_self(output_type);
|
||||
if (from_type != nullptr && to_type != nullptr) {
|
||||
if (conversions.is_convertible(from_type->value, to_type->value)) {
|
||||
const MultiFunction &multi_fn = *conversions.get_conversion_multi_function(
|
||||
MFDataType::ForSingle(from_base_type), MFDataType::ForSingle(to_base_type));
|
||||
MFDataType::ForSingle(from_type->value), MFDataType::ForSingle(to_type->value));
|
||||
execute_multi_function_on_value_or_field(
|
||||
multi_fn, {}, {from_field_type}, {to_field_type}, {input_value}, {output_value});
|
||||
multi_fn, {}, {from_type}, {to_type}, {input_value}, {output_value});
|
||||
}
|
||||
params.output_set(output_i);
|
||||
continue;
|
||||
@ -420,8 +414,8 @@ class LazyFunctionForMultiFunctionConversion : public LazyFunction {
|
||||
: fn_(fn), from_type_(from), to_type_(to), target_sockets_(std::move(target_sockets))
|
||||
{
|
||||
debug_name_ = "Convert";
|
||||
inputs_.append({"From", from});
|
||||
outputs_.append({"To", to});
|
||||
inputs_.append({"From", from.self});
|
||||
outputs_.append({"To", to.self});
|
||||
}
|
||||
|
||||
void execute_impl(lf::Params ¶ms, const lf::Context & /*context*/) const override
|
||||
@ -458,10 +452,10 @@ class LazyFunctionForMultiFunctionNode : public LazyFunction {
|
||||
debug_name_ = node.name;
|
||||
lazy_function_interface_from_node(node, r_used_inputs, r_used_outputs, inputs_, outputs_);
|
||||
for (const lf::Input &fn_input : inputs_) {
|
||||
input_types_.append(dynamic_cast<const ValueOrFieldCPPType *>(fn_input.type));
|
||||
input_types_.append(ValueOrFieldCPPType::get_from_self(*fn_input.type));
|
||||
}
|
||||
for (const lf::Output &fn_output : outputs_) {
|
||||
output_types_.append(dynamic_cast<const ValueOrFieldCPPType *>(fn_output.type));
|
||||
output_types_.append(ValueOrFieldCPPType::get_from_self(*fn_output.type));
|
||||
}
|
||||
}
|
||||
|
||||
@ -552,8 +546,7 @@ class LazyFunctionForViewerNode : public LazyFunction {
|
||||
if (use_field_input_) {
|
||||
const void *value_or_field = params.try_get_input_data_ptr(1);
|
||||
BLI_assert(value_or_field != nullptr);
|
||||
const ValueOrFieldCPPType &value_or_field_type = static_cast<const ValueOrFieldCPPType &>(
|
||||
*inputs_[1].type);
|
||||
const auto &value_or_field_type = *ValueOrFieldCPPType::get_from_self(*inputs_[1].type);
|
||||
GField field = value_or_field_type.as_field(value_or_field);
|
||||
const eAttrDomain domain = eAttrDomain(storage->domain);
|
||||
const StringRefNull viewer_attribute_name = ".viewer";
|
||||
@ -1193,14 +1186,13 @@ struct GeometryNodesLazyFunctionGraphBuilder {
|
||||
if (from_type == to_type) {
|
||||
return &from_socket;
|
||||
}
|
||||
const auto *from_field_type = dynamic_cast<const ValueOrFieldCPPType *>(&from_type);
|
||||
const auto *to_field_type = dynamic_cast<const ValueOrFieldCPPType *>(&to_type);
|
||||
const auto *from_field_type = ValueOrFieldCPPType::get_from_self(from_type);
|
||||
const auto *to_field_type = ValueOrFieldCPPType::get_from_self(to_type);
|
||||
if (from_field_type != nullptr && to_field_type != nullptr) {
|
||||
const CPPType &from_base_type = from_field_type->base_type();
|
||||
const CPPType &to_base_type = to_field_type->base_type();
|
||||
if (conversions_->is_convertible(from_base_type, to_base_type)) {
|
||||
if (conversions_->is_convertible(from_field_type->value, to_field_type->value)) {
|
||||
const MultiFunction &multi_fn = *conversions_->get_conversion_multi_function(
|
||||
MFDataType::ForSingle(from_base_type), MFDataType::ForSingle(to_base_type));
|
||||
MFDataType::ForSingle(from_field_type->value),
|
||||
MFDataType::ForSingle(to_field_type->value));
|
||||
auto fn = std::make_unique<LazyFunctionForMultiFunctionConversion>(
|
||||
multi_fn, *from_field_type, *to_field_type, std::move(target_sockets));
|
||||
lf::Node &conversion_node = lf_graph_->add_function(*fn);
|
||||
|
@ -166,10 +166,9 @@ void GeoTreeLogger::log_value(const bNode &node, const bNodeSocket &socket, cons
|
||||
const GeometrySet &geometry = *value.get<GeometrySet>();
|
||||
store_logged_value(this->allocator->construct<GeometryInfoLog>(geometry));
|
||||
}
|
||||
else if (const auto *value_or_field_type = dynamic_cast<const fn::ValueOrFieldCPPType *>(
|
||||
&type)) {
|
||||
else if (const auto *value_or_field_type = fn::ValueOrFieldCPPType::get_from_self(type)) {
|
||||
const void *value_or_field = value.get();
|
||||
const CPPType &base_type = value_or_field_type->base_type();
|
||||
const CPPType &base_type = value_or_field_type->value;
|
||||
if (value_or_field_type->is_field(value_or_field)) {
|
||||
const GField *field = value_or_field_type->get_field_ptr(value_or_field);
|
||||
if (field->node().depends_on_input()) {
|
||||
|
@ -10,7 +10,6 @@
|
||||
#include "DNA_node_types.h"
|
||||
|
||||
#include "BLI_color.hh"
|
||||
#include "BLI_cpp_type_make.hh"
|
||||
#include "BLI_listbase.h"
|
||||
#include "BLI_math_vec_types.hh"
|
||||
#include "BLI_string.h"
|
||||
@ -779,12 +778,6 @@ static bNodeSocketType *make_socket_type_string()
|
||||
return socktype;
|
||||
}
|
||||
|
||||
BLI_CPP_TYPE_MAKE(Object, Object *, CPPTypeFlags::BasicType)
|
||||
BLI_CPP_TYPE_MAKE(Collection, Collection *, CPPTypeFlags::BasicType)
|
||||
BLI_CPP_TYPE_MAKE(Texture, Tex *, CPPTypeFlags::BasicType)
|
||||
BLI_CPP_TYPE_MAKE(Image, Image *, CPPTypeFlags::BasicType)
|
||||
BLI_CPP_TYPE_MAKE(Material, Material *, CPPTypeFlags::BasicType)
|
||||
|
||||
static bNodeSocketType *make_socket_type_object()
|
||||
{
|
||||
bNodeSocketType *socktype = make_standard_socket_type(SOCK_OBJECT, PROP_NONE);
|
||||
|
@ -37,6 +37,7 @@
|
||||
#include "BKE_cachefile.h"
|
||||
#include "BKE_callbacks.h"
|
||||
#include "BKE_context.h"
|
||||
#include "BKE_cpp_types.h"
|
||||
#include "BKE_global.h"
|
||||
#include "BKE_gpencil_modifier.h"
|
||||
#include "BKE_idtype.h"
|
||||
@ -425,6 +426,7 @@ int main(int argc,
|
||||
|
||||
BKE_blender_globals_init(); /* blender.c */
|
||||
|
||||
BKE_cpp_types_init();
|
||||
BKE_idtype_init();
|
||||
BKE_cachefiles_init();
|
||||
BKE_modifier_init();
|
||||
|
Loading…
Reference in New Issue
Block a user