41using namespace value_elem;
49 if (old_type == new_type) {
54 if (!old_cpp_type || !new_cpp_type) {
58 if (type_conversions.
is_convertible(*old_cpp_type, *new_cpp_type)) {
63 *old_cpp_type, *new_cpp_type, old_value_ptr, new_value_ptr);
81 for (
const bNodeSocket *output_socket : node.output_sockets()) {
83 elem_by_local_socket.
add(output_socket, *elem);
90 for (
const SocketElem &input_elem : input_elems) {
91 if (input_elem.elem) {
92 elem_by_socket.
add({ctx_node.
context, input_elem.socket}, input_elem.elem);
93 r_modified_inputs.
append(input_elem.socket);
109 if (!to_elem || !*to_elem) {
112 elem_by_socket.
lookup_or_add(ctx_to, *to_elem).merge(*to_elem);
121 if (elem_by_socket.
contains({ctx_node.context, socket})) {
132 tree.ensure_topology_cache();
136 elem_by_socket.
add({
nullptr, initial_socket_elem.
socket}, initial_socket_elem.
elem);
139 {{
nullptr, initial_socket_elem.
socket}},
157 if (ctx_socket.context) {
162 if (!elem || !*elem) {
165 targets.input_sockets.append({ctx_socket.socket, *elem});
169 if (ctx_node.context) {
173 const bNodeSocket &socket = ctx_node.node->output_socket(0);
175 if (!elem || !*elem) {
178 targets.value_nodes.append({ctx_node.node, *elem});
181 for (
const int group_input_index :
tree.interface_inputs().index_range()) {
183 tree.interface_inputs()[group_input_index]->socket_typeinfo()->type);
189 for (
const bNode *node :
tree.group_input_nodes()) {
190 const bNodeSocket &socket = node->output_socket(group_input_index);
192 elem->merge(*socket_elem);
198 targets.group_inputs.append({group_input_index, *elem});
217 for (
const bNodeSocket *input_socket : node.input_sockets()) {
219 elem_by_local_socket.
add(input_socket, *elem);
226 for (
const SocketElem &output_elem : output_elems) {
227 if (output_elem.elem) {
229 {ctx_node.context, output_elem.socket}))
233 elem_by_socket.
add({ctx_node.
context, output_elem.socket}, new_elem);
235 r_outputs_to_propagate.
append(output_elem.socket);
253 if (!to_elem_filter) {
258 if (!converted_elem) {
261 if (ctx_to.
socket->is_multi_input()) {
264 elem_by_socket.
lookup_or_add(ctx_to, added_elem).merge(added_elem);
269 elem_by_socket.
add(ctx_to, to_elem);
282 if (!initial_socket_elem.
elem) {
287 upstream_elem_by_socket.
add({&initial_context, initial_socket_elem.
socket},
288 initial_socket_elem.
elem);
292 {{&initial_context, initial_socket_elem.
socket}},
316 initial_downstream_evaluation_sockets.
extend(upstream_eval_targets.
sockets.begin(),
317 upstream_eval_targets.
sockets.end());
318 initial_downstream_evaluation_sockets.extend(upstream_eval_targets.
group_inputs.begin(),
321 initial_downstream_evaluation_sockets.append(
322 {ctx_node.context, &ctx_node.node->output_socket(0)});
326 for (
const SocketInContext &ctx_socket : initial_downstream_evaluation_sockets) {
327 final_elem_by_socket.
add(ctx_socket, upstream_elem_by_socket.
lookup(ctx_socket));
331 initial_downstream_evaluation_sockets,
336 ctx_node, upstream_elem_by_socket, final_elem_by_socket, r_outputs_to_propagate);
341 ctx_from, ctx_to, upstream_elem_by_socket, final_elem_by_socket);
344 if (foreach_context_fn) {
347 if (handled_hashes.
add(ctx_socket.context->hash())) {
348 foreach_context_fn(*ctx_socket.context);
352 if (foreach_socket_fn) {
353 for (
auto &&item : final_elem_by_socket.
items()) {
354 foreach_socket_fn(*item.key.context, *item.key.socket, item.value);
390 float value = std::visit([](
auto v) {
return float(
v); }, value_variant);
391 float soft_min, soft_max, step, precision;
393 value = std::clamp(value, soft_min, soft_max);
394 if (array_len == 0) {
398 &C, scene, &value_ptr, prop, 0, scene->r.cfra, only_when_keyed);
401 if (index >= 0 && index < array_len) {
405 &C, scene, &value_ptr, prop, index, scene->r.cfra, only_when_keyed);
411 int value = std::visit([](
auto v) {
return int(
v); }, value_variant);
412 int soft_min, soft_max, step;
414 value = std::clamp(value, soft_min, soft_max);
415 if (array_len == 0) {
419 &C, scene, &value_ptr, prop, 0, scene->r.cfra, only_when_keyed);
422 if (index >= 0 && index < array_len) {
426 &C, scene, &value_ptr, prop, index, scene->r.cfra, only_when_keyed);
432 const bool value = std::visit([](
auto v) {
return bool(
v); }, value_variant);
433 if (array_len == 0) {
437 &C, scene, &value_ptr, prop, 0, scene->r.cfra, only_when_keyed);
440 if (index >= 0 && index < array_len) {
444 &C, scene, &value_ptr, prop, index, scene->r.cfra, only_when_keyed);
461 bool any_success =
false;
463 const std::string rna_path_for_index = fmt::format(
"{}[{}]", rna_path, i);
473 bNode &node = socket.owner_node();
476 const std::string default_value_rna_path = fmt::format(
477 "nodes[\"{}\"].inputs[{}].default_value", node.name, socket.index());
479 switch (socket.
type) {
481 const float value = value_variant.
get<
float>();
485 const int value = value_variant.
get<
int>();
489 const bool value = value_variant.
get<
bool>();
510 const float value = value_variant.
get<
float>();
511 const std::string rna_path = fmt::format(
"nodes[\"{}\"].outputs[0].default_value",
516 const int value = value_variant.
get<
int>();
517 const std::string rna_path = fmt::format(
"nodes[\"{}\"].integer", node.name);
521 const bool value = value_variant.
get<
bool>();
522 const std::string rna_path = fmt::format(
"nodes[\"{}\"].boolean", node.name);
527 const std::string rna_path = fmt::format(
"nodes[\"{}\"].vector", node.name);
533 const std::string rna_path = fmt::format(
"nodes[\"{}\"].rotation_euler", node.name);
548 const std::string main_prop_rna_path = fmt::format(
551 switch (interface_socket.socket_typeinfo()->type) {
553 const float value = value_variant.
get<
float>();
557 const int value = value_variant.
get<
int>();
561 const bool value = value_variant.
get<
bool>();
580 switch (socket.
type) {
607 if (
const std::optional<math::Quaternion> value =
648 for (
const bNodeSocket *socket : node.input_sockets()) {
649 if (!socket->is_available()) {
655 old_socket_values.
add(socket, *value);
658 for (
const bNodeSocket *socket : node.output_sockets()) {
659 if (!socket->is_available()) {
664 old_socket_values.
add(socket, *value);
670 old_socket_values.
add(socket, *value);
678 for (
auto &&item : updated_socket_values.
items()) {
680 value_by_socket.
add({context, &socket}, std::move(item.value));
681 r_modified_inputs.
append(&socket);
699 for (
const SocketToUpdate &socket_to_update : sockets_to_update) {
700 if (socket_to_update.multi_input_link) {
701 BLI_assert(socket_to_update.multi_input_link->tosock == socket_to_update.socket);
703 *socket_to_update.socket,
704 *socket_to_update.multi_input_link->fromsock,
705 socket_to_update.new_value);
706 if (!converted_value) {
709 value_by_socket.
add({socket_to_update.context, socket_to_update.multi_input_link->fromsock},
713 value_by_socket.
add({socket_to_update.context, socket_to_update.socket},
714 socket_to_update.new_value);
723 initial_sockets.
append(ctx_socket);
733 ctx_node, eval_log, value_by_socket, r_modified_inputs);
742 *ctx_from.
socket, *ctx_to.socket, *from_value);
743 if (!converted_value) {
746 value_by_socket.
add(ctx_to, std::move(*converted_value));
752 if (value_by_socket.
contains({ctx_node.context, socket})) {
753 r_sockets.append(socket);
758 bool any_success =
false;
769 {ctx_node.context, &ctx_node.node->output_socket(0)}))
777 for (
const bNode *group_input_node : nmd.
node_group->group_input_nodes()) {
778 for (
const bNodeSocket *socket : group_input_node->output_sockets().drop_back(1)) {
780 {&modifier_context, socket}))
783 C,
object, nmd, *nmd.
node_group->interface_inputs()[socket->index()], *value);
795 : socket_values_(socket_values), updated_socket_values_(updated_socket_values), node(node)
Functions to insert, delete or modify keyframes.
Scene * CTX_data_scene(const bContext *C)
#define FN_NODE_INPUT_VECTOR
#define FN_NODE_INPUT_INT
#define FN_NODE_INPUT_BOOL
#define FN_NODE_INPUT_ROTATION
void DEG_id_tag_update(ID *id, unsigned int flags)
#define ID_IS_EDITABLE(_id)
@ AUTOKEY_FLAG_INSERTAVAILABLE
ATTR_WARN_UNUSED_RESULT const BMVert * v
const Value * lookup_ptr(const Key &key) const
bool add(const Key &key, const Value &value)
const Value & lookup(const Key &key) const
ItemIterator items() const
bool contains(const Key &key) const
Value & lookup_or_add(const Key &key, const Value &value)
constexpr const char * c_str() const
void append(const T &value)
void extend(Span< T > array)
void convert_to_uninitialized(const CPPType &from_type, const CPPType &to_type, const void *from_value, void *to_value) const
bool is_convertible(const CPPType &from_type, const CPPType &to_type) const
const void * get_single_ptr_raw() const
void * allocate_single(eNodeSocketDatatype socket_type)
GeoTreeLog & get_tree_log(const ComputeContextHash &compute_context_hash)
void ensure_socket_values()
std::optional< T > find_primitive_socket_value(const bNodeSocket &query_socket)
InverseEvalParams(const bNode &node, const Map< const bNodeSocket *, bke::SocketValueVariant > &socket_values, Map< const bNodeSocket *, bke::SocketValueVariant > &updated_socket_values)
draw_view in_light_buf[] float
draw_view push_constant(Type::INT, "radiance_src") .push_constant(Type capture_info_buf storage_buf(1, Qualifier::READ, "ObjectBounds", "bounds_buf[]") .push_constant(Type draw_view int
bool autokeyframe_property(bContext *C, Scene *scene, PointerRNA *ptr, PropertyRNA *prop, int rnaindex, float cfra, bool only_if_property_keyed)
bool is_keying_flag(const Scene *scene, eKeying_Flag flag)
const DataTypeConversions & get_implicit_type_conversions()
Euler3Base< T > to_euler(const AxisAngleBase< T, AngleT > &axis_angle, EulerOrder order)
bool backpropagate_socket_values(bContext &C, Object &object, NodesModifierData &nmd, geo_eval_log::GeoModifierLog &eval_log, const Span< SocketToUpdate > sockets_to_update)
static void evaluate_node_elem_upstream(const NodeInContext &ctx_node, Vector< const bNodeSocket * > &r_modified_inputs, Map< SocketInContext, ElemVariant > &elem_by_socket)
LocalInverseEvalTargets find_local_inverse_eval_targets(const bNodeTree &tree, const SocketElem &initial_socket_elem)
void foreach_element_on_inverse_eval_path(const ComputeContext &initial_context, const SocketElem &initial_socket_elem, FunctionRef< void(const ComputeContext &context)> foreach_context_fn, FunctionRef< void(const ComputeContext &context, const bNodeSocket &socket, const ElemVariant &elem)> foreach_socket_fn)
static bool set_socket_value(bContext &C, bNodeSocket &socket, const SocketValueVariant &value_variant)
static bool set_modifier_value(bContext &C, Object &object, NodesModifierData &nmd, const bNodeTreeInterfaceSocket &interface_socket, const SocketValueVariant &value_variant)
static bool propagate_value_elem_filtered(const SocketInContext &ctx_from, const SocketInContext &ctx_to, const Map< SocketInContext, ElemVariant > &elem_by_socket_filter, Map< SocketInContext, ElemVariant > &elem_by_socket)
std::optional< SocketValueVariant > get_logged_socket_value(geo_eval_log::GeoTreeLog &tree_log, const bNodeSocket &socket)
static void get_input_elems_to_propagate(const NodeInContext &ctx_node, Vector< const bNodeSocket * > &r_sockets, Map< SocketInContext, ElemVariant > &elem_by_socket)
static bool set_rna_property_float3(bContext &C, ID &id, const StringRefNull rna_path, const float3 &value)
static void evaluate_node_elem_downstream_filtered(const NodeInContext &ctx_node, const Map< SocketInContext, ElemVariant > &elem_by_socket_filter, Map< SocketInContext, ElemVariant > &elem_by_socket, Vector< const bNodeSocket * > &r_outputs_to_propagate)
static void backpropagate_socket_values_through_node(const NodeInContext &ctx_node, geo_eval_log::GeoModifierLog &eval_log, Map< SocketInContext, SocketValueVariant > &value_by_socket, Vector< const bNodeSocket * > &r_modified_inputs)
std::optional< SocketValueVariant > convert_single_socket_value(const bNodeSocket &old_socket, const bNodeSocket &new_socket, const SocketValueVariant &old_value)
static bool set_value_node_value(bContext &C, bNode &node, const SocketValueVariant &value_variant)
static bool set_rna_property(bContext &C, ID &id, const StringRefNull rna_path, const RNAValueVariant &value_variant)
std::variant< float, int, bool > RNAValueVariant
static bool propagate_socket_elem(const SocketInContext &ctx_from, const SocketInContext &ctx_to, Map< SocketInContext, ElemVariant > &elem_by_socket)
void eval_downstream(const Span< SocketInContext > initial_sockets, ResourceScope &scope, FunctionRef< void(const NodeInContext &ctx_node, Vector< const bNodeSocket * > &r_outputs_to_propagate)> evaluate_node_fn, FunctionRef< bool(const SocketInContext &ctx_from, const SocketInContext &ctx_to)> propagate_value_fn)
UpstreamEvalTargets eval_upstream(const Span< SocketInContext > initial_sockets, ResourceScope &scope, FunctionRef< void(const NodeInContext &ctx_node, Vector< const bNodeSocket * > &r_modified_inputs)> evaluate_node_fn, FunctionRef< bool(const SocketInContext &ctx_from, const SocketInContext &ctx_to)> propagate_value_fn, FunctionRef< void(const NodeInContext &ctx_node, Vector< const bNodeSocket * > &r_sockets)> get_inputs_to_propagate_fn)
std::optional< ElemVariant > get_elem_variant_for_socket_type(const eNodeSocketDatatype type)
std::optional< ElemVariant > convert_socket_elem(const bNodeSocket &old_socket, const bNodeSocket &new_socket, const ElemVariant &old_elem)
VecBase< float, 3 > float3
void RNA_property_boolean_set_index(PointerRNA *ptr, PropertyRNA *prop, int index, bool value)
void RNA_property_int_set(PointerRNA *ptr, PropertyRNA *prop, int value)
void RNA_property_int_ui_range(PointerRNA *ptr, PropertyRNA *prop, int *softmin, int *softmax, int *step)
void RNA_property_float_ui_range(PointerRNA *ptr, PropertyRNA *prop, float *softmin, float *softmax, float *step, float *precision)
void RNA_property_float_set_index(PointerRNA *ptr, PropertyRNA *prop, int index, float value)
PropertyType RNA_property_type(PropertyRNA *prop)
void RNA_property_update(bContext *C, PointerRNA *ptr, PropertyRNA *prop)
void RNA_property_int_set_index(PointerRNA *ptr, PropertyRNA *prop, int index, int value)
void RNA_property_boolean_set(PointerRNA *ptr, PropertyRNA *prop, bool value)
int RNA_property_array_length(PointerRNA *ptr, PropertyRNA *prop)
void RNA_property_float_set(PointerRNA *ptr, PropertyRNA *prop, float value)
PointerRNA RNA_id_pointer_create(ID *id)
bool RNA_path_resolve_property_full(const PointerRNA *ptr, const char *path, PointerRNA *r_ptr, PropertyRNA **r_prop, int *r_index)
struct bNodeTree * node_group
bNodeSocketTypeHandle * typeinfo
NodeInverseElemEvalFunction eval_inverse_elem
NodeInverseEvalFunction eval_inverse
NodeElemEvalFunction eval_elem
const ComputeContext * context
const bNodeSocket * socket
Set< SocketInContext > group_inputs
Set< NodeInContext > value_nodes
Set< SocketInContext > sockets
void intersect(const ElemVariant &other)
const bNodeSocket * socket