Add Active Camera geometry node #106065

Closed
dbsc wants to merge 15 commits from dbsc/blender:active_camera_geo_node into main

When changing the target branch, be careful to rebase the branch in your fork to match. See documentation.
11 changed files with 62 additions and 3 deletions

View File

@ -276,6 +276,7 @@ class NODE_MT_geometry_node_GEO_INPUT_SCENE(Menu):
def draw(self, _context):
layout = self.layout
node_add_menu.add_node_type(layout, "GeometryNodeActiveCamera")
node_add_menu.add_node_type(layout, "GeometryNodeCollectionInfo")
node_add_menu.add_node_type(layout, "GeometryNodeImageInfo")
dbsc marked this conversation as resolved Outdated

This needs alphabetical sorting within this category

This needs alphabetical sorting within this category
Outdated
Review

Unless I'm mistaken the other nodes are not in alphabetical order. Should they be ordered as well?

Unless I'm mistaken the other nodes are not in alphabetical order. Should they be ordered as well?
node_add_menu.add_node_type(layout, "GeometryNodeIsViewport")

View File

@ -1364,6 +1364,7 @@ void BKE_nodetree_remove_layer_n(struct bNodeTree *ntree, struct Scene *scene, i
* the repeat zone. */
#define GEO_NODE_REPEAT_INPUT 2107
#define GEO_NODE_REPEAT_OUTPUT 2108
#define GEO_NODE_ACTIVE_CAMERA 2109
/** \} */

View File

@ -2483,7 +2483,7 @@ bNode *nodeAddNode(const bContext *C, bNodeTree *ntree, const char *idname)
BKE_ntree_update_tag_node_new(ntree, node);
if (ELEM(node->type, GEO_NODE_INPUT_SCENE_TIME, GEO_NODE_SELF_OBJECT, GEO_NODE_SIMULATION_INPUT))
if (ELEM(node->type, GEO_NODE_INPUT_SCENE_TIME, GEO_NODE_SELF_OBJECT, GEO_NODE_SIMULATION_INPUT, GEO_NODE_ACTIVE_CAMERA))
{
DEG_relations_tag_update(CTX_data_main(C));
}

View File

@ -1815,6 +1815,8 @@ void ED_update_for_newframe(Main *bmain, Depsgraph *depsgraph)
BKE_screen_view3d_scene_sync(screen, scene);
}
DEG_id_tag_update(&scene->id, ID_RECALC_COPY_ON_WRITE);
DEG_id_tag_update(&scene->camera->id, ID_RECALC_TRANSFORM);
DEG_relations_tag_update(bmain);
}
#endif

View File

@ -266,6 +266,9 @@ static int view3d_setobjectascamera_exec(bContext *C, wmOperator *op)
WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, scene);
}
DEG_relations_tag_update(CTX_data_main(C));
DEG_id_tag_update(&scene->camera->id, ID_RECALC_TRANSFORM);
return OPERATOR_FINISHED;
}

View File

