Blender V5.0
node_geo_bounding_box.cc
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2023 Blender Authors
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
7#include "GEO_transform.hh"
8
10
12
14{
15 b.add_input<decl::Geometry>("Geometry")
16 .description(
17 "Geometry to compute the bounding box of. Instances have to be realized before the full "
18 "bounding box can be computed");
19 b.add_input<decl::Bool>("Use Radius")
20 .default_value(true)
22 "For curves, point clouds, and Grease Pencil, take the radius attribute into account "
23 "when computing the bounds.");
24 b.add_output<decl::Geometry>("Bounding Box")
25 .propagate_all_instance_attributes()
26 .description("A cube mesh enclosing the input geometry");
27 b.add_output<decl::Vector>("Min");
28 b.add_output<decl::Vector>("Max");
29}
30
32{
33 GeometrySet geometry_set = params.extract_input<GeometrySet>("Geometry");
34 const bool use_radius = params.extract_input<bool>("Use Radius");
35
36 /* Compute the min and max of all realized geometry for the two
37 * vector outputs, which are only meant to consider real geometry. */
38 const std::optional<Bounds<float3>> bounds = geometry_set.compute_boundbox_without_instances(
39 use_radius);
40 if (!bounds) {
41 params.set_output("Min", float3(0));
42 params.set_output("Max", float3(0));
43 }
44 else {
45 params.set_output("Min", bounds->min);
46 params.set_output("Max", bounds->max);
47 }
48
49 /* Generate the bounding box meshes inside each unique geometry set (including individually for
50 * every instance). Because geometry components are reference counted anyway, we can just
51 * repurpose the original geometry sets for the output. */
52 if (params.output_is_required("Bounding Box")) {
53 geometry::foreach_real_geometry(geometry_set, [&](GeometrySet &sub_geometry) {
54 std::optional<Bounds<float3>> sub_bounds;
55
56 /* Reuse the min and max calculation if this is the main "real" geometry set. */
57 if (&sub_geometry == &geometry_set) {
58 sub_bounds = bounds;
59 }
60 else {
61 sub_bounds = sub_geometry.compute_boundbox_without_instances(use_radius);
62 }
63
64 if (!sub_bounds) {
65 sub_geometry.clear();
66 }
67 else {
68 const float3 scale = sub_bounds->max - sub_bounds->min;
69 const float3 center = sub_bounds->min + scale / 2.0f;
70 Mesh *mesh = geometry::create_cuboid_mesh(scale, 2, 2, 2, "uv_map");
72 sub_geometry.replace_mesh(mesh);
73 sub_geometry.keep_only({GeometryComponent::Type::Mesh, GeometryComponent::Type::Edit});
74 }
75 });
76
77 params.set_output("Bounding Box", std::move(geometry_set));
78 }
79}
80
81static void node_register()
82{
83 static blender::bke::bNodeType ntype;
84 geo_node_type_base(&ntype, "GeometryNodeBoundBox", GEO_NODE_BOUNDING_BOX);
85 ntype.ui_name = "Bounding Box";
86 ntype.ui_description =
87 "Calculate the limits of a geometry's positions and generate a box mesh with those "
88 "dimensions";
89 ntype.enum_name_legacy = "BOUNDING_BOX";
91 ntype.declare = node_declare;
94}
96
97} // namespace blender::nodes::node_geo_bounding_box_cc
#define NODE_CLASS_GEOMETRY
Definition BKE_node.hh:461
#define GEO_NODE_BOUNDING_BOX
#define NOD_REGISTER_NODE(REGISTER_FUNC)
uiWidgetBaseParameters params[MAX_WIDGET_BASE_BATCH]
void node_register_type(bNodeType &ntype)
Definition node.cc:2416
Mesh * create_cuboid_mesh(const float3 &size, int verts_x, int verts_y, int verts_z, std::optional< StringRef > uv_id)
void foreach_real_geometry(bke::GeometrySet &geometry, FunctionRef< void(bke::GeometrySet &geometry_set)> fn)
void transform_mesh(Mesh &mesh, float3 translation, math::Quaternion rotation, float3 scale)
static void node_declare(NodeDeclarationBuilder &b)
static void node_geo_exec(GeoNodeExecParams params)
VecBase< float, 3 > float3
void geo_node_type_base(blender::bke::bNodeType *ntype, std::string idname, const std::optional< int16_t > legacy_type)
void keep_only(Span< GeometryComponent::Type > component_types)
std::optional< Bounds< float3 > > compute_boundbox_without_instances(bool use_radius=true, bool use_subdiv=false) const
void replace_mesh(Mesh *mesh, GeometryOwnershipType ownership=GeometryOwnershipType::Owned)
Defines a node type.
Definition BKE_node.hh:238
std::string ui_description
Definition BKE_node.hh:244
NodeGeometryExecFunction geometry_node_execute
Definition BKE_node.hh:354
const char * enum_name_legacy
Definition BKE_node.hh:247
NodeDeclareFunction declare
Definition BKE_node.hh:362