diff --git a/scripts/startup/bl_ui/node_add_menu_geometry.py b/scripts/startup/bl_ui/node_add_menu_geometry.py index bd275f29c9c..9c239c671fc 100644 --- a/scripts/startup/bl_ui/node_add_menu_geometry.py +++ b/scripts/startup/bl_ui/node_add_menu_geometry.py @@ -295,6 +295,8 @@ class NODE_MT_geometry_node_GEO_INPUT_SCENE(Menu): node_add_menu.add_node_type(layout, "GeometryNodeObjectInfo") node_add_menu.add_node_type(layout, "GeometryNodeInputSceneTime") node_add_menu.add_node_type(layout, "GeometryNodeSelfObject") + if context.space_data.geometry_nodes_type == 'TOOL': + node_add_menu.add_node_type(layout, "GeometryNodeViewportTransform") node_add_menu.draw_assets_for_catalog(layout, "Input/Scene") diff --git a/source/blender/blenkernel/BKE_node.hh b/source/blender/blenkernel/BKE_node.hh index da8bf5f785e..8d47f0aef75 100644 --- a/source/blender/blenkernel/BKE_node.hh +++ b/source/blender/blenkernel/BKE_node.hh @@ -1278,6 +1278,7 @@ void BKE_nodetree_remove_layer_n(bNodeTree *ntree, Scene *scene, int layer_index #define GEO_NODE_GRID_TO_MESH 2129 #define GEO_NODE_DISTRIBUTE_POINTS_IN_GRID 2130 #define GEO_NODE_SDF_GRID_BOOLEAN 2131 +#define GEO_NODE_TOOL_VIEWPORT_TRANSFORM 2132 /** \} */ diff --git a/source/blender/editors/geometry/node_group_operator.cc b/source/blender/editors/geometry/node_group_operator.cc index 55459df30ab..df96316fa34 100644 --- a/source/blender/editors/geometry/node_group_operator.cc +++ b/source/blender/editors/geometry/node_group_operator.cc @@ -394,6 +394,7 @@ static int run_node_group_exec(bContext *C, wmOperator *op) Main *bmain = CTX_data_main(C); Scene *scene = CTX_data_scene(C); Object *active_object = CTX_data_active_object(C); + const RegionView3D *rv3d = CTX_wm_region_view3d(C); if (!active_object) { return OPERATOR_CANCELLED; } @@ -470,6 +471,7 @@ static int run_node_group_exec(bContext *C, wmOperator *op) operator_eval_data.depsgraphs = &depsgraphs; operator_eval_data.self_object_orig = object; operator_eval_data.scene_orig = scene; + operator_eval_data.rv3d = rv3d; nodes::GeoNodesCallData call_data{}; call_data.operator_data = &operator_eval_data; diff --git a/source/blender/nodes/NOD_geometry_nodes_lazy_function.hh b/source/blender/nodes/NOD_geometry_nodes_lazy_function.hh index 6ae679f2f39..a8ededf4f24 100644 --- a/source/blender/nodes/NOD_geometry_nodes_lazy_function.hh +++ b/source/blender/nodes/NOD_geometry_nodes_lazy_function.hh @@ -190,6 +190,7 @@ struct GeoNodesOperatorData { const Object *self_object_orig = nullptr; const GeoNodesOperatorDepsgraphs *depsgraphs = nullptr; Scene *scene_orig = nullptr; + const RegionView3D *rv3d = nullptr; }; struct GeoNodesCallData { diff --git a/source/blender/nodes/NOD_static_types.h b/source/blender/nodes/NOD_static_types.h index 9613abd3f99..cfac59ac9ff 100644 --- a/source/blender/nodes/NOD_static_types.h +++ b/source/blender/nodes/NOD_static_types.h @@ -469,6 +469,7 @@ DefNode(GeometryNode, GEO_NODE_TOOL_FACE_SET, 0, "TOOL_FACE_SET", ToolFaceSet, " DefNode(GeometryNode, GEO_NODE_TOOL_SELECTION, 0, "TOOL_SELECTION", ToolSelection, "Selection", "User selection of the edited geometry, for tool execution") DefNode(GeometryNode, GEO_NODE_TOOL_SET_FACE_SET, 0, "TOOL_SET_FACE_SET", ToolSetFaceSet, "Set Face Set", "Set sculpt face set values for faces") DefNode(GeometryNode, GEO_NODE_TOOL_SET_SELECTION, 0, "TOOL_SELECTION_SET", ToolSetSelection, "Set Selection", "Set selection of the edited geometry, for tool execution") +DefNode(GeometryNode, GEO_NODE_TOOL_VIEWPORT_TRANSFORM, 0, "VIEWPORT_TRANFORM", ViewportTransform, "Viewport Transform", "Retrieve the view direction and location of the 3D viewport") DefNode(GeometryNode, GEO_NODE_TRANSFORM_GEOMETRY, 0, "TRANSFORM_GEOMETRY", Transform, "Transform Geometry", "Translate, rotate or scale the geometry") DefNode(GeometryNode, GEO_NODE_TRANSLATE_INSTANCES, 0, "TRANSLATE_INSTANCES",TranslateInstances, "Translate Instances", "Move top-level geometry instances in local or global space") DefNode(GeometryNode, GEO_NODE_TRIANGULATE, 0, "TRIANGULATE", Triangulate, "Triangulate", "Convert all faces in a mesh to triangular faces") diff --git a/source/blender/nodes/geometry/CMakeLists.txt b/source/blender/nodes/geometry/CMakeLists.txt index e1a22540349..c0928d668ef 100644 --- a/source/blender/nodes/geometry/CMakeLists.txt +++ b/source/blender/nodes/geometry/CMakeLists.txt @@ -205,6 +205,7 @@ set(SRC nodes/node_geo_uv_pack_islands.cc nodes/node_geo_uv_unwrap.cc nodes/node_geo_viewer.cc + nodes/node_geo_viewport_transform.cc nodes/node_geo_volume_cube.cc nodes/node_geo_volume_to_mesh.cc diff --git a/source/blender/nodes/geometry/nodes/node_geo_viewport_transform.cc b/source/blender/nodes/geometry/nodes/node_geo_viewport_transform.cc new file mode 100644 index 00000000000..5528b527b46 --- /dev/null +++ b/source/blender/nodes/geometry/nodes/node_geo_viewport_transform.cc @@ -0,0 +1,51 @@ +/* SPDX-FileCopyrightText: 2024 Blender Authors + * + * SPDX-License-Identifier: GPL-2.0-or-later */ + +#include "DNA_view3d_types.h" + +#include "BLI_math_matrix.hh" + +#include "node_geometry_util.hh" + +namespace blender::nodes::node_geo_viewport_transform_cc { + +static void node_declare(NodeDeclarationBuilder &b) +{ + b.add_output("Projection") + .description("The 3D viewport's perspective or orthographic projection matrix"); + b.add_output("View").description( + "The view direction and location of the 3D viewport"); + b.add_output("Is Orthographic") + .description("Whether the viewport is using orthographic projection"); +} + +static void node_geo_exec(GeoNodeExecParams params) +{ + if (!check_tool_context_and_error(params)) { + return; + } + const Object &self_object = *params.self_object(); + const RegionView3D *rv3d = params.user_data()->call_data->operator_data->rv3d; + if (!rv3d) { + params.set_default_remaining_outputs(); + return; + } + params.set_output("Projection", float4x4(rv3d->winmat) * self_object.object_to_world()); + params.set_output("View", float4x4(rv3d->viewmat) * self_object.object_to_world()); + params.set_output("Is Orthographic", !bool(rv3d->is_persp)); +} + +static void node_register() +{ + static bNodeType ntype; + geo_node_type_base( + &ntype, GEO_NODE_TOOL_VIEWPORT_TRANSFORM, "Viewport Transform", NODE_CLASS_INPUT); + ntype.declare = node_declare; + ntype.geometry_node_execute = node_geo_exec; + ntype.gather_link_search_ops = search_link_ops_for_tool_node; + nodeRegisterType(&ntype); +} +NOD_REGISTER_NODE(node_register) + +} // namespace blender::nodes::node_geo_viewport_transform_cc