36#include "RNA_prototypes.hh"
54namespace geo_eval_log = nodes::geo_eval_log;
59 return gizmo.interaction_data !=
nullptr;
134 const bNodeSocket &socket = this->gizmo_node.input_by_identifier(identifier);
139 r_value = *value_opt;
184 bool any_interacting =
false;
188 return any_interacting;
198 float factor_from_transform = 1.0f;
199 float current_value = 0.0f;
205 gizmo_ =
WM_gizmo_new(
"GIZMO_GT_arrow_3d", &gzgroup,
nullptr);
220 if (is_interacting) {
253 if (!
params.get_input_value(
"Position", position) ||
254 !
params.get_input_value(
"Direction", direction))
256 params.r_report.missing_socket_logs =
true;
261 params.r_report.invalid_transform =
true;
268 float4x4 gizmo_transform =
params.parent_transform * gizmo_base_transform;
278 edit_data_.current_value = 0.0f;
282 fn_params.value_set_fn =
285 const float new_gizmo_value = *
static_cast<const float *
>(value_ptr);
286 self.edit_data_.current_value = new_gizmo_value;
287 const float offset = new_gizmo_value *
self.edit_data_.factor_from_transform;
289 value_variant.
set(value_variant.
get<
float>() + offset);
292 fn_params.value_get_fn =
295 *
static_cast<float *
>(value_ptr) =
self.edit_data_.current_value;
306 bool is_negative_transform =
false;
307 float current_value = 0.0f;
313 gizmo_ =
WM_gizmo_new(
"GIZMO_GT_dial_3d", &gzgroup,
nullptr);
328 if (is_interacting) {
359 if (!
params.get_input_value(
"Position", position) || !
params.get_input_value(
"Up", up) ||
360 !
params.get_input_value(
"Screen Space", screen_space) ||
361 !
params.get_input_value(
"Radius", radius))
363 params.r_report.missing_socket_logs =
true;
369 params.r_report.invalid_transform =
true;
375 float4x4 gizmo_transform =
params.parent_transform * gizmo_base_transform;
395 edit_data_.current_value = 0.0f;
402 const float new_gizmo_value = *
static_cast<const float *
>(value_ptr);
403 self.edit_data_.current_value = new_gizmo_value;
404 float offset = new_gizmo_value;
405 if (
self.edit_data_.is_negative_transform) {
409 value_variant.
set(value_variant.
get<
float>() + offset);
414 *
static_cast<float *
>(value_ptr) =
self.edit_data_.current_value;
422 std::array<wmGizmo *, 3> translation_gizmos_ = {};
423 std::array<wmGizmo *, 3> rotation_gizmos_ = {};
424 std::array<wmGizmo *, 3> scale_gizmos_ = {};
426 bool any_translation_visible_ =
false;
427 bool any_rotation_visible_ =
false;
428 bool any_scale_visible_ =
false;
439 float3 current_translation;
449 translation_gizmos_[axis] =
WM_gizmo_new(
"GIZMO_GT_arrow_3d", &gzgroup,
nullptr);
454 rotation_gizmos_[axis] =
WM_gizmo_new(
"GIZMO_GT_dial_3d", &gzgroup,
nullptr);
459 scale_gizmos_[axis] =
WM_gizmo_new(
"GIZMO_GT_arrow_3d", &gzgroup,
nullptr);
466 gizmos.
extend(translation_gizmos_);
467 gizmos.
extend(rotation_gizmos_);
468 gizmos.
extend(scale_gizmos_);
475 params.gizmo_node.storage);
484 if (!
params.get_input_value(
"Position", position) ||
485 !
params.get_input_value(
"Rotation", rotation))
487 params.r_report.missing_socket_logs =
true;
492 base_transform_from_socket.
location() = position;
496 transform_orientation_ = orientation_slot.
type;
498 parent_transform_ =
params.parent_transform;
507 any_translation_visible_ =
false;
508 any_rotation_visible_ =
false;
509 any_scale_visible_ =
false;
511 const auto &elem = std::get<nodes::inverse_eval::MatrixElem>(
params.elem.elem);
514 const bool translation_used = (storage.
flag &
517 const bool rotation_used = (storage.
flag &
527 any_translation_visible_ |= translation_used;
528 any_rotation_visible_ |= rotation_used;
529 any_scale_visible_ |= scale_used;
536 wmGizmo *gizmo = translation_gizmos_[axis];
542 if (any_rotation_visible_) {
546 else if (any_scale_visible_) {
552 gizmo->matrix_offset[3][2] = start;
561 wmGizmo *gizmo = rotation_gizmos_[axis];
565 int draw_options =
RNA_enum_get(gizmo->ptr,
"draw_options");
581 wmGizmo *gizmo = scale_gizmos_[axis];
585 const float length = (any_translation_visible_ || any_rotation_visible_) ? 0.775f : 1.0f;
593 const float4x4 &base_transform_from_socket)
597 wmGizmo *gizmo = translation_gizmos_[axis_i];
603 axis, base_transform_from_socket,
params);
606 edit_data_.current_translation[axis_i] = 0.0f;
612 const void *value_ptr) {
615 const float new_gizmo_value = *
static_cast<const float *
>(value_ptr);
616 self.edit_data_.current_translation[axis_i] = new_gizmo_value;
618 translation[axis_i] = new_gizmo_value;
628 1.0f,
math::length((
self.parent_transform_.view<3, 3>() * orientation)[axis_i]));
631 value.location() += offset;
632 value_variant.
set(value);
638 *
static_cast<float *
>(value_ptr) =
self.edit_data_.current_translation[axis_i];
645 const float4x4 &base_transform_from_socket)
649 wmGizmo *gizmo = rotation_gizmos_[axis_i];
655 axis, base_transform_from_socket,
params);
658 edit_data_.current_rotation[axis_i] = 0.0f;
664 const void *value_ptr) {
668 const float new_gizmo_value = *
static_cast<const float *
>(value_ptr);
669 self.edit_data_.current_rotation[axis_i] = new_gizmo_value;
672 float3 local_rotation_axis;
683 value.view<3, 3>() = rotation_matrix * value.
view<3, 3>();
684 value_variant.
set(value);
690 *
static_cast<float *
>(value_ptr) =
self.edit_data_.current_rotation[axis_i];
697 const float4x4 &base_transform_from_socket)
701 wmGizmo *gizmo = scale_gizmos_[axis_i];
707 axis, base_transform_from_socket,
params);
710 edit_data_.current_scale[axis_i] = 0.0f;
716 const void *value_ptr) {
720 const float new_gizmo_value = *
static_cast<const float *
>(value_ptr);
721 self.edit_data_.current_scale[axis_i] = new_gizmo_value;
722 float3 scale{1.0f, 1.0f, 1.0f};
723 scale[axis_i] += new_gizmo_value;
738 value.
view<3, 3>() = scale_matrix * value.
view<3, 3>();
739 value_variant.
set(value);
745 *
static_cast<float *
>(value_ptr) =
self.edit_data_.current_scale[axis_i];
752 const float4x4 &base_transform_from_socket,
756 const float3 global_location =
757 (
params.parent_transform * base_transform_from_socket).location();
759 float3 global_direction{};
761 global_direction = axis_direction;
765 base_transform_from_socket.
view<3, 3>(),
769 gizmo_transform.
location() = global_location;
795 switch (gizmo_node.
type) {
797 return std::make_unique<LinearGizmo>();
799 return std::make_unique<DialGizmo>();
801 return std::make_unique<TransformGizmos>();
811 if (edit_data_component->gizmo_edit_hints_) {
812 if (
const float4x4 *m = edit_data_component->gizmo_edit_hints_->gizmo_transforms.lookup_ptr(
831 if (!geometry.has_instances()) {
851 return transform * *m;
853 if (!geometry.has_instances()) {
858 const Span<int> handles = instances->reference_handles();
860 for (
const int reference_i : references.
index_range()) {
867 const int index = handles.first_index_try(reference_i);
869 const float4x4 sub_transform = transform * transforms[index];
871 reference_geometry, gizmo_id, sub_transform))
892 nmd_orig.
runtime->eval_log->find_viewer_node_log_for_path(viewer_path))
894 return viewer_log->geometry;
913 View3D *v3d =
static_cast<View3D *
>(area->spacedata.first);
926 MEM_delete(gzgroup_data);
951 auto compute_context_builder = std::make_shared<ComputeContextBuilder>();
952 compute_context_builder->keep_old_contexts();
956 *compute_context_builder,
957 [&](
const Object &object_orig,
960 const bNode &gizmo_node,
964 if (new_gizmos_by_node.
contains(gizmo_id)) {
968 if (!nmd_orig.
runtime->eval_log) {
973 const_cast<Object *
>(&object_orig));
982 compute_context, gizmo_node, gizmo_socket);
985 ntree.ensure_topology_cache();
988 if (std::optional<std::unique_ptr<NodeGizmos>> old_gizmos =
989 gzgroup_data.gizmos_by_node.pop_try(gizmo_id))
992 node_gizmos = old_gizmos->get();
993 new_gizmos_by_node.
add(gizmo_id, std::move(*old_gizmos));
998 new_node_gizmos->create_gizmos(*gzgroup);
1000 for (
wmGizmo *gizmo : new_node_gizmos->get_all_gizmos()) {
1003 node_gizmos = new_node_gizmos.get();
1004 new_gizmos_by_node.
add(gizmo_id, std::move(new_node_gizmos));
1014 const std::optional<float4x4> crazy_space_geometry_transform =
1019 if (missing_logged_data) {
1027 const bool missing_used_transform = gizmo_node.output_socket(0).is_logically_linked() &&
1028 !crazy_space_geometry_transform.has_value();
1029 if (missing_used_transform) {
1034 const float4x4 object_to_world{object_eval->object_to_world()};
1035 const float4x4 geometry_transform = crazy_space_geometry_transform.value_or(
1040 *
C, object_to_world * geometry_transform, gizmo_node, tree_log, report, elem};
1041 node_gizmos->
update(update_params);
1045 if (!any_interacting) {
1054 compute_context_builder,
1055 compute_context = &compute_context,
1056 gizmo_node_tree = &gizmo_node.owner_tree(),
1057 gizmo_node = &gizmo_node,
1058 object_orig = &object_orig,
1060 eval_log = nmd_orig.
runtime->eval_log](
1063 gizmo_node_tree->ensure_topology_cache();
1064 const bNodeSocket &socket = gizmo_node->input_by_identifier(socket_identifier);
1067 const_cast<Object &
>(*object_orig),
1082 bool any_gizmo_interactive =
false;
1083 for (
const std::unique_ptr<NodeGizmos> &node_gizmos : new_gizmos_by_node.
values()) {
1084 any_gizmo_interactive |= node_gizmos->is_any_interacting();
1086 if (any_gizmo_interactive) {
1087 for (std::unique_ptr<NodeGizmos> &node_gizmos : new_gizmos_by_node.
values()) {
1088 for (
wmGizmo *gizmo : node_gizmos->get_all_gizmos()) {
1097 for (std::unique_ptr<NodeGizmos> &node_gizmos : gzgroup_data.gizmos_by_node.values()) {
1099 for (
wmGizmo *gizmo : gizmos) {
1104 gzgroup_data.gizmos_by_node = std::move(new_gizmos_by_node);
1118 gzgt->
name =
"Geometry Nodes Widgets";
1119 gzgt->
idname =
"VIEW3D_GGT_geometry_nodes";
1123 gzgt->
poll = WIDGETGROUP_geometry_nodes_poll;
1124 gzgt->
setup = WIDGETGROUP_geometry_nodes_setup;
1126 gzgt->
refresh = WIDGETGROUP_geometry_nodes_refresh;
1127 gzgt->
draw_prepare = WIDGETGROUP_geometry_nodes_draw_prepare;
ScrArea * CTX_wm_area(const bContext *C)
Depsgraph * CTX_data_depsgraph_pointer(const bContext *C)
Scene * CTX_data_scene(const bContext *C)
Main * CTX_data_main(const bContext *C)
wmWindowManager * CTX_wm_manager(const bContext *C)
View3D * CTX_wm_view3d(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.
MINLINE float safe_divide(float a, float b)
void unit_m4(float m[4][4])
void copy_m4_m4(float m1[4][4], const float m2[4][4])
void rotation_between_vecs_to_quat(float q[4], const float v1[3], const float v2[3])
#define BLI_STRUCT_EQUALITY_OPERATORS_2(Type, m1, m2)
#define SET_FLAG_FROM_TEST(value, test, flag)
void DEG_id_tag_update_for_side_effect_request(Depsgraph *depsgraph, ID *id, unsigned int flags)
Object * DEG_get_evaluated_object(const Depsgraph *depsgraph, Object *object)
@ GEO_NODE_GIZMO_COLOR_PRIMARY
@ GEO_NODE_GIZMO_COLOR_SECONDARY
@ GEO_NODE_LINEAR_GIZMO_DRAW_STYLE_CROSS
@ GEO_NODE_LINEAR_GIZMO_DRAW_STYLE_BOX
@ GEO_NODE_LINEAR_GIZMO_DRAW_STYLE_ARROW
@ GEO_NODE_TRANSFORM_GIZMO_USE_ROTATION_X
@ GEO_NODE_TRANSFORM_GIZMO_USE_SCALE_X
@ GEO_NODE_TRANSFORM_GIZMO_USE_TRANSLATION_X
@ V3D_GIZMO_HIDE_MODIFIER
@ ED_GIZMO_ARROW_STYLE_CROSS
@ ED_GIZMO_ARROW_STYLE_BOX
@ ED_GIZMO_ARROW_STYLE_NORMAL
@ ED_GIZMO_DIAL_DRAW_FLAG_ANGLE_VALUE
@ ED_GIZMO_DIAL_DRAW_FLAG_CLIP
void ED_node_tree_propagate_change(const bContext *C, Main *bmain, bNodeTree *ntree)
void UI_GetThemeColor3fv(int colorid, float col[3])
@ WM_GIZMO_DRAW_OFFSET_SCALE
@ WM_GIZMOGROUPTYPE_PERSISTENT
const ComputeContextHash & hash() const
bool add(const Key &key, const Value &value)
ValueIterator values() const
bool contains(const Key &key) const
bool contains(const Key &key) const
constexpr int64_t first_index(const T &search_value) const
constexpr IndexRange index_range() const
void extend(Span< T > array)
void update_style(const NodeGeometryDialGizmo &storage, const bool is_interacting)
bool update_transform(GizmosUpdateParams ¶ms)
Vector< wmGizmo * > get_all_gizmos() override
void create_gizmos(wmGizmoGroup &gzgroup) override
void update_target_property()
void update(GizmosUpdateParams ¶ms) override
void create_gizmos(wmGizmoGroup &gzgroup) override
Vector< wmGizmo * > get_all_gizmos() override
bool update_transform(GizmosUpdateParams ¶ms)
void update_target_property()
void update_style(const NodeGeometryLinearGizmo &storage)
void update(GizmosUpdateParams ¶ms) override
bool is_any_interacting()
virtual ~NodeGizmos()=default
ApplyChangeFn apply_change
virtual void create_gizmos(wmGizmoGroup &gzgroup)=0
virtual void update(GizmosUpdateParams &)
virtual Vector< wmGizmo * > get_all_gizmos()=0
static constexpr Value Z_POS
static constexpr Value Z_NEG
static constexpr Axis from_int(const int axis_int)
void ensure_evaluated_gizmo_nodes()
Set< int > evaluated_gizmo_nodes
void ensure_socket_values()
std::optional< T > find_primitive_socket_value(const bNodeSocket &query_socket)
const Depsgraph * depsgraph
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
GeometrySet object_get_evaluated_geometry_set(const Object &object)
std::function< void( StringRef socket_identifier, FunctionRef< void(bke::SocketValueVariant &value)> modify_value)> ApplyChangeFn
static ThemeColorID get_axis_theme_color_id(const int axis)
static float4x4 matrix_from_position_and_up_direction(const float3 &position, const float3 &direction, const math::AxisSigned direction_axis)
static void WIDGETGROUP_geometry_nodes_refresh(const bContext *C, wmGizmoGroup *gzgroup)
static const float4x4 * find_direct_gizmo_transform(const bke::GeometrySet &geometry, const bke::NodeGizmoID &gizmo_id)
static void WIDGETGROUP_geometry_nodes_setup(const bContext *, wmGizmoGroup *gzgroup)
static std::optional< float4x4 > find_gizmo_geometry_transform(const bke::GeometrySet &geometry, const bke::NodeGizmoID &gizmo_id)
static std::unique_ptr< NodeGizmos > create_gizmo_node_gizmos(const bNode &gizmo_node)
static void WIDGETGROUP_geometry_nodes_draw_prepare(const bContext *, wmGizmoGroup *)
static bool WIDGETGROUP_geometry_nodes_poll(const bContext *C, wmGizmoGroupType *)
static void make_matrix_orthonormal_but_keep_z_axis(float4x4 &m)
static ThemeColorID get_gizmo_theme_color_id(const GeometryNodeGizmoColor color_id)
static bool gizmo_is_interacting(const wmGizmo &gizmo)
static bool has_nested_gizmo_transform(const bke::GeometrySet &geometry, const bke::NodeGizmoID &gizmo_id)
static void get_axis_gizmo_colors(const int axis, float *r_color, float *r_color_hi)
static bke::GeometrySet find_geometry_for_gizmo(const Object &object_eval, const NodesModifierData &nmd_orig, const View3D &v3d)
static std::optional< float4x4 > find_gizmo_geometry_transform_recursive(const bke::GeometrySet &geometry, const bke::NodeGizmoID &gizmo_id, const float4x4 &transform)
bool is_orthonormal(const MatT &mat)
T to_vector(const Axis axis)
T length(const VecBase< T, Size > &a)
bool is_unit_scale(const MatBase< T, NumCol, NumRow > &m)
T average(const VecBase< T, Size > &a)
CartesianBasis invert(const CartesianBasis &basis)
AxisSigned cross(const AxisSigned a, const AxisSigned b)
MatT from_scale(const VecBase< typename MatT::base_type, ScaleDim > &scale)
MatBase< T, NumCol, NumRow > normalize(const MatBase< T, NumCol, NumRow > &a)
VecBase< T, 3 > to_scale(const MatBase< T, NumCol, NumRow > &mat)
VecBase< T, 3 > transform_direction(const MatBase< T, 3, 3 > &mat, const VecBase< T, 3 > &direction)
MatT from_rotation(const RotationT &rotation)
T determinant(const MatBase< T, Size, Size > &mat)
void foreach_active_gizmo(const bContext &C, ComputeContextBuilder &compute_context_builder, const ForeachGizmoFn 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)
ie::ElemVariant get_editable_gizmo_elem(const ComputeContext &gizmo_context, const bNode &gizmo_node, const bNodeSocket &gizmo_socket)
MatBase< float, 3, 3 > float3x3
uint64_t get_default_hash(const T &v)
VecBase< float, 3 > float3
void RNA_boolean_set(PointerRNA *ptr, const char *name, bool value)
void RNA_float_set(PointerRNA *ptr, const char *name, float value)
void RNA_enum_set(PointerRNA *ptr, const char *name, int value)
int RNA_enum_get(PointerRNA *ptr, const char *name)
unsigned __int64 uint64_t
struct bNodeTree * node_group
NodesModifierRuntimeHandle * runtime
const c_style_mat & ptr() const
const MatView< T, ViewNumCol, ViewNumRow, NumCol, NumRow, SrcStartCol, SrcStartRow, Alignment > view() const
static MatBase identity()
bke::NodeGizmoID gizmo_id
const Object * object_orig
Map< GeoNodesObjectGizmoID, std::unique_ptr< NodeGizmos > > gizmos_by_node
bool get_input_value(const StringRef identifier, T &r_value)
nodes::inverse_eval::ElemVariant elem
float4x4 parent_transform
wmGizmoGroupFnSetupKeymap setup_keymap
wmGizmoGroupFnRefresh refresh
eWM_GizmoFlagGroupTypeFlag flag
wmGizmoGroupFnDrawPrepare draw_prepare
wmGizmoMap * parent_gzmap
void(* customdata_free)(void *)
float matrix_offset[4][4]
void VIEW3D_GGT_geometry_nodes(wmGizmoGroupType *gzgt)
void WM_main_add_notifier(uint type, void *reference)
void WM_gizmo_set_line_width(wmGizmo *gz, const float line_width)
wmGizmo * WM_gizmo_new(const char *idname, wmGizmoGroup *gzgroup, PointerRNA *properties)
void WM_gizmo_set_flag(wmGizmo *gz, const int flag, const bool enable)
void WM_gizmo_unlink(ListBase *gizmolist, wmGizmoMap *gzmap, wmGizmo *gz, bContext *C)
wmKeyMap * WM_gizmogroup_setup_keymap_generic_maybe_drag(const wmGizmoGroupType *, wmKeyConfig *kc)
void WM_gizmo_target_property_def_func(wmGizmo *gz, const char *idname, const wmGizmoPropertyFnParams *params)