43 return {ie::FloatElem::all()};
46 return {ie::FloatElem::all()};
52 elem.translation = ie::VectorElem::all();
57 elem.rotation = ie::RotationElem::all();
58 elem.scale = ie::VectorElem::all();
64 if (std::optional<ie::ElemVariant> elem = ie::get_elem_variant_for_socket_type(socket_type)) {
87 for (
const bNode *node :
tree.all_nodes()) {
88 if (node->is_muted()) {
91 if (node->is_group()) {
96 if (!group.
runtime->gizmo_propagation) {
100 for (
const ie::GroupInputElem &group_input_elem :
103 const bNodeSocket &input_socket = node->input_socket(group_input_elem.group_input_index);
104 all_gizmo_inputs.
append({&input_socket, &input_socket, group_input_elem.elem});
109 const bNodeSocket &gizmo_input_socket = node->input_socket(0);
112 for (
const bNodeLink *link : gizmo_input_socket.directly_linked_links()) {
113 if (!link->is_used()) {
116 all_gizmo_inputs.
append({&gizmo_input_socket, link->fromsock, elem});
122 for (
const GizmoInput &gizmo_input : all_gizmo_inputs) {
124 const ie::SocketElem gizmo_input_socket_elem{gizmo_input.gizmo_socket, gizmo_input.elem};
127 const std::optional<ie::ElemVariant> converted_elem = ie::convert_socket_elem(
128 *gizmo_input.gizmo_socket, *gizmo_input.propagation_start_socket, gizmo_input.elem);
129 if (!converted_elem) {
132 const ie::LocalInverseEvalTargets targets = ie::find_local_inverse_eval_targets(
133 tree, {gizmo_input.propagation_start_socket, *converted_elem});
134 const bool has_target = !targets.input_sockets.is_empty() ||
135 !targets.group_inputs.is_empty() || !targets.value_nodes.is_empty();
140 for (
const ie::SocketElem &input_socket : targets.input_sockets) {
144 for (
const ie::ValueNodeElem &value_node : targets.value_nodes) {
148 for (
const ie::GroupInputElem &group_input : targets.group_inputs) {
150 for (
const bNode *group_input_node :
tree.group_input_nodes()) {
152 &group_input_node->output_socket(group_input.group_input_index));
157 return gizmo_propagation;
162 tree.ensure_topology_cache();
164 if (
tree.has_available_link_cycle()) {
165 const bool changed =
tree.runtime->gizmo_propagation !=
nullptr;
166 tree.runtime->gizmo_propagation.reset();
171 const bool changed =
tree.runtime->gizmo_propagation ?
172 *
tree.runtime->gizmo_propagation != new_gizmo_propagation :
174 tree.runtime->gizmo_propagation = std::make_unique<TreeGizmoPropagation>(
175 std::move(new_gizmo_propagation));
186 const ie::GroupInputElem &group_input,
192 for (
const ie::SocketElem &gizmo_input :
210 const bNode &node = input_socket.socket->owner_node();
216 if (node.is_muted()) {
220 fn(*compute_context, node, *input_socket.socket);
223 if (node.is_group()) {
225 group.ensure_topology_cache();
230 ie::GroupInputElem{input_socket.socket->index(), input_socket.elem},
231 compute_context_cache,
232 &group_compute_context,
239 const Object *object_filter,
250 const std::optional<ed::space_node::ObjectAndModifier> object_and_modifier =
252 if (!object_and_modifier) {
256 if (object_and_modifier->object != object_filter) {
261 if (object_and_modifier->nmd != nmd_filter) {
266 const Object &
object = *object_and_modifier->object;
275 snode, compute_context_cache);
276 if (!current_compute_context) {
280 snode.
edittree->ensure_topology_cache();
286 const bNode &node = *item.key.node;
287 const bNodeSocket &output_socket = node.output_socket(0);
292 for (
const ie::SocketElem &socket_elem : item.value) {
293 if (socket_elem.socket->owner_node().flag &
NODE_SELECT) {
294 used_gizmo_inputs.
add(socket_elem);
301 if (socket.is_inactive()) {
304 const bNode &node = socket.owner_node();
309 for (
const ie::SocketElem &socket_elem : item.value) {
310 if (socket_elem.socket->owner_node().flag &
NODE_SELECT) {
311 used_gizmo_inputs.
add(socket_elem);
317 if (gizmo_node->is_muted()) {
320 const bNodeSocket &gizmo_input_socket = gizmo_node->input_socket(0);
322 used_gizmo_inputs.
add(
323 {&gizmo_input_socket,
327 for (
const ie::SocketElem &gizmo_input : used_gizmo_inputs) {
329 compute_context_cache,
330 current_compute_context,
333 const bNode &gizmo_node,
335 fn(object, nmd, compute_context, gizmo_node, gizmo_socket);
341 const Object *object_filter,
353 for (
const bScreen *screen : screens) {
364 snode, object_filter, nmd_filter, compute_context_cache,
fn);
379 if (!
tree.runtime->gizmo_propagation) {
383 tree.ensure_interface_cache();
389 const auto get_input_value = [&](
const int group_input_i) {
390 return input_values[group_input_i];
393 *nmd.
node_group, scope, compute_context_cache, get_input_value};
395 *nmd.
node_group, scope, value_inferencer, compute_context_cache);
398 for (
auto &&item :
tree.runtime->gizmo_propagation->gizmo_inputs_by_group_inputs.items()) {
399 const ie::GroupInputElem &group_input_elem = item.key;
400 if (item.value.is_empty()) {
406 for (
const ie::SocketElem &socket_elem : item.value) {
425 compute_context_cache,
426 [&](
const Object &object_with_gizmo,
429 const bNode &gizmo_node,
434 fn(compute_context, gizmo_node, gizmo_socket);
454 Object *active_object = active_base->object;
464 compute_context_cache,
466 const bNode &gizmo_node,
468 fn(*active_object, nmd, compute_context, gizmo_node, gizmo_socket);
476 const bNode &gizmo_node,
480 ie::foreach_element_on_inverse_eval_path(
486 const bNode &gizmo_node,
491 ie::foreach_element_on_inverse_eval_path(
496 const bNode &gizmo_node,
499 std::optional<ie::ElemVariant> found_elem = ie::get_elem_variant_for_socket_type(
503 ie::foreach_element_on_inverse_eval_path(
508 if (context.hash() == gizmo_context.
hash() && &socket == &gizmo_socket) {
509 found_elem->merge(elem);
527 const bNodeTree &gizmo_node_tree = gizmo_socket.owner_tree();
531 for (
const bNodeLink *link : gizmo_socket.directly_linked_links()) {
532 gizmo_node_tree.ensure_topology_cache();
533 if (!link->is_used()) {
536 if (link->fromnode->is_dangling_reroute()) {
539 const std::optional<bke::SocketValueVariant> old_value = ie::get_logged_socket_value(
540 gizmo_tree_log, *link->fromsock);
544 const std::optional<bke::SocketValueVariant> old_value_converted =
545 ie::convert_single_socket_value(*link->fromsock, *link->tosock, *old_value);
546 if (!old_value_converted) {
550 apply_on_gizmo_value_fn(new_value);
552 sockets_to_update.
append({&gizmo_context, &gizmo_socket, link, new_value});
556 ie::backpropagate_socket_values(
C,
object, nmd, eval_log, sockets_to_update);
562 if (!
tree.runtime->gizmo_propagation) {
565 return tree.runtime->gizmo_propagation->gizmo_endpoint_sockets.contains(&node.output_socket(0));
Base * CTX_data_active_base(const bContext *C)
wmWindowManager * CTX_wm_manager(const bContext *C)
#define GEO_NODE_GIZMO_LINEAR
#define GEO_NODE_GIZMO_DIAL
#define GEO_NODE_GIZMO_TRANSFORM
General operations, lookup, etc. for blender objects.
ModifierData * BKE_object_active_modifier(const Object *ob)
bScreen * BKE_workspace_active_screen_get(const WorkSpaceInstanceHook *hook) GETTER_ATTRS
#define BLI_assert_unreachable()
#define LISTBASE_FOREACH(type, var, list)
#define UNUSED_VARS_NDEBUG(...)
#define GEO_NODE_TRANSFORM_GIZMO_USE_ROTATION_ALL
#define GEO_NODE_TRANSFORM_GIZMO_USE_TRANSLATION_ALL
#define GEO_NODE_TRANSFORM_GIZMO_USE_SCALE_ALL
#define BASE_SELECTED(v3d, base)
MapType::KeyIterator keys() const
Span< Value > lookup(const Key &key) const
MapType::ItemIterator items() const
void add(const Key &key, const Value &value)
void append(const T &value)
const ComputeContextHash & hash() const
void add_multiple(Span< Key > keys)
void append(const T &value)
const ModifierComputeContext & for_modifier(const ComputeContext *parent, const NodesModifierData &nmd)
const GroupNodeComputeContext & for_group_node(const ComputeContext *parent, int32_t node_id, const bNodeTree *tree=nullptr)
const bNodeTreeZone * get_zone_by_node(const int32_t node_id) const
GeoTreeLog & get_tree_log(const ComputeContextHash &compute_context_hash)
bool is_group_input_used(int input_i)
const ComputeContext * compute_context_for_edittree(const SpaceNode &snode, bke::ComputeContextCache &compute_context_cache)
std::optional< ObjectAndModifier > get_modifier_for_node_editor(const SpaceNode &snode)
bool update_tree_gizmo_propagation(bNodeTree &tree)
static void foreach_active_gizmo_exposed_to_modifier(const NodesModifierData &nmd, bke::ComputeContextCache &compute_context_cache, const ForeachGizmoInModifierFn fn)
static void foreach_gizmo_for_input(const ie::SocketElem &input_socket, bke::ComputeContextCache &compute_context_cache, const ComputeContext *compute_context, const bNodeTree &tree, const ForeachGizmoInModifierFn fn)
bool is_builtin_gizmo_node(const bNode &node)
ie::ElemVariant get_editable_gizmo_elem(const ComputeContext &gizmo_context, const bNode &gizmo_node, const bNodeSocket &gizmo_socket)
void foreach_socket_on_gizmo_path(const ComputeContext &gizmo_context, const bNode &gizmo_node, const bNodeSocket &gizmo_socket, FunctionRef< void(const ComputeContext &context, const bNodeSocket &socket, const ie::ElemVariant &elem)> fn)
void apply_gizmo_change(bContext &C, Object &object, NodesModifierData &nmd, geo_eval_log::GeoNodesLog &eval_log, const ComputeContext &gizmo_context, const bNodeSocket &gizmo_socket, const FunctionRef< void(bke::SocketValueVariant &value)> apply_on_gizmo_value_fn)
static ie::ElemVariant get_gizmo_socket_elem(const bNode &node, const bNodeSocket &socket)
static TreeGizmoPropagation build_tree_gizmo_propagation(bNodeTree &tree)
void foreach_active_gizmo(const bContext &C, bke::ComputeContextCache &compute_context_cache, const ForeachGizmoFn fn)
static void foreach_active_gizmo_in_open_editors(const wmWindowManager &wm, const Object *object_filter, const NodesModifierData *nmd_filter, bke::ComputeContextCache &compute_context_cache, const ForeachGizmoFn fn)
void foreach_active_gizmo_in_modifier(const Object &object, const NodesModifierData &nmd, const wmWindowManager &wm, bke::ComputeContextCache &compute_context_cache, const ForeachGizmoInModifierFn fn)
FunctionRef< void(const Object &object, const NodesModifierData &nmd, const ComputeContext &compute_context, const bNode &gizmo_node, const bNodeSocket &gizmo_socket)> ForeachGizmoFn
void foreach_compute_context_on_gizmo_path(const ComputeContext &gizmo_context, const bNode &gizmo_node, const bNodeSocket &gizmo_socket, FunctionRef< void(const ComputeContext &context)> fn)
bool value_node_has_gizmo(const bNodeTree &tree, const bNode &node)
FunctionRef< void(const ComputeContext &compute_context, const bNode &gizmo_node, const bNodeSocket &gizmo_socket)> ForeachGizmoInModifierFn
static void foreach_gizmo_for_group_input(const bNodeTree &tree, const ie::GroupInputElem &group_input, bke::ComputeContextCache &compute_context_cache, const ComputeContext *compute_context, const ForeachGizmoInModifierFn fn)
static void foreach_active_gizmo_in_open_node_editor(const SpaceNode &snode, const Object *object_filter, const NodesModifierData *nmd_filter, bke::ComputeContextCache &compute_context_cache, const ForeachGizmoFn fn)
bool is_supported_value_node(const bNode &node)
Vector< InferenceValue > get_geometry_nodes_input_inference_values(const bNodeTree &btree, const IDProperty *properties, ResourceScope &scope)
struct bNodeTree * node_group
struct NodesModifierSettings settings
struct IDProperty * properties
struct bNodeTree * edittree
struct bNodeTree * nodetree
bNodeTreeRuntimeHandle * runtime
MultiValueMap< ie::SocketElem, ie::SocketElem > gizmo_inputs_by_node_inputs
Vector< const bNode * > gizmo_nodes
MultiValueMap< ie::GroupInputElem, ie::SocketElem > gizmo_inputs_by_group_inputs
Set< const bNodeSocket * > gizmo_endpoint_sockets
MultiValueMap< ie::ValueNodeElem, ie::SocketElem > gizmo_inputs_by_value_nodes