41 return {ie::FloatElem::all()};
44 return {ie::FloatElem::all()};
50 elem.translation = ie::VectorElem::all();
55 elem.rotation = ie::RotationElem::all();
56 elem.scale = ie::VectorElem::all();
62 if (std::optional<ie::ElemVariant> elem = ie::get_elem_variant_for_socket_type(socket_type)) {
85 for (
const bNode *node :
tree.all_nodes()) {
86 if (node->is_muted()) {
89 if (node->is_group()) {
94 if (!group.
runtime->gizmo_propagation) {
98 for (
const ie::GroupInputElem &group_input_elem :
101 const bNodeSocket &input_socket = node->input_socket(group_input_elem.group_input_index);
102 all_gizmo_inputs.
append({&input_socket, &input_socket, group_input_elem.elem});
107 const bNodeSocket &gizmo_input_socket = node->input_socket(0);
110 for (
const bNodeLink *link : gizmo_input_socket.directly_linked_links()) {
111 if (!link->is_used()) {
114 all_gizmo_inputs.
append({&gizmo_input_socket, link->fromsock, elem});
120 for (
const GizmoInput &gizmo_input : all_gizmo_inputs) {
122 const ie::SocketElem gizmo_input_socket_elem{gizmo_input.gizmo_socket, gizmo_input.elem};
125 const std::optional<ie::ElemVariant> converted_elem = ie::convert_socket_elem(
126 *gizmo_input.gizmo_socket, *gizmo_input.propagation_start_socket, gizmo_input.elem);
127 if (!converted_elem) {
130 const ie::LocalInverseEvalTargets targets = ie::find_local_inverse_eval_targets(
131 tree, {gizmo_input.propagation_start_socket, *converted_elem});
132 const bool has_target = !targets.input_sockets.is_empty() ||
133 !targets.group_inputs.is_empty() || !targets.value_nodes.is_empty();
138 for (
const ie::SocketElem &input_socket : targets.input_sockets) {
142 for (
const ie::ValueNodeElem &value_node : targets.value_nodes) {
146 for (
const ie::GroupInputElem &group_input : targets.group_inputs) {
148 for (
const bNode *group_input_node :
tree.group_input_nodes()) {
150 &group_input_node->output_socket(group_input.group_input_index));
155 return gizmo_propagation;
160 tree.ensure_topology_cache();
162 if (
tree.has_available_link_cycle()) {
163 const bool changed =
tree.runtime->gizmo_propagation.get() !=
nullptr;
164 tree.runtime->gizmo_propagation.reset();
169 const bool changed =
tree.runtime->gizmo_propagation ?
170 *
tree.runtime->gizmo_propagation != new_gizmo_propagation :
172 tree.runtime->gizmo_propagation = std::make_unique<TreeGizmoPropagation>(
173 std::move(new_gizmo_propagation));
183 const ie::GroupInputElem &group_input,
188 for (
const ie::SocketElem &gizmo_input :
205 const bNode &node = input_socket.socket->owner_node();
211 if (node.is_muted()) {
215 fn(*compute_context_builder.
current(), node, *input_socket.socket);
218 if (node.is_group()) {
220 group.ensure_topology_cache();
224 ie::GroupInputElem{input_socket.socket->index(), input_socket.elem},
225 compute_context_builder,
227 compute_context_builder.
pop();
233 const Object *object_filter,
244 const std::optional<ed::space_node::ObjectAndModifier> object_and_modifier =
246 if (!object_and_modifier) {
250 if (object_and_modifier->object != object_filter) {
255 if (object_and_modifier->nmd != nmd_filter) {
260 const Object &
object = *object_and_modifier->object;
275 snode.
edittree->ensure_topology_cache();
281 const bNode &node = *item.key.node;
282 const bNodeSocket &output_socket = node.output_socket(0);
287 for (
const ie::SocketElem &socket_elem : item.value) {
288 if (socket_elem.socket->owner_node().flag &
NODE_SELECT) {
289 used_gizmo_inputs.
add(socket_elem);
296 const bNode &node = socket.owner_node();
301 for (
const ie::SocketElem &socket_elem : item.value) {
302 if (socket_elem.socket->owner_node().flag &
NODE_SELECT) {
303 used_gizmo_inputs.
add(socket_elem);
309 if (gizmo_node->is_muted()) {
312 const bNodeSocket &gizmo_input_socket = gizmo_node->input_socket(0);
314 used_gizmo_inputs.
add(
315 {&gizmo_input_socket,
319 for (
const ie::SocketElem &gizmo_input : used_gizmo_inputs) {
321 compute_context_builder,
324 const bNode &gizmo_node,
326 fn(object, nmd, compute_context, gizmo_node, gizmo_socket);
332 const Object *object_filter,
344 for (
const bScreen *screen : screens) {
355 snode, object_filter, nmd_filter, compute_context_builder,
fn);
370 if (!
tree.runtime->gizmo_propagation) {
376 for (
auto &&item :
tree.runtime->gizmo_propagation->gizmo_inputs_by_group_inputs.items()) {
377 for (
const ie::SocketElem &socket_elem : item.value) {
396 compute_context_builder,
397 [&](
const Object &object_with_gizmo,
400 const bNode &gizmo_node,
405 fn(compute_context, gizmo_node, gizmo_socket);
425 Object *active_object = active_base->object;
435 compute_context_builder,
437 const bNode &gizmo_node,
439 fn(*active_object, nmd, compute_context, gizmo_node, gizmo_socket);
447 const bNode &gizmo_node,
451 ie::foreach_element_on_inverse_eval_path(
457 const bNode &gizmo_node,
462 ie::foreach_element_on_inverse_eval_path(
467 const bNode &gizmo_node,
470 std::optional<ie::ElemVariant> found_elem = ie::get_elem_variant_for_socket_type(
474 ie::foreach_element_on_inverse_eval_path(
479 if (context.hash() == gizmo_context.
hash() && &socket == &gizmo_socket) {
480 found_elem->merge(elem);
498 const bNodeTree &gizmo_node_tree = gizmo_socket.owner_tree();
502 for (
const bNodeLink *link : gizmo_socket.directly_linked_links()) {
503 gizmo_node_tree.ensure_topology_cache();
504 if (!link->is_used()) {
507 if (link->fromnode->is_dangling_reroute()) {
510 const std::optional<bke::SocketValueVariant> old_value = ie::get_logged_socket_value(
511 gizmo_tree_log, *link->fromsock);
515 const std::optional<bke::SocketValueVariant> old_value_converted =
516 ie::convert_single_socket_value(*link->fromsock, *link->tosock, *old_value);
517 if (!old_value_converted) {
521 apply_on_gizmo_value_fn(new_value);
523 sockets_to_update.
append({&gizmo_context, &gizmo_socket, link, new_value});
527 ie::backpropagate_socket_values(
C,
object, nmd, eval_log, sockets_to_update);
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 BLI_SCOPED_DEFER(function_to_defer)
#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)
void pop_until(const ComputeContext *context)
const ComputeContext * current() const
void push(Args &&...args)
const ComputeContextHash & hash() const
void add_multiple(Span< Key > keys)
void append(const T &value)
const bNodeTreeZone * get_zone_by_node(const int32_t node_id) const
GeoTreeLog & get_tree_log(const ComputeContextHash &compute_context_hash)
bool push_compute_context_for_tree_path(const SpaceNode &snode, ComputeContextBuilder &compute_context_builder)
std::optional< ObjectAndModifier > get_modifier_for_node_editor(const SpaceNode &snode)
static void foreach_active_gizmo_in_open_editors(const wmWindowManager &wm, const Object *object_filter, const NodesModifierData *nmd_filter, ComputeContextBuilder &compute_context_builder, const ForeachGizmoFn fn)
void foreach_active_gizmo(const bContext &C, ComputeContextBuilder &compute_context_builder, const ForeachGizmoFn fn)
static void foreach_active_gizmo_exposed_to_modifier(const NodesModifierData &nmd, ComputeContextBuilder &compute_context_builder, const ForeachGizmoInModifierFn fn)
void apply_gizmo_change(bContext &C, Object &object, NodesModifierData &nmd, geo_eval_log::GeoModifierLog &eval_log, const ComputeContext &gizmo_context, const bNodeSocket &gizmo_socket, const FunctionRef< void(bke::SocketValueVariant &value)> apply_on_gizmo_value_fn)
bool update_tree_gizmo_propagation(bNodeTree &tree)
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)
static ie::ElemVariant get_gizmo_socket_elem(const bNode &node, const bNodeSocket &socket)
static TreeGizmoPropagation build_tree_gizmo_propagation(bNodeTree &tree)
static void foreach_gizmo_for_group_input(const bNodeTree &tree, const ie::GroupInputElem &group_input, ComputeContextBuilder &compute_context_builder, 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_active_gizmo_in_modifier(const Object &object, const NodesModifierData &nmd, const wmWindowManager &wm, ComputeContextBuilder &compute_context_builder, const ForeachGizmoInModifierFn fn)
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)
FunctionRef< void(const ComputeContext &compute_context, const bNode &gizmo_node, const bNodeSocket &gizmo_socket)> ForeachGizmoInModifierFn
static void foreach_active_gizmo_in_open_node_editor(const SpaceNode &snode, const Object *object_filter, const NodesModifierData *nmd_filter, ComputeContextBuilder &compute_context_builder, const ForeachGizmoFn fn)
static void foreach_gizmo_for_input(const ie::SocketElem &input_socket, ComputeContextBuilder &compute_context_builder, const bNodeTree &tree, const ForeachGizmoInModifierFn fn)
struct bNodeTree * node_group
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