42using namespace value_elem;
50 if (old_type == new_type) {
55 if (!old_cpp_type || !new_cpp_type) {
59 if (type_conversions.
is_convertible(*old_cpp_type, *new_cpp_type)) {
64 *old_cpp_type, *new_cpp_type, old_value_ptr, new_value_ptr);
82 for (
const bNodeSocket *output_socket : node.output_sockets()) {
84 elem_by_local_socket.
add(output_socket, *elem);
91 for (
const SocketElem &input_elem : input_elems) {
92 if (input_elem.elem) {
93 elem_by_socket.
add({ctx_node.
context, input_elem.socket}, input_elem.elem);
94 r_modified_inputs.
append(input_elem.socket);
110 if (!to_elem || !*to_elem) {
113 elem_by_socket.
lookup_or_add(ctx_to, *to_elem).merge(*to_elem);
122 if (elem_by_socket.
contains({ctx_node.context, socket})) {
133 tree.ensure_topology_cache();
137 elem_by_socket.
add({
nullptr, initial_socket_elem.
socket}, initial_socket_elem.
elem);
140 {{
nullptr, initial_socket_elem.
socket}},
141 compute_context_cache,
163 if (!elem || !*elem) {
166 targets.input_sockets.append({ctx_socket.
socket, *elem});
170 if (ctx_node.context) {
174 const bNodeSocket &socket = ctx_node.node->output_socket(0);
176 if (!elem || !*elem) {
179 targets.value_nodes.append({ctx_node.node, *elem});
182 for (
const int group_input_index :
tree.interface_inputs().index_range()) {
184 tree.interface_inputs()[group_input_index]->socket_typeinfo()->type);
190 for (
const bNode *node :
tree.group_input_nodes()) {
191 const bNodeSocket &socket = node->output_socket(group_input_index);
193 elem->merge(*socket_elem);
199 targets.group_inputs.append({group_input_index, *elem});
218 for (
const bNodeSocket *input_socket : node.input_sockets()) {
220 elem_by_local_socket.
add(input_socket, *elem);
227 for (
const SocketElem &output_elem : output_elems) {
228 if (output_elem.elem) {
230 {ctx_node.context, output_elem.socket}))
234 elem_by_socket.
add({ctx_node.
context, output_elem.socket}, new_elem);
236 r_outputs_to_propagate.
append(output_elem.socket);
254 if (!to_elem_filter) {
259 if (!converted_elem) {
262 if (ctx_to.
socket->is_multi_input()) {
265 elem_by_socket.
lookup_or_add(ctx_to, added_elem).merge(added_elem);
270 elem_by_socket.
add(ctx_to, to_elem);
283 if (!initial_socket_elem.
elem) {
288 upstream_elem_by_socket.
add({&initial_context, initial_socket_elem.
socket},
289 initial_socket_elem.
elem);
293 {{&initial_context, initial_socket_elem.
socket}},
294 compute_context_cache,
317 initial_downstream_evaluation_sockets.
extend(upstream_eval_targets.
sockets.begin(),
318 upstream_eval_targets.
sockets.end());
319 initial_downstream_evaluation_sockets.extend(upstream_eval_targets.
group_inputs.begin(),
322 initial_downstream_evaluation_sockets.append(
323 {ctx_node.context, &ctx_node.node->output_socket(0)});
327 for (
const SocketInContext &ctx_socket : initial_downstream_evaluation_sockets) {
328 final_elem_by_socket.
add(ctx_socket, upstream_elem_by_socket.
lookup(ctx_socket));
332 initial_downstream_evaluation_sockets,
333 compute_context_cache,
337 ctx_node, upstream_elem_by_socket, final_elem_by_socket, r_outputs_to_propagate);
342 ctx_from, ctx_to, upstream_elem_by_socket, final_elem_by_socket);
345 if (foreach_context_fn) {
348 if (handled_hashes.
add(ctx_socket.context->hash())) {
349 foreach_context_fn(*ctx_socket.context);
353 if (foreach_socket_fn) {
354 for (
auto &&item : final_elem_by_socket.
items()) {
355 foreach_socket_fn(*item.key.context, *item.key.socket, item.value);
391 float value = std::visit([](
auto v) {
return float(
v); }, value_variant);
392 float soft_min, soft_max,
step, precision;
394 value = std::clamp(value, soft_min, soft_max);
395 if (array_len == 0) {
399 &
C, scene, &value_ptr, prop, 0, scene->
r.
cfra, only_when_keyed);
402 if (index >= 0 && index < array_len) {
406 &
C, scene, &value_ptr, prop, index, scene->
r.
cfra, only_when_keyed);
412 int value = std::visit([](
auto v) {
return int(
v); }, value_variant);
413 int soft_min, soft_max,
step;
415 value = std::clamp(value, soft_min, soft_max);
416 if (array_len == 0) {
420 &
C, scene, &value_ptr, prop, 0, scene->
r.
cfra, only_when_keyed);
423 if (index >= 0 && index < array_len) {
427 &
C, scene, &value_ptr, prop, index, scene->
r.
cfra, only_when_keyed);
433 const bool value = std::visit([](
auto v) {
return bool(
v); }, value_variant);
434 if (array_len == 0) {
438 &
C, scene, &value_ptr, prop, 0, scene->
r.
cfra, only_when_keyed);
441 if (index >= 0 && index < array_len) {
445 &
C, scene, &value_ptr, prop, index, scene->
r.
cfra, only_when_keyed);
462 bool any_success =
false;
464 const std::string rna_path_for_index = fmt::format(
"{}[{}]", rna_path,
i);
474 bNode &node = socket.owner_node();
477 const std::string default_value_rna_path = fmt::format(
480 switch (socket.
type) {
482 const float value = value_variant.
get<
float>();
486 const int value = value_variant.
get<
int>();
490 const bool value = value_variant.
get<
bool>();
512 const float value = value_variant.
get<
float>();
513 const std::string rna_path = fmt::format(
"nodes[\"{}\"].outputs[0].default_value",
518 const int value = value_variant.
get<
int>();
519 const std::string rna_path = fmt::format(
"nodes[\"{}\"].integer",
BLI_str_escape(node.
name));
523 const bool value = value_variant.
get<
bool>();
524 const std::string rna_path = fmt::format(
"nodes[\"{}\"].boolean",
BLI_str_escape(node.
name));
529 const std::string rna_path = fmt::format(
"nodes[\"{}\"].vector",
BLI_str_escape(node.
name));
535 const std::string rna_path = fmt::format(
"nodes[\"{}\"].rotation_euler",
551 const std::string main_prop_rna_path = fmt::format(
554 switch (interface_socket.socket_typeinfo()->type) {
556 const float value = value_variant.
get<
float>();
560 const int value = value_variant.
get<
int>();
564 const bool value = value_variant.
get<
bool>();
584 switch (socket.
type) {
611 if (
const std::optional<math::Quaternion> value =
652 for (
const bNodeSocket *socket : node.input_sockets()) {
653 if (!socket->is_available()) {
659 old_socket_values.
add(socket, *value);
662 for (
const bNodeSocket *socket : node.output_sockets()) {
663 if (!socket->is_available()) {
668 old_socket_values.
add(socket, *value);
674 old_socket_values.
add(socket, *value);
682 for (
auto &&item : updated_socket_values.
items()) {
684 value_by_socket.
add({context, &socket}, std::move(item.value));
685 r_modified_inputs.
append(&socket);
703 for (
const SocketToUpdate &socket_to_update : sockets_to_update) {
704 if (socket_to_update.multi_input_link) {
705 BLI_assert(socket_to_update.multi_input_link->tosock == socket_to_update.socket);
707 *socket_to_update.socket,
708 *socket_to_update.multi_input_link->fromsock,
709 socket_to_update.new_value);
710 if (!converted_value) {
713 value_by_socket.
add({socket_to_update.context, socket_to_update.multi_input_link->fromsock},
717 value_by_socket.
add({socket_to_update.context, socket_to_update.socket},
718 socket_to_update.new_value);
727 initial_sockets.
append(ctx_socket);
733 compute_context_cache,
737 ctx_node, eval_log, value_by_socket, r_modified_inputs);
746 *ctx_from.
socket, *ctx_to.socket, *from_value);
747 if (!converted_value) {
750 value_by_socket.
add(ctx_to, std::move(*converted_value));
756 if (value_by_socket.
contains({ctx_node.context, socket})) {
757 r_sockets.append(socket);
762 bool any_success =
false;
773 {ctx_node.context, &ctx_node.node->output_socket(0)}))
781 for (
const bNode *group_input_node : nmd.
node_group->group_input_nodes()) {
782 for (
const bNodeSocket *socket : group_input_node->output_sockets().drop_back(1)) {
784 {&modifier_context, socket}))
787 C,
object, nmd, *nmd.
node_group->interface_inputs()[socket->index()], *value);
799 : 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
size_t BLI_str_escape(char *__restrict dst, const char *__restrict src, size_t dst_maxncpy) ATTR_NONNULL(1
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
KeyIterator keys() const &
bool contains(const Key &key) const
ItemIterator items() 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)
VecBase< float, D > step(VecOp< float, D >, VecOp< float, D >) RET
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()
QuaternionBase< float > Quaternion
Euler3Base< T > to_euler(const AxisAngleBase< T, AngleT > &axis_angle, EulerOrder order)
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)
static void backpropagate_socket_values_through_node(const NodeInContext &ctx_node, geo_eval_log::GeoNodesLog &eval_log, Map< SocketInContext, SocketValueVariant > &value_by_socket, Vector< const bNodeSocket * > &r_modified_inputs)
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)
bool backpropagate_socket_values(bContext &C, Object &object, NodesModifierData &nmd, geo_eval_log::GeoNodesLog &eval_log, const Span< SocketToUpdate > sockets_to_update)
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)
UpstreamEvalTargets eval_upstream(const Span< SocketInContext > initial_sockets, bke::ComputeContextCache &compute_context_cache, 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)
void eval_downstream(const Span< SocketInContext > initial_sockets, bke::ComputeContextCache &compute_context_cache, 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)
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)
MatBase< float, 4, 4 > float4x4
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
bNodeTypeHandle * typeinfo
NodeInverseElemEvalFunction eval_inverse_elem
NodeInverseEvalFunction eval_inverse
NodeElemEvalFunction eval_elem
const ComputeContext * context
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