Cleanup: Geometry Nodes: avoid unnecessary void pointer
All socket types use `SocketValueVariant` now, so using `void *` is not necessary anymore. Pull Request: https://projects.blender.org/blender/blender/pulls/144415
This commit is contained in:
@@ -92,11 +92,9 @@ static std::unique_ptr<BakeItem> move_common_socket_value_to_bake_item(
|
||||
if (const auto *item_socket_value = std::get_if<nodes::BundleItemSocketValue>(
|
||||
&bundle_item.value.value))
|
||||
{
|
||||
SocketValueVariant value_variant = item_socket_value->value;
|
||||
if (std::unique_ptr<BakeItem> bake_item = move_common_socket_value_to_bake_item(
|
||||
*item_socket_value->type,
|
||||
*static_cast<SocketValueVariant *>(item_socket_value->value),
|
||||
std::nullopt,
|
||||
r_geometry_bake_items))
|
||||
*item_socket_value->type, value_variant, std::nullopt, r_geometry_bake_items))
|
||||
{
|
||||
bundle_bake_item->items.append(
|
||||
BundleBakeItem::Item{bundle_item.key,
|
||||
@@ -297,7 +295,7 @@ Array<std::unique_ptr<BakeItem>> move_socket_values_to_bake_items(
|
||||
copy_bake_item_to_socket_value(
|
||||
*socket_value->value, stype->type, {}, data_block_map, r_attribute_map))
|
||||
{
|
||||
bundle.add(item.key, nodes::BundleItemSocketValue{stype, &*child_value_variant});
|
||||
bundle.add(item.key, nodes::BundleItemSocketValue{stype, *child_value_variant});
|
||||
}
|
||||
else {
|
||||
return std::nullopt;
|
||||
|
||||
@@ -18,7 +18,7 @@ struct BundleItemSocketValue {
|
||||
/** The type of data referenced. It uses #bNodeSocketType::geometry_nodes_cpp_type. */
|
||||
const bke::bNodeSocketType *type;
|
||||
/** Non-owning pointer to the value. The memory is owned by the Bundle directly. */
|
||||
void *value;
|
||||
bke::SocketValueVariant value;
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -60,16 +60,8 @@ class Bundle : public ImplicitSharingMixin {
|
||||
|
||||
private:
|
||||
Vector<StoredItem> items_;
|
||||
Vector<void *> buffers_;
|
||||
|
||||
public:
|
||||
Bundle();
|
||||
Bundle(const Bundle &other);
|
||||
Bundle(Bundle &&other) noexcept;
|
||||
Bundle &operator=(const Bundle &other);
|
||||
Bundle &operator=(Bundle &&other) noexcept;
|
||||
~Bundle();
|
||||
|
||||
static BundlePtr create();
|
||||
|
||||
bool add(StringRef key, const BundleItemValue &value);
|
||||
@@ -115,21 +107,15 @@ inline std::optional<T> BundleItemValue::as_socket_value(
|
||||
if (!socket_value) {
|
||||
return std::nullopt;
|
||||
}
|
||||
if (!socket_value->value || !socket_value->type) {
|
||||
return std::nullopt;
|
||||
if (socket_value->type->type == dst_socket_type.type) {
|
||||
return socket_value->value.get<T>();
|
||||
}
|
||||
const void *converted_value = socket_value->value;
|
||||
BUFFER_FOR_CPP_TYPE_VALUE(*dst_socket_type.geometry_nodes_cpp_type, buffer);
|
||||
if (socket_value->type != &dst_socket_type) {
|
||||
if (!implicitly_convert_socket_value(
|
||||
*socket_value->type, socket_value->value, dst_socket_type, buffer))
|
||||
{
|
||||
return std::nullopt;
|
||||
}
|
||||
converted_value = buffer;
|
||||
if (std::optional<bke::SocketValueVariant> converted_value = implicitly_convert_socket_value(
|
||||
*socket_value->type, socket_value->value, dst_socket_type))
|
||||
{
|
||||
return converted_value->get<T>();
|
||||
}
|
||||
const auto &value_variant = *static_cast<const bke::SocketValueVariant *>(converted_value);
|
||||
return value_variant.get<T>();
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
template<typename T> inline const bke::bNodeSocketType *socket_type_info_by_static_type()
|
||||
@@ -183,15 +169,8 @@ template<typename T> inline std::optional<T> BundleItemValue::as() const
|
||||
if (!socket_value) {
|
||||
return std::nullopt;
|
||||
}
|
||||
if (!socket_value->value || !socket_value->type) {
|
||||
return std::nullopt;
|
||||
}
|
||||
if (!socket_value->type->geometry_nodes_cpp_type->is<bke::SocketValueVariant>()) {
|
||||
return std::nullopt;
|
||||
}
|
||||
const auto *value = static_cast<const bke::SocketValueVariant *>(socket_value->value);
|
||||
if (value->is_list()) {
|
||||
return value->get<ListPtr>();
|
||||
if (socket_value->value.is_list()) {
|
||||
return socket_value->value.get<ListPtr>();
|
||||
}
|
||||
return std::nullopt;
|
||||
}
|
||||
@@ -242,7 +221,7 @@ template<typename T, typename Fn> inline void to_stored_type(T &&value, Fn &&fn)
|
||||
}
|
||||
else if (const bke::bNodeSocketType *socket_type = socket_type_info_by_static_type<DecayT>()) {
|
||||
auto value_variant = bke::SocketValueVariant::From(std::forward<T>(value));
|
||||
fn(BundleItemValue{BundleItemSocketValue{socket_type, &value_variant}});
|
||||
fn(BundleItemValue{BundleItemSocketValue{socket_type, value_variant}});
|
||||
}
|
||||
else {
|
||||
/* All allowed types should be handled above already. */
|
||||
|
||||
@@ -8,17 +8,16 @@
|
||||
|
||||
#include "NOD_geometry_nodes_lazy_function.hh"
|
||||
|
||||
#include "BKE_node_socket_value.hh"
|
||||
|
||||
namespace blender::nodes {
|
||||
|
||||
struct ClosureEagerEvalParams {
|
||||
struct InputItem {
|
||||
std::string key;
|
||||
const bke::bNodeSocketType *type = nullptr;
|
||||
/**
|
||||
* The actual socket value of type bNodeSocketType::geometry_nodes_cpp_type.
|
||||
* This is not const, because it may be moved from.
|
||||
*/
|
||||
void *value = nullptr;
|
||||
/** This may be moved from. */
|
||||
bke::SocketValueVariant value;
|
||||
};
|
||||
|
||||
struct OutputItem {
|
||||
@@ -28,7 +27,7 @@ struct ClosureEagerEvalParams {
|
||||
* Where the output value should be stored. This is expected to point to uninitialized memory
|
||||
* when it's passed into #evaluate_closure_eagerly which will then construct the value inplace.
|
||||
*/
|
||||
void *value = nullptr;
|
||||
bke::SocketValueVariant *value = nullptr;
|
||||
};
|
||||
|
||||
Vector<InputItem> inputs;
|
||||
|
||||
@@ -56,10 +56,10 @@ template<typename T> constexpr bool is_GeoNodesMultiInput_v<GeoNodesMultiInput<T
|
||||
* Performs implicit conversion between socket types. Returns false if the conversion is not
|
||||
* possible. In that case, r_to_value is left uninitialized.
|
||||
*/
|
||||
[[nodiscard]] bool implicitly_convert_socket_value(const bke::bNodeSocketType &from_type,
|
||||
const void *from_value,
|
||||
const bke::bNodeSocketType &to_type,
|
||||
void *r_to_value);
|
||||
[[nodiscard]] std::optional<bke::SocketValueVariant> implicitly_convert_socket_value(
|
||||
const bke::bNodeSocketType &from_type,
|
||||
const bke::SocketValueVariant &from_value,
|
||||
const bke::bNodeSocketType &to_type);
|
||||
|
||||
/**
|
||||
* Builds a lazy-function that can convert between socket types. Returns null if the conversion is
|
||||
|
||||
@@ -122,9 +122,9 @@ static void node_geo_exec(GeoNodeExecParams params)
|
||||
if (name.is_empty()) {
|
||||
continue;
|
||||
}
|
||||
void *input_ptr = params.low_level_lazy_function_params().try_get_input_data_ptr(i);
|
||||
BLI_assert(input_ptr);
|
||||
bundle.add(name, BundleItemSocketValue{stype, input_ptr});
|
||||
bke::SocketValueVariant value = params.extract_input<bke::SocketValueVariant>(
|
||||
node.input_socket(i).identifier);
|
||||
bundle.add(name, BundleItemSocketValue{stype, std::move(value)});
|
||||
}
|
||||
|
||||
params.set_output("Bundle", std::move(bundle_ptr));
|
||||
|
||||
@@ -144,14 +144,13 @@ static void node_geo_exec(GeoNodeExecParams params)
|
||||
fmt::format("{}: \"{}\"", TIP_("Cannot get internal value from bundle"), name));
|
||||
continue;
|
||||
}
|
||||
void *output_ptr = lf_params.get_output_data_ptr(i);
|
||||
if (socket_value->type->type == stype->type) {
|
||||
socket_value->type->geometry_nodes_cpp_type->copy_construct(socket_value->value, output_ptr);
|
||||
}
|
||||
else {
|
||||
if (implicitly_convert_socket_value(
|
||||
*socket_value->type, socket_value->value, *stype, output_ptr))
|
||||
|
||||
SocketValueVariant output_value = std::move(socket_value->value);
|
||||
if (socket_value->type->type != stype->type) {
|
||||
if (std::optional<SocketValueVariant> converted_value = implicitly_convert_socket_value(
|
||||
*socket_value->type, output_value, *stype))
|
||||
{
|
||||
output_value = std::move(*converted_value);
|
||||
params.error_message_add(
|
||||
NodeWarningType::Info,
|
||||
fmt::format("{}: \"{}\" ({} " BLI_STR_UTF8_BLACK_RIGHT_POINTING_SMALL_TRIANGLE " {})",
|
||||
@@ -168,10 +167,10 @@ static void node_geo_exec(GeoNodeExecParams params)
|
||||
name,
|
||||
TIP_(socket_value->type->label),
|
||||
TIP_(stype->label)));
|
||||
construct_socket_default_value(*stype, output_ptr);
|
||||
output_value = *socket_value->type->geometry_nodes_default_value;
|
||||
}
|
||||
}
|
||||
lf_params.output_set(i);
|
||||
lf_params.set_output(i, std::move(output_value));
|
||||
}
|
||||
|
||||
params.set_default_remaining_outputs();
|
||||
|
||||
@@ -43,59 +43,11 @@ bool BundleSignature::all_matching_exactly(const Span<BundleSignature> signature
|
||||
return true;
|
||||
}
|
||||
|
||||
Bundle::Bundle() = default;
|
||||
|
||||
Bundle::~Bundle()
|
||||
{
|
||||
for (StoredItem &item : items_) {
|
||||
if (BundleItemSocketValue *socket_value = std::get_if<BundleItemSocketValue>(
|
||||
&item.value.value))
|
||||
{
|
||||
socket_value->type->geometry_nodes_cpp_type->destruct(socket_value->value);
|
||||
}
|
||||
}
|
||||
for (void *buffer : buffers_) {
|
||||
MEM_freeN(buffer);
|
||||
}
|
||||
}
|
||||
|
||||
Bundle::Bundle(const Bundle &other)
|
||||
{
|
||||
for (const StoredItem &item : other.items_) {
|
||||
this->add_new(item.key, item.value);
|
||||
}
|
||||
}
|
||||
|
||||
Bundle::Bundle(Bundle &&other) noexcept
|
||||
: items_(std::move(other.items_)), buffers_(std::move(other.buffers_))
|
||||
{
|
||||
}
|
||||
|
||||
BundlePtr Bundle::create()
|
||||
{
|
||||
return BundlePtr(MEM_new<Bundle>(__func__));
|
||||
}
|
||||
|
||||
Bundle &Bundle::operator=(const Bundle &other)
|
||||
{
|
||||
if (this == &other) {
|
||||
return *this;
|
||||
}
|
||||
this->~Bundle();
|
||||
new (this) Bundle(other);
|
||||
return *this;
|
||||
}
|
||||
|
||||
Bundle &Bundle::operator=(Bundle &&other) noexcept
|
||||
{
|
||||
if (this == &other) {
|
||||
return *this;
|
||||
}
|
||||
this->~Bundle();
|
||||
new (this) Bundle(std::move(other));
|
||||
return *this;
|
||||
}
|
||||
|
||||
[[maybe_unused]] static bool is_valid_key(const StringRef key)
|
||||
{
|
||||
return key.find('/') == StringRef::not_found;
|
||||
@@ -104,22 +56,7 @@ Bundle &Bundle::operator=(Bundle &&other) noexcept
|
||||
void Bundle::add_new(const StringRef key, const BundleItemValue &value)
|
||||
{
|
||||
BLI_assert(is_valid_key(key));
|
||||
if (const BundleItemSocketValue *socket_value = std::get_if<BundleItemSocketValue>(&value.value))
|
||||
{
|
||||
const bke::bNodeSocketType &type = *socket_value->type;
|
||||
BLI_assert(type.geometry_nodes_cpp_type);
|
||||
const CPPType &cpp_type = *type.geometry_nodes_cpp_type;
|
||||
void *buffer = MEM_mallocN_aligned(cpp_type.size, cpp_type.alignment, __func__);
|
||||
cpp_type.copy_construct(socket_value->value, buffer);
|
||||
items_.append(StoredItem{std::move(key), {BundleItemSocketValue{&type, buffer}}});
|
||||
buffers_.append(buffer);
|
||||
}
|
||||
else if (std::holds_alternative<BundleItemInternalValue>(value.value)) {
|
||||
items_.append(StoredItem{std::move(key), value});
|
||||
}
|
||||
else {
|
||||
BLI_assert_unreachable();
|
||||
}
|
||||
items_.append(StoredItem{std::move(key), value});
|
||||
}
|
||||
|
||||
void Bundle::add_override(const StringRef key, const BundleItemValue &value)
|
||||
@@ -164,7 +101,7 @@ void Bundle::add_path_override(const StringRef path, const BundleItemValue &valu
|
||||
std::move(child_bundle));
|
||||
this->add(
|
||||
first_part,
|
||||
BundleItemSocketValue{bke::node_socket_type_find_static(SOCK_BUNDLE), &child_bundle_value});
|
||||
BundleItemSocketValue{bke::node_socket_type_find_static(SOCK_BUNDLE), child_bundle_value});
|
||||
}
|
||||
|
||||
bool Bundle::add_path(StringRef path, const BundleItemValue &value)
|
||||
@@ -245,17 +182,7 @@ BundlePtr Bundle::copy() const
|
||||
bool Bundle::remove(const StringRef key)
|
||||
{
|
||||
BLI_assert(is_valid_key(key));
|
||||
const int removed_num = items_.remove_if([&key](StoredItem &item) {
|
||||
if (item.key == key) {
|
||||
if (BundleItemSocketValue *socket_value = std::get_if<BundleItemSocketValue>(
|
||||
&item.value.value))
|
||||
{
|
||||
socket_value->type->geometry_nodes_cpp_type->destruct(socket_value->value);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
});
|
||||
const int removed_num = items_.remove_if([&key](StoredItem &item) { return item.key == key; });
|
||||
return removed_num >= 1;
|
||||
}
|
||||
|
||||
|
||||
@@ -788,18 +788,18 @@ void evaluate_closure_eagerly(const Closure &closure, ClosureEagerEvalParams &pa
|
||||
if (const std::optional<int> mapped_i = inputs_map[input_item_i]) {
|
||||
const bke::bNodeSocketType &from_type = *item.type;
|
||||
const bke::bNodeSocketType &to_type = *signature.inputs[*mapped_i].type;
|
||||
const CPPType &to_cpp_type = *to_type.geometry_nodes_cpp_type;
|
||||
void *value = allocator.allocate(to_cpp_type);
|
||||
if (&from_type == &to_type) {
|
||||
to_cpp_type.copy_construct(item.value, value);
|
||||
bke::SocketValueVariant input_value;
|
||||
if (std::optional<bke::SocketValueVariant> value = implicitly_convert_socket_value(
|
||||
from_type, item.value, to_type))
|
||||
{
|
||||
input_value = *value;
|
||||
}
|
||||
else {
|
||||
if (!implicitly_convert_socket_value(from_type, item.value, to_type, value)) {
|
||||
const void *default_value = closure.default_input_value(*mapped_i);
|
||||
to_cpp_type.copy_construct(default_value, value);
|
||||
}
|
||||
input_value = *to_type.geometry_nodes_default_value;
|
||||
}
|
||||
lf_input_values[indices.inputs.main[*mapped_i]] = {to_cpp_type, value};
|
||||
lf_input_values[indices.inputs.main[*mapped_i]] = {
|
||||
CPPType::get<bke::SocketValueVariant>(),
|
||||
allocator.construct<bke::SocketValueVariant>(std::move(input_value)).release()};
|
||||
}
|
||||
else {
|
||||
/* Provided input value is ignored. */
|
||||
@@ -859,15 +859,15 @@ void evaluate_closure_eagerly(const Closure &closure, ClosureEagerEvalParams &pa
|
||||
if (const std::optional<int> mapped_i = outputs_map[output_item_i]) {
|
||||
const bke::bNodeSocketType &from_type = *signature.outputs[*mapped_i].type;
|
||||
const bke::bNodeSocketType &to_type = *item.type;
|
||||
const CPPType &to_cpp_type = *to_type.geometry_nodes_cpp_type;
|
||||
void *computed_value = lf_output_values[indices.outputs.main[*mapped_i]].get();
|
||||
if (&from_type == &to_type) {
|
||||
to_cpp_type.move_construct(computed_value, item.value);
|
||||
if (std::optional<bke::SocketValueVariant> value = implicitly_convert_socket_value(
|
||||
from_type,
|
||||
*lf_output_values[indices.outputs.main[*mapped_i]].get<bke::SocketValueVariant>(),
|
||||
to_type))
|
||||
{
|
||||
new (item.value) bke::SocketValueVariant(std::move(*value));
|
||||
}
|
||||
else {
|
||||
if (!implicitly_convert_socket_value(from_type, computed_value, to_type, item.value)) {
|
||||
construct_socket_default_value(to_type, item.value);
|
||||
}
|
||||
new (item.value) bke::SocketValueVariant(*to_type.geometry_nodes_default_value);
|
||||
}
|
||||
}
|
||||
else {
|
||||
|
||||
@@ -548,37 +548,34 @@ static void execute_multi_function_on_value_variant__field(
|
||||
return true;
|
||||
}
|
||||
|
||||
bool implicitly_convert_socket_value(const bke::bNodeSocketType &from_type,
|
||||
const void *from_value,
|
||||
const bke::bNodeSocketType &to_type,
|
||||
void *r_to_value)
|
||||
std::optional<SocketValueVariant> implicitly_convert_socket_value(
|
||||
const bke::bNodeSocketType &from_type,
|
||||
const SocketValueVariant &from_value,
|
||||
const bke::bNodeSocketType &to_type)
|
||||
{
|
||||
BLI_assert(from_value != r_to_value);
|
||||
if (from_type.type == to_type.type) {
|
||||
from_type.geometry_nodes_cpp_type->copy_construct(from_value, r_to_value);
|
||||
return true;
|
||||
return from_value;
|
||||
}
|
||||
const bke::DataTypeConversions &conversions = bke::get_implicit_type_conversions();
|
||||
const CPPType *from_cpp_type = from_type.base_cpp_type;
|
||||
const CPPType *to_cpp_type = to_type.base_cpp_type;
|
||||
if (!from_cpp_type || !to_cpp_type) {
|
||||
return false;
|
||||
return std::nullopt;
|
||||
}
|
||||
if (conversions.is_convertible(*from_cpp_type, *to_cpp_type)) {
|
||||
const MultiFunction &multi_fn = *conversions.get_conversion_multi_function(
|
||||
mf::DataType::ForSingle(*from_cpp_type), mf::DataType::ForSingle(*to_cpp_type));
|
||||
SocketValueVariant input_variant = *static_cast<const SocketValueVariant *>(from_value);
|
||||
SocketValueVariant *output_variant = new (r_to_value) SocketValueVariant();
|
||||
SocketValueVariant input_variant = from_value;
|
||||
SocketValueVariant output_variant;
|
||||
std::string error_message;
|
||||
if (!execute_multi_function_on_value_variant(
|
||||
multi_fn, {}, {&input_variant}, {output_variant}, nullptr, error_message))
|
||||
multi_fn, {}, {&input_variant}, {&output_variant}, nullptr, error_message))
|
||||
{
|
||||
std::destroy_at(output_variant);
|
||||
return false;
|
||||
return std::nullopt;
|
||||
}
|
||||
return true;
|
||||
return output_variant;
|
||||
}
|
||||
return false;
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
class LazyFunctionForImplicitConversion : public LazyFunction {
|
||||
@@ -691,16 +688,16 @@ class LazyFunctionForMutedNode : public LazyFunction {
|
||||
continue;
|
||||
}
|
||||
const int lf_input_index = lf_index_by_bsocket_[input_bsocket->index_in_tree()];
|
||||
const void *input_value = params.try_get_input_data_ptr_or_request(lf_input_index);
|
||||
if (input_value == nullptr) {
|
||||
const SocketValueVariant *input_value =
|
||||
params.try_get_input_data_ptr_or_request<SocketValueVariant>(lf_input_index);
|
||||
if (!input_value) {
|
||||
/* Wait for value to be available. */
|
||||
continue;
|
||||
}
|
||||
void *output_value = params.get_output_data_ptr(lf_output_index);
|
||||
if (implicitly_convert_socket_value(
|
||||
*input_bsocket->typeinfo, input_value, *output_bsocket->typeinfo, output_value))
|
||||
if (std::optional<SocketValueVariant> converted_value = implicitly_convert_socket_value(
|
||||
*input_bsocket->typeinfo, *input_value, *output_bsocket->typeinfo))
|
||||
{
|
||||
params.output_set(lf_output_index);
|
||||
params.set_output(lf_output_index, std::move(*converted_value));
|
||||
continue;
|
||||
}
|
||||
set_default_value_for_output_socket(params, lf_output_index, *output_bsocket);
|
||||
|
||||
Reference in New Issue
Block a user