@ -182,9 +182,18 @@ static bool node_needs_own_transform_relation(const bNode &node)
return false;
}
static bool node_needs_camera_transform_relation(const bNode &node) {
if (node.type == GEO_NODE_ACTIVE_CAMERA) {
return true;
}
return false;
}
static void process_nodes_for_depsgraph(const bNodeTree &tree,
Set<ID *> &ids,
bool &r_needs_own_transform_relation,
bool &r_needs_camera_transform_relation,
Set<const bNodeTree *> &checked_groups)
{
if (!checked_groups.add(&tree)) {
@ -196,11 +205,13 @@ static void process_nodes_for_depsgraph(const bNodeTree &tree,
add_used_ids_from_sockets(node->inputs, ids);
add_used_ids_from_sockets(node->outputs, ids);
r_needs_own_transform_relation |= node_needs_own_transform_relation(*node);
r_needs_camera_transform_relation |= node_needs_camera_transform_relation(*node);
}
for (const bNode *node : tree.group_nodes()) {
if (const bNodeTree *sub_tree = reinterpret_cast<const bNodeTree *>(node->id)) {
process_nodes_for_depsgraph(*sub_tree, ids, r_needs_own_transform_relation, checked_groups);
process_nodes_for_depsgraph(*sub_tree, ids, r_needs_own_transform_relation,
r_needs_camera_transform_relation, checked_groups);
}
}
}
@ -258,11 +269,13 @@ static void update_depsgraph(ModifierData *md, const ModifierUpdateDepsgraphCont
DEG_add_node_tree_output_relation(ctx->node, nmd->node_group, "Nodes Modifier");
bool needs_own_transform_relation = false;
bool needs_camera_transform_relation = false;
Set<ID *> used_ids;
find_used_ids_from_settings(nmd->settings, used_ids);
Set<const bNodeTree *> checked_groups;
process_nodes_for_depsgraph(
*nmd->node_group, used_ids, needs_own_transform_relation, checked_groups);
*nmd->node_group, used_ids, needs_own_transform_relation,
needs_camera_transform_relation, checked_groups);
if (ctx->object->type == OB_CURVES) {
Curves *curves_id = static_cast<Curves *>(ctx->object->data);
@ -299,6 +312,9 @@ static void update_depsgraph(ModifierData *md, const ModifierUpdateDepsgraphCont
if (needs_own_transform_relation) {
DEG_add_depends_on_transform_relation(ctx->node, "Nodes Modifier");
}
if (needs_camera_transform_relation && ctx->scene->camera != nullptr) {
DEG_add_object_relation(ctx->node, ctx->scene->camera, DEG_OB_COMP_TRANSFORM, "Camera relation!");
}
}
static bool check_tree_for_time_node(const bNodeTree &tree, Set<const bNodeTree *> &checked_groups)

View File

@ -283,6 +283,7 @@ DefNode(FunctionNode, FN_NODE_STRING_LENGTH, 0, "STRING_LENGTH", StringLength, "
DefNode(FunctionNode, FN_NODE_VALUE_TO_STRING, 0, "VALUE_TO_STRING", ValueToString, "Value to String", "")
dbsc marked this conversation as resolved Outdated

I'd suggest being more specific: Retrieve the scene's active camera

I'd suggest being more specific: `Retrieve the scene's active camera`
DefNode(GeometryNode, GEO_NODE_ACCUMULATE_FIELD, def_geo_accumulate_field, "ACCUMULATE_FIELD", AccumulateField, "Accumulate Field", "Add the values of an evaluated field together and output the running total for each element")
DefNode(GeometryNode, GEO_NODE_ACTIVE_CAMERA, 0, "ACTIVE_CAMERA", ActiveCamera, "Active Camera", "Retrieve the scene's active camera")
DefNode(GeometryNode, GEO_NODE_ATTRIBUTE_DOMAIN_SIZE, def_geo_attribute_domain_size, "ATTRIBUTE_DOMAIN_SIZE", AttributeDomainSize, "Domain Size", "Retrieve the number of elements in a geometry for each attribute domain")
DefNode(GeometryNode, GEO_NODE_ATTRIBUTE_STATISTIC, def_geo_attribute_statistic, "ATTRIBUTE_STATISTIC",AttributeStatistic, "Attribute Statistic", "Calculate statistics about a data set from a field evaluated on a geometry")
DefNode(GeometryNode, GEO_NODE_BLUR_ATTRIBUTE, def_geo_blur_attribute, "BLUR_ATTRIBUTE", BlurAttribute, "Blur Attribute", "Mix attribute values of neighboring elements")

View File

@ -32,6 +32,7 @@ set(SRC
nodes/node_geo_blur_attribute.cc
nodes/node_geo_boolean.cc
nodes/node_geo_bounding_box.cc
nodes/node_geo_active_camera.cc
nodes/node_geo_collection_info.cc
nodes/node_geo_common.cc
nodes/node_geo_convex_hull.cc

View File

@ -13,6 +13,7 @@ void register_geometry_nodes()
register_node_type_geo_group();
register_node_type_geo_accumulate_field();
register_node_type_geo_active_camera();
register_node_type_geo_attribute_capture();
register_node_type_geo_attribute_domain_size();
register_node_type_geo_attribute_statistic();

View File

@ -9,6 +9,7 @@ void register_node_tree_type_geo();
void register_node_type_geo_group();
void register_node_type_geo_accumulate_field();
void register_node_type_geo_active_camera();
void register_node_type_geo_attribute_capture();
void register_node_type_geo_attribute_domain_size();
void register_node_type_geo_attribute_separate_xyz();

View File

@ -0,0 +1,32 @@
/* SPDX-License-Identifier: GPL-2.0-or-later */
#include "node_geometry_util.hh"
#include "DEG_depsgraph_query.h"
namespace blender::nodes::node_geo_active_camera_cc {
static void node_declare(NodeDeclarationBuilder &b)
{
b.add_output<decl::Object>(N_("Active Camera"));
}
static void node_geo_exec(GeoNodeExecParams params)
{
const Scene *scene = DEG_get_input_scene(params.depsgraph());
dbsc marked this conversation as resolved Outdated

If you expect this scene to be evaluate (a copy must be created and initialized) before the geometry nodes work, then the modifier must also create a dependency on the scene and its copy-write component.
It's better to take the original scene (also, do this const). From it to get the original camera. And return it evaluated version (~gel_eval_for_id...). We are already dependent on camera update anyway, its cow copy should be already evaluated.

If you expect this scene to be evaluate (a copy must be created and initialized) before the geometry nodes work, then the modifier must also create a dependency on the scene and its copy-write component. It's better to take the original scene (also, do this const). From it to get the original camera. And return it evaluated version (~`gel_eval_for_id`...). We are already dependent on camera update anyway, its cow copy should be already evaluated.
const Object *camera = DEG_get_original_object(scene->camera);
params.set_output("Active Camera", const_cast<Object *>(camera));
}
} // namespace blender::nodes::node_geo_active_camera_cc
void register_node_type_geo_active_camera()
{
namespace file_ns = blender::nodes::node_geo_active_camera_cc;
static bNodeType ntype;
geo_node_type_base(&ntype, GEO_NODE_ACTIVE_CAMERA, "Active Camera", NODE_CLASS_INPUT);
ntype.geometry_node_execute = file_ns::node_geo_exec;
ntype.declare = file_ns::node_declare;
nodeRegisterType(&ntype);
}